Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
2
Question by idbrii · Feb 06, 2019 at 11:48 PM · prefabprefab-instancevalidation

How can I detect prefabs edited in the prefab editor in OnValidate?


In short

I want two functions:

  • Is input GameObject in a prefab asset (in Project or prefab editor)?

  • Is input GameObject in a prefab instance (in scene but not prefab editor)?

    Details

I like to do validation on my objects, but I don't understand how to do it with the new prefab system. I need to be able to check whether an object is a prefab instance/asset from OnValidate (to ignore missing data that'd be filled on an instance or skip adding scene-specific data on assets), so I want two kinds of validation:

  • validate objects in the prefab editor (prefab assets)

  • validate objects in the scene (prefab instances)

    Research

I wrote some code (below) to print the object, the scene, and what seemed like relevant PrefabUtility calls.

From prefab editor editing "Sphere":

 'Sphere'     Sphere AnyPrefab=False PrefabAsset=False PrefabInstance=False NonAssetPrefabInstance=False is_stage_scene= True NotAPrefab None
 'Sphere'            AnyPrefab=False PrefabAsset=False PrefabInstance=False NonAssetPrefabInstance=False is_stage_scene=False NotAPrefab None
 'Sphere'            AnyPrefab=False PrefabAsset=False PrefabInstance=False NonAssetPrefabInstance=False is_stage_scene=False NotAPrefab None
 'Sphere'            AnyPrefab= True PrefabAsset= True PrefabInstance=False NonAssetPrefabInstance=False is_stage_scene=False Regular Prefab
 'Sphere'   Gameplay AnyPrefab= True PrefabAsset=False PrefabInstance= True NonAssetPrefabInstance= True is_stage_scene=False Regular PrefabInstance

From my "Gameplay" scene:

 'Sphere'   Gameplay AnyPrefab= True PrefabAsset=False PrefabInstance= True NonAssetPrefabInstance= True is_stage_scene=False Regular PrefabInstance

Presumably touching a prefab in the prefab editor will trigger validation in the scene, so that explains the "Gameplay" result from prefab editor. Clicking the IsPartOfAnyPrefab=True result without a scene reveals the asset in my Project tab.

I don't understand the other things with no scene.

We can distinguish three cases:

 scene:  AnyPrefab= True PrefabAsset=False PrefabInstance= True NonAssetPrefabInstance= True is_stage_scene=False Regular    PrefabInstance
 asset:  AnyPrefab= True PrefabAsset= True PrefabInstance=False NonAssetPrefabInstance=False is_stage_scene=False Regular    Prefab
 editor: AnyPrefab=False PrefabAsset=False PrefabInstance=False NonAssetPrefabInstance=False is_stage_scene= True NotAPrefab None

It seems that GetPrefabAssetType is an unreliable way to tell prefab assets from instances and not as useful as the deprecated GetPrefabType. Instead, we must check multiple things:

 bool is_prefab_instance = IsPartOfAnyPrefab(obj) && !IsPartOfPrefabAsset(obj) &&  IsPartOfNonAssetPrefabInstance(obj)
 bool is_prefab_asset    = IsPartOfAnyPrefab(obj) &&  IsPartOfPrefabAsset(obj) && !IsPartOfNonAssetPrefabInstance(obj)
 var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
 bool is_prefab_editor   = stage != null && stage.scene == obj.scene;

Is there a simpler way to detect prefabs in the prefab editor? Are there flaws with my approach?

Code I'm using:

 using UnityEngine;
 using UnityEditor;
 public class WhatIsPrefab : MonoBehaviour
 {
     public bool ToggleToValidate;
     void OnValidate()
     {

         var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
         bool is_stage_scene = stage != null && stage.scene == gameObject.scene;
         Debug.Log(string.Format("'{0}' {1,10} AnyPrefab={2,5} PrefabAsset={3,5} PrefabInstance={4,5} NonAssetPrefabInstance={5,5} is_stage_scene={6,5} {7} {8}",
                     name,
                     gameObject.scene.name,
                     PrefabUtility.IsPartOfAnyPrefab(gameObject),
                     PrefabUtility.IsPartOfPrefabAsset(gameObject),
                     PrefabUtility.IsPartOfPrefabInstance(gameObject),
                     PrefabUtility.IsPartOfNonAssetPrefabInstance(gameObject),
                     is_stage_scene,
                     PrefabUtility.GetPrefabAssetType(gameObject),
                     PrefabUtility.GetPrefabType(gameObject)), // deprecated, but just in case
                 this);
     }
 }







Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by idbrii · Feb 07, 2019 at 12:49 AM

Here's the complete code using my above method. I suspect I'll have problems with nested prefabs (are they assets or instances?).

     // In scene.
     public static bool IsPrefabInstance(GameObject obj)
     {
         bool is_prefab_instance = false;
 #if UNITY_EDITOR
         is_prefab_instance = UnityEditor.PrefabUtility.IsPartOfAnyPrefab(obj)
             && !UnityEditor.PrefabUtility.IsPartOfPrefabAsset(obj)
             && UnityEditor.PrefabUtility.IsPartOfNonAssetPrefabInstance(obj);
 #endif
         return is_prefab_instance;
     }

     // In project or prefab editor.
     public static bool IsPrefabAsset(GameObject obj)
     {
         bool is_prefab_asset = false;
 #if UNITY_EDITOR
         var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
         is_prefab_asset = (stage != null
                 && stage.scene == obj.scene)
             || (UnityEditor.PrefabUtility.IsPartOfAnyPrefab(obj)
                     && UnityEditor.PrefabUtility.IsPartOfPrefabAsset(obj)
                     && !UnityEditor.PrefabUtility.IsPartOfNonAssetPrefabInstance(obj));
 #endif
         return is_prefab_asset;
     }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image pointcache · Jul 04, 2019 at 08:03 AM 0
Share

The api seems to be really lacking, if that's what it takes to check a simple thing.

avatar image
0

Answer by Wappenull · Sep 22, 2020 at 02:07 PM

This is my take on identifying prefab properties using new API. There is example project to download. But here is core logic that check everything. (Kinda long)

https://github.com/wappenull/UnityPrefabTester/blob/master/Assets/Scripts/Wappen/Editor/PrefabHelper/PrefabHelper.cs

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

195 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Another another **Setting the parent of a transform which resides in a prefab** problem, and OnValidate 1 Answer

Setting the parent of a transform which resides in a prefab is disabled to prevent data corruption. 0 Answers

Instantiate prefab by total int 1 Answer

How to designate a specific prefab for the script. (Or how to move something to a specific prefab) 1 Answer

Problems with instantiating 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges