Tile-based Enemy AI issue
Hi all,
This is the first question I post here, please bear with me if I'm doing anything wrong.
So, I'm building a "simple" top-down, grid-based, turn-based game, and I've written a simple enemy AI script to control my enemies. It works ok, but sometimes the enemies don't move during their turn. I understand/think that it's happening because my if statements are being skipped and by the end of the function none of the conditions have been met, resulting in no movement. To fix this, I tried adding some recursion in the script, calling it again at the end of the script in place of the call to Patrol()
, but this was giving me a nasty Stack Overflow Exception.
I've been slamming my head against the wall trying to fix this script, but I still get the same inconsistent results. I'm fairly new to programming and admit not having a firm grasp of CS concepts, though I work hard to get better. Because of the obstacles in my world, I need to check whether or not the enemy can move in a certain direction, but all the extra checks are blocking my function from returning a move. Any ideas on how to make my script work, basically, how to have it return a value each time and make sure my enemies always move on their turn?
Here's my script:
private void Chase () {
int multiX = 0;
int multiY = 0;
float deltaX = Mathf.Abs(player.transform.position.x - this.transform.position.x);
float deltaY = Mathf.Abs(player.transform.position.y - this.transform.position.y);
// if the distance to the player in the x-axis is greater than in the y-axis, move enemy in the x-axis
if (deltaX > deltaY)
{
#region set X multiplier
// if the player is to the right of the enemy, move enemy to the right
if (player.transform.position.x > this.transform.position.x && canMoveRight)
{
multiX = 1;
}
// if the player is to the left of the enemy, move enemy to the left
else if (player.transform.position.x < this.transform.position.x && canMoveLeft)
{
multiX = -1;
}
#endregion
}
// else if the distance to the player in the y-axis is greater than in the x-axis, move enemy in the y-axis
if (deltaY > deltaX)
{
#region set Y multiplier
// if the player is above the enemy, move enemy up
if (player.transform.position.y > this.transform.position.y && canMoveUp)
{
multiY = 1;
}
// if the player is below the enemy, move enemy down
else if (player.transform.position.y < this.transform.position.y && canMoveDown)
{
multiY = -1;
}
#endregion
}
// if the distance to the player is equal in both the x-axis and the y-axis,
// move enemy closer to player in a random direction
if (deltaX == deltaY)
{
if (player.transform.position.y > this.transform.position.y && canMoveUp)
{
multiY = 1;
}
else if (player.transform.position.x > this.transform.position.x && canMoveRight)
{
multiX = 1;
}
else if (player.transform.position.y < this.transform.position.y && canMoveDown)
{
multiY = -1;
}
else if (player.transform.position.x < this.transform.position.x && canMoveLeft)
{
multiX = -1;
}
}
Vector3 moveVector = this.transform.position + new Vector3 (multiX, multiY, 0);
// check to see if enemy will move or not
if (transform.position != moveVector)
{
LeanTween.move (gameObject, moveVector, 0.3f);
enemyWalkSound ();
}
else
{
Patrol ();
}
} // Chase
Any help would be greatly appreciated. I love this community, and although it's my first time posting a question, I'm often on here reading posts, trying to get better at my craft. Thanks again!
I don't know if you still need help with this but I can give you some tips to help you debug your code or how you can find this out in the future.
If you are using Visual Studios and haven't tried this, you can use breakpoints to watch your code execute as the function is called. To do this, just left click right by the line numbers inside of the function you want to watch. You will see a red circle appear next to the line. Next you want to click the "Attach to Unity" at the top of Visual Studios. You will see Visual Studios do some stuff and it might take a few seconds to complete.
Once you have your script attached to unity, go back into unity and run your scene as you normally would and do the appropriate actions to make your script fire. Once your script fires, you will be taken straight to Visual Studios and you get to watch your script run as it would without you watching.
You have to manually move to the next line while you are using breakpoints but it is a very useful tool that will give you a better understanding of what exactly your code is doing.
Click on the Debug button in the menu strip of Visual Studios to find "Step Into" and "Step Over" buttons. In my Visual Studios F10 is Step Over and F11 is Step Into. You can use either of them to advance to the next line of code when you are running your game with breakpoints but you need to watch for other functions that will be called. Once you are on a line that calls another function, Step Into will take you to the execution of that function, while step over will call the function without needing your input.
Once you are looking at your code, keep an eye in the Locals window to see what data is changed. Also watch out for what parts of your code are executing and when.
Doing this you should be able to see exactly what is happening in your code and when it is happening which is very helpful for figuring this stuff out.
Your answer
Follow this Question
Related Questions
My 2d enemy is infinitley jumping 1 Answer
One large 2d grid or multiple small ones? 1 Answer
How to fix enemy's rotation (2D) 0 Answers
Grid-based 2D game (turn based): How should I get started? 1 Answer
How to fix enemy's rotation (2D) 0 Answers