My game uses C# and coroutines for scripting cutscenes and dialogue trees. Looks something like this:
public IEnumerator test( )
yield return StartCoroutine( bob.say( "Hello, I'm Bob" ) ) ;
yield return StartCoroutine( jim.walkToPoint( 10, 20 ) ) ;
yield return StartCoroutine( jim.say( "Hey Bob, I'm Jim" ) ) ;
Each of these statements can pause the script, and it can have other subroutines underneath it that also pause the script until some event has occurred (for example, until player has acknowledged that they have read some text). That’s why we need to use “yield return StartCoroutine”. It works great…
But I’d like this to be easier for non-programmers to use. Unfortunately the syntax is pretty ugly and frightening. Would there be any way to make it look more like this?
bob.say( "Hello, I'm Bob" ) ;
jim.walkToPoint( 10, 20 ) ;
jim.say( "Hey Bob, I'm Jim" ) ;
Can’t figure out how to do this in C# (no macros, so can’t do it that way). I don’t have much C# experience, can anyone think of way to simplify this code?
Using coroutines you can’t get around the need for the “yield return” bit, but you can move the “StartCoroutine” into the called function, so long as that function has a sensible Component to call it on. It won’t necessarily feel any better though.
Another approach is to use a generic wait method on bob, jim, etc, which is not shorter but is perhaps tidier:
bob.say("Hello, I'm Bob");
yield return bob.wait();
yield return jim.wait();
So in these cases ‘wait’ would return the Coroutine, and would internally call StartCoroutine passing a private IEnumerator method. You could make ‘wait’ actually be a member of the caller if that helps.
There are a lot of different ways to structure it, but I don’t think any are ideal.
Considered using a Queue? Enque everything up on a manager class, then dequeue the items one at a time in a coroutine? It will make your code more complex, but should simplify the user code.
Pseudo code example. Its rough, and the syntax is probably wrong, but you get the idea.
public delegate IEnumerator MyAction (string parameter);
while (actionsToExecute.Count == 0) yield return null;
yield return StartCoroutine (actionsToExecute.Dequeue());
Your methods would need to add the coroutine to your queue, instead of being the coroutines themselves.
Note in C# you can use lamda functions, which I believe are pretty close to macros. Either way they may help with this.