Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
avatar image
3
Question by Phong · Nov 08, 2012 at 06:19 PM · serializedobjectpropertyfield

How to configure a PropertyField so it won't allow scene objects

My MonoBehaviour has a field

 public GameObject targetPrefab;

I am writing a custom inspector and would like the user to only be able to drag assets to this field, NOT scene objects. I EditorGUILayout has ObjectField which has a flag for disallowing scene objects:

target.targetPrefab = (GameObject) EditorGUILayout.ObjectField("Target Prefab", target.targetPrefab, ` `typeof(GameObject), false);

I would like to use:

 so = new SerializedObject(target);
 targ = so.FindProperty("targetPrefab");
 EditorGUILayout.PropertyField(targ);

However I can't find a way of disallowing scene objects from being dragged to the PropertyField. Is there a way?

Thanks.

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
2
Best Answer

Answer by vexe · Feb 20, 2014 at 12:35 PM

Unity 4.3.4 is here, and there's still no parameter you could pass to PropertyField to disallow dropping scene objects.

If you have ILSpy or .NET reflector, you could inspect PropertyField yourself to see how it's implemented. As you might have guessed, PropertyField has a switch statement internally so that it picks the right field type to use, based on your property. Here's the part related to when the property's type is a reference type:

   case SerializedPropertyType.ObjectReference:
                 ObjectField(position, property, label);

Here's that ObjectField:

 internal static void ObjectField(Rect position, SerializedProperty property, GUIContent label)
 {
     ObjectField(position, property, label, EditorStyles.objectField);
 }

Follow along:

 internal static void ObjectField(Rect position, SerializedProperty property, GUIContent label, GUIStyle style)
 {
     int id = GUIUtility.GetControlID(s_PPtrHash, EditorGUIUtility.native, position);
     position = PrefixLabel(position, id, label);
     bool allowSceneObjects = false;
     if (property != null)
     {
         Object targetObject = property.serializedObject.targetObject;
         if ((targetObject != null) && !EditorUtility.IsPersistent(targetObject))
         {
             allowSceneObjects = true;
         }
     }
     DoObjectField(position, position, id, null, null, property, null, allowSceneObjects, style);
 }
  

So at the end it's using that DoObjectField, which is essentially the same method used in EditorGUILayout.ObjectField (if you follow that along, you'll end up with DoObjectField as well) - As you can see allowSceneObjects is being set internally which sucks :(

You could always fallback and use EditorGUILayout.ObjectField and set your object directly. But before that you have to Undo.RecordObject(yourObject, "Some title"); if you want undo support.

If there's a solution to setting allowSceneObjects yourself for PropertyField then it's gonna be a hack, definitely a hack.

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
avatar image
1

Answer by TonyVT · Mar 25, 2016 at 11:22 AM

I know the question is a bit old, but i stumbled upon the same problem and found a workaround. Maybe it is not elegant, but works. I'll write it here, because this question is #1 in Google if you look for this problem.

The idea is to check in the Editor script if the reference provided is from a prefab. If not, the previous reference has to be restored. This is an example code:

 [CustomEditor(typeof(ModelAvatarGenerator), false)]
 public class CustomModelAvatarEditor : Editor
 {
     #region Serialized Properties
     
     /// <summary>
     /// Serialized property of fbxModel of target
     /// </summary>
     private SerializedProperty m_fbxModel;
     
     #endregion
     
     public void OnEnable()
     {
         m_fbxModel = serializedObject.FindProperty("fbxModel");
     }
     
     /// <summary>
     /// Executed at script displaying
     /// </summary>
     public override void OnInspectorGUI()
     {
         serializedObject.Update();
     
         //holds label and tooltip of each control
         GUIContent labelTooltip;
     
         //Custom Avatar Model (remember to force the user to insert only prefabs instances)
         GUILayout.BeginVertical();
         labelTooltip = new GUIContent("Model Avatar", "Model to use as user avatar");
         GameObject oldReference = (GameObject)m_fbxModel.objectReferenceValue; //save current avatar reference
         EditorGUILayout.PropertyField(m_fbxModel, labelTooltip);
     
         if ((GameObject)m_fbxModel.objectReferenceValue != null) //to allow null (None) to be used as a correct value
         {
             PrefabType avatarPrefabType = PrefabUtility.GetPrefabType((GameObject)m_fbxModel.objectReferenceValue); //get its prefab type
     
             if(avatarPrefabType != PrefabType.ModelPrefab && avatarPrefabType != PrefabType.Prefab) //if it is not a prefab on disk, restore previous reference
             {
                 m_fbxModel.objectReferenceValue = oldReference;
             }
         }
     
         GUILayout.EndVertical();
     
         serializedObject.ApplyModifiedProperties();
     }
     
 }

Hope this helps! Happy coding ;)

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

11 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

Related Questions

Why are the children of my Serialized Property not being drawn? 1 Answer

How can I get the serializedObject of a missing MonoBehaviour without an Editor? 0 Answers

PropertyDrawer and EditorWindow 1 Answer

Is it better/more performant to make a SerializedProperty reference or get the reference as needed from the serializedObject reference? 0 Answers

Change look of one type to different everywhere 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