明天实现的内容:
鼠标输出
在没有引入手柄操作前,将由鼠标来管制摄像机旋转,首先咱们要获取到鼠标输出。

public class PlayerInput : MonoBehaviour{    // 摄像机管制轴    public string cameraAxisX;    public string cameraAxisY;    // 摄像机管制信号    public float cameraUp;    public float cameraRight;    // ...        void Update()    {        // 摄像机信号        cameraUp = Input.GetAxis(cameraAxisY);        cameraRight = Input.GetAxis(cameraAxisX);        // ...    }}

摄像机方案设计
老师的计划为,将摄像机挂载到游戏对象下作为子物体,同时在摄像机的上一级增加一个新对象CameraHandle作为摄像机的父物体。如果咱们要旋转,就要旋转整个玩家的游戏对象,高低旋转只须要旋转CameraHandle就行了。
这是新增脚本CameraController ,挂载到Camera上。

using System.Collections;using System.Collections.Generic;using UnityEngine;public class CameraController : MonoBehaviour{    // 灵敏度    public float horizontalSensitivity;    public float verticalSensitivity;    // 输出模块    public PlayerInput pi;    // PlayerController游戏对象    private GameObject playerHandle;    // CameraHandle游戏对象    private GameObject cameraHandle;    // 用于存储CameraHandle的欧拉角X值    private float temp_eulerX;    void Awake()    {        cameraHandle = transform.parent.gameObject;        playerHandle = cameraHandle.transform.parent.gameObject;        pi = playerHandle.GetComponent<PlayerInput>();    }    // Update is called once per frame    void Update()    {        // 左右旋转时旋转PlayerHandle        playerHandle.transform.Rotate(Vector3.up, pi.cameraRight * horizontalSensitivity * Time.deltaTime);        // 高低旋转时旋转CameraHandle        temp_eulerX -= pi.cameraUp * verticalSensitivity * Time.deltaTime;        // 限度俯仰角        temp_eulerX = Mathf.Clamp(temp_eulerX, -40, 30);        // 赋值localEulerAngles        cameraHandle.transform.localEulerAngles = new Vector3(temp_eulerX , 0, 0);                }}

旋转摄像机时的角色模型管制
当摄像机旋转时,角色模型不要跟着旋转。方法很简略,将模型在摄像机旋转前的欧拉角保留下来,在摄像机旋转后再将之前保留的欧拉角赋值回去就行了。所以这两个操作的地位千万别弄错。

    // 角色模型游戏对象    private GameObject model;    void Awake()    {        // ...        model = playerHandle.GetComponent<PlayerController>().model;    }    // Update is called once per frame    void Update()    {        // 失去摄像机旋转前的模型欧拉角        Vector3 temp_modelEuler = model.transform.eulerAngles;        // 摄像机旋转...                // 摄像机旋转后将模型原来的欧拉角再赋给模型        model.transform.eulerAngles = temp_modelEuler;    }

当你这样做当前,会有一个惊喜发现,当你转动摄像机而不挪动角色时,模型不会动,而当你挪动时,模型会主动旋转到摄像机的朝向。起因是因为当你旋转摄像机时,PlayerController游戏对象也进行了旋转,这时整个玩家的后方曾经变了。当挪动时,会执行旋转代码,这时咱们往前走,后方就是摄像机的朝向。所以模型会转到摄像机的朝向。
留神上面代码的dirVec为依据PlayerController游戏对象的方向失去的玩家挪动方向,所以后方是PlayerController的后方。当旋转摄像机时,实际上是旋转PlayerController对象,而后摄像机跟着旋转。

        // 计算玩家的方向 这个transform.forward是PlayerInput挂载的游戏对象,也就是PlayerController的transform.forward        // 所以dirVec失去的是以PlayerController的transform.forward为后方的方向        dirVec = m_dirAxis.x * transform.right + m_dirAxis.y * transform.forward;        // ...        // 只在有速度时可能旋转 避免原地旋转        if (pi.dirMag > 0.1f)        {            // 使用旋转 应用Slerp进行成果优化               model.transform.forward = Vector3.Slerp(model.transform.forward, pi.dirVec, 0.3f);        }

摄像机提早挪动
为了更好的视觉效果,咱们经常心愿摄像机能绝对于角色的挪动有一个提早挪动。要实现这种成果,首先咱们在摄像机下级再增加一个父对象CameraPos,用来作为摄像机的地位。好了,当初Camera是不是PlayerController的游戏对象都能够了。然而CameraController脚本要挂载到CameraPos身上了。

当初,咱们要在CameraController中获取到Camera游戏对象,再通过CameraPos的地位信息来管制Camera游戏对象的地位。

        // 摄像机游戏对象的挪动和旋转        camera.transform.eulerAngles = this.transform.eulerAngles;        // 摄像机的地位通过Lerp来实现一种提早挪动的成果        camera.transform.position = Vector3.SmoothDamp(            camera.transform.position, this.transform.position, ref temp_dampValue, 0.1f);