Unity第三人称人物(含人物骨架)移动+镜头移动&跟随

1.先设定动画机。

 (已含添加的动画。右图三角形图标为动画:)

 将动画赋予给人物:

 添加摄影人物中心的摄像头,用空物体与固定位置的摄像头,树级关系如下:

 CameraCentre挂载ThirdPersonCamera.cs, Keqing挂载CharacterMovement.cs。

脚本如下:

ThirdPersonCamera.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ThirdPersonCamera : MonoBehaviour
{


    public float Pitch { get; private set; }
    public float Yaw { get; private set; }
    public Quaternion eulerAngle;
    public float CameraSensitivity = 3;

    // Start is called before the first frame update
    void Start(){}
    // Update is called once per frame
    void Update()
    {
        CameraRotation();
    }
    private void CameraRotation()
    {
        Pitch += Input.GetAxis("Mouse Y") * CameraSensitivity;
        Yaw += Input.GetAxis("Mouse X") * CameraSensitivity;

        Pitch = Mathf.Clamp(Pitch, -90, 90);

        eulerAngle = Quaternion.Euler(Pitch, Yaw, 0);
        transform.eulerAngles = new Vector3(Pitch, Yaw, 0);
        transform.rotation = eulerAngle;
    }
}

CharacterMovement.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CharacterController))]
public class CharacterMovement : MonoBehaviour
{
    [SerializeField]
    private ThirdPersonCamera _CameraCentre;

    private Rigidbody _CharacterRigidBody;
    private Animator _Animator;
    private CharacterController _Controller;

    public float Speed = 5.0f;
    public float TurnSpeed = 10.0f;
    public float turnSmoothTime = 0.1f;
    private Vector3 SpeedVector;



    private void Awake()
    {
        _CharacterRigidBody = GetComponent<Rigidbody>();
        _Animator = GetComponent<Animator>();
        _Controller = GetComponent<CharacterController>();
    }

    /// <summary>
    /// Start is called before the first frame update;
    /// Initialising every status in game.
    /// </summary>
    private void Start()
    {
        _CharacterRigidBody.rotation = Quaternion.Euler(0f, 0f, 0f);
    }
    /// <summary>
    /// For Physical animation update simulation.
    /// </summary>
    private void FixedUpdate()
    {
        float xMove = Input.GetAxis("Horizontal");
        float zMove = Input.GetAxis("Vertical");
        SpeedVector = new Vector3(xMove, 0, zMove).normalized;
        Debug.Log("SpeedVector:" + SpeedVector);



        if (SpeedVector.magnitude >= 0.01f)
        {
            float targetAngle = Mathf.Atan2(SpeedVector.x, SpeedVector.z) * Mathf.Rad2Deg + _CameraCentre.transform.eulerAngles.y;
            //Debug.Log("Mathf.Atan2:" + Mathf.Atan2(SpeedVector.x, SpeedVector.z));
            //Debug.Log("Mathf.Atan2*Math.Rad2Deg:" + Mathf.Atan2(SpeedVector.x, SpeedVector.z) * Mathf.Rad2Deg);
            //Debug.Log("CameraCentre.transform.eulerAngles.y:" + _CameraCentre.transform.eulerAngles.y);
            //Debug.Log("targetAngle:" + targetAngle);
            
            

            float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref TurnSpeed, turnSmoothTime);
            //Debug.Log("transform.eulerAngles.y" + transform.eulerAngles.y);



            //Debug.Log(angle);
            //Debug.Log("RigidBody.rotation(Before rotating):" + _CharacterRigidBody.rotation.eulerAngles);
            //_CharacterRigidBody.rotation = Quaternion.Euler(0f, angle, 0f);
            //Not rotate smoothly

            //_CharacterRigidBody.MoveRotation(_CharacterRigidBody.rotation * Quaternion.Euler(0f, angle, 0f));
            //After the first mouseY moving, angle is changing all the time
            //Camera.tramsform.eulerAngle.y returns a digit if the camera is not in its first place,
            //which means once camera rotates, Camera.tramsform.eulerAngle.y returns a digit consistently
            //if if statement is true, targetAngle keeps return value.


            _CharacterRigidBody.MoveRotation(Quaternion.Euler(0f, angle, 0f));
            //Debug.Log("RigidBody.rotation(After rotating):" + _CharacterRigidBody.rotation.eulerAngles);


            Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
            //Debug.Log("moveDir:" + moveDir);
            
            _Controller.Move(moveDir.normalized * Speed * Time.fixedDeltaTime);



        }

        AnimatorUpdate();
    }
    private void AnimatorUpdate()
    {
        _Animator.SetFloat("Speed", SpeedVector.magnitude);
    }
}


版权声明:本文为m0_51085115原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。