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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How to get notification if children have added/moved/removed?

Discussion in 'UGUI & TextMesh Pro' started by Assassinbeast, Apr 9, 2015.

  1. Assassinbeast

    Assassinbeast

    Joined:
    Nov 4, 2013
    Posts:
    31
    Hello. How can i get a notifcation when a child have been placed on a gameobject?

    When i derive from UIBehaviour, then i can use OnTransformParentChanged() when the gameobject have changed its own parent, but how do i get the notification if a child object have been added, moved or removed?
     
  2. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
    Simple answer is you can't through normal behaviour.
    What you would need to do is attach a script to your parent GO which tracks the number of children (and/or their order), then validate that on update. If it changes, then do what you need to do.

    Hope that helps.

    Another way, would be to have the script on the Parent GO manage the adding / removal of children instead of just adding children directly. SO having a method which takes the new child and then adds it to the parent (plus anything else).
     
  3. Assassinbeast

    Assassinbeast

    Joined:
    Nov 4, 2013
    Posts:
    31
    Yes, but how does the "Horizontal Layout Group" (unitys buildin) component do it? Every time i put a child on, then it automaticly updates so all children will have the same horizontal width and updated positions.
     
  4. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
    IT_1 likes this.
  5. Assassinbeast

    Assassinbeast

    Joined:
    Nov 4, 2013
    Posts:
    31
    Ahh okay, thanks.
    So the first solution you gave me was to check update every loop.
    And the second solution to "know" when to update and do it manually.

    So in conclusion, the first solution is easier to manage but a little slower because i have to "check" every loop in the update(), and the second solution is a little harder to manage because i have to "know" and manually udpate it.

    Am i correct?
     
  6. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
    That's pretty much it. Unity doesn't have any "Child" style events or watches.

    The second option is probably easier because you are managing the GO from itself, pretty much the same way as public property getters and setters, e.g.:

    Code (CSharp):
    1. public void AddChildToGO(gameobject GO)
    2. {
    3.     go.transform.parent = this;
    4.     NotifyChildAdded();
    5. }
    *Note, the code above is just an example and from memory (so probably won't compile, but you should get the idea)

    **Edit, if you are also adding UI elements as children, you'll see to use the SetParentAndAlign function (again from memory, the function to align UI which does more than just add a child)
     
    Assassinbeast likes this.
  7. Assassinbeast

    Assassinbeast

    Joined:
    Nov 4, 2013
    Posts:
    31
    Cool, thanks for your help :)
     
  8. CoalCzar

    CoalCzar

    Joined:
    Nov 25, 2012
    Posts:
    22
  9. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
    Thanks for the info @CoalCzar useful info. Knew about that function, but they added UI specific functions to make it easier.
    Although now with 5.2, the goal posts have changed again to 3D meshes and base GO's, may have to dig in to it again :D
     
  10. ofusion

    ofusion

    Joined:
    Dec 5, 2013
    Posts:
    27
    OnTransformChildreChanged is not work in editor mode.
    Is it possible to get notification when a scene object' children have added/moved/removed?
     
  11. xophiix

    xophiix

    Joined:
    Dec 9, 2014
    Posts:
    3
    OnTransformChildreChanged only works for your first level of child list. So when your child is adding an grandchild, you won't be notified.
     
  12. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
    Only really accurate way is to either create your own AddChild methods or have a script monitoring transform.count for all it's children. Either way it's a bit more overhead.

    if using OnTransformChildrenChanged, you will need to filter the event up to parents from children (if you have grandchildren for example)
     
  13. unity_123uzunince123

    unity_123uzunince123

    Joined:
    Mar 21, 2020
    Posts:
    2
    ExecuteAlways or ExecuteInEditMode attributes can be used
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. [ExecuteAlways]
    4. public class RefreshChildrenPositions: MonoBehaviour
    5. {
    6.     private void OnTransformChildrenChanged()
    7.     {
    8.         print(0);
    9.     }
    10. }
    11.  
     
  14. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,873
    Six years later that callback still doesn't appear to work correctly: it is invoked BEFORE the transform list is changed, rather than AFTER, so that if you need to react to the change ... you can't. You will find that the list of child-transforms is wrong: it hasn't changed (the opposite of the method name :)).

    Instead, the way that Unity's own team did it - manually polling! - appears to be the only correct solution.
     
    Wappenull likes this.
  15. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    245
    Hello, you can delay execution through EditorApplication.delayCall https://docs.unity3d.com/ScriptReference/EditorApplication-delayCall.html
     
  16. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,873
    Bearing in mind that these are MonoBehaviour callbacks, i.e. this is outside the Editor. The method you cite is a good one for the Editor half of the solution, but MB needs code both in Editor and Rutnime.

    We can fudge it at runtime, by delaying one frame before reacting, but that causes flickering visually so its not great.
     
  17. theNecromuncher

    theNecromuncher

    Joined:
    May 5, 2017
    Posts:
    5
    If anyone is still here 7 years after the original post - assuming I get the event of a child being added/removed, is there a way to get a handle on that specific child?
     
  18. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,873
    No. This API was never properly planned, it's more of a hack IMHO.

    However: update to my post from last year: the broken behaviour appears to be fixed in recent LTS releases. I don't know which version, I didn't see it in the release notes, but I noticed that my unit tests started passing in more recent UnityEditor versions, and seem to be stable/consistent.