using UnityEngine; using UnityEngine.InputSystem; public class FreeCam : MonoBehaviour { [Header("Controls")] public float moveSpeed = 10f; public bool ghost = true; [Header("Sensitivity")] public float XAxisSensitivity = 30f; public float YAxisSensitivity = 30f; [Space] [Range(0, 89)] public float MaxXAngle = 60f; // privates private Vector2 _inputMouse; private Vector2 _velocity; private CharacterController _controller; private float _rotationX; private void Start() { // TODO remove - doesn't belong here - test only Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; _inputMouse = Vector2.zero; _velocity = Vector2.zero; _controller = gameObject.GetComponent(); _rotationX = 0; } // Update is called once per frame // TODO test if checking (input values = 0) to avoid calculus reduces CPU usage private void Update() { float rotationHorizontal = _inputMouse.x * XAxisSensitivity * Time.deltaTime; float rotationVertical = _inputMouse.y * YAxisSensitivity * Time.deltaTime; // always rotate Y in global world space to avoid gimbal lock transform.Rotate(Vector3.up * rotationHorizontal, Space.World); float rotationY = transform.localEulerAngles.y; _rotationX += rotationVertical; _rotationX = Mathf.Clamp(_rotationX, -MaxXAngle, MaxXAngle); transform.localEulerAngles = new Vector3(-_rotationX, rotationY, 0); float translationX = _velocity.x * moveSpeed * Time.deltaTime; float translationZ = _velocity.y * moveSpeed * Time.deltaTime; Vector3 _move = new Vector3(translationX, 0f, translationZ); // ghost directly moves transform. non-ghost uses CharacterController collision detection if (ghost) { transform.Translate(_move); } else { _move = transform.TransformVector(_move); _controller.Move(_move); } } public void OnLook(InputValue value) { Vector2 valueAsVector2 = value.Get(); _inputMouse.x = valueAsVector2.x; _inputMouse.y = valueAsVector2.y; } public void OnMovement(InputValue value) { Vector2 valueAsVector2 = value.Get(); _velocity.x = valueAsVector2.x; _velocity.y = valueAsVector2.y; } }