How can I make a smooth transition between two animations?

Viewed 589

First animation when starting the game the character is examine or typing and then after 10 seconds I want the character to start walking and just before reaching the destination to change to idle.

The order should be : Typing , Walking , Idle

With this script the character is typing waiting 10 seconds rotating looking the target and then move to the target without the two animations Walking and Idle.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AgentControl : MonoBehaviour
{
    public List<Transform> points;
    public bool waitTimeToMove = false;
    //notice WaitTime is a float now
    public float WaitTime = 10f;
    public bool randomWaitTime;
    float waitMinTime = 1f;
    float waitMaxTime = 10f;
    public bool loop = false;

    private int destPoint = 0;
    private NavMeshAgent agent;
    private Transform originalPos;
    //two vars for handling timer
    private float timer = 0;
    private float originSpeed;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();

        // Disabling auto-braking allows for continuous movement
        // between points (ie, the agent doesn't slow down as it
        // approaches a destination point).
        agent.autoBraking = false;

        originSpeed = agent.speed;

        if (randomWaitTime == true)
        {
            WaitTime = Random.Range(waitMinTime, waitMaxTime);
        }

        //transforms dont exist without A GameObject and a GameObject doesn't exist without a transform
        //create a new GameObject to hold our position
        GameObject originalPositionObject = new GameObject();
        originalPositionObject.name = "WP";
        originalPositionObject.tag = "Waypoint";
        originalPositionObject.transform.parent = GameObject.Find("Waypoints").transform;
        //set the new gameobjects position equal to where the transform is right now
        originalPositionObject.transform.position = transform.position;
        //add this to the points list instead
        points.Add(originalPositionObject.transform);
    }


    void GotoNextPoint()
    {
        // Returns if no points have been set up
        if (points.Count == 0)
            return;

        // Set the agent to go to the currently selected destination.
        agent.destination = points[destPoint].position;

        // Choose the next point in the array as the destination,
        // cycling to the start if necessary.
        destPoint = (destPoint + 1) % points.Count;
    }


    void Update()
    {
        // Choose the next destination point when the agent gets
        // close to the current one.
        if (!agent.pathPending && agent.remainingDistance < 1f)
        {
            //if wait to move is true
            if (waitTimeToMove)
            {
                //if timer is less than 10
                if (timer < WaitTime)
                {
                    //add Time.deltaTime each time we hit this point
                    timer += Time.deltaTime;
                }
                //no longer waiting because timer is greater than 10
                else
                {

                    waitTimeToMove = false;
                }
            }
            //if we hit here waitToMove is false, so go ahead as usual
            else
            {
                if (loop == false && destPoint == points.Count - 1)
                {
                    agent.speed = 0;
                }

                if (loop == true || destPoint != points.Count - 1)
                {
                    agent.speed = originSpeed;
                    // Not working if setting back to loop = true in the inspector
                    // After it was not loop and agent in last waypoint
                    // When setting to loop = true it's not continue to check why
                    // Should continue the loop if loop true !
                    // Loop = true is not working when game is running only on Start

                    GotoNextPoint();
                }
            }
        }
    }
}

In the editor I have an animator controller for the character with 3 states : The touc/examine , walk , idle

The first animation is working fine but it's not changing to walk after 10 seconds and not changing to walk at all. It keep looping the first animation all the time. and the first animation length is more then 0 seconds.

between the first animation state and the second walk state there is a transition and exit time is disabled with one condition Walk True and a parameter I added of type bool name Walk.

between the second state walk and the last state idle also there is a transition and exit time disabled too with condition Walk True.

Screenshot of the first transition :

Transition 1

Transition 2

The main idea is to change transitions smooth between the 3 states and then stop when the last state played without looping. Each state should play once.

What I did so far :

In both transitions disabled Has Exit Time (enabled false)

Then changed the script added a line to start the Walk animation state :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AgentControl : MonoBehaviour
{
    public List<Transform> points;
    public bool waitTimeToMove = false;
    //notice WaitTime is a float now
    public float WaitTime = 10f;
    public bool randomWaitTime;
    float waitMinTime = 1f;
    float waitMaxTime = 10f;
    public bool loop = false;
    public Animator anim;

    private int destPoint = 0;
    private NavMeshAgent agent;
    private Transform originalPos;
    //two vars for handling timer
    private float timer = 0;
    private float originSpeed;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();

        // Disabling auto-braking allows for continuous movement
        // between points (ie, the agent doesn't slow down as it
        // approaches a destination point).
        agent.autoBraking = false;

        originSpeed = agent.speed;

        if (randomWaitTime == true)
        {
            WaitTime = Random.Range(waitMinTime, waitMaxTime);
        }

        //transforms dont exist without A GameObject and a GameObject doesn't exist without a transform
        //create a new GameObject to hold our position
        GameObject originalPositionObject = new GameObject();
        originalPositionObject.name = "WP";
        originalPositionObject.tag = "Waypoint";
        originalPositionObject.transform.parent = GameObject.Find("Waypoints").transform;
        //set the new gameobjects position equal to where the transform is right now
        originalPositionObject.transform.position = transform.position;
        //add this to the points list instead
        points.Add(originalPositionObject.transform);

        anim = GetComponent<Animator>();
    }


    void GotoNextPoint()
    {
        // Returns if no points have been set up
        if (points.Count == 0)
            return;

        // Set the agent to go to the currently selected destination.
        agent.destination = points[destPoint].position;

        // Choose the next point in the array as the destination,
        // cycling to the start if necessary.
        destPoint = (destPoint + 1) % points.Count;
    }


    void Update()
    {
        // Choose the next destination point when the agent gets
        // close to the current one.
        if (!agent.pathPending && agent.remainingDistance < 1f)
        {
            //if wait to move is true
            if (waitTimeToMove)
            {
                //if timer is less than 10
                if (timer < WaitTime)
                {
                    //add Time.deltaTime each time we hit this point
                    timer += Time.deltaTime;
                }
                //no longer waiting because timer is greater than 10
                else
                {

                    waitTimeToMove = false;

                    anim.SetBool("Walk", true);
                }
            }
            //if we hit here waitToMove is false, so go ahead as usual
            else
            {
                if (loop == false && destPoint == points.Count - 1)
                {
                    agent.speed = 0;
                }

                if (loop == true || destPoint != points.Count - 1)
                {
                    agent.speed = originSpeed;
                    // Not working if setting back to loop = true in the inspector
                    // After it was not loop and agent in last waypoint
                    // When setting to loop = true it's not continue to check why
                    // Should continue the loop if loop true !
                    // Loop = true is not working when game is running only on Start

                    GotoNextPoint();
                }
            }
        }
    }
}

After 10 seconds :

anim.SetBool("Walk", true);

but now I want that a bit before or when the agent get to the target destination to change it to the Idle state animation :

anim.SetBool("Idle", true);

but I'm not sure where to put it in the script. I tried in this place :

if (loop == false && destPoint == points.Count - 1)
                    {
                        agent.speed = 0;
                        anim.SetBool("Idle", true);
                    }

but it didn't work fine the agent kept walking after the target destination then moved back to the target destination then changed to idle a mess.

0 Answers
Related