- Home /
(AI) Unity Crashing on second if statement.
I am creating an AI player. At this point I am trying to have them do different things depending on the distance the AI is away from the player. From 100 to 50 I want the AI to walk toward the player, next at 50, I want it to decide to walk forward, left, or right. Right now the problem comes at the time of this decision at 50. I have had it print statements for the b4 2nd else if this whole time, its just when it gets to the second else if between mid range and close range that unity just crashes and I have to force quit the application. Below is the code.
Once again, it all crashes at the second if statement in the update. I have no Idea what is wrong. It is not even printing out comments in the second if statement. Please help.
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class chase : MonoBehaviour {
static Animator anim;
public Transform player;
public float enemySpeed = 0.5f;
public float strafeSpeed = 0.5f;
public float attackdistance = 50;
public float farDistance = 100;
public float midDistance = 50;
public float closeRange = 5;
// Use this for initialization
void Start()
{
//gets possible animations from stored unity animator
anim = GetComponent<Animator>();
}
//start of game logic for AI
// Update AI mode based on enemy distance (far, mid, or close)
void FixedUpdate() {
print("inside update");
// makes AI walk forward due to far distance
//if ((Vector3.Distance(player.position, this.transform.position) <= farDistance) && (Vector3.Distance(player.position, this.transform.position) > midDistance))
if ((floatDistanceBetweenAIPlayer() < farDistance) && (floatDistanceBetweenAIPlayer() > midDistance))
{
print("got through 1st if");
// magnitude of distance from AI to enemy
Vector3 myDirection = vectorDistanceBetweenAIPlayer(player);
//AI looks at player
updateLookAtPlayer(myDirection);
//AI walks toward player
updateWalkForward();
print("iswalkingforward far dist");
print("b4 2nd else if");
}
//makes AI decide to go left, right, forward, jump attack, or idle
//if ((Vector3.Distance(player.position, this.transform.position) <= midDistance) && (Vector3.Distance(player.position, this.transform.position) > closeRange))
else if ((floatDistanceBetweenAIPlayer() < midDistance)&& (floatDistanceBetweenAIPlayer() > closeRange))
{
print("were in 2nd if");
// magnitude of distance from AI to enemy
Vector3 myDirection = vectorDistanceBetweenAIPlayer(player);
print("myDirection has data: " + myDirection);
//AI looks at player
updateLookAtPlayer(myDirection);
print("updateLookAtPlayer(myDirection) has data: ");
//start decision process by generating a random numer
int rnd = Random.Range(1, 3);
print("rando " + rnd);
if (rnd == 1)
{
print("inside if");
updateWalkLeft();
print("INSIDE updateWalkLeft(): ");
}
if (rnd == 2)
{
updateWalkRight();
}
}
/*else
{
anim.SetBool("isIdle", true);
anim.SetBool("isWalking", false);
anim.SetBool("isAttacking", false);
}*/
}
it would help if we could see what the other functions are that you're calling. Also, try to cache "floatDistanceBetweenAIPlayer" at the beginning of the update, before you use it so many times in the same frame.
Unity beco$$anonymous$$g unresponsive almost always means you've created an infinite loop in your code. So my guess is you've got a non-ter$$anonymous$$ating while() condition in either updateWalkLeft(); or updateWalkRight();
This is the rest of the code that the functions are calling. it looks like we are getting problems with the condition in floatDistanceBetweenAIPlayer. I'm not sure much more beyond that.
//finds magnitude of distance between player and AI as a float
float floatDistanceBetweenAIPlayer()
{
//dist is getting the float magnitude of players position subtracted from the AI's postition
float dist = Vector3.Distance(player.position, transform.position);
return dist;
}
Vector3 vectorDistanceBetweenAIPlayer(Transform player)
{
Vector3 dist = player.position - transform.position;
return dist;
}
// updates AI's look direction
void updateLookAtPlayer(Vector3 direction)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), 0.1f);
direction.y = 0;
}
// moves AI forward and starts animation
void updateWalkForward()
{
this.transform.Translate(0, 0, enemySpeed);
//anim.SetBool("isIdle", false);
anim.SetBool("isWalkingForward", true);
anim.SetBool("isWalkingLeft", false);
anim.SetBool("isWalkingRight", false);
}
// moves AI forward and starts animation
void updateWalkLeft()
{
// create time delay based on range from 0 to 10
WaitForSeconds timeDelay = new WaitForSeconds(Random.Range(0, 10));
//loops through time delay until it reaches zero
while (!timeDelay.Equals(0))
{
transform.Translate(-(strafeSpeed), 0, 0);
//anim.SetBool("isIdle", false);
anim.SetBool("isWalkingForward", false);
anim.SetBool("isWalkingLeft", true);
anim.SetBool("isWalkingRight", false);
}
}
void updateWalkRight()
{
// create time delay based on range from 0 to 10
WaitForSeconds timeDelay = new WaitForSeconds(Random.Range(0, 10));
//loops through time delay until it reaches zero
while (!timeDelay.Equals(0))
{
this.transform.Translate((strafeSpeed), 0, 0);
// anim.SetBool("isIdle", false);
anim.SetBool("isWalkingForward", false);
anim.SetBool("isWalkingLeft", false);
anim.SetBool("isWalkingRight", true);
}
}
}
If it is not printing out the second if statement, then it is not getting there. Could you show the floatDistanceBetweenAIPlayer() code? Also, not sure if you know how to debug using breakpoints, but they would be very helpful to figure out where your code is breaking. Here is a quick tutorial on debugging in VS from Unity themselves.
Answer by tanoshimi · Jun 26, 2017 at 05:21 PM
As predicted, you've got infinite loops in your updateWalkLeft and updateWalkRight methods, since your while loop continues while timeDelay is not 0, but never change the value of timeDelay in the loop.... so it's never gonna decrease:
void updateWalkLeft()
{
// create time delay based on range from 0 to 10
WaitForSeconds timeDelay = new WaitForSeconds(Random.Range(0, 10));
//loops through time delay until it reaches zero
// THIS WILL GO ON FOREVER!
while (!timeDelay.Equals(0))
{
transform.Translate(-(strafeSpeed), 0, 0);
//anim.SetBool("isIdle", false);
anim.SetBool("isWalkingForward", false);
anim.SetBool("isWalkingLeft", true);
anim.SetBool("isWalkingRight", false);
}
}
would it be better to use a coroutine? I have been trying so I changed the walk left and added an ienumerator. I am very new to coroutines so not surprisingly, this did not work out exactly as I wanted. Right now, the player makes it to 50, slowly moves to the side for a little bit, and then starts glitching back and forth
void updateWalkRight()
{
float time = (Random.Range(2, 10));
print("time" + time);
//Vector posistion of AI
Vector3 position = new Vector3(transform.position.x, transform.position.y, transform.position.z);
//Vector with randomly generated x values to make AI strafe right
Vector3 destination = new Vector3((transform.position.x)-(Random.Range(2, 10)),transform.position.y,transform.position.z);
StartCoroutine($$anonymous$$oveFromTo(position, destination, time));
}
IEnumerator $$anonymous$$oveFromTo(Vector3 position, Vector3 desination, float time)
{
float elapsedTime = 0;
while (elapsedTime < time)
{
transform.position = Vector3.Lerp(position, desination, (elapsedTime / time));
elapsedTime += Time.deltaTime;
yield return null;
}
transform.position = desination;
}
}
Coroutines should be used for any function that needs to be spread over several frames. So, yes, this is a good use case. Your code seems ok at first glance - but how (and how often) are you calling updateWalkRight? You don't ever seem to cancel the running coroutine, so make sure you aren't launching more than one instance at the same time.
Your answer
Follow this Question
Related Questions
Update Function Won't Do If Statements 1 Answer
Update within an if statement not working? 3 Answers
Checking if statement in higher frequency 0 Answers
c# Ignoring conditional statement? 1 Answer