RiftMayhem/Assets/Scripts/CameraFollow.cs
2025-06-08 19:57:55 +01:00

117 lines
3.1 KiB
C#

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<GameObject> players = new List<GameObject>();
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<Animator>();
}
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;
}
/// <summary>
/// Call this to trigger a subtle screen shake.
/// </summary>
public void Shake(float duration = 0.2f, float magnitude = 0.05f)
{
shakeDuration = duration;
shakeMagnitude = magnitude;
}
}