using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraFollow : MonoBehaviour { [SerializeField] private GameEventListener_RiftPlayer onPlayerSpawned; [Space] public bool SpectatorMode = false; public bool SmoothMovement = false; [SerializeField] private Vector3 offset; [SerializeField] private Vector3 rotationEuler; [SerializeField] private bool HasCutsceneAnimation; public List players = new List(); private float zDistance; private GameObject firstInRace; private Vector3 startingPos; private Quaternion startingRot; private bool isReady = false; Animator anim; // Shake variables private float shakeDuration = 0f; private float shakeMagnitude = 0.05f; private float shakeDamping = 1f; private Vector3 shakeOffset = Vector3.zero; private void Awake() { startingPos = this.transform.position; startingRot = this.transform.rotation; onPlayerSpawned.Response.AddListener(OnPlayerSpawned); if (HasCutsceneAnimation) anim = GetComponent(); } void Update() { if (!isReady) return; if (SpectatorMode) { zDistance = 0f; for (int i = players.Count - 1; i >= 0; i--) { if (players[i] == null) { players.RemoveAt(i); continue; } if (players[i].transform.position.z - this.transform.position.z > zDistance) { zDistance = players[i].transform.position.z - this.transform.position.z; firstInRace = players[i]; } } } if (firstInRace == null) return; // Screen shake logic if (shakeDuration > 0f) { shakeOffset = Random.insideUnitSphere * shakeMagnitude; shakeDuration -= Time.deltaTime * shakeDamping; } else { shakeOffset = Vector3.zero; shakeDuration = 0f; } Vector3 targetPosition = firstInRace.transform.position + offset + shakeOffset; if (SmoothMovement) this.transform.position = Vector3.Lerp(this.transform.position, targetPosition, Time.deltaTime); else this.transform.position = targetPosition; this.transform.rotation = Quaternion.Euler(rotationEuler); } public void OnPlayerSpawned(RiftPlayer photonView) { players.Add(photonView.gameObject); if (SpectatorMode) return; firstInRace = photonView.gameObject; if (!HasCutsceneAnimation) isReady = true; } public void OnCameraAnimationEnded() { anim.enabled = false; isReady = true; } /// /// Call this to trigger a subtle screen shake. /// public void Shake(float duration = 0.2f, float magnitude = 0.05f) { shakeDuration = duration; shakeMagnitude = magnitude; } }