(AI) Using a Coroutine in a character move left/right situation for a random amount of time

by mhirsch   Last Updated June 27, 2017 05:13 AM

Using C# So what I am trying to do is have an AI character make decisions based on 3 zones, far distance, mid distance, or close range (not yet to close range). So far, the logic is set up so the character if in the far zone (50 to 100) will come forward. Once it reaches 50, it will decide if it will move left or move right (eventually going to add in move forward, or jump attack) for a certain amount of time between 2 and 10 seconds. This is based off a random number generator. Once this number is generated (1 or 2), it will call on either the move left or move right functions. These functions create a position vector, a destination vector (x or -x direction), and a time float which is another random range between 2 and 10. These values are then output to a coroutine. I am fairly new to coroutines. Right now, running the code I have, the AI character comes in from 100 units just fine. Once it reaches 50, it will slowly move left or right for a little bit, and then start glitching back and forth. I am wonder what I have done wrong here. Am I missing some type of position cache at the beginning or possibly the coroutine isn't returning a time. I'm really not sure. Please help.

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 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))
    {
        // magnitude of distance from AI to enemy
        Vector3 myDirection = vectorDistanceBetweenAIPlayer(player);
        //AI looks at player
        updateLookAtPlayer(myDirection);

        //AI walks toward player
        updateWalkForward();      
    }

    //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))
    if ((floatDistanceBetweenAIPlayer() < midDistance)&& (floatDistanceBetweenAIPlayer() > closeRange))
    {
        // magnitude of distance from AI to enemy
        Vector3 myDirection = vectorDistanceBetweenAIPlayer(player);

        //AI looks at player
        updateLookAtPlayer(myDirection);

        //start decision process by generating a random numer
        int rnd = Random.Range(1, 3);
        //int rnd = 1;

        print("rando " + rnd);
        if (rnd == 1)
        {
            updateWalkLeft();
            print("walkleft");
        }
        if (rnd == 2)
        {
            updateWalkRight();
            print("walkright");
        }
    }
}

//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 to left
void updateWalkLeft()

{
    float time = (Random.Range(2, 10));
    print("time" + time);
    //vector of position of AI
    Vector3 position = new Vector3(transform.position.x, transform.position.y, transform.position.z);
    //Vector with randomly generated x values to make the AI strafe left
    Vector3 destination = new Vector3((transform.position.x) + (Random.Range(2, 10)), transform.position.y, transform.position.z);


    StartCoroutine(MoveFromTo(position, destination, time));
}

//moves AI to right
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(MoveFromTo(position, destination, time));
}


IEnumerator MoveFromTo(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;
}

}

Tags : c# ai coroutines


Related Questions





NullReferenceException in StartCoroutine method

Updated November 25, 2016 08:05 AM

Best way to queue animation coroutines in unity

Updated April 15, 2017 00:13 AM