Problem with array and coroutine...Sometimes Works!!!
hi guys, i need help with something, i'm a bit of a newbie to C#, and i'm developing a horror video game.
One of the things I want this code to do is to make is when the player goes through a trigger ( static bool in other Sript) certain lights ( in an array) turn off for a few seconds and then reappear, it sounds simple, doesn't it? The point is that I do not know why this code sometimes works and sometimes it does not, in fact lately the number of times it is not working is more. Then I leave the code. I hope you can help me. Even if you know of a better or more optimized, or less bugged way to do this, I would also be very grateful if you would let me know. Greetings friends, thank you very much in advance.
public class ParpadearLuces : MonoBehaviour
{
public GameObject[] _LucesSubterraneo;
public GameObject craneo;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (CalaveraTrigger.apagarLuces==true)
{
StartCoroutine(esperar10Segundos());
}
void ApagarLuces()
{
for (int i = 0; i < _LucesSubterraneo.Length; i++)
_LucesSubterraneo[i].SetActive(false);
}
IEnumerator desaparecerCraneo()
{
yield return new WaitForSeconds(1);
craneo.SetActive(false);
for (int i = 0; i < _LucesSubterraneo.Length; i++)
_LucesSubterraneo[i].SetActive(true);
CalaveraTrigger.apagarLuces = false;
Destroy(this);
}
IEnumerator esperar10Segundos()
{
yield return new WaitForSeconds(10);
ApagarLuces();
StartCoroutine(desaparecerCraneo());
}
}
}
Answer by xxmariofer · Jun 11, 2021 at 08:08 AM
You have an issue with the }, and also you need to set CalaveraTrigger.apagarLuces back to false, or it will call apagar luces infinite times and will create unexpected behaviour
public class ParpadearLuces : MonoBehaviour
{
public GameObject[] _LucesSubterraneo;
public GameObject craneo;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (CalaveraTrigger.apagarLuces==true)
{
StartCoroutine(esperar10Segundos());
}
}
void ApagarLuces()
{
for (int i = 0; i < _LucesSubterraneo.Length; i++)
_LucesSubterraneo[i].SetActive(false);
}
IEnumerator desaparecerCraneo()
{
yield return new WaitForSeconds(1);
craneo.SetActive(false);
for (int i = 0; i < _LucesSubterraneo.Length; i++)
_LucesSubterraneo[i].SetActive(true);
CalaveraTrigger.apagarLuces = false;
Destroy(this);
}
IEnumerator esperar10Segundos()
{
CalaveraTrigger.apagarLuces=true;
yield return new WaitForSeconds(10);
ApagarLuces();
StartCoroutine(desaparecerCraneo());
}
}
Thank you so much. Your answer could be the solution. As you mentioned, I have reviewed the script and I have realized that I had already set the bool to FALSE in the "desaparecerCraneo()" coroutine However, to prevent the bool (CalaveraTrigger.apagarLuces ) from staying false I have added the command to destroy the gameObject at the end of the coroutine (is that the correct way to do it? Are there better ways?). On the other hand, I insist on understanding why sometimes it works and sometimes not, since in many of the scripts that I use coroutines I have this problem. I will be attentive to a possible answer.
In these $$anonymous$$utes I have realized that it is better that in voidOnTriggerEnter () go a boolean in true inside it. And in the update () put an if (boolean == true) {execute the coroutine) ... this way it works every time. Although I still have doubts about whether destroying the object is a good way to do what I was talking about in the previous comment.
Hello,
No deleting the gameobject to avoid "apagarluces" to be set to false is not a good solution. Update gets called every frame, and since you are waiting 1 second to reset the variable to false you are starting (if your game runs at 60fps) 60 times.
To avoid this, as i suggested set
CalaveraTrigger.apagarLuces=false;
in the previous code i posted there was an error, change
IEnumerator esperar10Segundos()
{
CalaveraTrigger.apagarLuces=true;
yield return new WaitForSeconds(10);
ApagarLuces();
StartCoroutine(desaparecerCraneo());
}
to
IEnumerator esperar10Segundos()
{
CalaveraTrigger.apagarLuces=false;
yield return new WaitForSeconds(10);
ApagarLuces();
StartCoroutine(desaparecerCraneo());
}
You solved my life ... thank you, all the bugs were solved, it is incredible how I did not see these things. I guess experience will help me. Thank you. :)
You are welcome, if it worked please accept the answer as correct for future readers