From fc78d599a8c02888f36149331127d0194ed6078a Mon Sep 17 00:00:00 2001 From: Trey Shaw Date: Tue, 21 Jul 2026 21:13:43 -0500 Subject: [PATCH] better cam controls --- Assets/Scenes/World_Greaybox.unity | 38 ++++- Assets/Scripts/Management/CameraController.cs | 135 +++++++++++++++++- Assets/Scripts/Management/PlayerController.cs | 86 +++++------ 3 files changed, 216 insertions(+), 43 deletions(-) diff --git a/Assets/Scenes/World_Greaybox.unity b/Assets/Scenes/World_Greaybox.unity index e37ebbc..8d098cb 100644 --- a/Assets/Scenes/World_Greaybox.unity +++ b/Assets/Scenes/World_Greaybox.unity @@ -1069,9 +1069,33 @@ PrefabInstance: propertyPath: m_LocalScale.y value: 2.41278 objectReference: {fileID: 0} + - target: {fileID: 5478143440182735446, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: maxDistance + value: 4 + objectReference: {fileID: 0} + - target: {fileID: 5478143440182735446, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: rotationSpeed + value: 1000 + objectReference: {fileID: 0} + - target: {fileID: 5478143440182735446, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: targetOffset.y + value: 0.15 + objectReference: {fileID: 0} + - target: {fileID: 5478143440182735446, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: collisionOffset + value: 0.5 + objectReference: {fileID: 0} - target: {fileID: 5478143440182735446, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} propertyPath: collisionRadius - value: 0.01 + value: 0.3 + objectReference: {fileID: 0} + - target: {fileID: 5478143440182735446, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: collisionLayers.m_Bits + value: 8 + objectReference: {fileID: 0} + - target: {fileID: 5478143440182735446, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: obstructionMask.m_Bits + value: 12 objectReference: {fileID: 0} - target: {fileID: 5526037850913171920, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} propertyPath: m_LocalPosition.x @@ -1113,6 +1137,18 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 6872729306491234319, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: m_LocalRotation.w + value: 0.7071068 + objectReference: {fileID: 0} + - target: {fileID: 6872729306491234319, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: m_LocalRotation.y + value: 0.7071068 + objectReference: {fileID: 0} + - target: {fileID: 6872729306491234319, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 90 + objectReference: {fileID: 0} - target: {fileID: 8111368525007731252, guid: 0fd9b22e9158e474a96c42de5ee0d85f, type: 3} propertyPath: m_Height value: 2.67 diff --git a/Assets/Scripts/Management/CameraController.cs b/Assets/Scripts/Management/CameraController.cs index 7dc9ce0..b02303d 100644 --- a/Assets/Scripts/Management/CameraController.cs +++ b/Assets/Scripts/Management/CameraController.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Unity.VisualScripting; +using UnityEditor.Rendering; using UnityEngine; using UnityEngine.UIElements; using static Unity.Cinemachine.CinemachineTargetGroup; @@ -8,7 +9,137 @@ public class CameraController : MonoBehaviour { - public float camTargetRotation { get; private set; } = 0; + [Header("Target")] + [SerializeField] private Transform target; + [SerializeField] private Vector3 targetOffset = new Vector3(0f, 1.5f, 0f); + public Camera MainCamera; + public Transform playerCamHome; + + [Header("Orbit")] + [SerializeField] private float distance = 5f; + [SerializeField] private float minDistance = 1f; + [SerializeField] private float maxDistance = 8f; + [SerializeField] private float rotationSpeed = 180f; + [SerializeField] private float rotationOffset = 270f; + [SerializeField] private float minPitch = -30f; + [SerializeField] private float maxPitch = 75f; + + [Header("Zoom")] + [SerializeField] private float zoomSpeed = 2f; + [SerializeField] private float zoomSmoothness = 10f; + + [Header("Camera Collision")] + [SerializeField] private LayerMask collisionLayers; + [SerializeField] private float collisionRadius = 0.25f; + [SerializeField] private float collisionOffset = 0.1f; + [SerializeField] private float positionSmoothness = 15f; + + private float yaw; + private float pitch = 20f; + private float targetDistance; + private Vector3 currentVelocity; + + public Vector3 Forward + { + get + { + Vector3 forward = MainCamera.transform.forward; + forward.y = 0f; + return forward.normalized; + } + } + public Vector3 Right + { + get + { + Vector3 right = MainCamera.transform.right; + right.y = 0f; + return right.normalized; + } + } + + private void Start() + { + targetDistance = distance; + + Vector3 startingAngles = MainCamera.transform.eulerAngles; + yaw = startingAngles.y + rotationOffset; + pitch = startingAngles.x; + + if (pitch > 180f) + { + pitch -= 360f; + } + } + + private void LateUpdate() + { + if (target == null) + { + if (GameManager.Instance.PlayerController.DougBody != null) + target = GameManager.Instance.PlayerController.DougBody.transform; + else + return; + } + + HandleRotation(); + HandleZoom(); + UpdateCameraPosition(); + } + + private void HandleRotation() + { + if (!Input.GetMouseButton(1)) + { + UnityEngine.Cursor.visible = true; + UnityEngine.Cursor.lockState = CursorLockMode.None; + return; + } + else + { + UnityEngine.Cursor.visible = false; + UnityEngine.Cursor.lockState = CursorLockMode.Locked; + } + + yaw += Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime; + pitch -= Input.GetAxis("Mouse Y") * rotationSpeed * Time.deltaTime; + + pitch = Mathf.Clamp(pitch, minPitch, maxPitch); + } + + private void HandleZoom() + { + float scrollInput = Input.GetAxis("Mouse ScrollWheel"); + + targetDistance -= scrollInput * zoomSpeed; + targetDistance = Mathf.Clamp(targetDistance, minDistance, maxDistance); + + distance = Mathf.Lerp(distance, targetDistance, zoomSmoothness * Time.deltaTime); + } + + private void UpdateCameraPosition() + { + Vector3 targetPosition = target.position + targetOffset; + + Quaternion orbitRotation = Quaternion.Euler(pitch, yaw, 0f); + + Vector3 desiredDirection = orbitRotation * Vector3.back; + Vector3 desiredPosition = targetPosition + desiredDirection * distance; + + float correctedDistance = distance; + + if (Physics.SphereCast(targetPosition, collisionRadius, desiredDirection, out RaycastHit hit, distance, collisionLayers, QueryTriggerInteraction.Ignore)) + { + correctedDistance = Mathf.Max(minDistance, hit.distance - collisionOffset); + } + + Vector3 finalPosition = targetPosition + desiredDirection * correctedDistance; + + MainCamera.transform.position = Vector3.SmoothDamp(MainCamera.transform.position, finalPosition, ref currentVelocity, 1f / positionSmoothness); + + MainCamera.transform.rotation = Quaternion.LookRotation(targetPosition - MainCamera.transform.position, Vector3.up); } + + /*public float camTargetRotation { get; private set; } = 0; public CameraControlMode CamControlMode { get; private set; } = CameraControlMode.SnapRotate; public Camera MainCamera; @@ -342,7 +473,7 @@ void UpdateFade() targetAlpha.Remove(r); } } - } + }*/ } public enum CameraControlMode diff --git a/Assets/Scripts/Management/PlayerController.cs b/Assets/Scripts/Management/PlayerController.cs index 83b0635..082dc28 100644 --- a/Assets/Scripts/Management/PlayerController.cs +++ b/Assets/Scripts/Management/PlayerController.cs @@ -149,17 +149,9 @@ void ApplyWalk() verticalMovement = Input.GetAxisRaw("Vertical"); horizontalMovement = Input.GetAxisRaw("Horizontal"); } + Vector3 input = Vector3.ClampMagnitude(new Vector3(horizontalMovement, 0f, verticalMovement), 1f); - moveDir = new Vector3(horizontalMovement, 0, verticalMovement).normalized; - - if (cameraController != null) - { - // re-matrix the rotation direction so movement is consistent no matter what - // the camera rotation is - - Matrix4x4 matrix = Matrix4x4.Rotate(Quaternion.Euler(0, cameraController.playerCamHome.rotation.eulerAngles.y, 0)); - moveDir = matrix.MultiplyPoint3x4(moveDir); - } + moveDir = cameraController.Forward * input.z + cameraController.Right * input.x; } /// @@ -244,44 +236,58 @@ void RotatePlayerTowardMouse() } }*/ - Camera cam = cameraController.MainCamera; - - Ray ray = cam.ScreenPointToRay(Input.mousePosition); - - Vector3 targetPoint; - - // 1. Try real world hit first (most stable) - if (Physics.Raycast(ray, out RaycastHit hit, 1000f)) + // When rotating the cam with right mouse, look forward + if (Input.GetMouseButton(1)) { - targetPoint = hit.point; + Quaternion targetRotation = Quaternion.LookRotation(cameraController.Forward); + + DougBody.transform.rotation = Quaternion.Slerp( + DougBody.transform.rotation, + targetRotation, + rotationSpeed * Time.deltaTime + ); } else { - // 2. Fallback to plane at player height - Plane plane = new Plane(Vector3.up, DougBody.transform.position); + Camera cam = cameraController.MainCamera; - if (!plane.Raycast(ray, out float enter)) + Ray ray = cam.ScreenPointToRay(Input.mousePosition); + + Vector3 targetPoint; + + // 1. Try real world hit first (most stable) + if (Physics.Raycast(ray, out RaycastHit hit, 1000f)) + { + targetPoint = hit.point; + } + else + { + // 2. Fallback to plane at player height + Plane plane = new Plane(Vector3.up, DougBody.transform.position); + + if (!plane.Raycast(ray, out float enter)) + return; + + targetPoint = ray.GetPoint(enter); + } + + // 3. Flatten direction so we only rotate on Y axis + Vector3 direction = targetPoint - DougBody.transform.position; + direction.y = 0f; + + if (direction.sqrMagnitude < 0.001f) return; - targetPoint = ray.GetPoint(enter); + // 4. Convert to rotation + Quaternion targetRotation = Quaternion.LookRotation(direction.normalized); + + // 5. Smooth rotation + DougBody.transform.rotation = Quaternion.Slerp( + DougBody.transform.rotation, + targetRotation, + rotationSpeed * Time.deltaTime + ); } - - // 3. Flatten direction so we only rotate on Y axis - Vector3 direction = targetPoint - DougBody.transform.position; - direction.y = 0f; - - if (direction.sqrMagnitude < 0.001f) - return; - - // 4. Convert to rotation - Quaternion targetRotation = Quaternion.LookRotation(direction.normalized); - - // 5. Smooth rotation - DougBody.transform.rotation = Quaternion.Slerp( - DougBody.transform.rotation, - targetRotation, - rotationSpeed * Time.deltaTime - ); } ///