Newer
Older
Hierarchical-Task-Network-Unity-3D / Assets / Scripts / CameraMovement.cs
using UnityEngine;
using UnityEngine.InputSystem;

public class CameraMovement : MonoBehaviour
{
    [Header("Input")]
    [SerializeField] private InputActionAsset inputActions;

    private InputActionMap actionMap;
    private InputAction moveInputAction;
    private InputAction lookInputAction;
    private InputAction zoomInputAction;
    private InputAction rotateInputAction;
    private InputAction speedModifierAction;
    private InputAction verticalMoveInputAction;

    [Header("Movement Settings")]
    public float moveSpeed = 10f;
    public float fastSpeedMultiplier = 2f;
    public float zoomSpeed = 10f;
    public float rotationSpeed = 0.2f; // Sensitivity (not degrees per second)

    [Header("Pitch Clamp")]
    public float minPitch = -89f;
    public float maxPitch = 89f;

    private Vector2 moveInput;
    private Vector2 lookInput;
    private float zoomInput;
    private float verticalInput;
    private bool isRotating;

    private float yaw = 0f;
    private float pitch = 0f;

    private void Awake()
    {
        actionMap = inputActions.FindActionMap("Player");

        moveInputAction = actionMap.FindAction("Move");
        lookInputAction = actionMap.FindAction("Look");
        zoomInputAction = actionMap.FindAction("Zoom");
        rotateInputAction = actionMap.FindAction("Rotate");
        speedModifierAction = actionMap.FindAction("SpeedModifier");
        verticalMoveInputAction = actionMap.FindAction("VerticalMove");
    }

    private void OnEnable()
    {
        actionMap?.Enable();
        rotateInputAction.performed += ctx => isRotating = true;
        rotateInputAction.canceled += ctx => isRotating = false;

        // Initialize rotation state to match current camera orientation
        Vector3 euler = transform.eulerAngles;
        yaw = euler.y;
        pitch = euler.x;
    }

    private void OnDisable()
    {
        rotateInputAction.performed -= ctx => isRotating = true;
        rotateInputAction.canceled -= ctx => isRotating = false;
        actionMap?.Disable();
    }

    private void Update()
    {
        //Get input values
        moveInput = moveInputAction.ReadValue<Vector2>();
        lookInput = lookInputAction.ReadValue<Vector2>();
        zoomInput = zoomInputAction.ReadValue<float>();
        verticalInput = verticalMoveInputAction.ReadValue<float>();

        float speedMultiplier = speedModifierAction.IsPressed() ? fastSpeedMultiplier : 1f;

        if (isRotating)
            RotateCamera(lookInput);

        MoveCamera(moveInput, verticalInput, speedMultiplier);
        ZoomCamera(zoomInput);
    }

    private void RotateCamera(Vector2 mouseDelta)
    {
        yaw += mouseDelta.x * rotationSpeed;
        pitch -= mouseDelta.y * rotationSpeed;
        pitch = Mathf.Clamp(pitch, minPitch, maxPitch);

        transform.rotation = Quaternion.Euler(pitch, yaw, 0f);
    }

    private void MoveCamera(Vector2 input, float vertical, float speedMultiplier)
    {
        Vector3 direction = transform.forward * input.y + transform.right * input.x + transform.up * vertical;
        transform.position += direction * moveSpeed * speedMultiplier * Time.deltaTime;
    }

    private void ZoomCamera(float scroll)
    {
        if (Mathf.Abs(scroll) > 0.01f)
        {
            transform.position += transform.forward * scroll * zoomSpeed * Time.deltaTime;
        }
    }
}