Search Unity

IsPartOfPrefabAsset/IsPartOfPrefabContents

Discussion in 'Prefabs' started by SentientSkull, Oct 14, 2020.

  1. SentientSkull

    SentientSkull

    Joined:
    Apr 26, 2013
    Posts:
    75
    I'm trying to use 'IsPartOfPrefabAsset' in a method called from Awake(). I was expecting this to return 'true' when called from a prefab asset that is loaded in the editor (staged), but it returns 'false'. However it does return 'true' if called from OnValidate(). How can I tell when a prefab asset is being edited?

    I need this (or some way to know) because I'm generating a unique id string in 'Awake' for scene objects in edit mode and adding them to a serializable list, but I don't want this to happen when editing the prefab.

    I found 'PrefabStage.IsPartOfPrefabContents', but this is only in Unity 2020.2 (I'm using 2020.1.8). So is there some other way to detect this state?
     
  2. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
  3. SentientSkull

    SentientSkull

    Joined:
    Apr 26, 2013
    Posts:
    75
    If I try to add 'PrefabStage.IsPartOfPrefabContents', Visual Studio gives me 'CS0117: PrefabStage' does not contain a definition for 'IsPartOfPrefabContents'. I'm now in 2020.1.9.

    I think when I had searched for it, I got the page for 2020.2 and saw the 'Experimental' note and assumed it was new in 2020.2.

    Edit: For some reason Intellisense won't show 'IsPartOfPrefabContents', but typing it out works now (maybe I had a typo before when it was giving the error).

    Edit 2: Now VS gives me an error saying 'CS0120: An object reference is required for the non-static field, method, or property 'PrefabStage.IsPartOfPrefabContents(gameObject)' when I try to use it like this:

    if (PrefabStage.IsPartOfPrefabContents(gameObject))
     
    Last edited: Oct 15, 2020
  4. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Does it give compile errors in the Unity Console window? I can't assist with compile errors that only Visual Studio produce that are not aligned with Unity's own compilation.
     
  5. SentientSkull

    SentientSkull

    Joined:
    Apr 26, 2013
    Posts:
    75
    Yes, the error also shows in Unity's console.
     
  6. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Just to check, you are using the namespace PrefabStage is in?
    UnityEditor.Experimental.SceneManagement
     
  7. SentientSkull

    SentientSkull

    Joined:
    Apr 26, 2013
    Posts:
    75
    Yes, that's definitely there. I also started a new project just to test and get the same issue.
    I'm just trying to pass gameObject from the script. Not sure what I might be doing wrong.

    I found that using

    Code (CSharp):
    1. if (gameObject.scene != SceneManager.GetActiveScene())
    seems to work, but not sure if it might cause problems in other situations.
     
  8. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Ah sorry, IsPartOfPrefabContents needs to be called on the current Prefab stage, it's not a static method.

    This should work:
    if (PrefabStageUtility.GetCurrentPrefabStage().IsPartOfPrefabContents(gameObject))
     
  9. SentientSkull

    SentientSkull

    Joined:
    Apr 26, 2013
    Posts:
    75
    Thanks, this works. But in the way I'm using it, I had to check if the PrefabStage is not null or I get null reference exception.

    Code (CSharp):
    1. var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
    2. if (prefabStage)
    3.     return;
     
  10. egor-7355

    egor-7355

    Joined:
    Sep 29, 2016
    Posts:
    6
    Just to combine everything together, this is the code that will check if 'yourGameObject' is a part of currently open Prefab scene:
    Code (CSharp):
    1. var prefabStage = PrefabStageUtility.GetCurrentPrefabStage ();
    2. if (prefabStage != null && prefabStage.IsPartOfPrefabContents(yourGameObject))
    3.     return;

    Don't forget to put this at the top of the file:
    Code (CSharp):
    1. using UnityEditor.SceneManagement;