zifa2003293 发表于 2022-10-23 16:42

unity character control

capsule collider和character controller会冲突,要能碰撞就得挂上                                       
rigidbody use gravity使用重力后,角色移动过程中有概率摔倒       
对比animancer与官方的animantor有点优势,demo版本官方animator不需要插件资源包资源就少多了。
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public enum PlayerState
{
    Moving,
    Idle,
}

public class CharacterControl : MonoBehaviour
{
    public GameObject effect_click_prefab;
    bool isMoving = false;
    Vector3 targetPosition = Vector3.zero;

    public float speed = 4;
    public PlayerState state = PlayerState.Idle;
    CharacterController controller;
    Animator animator;
    //AnimancerComponent animancer;
    //public AnimationClip _Idle;
    //public AnimationClip _Action;

    Transform m_Cam;

    // Start is called before the first frame update
    void Start()
    {
      targetPosition = transform.position;
      controller = GetComponent<CharacterController>();
      animator = GetComponent<Animator>();
      //animancer = GetComponent<AnimancerComponent>();
      m_Cam = Camera.main.transform;
    }

    // Update is called once per frame
    void Update()
    {
      DoRotateAndMoveByASDW(); //按键移动
      //DoRotateByMouseDown(); //按鼠标移动
      //DoMove();
    }

    private void LateUpdate()
    {
      if (state == PlayerState.Moving)
      {
            PlayAnim("run");
      }
      else if (state == PlayerState.Idle)
      {
            PlayAnim("idle");
      }
    }

    void PlayAnim(string animName)
    {
      int i = animName == "idle" ? 0 : 2;
      animator.SetFloat("test", i);
      //animancer.Play(animName == "idle" ? _Idle : _Action, 0.25f);
    }

    void ShowClickEffect(Vector3 hitPoint)
    {
      //hitPoint = new Vector3(hitPoint.x, hitPoint.y+0.1f, hitPoint.z);
      //GameObject.Instantiate(effect_click_prefab,hitPoint,Quaternion.identity);
    }

    void LookAtTarget(Vector3 hitPoint)
    {
      targetPosition = hitPoint;
      transform.LookAt(targetPosition);
    }

    void DoRotateAndMoveByASDW()
    {
      float h = CrossPlatformInputManager.GetAxis("Horizontal");
      float v = CrossPlatformInputManager.GetAxis("Vertical");
      Vector3 m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
      Vector3 m_Move = v * m_CamForward + h * m_Cam.right;
      if (m_Move.magnitude > 1f) m_Move.Normalize();
      m_Move = transform.InverseTransformDirection(m_Move);
      float m_TurnAmount = Mathf.Atan2(m_Move.x, m_Move.z);
      float m_ForwardAmount = m_Move.z;
      float turnSpeed = Mathf.Lerp(180, 360, m_ForwardAmount);
      transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);

      if (m_Move.x + m_Move.z > 0)
      {
            state = PlayerState.Moving;
            transform.Translate(new Vector3(m_Move.x, 0, m_Move.z) * Time.deltaTime * speed);
      }
      else
      {
            state = PlayerState.Idle;
      }
    }

    void DoRotateByMouseDown()
    {
      if (Input.GetMouseButtonDown(0))
      {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hitInfo;
            bool isCollider = Physics.Raycast(ray, out hitInfo);
            if (isCollider && hitInfo.collider.tag == "ground")
            {
                isMoving = true;
                ShowClickEffect(hitInfo.point); //显示点击特效
                LookAtTarget(hitInfo.point);
            }
      }

      if (Input.GetMouseButtonUp(0))
      {
            isMoving = false;
      }

      //鼠标长按继续移动
      if (isMoving)
      {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hitInfo;
            bool isCollider = Physics.Raycast(ray, out hitInfo);
            if (isCollider && hitInfo.collider.tag == "ground")
            {
                LookAtTarget(hitInfo.point);
            }
      }
    }

    void DoMove()
    {
      float distance = Vector3.Distance(targetPosition, transform.position);
      if (distance > 0.3f)
      {
            state = PlayerState.Moving;
            controller.SimpleMove(transform.forward * speed);
      }
      else
      {
            state = PlayerState.Idle;
      }
    }
}旋转用的官方资源包里的robot:unity第三人称角色控制
页: [1]
查看完整版本: unity character control