Create a Basic Video Game AI in Unity Using C# | Iman Irajdoost | Skillshare

Playback Speed


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Create a Basic Video Game AI in Unity Using C#

teacher avatar Iman Irajdoost, Software/Game Developer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

8 Lessons (55m)
    • 1. Introduction

      2:08
    • 2. Project Structure Part 1

      6:00
    • 3. Project Structure Part 2

      10:34
    • 4. Theories of AI: State Machines

      9:58
    • 5. Random Algorithm

      8:45
    • 6. Greedy Algorithm

      12:34
    • 7. Smart Algorithm

      2:44
    • 8. Final Overview

      2:31
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

22

Students

--

Projects

About This Class

In this class, you will learn the principles of an Artificial Intelligence in Video Games and you'll learn how to implement it in Unity using the C# language.

I'll teach you how an AI works in a video game and what are the Algorithms that you can use to implement a simple AI for your game.

At the end of this course, you will be able to create basic AIs for your games and you'll have a clear vision on how you can create more complex AIs.

A basic knowledge of Unity and C# is recommended for this lesson.

Download the Code from HERE

--------------------------

During this class you will learn

  • The Basic Theories of Artificial Intelligence
  • What are State Machines and Decision Trees
  • What are deterministic and non-deterministic games
  • The Algorithms that exist for creating AIs and what are their pros and cons
  • How to be creative while creating an AI

---------------------------

The structure of the class is as follows:

  1. Introduction: see what the class is about!
  2. Project Structure Part 1: Download the code and start to get to know the game objects in the Unity scene
  3. Project Structure Part 2: Get familiar with the code that is already written and get ready for the AI part
  4. Theories of AI: State Machines: Learn the basics of AI in video games and see what are state machines and decision trees
  5. Random Algorithm: Dive into the AI code and learn how to create a basic AI that does random actions
  6. Greedy Algorithm: Understand the pros and cons of greedy algorithm and learn how you can implement it
  7. Smart Algorithm: Learn how you can use your creativity to mix algorithms in order to create a cool AI
  8. Final Overview: See what you can do beyond this class

---------------------------

The link to the Github project is here

The link to my itch.io page is here

Check out my personal website to see my content

Check out other awesome game design classes on Skillshare

Meet Your Teacher

Teacher Profile Image

Iman Irajdoost

Software/Game Developer

Teacher

Software, Game Developer and Creator. I'm passionate about learning and sharing what I know with the World. You can check out the games, music and other stuff that I create on my website.

Feel free to contact me using my social media. Follow me on my Instagram to learn little tips and tricks about game development!

See full profile

Class Ratings

