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

trying to work on a timer that could run on many gameobjects

Discussion in 'Scripting' started by superwholock, Apr 23, 2022.

  1. superwholock

    superwholock

    Joined:
    Feb 6, 2018
    Posts:
    6
    So i'm trying to make a game where you bake things, and currently, the players starts with 2 stand mixers, 2 ovens, and 2 spots on a counter for mixing. Currently each of these gameobjects has it's own function on a gameManager script (gamemanager is not on each of these objects, the script references them) that keeps track of a different timer function for each object (i.e. oventimer1, oventimer2, mixertimer1, mixertimer2, etc). while this works, what I want is to use a singular timer function that could be called on each gameobject and passed information about how long to run for, and then what to do when the timer ends.
    My question is would I have to do something like write a method to extend the gameobject, and then pass in the parameters like time, and then what to do when it ends? Or is there some other more efficient way to do this. Eventually I want the player to be able to unlock and purchase more ovens and mixers, so I feel like it would be most efficient to have one timer function that any of the mixers or ovens could call so that when I add more of them later, they don't need their own function like oventimer3 or mixertimer3
     
  2. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,593
    You can use an interface for this kind of thing, make all of your classes inherit from some iTimer interface class, and have an override method in each of them which does their own unique timer. Then, when storing references to your gameObjects, you can save it as a collection of iTimers, allowing you to call your interface method on all of them, while having them all do their unique things.
     
  3. superwholock

    superwholock

    Joined:
    Feb 6, 2018
    Posts:
    6
    So i had to look up a bunch of stuff, and I think after reading through the C# documentation that I get how to implement interfaces, i've used things like IPointerClick in projects before. But how would I save the gameobjects as a collection of iTimers? Does each of the objects gets it's own script with the iTimer interface? Does my gameManager script need a function that iterates through all of the iTimers in the scene or something? I don't think i've tried anything this complex before, but I really want to understand it.
     
  4. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,593
    So, each of your unique scripts would implement the iTimer interface, which means they would have a shared method which could be called by whatever manager script you have, which should have a reference to each of them. Here's a pretty basic rundown of what it might look like.

    Code (CSharp):
    1. public interface iTimer
    2. {
    3.     void Timer();
    4. }
    Code (CSharp):
    1. public class Oven : MonoBehavior, iTimer
    2. {
    3.     public void Timer()
    4.     {
    5.         // does whatever your oven's supposed to do
    6.     }
    7. }
    Code (CSharp):
    1. public class Mixer : MonoBehavior, iTimer
    2. {
    3.     public void Timer()
    4.     {
    5.         // does whatever your mixer's supposed to do
    6.     }
    7. }
    Code (CSharp):
    1. public class KitchenManager : MonoBehavior
    2. {
    3.     List<iTimer> KitchenObjects;
    4.  
    5.     void Start()
    6.     {
    7.         KitchenObjects = new List<iTimer>();
    8.         // add your oven and mixer to this list
    9.     }
    10.  
    11.     void Update()
    12.     {
    13.         foreach(iTimer object in KitchenObjects)
    14.         {
    15.             object.Timer();
    16.         }
    17.     }
    18. }
     
  5. superwholock

    superwholock

    Joined:
    Feb 6, 2018
    Posts:
    6
    so i would have to manually add the ovens and mixers into the kitchenobjects list via the inspector? I want the player to eventually have more ovens, so if they purchase an upgrade, they get a third oven or mixer, is there a way to add that newly instantiated gameobject to the kitchenobject list? or would it make more sense to have the extra ovens and mixers already instantiated and on the list, and then just activate them when needed?
     
  6. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,593
    You can have each of your kitchen objects add themselves to the List when they are created. If you use a Singleton or a ScriptableObject for your List, then it can pretty much be accessed anywhere.
     
  7. superwholock

    superwholock

    Joined:
    Feb 6, 2018
    Posts:
    6
    thanks for all your help on this, i'll update this thread when I try to implement this
     
  8. superwholock

    superwholock

    Joined:
    Feb 6, 2018
    Posts:
    6
    Sorry for the late update on this thread, but I've been taking summer college courses.
    I've done more reading on the documentation for interfaces, and I think that I get the gist of how to implement them, but my issue now is that I can't figure out how to add my gameobjects with their implementation of the method from the interface to a list. You said in one of your earlier comments, that you "//add your ovens and mixers to this list" but my objects are currently referenced by my gamemanger as gameobjects, and when I try to add those gameobjects the list of iTimers, it says it cannot convert from gameobject to iTimer. Should i just be referencing this as an iTimer, or is there a broader type declaration I can use, like how gameobject contains information for all of the components contained on it.
    Because I am using that current reference as a gameobject to access the animator on that object, but if I change that reference to an iTimer, I can't do that unless I add another reference to that object.
    so I'd have to do something like

    GameObject mixer1;
    iTimer mixer1_timer;

    and they'd both be referencing the same mixer.
    I tried setting the mixer as an Object and an object, but that didn't work either
     
  9. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,593
    One thing you can do is just get the Component of the objects from your game manager.
    Code (CSharp):
    1. mixer1.GetComponent<iTimer>();
    another thing you could do is just reference them all as iTimers, and just call GetComponent to get the Animator anyways. You can use GetComponent on pretty much anything on an object.
    Code (CSharp):
    1. mixer1_timer.GetComponent<Animator>();
    I don't know what else your GameManager is doing with them though, so I don't know what would work best for you.

    What I suggested in my third post was to use the Awake() method to have it put itself into your lists, although it might be a bit advanced. It would either require you turn your Managers into Singletons, or to use ScriptableObjects. I recommend learning about both eventually, as they're pretty useful.