Hi guys, I have a problem, I created a script and this script checks the time and outputs the stars relative to the time, but it only works for 1 level and I need to modify this script somehow to use it in many levels with different times, please help
// This script manages the timer for the game and handles the display of the finish canvas when the player completes the level.
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class Timer : MonoBehaviour
{
public LayerMask finishLayer; // Layer mask for the finish line
public Player playerMovement; // Reference to the Player script
public GameObject finishcanvas; // Reference to the canvas to display when the level is finished
private Rigidbody2D rb; // Rigidbody2D component of the object
public GameObject objectToShow1; // GameObject to show for the first star
public GameObject objectToShow2; // GameObject to show for the second star
public GameObject objectToShow3; // GameObject to show for the third star
[SerializeField] private TextMeshProUGUI timerText; // Text to display the timer
[SerializeField] private TextMeshProUGUI timerTextInOtherCanvas; // Text to display the timer in another canvas
[SerializeField] private TextMeshProUGUI timerTextFinish; // Text to display the timer on the finish canvas
private float elapsedTime; // Elapsed time since the start of the level
private Animator anim; // Animator component of the object
private bool isTimerRunning = true; // Flag to indicate if the timer is running
private bool hasFinished = false; // Flag to indicate if the player has finished the level
// Start is called before the first frame update
private void Start()
{
rb = GetComponent<Rigidbody2D>(); // Get the Rigidbody2D component
anim = GetComponent<Animator>(); // Get the Animator component
if (finishcanvas != null)
{
finishcanvas.SetActive(false); // Deactivate the finish canvas at the start
}
// Subscribe to the event for displaying the finish canvas
FinishCanvasController.OnFinishCanvasDisplayed += HandleFinishCanvasDisplayed;
}
// OnDestroy is called when the MonoBehaviour will be destroyed
private void OnDestroy()
{
// Unsubscribe from the event when the object is destroyed
FinishCanvasController.OnFinishCanvasDisplayed -= HandleFinishCanvasDisplayed;
}
// HandleFinishCanvasDisplayed is called when the finish canvas is displayed
private void HandleFinishCanvasDisplayed()
{
// Start the coroutine to handle reward display
StartCoroutine(RewardCoroutine());
}
// Finish checks if a collision object is tagged as "finish"
private bool Finish(GameObject obj)
{
return obj.CompareTag("finish") || obj.layer == LayerMask.NameToLayer("Finish");
}
// Endgame is called when the player finishes the level
private void endgame()
{
rb.velocity = Vector2.zero; // Stop the object's velocity
rb.bodyType = RigidbodyType2D.Static; // Set the body type to static
playerMovement.DisableFlip(); // Disable player movement
Invoke(nameof(FinishCanvas), 0f); // Invoke the method to display the finish canvas
isTimerRunning = false; // Stop the timer
}
// OnCollisionEnter2D is called when this collider/rigidbody has begun touching another rigidbody/collider
private void OnCollisionEnter2D(Collision2D collision)
{
if (Finish(collision.gameObject))
{
endgame(); // Call endgame when the player reaches the finish line
hasFinished = true; // Set the flag indicating the player has finished
}
}
// FinishCanvas displays the finish canvas
private void FinishCanvas()
{
if (finishcanvas != null)
{
finishcanvas.SetActive(true); // Activate the finish canvas
FinishCanvasController.NotifyFinishCanvasDisplayed(); // Notify that the finish canvas is displayed
}
}
// timer updates the timer text based on elapsed time
private void timer()
{
if (!hasFinished) // Timer continues if the player hasn't finished the level
{
elapsedTime += Time.deltaTime; // Increment elapsed time
int minutes = Mathf.FloorToInt(elapsedTime / 60); // Calculate minutes
int seconds = Mathf.FloorToInt(elapsedTime % 60); // Calculate seconds
// Update timer text in different canvases
timerText.text = string.Format("Time: {0:00}:{1:00}", minutes, seconds);
timerTextInOtherCanvas.text = string.Format("Time: {0:00}:{1:00}", minutes, seconds);
timerTextFinish.text = string.Format("Time: {0:00}:{1:00}", minutes, seconds);
}
}
// Update is called once per frame
private void Update()
{
if (isTimerRunning && !IsDeathAnimationPlaying())
{
timer(); // Update the timer if the timer is running and the death animation is not playing
}
}
// RewardCoroutine handles the display of stars based on the elapsed time
private IEnumerator RewardCoroutine()
{
if (elapsedTime <= 75)
{
// Display all three stars
yield return new WaitForSeconds(0.3f);
objectToShow1.SetActive(true);
yield return new WaitForSeconds(1f);
objectToShow2.SetActive(true);
yield return new WaitForSeconds(1f);
objectToShow3.SetActive(true);
}
if (elapsedTime >= 75 && elapsedTime <= 93)
{
// Display two stars and change the color of the third star
yield return new WaitForSeconds(0.3f);
objectToShow1.SetActive(true);
yield return new WaitForSeconds(1f);
objectToShow2.SetActive(true);
yield return new WaitForSeconds(1f);
SetObjectColor(objectToShow3, "#242424");
objectToShow3.SetActive(true);
}
if (elapsedTime >= 93)
{
// Display one star and change the color of the other two stars
yield return new WaitForSeconds(0.3f);
objectToShow1.SetActive(true);
yield return new WaitForSeconds(1f);
SetObjectColor(objectToShow2, "#242424");
objectToShow2.SetActive(true);
yield return new WaitForSeconds(1f);
SetObjectColor(objectToShow3, "#242424");
objectToShow3.SetActive(true);
}
}
// SetObjectColor sets the color of a GameObject based on a hex color value
private void SetObjectColor(GameObject gameObject, string hexColor)
{
if (gameObject != null)
{
Graphic graphic = gameObject.GetComponent<Graphic>();
if (graphic != null)
{
Color targetColor;
if (ColorUtility.TryParseHtmlString(hexColor, out targetColor))
{
graphic.color = targetColor;
}
}
}
}
// IsDeathAnimationPlaying checks if the death animation is currently playing
private bool IsDeathAnimationPlaying()
{
AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
return stateInfo.IsTag("death");
}
}
// FinishCanvasController manages the event for displaying the finish canvas
public static class FinishCanvasController
{
public delegate void FinishCanvasDisplayedDelegate();
public static event FinishCanvasDisplayedDelegate OnFinishCanvasDisplayed;
// NotifyFinishCanvasDisplayed invokes the event for displaying the finish canvas
public static void NotifyFinishCanvasDisplayed()
{
OnFinishCanvasDisplayed?.Invoke();
}
}