一、准备阶段-1-角色的控制(简单版_V1.0)

前言:这个阶段准备写一个角色状态机,而在写角色状态机的时候,我准备从最简单的操作物体的移动旋转开始。紧接着梳理一下层、Tag和碰撞的知识点,进而再实现角色状态机。

实现简单的角色控制:
一、使角色始终紧贴地面。。
二、点击鼠标左键,获取目标位置。
三、控制角色移动和有过渡动画的转向。

详细步骤如下:
1.首先我们在角色绑定上脚本:

2.定义属性:

    /// <summary>
    /// 角色移动速度
    /// </summary>
    [SerializeField]
    private float m_Speed = 10.0f;

    /// <summary>
    /// 角色移动目标位置
    /// </summary>
    private Vector3 m_TargetPos = Vector3.zero;

    /// <summary>
    /// 角色转向(四元数)
    /// </summary>
    private Quaternion m_DirectionQua;

    /// <summary>
    /// 角色转向速度
    /// </summary>
    private float m_RotationSpeed = 0.0f;

    /// <summary>
    /// 角色完成转向
    /// </summary>
    private bool m_RotationOver = false;

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

3.使角色紧贴地面并且获得目标位置(以下代码片段写在Update里面):

        //1.让角色始终贴紧地面
        if (!m_CharacterController.isGrounded)
        {
            m_CharacterController.Move((transform.position + new Vector3(0.0f, -1000.0f, 0.0f)) - transform.position);
        }

        //2.点击鼠标左键 获得目标位置
        if (Input.GetMouseButtonUp(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hitInfo;
            if (Physics.Raycast(ray, out hitInfo))
            {
                if (hitInfo.collider.gameObject.name.Equals("Ground", System.StringComparison.CurrentCultureIgnoreCase))
                {
                    m_TargetPos = hitInfo.point;
                    m_RotationOver = false;
                    m_RotationSpeed = 0.0f;
                }
            }
        }

4.使角色转向和移动(同样写在Update里面):

//3.根据目标位置和当前位置判断 是否应该移动和转向
        if (m_TargetPos != Vector3.zero)
        {
            if (Vector3.Distance(m_TargetPos, transform.position) > 0.1f)
            {
                Vector3 direction = m_TargetPos - transform.position;
                direction = direction.normalized;
                direction.y = 0.0f;

                //1.转向
                if (!m_RotationOver)
                {
                    m_RotationSpeed += 5.0f;
                    m_DirectionQua = Quaternion.LookRotation(direction);
                    transform.rotation = Quaternion.Lerp(transform.rotation, m_DirectionQua, m_RotationSpeed * Time.deltaTime);
                    if (Quaternion.Angle(transform.rotation, m_DirectionQua) < 0.1f)
                    {
                        m_RotationOver = true;
                        m_RotationSpeed = 1.0f;
                    }
                }

                //2.移动
                m_CharacterController.Move(direction * m_Speed * Time.deltaTime);
            }
        }

5.完整的代码如下:

public class RoleCtrl_Study : MonoBehaviour 
{
    /// <summary>
    /// 角色移动速度
    /// </summary>
    [SerializeField]
    private float m_Speed = 10.0f;

    /// <summary>
    /// 角色移动目标位置
    /// </summary>
    private Vector3 m_TargetPos = Vector3.zero;

    /// <summary>
    /// 角色转向(四元数)
    /// </summary>
    private Quaternion m_DirectionQua;

    /// <summary>
    /// 角色转向速度
    /// </summary>
    private float m_RotationSpeed = 0.0f;

    /// <summary>
    /// 角色完成转向
    /// </summary>
    private bool m_RotationOver = false;

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

    private void Start()
    {
        m_CharacterController = transform.GetComponent<CharacterController>();
    }

    private void Update()
    {
        //1.让角色始终贴紧地面
        if (!m_CharacterController.isGrounded)
        {
            m_CharacterController.Move((transform.position + new Vector3(0.0f, -1000.0f, 0.0f)) - transform.position);
        }

        //2.点击鼠标左键 获得目标位置
        if (Input.GetMouseButtonUp(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hitInfo;
            if (Physics.Raycast(ray, out hitInfo))
            {
                if (hitInfo.collider.gameObject.name.Equals("Ground", System.StringComparison.CurrentCultureIgnoreCase))
                {
                    m_TargetPos = hitInfo.point;
                    m_RotationOver = false;
                    m_RotationSpeed = 0.0f;
                }
            }
        }

        //3.根据目标位置和当前位置判断 是否应该移动和转向
        if (m_TargetPos != Vector3.zero)
        {
            if (Vector3.Distance(m_TargetPos, transform.position) > 0.1f)
            {
                Vector3 direction = m_TargetPos - transform.position;
                direction = direction.normalized;
                direction.y = 0.0f;

                //1.转向
                if (!m_RotationOver)
                {
                    m_RotationSpeed += 5.0f;
                    m_DirectionQua = Quaternion.LookRotation(direction);
                    transform.rotation = Quaternion.Lerp(transform.rotation, m_DirectionQua, m_RotationSpeed * Time.deltaTime);
                    if (Quaternion.Angle(transform.rotation, m_DirectionQua) < 0.1f)
                    {
                        m_RotationOver = true;
                        m_RotationSpeed = 1.0f;
                    }
                }

                //2.移动
                m_CharacterController.Move(direction * m_Speed * Time.deltaTime);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Dean272727/article/details/87857021
今日推荐