- Home /
good way to call a method only once within countdown??
I want to call multiple methods on specific countdown time. So i've been using boolean value and change it to false when the method is called. But having a lot of methods makes me to create too many boolean values. is there any better way to make this ?
public class DoSomethingWithCountdown : MonoBehaviour {
private float timer = 100f;
private bool firstBool = true;
private bool secondBool = true;
private bool thirdBool = true;
// more boolean values will be needed...
void Update() {
timer -= Time.deltaTime;
if (timer < 80 && firstBool) {
// do something
firstBool = false;
}
if (timer < 50 && secondBool) {
// do something
secondBool = false;
}
if (timer < 20 && thirdBool) {
// do something
thirdBool = false;
}
// and so on...
}
}
Answer by CorruptedTNC · Jun 16, 2020 at 09:42 AM
Yep, there are a few ways you can do this. First of all well done for identifying that there's probably an easier way of accomplishing your goal, it's a good sign that you're learning and improving!
I'd personally approach it this way: You could create a class that wraps an action, and have that class invoke the action after a specified time frame.
using System;
using UnityEngine;
internal sealed class TimedEvent
{
private float m_CurrentTime;
private float m_MaxTime;
private Action m_Action;
private bool m_HasRun;
public TimedEvent(float time, Action action)
{
m_MaxTime = 0f;
m_Action = action;
}
public void Tick()
{
if (m_HasRun)
{
return;
}
m_CurrentTime += Time.deltaTime;
if (m_CurrentTime >= m_MaxTime)
{
m_Action();
m_HasRun = true;
}
}
}
Which can then be used like so
using System;
using UnityEngine;
internal sealed class SomeGameObject : MonoBehaviour
{
private TimedEvent m_EventOne = new TimedEvent(5f, () => Debug.Log("HELLO!"));
// Repeat for other events, probably introduce a collection of them so you can
// iterate them and make them process a tick all at once
private void Update()
{
m_EventOne.Tick();
}
}
You could also make an event 'reset' itself every time it invokes its action if it's meant to loop.
You could even go a step further and introduce a class that wraps your events, and allow other scripts to register timed events. I recently needed a timed event system for day/night cycle and regular reoccurring events. I can't post code for this, but here's a general idea.
I have a class which has a
Dictionary<float, Action>
to hold events and their timesIt has a public method
RegisterEvent(float time, Action action)
where time is between 0 (start of day) and 1 (end of day)Each update cycle, check to see if we've passed the specified time
It's the responsibility of the action to handle behaviour like looping, not the time management class
Time can be fast forwarded if the day ends prematurely, and all the events will still fire
Sorry if this doesn't compile, I don't have visual studio in front of me :D