Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Can't set parent inside OnDisable method.

Discussion in 'Scripting' started by harryblack, Nov 18, 2020.

  1. harryblack

    harryblack

    Joined:
    Dec 26, 2016
    Posts:
    19
    Hello,

    I am using Unity 2019.4.1f1 for my project. I created an object pooler inside my game and for each pooled object that gets disabled I tried to set its parent to a root(pool) object and I made this call inside OnDisable.

    upload_2020-11-18_15-5-17.png

    This is the PutBackObject method..
    upload_2020-11-18_15-4-43.png

    now as I understand, I can't change hierarchy while the object is being disabled (for some reason)..
    So I would like to know
    1.) Is there a way where I can achieve this reparenting while still using gameObject.SetActive(false);
    2.) Also is there a way in which I can add a method like "OnPreDisable" and get the unity system to call it just before OnDisable somehow?

    Thanks in advance.
     
  2. rubcc95

    rubcc95

    Joined:
    Dec 27, 2019
    Posts:
    222
    Since you can't disable or enable a gameObject same frame you set the parent, you can use the same implementation making PutBackObject a Coroutine. But that's a bit hack... You can't anyway call, instead of gameObject, some method poolable.Disable() ?

    Code (CSharp):
    1. public class Poolable : MonoBehaviour
    2. {
    3.     protected virtual void Disable()
    4.     {
    5.         if (Pooler != null)
    6.             Pooler.PutBackObject(gameObject);
    7.         gameObject.SetActive(false);
    8.     }
    9. }
     
  3. harryblack

    harryblack

    Joined:
    Dec 26, 2016
    Posts:
    19
    Thanks for the suggestion rubcc95.

    I can.. But its just that I will have to now look for all the scripts that use SetActive(false) on objects that have to be pooled and then make them call my method.. Just thought might be there can be some way where I will not have to make those changes...
     
  4. rubcc95

    rubcc95

    Joined:
    Dec 27, 2019
    Posts:
    222
    So try this, but gameObject is going to be changed next frame.

    Code (CSharp):
    1. public class Poolable : MonoBehaviour
    2. {
    3.     public ObjectPooler Pooler { get; set; }
    4.  
    5.     protected virtual void OnDisable()
    6.     {
    7.         if (Pooler != null)
    8.             StartCoroutine(Pooler.PutBackObject(gameObject));
    9.     }
    10. }
    Code (CSharp):
    1. public IEnumerator PutBackObject(GameObject instance)
    2. {
    3.     yield return null;
    4.     //your regular PutBackObject Method;
    5. }
     
    harryblack likes this.
  5. harryblack

    harryblack

    Joined:
    Dec 26, 2016
    Posts:
    19
    Thanks rubcc95..
    It worked like a charm :)
     
  6. harryblack

    harryblack

    Joined:
    Dec 26, 2016
    Posts:
    19
    Just for future reference.. I had to move
    StartCoroutine(Pooler.PutBackObject(gameObject));
    inside another object(that will remain active throughout the game) in a method SendToPool(GameObject instance).

    Then called this method inside OnDisable. otherwise coroutine wont work.
     
  7. rubcc95

    rubcc95

    Joined:
    Dec 27, 2019
    Posts:
    222
    Oh sure, I forgot it completely, Coroutines break when scripts are disabled. :rolleyes:
    Yeah, just a non-disabled object should call it. If ObjectPooler is a MonoBehaviour, just:

    Code (CSharp):
    1. public class Poolable : MonoBehaviour
    2. {
    3.     public ObjectPooler Pooler { get; set; }
    4.     protected virtual void OnDisable()
    5.     {
    6.         if (Pooler != null)
    7.             Pooler.StartCoroutine(PutBackObject(gameObject));
    8.     }
    9. }
     
    harryblack likes this.