- Home /
How can I repeat an action after set number of seconds,
To simplify, my player has a flashlight and after a set amount of time the battery percentage should lower by 1%. Since it starts at 100%, after some time -> 99% then 98% and so on. So far, I've tried using InvokeRepeating and coroutines but both have given me issues. Bellow is my current script:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
public class Flashlight : MonoBehaviour
{
public Transform player;
public Light flashlight;
public Vector3 offset;
public float rotateSpeed;
public float threshold;
public float battery;
public Text batteryDisplay;
public float percentDropTime;
void start()
{
flashlight = GetComponent<Light>();
InvokeRepeating("LowerBattery", percentDropTime, 0);
}
void Update()
{
UnityEngine.Debug.Log(battery);
transform.position = player.position + offset;
transform.eulerAngles = new Vector3(player.eulerAngles.x, player.eulerAngles.y + rotateSpeed, player.eulerAngles.z);
UpdateBattery();
}
void UpdateBattery()
{
batteryDisplay.text = "Battery " + battery.ToString() + "%";
}
void LowerBattery()
{
battery--;
}
}
,
Answer by WaqasHaiderDev · May 30, 2020 at 08:38 AM
Hi, Your InvokeRepeating Function syntax is the problem. try this
InvokeRepeating("LowerBattery", 0, percentDropTime);
Basically the first time parameter is the time gap after which function will start invoking and the second parameter is repeat rate. Also instead of updating UI text in every update call, you can call UpdateBattery() just at end of LowerBattery() function.
Answer by superpup19_unity · May 30, 2020 at 02:37 AM
Hmmm, try this maybe? Honestly I didnt test the code out, but it should work
float batteryPercent = 100f;
void Start()
{
LowerBattery();
}
void LowerBattery()
{
batteryPercent -= 1f;
StartCoroutine(TimerCoroutine());
}
IEnumerator TimerCoroutine()
{
//Replace 4f with how many seconds there is between battery draining
yield return new WaitForSeconds(4f);
LowerBattery();
}
Answer by MenimalsEntertainment · May 30, 2020 at 04:54 AM
Hello @msclafani19, Through the Update() method, you can constantly check the time. I don't know specifically when you want it, but you could try or modify something like this:
void Update(){
int t = (int) Time.time
//you might want to use Time.deltatime, not sure
if (Time.time - t >= 1){
LowerBattery();
t = Time.time;
}
}
Using this, at the beginning, t will be set to 0, and every second, the battery percentage will be lowered and t will be increased. You could also use t++;
to increment t.
https://docs.unity3d.com/ScriptReference/Time-deltaTime.html This might help, it's the documentation for Time.deltaTime and it has a good example of a timer.
Answer by msclafani19 · May 30, 2020 at 04:09 PM
So you all are going to get a kick out of this. Turns out my start() function was lower cased so it wasn't recognized as a Start() function. Must have happened when I was playing around with functions. Despite showing my oblivious mistake, I will keep this question up so those who make the same mistakes can hopefully notice this mistake, too.
Yes I just noticed. I usually pick start function from auto complete of Visual Studio so I did not notice that. But what about your InvokeRepeating syntax? In your syntax, your function was going to be repeated in no time i.e. "0" seconds. And even after correcting Start() function, that was going to cause another problem.
I fixed my InvokeRepeated method using your correction and it works fine now . Thank you
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
InvokeRepeating firing too often 1 Answer
Run Coroutine once, but finish Lerping 2 Answers
How to wait for a co routine to finish when calling from a method 1 Answer