Decision making coroutine via input
I'm working on a sidescroller game that has the character getting across events. This triggers the text when he collides with the area of the event and waits for the input ( 2 possible options ) explaining the event. I have different lists with the functions for the events, each function has a simple IF statement with a GetKeyDown to switch between one or another option. That calls another function that makes some changes on sliders that tracks the points in that area, shows a text with the outcome and prompts the player to click to continue, which resets the loop and starts again, pulling another random event from the lists depending on the points in the sliders.
My first approach was to set a bool for the event being active on FALSE and then getting into an UPDATE function once it's on TRUE. Of course...pulling the events from a list and using Update causes the problem of calling all the events from the list. So I got to know the coroutines! How would I translate the fact that I'm trying to listen the input of one or another key while the event is active, outside the UPDATE function? I've tried changing the events function into IEnumerators, ending with YIELD RETURN NULL. That caused unity to freeze :P... Here is the sample code (I'm kind of new to game programming, sorry if the code is messy):
{
private static System.Random rnd = new System.Random(); //Construyo el Random de system para pasar el int que va a elegir un index de la lista.
public static EventManager events; //Instancia pública para llamar desde otros scripts.
bool managerEventOn = false; //Booleano para controlar si hay un evento en marcha o no.
public int moralPoolSizeTier1 = 10; //Tamaño del pool para los eventos nivel 1 de Moral.
private Vector2 objectPoolPosition = new Vector2(-15, -25); //A holding position for our unused columns offscreen.
List<Action> InsanityList;
List<Action> moralList;
List<Action> wealthList;
List<Action> encountersList;
public void Start()
{
InsanityList = new List<Action>();
InsanityList.Add(() => seTeQuemaElAsado());
moralList = new List<Action>();
moralList.Add(() => eventVillagerInNeed());
moralList.Add(() => seTeQuemaElAsado());
wealthList = new List<Action>();
encountersList = new List<Action>();
}
//Empieza la prueba
IEnumerator WaitForKeyDown(KeyCode keyCode)
{
while (!Input.GetKeyDown(keyCode))
yield return null;
}
private void Update()
{
Player playerActions = GameObject.Find("Player").GetComponent<Player>();
while (managerEventOn)
{
int r = rnd.Next(moralList.Count);
moralList[r]();
Time.timeScale = 1;
}
}
public void switchingEvent()
{
managerEventOn = true;
return;
}
public void eventVillagerInNeed() //Antes de IEnumerator era Public Void
{
Player playerActions = GameObject.Find("Player").GetComponent<Player>();
managerEventOn = true;
Text eventText;
//Setea el texto del evento en cuestión.
Text textitos = GameObject.Find("eventText").GetComponent<Text>();
textitos.text = "Un aldeano pide tu ayuda. Se lo ve herido... ";
//El jugador elige entre el bien y el mal...
if (Input.GetKeyDown("c"))
{
textitos.text = "Le das un garrotazo en la nuca y le robás toda la papa (Moral -2). Click para continuar.";
//Los stats que cambian y cómo cambian.
playerActions.modifyStat("reduceMoral", 2);
managerEventOn = false;
}
else if (Input.GetKeyDown("v"))
{
textitos.text = "Le das mucho amor y ayudás al pobre hombre (Moral +4). Click para continuar.";
//Los stats que cambian y cómo cambian.
playerActions.modifyStat("addMoral", 4);
managerEventOn = false;
}
return;
}
public void seTeQuemaElAsado()
{
Player playerActions = GameObject.Find("Player").GetComponent<Player>();
managerEventOn = true;
Text eventText;
//Setea el texto del evento en cuestión.
Text textitos = GameObject.Find("eventText").GetComponent<Text>();
textitos.text = "El asadito se te esta prendiendo fuego... ";
//El jugador elige entre el bien y el mal...
if (Input.GetKeyDown("c"))
{
textitos.text = "Apagas el fuego con la pija (Demencia +3). Click para continuar.";
//Los stats que cambian y cómo cambian.
playerActions.modifyStat("reduceSanity", 3);
managerEventOn = false;
}
else if (Input.GetKeyDown("v"))
{
textitos.text = "Buscas agua y apagas el incendio como un ser humano (Demencia -1). Click para continuar.";
//Los stats que cambian y cómo cambian.
playerActions.modifyStat("addSanity", 50);
managerEventOn = false;
}
return ;
}
}
Ideally, one event would be picked from its list and it would be used for the rest of the flow, but it keeps changing events from inside the list. I couldn't manage to make it use the first value retrieved randomly alone.
Answer by Pateeto · Jun 05, 2018 at 08:17 AM
Right now, what happens when running on Unity is that the events flick infinitely in a loop when the character meets an event. It is like it's bringing all the events in the list while being on TRUE so it never stops on the first event it gets from the list.
Your answer
Follow this Question
Related Questions
Do something for 10 sec 2 Answers
Why Is This Coroutine Freezing my Unity5 editor? 2 Answers
Unity 5.6 - Get list of animations 1 Answer
StopCoroutine() Not Working 2 Answers
Spawner within range 1 Answer