- Home /
How can I get the full path to a GameObject?
I would like to know the full path to a GameObject in the scene. The path would contain all of the parent information for the GameObject.
For example, if I have a scene like this
-A |-B |-C |-D -E
then the path for A would be '/A', the path for B would be '/A/B', the path for C would be '/A/B/C', etc.
Clearly we can find any object by its path, but how do I get a path from an object?
Thanks!
Answer by duck · Dec 01, 2009 at 04:30 PM
I couldn't see a built-in function to give you this, so here's one which you can use:
public static string GetGameObjectPath(GameObject obj)
{
string path = "/" + obj.name;
while (obj.transform.parent != null)
{
obj = obj.transform.parent.gameObject;
path = "/" + obj.name + path;
}
return path;
}
That's C#. Give me a shout if you need it in JS.
And without anterior slash:
private static string GetGameObjectPath(Transform transform)
{
string path = transform.name;
while (transform.parent != null)
{
transform = transform.parent;
path = transform.name + "/" + path;
}
return path;
}
+1 use of the word anterior. (This is useful code hoewever. I use it for finding duplicate components with a given name).
The idea of getting path is to store it or/and use it for finding the GameObject. ex. GameObject.Find(path).
, which won't work if GameObject is hidden and you need to use Resources.FindAllObjectsOfType(GameObject).Where(go=> GetGameObjectPath(go)==path)
. which won't work for Prefab Instances, cos on the same path- same name there is ghost Prefab object, so you might get the Ghost ins$$anonymous$$d of the instance. As there is not Unity way to check if the GameObject is Prefab or PrefabInstance, during runtime(go vote for that), I was experimenting with Resources.FindAllObjectsOfType(GameObject).Where(go=> GetGameObjectPath(go)==path) && go.transform.hideFlags!=HideFlags.HideInHierachy
Answer by SukiSan · Jun 03, 2012 at 03:16 PM
Or, for those of us who love the beauty of recursion:
public static string GetPath(this Transform current) {
if (current.parent == null)
return "/" + current.name;
return current.parent.GetPath() + "/" + current.name;
}
I implemented it as extension method to be able to simply write transform.GetPath();
For meaningful log messages I added the same for Component:
public static string GetPath(this Component component) {
return component.transform.GetPath() + "/" + component.GetType().ToString();
}
which enables me to write
Debug.Log("failed to satisfy a condition in " + this.GetPath()");
I really like your recursive solution, thank you so much. I think I would rather using component.GetType().Name.
Notice that Transform also inherits from Component and users should be careful when opting for one of both extensions. I am no sure, it depends on efficiency vs usability, but it could be worth it to merge both methods into the Component signature using if(component is Transform transform)
$$anonymous$$G:
public static string GetPathInScene(this Component self) =>
self is Transform transform
? transform.GetPathInScene()
: $"{GetPathInScene(self.transform)}/{self.GetType().Name}";
Answer by winxalex · Oct 23, 2015 at 09:05 PM
Unity v5 (Editor only)
if(this.transform!=this.transform.root)
Debug.Log("Path:"+transform.root.name+"/"+AnimationUtility.CalculateTransformPath (this.transform,transform.root));
else you know :)
FYI: This one will only work in the editor due to the use of AnimationUtility which comes from the UnityEditor namespace.
Question didn't specify runtime or/and editor. I assumed solution of building editor that stores path during edit and use during runtime. Read my reply to duck about problems of runtime use. ;)
Answer by xtyler · Dec 19, 2018 at 07:16 PM
Concise:
Debug.Log(string.Join("/", gameObject.GetComponentsInParent<Transform>().Select(t => t.name).Reverse().ToArray()), gameObject);
Remember, if you pass GameObject to Debug.Log, when you can click the log in console it will highlight it in hierarchy
I had a problem on the string Join and solved like that: string.Join("/", gameObject.GetComponentsInParent().Reverse().Select(t => t.name).ToArray());