二、功能开发阶段-1-角色的控制(版本_V2.0)

前言:
目前我自己的项目做得有点混乱。以前在公司工作的时候,因为开发任务都是由上级派发下来的,派发什么任务就去做什么。所以当我一个人尝试着做独立项目的时候,竟然有一点毫无头绪。
这篇文章我将会总结一下简单的角色控制的代码,在实际的项目中,还应该引入FSM角色状态机去进一步的完善角色的控制。那么,接下来的开发任务就是:简单角色控制->摄像机控制->引入FSM。这三个功能完成后,我将进行UI底层框架的设计,接下来再完善策划需求,开发相应的UI界面。**

一、角色控制器的逻辑思想

1.角色控制器类型:第三人称角色控制器。
2.设计思想:鼠标控制镜头的方向,键盘(W/A/S/D)控制角色的移动。这里我们应该能确定的是,当玩家按下W键的时候,角色不应该只是朝着当前的forward方向进行移动,而是应该根据当前的角色的朝向(forward方向)和摄像的朝向,以及键盘的输入来先做旋转,再做移动。
在这里插入图片描述
3.动画控制器(AnimatorController):当前我们的角色只有站立和移动功能。

二、功能开发

1.AnimatorController相关:
a.创建AnimatorController,并且命名为“TestRoleAC”,需要的Paramters为:float类型的Speed,float类型的Direction。
b.创建一个子状态机,并且命名为NoWeaponLocomotion。
在这里插入图片描述
c.双击子状态机“NoWeaponLocomotion”,创建Idle和Run状态,并且设置相应的动画过渡条件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.角色控制

a.创建一个空物体(命名为“MainPlayerTest”)
b.然后将我们的角色模型拖到“MainPlayerTest”的下方(设置为子物体)。
c.再在“MainPlayerTest”上添加“Character Controller”组件和“AnimatorController”组件,并且把“Apply Root Motion”勾选上。
d.最后创建“Test_RoleCtrl”脚本,并且挂载在“MainPlayerTest”上。
在这里插入图片描述
e.“Test_RoleCtrl.cs”脚本的代码如下

public class Test_RoleCtrl : MonoBehaviour 
{
    /// <summary>
    /// 角色控制器
    /// </summary>
    private CharacterController m_CC;

    /// <summary>
    /// 角色的转身速度
    /// </summary>
    public float m_RotationSpeed = 10.0f;


    /// <summary>
    /// 角色的目标方向(四元数)
    /// </summary>
    private Quaternion m_TargetQuaternion;

    /// <summary>
    /// 是否完成转身
    /// </summary>
    private bool m_RotationOver = false;

    /// <summary>
    /// 角色动画状态机
    /// </summary>
    public Animator g_Animator;

    private void Awake()
    {
        m_CC = GetComponent<CharacterController>();
        g_Animator = GetComponent<Animator>();
    }

    private void Start()
    {
        Init();
    }

    private void Init()
    {
        transform.position = Vector3.zero;
    }

    private void Update()
    {
        if (m_CC == null)
        {
            return;
        }

        //让角色紧紧贴住地面(注意这里只是简单的把角色强行设置到地面上)
        if (!m_CC.isGrounded)
        {
            m_CC.Move((transform.position + new Vector3(0.0f, -500.0f, 0.0f)) - transform.position);
        }

        #region 角色控制部分
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        Vector3 inputDir = new Vector3(h, 0.0f, v);
        if (inputDir.magnitude > 0.0f)
        {
            //没有完成角色旋转
            m_RotationOver = false;
            Rotation(inputDir);
        }
        //播放Run动画
        g_Animator.SetFloat("Speed", inputDir.magnitude);

        #endregion
    }

    /// <summary>
    /// 角色的旋转
    /// </summary>
    /// <param name="dir"></param>
    private void Rotation(Vector3 dir)
    {
        //方法一 四元数版本:

        //*重点:表示将当前键盘输入dir旋转当前摄像机的旋转量,
        //其作用是将输入方向转换到以摄像机为基准的空间中,
        //这样我们就得到了一个新的向量,当前向量就表示为角色应当旋转到的朝向
        //CameraCtrl.Instance.CameraRotationY 这个是在相机的控制器中的代码 具体可以看相机部分的文章讲解
        Vector3 wantedDir = CameraCtrl.Instance.CameraRotationY.transform.localRotation * dir;
        wantedDir.y = 0;
        wantedDir.Normalize();
        if (!m_RotationOver)
        {
            m_TargetQuaternion = Quaternion.LookRotation(wantedDir);

            transform.rotation = Quaternion.Lerp(transform.rotation, m_TargetQuaternion, m_RotationSpeed * Time.deltaTime);
            if (Quaternion.Angle(transform.rotation, m_TargetQuaternion) < 1.0f)
            {
                m_RotationOver = true;
            }
        }

        //方法二 向量版本:
        //if (!m_RotationOver)
        //{
        //    transform.forward = Vector3.Lerp(transform.forward, wantedDir, m_RotationSpeed * Time.deltaTime);
        //    if (Vector3.Angle(transform.forward, wantedDir) < 1.0f)
        //    {
        //        m_RotationOver = true;
        //    }
        //}

        //实测情况是 当用第二版的时候,转向没有方法一自然,这里我还是比较推荐使用四元数去操作。
    }

}

总结:我们的角色控制的代码已经完成了,但是还有相机的代码没有去做,接下来,我们马上去做摄像机的控制(详见下一篇博客)

猜你喜欢

转载自blog.csdn.net/Dean272727/article/details/88898693