Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Monobehaviour tutorial

Discussion in 'Scripting' started by rainboww, Jun 13, 2019.

  1. rainboww

    rainboww

    Joined:
    Jan 5, 2017
    Posts:
    125
    I try to get a couroutine running but monobehaviour is troubling me.
    I have no idea how to use it properly.
    Somewhere its said it has to be attached to a gameobject i did attach my script to a gameobject is that the idea?
    it said it cannot be instantiated by new how to instantiate it at all?
    But in the end my coroutine keeps returning errors the latest is a NullReferenceException.
    I cannot find much informations about how to use monobehaviour properly in the internet.
     
    Last edited: Jun 13, 2019
  2. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Attach your script to the object in the scene you want your coroutine to run on.
    It is correct you're not suppose to make "new" Monobehaviours. You're suppose to Instantiate them as a part of prefab or load with the scene.
    Or .AddComponent<T> them.
     
  3. rainboww

    rainboww

    Joined:
    Jan 5, 2017
    Posts:
    125
    Thankyou i managed to defeat that errors now (i did search the item in the scene).
    I want to use the coroutine only to make sure my loop does not hang up the interface and i can use a loadscreen but the execution of the coroutine has to be finished before the app continues.

    My questions are now:
    1. is coroutine the right approach?
    2. How do i make sure it is finished before continuing the app(i like to add a return statement after the function is finished, the main generator is finished i just want to rewrite it so the interface does not hang up so i want to have an easy statement there that delays)?
     
    Last edited: Jun 13, 2019
  4. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
  5. rainboww

    rainboww

    Joined:
    Jan 5, 2017
    Posts:
    125
    I try to explain it a bit better.
    I have a mapgenerator which runs on the main thread.
    The mapgenerator creates a bunch of gameobject, fields, and so on.
    On bigger operations it hangs up the game so it no longer responds due to the many loops and executions.
    All in all i think it could really get heavy when generating big maps and if i dont manage it somehow it could hang everything up for several seconds or depending on the settings with big maps might take minutes to complete.

    Now i try to refactor it:

    I want to avoid those notifications from windows that the program does not respond and even when generating big maps the user should be able to see the game has not died and i want to later add a loadingscreen that will show how far the loadingprocess is.

    the mapgeneration spans over several functions so i like to at best only rewrite the deepest nested functions i think the generator has now some 200-400 lines Note: i use only one scene and enable / disable gameobjects as needed

    About the question: I want to have the mainthread wait for the coroutine its just there to make sure update continues.
     
    Last edited: Jun 13, 2019
  6. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Okay, so you'd need to move the map generation logic inside coroutine.

    If you want to split each object generation by one frame do something like this:
    Code (CSharp):
    1. private bool _doneGeneration;
    2. private void IEnumerator GenerationCoroutine() {
    3.     while (hasObjectsToGenerate) {
    4.          // Or do a multiple objects generation, add another loop here, like for
    5.           GenerateAnObject();
    6.           yield return null; // This will prevent hanging main thread
    7.                              // and postpone one operation per frame.
    8.     }
    9.  
    10.     _doneGeneration = true;
    11. }
    Startup a coroutine like so:
    Code (CSharp):
    1. _doneGeneration = false;
    2. StartCoroutine(GenerationCoroutine());
    And until _doneGeneration is not set to true, your generator will not be done.
    You can as well use an Action (event) to notify when you're done generating and subscribe your UI to it.

    Or you can use another coroutine in your UI, waiting for the _doneGeneration to become true.
    (Might need to expose it via property etc).