如何在两个动画之间进行平滑过渡?

时间:2020-06-08 18:35:17

标签: c# unity3d animation

开始游戏时首先检查角色或打字的动画,然后在10秒钟后我希望角色开始行走,并且在到达目的地之前变为空闲状态。

顺序应为:打字,步行,空闲

使用此脚本,角色将在等待目标对象10秒钟的情况下旋转输入,然后移动到目标而没有两个动画“行走”和“空闲”。

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();
                }
            }
        }
    }
}

在编辑器中,我有一个角色的动画控制器,具有3种状态:touc / examine,walk和idle

第一个动画效果很好,但是10秒钟后它不会改变走路的感觉,也不会改变走路的感觉。它一直循环播放第一个动画。并且第一个动画长度大于0秒。

在第一个动画状态和第二个行走状态之间存在一个过渡,并且退出状态的退出时间受一个条件“行走真实”和我添加的bool名称“行走”类型的参数的限制。

在第二个状态行走和最后一个状态空闲之间,也存在条件为“真”的情况下也禁用了过渡和退出时间。

第一次转换的屏幕截图:

Transition 1

Transition 2

主要思想是在3个状态之间平滑过渡,然后在播放最后一个状态时停止播放,而不会循环播放。每个状态应播放一次。

我到目前为止所做的:

在两个过渡中均已禁用具有退出时间(已启用false)

然后更改脚本,添加一行以启动Walk动画状态:

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();
                }
            }
        }
    }
}

10秒后:

anim.SetBool("Walk", true);

但是现在我想要在代理到达目标目的地之前或何时将其更改为空闲状态动画:

anim.SetBool("Idle", true);

但是我不确定将其放在脚本中的什么位置。我在这个地方尝试过:

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

但是它不能正常工作,代理在目标位置之后继续走动,然后又移回目标位置,然后转为闲置。

0 个答案:

没有答案