From c2b26c0491886b99f422e830cd9ec1637a4ddc2e Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sun, 1 Mar 2026 09:36:29 +0800 Subject: first --- Assets/Scripts/Camera/CameraFollow.cs | 121 ++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 Assets/Scripts/Camera/CameraFollow.cs (limited to 'Assets/Scripts/Camera/CameraFollow.cs') diff --git a/Assets/Scripts/Camera/CameraFollow.cs b/Assets/Scripts/Camera/CameraFollow.cs new file mode 100644 index 0000000..47b96f4 --- /dev/null +++ b/Assets/Scripts/Camera/CameraFollow.cs @@ -0,0 +1,121 @@ +using System; +using JetBrains.Annotations; +using UnityEngine; + +namespace Camera +{ + public class CameraFollow : MonoBehaviour + { + [CanBeNull] public static CameraFollow Current; + private Transform _followTarget; + + private float _defaultYaw; + private bool _enableMove; + private float _height; + + [CanBeNull] + public Transform followTarget + { + get => _followTarget; + set { + if (_followTarget == value) return; + + _followTarget = value; + + if (_followTarget != null) + OnFollowTargetChanged(value); + else + OnFollowTargetLost(); + } + } + + private void Awake() + { + _defaultYaw = rotationYaw.eulerAngles.y; + + if (Current != null) + Debug.LogWarning("Duplicate CameraFollow Found!"); + Current = this; + followTarget = defaultFollowTarget; + } + + [Header("Parameters")] + [SerializeField] private bool enableYaw; + [SerializeField] private Transform defaultFollowTarget; + [SerializeField] [Range(0.015f, 1f)] private float yawRotationLerp; + [SerializeField] [Range(0.015f, 1f)] private float positionLerp; + [SerializeField] [Range(0.015f, 1f)] private float heightLerp; + [SerializeField] private LayerMask heightCheckLayerMask; + + [Header("Bindings")] + [SerializeField] private Transform rotationYaw; + [SerializeField] private Transform rotationPitch; + [SerializeField] private Transform positionCamera; + [SerializeField] private Transform positionHeight; + + private void OnFollowTargetChanged([CanBeNull] Transform target) + { + Debug.Log($"Follow target: {target?.name}"); + _enableMove = target != null; + } + + private void OnFollowTargetLost() + { + Debug.Log("Follow target lost"); + _enableMove = false; + } + + private void FixedUpdate() + { + FixedUpdateHeight(); + + if (_enableMove) + { + try + { + FixedUpdateMoveCamera(); + } + catch (NullReferenceException) + { + OnFollowTargetLost(); + } + } + } + + private void FixedUpdateMoveCamera() + { + var transformYaw = _followTarget.rotation.eulerAngles.y; + var transformPosition = _followTarget.position; + + var targetYaw = transformYaw; + var targetYawRotation = Quaternion.Euler(0, enableYaw ? targetYaw : _defaultYaw, 0); + var targetPosition = new Vector3(transformPosition.x, 0, transformPosition.z); + + transform.position = Vector3.Lerp(transform.position, targetPosition, positionLerp); + rotationYaw.rotation = Quaternion.Lerp(rotationYaw.rotation, targetYawRotation, yawRotationLerp); + positionHeight.position = new Vector3( + transformPosition.x, + Mathf.Lerp(positionHeight.position.y, _height, heightLerp), + transformPosition.z + ); + } + + private void FixedUpdateHeight() + { + var transformPosition = transform.position; + var start = transformPosition + Vector3.up * 100; + var end = transformPosition + Vector3.down * 100; + Physics.Linecast(start, end, out RaycastHit hit, heightCheckLayerMask); + if (hit.collider == null) + _height = transformPosition.y; + else + _height = hit.point.y; + } + + private void OnDestroy() + { + if (Current == this) + Current = null; + } + } +} -- cgit