【Unity】U3D ARPG游戏制作实例(二)人物基本动作切换


准备工作

打开准备好的场景。
在这里插入图片描述

上一章节的EasyTouch摇杆和按钮添加到此场景中。
在这里插入图片描述

导入一个角色模型:
在这里插入图片描述

将模型放到空节点下:
在这里插入图片描述
将上一章的脚本挂到空节点player下,并添加Character Controller组件:
在这里插入图片描述
看看效果:
请添加图片描述

Unity操作

在角色目录下创建AnimatorController文件夹,在文件夹下创建名为PlayerAnimatorController的Animator Controller:
在这里插入图片描述

给角色模型添加Animator组件:
在这里插入图片描述

将角色模型的Avatar和创建好的PlayerAnimatorController拖拽到Animator组件中:
在这里插入图片描述
Avatar如果没有可以自己创建一个:选中模型中的Rig选项卡,将Avatar Definition指定为Create From This Model,点击Apply。当然,最好还是用跟模型相匹配的Avatar,不然动作很可能会变形。
在这里插入图片描述

打开PlayerAnimatorController,右键点击空白处创建一个名为Idle的空白状态(Create State --> Empty),再将此状态设置为默认状态(Set as Layer Default State),通常情况下创建的第一个状态会自动被指定为默认状态,黄色状态即为默认状态。
在这里插入图片描述

再创建Die和Run两个状态,按照下图,右键点击各个状态将动线连接到相应的状态(Make Transition)。
在这里插入图片描述

切换到Parameters选项卡,添加三个bool变量(idle、run、die)。
在这里插入图片描述

左键选中Idle状态,将停止状态对应的动画拖拽到Motion字段中。按照此方式分别给Die、Run也指定动画。
在这里插入图片描述

选中单个动画文件,点击编辑按钮(Edit)。
在这里插入图片描述
勾选Loop Time,使该动画可以重复播放,然后点击Apply保存修改。Idle和Run都需要做此操作,而Die则不需要,除非你的角色需要不停的Die。
在这里插入图片描述

左键选择一条动线(Transition),取消勾选Has Exit Time以保证动画可以立即切换。然后在下方Conditions添加一个条件,从Idle到Run的条件是run为true;从Run到Idle的条件是run为false;从Any State到Die的条件是die为true。
在这里插入图片描述

注意,动画之间切换是有一个过渡时间的,拖拽此处可以调整过渡时间。
在这里插入图片描述

代码调整

将上一章CharacterMotor的代码改为:

using UnityEngine;

namespace ARPGFinish.Character
{
    /// <summary>
    /// 角色马达
    /// 用于处理角色移动
    /// </summary>
    public class CharacterMotor : MonoBehaviour
    {

        /// <summary>
        /// 动画系统
        /// </summary>
        private CharacterAnimation chAnim;

        /// <summary>
        /// 角色控制器
        /// </summary>
        private CharacterController chController;

        /// <summary>
        /// 移动速度
        /// </summary>
        public float moveSpeed = 5;

        /// <summary>
        /// 转向速度
        /// </summary>
        public float rotationSpeed = 0.5f;

        /// <summary>
        /// 重力
        /// </summary>
        private float gravity = 2;

        /// <summary>
        /// 跳跃速度
        /// </summary>
        public float jumpSpeed = 3;

        /// <summary>
        /// 跳跃时间
        /// </summary>
        public float jumpTime = 0.5f;

        /// <summary>
        /// 累计跳跃时间用来判断是否结束跳跃
        /// </summary>
        public float jumpTimeFlag = 0;

        /// <summary>
        /// 是否移动
        /// </summary>
        private bool isMoving = false;

        /// <summary>
        /// 是否跳跃
        /// </summary>
        private bool isJump = false;

        private void Start()
        {
            chAnim = GetComponent<CharacterAnimation>();
            chController = GetComponent<CharacterController>();
        }

        /// <summary>
        /// 移动方法
        /// </summary>
        public void Move(float x, float z)
        {
            if (x != 0 || z != 0)
            {
                isMoving = true;
                // 1转向 前往的方向
                LookAtTarget(new Vector3(x, 0, z));
            }
        }

        /// <summary>
        /// 转向
        /// 通过Lerp实现转向
        /// </summary>
        private void LookAtTarget(Vector3 target)
        {
            if (target != Vector3.zero)
            {
                Quaternion dir = Quaternion.LookRotation(target);
                transform.rotation = Quaternion.Lerp(transform.rotation, dir, rotationSpeed);
            }
        }

        /// <summary>
        /// 停止移动方法
        /// </summary>
        public void MoveFinish()
        {
            isMoving = false;
        }

        /// <summary>
        /// 角色跳跃
        /// </summary>
        public void Jump()
        {
            isJump = true;
        }

        private void Update()
        {
            //float distance = Vector3.Distance(dir.GetTargetPosition(),this.transform.position);
            if (isMoving)
            {
                chController.Move(transform.forward * moveSpeed * Time.deltaTime);
                // 3播放运动动画  
                chAnim.PlayAnimation("run");
            }
            else
            {
                chAnim.PlayAnimation("idle");
            }

            // 如果在跳跃状态,并且当前时间没有到达跳跃时间,则持续向上移动如果到达跳跃时间,那么持续下降直到遇到地面
            if (isJump)
            {
                if (jumpTimeFlag < jumpTime)
                {
                    chController.Move(transform.up * jumpSpeed * Time.deltaTime);
                    jumpTimeFlag += Time.deltaTime;
                }
                else if (jumpTime < jumpTimeFlag)
                {
                    chController.Move(transform.up * -gravity * Time.deltaTime);
                }

                if (chController.collisionFlags == CollisionFlags.Below)
                {
                    jumpTimeFlag = 0;
                    isJump = false;
                }
            }
        }
    }
}

在Character文件夹添加一个新脚本CharacterAnimation,代码如下:

using UnityEngine;

namespace ARPGFinish.Character
{
    /// <summary>
    /// 角色动画系统
    /// </summary>
    public class CharacterAnimation : MonoBehaviour
    {
        /// <summary>
        /// 动画组件
        /// </summary>
        private Animator anim;

        /// <summary>
        /// 上一个播放的动画
        /// </summary>
        string preAnimName = "idle";

        private void Start()
        {
            anim = GetComponentInChildren<Animator>();
        }

        /// <summary>
        /// 播放动画
        /// 结束上一个动画,播放当前动画
        /// </summary>
        /// <param name="animName">需要播放的动画名称</param>
        public void PlayAnimation(string animName)
        {
            Debug.Log("========" + animName);
            // 结束上一个动画
            anim.SetBool(preAnimName, false);
            // 开始新的动画
            anim.SetBool(animName, true);
            // 将当前动画设为上一个动画
            preAnimName = animName;
        }
    }
}

将新脚本拖拽到Player中。
在这里插入图片描述

运行结果

请添加图片描述

关于场景和建模

由于本章节主要讲解Unity动画开发部分,所以建模以及动画的相关工作并为在此章节提及。如果有需要可以考虑在Asset Store中下载,或者在一些模型动画商城购买。


更多内容请查看总目录【Unity】Unity学习笔记目录整理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值