动画系统

游戏玩家:

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


//此类需要声明属性System.Serializble,表示可序列化
[System.Serializable]
public class Anim
{
    public AnimationClip idle;
    public AnimationClip runForward;
    public AnimationClip runBackward;
    public AnimationClip runRight;
    public AnimationClip runLeft;

}

public class PlayerCtrl : MonoBehaviour
{
    private float h = 0.0F;
    private float v = 0.0F;

    //必须先分配变量,之后才能使用常用组件
    private Transform tr;

    //移动速度变量
    public float moveSpeed = 10.0F;
    //旋转速度变量
    public float rotSpeed = 100.0F;

    //要显示到检视视图的动画类变量
    public Anim anim;
    //要访问下列3D模型Animation组件对象的变量
    public Animation _animation;

    // Start is called before the first frame update
    void Start()
    {
        //向脚本初始部分分配Transform组件
        tr = GetComponent<Transform>();

        _animation = GetComponentInChildren<Animation>();

        //_animation.clip = anim.idle;
        //_animation.Play();
    }

    // Update is called once per frame
    void Update()
    {
        h = Input.GetAxis("Horizontal");
        v = Input.GetAxis("Vertical");

        //计算前后左右移动方向向量
        Vector3 moveDir = (Vector3.forward * v) + (Vector3.right * h);

        //Translate(移动方向*Time.deltaTime*位移值*速度,基础坐标)
        tr.Translate(moveDir.normalized * Time.deltaTime * moveSpeed, Space.Self);

        //以Vecter3.up轴为基准,以rotSpeed速度旋转
        tr.Rotate(Vector3.up * Time.deltaTime * rotSpeed * Input.GetAxis("Mouse X"));

        if (v >= 0.1F)
        {
            //前进动画
            _animation.CrossFade(anim.runForward.name, 0.3F);
        }
        else if (v <= -0.1F)
        {
            //后退动画
            _animation.CrossFade(anim.runBackward.name, 0.3F);
        }
        else if (h >= 0.1F)
        {
            //向右动画
            _animation.CrossFade(anim.runRight.name, 0.3F);
        }
        else if (h <= -0.1F)
        {
            //向左动画
            _animation.CrossFade(anim.runLeft.name, 0.3F);
        }
        else
        {
            //idle动画
            _animation.CrossFade(anim.idle.name, 0.3F);
        }
    }
}

敌人物体(NPC):

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

public class MonsterCtrl : MonoBehaviour
{
    //声明表示怪兽状态信息的Enumerable变量
    public enum MonsterState { idle,trace,attack,die};
    //保存怪兽当前状态的Enum变量
    public MonsterState monsterState = MonsterState.idle;

    //为提高速度而向变量分配各种组件
    private Transform monsterTran;
    private Transform playerTran;
    private NavMeshAgent nvAgent;
    private Animator animator;

    //追击范围
    public float traceDist = 10.0F;
    //攻击范围
    public float attackDist = 2.0F;

    //怪兽是否死亡
    private bool isDie = false;

    // Start is called before the first frame update
    void Start()
    {
        //获取怪兽的Transform组件
        monsterTran = this.gameObject.GetComponent<Transform>();
        //获取玩家Transform组件
        playerTran = GameObject.FindWithTag("Player").GetComponent<Transform>();
        //获取NavMeshAgent组件
        nvAgent = this.gameObject.GetComponent<NavMeshAgent>();
        //获取Animator组件
        animator = this.gameObject.GetComponent<Animator>();

        //设置要追击对象的位置后,怪兽马上开始追击
        nvAgent.destination = playerTran.position;

        //运行定期检查怪兽当前状态的协程函数
        StartCoroutine(this.CheckMonsterState());

        //运行根据怪兽当前状态执行相应例程的协程函数
        StartCoroutine(this.MonsterAction());
    }

    //定期检查怪兽当前状态并更新monsterState值
    IEnumerator CheckMonsterState()
    {
        while (!isDie)
        {
            //等待0.2秒后执行后面的代码
            yield return new WaitForSeconds(0.2F);

            //测量怪兽与玩家之间的距离
            float dist = Vector3.Distance(playerTran.position, monsterTran.position);

            if (dist <= attackDist)
            {
                monsterState = MonsterState.attack;        //查看玩家是否进入攻击范围
            }
            else if (dist <= traceDist)
            {
                monsterState = MonsterState.trace;         //查看玩家是否进入追击范围
            }
            else
            {
                monsterState = MonsterState.idle;          //怪兽的状态为开始状态
            }
        }
    }

    //根据怪兽当前状态执行适当的动作
    IEnumerator MonsterAction()
    {
        while (!isDie)
        {
            switch (monsterState)
            {
                //idle状态
                case MonsterState.idle:
                    //停止追击
                    nvAgent.Stop();
                    //将Animator的IsTrace变量设置为false
                    animator.SetBool("IsTrace", false);
                    break;

                //追击状态
                case MonsterState.trace:
                    //传递要追击对象的位置
                    nvAgent.destination = playerTran.position;
                    //重新开始追击
                    nvAgent.Resume();
                    //将Animator的IsTrace变量设置为true
                    animator.SetBool("IsTrace", true);
                    break;
                
                //攻击状态
                case MonsterState.attack:
                    break;
                case MonsterState.die:
                    break;
                default:
                    break;
            }
            yield return null;
        }
    }
}
原文地址:https://www.cnblogs.com/Optimism/p/10872457.html