- Home /
How can I make that the waiting time in StartCoroutine will take effect when changing the value in inspector when the game is running ?
The problem is that the variable speedChangeWait is out of the while loop to prevent memory leak but then when I'm changing the speedChangeWait value while the game is running in the inspector it's not really changing it. Only when I'm starting the game over again it will take effect.
How can I make that it will take effect when changing the speedChangeWait value while the game is running, Without put it in the while to prevent memory leak ?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GateControl : MonoBehaviour
{
public Transform door;
public float doorMovingLength = 64f;
public float constantDoorSpeed = 1f;
public float currentDoorSpeed;
public bool randomDoorSpeed = false;
public int speedChangeWait = 3;
[Range(0.3f, 10)]
public float randomSpeedRange;
private Vector3 originalDoorPosition;
private bool isRising = true;
private float fraq = 0;
// Use this for initialization
void Start()
{
originalDoorPosition = door.position;
StartCoroutine(DoorSpeedWaitForSeconds());
}
// Update is called once per frame
void Update()
{
if (isRising)
fraq += Time.deltaTime * currentDoorSpeed;
else
fraq -= Time.deltaTime * currentDoorSpeed;
if (fraq >= 1)
isRising = false;
if (fraq <= 0)
isRising = true;
fraq = Mathf.Clamp(fraq, 0, 1);
door.position = Vector3.Lerp(originalDoorPosition,
new Vector3(originalDoorPosition.x, originalDoorPosition.y, doorMovingLength),
fraq);
}
IEnumerator DoorSpeedWaitForSeconds()
{
var delay = new WaitForSeconds(speedChangeWait);//define ONCE to avoid memory leak
while (true)
{
if (randomDoorSpeed == true && randomSpeedRange > 0.3f)
currentDoorSpeed = Random.Range(0.3f, randomSpeedRange);
if (!randomDoorSpeed)
currentDoorSpeed = constantDoorSpeed;//reset back to original value
yield return delay;//wait
}
}
}
Answer by Harinezumi · Jul 31, 2018 at 08:38 AM
The problem is that the WaitForSeconds
is created with the value of the variable you pass it, so updating the variable will not change the WaitForSeconds
object. Instead, you can check a timer variable each frame, and if its value is greater than speedChangeWait
, then your wait has ended:
IEnumerator DoorSpeedWaitForSeconds () {
float timer = 0;
while (true) {
// rest of the code is the same, just replace the yield return delay with this:
while (timer < speedChangeWait) { timer += Time.deltaTime; yield return null; }
timer = 0;
}
}
You may also want to reset the timer whenever you change the value of speedChangeWait
in the Editor using OnValidate()
and making timer
a member variable:
#if UNITY_EDITOR // make OnValidate() only exist in Editor mode
private void OnValidate () {
timer = 0;
}
#endif