- Home /
AI function/coroutine animation issues
Gentlemen.
Currently, I'm writing some comprehensive AI. I'm coding reactions to a large variety of situations, and referring to them within the Update function, but it's not going so well.
One of the biggest problems I have is with attacking; Despite the fact that the animations have their wrap modes set to Once, they just don't stop. Even when the function shouldn't be able to activate because of a boolean check variable. Here's an example:
This is the bit that checks for certain conditions:
var canAttack = true;
function Update () {
if(Vector3.Distance(Player.transform.position, transform.position) < playerAttackRad && canAttack)
Attack1();
}
And this is the Attack function:
function Attack1 () {
rigidbody.velocity = Vector3.zero;
yield WaitForSeconds(.5);
animation.Play("StandAttack1");
canAttack = false;
yield WaitForSeconds(.8);
animation.Stop("StandAttack1");
dodgeJump();
yield;
}
As you can see, in order for the function to be triggered, canAttack has to be true, which it starts out as. And then when the function is executed, it's changed to false, and set back after a certain amount of time.
But despite this, the animation will either not play, play repeatedly, or begin to spaz out after playing correctly the first time. Any wisdom to impart?
~~EDIT~~
Here's the current state of the function, which still isn't working as it should:
function Attack1 () {
rigidbody.velocity = Vector3.zero;
animation.Play("StandAttack1");
canAttack = false;
dodgeJump();
}
~~DOUBLE EDIT~~
Here's a video showing off the issue:
http://www.youtube.com/watch?v=zcfEOgqgF4A
As you can see, the animation is playing more than once, which I don't think it should be able to what with it being set to Once. Also note the spazzing near the end of each loop.
~~TRIPLE EDIT~~
Here's the re-enabling code:
function Update () {
if(!canAttack)
AttackEnable();
}
function AttackEnable () {
yield WaitForSeconds(Random.Range(5,8));
canAttack = true;
}
Answer by Waz · Jul 15, 2011 at 03:44 AM
Remove that new Update code and only use (after grokking) this:
function Attack1 ()
{
rigidbody.velocity = Vector3.zero;
animation.Play("StandAttack1");
canAttack = false;
yield WaitForSeconds(2.0);
canAttack = true;
}
Notice:
set the canAttack guard before yielding
let the animation end itself, no need to stop it
I've left out dodgeJump(), since I don't know what it does.
Ah, there we are. This one fixed the spazzing and multiple execution issues, but I had to have the animation set to a higher layer than all of the others to stop it from cutting out midway through. Thanks, Warwick!
Answer by Waz · Jul 12, 2011 at 11:53 AM
You are restarting the coroutine for 0.5 seconds - about 30 times- before you set canAttack to false. That will make for good spazage.
Wait, so what does Yield DO, exactly? Your answer gives me the impression that I've been misunderstanding it.
A yielded coroutine only delays its execution. Being yielded does not mean the coroutine cannot be called again. If you run that coroutine inside a for loop 100 times, then you'll have 100 yielded coroutines running at the same time.
Yield exits the function, and re-enters it at the yield point after the yield-instruction specified amount of time/frames.
function Example()
{
Debug.Log("this is called in the frame the function is called");
yield;
Debug.Log("this is called the frame after");
yield WaitForSeconds( 1.0 );
Debug.Log("this is called a second later");
}
After testing it without any yield statements in the code, it's still spazzing out, it seems. What else could it be?
I think we'll need to see a video or at least more detail to understand what sort of problem it is. Certainly there is nothing wrong with the updated code fragment you've now posted.
Your answer
Follow this Question
Related Questions
Animation method/coroutine playable once or loop 0 Answers
Coroutine will be executed only once, why? 1 Answer
How to make Reloading animation play ONCE 0 Answers
Coroutine a function within a loop? 1 Answer
Death animation play more than once 1 Answer