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

C# Loop help

Discussion in 'Scripting' started by darkAbacus247, Apr 6, 2015.

  1. darkAbacus247

    darkAbacus247

    Joined:
    Sep 7, 2010
    Posts:
    251
    Hey all,
    is there a simple way to find the last parent shared between two children?

    Say I have 5 game objects (A,B,C,D,E), of these E is parented to D, and C parented to B. B & D are then parented to A. Sorry for any confusion...

    I'd like to run a script that asks E to traverse up the chain until it finds the last parent shared with C (in this example this would be A), please do note that I'm not looking to use 'transform.root'. I know in this example that would work, though the project often has a far more complex parenting system, finding the root would not give a desired result. Say I had something more like A-Z where the last shared parent for two elements is M, finding the root would result in A when I'm looking for M.

    Hopefully this makes sense, I'm pretty sure it's just a loop statement but for any reason I'm not able to work it out...
     
  2. Galf

    Galf

    Joined:
    Feb 24, 2013
    Posts:
    27
    So you're looking for most recent common ancestor? If there's no ordering to your chain, the simplest thing I can think of (note: not the most efficient) would be:

    - create a list of the entire ancestor tree for element1
    - create a list of the entire ancestor tree for element2
    - for each ancestor in element1's ancestor tree, check if it exists in element2's ancestor tree. If it does, you're done, return it.
     
  3. darkAbacus247

    darkAbacus247

    Joined:
    Sep 7, 2010
    Posts:
    251
    yep most recent ancestor,
    was thinking the same but it might be pretty expensive was hoping there'd be a cheaper way. There's no real order, objects group / ungroup based on distance. Sometimes theres 10, 20+ sometimes 2
     
  4. darkAbacus247

    darkAbacus247

    Joined:
    Sep 7, 2010
    Posts:
    251
    This is what I've come up with so far, I only have to run it once each time it's needed...but if anyone happens to know of a better way to go about this, suggestions much appreciated :)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class findRelatives : MonoBehaviour {
    6.     public GameObject objA, objB, IAP; //Identical Ancestory Point
    7.     public List<GameObject> objA_parents, objB_parents = new List<GameObject>();
    8.  
    9.     void Update(){
    10.         GameObject target = objA;
    11.         GameObject target2 = null;
    12.         while(!objA_parents.Contains(objA.transform.parent.root.gameObject)){
    13.             target2 = target.transform.parent.gameObject;
    14.             objA_parents.Add(target2);
    15.             target = target2;
    16.         }
    17.  
    18.         target = objB;
    19.         target2 = null;
    20.         while(!objB_parents.Contains(objB.transform.parent.root.gameObject)){
    21.             target2 = target.transform.parent.gameObject;
    22.             objB_parents.Add(target2);
    23.             target = target2;
    24.         }
    25.  
    26.         for(int i = 0; i < objA_parents.Count; i++){
    27.             for(int j = 0; j < objB_parents.Count; j++){
    28.                 if(!objA_parents.Contains(objB_parents[j])) objB_parents.Remove(objB_parents[j]);
    29.                 if(!objB_parents.Contains(objA_parents[i])) objA_parents.Remove(objA_parents[i]);
    30.             }  
    31.         }
    32.  
    33.         IAP = objA_parents [0];
    34.  
    35.     }
    36. }
     
    Last edited: Apr 6, 2015
  5. lordconstant

    lordconstant

    Joined:
    Jul 4, 2013
    Posts:
    389
    You could just use Transform.parent if something doesnt have a parent its at the top. Then just see if any other gameobjects lead back to that object.
     
  6. darkAbacus247

    darkAbacus247

    Joined:
    Sep 7, 2010
    Posts:
    251
    The trouble is that I'm trying to find a shared relative within a tree. Specifically the most recent ancestor (like galf says), more likely than not the children are buried pretty deep within parenting. I basically want to say, I have a parent, so do you. They are not the same, but our parents parent (or even our parents...parents parent) is the same, who is our parents parent? Sometimes an object may only have say 5 jumps to the root parent where the object it's checking against may have 20 jumps...if that makes sense at all.

    The above script is working well enough, but I expect once I get everything into it it's going to cause some serious lag issues