Start coroutine on an inactive/de-activated GameObject

前端 未结 2 574
余生分开走
余生分开走 2020-12-12 02:47

I have the following code:

void Start()
{
    gameObject.SetActive(false);
    StartCoroutine(Load());
}

IEnumerator Load()
{
    yield return new WaitForSe         


        
相关标签:
2条回答
  • 2020-12-12 03:43

    What I do to avoid stopping coroutine is have a game object that does not get deactivated.

    public class CoroutineHandler : MonoBehaviour
    {
        private static CoroutineHandler instance = null;
        public static CoroutineHandler Instance
        {
            get
            {
                if(instance == null)
                {
                    GameObject inst = new GameObject("CoroutineHandler");
                    DontDestroyOnLoad(inst);
                    instance = inst.AddComponent<CoroutineHandler>();
                }
                return instance;
            }
        }
    }
    

    Then use this for such coroutines by using CoroutineHandler.Instance.StartCoroutine(RoutineMethodHere());.

    If you do not want something like this, since it can go wrong or cause leaks if not handled correctly, you can try using Invoke("MethodName", delay);

    0 讨论(0)
  • 2020-12-12 03:47

    You cannot start a coroutine function from a script that has its GameObject de-activated.

    The StartCoroutine function is a function under the MonoBehaviour class. When you have to start a coroutine on a deactivated GameObject, you need a reference to a MonoBehaviour object that has an active GameObject.

    Two ways to do this:

    1. Use an already existing GameObject that's unlikely to be deactivated. In my case, I usually use the camera. I access the camera's MonoBehaviour since it's likely to be activated then use it to start the coroutine function.

    I suggest you use this method.

    Replace the code in your Start function with the one below:

    //De-activate this GameObject
    gameObject.SetActive(false);
    //Get camera's MonoBehaviour
    MonoBehaviour camMono = Camera.main.GetComponent<MonoBehaviour>();
    //Use it to start your coroutine function
    camMono.StartCoroutine(Load());
    

    2. Attach the script to an empty GameObject and the script on the empty GameObject will control or be able to activate/de-activate the other GameObject.

    The script with the coroutine function you expect to run on a de-activated GameObject (Attach it to the GameObject you wish to de-activate):

    public class YourDeactivatableScript: MonoBehaviour
    {
        public IEnumerator Load()
        {
            yield return new WaitForSeconds(waitTime);
            gameObject.SetActive(true);
        }
    }
    

    Now, let's say that you want to deactivate a GameObject named "Cube" that has the YourDeactivatableScript script attached to it but still be able to start its Load coroutine function, create an empty GameObject with a new script, then start the Load function from it.

    Create an empty GameObject then attach this script to it:

    public class LoadFuncCallerScript: MonoBehaviour
    {
        GameObject targetObject;
    
        public void Start()
        {
             //Find the GameObject you want to de-activate
            targetObject = GameObject.Find("Cube");
            //De-activate it
            targetObject.SetActive(false);
            //Get it's component/script
            YourDeactivatableScript script = targetObject.GetComponent<YourDeactivatableScript>();
            //Start coroutine on the other script with this MonoBehaviour
            StartCoroutine(script.Load());
        }
    }
    

    The coroutine is now started from another script named LoadFuncCallerScript.

    0 讨论(0)
提交回复
热议问题