Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by esitoinatteso · Jun 07, 2015 at 01:40 PM · coroutineinterfacestate-machinestartcoroutinebehaviour

StateMachineBehaviour + StartCoroutine()

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().

Thanks for your time!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by jxz12 · Apr 28, 2017 at 11:28 AM

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.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by fafase · Jun 07, 2015 at 01:51 PM

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{}

then you can use it as a component.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Mouton · Jun 07, 2015 at 02:16 PM 1
Share

State$$anonymous$$achineBehaviour is a built-in class, derived from ScriptableObject, so he can't derive it from $$anonymous$$onoBehaviour.

http://docs.unity3d.com/ScriptReference/State$$anonymous$$achineBehaviour.html

avatar image fafase · Jun 07, 2015 at 02:24 PM 1
Share

Aaah ok, so yes, add a Init method to your script and when it is created, just pass a $$anonymous$$onoBehaviour reference. Then whenever you need one, you can use it.

You can also override the CreateInstance:

public class $$anonymous$$yClass:State$$anonymous$$achineBehaviour{ private $$anonymous$$onoBehaviour monoBehaviour = null;

 public static void CreateInstance($$anonymous$$onoBehaviour new$$anonymous$$onoBehaviour){
      CreateInstance();  // Call the original one that actually creates the object
      this.monoBehaviour = new$$anonymous$$onoBehaviour;
 }

}

But you also need to make sure the reference is an object that will always be there.

avatar image esitoinatteso · Jun 08, 2015 at 07:41 PM 0
Share

Hi fafase! Thanks a lot for your suggestion! Unfortunately I'm not sure to understand, sorry. Could you please elaborate a bit more how would I use the CreateInstance() function?

Right now the script I've posted ( let's say its name is $$anonymous$$yClass) inherits from State$$anonymous$$achineBehaviour ( as $$anonymous$$outon pointed out), and is placed as a component of a state machine' State.

When the game starts, the script is already there so I can't create an instance of it runtime. That is, unless I manage to address that particular stage and instantiate $$anonymous$$yClass as its component.

A side note:

 this.monoBehaviour = new$$anonymous$$onoBehaviour;

this is not supported with static, it returned me an error.

Thanks a lot again!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

JS Wait for a function to complete - no WaitForSeconds 1 Answer

Stop a coroutine on a single gameobject 1 Answer

Return result of the IEnumerator. 2 Answers

StartCoroutine namespace or type not found 2 Answers

Animation Event and Sate Machine Behaviour 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges