找回密码
 立即注册
查看: 303|回复: 0

unity character control

[复制链接]
发表于 2022-10-23 16:42 | 显示全部楼层 |阅读模式
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第三人称角色控制
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-17 14:39 , Processed in 0.115712 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表