using UnityEngine; using System.Collections; using UnityEngine.InputSystem; namespace RootMotion { public class CameraController : MonoBehaviour { [System.Serializable] public enum UpdateMode { Update, FixedUpdate, LateUpdate, FixedLateUpdate } public Transform target; // The target Transform to follow //public Transform rotationSpace; // If assigned, will use this Transform's rotation as the rotation space instead of the world space. Useful with spherical planets. public UpdateMode updateMode = UpdateMode.LateUpdate; // When to update the camera? public bool lockCursor = true; // If true, the mouse will be locked to screen center and hidden [Header("Position")] public bool smoothFollow; // If > 0, camera will smoothly interpolate towards the target public float followSpeed = 10f; // Smooth follow speed [Header("Rotation")] public float rotationSensitivity = 3.5f; // The sensitivity of rotation public float yMinLimit = -20; // Min vertical angle public float yMaxLimit = 80; // Max vertical angle public bool rotateAlways = true; // Always rotate to mouse? [Header("Distance")] public float distance = 10.0f; // The current distance to target public float minDistance = 4; // The minimum distance to target public float maxDistance = 10; // The maximum distance to target public float zoomSpeed = 10f; // The speed of interpolating the distance public float zoomSensitivity = 1f; // The sensitivity of mouse zoom [Header("Blocking")] public LayerMask blockingLayers; public float blockingRadius = 1f; public float blockingSmoothTime = 0.1f; public float blockingOriginOffset; public float x { get; private set; } // The current x rotation of the camera public float y { get; private set; } // The current y rotation of the camera public float distanceTarget { get; private set; } // Get/set distance private Vector3 targetDistance, position; private Quaternion rotation = Quaternion.identity; private Vector3 smoothPosition; private Camera cam; private bool fixedFrame; private float fixedDeltaTime; private Quaternion r = Quaternion.identity; private Vector3 lastUp; //Rotation public void SetAngles(Quaternion rotation) { Vector3 euler = rotation.eulerAngles; this.x = euler.y; this.y = euler.x; } public void SetAngles(float yaw, float pitch) { this.x = yaw; this.y = pitch; } // Initiate, set the params to the current transformation of the camera relative to the target protected virtual void Awake() { //Vector3 angles = transform.eulerAngles; //x = angles.y; //y = angles.x; distanceTarget = distance; smoothPosition = transform.position; cam = GetComponent(); } protected virtual void Update() { if (updateMode == UpdateMode.Update) UpdateTransform(); } protected virtual void FixedUpdate() { fixedFrame = true; fixedDeltaTime += Time.deltaTime; if (updateMode == UpdateMode.FixedUpdate) UpdateTransform(); } protected virtual void LateUpdate() { UpdateInput(); if (updateMode == UpdateMode.LateUpdate) UpdateTransform(); if (updateMode == UpdateMode.FixedLateUpdate && fixedFrame) { UpdateTransform(fixedDeltaTime); fixedDeltaTime = 0f; fixedFrame = false; } } // Read the user input public void UpdateInput() { if (!cam.enabled) return; // Cursors Cursor.lockState = lockCursor ? CursorLockMode.Locked : CursorLockMode.None; Cursor.visible = lockCursor ? false : true; // Should we rotate the camera? bool rotate = rotateAlways; // delta rotation if (rotate) { // var _pass = _rotate.Player.CameraRotation.ReadValue(); //x += _pass.normalized.x; //y = ClampAngle(y +_pass.normalized.y * rotationSensitivity, yMinLimit, yMaxLimit); } // Distance distanceTarget = Mathf.Clamp(distanceTarget + zoomAdd, minDistance, maxDistance); } // Update the camera transform public void UpdateTransform() { UpdateTransform(Time.deltaTime); } public void UpdateTransform(float deltaTime) { if (!cam.enabled) return; // Rotation //rotation = Quaternion.AngleAxis(x, Vector3.up) * Quaternion.AngleAxis(y, Vector3.right); if (target != null) { // Distance distance += (distanceTarget - distance) * zoomSpeed * deltaTime; } //transform.rotation = rotation; } // Zoom input private float zoomAdd { get { float scrollAxis = Input.GetAxis("Mouse ScrollWheel"); if (scrollAxis > 0) return -zoomSensitivity; if (scrollAxis < 0) return zoomSensitivity; return 0; } } // Clamping Euler angles private float ClampAngle(float angle, float min, float max) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp(angle, min, max); } } }