193 lines
5.4 KiB
C#
193 lines
5.4 KiB
C#
using UnityEngine;
|
|
using TMPro;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Unity.Cinemachine;
|
|
|
|
public class RaceManager : MonoBehaviour
|
|
{
|
|
public static RaceManager Instance;
|
|
|
|
[Header("Race Settings")]
|
|
public int totalLaps = 3;
|
|
public int numberOfCheckpoints = 0;
|
|
|
|
[Header("Countdown Settings")]
|
|
public int preliminaryCounts = 3;
|
|
public float delayBetweenCounts = 1.0f;
|
|
public AudioSource countAudioSource;
|
|
public AudioSource startSignalAudioSource;
|
|
public TextMeshProUGUI countdownText;
|
|
|
|
[Header("Finish Line Settings")]
|
|
public Transform finishLine;
|
|
|
|
[Header("UI Elements")]
|
|
public TextMeshProUGUI playerPositionText;
|
|
public TextMeshProUGUI lapsLeftText;
|
|
public GameObject playerVehicle;
|
|
|
|
[Header("Post-Race Settings")]
|
|
public CinemachineCamera victoryCamera;
|
|
public CinemachineCamera playerCamera;
|
|
public GameObject postRaceCanvas;
|
|
public GameObject playerUI;
|
|
|
|
private List<RacerProgress> racers = new List<RacerProgress>();
|
|
public bool raceFinished = false;
|
|
public bool raceStarted = false;
|
|
public string winnerName = "";
|
|
|
|
private RacerProgress playerProgress;
|
|
private string[] placeMapping = { "1st", "2nd", "3rd" };
|
|
|
|
void Awake()
|
|
{
|
|
if (Instance == null)
|
|
Instance = this;
|
|
else
|
|
Destroy(gameObject);
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
GameObject[] racerObjects = GameObject.FindGameObjectsWithTag("Racer");
|
|
foreach (GameObject racer in racerObjects)
|
|
{
|
|
RacerProgress progress = racer.GetComponent<RacerProgress>();
|
|
if (progress != null)
|
|
{
|
|
racers.Add(progress);
|
|
}
|
|
}
|
|
|
|
if (playerVehicle != null)
|
|
{
|
|
playerProgress = playerVehicle.GetComponent<RacerProgress>();
|
|
}
|
|
|
|
if (postRaceCanvas != null)
|
|
postRaceCanvas.SetActive(false);
|
|
|
|
LockRacers();
|
|
StartCoroutine(RaceCountdown());
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (playerProgress != null && raceStarted && !raceFinished)
|
|
{
|
|
int playerPosition = GetPlayerPosition();
|
|
UpdatePositionUI(playerPosition);
|
|
UpdateLapsLeftUI();
|
|
}
|
|
}
|
|
|
|
private IEnumerator RaceCountdown()
|
|
{
|
|
if (countdownText != null) countdownText.gameObject.SetActive(true);
|
|
|
|
for (int i = preliminaryCounts; i > 0; i--)
|
|
{
|
|
if (countAudioSource != null) countAudioSource.Play();
|
|
if (countdownText != null) countdownText.text = i.ToString();
|
|
yield return new WaitForSeconds(delayBetweenCounts);
|
|
}
|
|
|
|
if (startSignalAudioSource != null) startSignalAudioSource.Play();
|
|
if (countdownText != null) countdownText.text = "GO!";
|
|
|
|
yield return new WaitForSeconds(1f); // Display "GO!" briefly
|
|
if (countdownText != null) countdownText.gameObject.SetActive(false);
|
|
|
|
UnlockRacers();
|
|
raceStarted = true;
|
|
}
|
|
|
|
private void LockRacers()
|
|
{
|
|
foreach (RacerProgress racer in racers)
|
|
{
|
|
Rigidbody rb = racer.GetComponent<Rigidbody>();
|
|
if (rb != null)
|
|
{
|
|
rb.linearVelocity = Vector3.zero;
|
|
rb.angularVelocity = Vector3.zero;
|
|
rb.constraints = RigidbodyConstraints.FreezePosition | RigidbodyConstraints.FreezeRotation;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UnlockRacers()
|
|
{
|
|
foreach (RacerProgress racer in racers)
|
|
{
|
|
racer.GetComponent<BaseHovercarController>().canAccelerate = true;
|
|
Rigidbody rb = racer.GetComponent<Rigidbody>();
|
|
if (rb != null)
|
|
{
|
|
rb.constraints = RigidbodyConstraints.None;
|
|
}
|
|
}
|
|
}
|
|
|
|
private int GetPlayerPosition()
|
|
{
|
|
racers.Sort((r1, r2) => GetRacerProgressValue(r2).CompareTo(GetRacerProgressValue(r1)));
|
|
for (int i = 0; i < racers.Count; i++)
|
|
{
|
|
if (racers[i] == playerProgress)
|
|
return i + 1;
|
|
}
|
|
return racers.Count;
|
|
}
|
|
|
|
private void UpdatePositionUI(int position)
|
|
{
|
|
if (position < 4)
|
|
{
|
|
playerPositionText.text = placeMapping[position - 1];
|
|
}
|
|
else
|
|
{
|
|
playerPositionText.text = position + "th";
|
|
}
|
|
}
|
|
|
|
private void UpdateLapsLeftUI()
|
|
{
|
|
int lapsLeft = Mathf.Max(totalLaps - playerProgress.lapCount, 0);
|
|
lapsLeftText.text = "Laps Left: " + lapsLeft;
|
|
}
|
|
|
|
private float GetRacerProgressValue(RacerProgress rp)
|
|
{
|
|
return rp.lapCount * numberOfCheckpoints + rp.currentCheckpointIndex;
|
|
}
|
|
|
|
public void CheckFinish(RacerProgress rp)
|
|
{
|
|
if (rp.lapCount >= totalLaps && !raceFinished)
|
|
{
|
|
raceFinished = true;
|
|
winnerName = rp.gameObject.name;
|
|
Debug.Log("Race Finished! Winner: " + winnerName);
|
|
TriggerPostRaceEvents();
|
|
}
|
|
}
|
|
|
|
private void TriggerPostRaceEvents()
|
|
{
|
|
if (victoryCamera != null && playerVehicle != null && playerCamera != null)
|
|
{
|
|
victoryCamera.gameObject.SetActive(true);
|
|
playerCamera.gameObject.SetActive(false);
|
|
}
|
|
|
|
if (postRaceCanvas != null) postRaceCanvas.SetActive(true);
|
|
if (playerUI != null) playerUI.SetActive(false);
|
|
|
|
LockRacers(); // Lock racers at the end of the race
|
|
}
|
|
}
|