Hi there! I’d like to know, if it’s possible, how to StartCoroutine() inside a StateMachineBehaviour script.
I’ve tried the following:
IEnumerator WaitSomeThenResetStuff (Animator anim){
yield return new WaitForSeconds(4f);
//Reset stuff
anim.ResetTrigger("stuff");
}
// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
StartCoroutine(WaitSomeThenResetStuff(animator));
}
But " StartCoroutine" is unknown to classes that inherits from StateMachineBehaviour.
I thought ( because my knowledge is approssimative) to solve the problem by adding an interface to MonoBehaviour but another error showed up… maybe I made some mistakes or maybe that’s not the best approach.
I ended up using the StateMachineBehaviour’s Update with a clock to do the same thing, caching Time.time inside OnStateEnter().
Hi, I’m a little late but I came across a similar problem and came up with a few solutions that work.
The first is to use a MonoBehaviour attached to the animator’s GameObject, and have the function inside that starts the coroutine be public so that you can call it like so:
public class MyScript : MonoBehaviour {
public void DoCoroutine() {
StartCoroutine(/*your routine*/);
}
}
public class MyState : StateMachineBehaviour {
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
animator.GetComponent<MyScript>().DoCoroutine();
}
}
and another way that I’d use if possible would be to just use animation events, which are nice if you like working entirely inside Unity’s animation system, which it seems like you do since you’re using the StateMachineBehaviours already.
StartCoroutine needs a MonoBehaviour to be used. Your StateMachineBehaviour seems not to be so you probably have a constructor call to create the StateMachine object. This constructor is most likely called from a MonoBehaviour. That’d be when you pass the MonoBehaviour:
private MonoBehaviour monoBehaviour = null;
public StateMachineBehaviour(MonoBehaviour monoBehaviour){
this.monoBehaviour = monoBehaviour;
}
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
this.monoBehaviour.StartCoroutine(WaitSomeThenResetStuff(animator));
}
the other solution is to make your StateMachine inherits from MonoBehaviour which would actually make it consistent with the current naming. Using the term Behaviour generally implies that it includes the Behaviour class in it (not necessarily though).
public class StateMachineBehaviour:MonoBehaviour{}