- Home /
Waiting for a method to signal it is done before launching it again
I am making a visualization in C# where there are a lot of gamemove related 'actions'. An action can be 'walk to', 'say to' or 'pick up' etc etc. If the story I want to visualize goes like this for example:
Player walks to NPC1.
Player says to NPC1.
In this case i obviously want the first action (sentence) to be completed before starting the second one. My code looks as follows:
void Update () {
parseScenario ();
}
The definition for the parseScenario function is the following: (small theoretical background (since the implementation is a bit different): entry is a list which contains a number of gamemoves (sentences) to complete. Look at this like a parent list, since each of these lists can contain a number of other gamemoves (sentences) to complete, this is indicated by a _next field which is the next one to do)
public void parseScenario () {
foreach (string e in entry) {
parseEntryLine(e);
}
}
The parseEntryLine method looks like this:
public void parseEntryLine (string gm_label) {
currentGM = findGameMoveByLabel (gm_label);
if (currentGM.isBrick ()) {
//Interprete it and perform the animation for it
animateExpr(currentGM);
//Check if it has a next
if (currentGM._next != null) {
parseEntryLine (currentGM._next);
}
}
}
And the animateExpr method is just a function which contains a really big switch statement. Based on what the contents of the 'action verb' is, I start a method which performs the action in here.
Now the problem is that obviously when I run it like this the entire story just gets executed immediately.
I cannot figure out how to wait for an action to complete before starting a new one. Please note that these actions do not have a fixed timespan. (Some require input from the player as well).
I hope the question is clear, if not please ask me to make it more clear.
Answer by Kiwasi · Dec 17, 2014 at 10:25 PM
You would typically do this in one of several ways. Listed in my order of preference.
Using a coroutine. Simply yield every frame until the task is done
Using a call back. Pass the method a delegate to call when it is completed
Using bool checking. Set a bool as a flag to identify when each task is done
Thank you @Bored$$anonymous$$ormon! I thought coroutines might be the way to go. But I cannot figure out how to use it properly. Does everything else wait for the complete function to finish before executing the next line of code?
What are the changes required to the animateExpr function ?
Control gets passed back to the Unity engine. In essence this means all of the other Update methods are called.
Here is some pseudo code
This starts the coroutine chain. You only want to call it once
void Start (){
StartCoroutine(ParseScenario());
}
We can yield the result of StartCoroutine. This means that each string will wait for the last string to be processed before resu$$anonymous$$g. The yield return null at the end covers you in case there are no strings in entry.
public IEnumerator parseScenario () {
foreach (string e in entry) {
yield return StartCoroutine(parseEntryLine(e));
}
yield return null;
}
Do the same thing on parseEntryLine.
$$anonymous$$aking a guess at animateExpr
public IEnumerator animateExpr(...){
while (doingStuff){
// Do stuff
// Use this to wait a frame
yield return null;
// Exit the loop when you are done
}
}
If you do use a while loop be sure to save the game before hand. Unity will freeze unrecoverably if you ask it to do an infinite loop.
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Multiple Cars not working 1 Answer
A node in a childnode? 1 Answer
Unhandled exceptions while deploying on Visual Studio 1 Answer