Reputation: 171
Hi folks I have this little 2D guy who has 2 states "IsSpeaking" and "Silence" I use them to make the Animator set a bool to true or false and the character seems to be speaking.
I need that the IsSpeaking lasts a different amount of time depending on the amount of text that is displayed on screen like this:
Text dialogueNumber(X) appears
Animate Speaking
Wait "X" time...
Animate Idle
Wait in Idle for next text (dialogueNumber) to appear and restart cycle...
I tried to do this with this little code:
void Update () {
StartCoroutine(IsSpeaking());
}
IEnumerator IsSpeaking()
{
switch (dialogueNumber)
{
case 0:
yield return null;
break;
case 1:
functionsScript.IsSpeaking();
yield return new WaitForSeconds(3);
functionsScript.Silence();
yield break;
case 2:
functionsScript.IsSpeaking();
yield return new WaitForSeconds(6);
functionsScript.Silence();
yield break;
}
yield break;
So the longer the text the longer the Wait time to switch to the silence animation but it seems works fine the first time (case 1) and after it goes to silence it keeps going going back and forth randomly from IsSpeaking to Silence, I'm not sure if this was the best way to achieve this or if there's a better way to switch between states and wait an amount of time?
Thanks a lot for the advice...
Upvotes: 0
Views: 1444
Reputation: 171
Indeed my problem had a bad approach it was easier to make this outside the update function, turned out to be easier to set the number in the same "Next" button as a function called inside the On Click() resulting in something like this:
public void TextID()
{
textID= (int)VD.nodeData.extraVars["cuadro"];
print(textID);
switch (textID)
{
case 0:
break;
case 1:
StartCoroutine(LipsMoving(3));
break;
case 2:
StartCoroutine(LipsMoving(6));
break;
}
}
IEnumerator LipsMoving(int talkTime)
{
funcionesScript.Speaking();
yield return new WaitForSeconds(talkTime);
funcionesScript.Idle();
yield return null;
}
In this way I get the frame ID as the user clicks the button and also runs my coroutine without weird loops. Thanks again for the help and patience it's refreshing to have different points of view to find the right way, hope this is useful to you guys
Upvotes: 0
Reputation: 342
Wouldnt it be better to let the player decide when the next dialogue appears? Not everyone reads the same speed.
Something along the line (hope thats not horribly on the wrong track):
while(!ExitDialogue)
{
animation.Play("Idle");
yield return StartCoroutine(IdleUntilNext()); //waits for player to press the defined button _keyCode_
diaNumber++;
animation.Stop("Idle");
animation.Play("Speak");
StartCoroutine(SpeakDialogue(diaNumber)); //wait for X seconds depending on diaNumber before stopping the animation
animation.Stop("Speak");
}
IEnumerator SpeakDialogue(int diaNumber)
{
switch (diaNumber)
{
case 1:
yield return new WaitForSeconds(3);
yield break;
case 2:
yield return new WaitForSeconds(6);
yield break;
default:
ExitDialogue = true;
yield break;
}
}
IEnumerator IdleUntilNext()
{
while(!Input.GetKeyDown(_keyCode_))
{
yield return null;
}
}
Upvotes: 1
Reputation: 125435
You are calling IsSpeaking
every frame in the Update
function which means it will be started over and over again even when the other one is not yet finished due to WaitForSeconds
. Your current code could literately spawn over 400 coroutines running at- theme time and also trying to "speak" and "silence" at the-same time.
You can use a simple boolean variable to fix that issue.
bool speaking = false;
void Update()
{
//Run only if not running
if (!speaking)
StartCoroutine(IsSpeaking());
}
Then set the boolean variable to false
before breaking out of the switch statement in the coroutine.
IEnumerator IsSpeaking()
{
speaking = true;
switch (dialogueNumber)
{
case 0:
yield return null;
speaking = false;
break;
case 1:
functionsScript.IsSpeaking();
yield return new WaitForSeconds(3);
functionsScript.Silence();
speaking = false;
yield break;
case 2:
functionsScript.IsSpeaking();
yield return new WaitForSeconds(6);
functionsScript.Silence();
speaking = false;
yield break;
}
yield break;
}
Upvotes: 5