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

Is it possible to get a component of a sibling?

Discussion in 'Scripting' started by Flynn_Prime, Jul 29, 2017.

  1. Flynn_Prime

    Flynn_Prime

    Joined:
    Apr 26, 2017
    Posts:
    383
    I have a prefab that gets instantiated and I would like to access it's sibling. Is there a simple way to do this?
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    well 'transform.parent' is the parent GameObject of both... accessing its children will all be siblings of that one.

    If you're not spawning the prefab as a child of anything, and by sibling you mean another GameObject in the root of the scene you're in.

    Well, GameObject.scene gives you a reference to the scene the GameObject is in (there can be more than one if a multi-scene scene), and with that you can call scene.GetRootGameObjects to get a reference to all the root GameObjects... one of which being the sibling.

    Of course... determing which one is the sibling you're concerned with... well you'll need some type of identifier. Maybe named accordingly, or tagged accordingly, or sticking an identifying Script on it accordingly?

    Personally all my prefabs/entities/things of substantial value, get a 'Entity' script attached to its root (the top most GameObject of the prefab for example), and I keep a HashSet of all the active 'Entities' in the scene for easy lookup.
     
    rakkarage likes this.
  3. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    You can get the child index using transform.GetSiblingIndex() and then add one to it to get it's neighbour. Then you can do what @lordofduct mentioned and use the parent (e.g. myObject.transform.parent.GetChild( newIndex ) )
     
    Bunny83, rakkarage and Flynn_Prime like this.
  4. Flynn_Prime

    Flynn_Prime

    Joined:
    Apr 26, 2017
    Posts:
    383
    Thanks to you both!
     
  5. MaxxVelocity

    MaxxVelocity

    Joined:
    Sep 29, 2019
    Posts:
    12
    I'm new to this (and late to respond), but this has come up for me, and I am thinking I'll try going with getting the parent, and then from the parent, using GetComponentInChildren. The reason being: it's a bad idea to assume that any physical position in a sequence will have a specific identity. Nothing in the code can can guarantee that a +1 index is going to be the correct sibling if more than one exists.

    I can see the GetSiblingIndex working if you added a search criteria, such as a loop that keeps doing a GetComponent until it finally finds something which is not null. That might work better in certain cases.

    In my case, I only want one instance of a component to exist within the parent's children, so doing the parent-down way is the least code complexity.

    (BTW, I can attest this works, I already tried it.)
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,541
    Yes and no. In the past (before GetSiblingIndex was even a thing) there was no guarantee about the order of objects are components within an object. However when Unity introduced the new audio filter system (I think that was around Unity5 ?!?) they actually introduced a consistent component order. From that point on it was possible to rearrange components in the inspector and you got a consistent order.

    While I do get your worries and I usually do not rely on such relationships, it does work if you make sure you actually keep the order correct in the editor. We also got the SetSiblingIndex method to reorder the objects at runtime.
     
  7. ow3n

    ow3n

    Joined:
    May 8, 2016
    Posts:
    14
    Get the parent then the children components:

    Code (CSharp):
    1.  
    2. [SerializeField] GameObject parent;
    3. [SerializeField] SpriteRenderer[] childSprites;
    4.  
    5. void Awake()
    6. {
    7.     parent = transform.parent.gameObject;
    8.     childSprites = parent.GetComponentsInChildren<SpriteRenderer>();
    9. }
    10.