基于Character Controller的基本第三人称控制

1.准备工作

安装cinemachine

添加FreeLook Camera

找到合适的人物模型以及动画

添加Character Controller组件

2. MovementInput具体代码

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

//This script requires you to have setup your animator with 3 parameters, "InputMagnitude", "InputX", "InputZ"
//With a blend tree to control the inputmagnitude and allow blending between animations.
[RequireComponent(typeof(CharacterController))]
public class MovementInput : MonoBehaviour {

    public float Velocity;
    [Space]

    public float InputX;
    public float InputZ;
    public Vector3 desiredMoveDirection;
    public bool blockRotationPlayer;
    public float desiredRotationSpeed = 0.1f;
    public Animator anim;
    public float Speed;
    public float allowPlayerRotation = 0.1f;
    public Camera cam;
    public CharacterController controller;
    public bool isGrounded;

    [Header("Animation Smoothing")]
    [Range(0, 1f)]
    public float HorizontalAnimSmoothTime = 0.2f;
    [Range(0, 1f)]
    public float VerticalAnimTime = 0.2f;
    [Range(0,1f)]
    public float StartAnimTime = 0.3f;
    [Range(0, 1f)]
    public float StopAnimTime = 0.15f;

    private float verticalVel;
    private Vector3 moveVector;

    // Use this for initialization
    void Start () {
      anim = this.GetComponent<Animator> ();
      cam = Camera.main;
      controller = this.GetComponent<CharacterController> ();
    }
	
	// Update is called once per frame
	void Update () {
		InputMagnitude ();
        //跳跃相关
        //可能不太能处理复杂地形的情况
        //使用射线法能更好地跳跃
        /*
		//If you don't need the character grounded then get rid of this part.
		isGrounded = controller.isGrounded;
		if (isGrounded) {
			verticalVel -= 0;
		} else {
			verticalVel -= 2;
		}
		moveVector = new Vector3 (0, verticalVel, 0);
		controller.Move (moveVector);
        */
		//Updater
	}

    void PlayerMoveAndRotation() {
        var forward = cam.transform.forward;
	var right = cam.transform.right;

	forward.y = 0f;
	right.y = 0f;

	forward.Normalize ();
	right.Normalize ();
        //这才是实际我们想要地行动方向
        //以摄像机为基准
	desiredMoveDirection = forward * InputZ + right * InputX;

        if (blockRotationPlayer == false) 
        {
            transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(desiredMoveDirection), desiredRotationSpeed);
            controller.Move(desiredMoveDirection * Time.deltaTime * Velocity);
	}
    }

	//输入单位化
	void InputMagnitude() {
		//Calculate Input Vectors
		InputX = Input.GetAxis ("Horizontal");
		InputZ = Input.GetAxis ("Vertical");

		//anim.SetFloat ("InputZ", InputZ, VerticalAnimTime, Time.deltaTime * 2f);
		//anim.SetFloat ("InputX", InputX, HorizontalAnimSmoothTime, Time.deltaTime * 2f);

		//Calculate the Input Magnitude
		Speed = new Vector2(InputX, InputZ).sqrMagnitude;

		//物理性地移动角色
              //有这个判断能让角色忽略一些很小的旋转和移动
              //如果没有这个判断,会始终在移动后指向世界方向(0,0,0);
		if (Speed > allowPlayerRotation) {
			anim.SetFloat ("Blend", Speed, StartAnimTime, Time.deltaTime);
			PlayerMoveAndRotation ();
		} else if (Speed < allowPlayerRotation) {
			anim.SetFloat ("Blend", Speed, StopAnimTime, Time.deltaTime);
		}
	}
}

原文地址:https://www.cnblogs.com/linqd/p/15189906.html