using UnityEngine; [RequireComponent(typeof(CharacterController))] public class CameraController : MonoBehaviour { public Transform target; private void Reset() { target = transform; } class CameraState { public float yaw; public float pitch; public float roll; public float x; public float y; public float z; public void SetFromTransform(Transform t) { pitch = t.eulerAngles.x; yaw = t.eulerAngles.y; roll = t.eulerAngles.z; x = t.position.x; y = t.position.y; z = t.position.z; } public void Translate(Vector3 translation) { Vector3 rotatedTranslation = Quaternion.Euler(pitch, yaw, roll) * translation; x += rotatedTranslation.x; y += rotatedTranslation.y; z += rotatedTranslation.z; } public void LerpTowards(CameraState target, float positionLerpPct, float rotationLerpPct) { yaw = Mathf.Lerp(yaw, target.yaw, rotationLerpPct); pitch = Mathf.Lerp(pitch, target.pitch, rotationLerpPct); roll = Mathf.Lerp(roll, target.roll, rotationLerpPct); x = Mathf.Lerp(x, target.x, positionLerpPct); y = Mathf.Lerp(y, target.y, positionLerpPct); z = Mathf.Lerp(z, target.z, positionLerpPct); } public void UpdateTransform(Transform t) { t.eulerAngles = new Vector3(pitch, yaw, roll); //t.position = new Vector3(x, y, z); } } CameraState m_TargetCameraState = new CameraState(); CameraState m_InterpolatingCameraState = new CameraState(); public float boost = 3.5f; public float positionLerpTime = 0.2f; public AnimationCurve mouseSensitivityCurve = new AnimationCurve(new Keyframe(0f, 0.5f, 0f, 5f), new Keyframe(1f, 2.5f, 0f, 0f)); public float rotationLerpTime = 0.01f; public bool invertY = false; private CharacterController ctrlor; private void Start() { ctrlor = GetComponent(); } void OnEnable() { m_TargetCameraState.SetFromTransform(target.transform); m_InterpolatingCameraState.SetFromTransform(target.transform); } Vector3 GetInputTranslationDirection() { Vector3 direction = new Vector3(); if (Input.GetKey(KeyCode.W)) { direction += target.transform.TransformDirection(Vector3.forward); } if (Input.GetKey(KeyCode.S)) { direction += target.transform.TransformDirection(Vector3.back); } if (Input.GetKey(KeyCode.A)) { direction += target.transform.TransformDirection(Vector3.left); } if (Input.GetKey(KeyCode.D)) { direction += target.transform.TransformDirection(Vector3.right); } if (Input.GetKey(KeyCode.Q)) { direction += target.transform.TransformDirection(Vector3.down); } if (Input.GetKey(KeyCode.E)) { direction += target.transform.TransformDirection(Vector3.up); } return direction; } public bool allowMove; public bool allowRotate; void FixedUpdate() { //if (Input.GetMouseButtonDown(1)) //{ // Cursor.lockState = CursorLockMode.Locked; //} //if (Input.GetMouseButtonUp(1)) //{ // Cursor.visible = true; // Cursor.lockState = CursorLockMode.None; //} if (allowRotate) { if (Input.GetMouseButton(1)) { var mouseMovement = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y") * (invertY ? 1 : -1)); var mouseSensitivityFactor = mouseSensitivityCurve.Evaluate(mouseMovement.magnitude); m_TargetCameraState.yaw += mouseMovement.x * mouseSensitivityFactor; m_TargetCameraState.pitch += mouseMovement.y * mouseSensitivityFactor; } } var translation = new Vector3(); if (allowMove == true) { translation = GetInputTranslationDirection() * Time.deltaTime; } //if (Input.GetKey(KeyCode.LeftShift)) //{ // translation *= 1.2f; //} //boost += Input.mouseScrollDelta.y * 0.2f; // translation *= Mathf.Pow(2.0f, boost); translation *= boost; m_TargetCameraState.Translate(translation); var positionLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / positionLerpTime) * Time.deltaTime); var rotationLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / rotationLerpTime) * Time.deltaTime); ctrlor.Move(translation); m_InterpolatingCameraState.LerpTowards(m_TargetCameraState, positionLerpPct, rotationLerpPct); m_InterpolatingCameraState.UpdateTransform(target.transform); } }