Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 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
5
Question by Dakwamine · Jun 27, 2012 at 08:28 PM · objectcoroutinescriptableobjectcoroutines

How can I use Coroutines in ScriptableObject?

I can only use coroutines in MonoBehaviours. How can I workaround in order to get a similar behaviour in ScriptableObjects?

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

5 Replies

· Add your reply
  • Sort: 
avatar image
7
Best Answer

Answer by Dakwamine · Jun 29, 2012 at 07:25 PM

I can't see a registered user answer here (I will not mention his pseudonym as I am thinking it was intentional to delete it), but I received a mail alert of his sumbission which contained enough information to resolve my query.

The solution was to create another class which extends MonoBehaviour and then call StartCoroutine from this class. I don't use exactly what the user described in his answer but it gives the general idea:

Declare the coroutine using another MonoBehaviour. For example:

 public class Example : MonoBehaviour {
     public static Example instance;
     
     void Start() {
         Example.instance = this;
     }
 }
 
 public class Scriptable : ScriptableObject {
     public void doStuff() {
         Example.instance.StartCoroutine(myCoroutine());
     }
 }

Thanks mister!

Comment
Add comment · Show 4 · 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 HendrysTobar · Oct 04, 2013 at 10:53 AM 1
Share

mmm But in that case you should Add an Example script to an Example Object in the scene, right?

So, it would nulify the ScriptableObject's main objective which is to avoid adding objects to the hierarchy...

Am i right?

avatar image Dakwamine · Oct 04, 2013 at 12:05 PM 0
Share

In that case, you only need one GameObject with an Example $$anonymous$$onoBehaviour on it. This one is used by all the ScriptableObjects as the main "referrer". So you are right.

avatar image HendrysTobar · Oct 04, 2013 at 12:49 PM 0
Share

Umm yeah, you're right, at least, this way you only have to instance one object in the hyerarchy and not one for each script. $$anonymous$$aybe this is something Unity should think to feature in the future, isn't it?

avatar image Owen-Reynolds · Dec 28, 2018 at 06:35 PM 0
Share

This is a little misleading, since it's not the special way ScriptableObjects do it. Static classes have been using the same trick for a while: "put the coroutine on some monobehaviour and call it through a link" is the normal way.

avatar image
2

Answer by ExtraMedicated · Apr 19, 2018 at 01:25 PM

In my case, I wanted to keep the coroutine in a simple class (not inheriting anything), but call the function which triggers the couroutine from a MonoBehaviour.

So what I did was pass the MonoBehaviour to the function that I wanted to start the coroutine from.

Here was my class that has the couroutine (Note that I don't put the name of the coroutine in quotes when calling StartCoroutine()):

 public class VolumeChangeIndicator 
 {
     private float timer, volume;
     private float delay = 0.1F;
     private bool running;
     private AudioClip soundClip;
     private AudioSource audioSource;
     public VolumeChangeSound(AudioSource audioSource, AudioClip soundClip){
         this.audioSource = audioSource;
         this.soundClip = soundClip;
     }
     // This function triggers the coroutine.
     public void VolumeSet(MonoBehaviour caller, float value){    
         volume = value;
         timer = delay;
         if (!running){
             caller.StartCoroutine(VolChangeSound());
         }
     }
     IEnumerator VolChangeSound(){
         running = true;
         while (timer > 0){
             timer -= Time.unscaledDeltaTime;
             yield return new WaitForEndOfFrame();
         }
         timer = 0;
         audioSource.PlayOneShot(soundClip, volume);
         running = false;
     }
 }

Then in my MonoBehavior, I did this:

 public AudioClip volumeIndicatorSound;
 private AudioSource audioSource;
 private VolumeChangeIndicator volumeChangeIndicator;
 
 void Start(){
     audioSource = gameObject.AddComponent<AudioSource>();
      // Instantiate the class...
     volumeChangeIndicator = new VolumeChangeIndicator(audioSource, volumeIndicatorSound);
 }
 
 // This function is called by a slider every time the value is changed.
 public void SetVolume(float value){
     SetVolume(value, true);
 }
 
 public void SetVolume(float value, bool playSound){
     PlayerPrefs.SetFloat("master_volume",value);
     if (playSound){
         // Pass this MonoBehaviour to the function so it can be used to run the coroutine.
         volumeChangeIndicator.VolumeSet(this, value);
     }
 }


Comment
Add comment · Show 1 · 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 Bunny83 · Apr 19, 2018 at 01:35 PM 0
Share

Yes this is also possible and a viable solution but keep in $$anonymous$$d that the coroutine's lifetime is bound to the $$anonymous$$onoBehaviour it's running on. If the $$anonymous$$onoBehaviour is disabled, deactivated or destroyed the coroutine would be ter$$anonymous$$ated. If you have several cases where you want to run a coroutine independent from a particular object it's usually the best to use a monobehaviour based singleton which never gets destroyed.

avatar image
-1

Answer by winxalex · Nov 10, 2015 at 02:22 PM

@Dakwamine You use ScriptableObject when you have creating asset on mind, so you can move across scenes and projects or load run-time. Binding to Scene GameObject's MonoBehaviour you are strangled to that Scene or scenes if you DontDestroy GameObject.

 public class Scriptable : ScriptableObject {
    GameObject PrefabGameObjectWithExampleMonoBehaviour;
      public void doStuff() {
         PrefabGameObjectWithExampleMonoBehaviour.GetComponent<Example>().StartCoroutine(myCoroutine());
      }


@Bunny83 You not need to make instance of the PrefabGameObjectWithExampleMonoBehaviour by including Scriptable which is referencing PrefabGameObjectWithExampleMonoBehaviour, Unity creates hidden instance which when there is no other instance can be consider as singleton. }

You can now move .asset and prefab as pack and you wont lose functionality.

Edit: Code is pseudo!

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 astracat111 · Apr 11, 2017 at 07:40 PM

I thought you did like OnEnable() inside of the scriptable object...

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
0

Answer by michaelfelleisen · May 19, 2021 at 03:47 PM

I made a small forum thread about this which might be interesting. Its an alternative to the stuff I saw here and its an awesome in my opinion.

https://forum.unity.com/threads/scriptableobjects-and-coroutines.1112239/

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

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

12 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

Related Questions

How to change this using a coroutine 1 Answer

Yield return null? 3 Answers

CancelInvoke cant cancell,Updating InvokeRepeating 1 Answer

StopCoroutine with IEnumerator not working 2 Answers

coroutine not running after yield new WaitForSeconds 1 Answer


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