Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Using time in C# and switch

Discussion in 'Scripting' started by Antowas, Nov 7, 2014.

  1. Antowas

    Antowas

    Joined:
    Oct 29, 2014
    Posts:
    3
    Hello everyone,

    Admittedly, I am not very good at coding in C#, but I am learning. I am working on a 2D top down farming game and I am making a few small tests as I get my feet wet to get familiar with C# and Unity at the same time. I wrote a script that progresses the stage of a crop in sprite form every time the space bar is pressed, but I have a few questions.

    1) How do I tie this to a timer that starts once the crop is planted?

    2) How do I set the sprite to change after a certain amount of time has passed, as opposed to pressing the space bar?

    I tried this via a switch, but I am not familiar enough with the concept to get it to work properly. I would like to use switch, so I can call back to earlier in the sequence for crops that can have multiple harvests.

    Any help is greatly appreciated.

    This is what I have at present
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class GrowingTest : MonoBehaviour
    6. {
    7.  
    8.    private int GrowStage = 0; //Sets variable called GrowStage
    9.    public Sprite stage1; // Drag first crop sprite here
    10.    public Sprite stage2; // Drag second crop sprite here
    11.    public Sprite stage3; // Drag third crop sprite here
    12.  
    13.    private SpriteRenderer spriteRenderer;
    14.    // Use this for initialization
    15.    void Start ()
    16.    {
    17.    
    18.      spriteRenderer = GetComponent<SpriteRenderer>(); //Calls Sprite Renderer Component from Unity via spriteRenderer alias
    19.  
    20.    }
    21.    
    22.    // Update is called once per frame
    23.    void Update ()
    24.    {
    25.    if (Input.GetKeyDown("space"))  //When spacebar is pressed
    26.        GrowStage = GrowStage + 1;  //Add 1 to GrowStage variable
    27.        
    28.    }
    29.    void FixedUpdate()
    30.       {
    31.        if (GrowStage > 0) //If GrowStage variable is set to 1
    32.            {
    33.            spriteRenderer.sprite = stage1; //swap to sprite 1
    34.            }
    35.        if (GrowStage > 1)
    36.            {
    37.            spriteRenderer.sprite = stage2;
    38.            }
    39.        if (GrowStage > 2)
    40.            {
    41.            spriteRenderer.sprite = stage3;
    42.            }
    43.      }
    44.  
    45.  
    46. }
    47.  
     
  2. slay_mithos

    slay_mithos

    Joined:
    Nov 5, 2014
    Posts:
    130
    Time.deltaTime is what you want to use to get the elapsed time since the last update, so you will do a += Time.deltaTime on a stored variable.

    While we are making small corrections, your FixedUpdate could use a bit of change, by doing IF ... ELSE IF ... ELSE IF, and changing the conditions.

    Right now, it will change the sprite multiple times in the same update, meaning that it uses a bit more resources than it should.
    It doesn't impact things too much for a small project, but it's good to try and not fall into those small traps.
     
  3. justinlloyd

    justinlloyd

    Joined:
    Aug 5, 2010
    Posts:
    1,680
    What you are building is a simple state machine. This is definitely something you want to read up on as a lot of simple game play components require an understanding of this technique.

    The code below compiles and is tested within the limits that I care to test for.

    The component can be attached to a plant and have the sprites populated through an array in the Inspector. It will also fire events whenever the plant changes state, which is very useful if you want other scripts to know when the plant starts and stops growing or has completely grown.


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. [RequireComponent(typeof(SpriteRenderer))]
    6. public class GrowthMachine : MonoBehaviour
    7. {
    8.     // event to fire when the plant advances to the next growth stage
    9.     public delegate void GrownToStageHandler(Object sender, int growthStage, int growthStages);
    10.     public event GrownToStageHandler GrownToStage;
    11.  
    12.     // event to fire when the plant has completely grown
    13.     public delegate void CompletelyGrownHandler(Object sender, int growthStage, int growthStages);
    14.     public event CompletelyGrownHandler CompletelyGrown;
    15.  
    16.     // event to fire when the plant starts to growth
    17.     public delegate void StartedGrowingHandler(Object sender, int growthStage, int growthStages);
    18.     public event StartedGrowingHandler StartedGrowing;
    19.  
    20.     // event to fire when the plant stops to growth
    21.     public delegate void StoppedGrowingHandler(Object sender, int growthStage, int growthStages);
    22.     public event StoppedGrowingHandler StoppedGrowing;
    23.  
    24.     // Sprites for each growth stage
    25.     [SerializeField]
    26.     protected List<Sprite> m_stages;
    27.  
    28.     // how long to wait in seconds between each growth stage
    29.     [SerializeField]
    30.     [Range(0.01f, 100.0f)]
    31.     protected float m_growthRate;
    32.  
    33.     // should I start growing the moment I am planted?
    34.     [SerializeField]
    35.     protected bool m_growImmediately;
    36.  
    37.     // what stage of growth is this plant at?
    38.     private int m_growthStage;
    39.  
    40.     // cached sprite renderer component
    41.     private SpriteRenderer m_spriteRenderer;
    42.  
    43.     // indicates whether the plant is growing or not
    44.     private bool m_isGrowing;
    45.  
    46.     void Start()
    47.     {
    48.         m_spriteRenderer = GetComponent<SpriteRenderer>();
    49.         // should I start growing the moment I am planted?
    50.         if (m_growImmediately)
    51.         {
    52.             StartGrowing();
    53.         }
    54.  
    55.     }
    56.  
    57.     // stops the plant from growing and terminates the coroutine that makes the plant grow
    58.     public void StopGrowing()
    59.     {
    60.         // am I growing? if not, do nothing
    61.         if (m_isGrowing == false)
    62.         {
    63.             return;
    64.         }
    65.  
    66.         StopCoroutine(Growing());
    67.         m_isGrowing = false;
    68.         FireStoppedGrowing();
    69.     }
    70.  
    71.     // forces the plant to start growing -- either automatically when it is planted or forcibly
    72.     public void StartGrowing()
    73.     {
    74.         // am I already growing? if so, do nothing
    75.         if (m_isGrowing)
    76.         {
    77.             return;
    78.         }
    79.  
    80.         StartCoroutine(Growing());
    81.     }
    82.  
    83.     // coroutine that will grow the plant through the various stages to the end
    84.     IEnumerator Growing()
    85.     {
    86.         m_isGrowing = true;
    87.         // verify we don't have a negative or zero growth rate
    88.         System.Diagnostics.Debug.Assert(m_growthRate > 0.0f);
    89.         // verify we have a list of sprites to handle the growth stages
    90.         System.Diagnostics.Debug.Assert(m_stages != null);
    91.         int stagesToGrow = m_stages.Count;
    92.         // verify we have at least one sprite to handle the first growth stage
    93.         System.Diagnostics.Debug.Assert(stagesToGrow > 0);
    94.         FireStartedGrowing();
    95.         ResetGrowth();
    96.         for (int i = 1; i < stagesToGrow; i++)
    97.         {
    98.             yield return new WaitForSeconds(m_growthRate);
    99.             AdvanceToNextGrowthStage();
    100.         }
    101.  
    102.         m_isGrowing = false;
    103.         FireStoppedGrowing();
    104.     }
    105.  
    106.     // reset the growth of the plant to the very first stage. Assumes we have a first stage to reset to
    107.     public void ResetGrowth()
    108.     {
    109.         GrowthStage = 0;
    110.     }
    111.  
    112.     // advance the plant to the next stage of growth
    113.     public void AdvanceToNextGrowthStage()
    114.     {
    115.         // have we grown to the last stage? if so, do nothing more
    116.         if (GrowthStage >= (m_stages.Count - 1))
    117.         {
    118.             return;
    119.         }
    120.  
    121.         // update the sprite to the next growth stage
    122.         GrowthStage++;
    123.         // let any other scripts paying attention to this plant know about the growth
    124.         FireAdvancedToNextStage();
    125.         // let any other scripts paying attention to this plant know about reaching the final stage growth
    126.         if (GrowthStage == (m_stages.Count - 1))
    127.         {
    128.             FireCompletelyGrown();
    129.         }
    130.  
    131.     }
    132.  
    133.     // reset the script values to sane defaults
    134.     void Reset()
    135.     {
    136.         m_stages = new List<Sprite>();
    137.         m_growthRate = 1.0f;
    138.         m_growImmediately = true;
    139.     }
    140.  
    141.     // inform any other scripts listening to this plant that i've started growing -- either forcibly or because I
    142.     // started automatically.
    143.     private void FireStartedGrowing()
    144.     {
    145.         if (StartedGrowing != null)
    146.         {
    147.             StartedGrowing(this, m_growthStage, m_stages.Count);
    148.         }
    149.  
    150.     }
    151.  
    152.     // inform any other scripts listening to this plant that i've stopped growing -- either forcibly or because I
    153.     // reached the end of my growth cycle).
    154.     private void FireStoppedGrowing()
    155.     {
    156.         if (StoppedGrowing != null)
    157.         {
    158.             StoppedGrowing(this, m_growthStage, m_stages.Count);
    159.         }
    160.  
    161.     }
    162.  
    163.     // inform any other scripts listening to this plant that i've completely grown up
    164.     private void FireCompletelyGrown()
    165.     {
    166.         if (CompletelyGrown != null)
    167.         {
    168.             CompletelyGrown(this, (int)(m_growthStage), m_stages.Count);
    169.         }
    170.     }
    171.  
    172.     // inform any other scripts listening to this plant that i've grown to the next stage
    173.     private void FireAdvancedToNextStage()
    174.     {
    175.         if (GrownToStage != null)
    176.         {
    177.             GrownToStage(this, (int)(m_growthStage), m_stages.Count);
    178.         }
    179.  
    180.     }
    181.  
    182.     // permits the growth stage to be immediately set by other scripts
    183.     public int GrowthStage
    184.     {
    185.         get
    186.         {
    187.             return m_growthStage;
    188.         }
    189.         set
    190.         {
    191.             System.Diagnostics.Debug.Assert(value >= 0);
    192.             System.Diagnostics.Debug.Assert(value < m_stages.Count);
    193.             m_growthStage = value;
    194.             m_spriteRenderer.sprite = m_stages[value];
    195.         }
    196.     }
    197.  
    198.     // indicates whether the plant is currently growing or not
    199.     public bool IsGrowing
    200.     {
    201.         get
    202.         {
    203.             return m_isGrowing;
    204.         }
    205.     }
    206.  
    207. }
    208.  
     
  4. Antowas

    Antowas

    Joined:
    Oct 29, 2014
    Posts:
    3
    I really appreciate the tips. I have reworked my own code based on this.
     
  5. Antowas

    Antowas

    Joined:
    Oct 29, 2014
    Posts:
    3
    Goodness... I don't even know what half that stuff means at present, but I certainly appreciate you providing the code. I will copy it and study it until I understand it completely and can configure it myself. I do have a long way to go, but I have a lot of videos from Youtube and various websites (Unity Live Training included) to get a handle on things.

    I am very grateful for your help!
     
  6. clayton1314

    clayton1314

    Joined:
    Jul 11, 2017
    Posts:
    2
    would this work in 3d?