Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Other a system of rewards in levels in the form of stars with the help of time

Discussion in 'Scripting' started by Pandausers, Mar 14, 2024.

  1. Pandausers

    Pandausers

    Joined:
    Feb 17, 2024
    Posts:
    36
    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

    Code (CSharp):
    1. // This script manages the timer for the game and handles the display of the finish canvas when the player completes the level.
    2.  
    3. using System.Collections;
    4. using TMPro;
    5. using UnityEngine;
    6. using UnityEngine.UI;
    7.  
    8. public class Timer : MonoBehaviour
    9. {
    10.     public LayerMask finishLayer; // Layer mask for the finish line
    11.     public Player playerMovement; // Reference to the Player script
    12.     public GameObject finishcanvas; // Reference to the canvas to display when the level is finished
    13.     private Rigidbody2D rb; // Rigidbody2D component of the object
    14.     public GameObject objectToShow1; // GameObject to show for the first star
    15.     public GameObject objectToShow2; // GameObject to show for the second star
    16.     public GameObject objectToShow3; // GameObject to show for the third star
    17.  
    18.     [SerializeField] private TextMeshProUGUI timerText; // Text to display the timer
    19.     [SerializeField] private TextMeshProUGUI timerTextInOtherCanvas; // Text to display the timer in another canvas
    20.     [SerializeField] private TextMeshProUGUI timerTextFinish; // Text to display the timer on the finish canvas
    21.  
    22.     private float elapsedTime; // Elapsed time since the start of the level
    23.     private Animator anim; // Animator component of the object
    24.     private bool isTimerRunning = true; // Flag to indicate if the timer is running
    25.     private bool hasFinished = false; // Flag to indicate if the player has finished the level
    26.  
    27.     // Start is called before the first frame update
    28.     private void Start()
    29.     {
    30.         rb = GetComponent<Rigidbody2D>(); // Get the Rigidbody2D component
    31.         anim = GetComponent<Animator>(); // Get the Animator component
    32.  
    33.         if (finishcanvas != null)
    34.         {
    35.             finishcanvas.SetActive(false); // Deactivate the finish canvas at the start
    36.         }
    37.  
    38.         // Subscribe to the event for displaying the finish canvas
    39.         FinishCanvasController.OnFinishCanvasDisplayed += HandleFinishCanvasDisplayed;
    40.     }
    41.  
    42.     // OnDestroy is called when the MonoBehaviour will be destroyed
    43.     private void OnDestroy()
    44.     {
    45.         // Unsubscribe from the event when the object is destroyed
    46.         FinishCanvasController.OnFinishCanvasDisplayed -= HandleFinishCanvasDisplayed;
    47.     }
    48.  
    49.     // HandleFinishCanvasDisplayed is called when the finish canvas is displayed
    50.     private void HandleFinishCanvasDisplayed()
    51.     {
    52.         // Start the coroutine to handle reward display
    53.         StartCoroutine(RewardCoroutine());
    54.     }
    55.  
    56.     // Finish checks if a collision object is tagged as "finish"
    57.     private bool Finish(GameObject obj)
    58.     {
    59.         return obj.CompareTag("finish") || obj.layer == LayerMask.NameToLayer("Finish");
    60.     }
    61.  
    62.     // Endgame is called when the player finishes the level
    63.     private void endgame()
    64.     {
    65.         rb.velocity = Vector2.zero; // Stop the object's velocity
    66.         rb.bodyType = RigidbodyType2D.Static; // Set the body type to static
    67.  
    68.         playerMovement.DisableFlip(); // Disable player movement
    69.         Invoke(nameof(FinishCanvas), 0f); // Invoke the method to display the finish canvas
    70.         isTimerRunning = false; // Stop the timer
    71.     }
    72.  
    73.     // OnCollisionEnter2D is called when this collider/rigidbody has begun touching another rigidbody/collider
    74.     private void OnCollisionEnter2D(Collision2D collision)
    75.     {
    76.         if (Finish(collision.gameObject))
    77.         {
    78.             endgame(); // Call endgame when the player reaches the finish line
    79.             hasFinished = true; // Set the flag indicating the player has finished
    80.         }
    81.     }
    82.  
    83.     // FinishCanvas displays the finish canvas
    84.     private void FinishCanvas()
    85.     {
    86.         if (finishcanvas != null)
    87.         {
    88.             finishcanvas.SetActive(true); // Activate the finish canvas
    89.             FinishCanvasController.NotifyFinishCanvasDisplayed(); // Notify that the finish canvas is displayed
    90.         }
    91.     }
    92.  
    93.     // timer updates the timer text based on elapsed time
    94.     private void timer()
    95.     {
    96.         if (!hasFinished) // Timer continues if the player hasn't finished the level
    97.         {
    98.             elapsedTime += Time.deltaTime; // Increment elapsed time
    99.             int minutes = Mathf.FloorToInt(elapsedTime / 60); // Calculate minutes
    100.             int seconds = Mathf.FloorToInt(elapsedTime % 60); // Calculate seconds
    101.  
    102.             // Update timer text in different canvases
    103.             timerText.text = string.Format("Time: {0:00}:{1:00}", minutes, seconds);
    104.             timerTextInOtherCanvas.text = string.Format("Time: {0:00}:{1:00}", minutes, seconds);
    105.             timerTextFinish.text = string.Format("Time: {0:00}:{1:00}", minutes, seconds);
    106.         }
    107.     }
    108.  
    109.     // Update is called once per frame
    110.     private void Update()
    111.     {
    112.         if (isTimerRunning && !IsDeathAnimationPlaying())
    113.         {
    114.             timer(); // Update the timer if the timer is running and the death animation is not playing
    115.         }
    116.     }
    117.  
    118.     // RewardCoroutine handles the display of stars based on the elapsed time
    119.     private IEnumerator RewardCoroutine()
    120.     {
    121.         if (elapsedTime <= 75)
    122.         {
    123.             // Display all three stars
    124.             yield return new WaitForSeconds(0.3f);
    125.             objectToShow1.SetActive(true);
    126.             yield return new WaitForSeconds(1f);
    127.             objectToShow2.SetActive(true);
    128.             yield return new WaitForSeconds(1f);
    129.             objectToShow3.SetActive(true);
    130.         }
    131.  
    132.         if (elapsedTime >= 75 && elapsedTime <= 93)
    133.         {
    134.             // Display two stars and change the color of the third star
    135.             yield return new WaitForSeconds(0.3f);
    136.             objectToShow1.SetActive(true);
    137.             yield return new WaitForSeconds(1f);
    138.             objectToShow2.SetActive(true);
    139.             yield return new WaitForSeconds(1f);
    140.             SetObjectColor(objectToShow3, "#242424");
    141.             objectToShow3.SetActive(true);
    142.         }
    143.  
    144.         if (elapsedTime >= 93)
    145.         {
    146.             // Display one star and change the color of the other two stars
    147.             yield return new WaitForSeconds(0.3f);
    148.             objectToShow1.SetActive(true);
    149.             yield return new WaitForSeconds(1f);
    150.             SetObjectColor(objectToShow2, "#242424");
    151.             objectToShow2.SetActive(true);
    152.             yield return new WaitForSeconds(1f);
    153.             SetObjectColor(objectToShow3, "#242424");
    154.             objectToShow3.SetActive(true);
    155.         }
    156.     }
    157.  
    158.     // SetObjectColor sets the color of a GameObject based on a hex color value
    159.     private void SetObjectColor(GameObject gameObject, string hexColor)
    160.     {
    161.         if (gameObject != null)
    162.         {
    163.             Graphic graphic = gameObject.GetComponent<Graphic>();
    164.             if (graphic != null)
    165.             {
    166.                 Color targetColor;
    167.  
    168.                 if (ColorUtility.TryParseHtmlString(hexColor, out targetColor))
    169.                 {
    170.                     graphic.color = targetColor;
    171.                 }
    172.             }
    173.         }
    174.     }
    175.  
    176.     // IsDeathAnimationPlaying checks if the death animation is currently playing
    177.     private bool IsDeathAnimationPlaying()
    178.     {
    179.         AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
    180.         return stateInfo.IsTag("death");
    181.     }
    182. }
    183.  
    184. // FinishCanvasController manages the event for displaying the finish canvas
    185. public static class FinishCanvasController
    186. {
    187.     public delegate void FinishCanvasDisplayedDelegate();
    188.     public static event FinishCanvasDisplayedDelegate OnFinishCanvasDisplayed;
    189.  
    190.     // NotifyFinishCanvasDisplayed invokes the event for displaying the finish canvas
    191.     public static void NotifyFinishCanvasDisplayed()
    192.     {
    193.         OnFinishCanvasDisplayed?.Invoke();
    194.     }
    195. }
    196.  
     
  2. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    283
    You should clarify what the problem is, as it's not entirely clear at the moment. What does 'works only on 1 level' mean? What do your levels represent, are they new scenes with each having its own timer? Or do you have one scene and you want to reuse this timer? If so, then you need to at least write code that will reset the timer, resetting the time, turning off the visibility of objects (stars), etc.
     
  3. Pandausers

    Pandausers

    Joined:
    Feb 17, 2024
    Posts:
    36
    So far I have 2 levels, they consist of 2 scenes, and when the character runs to gamobjectfinish, the timer stops and the number of stars in the 1st scene is displayed relative to this timer. Also in the 2nd scene, the number of stars is displayed from the same time as in the 1st scene, but I need the time to be different and I want to modify this script somehow so that I don't create a new script for each level
     
  4. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    283
    If you simply want to conveniently configure three time ranges? That is, all the script logic remains the same, but these magical numbers, I mean the following (75, 93)

    if (elapsedTime <= 75)

    if (elapsedTime >= 75 && elapsedTime <= 93)

    if (elapsedTime >= 93)


    Do you want to control them from the inspector? Then why not extract these two numbers into public fields in the inspector?
     
  5. Pandausers

    Pandausers

    Joined:
    Feb 17, 2024
    Posts:
    36
    yes thx for your answer this is very helped me