Expectations Met?
  • Exceeded!
    0%
  • Yes
    0%
  • Somewhat
    0%
  • Not really
    0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Introduction: Hello everyone and welcome to this class about how to implement a basic artificial intelligence in Unity using the C Sharp language. My name is Iman Irajdoost, and I will be guiding you through this tutorial During the years I have developed many, many games. Some of them are published and some of them are not. If you want to see some of the games that I have worked on, you can go to the itch.io using the link in the description section. The kind of AI we're going to look into is a real-time AI so, it's not like a game of chess or a game that is turn-based. It's a real time game that is much harder to create an AI for. At the end of the class, you will have something like this. So in the bottom, there is the human player, and at the top is the AI, the game that we're going to create is very, very simple because we want to understand the basics of an AI, but the ideas are the same for much more complex games. So if you understand the basics here, you will be able to create much more complex AIs. Also, you can check out Bomball in itch.io, which is a prototype of the game we have been working on, in Bomball, I have used the same methods that I'm going to teach you in this class to implement the artificial intelligence. During the class, as I explain the code, I will also explain the theories of artificial intelligence, so that you can understand how it works in the world of computers And AI. For my project, I have used Unity 2020, but you can use almost any kind of version of Unity that you want. I will also assume that you have some experience in coding because I am not going to explain every and each line of code. So I will assume that you have some basic understanding of C Sharp language. So if the world of video games and AI interests you, this course is for you. Let's get started. 2. Project Structure Part 1: All right, So we'll start off by looking at the project structure. I have already written the code for the game, but we'll be writing the AI part together. I'll be explaining every component and every code that I have written until now so that you can understand exactly how the game works. What it's about, let us run the game once and see how it is. So as you can see, I'm using the arrow keys to go right and left. My player is the blue tank. You can say, I don't know if it's a tank or something else, but it's at the bottom of the screen. So I'm going right and left. I'm using space to shoot bullets towards the enemy. So as you can see in the bottom left of the screen, my score increases. So it's the same thing for the AI. If he shoots me and if it hits me, it'll get a score. it's as simple as that. I move right, left, I shoot, and I score. That's about that. So our goal here is to create an artificial intelligence that can actually play this game. So what is the condition to play this game? I have a limited number of actions, so I can move right, left, and I can shoot. I have actually exactly three actions. So I don't have many variables in my game. So let's start in the hierarchy here and see what we have, what game objects we have here. So I have my main camera, which is on perspective, and not much to change here. I have my background, which is a sprite renderer, and I have increased the scale to 100 so that it covers the screen. As you can see, if I change the color, it changes the background. Then the next one is my player. In the hierarchy of my Player I have my player Managers Script. I have a shoot script and move script. I have a rigid body 2D and a circle collider. So in my rigid body, I have gravity scale of 0. So that's my player doesn't actually move down. And I have set my circle collider's radius to 0.05. So as you can see here, it's just a bit less than the radius of my player. And inside my player I have the art. So my sprite renderer here is the, this circle, blue circle here. I have a shooter which is you can see the barrel of my tank here. And I have a shoot position which is the tip of my barrel. And this is the place where I shoot the bullets from. So if I go back to my players object, if I take a look at my shoot script, I have this shooting position, which will point towards the shoot position that I've already created. My bullet object is that is a prefab of the bullet that I've created. The shoot delay is the time between my shots. So I can only shoot about each 0.4 seconds. This is my movie script and the speed of my movement. If I increase or decrease this number, I will change the speed of my player. When you create games with unity. This is the standard structure that many people use. So as you can see, some of them are the default components of unity like circle collider and rigid body. And some of them are the scripts that I have created like move, shoot, and player manager. The idea of component-based script is that each action, each feature that's my player has, it should be a component. So my player shoots, I have a shoot component or a shoot script. My player moves, I have a movie script or component, and I have one component for managing these actions. My AI is kinda like my player. It has an AI manager, a shoot script, move script, rigid body, circle collider exactly like my player. But the difference is here, my AI manager. So the code that I am showing you now is the completed code. And as you can see here, this is my decision time. So each 0.2 seconds, my AI. Will think about his next move. His current state, moving left, right, shoot, and going to safety. And I'll be explaining the rest when we get to the AI manager's code. So my two walls here, Wall 1 and Wall 2 are the boundaries of my level. And the sprites I have used are the default sprites of unity. So I haven't used anything, any particular sprites because we're not focusing on art here. And that's why it's so ugly here. The next thing is my canvas. So I have two things in my Canvas. If I double-click on it. As you can see, this is my player score, which is at the bottom left of the screen, and my enemy score, which is at the top right, both of them have the same structure. They have a text at the top and score text at the bottom, which my game manager references to. This is the event system that is a predefined for unity and it is created by itself. So in the next lesson, we'll take a look at the code. 3. Project Structure Part 2: Okay, We have reached the fun part, which is the coding. I hope it's fun for you guys because we're going to spend a lot of time in the coding section. We are going to start off by a script, which is really simple. The Move script, I open it up in Visual Studio. And I've created as much comments as I could, I have written comments above my methods. I have written comments above my classes so that you guys can understand exactly what each part of the code is and what it does, what it's about. I hope that these comments can help you understand it if you want to download the code from GitHub. The reason that I'm not writing all these codes again, is that our focus here is the artificial intelligence. And these codes have nothing to do with AI. These are the standard codes that we write for any 2D game that we create using Unity. That's why I want to focus more on the AI part instead of the parts of that are familiar for game developers. But I want to show you how it works either way. Okay, in my Move class, I have a required component type of rigid body, which will tell the GameObject that this script is attached to, that we are going to need a rigid body. So it says that this component is necessary for this script to work. That's why we have created require component. After that is my public variables, which is public float speed. I made it public So that I can change it using the inspector in unity. The next part is my private variables, which I have my rigid body here. Then the next part is my methods. So here I have my Awake method, which is run before the first frame in unity. In the Awake method, I have cached my rigid body. So I have my move character method that takes a parameter of direction as an int, I have my current direction default to 0. If it's less than 0, it means it's negative one, my player will go left. If it's more than 0, it's one. It means that my player will go right, and if it's neither, it will just stay 0 and it means that it will stay where he is. So the rb.velocity code is the one that does the magic. It's a new vector two, and on the x-axis, it will multiply the speed variable that we have set above by my current direction, which is either one or 0 or negative one. And I don't want any speed on the y-axis, so I'll just leave it at 0. That's about my move method. It's a very, very simple method. The next script is the Shoot script. Again, I have my public variables, my private variables and my ,ethods. My public variables are the shooting position, and that's where I start shooting, which is my tip of the barrel or tip of my gun. I have my bullet object, which is the prefab of my bullet. I have the shoot delay, which is the delay between each shot and my private variables. I have Boolean of can shoot. So it will just detect if we are in-between the shots, between the shoot delays or not. I have cached my co-routine, which I will show you in a minute. I have my bullet radius and my circle collider 2D, which I cached in the awake method. So in my methods, I will set my bullet radius to the radius of my collider. I have a public float. GetBulletRadius, which returns the bullet's radius, which is always the same. And I have a method called ShootBullet, which actually shoots the bullet from the tip of my gun. So I have a direction and I have a Boolean to see if it's the player who's shooting. inside the method I check if I can shoot. So if I am not actually in between the shots, I am not in the shoot delay. I create my Bullet using the Instantiate method. And so I create my bullet object prefab at the shooting position; tip of my barrel. And I will get the reference of my bullet manager from the created object. And I will call the bullet manager's ShootBullet method, which will actually shoot the bullet in the direction that we want. After that, I have my co-routine, which is the Shoot delay co-routine, which disables the shooting method for 0.4 seconds. And you can obviously change that. The next method is disable shooting, which is the co-routine that we call. What it does is simply, Sets the can shoot Boolean false, and it will again reset the can shoot to true, and the last method simply returns My can shoot Boolean. Next is my player manager. My player manager class manages all behaviors and components which are attached to this game object. So I have all my inputs here. As you see here, I have my two components, shoot and move, and have cached them in my Awake method and in my update method, I get the inputs from the player. So I'll say if my move manager script IS NOT null, my direction is going to be my Input.GetAxisRaw, which is going to be my arrow keys. And my Move character method will be called on my Move manager script using the direction that I've got from user. Next is the shooting script. Again, if my shooting script is not null and I press the space key, my shooting script will be called on shoot manager. So I have shoot manager.ShootBullet(1). And true, one is the direction that I'm shooting. So I'm shooting from down to top, which will be positive one. If I was the AI, I would have written -1 here. And the second parameter shows that I am the player. So in the case of AI, I will write -1 and false here. The next part would be my game manager. My game manager is nothing complicated either. So I have public variables, which is my player score and enemy score. I have used TextMeshPro, I have used a Singleton type of class here. If you do not know what Singleton is, I suggest you look it up. It's very useful in coding. The next part is the private variables, which are the player's current score and the enemy's current score. And in the Awake method. I have these five lines of code, which are the standard codes for a Singleton. The next method is add score, which is called when a player or AI actually hit the other one with the bullet. So if it's my player, I will increase the player's score. If it's the AI, I will increase the AI's score. And in the end, I will call update UI, which will update the text mesh that are on the Canvas. So I will update my UI. The last piece here that I've almost forgot to mention is my bullet prefab. In my bullet prefab, I have a sprite renderer, which is simply a circle with a red color, red color for my AI and a blue one for my player. I have a circle collider, a rigid body, and I have a script called bullet manager. In my bullet manager, I have a speed, two colors which will show the color for each player. So if it's the player who's shooting, it will show the player's color, which is blue. And if it's AI who's shooting the bullet, it will be red. My private variables will be my rigid body and my sprite render, which are cached in the Awake method. And I have a private boolean which shows if this particular bullet is my player's bullet or the AI's, I have a method called Shoot bullet, which is really close like the one in the shoot script. Inside the method, I will see if it was my player who shot the bullet. And then I will add the velocity to the bullet so 0 to the x and the speed times direction for the Y. And after that, if it's the player who shot the bullet, I'll change the color to player color. And if it's not, I'll change it to AI color. In this method on Enable, I will say destroy this game object after three seconds. Last but not least, is the OnTriggerEnter 2D. It will check if this bullet actually hits someone or not. First of all, it will say if it's the player who shot the bullet, so I have to look for the enemy. If it hits the enemy, I call GameManager.instance.AddScore m_is_player and I will destroy the game object. And if it's the player, we'll do the same thing in the end, I have a Boolean method called is players bullet. And it returns if this bullet is the my players or not. Alright. That's about that for the scripts. The only thing that remains here is our AI manager, which is the brain of our enemy, and which is something that we're going to talk about, right? So in the next lesson, we will go through some theories to see what exactly is an AI, how it works in the world of computers and all? And we will get into the coding very soon. See you in the next lesson. 4. Theories of AI: State Machines: All right, so let's take a look at some theories about artificial intelligence. This lesson is probably the most important part of the course because we're going to talk about some of the basics and some of the most important bases of the artificial intelligence. Okay, let's start by saying, what is AI? So an AI is simply an algorithm that makes computer softwares or games think, And it just tells them how to think and how to reach their goal. So it's just like human beings. We have some data around us, we have some variables. We are in a situation. And so we decide based on these informations that we have. So we take the best action possible according to our knowledge. This is exactly the same thing for our AI. If you consider this our AI. There are things that affect our tank in our game. There are bullets that are being shot at our AI. So our AI has this data that he will understand that these bullets are dangerous and they are coming towards him so it has to dodge the bullets. Our AI knows that he can move right or move left. And it knows that it's a competitive game so it must actually destroy the other players, so it knows it has to shoot as well. So for our AI, this is the environment that he's in, and these are the variables that our AI is aware of. So it can't think outside this environment. So our environment is limited, our variables are limited, and so our actions are as well limited. So if we expand any of these variables, we can say our AI will become much more complex. So as you can see that I have created a very simple game so that our environment is limited, our variables is limited, and our actions as well, by limiting the number of these variables, we can create much simpler AIs. Obviously, the theory of artificial intelligence is much more complex than that. I'm just showing you what I know and I have experienced and what we need to actually implement an AI in Unity. You don't have to read 1000 pages Book of AI to learn how to create simple AIs in Unity. But of course we'll get to that geeky parts as well. The second part is how an AI works. To understand how an AI works, we have to take a look at the state machines. So state machine is, as the name suggests, it shows the states of the artificial intelligence. And each action it takes will change that state. Well, not all the time, but it most likely changes the state of AI. So under some certain conditions, our AI can change its state from one to another. So if we say, for example, this is my starting state. So it can be just the state that I'm standing still. So I'll just call it stand. And my next state would be S2. And this state, I'm dodging bullets, so I'll just call it dodge and in my S3, the third state, I am shooting towards the player. I have exactly three states here, stand, dodge and shoot. And to go from one state to another, I have to take an action. So my action from going from stand to dodge would be, for example, action one, A1. And what is A1? I'll say that A1 is move right. Under some conditions I take this action and I will go to state two. But Sometimes. For example, the bullet is on my right, so I have to take action to, so I'll say a2 and a2 would be move left. to go to the shooting position, Let's say I have to take action three. And action three would be simply start shooting. So I'll just randomly start shooting. Or my action could be something like in a more complex game, I can say start aiming and then shoot. Since our action and our state have the same name here, they're very close and they actually are the same thing. So the action of shooting will take me to the state of shooting. I can also go from my stand state to my shooting state using A3. So it's the same thing if I start shooting and I'll go to the shooting state and all these actions, all these states, they are reversible. So I can go from shooting state also to the standing state is clear that if I, for example, I can draw a line like this, if I say my action 4 is just stop moving. I'll say SM. It means that I'm going to the standard position and the same thing can be done for my S3. The last part is, the most important part for us, is actually how we can implement this state machine. So the first thing that you have to do is to create your state machines or your decision trees. That I'll show you very soon as well. You have to know what are your actions, what are your states for your AI, and each action will take you to which state. To go back to how to implement it. I would say the first thing is to create your state machines or your decision tree. The second thing is to create the pseudocode. I hope I write it well here. It looks kind of French, but I think we're good. And the last part would be coding. I'll show you here the decision tree as well. It's not much different from the state machine. The idea is the same. The way we show it is different. So we have our starting state, which is S1. We have, for example, action one which goes to S2. And we have our action three that goes to S3. And we may have other actions as well. I'll just say n. So this is A1, A3 and An and this could be Sn, and the tree continues down here and down here. Let's take a look at an example in our game. So this is our player here, and this would be our AI. To create a good AI, you have to know how well you can play your game. So you have to master your game to be able to create a very, very good AI. You have to know exactly what actions lead to want, what are the tricks in your game? What can actually make things difficult for the other player and things like that. This is very, very important that the more you know about your gain, the better the AI that you can create. Let's see what we can do here with our player. So we can shoot obviously here and we can move right and left. But what is the intelligent, what does the smart move when we play our game? So imagine our AI, our opponent, is shooting towards us. So you have to clear the way. So you just don't have to be in the way of the bullets. So here, This is dangerous. And imagine we'll have another bullet coming through here. I'll just create another bullet that's coming down. And I'll make it red here. And here. This is a danger zone. Imagine another bullet here. This is another danger zone. So as a player, as a smart player, not a noob player, you have to avoid these places. As you does the bullets, and you avoid these dangerous zones. You have to shoot towards your enemy as well. The simplest way is to just shoot when you see the player in front of you. But as this game is an action game, and is a fast-paced game. And, both of our players are on the move. When you shoot towards the player, when he's in front of you, you don't have a big chance of hitting them. So the smart way is to actually shoot around them so that you can block them in a waym So that your shot. Maybe in the middle, will hit them eventually. Kinda like if you don't have a strategy, you just shoot left and right randomly until one of them hits the AI. So our main strategy to create our AI would be first of all, to dodge the bullets, dodge the dangerous zones, and to shoot towards the player. So in the next lesson, we'll take a look at the possible algorithms that we can create for our AI. 5. Random Algorithm: All right, time to dive into the AI manager's code. The structure of my AI manager's class is the same as my player manager or any other script that I've written. To start off my coding process in AI manager, I will start with using enums here. I have created an enum called AI type, which will hold the AI types and algorithms that my AI can run. If you don't know what enum is, it's simply a package like a dictionary that stores integers, but with a name that is human-readable. So if I take a look here, I created my enum of AI type. And here I have four different entries and they are all actually ints. So if I hold my mouse on one of them, as you can see, for example, do nothing equals 0, random equals one, Greedy equals 2, and smart equals three. I created four types of AI. So the first one, do nothing, actually does exactly what it says. It does nothing. It's just for testing purposes, so it just returns null. The second one, random is just a random algorithm that picks a random action from our list of available actions. Greedy algorithm always looks for the best possible solution. And the smart algorithm is the mixture of my greedy algorithm and my random algorithm. The next enum that I have created is the states, which is the current state of my AI. So I have move right, move left and shoot. Next, I have my methods, in my awake method, I have cached my move manager, my shoot manager and my collider. And we'll talk about the rest of the awake method in the next lesson. In my start method, I will run the type of AI that I have chosen in my Unity's inspector. So this is my current AI type. If I look at my public variables, my current AI type is AI type.random, and I can change this in the inspector. Inside the switch, I will look for the AI type. So if it's AI type.do nothing. We'll run the do-nothing method. Invoke repeating, will just run the method that I have passed to its first parameter, each x seconds. So the first parameter is the name of the method that I want to run. The second one is when you want to run it. So 0 means run it instantly. And the third one is the repeat rate. So in my case, I have a variable called decision time, which in my public variables, I have it here so I can change it in the Inspector. And I have created custom range between 0.01 and 1 second for it. If I take a look at the Run do nothing method, it's just simply a debug.log. And obviously my AI will do nothing. So it's just for testing purposes. The second one is when my AI type is random, I will run the run random method. Let's take a look at it. Remember that this method will run each x seconds. So it means that everything that you see here will run every 0.1 or 0.2 seconds of time. So I have a debug dot log that says running random decision. In the next line, I get all the possible actions. So I get enum dot, getName types of state dot length. So this line of code finds all the possible states that I have in my states enum and takes its length and put it in the variable called states count. In the next line, it will choose one of the available actions from my states enum, completely random. So there is no decision-making here, there is no condition. Nothing. It just picks one completely random. So inside my states enum, if I take a look again, I have move right, move left, and shoot each 0.2 seconds. For example, my AI will pick one of these states randomly. It will either move right, move left, or shoot. And finally, to apply this action, I have a current state, which is the current state of my AI. And I will take the decision that I have from the last line and I will convert it to the type of enum and it will update my current state. And in the end, I have logged finished taking decision. So how does it perform this action? In the update method, if you take a look at the update method, we have if current AI type is equal to, AIType.DoNothing, we will just return. So we will do nothing. But if our AI type is something else, we have a switch here. We have our current state and our current state is also among our public variables. So this is our current state and we have a switch case. In the case of move right, our move manager script will move the character to the right. If it's move left, our move manager script will move the character to the left, so minus one. And in case of state that is shoot, my shoot manager script, will shoot the bullet down, if you remember from our shoot script, plus one was shooting from bottom to top, and minus one means from top to bottom. And the second parameter is of course, false because I am not the player. So congratulations, we have created an AI. It's not something that's really thinks, but it does things and you should be proud of yourself right now. Let's take a look at it in action and see how it works. I have my current AI type, typeof random. I'll make sure I have selected my random and I will leave my decision time to 0.2, so it will decide what to do next. Each 0.2 seconds. I have nothing to do with my current state because my current state will be updated based on the decisions that my AI will take. And the other settings are not for my random AI, so I just leave them at their defaults. Let's run the game and see how it works. As you can see, our AI works. It acts kinda crazy, but it works. So it's a progress, there is no pattern to the way our AI performs. There are no smart moves, there are no strategies, nothing, it just do things randomly. Move left, move right, and shoot. It can be a fun way, it can be a fun AI, but it's really too weak as I can say. So if I just focus here, I can dodge all of his bullets and he will eventually take a hit from my bullets. It doesn't have a strategy and nothing at all. It's not an intelligence. It just something that does random things. It's like playing the game with closed eyes and just pushing the buttons. In 90% of the time, a random AI is not a good idea. But adding randomness to your AI is a very good idea. So it's kind of a, it's a must. Actually, you have to add randomness to your AI, but your AI must not act completely random. It has to be aware of the things around him. What we did here, was that among all the states that we had. So move right, move left and shoot. We took one completely randomly, so there was no condition, nothing. In the next lesson, we will learn how to improve our AI and use other algorithms to actually have something that our AI can think about. And we will add some randomness to it as well. See you in the next video. 6. Greedy Algorithm: All right, In this lesson, we'll take a look at the greedy algorithm. The greedy algorithm is an algorithm that always looks for the best possible solution. It means that if you have many possibilities, for example, going right, left, shooting, dodging bullets, it will always look for the best solution regardless of the next action or the next outcome that it can cause. At first, you might say, well, it's a good thing you always go for the best possible solution. But in reality, it's different. It's not always great to follow the best way. Sometimes you have to sacrifice something for a greater good, it's like a game of chess. Sometimes you have to sacrifice a piece to win the game. So the greedy algorithm is a good algorithm, but it's not always efficient. Now the question is, if I want to implement this greedy algorithm in my game, what is the best possible action for my AI to take? So what is the best solution that it can do every time? We don't have a very big decision tree in our game here, our actions are no more than three or four actions. I have added a fourth one in my actions here go to safety. This is the same as dodging bullets. But the action of dodging bullets is actually the same thing as moving right and left. So my tree, my decision tree is so limited. Therefore, my greedy algorithm would be simply dodging and shooting. Let's see how we can implement it. I've already implemented the shooting part. The only thing that remains is dodging bullets. To implement dodging bullets, first of all, I have to see the bullets coming towards me. So I will create a method that sees all the bullets that are coming towards me and I have to know where they are landing. Are they dangerous or not? So if this bullet is coming right here, It's okay. I am not in danger, but if I see this one coming towards me, it means that I'm in danger so I have to change my position. And therefore dodge the bullet. I have to be careful however, because if I dodge this bullet here and if I go towards this position, I'm in danger again, so I will dodge this bullets, but I'm going to hit another. My safe position will be something between these bullets or rather a bit to the right, a bit more to the right or to the left. And we'll just say that, this is our boundary. As you can see here, these positions are continuous. So I can't really give my AI a fixed position to go to. The first thing I have to do after finding my bullets and finding the dangerous positions is that I have to be able to give a certain position to my player to go to, to do that, I have created a kind of a threshold, so that my positions are no longer continuous. I have created points in shape of circles like this. So this is the center of the circles. Imagine it's the center, it's not really in the center here, I've created all of these along the x-axis. That my AI can move so that if a bullet is going to hit, for example, here or here, or here, then these positions will be the dangerous ones. And so my AI will not go to these points and all the rest would be my safe zones. So what I did here is I created all of these points. And to actually find the safe zones, I will simply say my safe zones would be my available points minus my danger zones. So like that, I will find where my safe zones are. Let's take a look at the code and see how I implemented that. As I mentioned before, I added this go to safety state, to my states. So I have move right, move left, shoot and now go to safety. And in my awake methods, I have created points and I have set the next safe point which is a circle collider to the first available point that I have created. So what does it mean? Create all points, creates all the circles that I have mentioned earlier between the boundaries that we have. So x limit that I have created here in our public variables, which is this one, is the boundaries of my level. So x limit Positive would be the right boundary and the negative one will be the left boundary. So I start creating my points from left all the way to the right in a while loop. And I'll say that while, my current position x is less than the boundary of my x limit. So if I have not yet reached the right boundary of my level, I will create these available points. So I'll say GameObject G, I call it G, instantiate(pointsPrefab) PointPrefab is a prefab that I have, again, in my public variables that I have set in the inspector. It's simply a circle collider 2D, and I have added Its circle collider 2D reference to my available points list. And then I added the collider's radius to my current position. So this would be my threshold. This would be the space between my circles. So my colliders radius is the space between my available points. Next is my next safe position, which is again a circle collider 2D. This is the position that my AI is going to move towards when it finds the safe position. So I have a default of available points indexed 0. So we'll just go all the way to the left if it doesn't find a next safe position in time, I just created this, so that we avoid our AI from standing still at the beginning. And we have a list of safe positions, which is a list of all the positions that my AI can go towards. So when I choose the AI type dot greedy algorithm, what happens is that my run greedy method will run, what is my run greedy method? My run greedy method is a very simple method. The only thing that is a bit more complicated is the state of going to safety that we're going to take a look at. So in my run greedy method, I have a debug dot log: running greedy decision. I don't have to get all the possible actions, but I could. But since it's a greedy method and we always want to take the best action. The best action for me here is going to safety, AKA dodging bullets and shooting. So I have a chance of 50-50, so it's either 0 or 1. my chance of going to safety or shooting, we saw the state that shoots, so the new thing here is the state of going to safety. So go to safety will move the AI to the next safe zone. So let's take a look at move to position. Move the position takes an argument of vector 2, which is the position I want to go to. And if that position is to my right, I'll go to the right. If it's to my left, I will go to the left. So I have a threshold of 0.02. It means that if I'm staying just near that position that I'm receiving, I will just stay there and I won't move. But the magic happens in look for next safe zone method. So as I've described earlier, first of all, it will look for all the bullets that are in the scene, find all dangerous bullets. Let's take a look at the method. This method will simply find all the bullets that are in the scene. And if there are any bullets, it will add it to a list and it will return the list in the end. So these few lines here will make sure that this is the player's bullet and it's not mine. And if it's actually not above me, so if it's passed my my AI, I don't care about it. So it will really look for all the dangerous bullets, possible dangerous bullets. Back to my look for next safe zone method. If I have possible dangerous bullets, I have a debug dot log, I'll say, found bullets. And for each bullet, I will call the overlaps circle all on physics 2D to understand what are the danger zones. So I have a bullet coming towards me. I know its x axis. I will compare it to the AI's y-axis. And if it overlaps with my available points that I have created earlier, I will add all those available points to my danger zones. It means that I'm going to understand which of my points are dangerous. As you can see here, if we have danger zones, it means we have to avoid them. And this is the formula to find my safe positions. Safe positions would be equal to my available points minus danger zones. So for each of the available points, first of all, I consider them safe. But if that available point is among one of the danger zones that I have found, I would say is safe equals false, and I would add them to safe positions only if they are safe. And then if our next safe position is among the safe positions that we found, we will continue going that way. Why did I do that here is because we don't want to change the position of our AI each time that it finds a new safe position. So imagine that my AI is going right to a safe position. And then 0.1 second later it wants to decide again for the next safe position. But the fact is that the position that it has recently found is still safe. So we don't want to change his course again, it will just go crazy left and right. It might look things a bit artificial. So we want to make it as natural as we can. So if my AI is going to a safe position and that position is still safe the next time it thinks, So we want to just keep going that way. But if it's no longer safe, then I want to update the next safe position that it wants to move towards. Among all the safe positions that I have found, I'm going to just pick one randomly and return its position. Let's take a look at my greedy algorithm in action. As you can see here, my AI just stays like that here. And if I shoot towards him, it will change its position. So if I shoot to the left or right, it just stays there. And if I try to shoot towards him, it will just dodge the bullet. So he's overpowered, as you can see that he's got me like ten times and I couldn't even get him once. This is one of the reasons greedy algorithm is not good. So it will make our AI, in this game, it will make our AI overpowered. I can't even, I can't even hit him once it's, it's unbelievable. In the next lesson we'll take a look at a slightly improved version of the algorithm. See you in the next lesson. 7. Smart Algorithm: The final AI type that we will look into is the smart AI. It's not a name that exists in the world of artificial intelligence or anything like that, is just a made-up name that I created for this kind of AI. I want to show you that with a mixture of what we already did until now, with a bit of creativity, we can actually create a very, very good AI. And this is possible for almost any kind of game that you're creating. For each game, you have to be creative. You have to test everything. You have to see what works, what doesn't work in your game. Tweak the decision time, tweak the numbers as much as you can until you get the result that you want. This is what I did with my smart algorithm. I created a float of chance and I created a number between 0 and 1,a float number. And with a chance of 40 percent, I run my random algorithm. So as we saw earlier, our run random algorithm is actually a good algorithm for this kind of AI. So I'll give him a chance of 40 percent to run each decision time. And with a chance of remaining 60 percent, I will run my greedy algorithm. So my run smart algorithm is a mixture of my random and greedy algorithm. Let's see how it works. If you remember the run greedy algorithm, it was overpowered, right Now because we have added a bit of randomness here. We have a chance of 40 percent that our AI will just do something that we are not predicting. So it will eventually hit our bullet. It is still a bit overpowered, but we can of course tweak the numbers. But a bit of challenge is good for your player. So in your game design, always try to create AIs that are a bit challenging for your player and always remember to increase the difficulty as the game progresses. All right, so I'm actually happy with what we did here. And you guys should be proud of yourselves that you have created an AI that is not simple at all, what you learned here can be applied to many, many games. The bases of artificial intelligence are the same in any game. It just depends on the scale of your game and your own creativity. 8. Final Overview: I would like to thank you and also congratulate you for completing this course. I hope that this has been useful for you as well as entertaining. Let's discuss what we can do beyond this class. First of all, the game that we created is considered deterministic. The difference between a deterministic and a non-deterministic game is that in a deterministic game, you will always know what your output is. So if I hit space, I know that my character will shoot. Or in a game of chess, I know the outcome or the output when I move a piece in my board. So a game of chess is considered deterministic. But in a non-deterministic game, chances and randomness will affect the outcome of your game. So you cannot have a concrete decision tree. You can use algorithms like Monte Carlo tree search to deal with AIs in non-deterministic games. To go beyond the algorithms that we have discussed. you can search for Monte Carlo tree search, genetic algorithm, BFS and DFS. These are some great algorithms to create complex AIs. I will also invite you to take a look at GVGAI.net, the general video game AI competition, which explores the problem of creating controllers. For general video games, that means an agent or an AI that can play any type of game that is given to. It's some advanced geeky stuff, but I love it. You can also download the papers about GVGAI from their website. I also recommend that you challenge yourself by adding another action to your AI. For example, taking cover or by limiting the number of shots that your AI can shoot, or by simply creating a defense mechanic for your game. For example, by hitting the bullets with your shot, your opponent's bullet will disappear. And remember to check out my page on itch.io and Try out Bomball to be inspired on how to create a more complex AI. Once again, thank you all and have a wonderful gaming journey.