Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to find the prefab root in the prefab editor with an environment?

Discussion in 'Prefabs' started by watsonsong, Sep 29, 2018.

  1. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    I am try to use the GetNearestPrefabInstanceRoot and FindPrefabRoot and transform.root, both of them gets the environment root but not the prefab root.
    Is there any way to get the prefab root?
     
  2. Mads-Nyholm

    Mads-Nyholm

    Unity Technologies

    Joined:
    Aug 19, 2013
    Posts:
    217
    Hi,

    When opening a prefab in Prefab Mode we load the *contents* of the prefab. This means that for a normal prefab the GameObjects of the prefab itself are plain GameObjects while nested prefabs are Prefab instances. (For Prefab Variants the root will be a Prefab instance).

    To get the root GameObject of the opened Prefab you have to use the PrefabStageUtility (in namespace UnityEditor.Experimental.SceneManagement):

    PrefabStage prefabStage = PrefabStageUtility.GetPrefabStage(yourGameObject);


    The
    prefabStage
    will be null if
    yourGameObject
    is not part of a PrefabStage.
    If the
    prefabStage
    is valid you can do the following to get the root of the prefab:

    GameObject root = prefabStage.prefabContentsRoot;
     
    gresolio likes this.
  3. Wappenull

    Wappenull

    Joined:
    Oct 29, 2013
    Posts:
    51
    There are totally 3 distinct type/state of prefab. And they must be handled differently.
    • Prefab Asset (The one that sits in Asset folder)
    • Prefab Instance (The one that dragged into scene to become blue game object, or nested inside another prefab)
    • Prefab Stage (Editing prefab intermediate in UnityEditor prefab edit mode)
    For example: from getting assetPath alone, these 3 cases will need different API
    • Prefab Asset => use UnityEditor.AssetDatabase.GetAssetPath()
    • Prefab Instance => PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot()
    • Prefab Stage => PrefabStageUtility.GetCurrentPrefabStage then editorPrefabStage.prefabAssetPath
    Finding root of game object for each case also need different API
    • Prefab Asset => use gameObject.transform.root.gameObject()
    • Prefab Instance => PrefabUtility.GetNearestPrefabInstanceRoot()
    • Prefab Stage => PrefabStageUtility.GetCurrentPrefabStage then editorPrefabStage.prefabContentsRoot
    (See deprecate message in old PrefabUtility.FindPrefabRoot function, it is very useful.)

    Im not sure which case you are on.
    But for PrefabUitility API example, you could look into my demo on https://github.com/wappenull/UnityPrefabTester
    It is editor script demo.

    Edit: Add finding root APIs