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
5
Question by Howard · Jan 19, 2011 at 06:18 AM · guieditorinspectoreditorguioninspectorgui

OnInspectorGUI - Using the default Object Selection popup.

Hi everyone, this seems pretty basic stuff, but I can't seem to get it to work for the life of me so I hoped maybe someone could show me the silly little thing I'm doing wrong to fix it.

I want to build a doubly-linked-list of GameObject nodes that can be placed in the world. Each node has a next node, and a previous node. When I set an objects "Next Node" or "Prev Node" I want both objects to automatically point to each other (the user shouldn't have to go and change both nodes to correctly point to eachother). I can do this by hiding my NextNode and PrevNode members behind accessors, like so:

using UnityEngine; using System.Collections;

public class CameraNode : MonoBehaviour { // public members //////////////////////////////////////////////

 // public methods ///////////////////////////////////////////////

 // public accessors /////////////////////////////////////////////
 public CameraNode NextNode
 {
     get { return m_nextNode; }
     set
     {
         m_nextNode = value;
         if( ( value != null ) &&
             ( value.PrevNode != this ) )
         {
             value.PrevNode = this;
         }
     }
 }

 public CameraNode PrevNode
 {
     get { return m_prevNode; }
     set
     {
         m_prevNode = value;
         if( ( value != null ) && 
             ( value.NextNode != this ) )
         {
             value.NextNode = this;
         }
     }
 }

 // private methods ///////////////////////////////////////////////

 // private members //////////////////////////////////////////////
 private CameraNode m_nextNode;
 private CameraNode m_prevNode;

}

Now, I do want these nodes editable in the inspector. No worries, I can write an editor script. So I do:

using UnityEngine; using UnityEditor; using System.Collections;

[CustomEditor(typeof(CameraNode))] public class CameraNodeEditor : Editor { public override void OnInspectorGUI()
{ if( target is CameraNode ) //thank you yoyo { CameraNode editing = (CameraNode)target; GameObject nextNodeObj = (GameObject)EditorGUILayout.ObjectField(

                       "Next Node"
                      , editing.NextNode
                      , typeof( CameraNode ) );

   if( nextNodeObj != null )
   {
     editing.NextNode = nextNodeObj.GetComponent<CameraNode>();
   }

   DrawDefaultInspector();
 }

} }

But here's the problem, I'm expecting this (look at the highlighted Test) What I Want

  • I can select an object that only has a particular component.
  • I can select form objects in the world, or prefabs (assets)

But what I get is this: alt text

  • I can only see assets?
  • It looks ugly in the inspector, and non standard.

Now I've seen other questions on the forums that ask this question too, and people recommended a TextField? But that's not really what I want here. Surely this is a reusable component right? How did the Unity developers do it?

Thanks for your time,

  • Howard

Comment
Add comment · Show 4
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 yoyo · Jan 19, 2011 at 07:04 AM 1
Share

Upvoted for the nicely formatted question, clearly asked, with screenshots to boot! I think this is a bug in Unity 3, but I hesitate to post that as an answer. BTW, the docs state that the ObjectField method "$$anonymous$$ake[s] an object drop slot field" -- does drag/drop from the Hierarchy work as expected?

avatar image yoyo · Jan 19, 2011 at 07:06 AM 2
Share

Aside: rather than "if( target.GetType() == typeof( CameraNode ) )" it's clearer to write "if (target is CameraNode)".

avatar image Howard · Jan 19, 2011 at 04:19 PM 0
Share

ooh thank you! that's a good tip.

avatar image Howard · Jan 20, 2011 at 03:07 AM 0
Share

When I attempt to drag an object from the hierarchy I get the following error:

"InvalidCastException: Cannot cast from source type to destination type. CameraNodeEditor.OnInspectorGUI () (at Assets/Editor/CameraNodeEditor.cs:14) UnityEditor.InspectorWindow.OnGUI () (at E:/BuildAgent/work/71ca6fec1b41cc30/Editor/$$anonymous$$ono/Inspector/InspectorWindow.cs:364) System.Reflection.$$anonymous$$ono$$anonymous$$ethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture)"

1 Reply

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

Answer by runevision · Jan 19, 2011 at 10:29 AM

It seems that the ObjectField never shows scene objects. I guess this is because the object selector doesn't know if the object is going to be stored in a persistent object (prefab) or a scene object, and a prefab is not supposed to be able to ever reference a scene object. I guess we need to figure out a way to handle that.

In the mean time, you can work around it by using a PropertyField.

First of all, note that you have to make your variables serialized in order for them to be stored. All public variables of supported data types are serialized by default, but private variables can also be serialized by using the [SerializeField] attribute. This will make them show up in the Inspector, but you can hide them again, using the [HideInInspector] attribute:

[HideInInspector]
[SerializeField]
private CameraNode m_nextNode;
[HideInInspector]
[SerializeField]
private CameraNode m_prevNode;

Now, use a PropertyField to show the object field:

using UnityEngine; using UnityEditor; using System.Collections;

[CustomEditor(typeof(CameraNode))] public class CameraNodeEditor : Editor { SerializedObject m_Object; SerializedProperty m_NextNodeProperty;

 void OnEnable ()
 {
     m_Object = new SerializedObject (target);
     m_NextNodeProperty = m_Object.FindProperty ("m_nextNode");
 }

 public override void OnInspectorGUI()   
 {
     EditorGUIUtility.LookLikeInspector();

     if( target.GetType() == typeof( CameraNode ) )
     {
         CameraNode editing = (CameraNode)target;

         CameraNode nodeBefore = editing.NextNode;
         EditorGUILayout.PropertyField (m_NextNodeProperty);
         if (m_NextNodeProperty.objectReferenceValue as CameraNode != nodeBefore)
         editing.NextNode = m_NextNodeProperty.objectReferenceValue as CameraNode;

         DrawDefaultInspector();
     }
 }

}

I have confirmed that to work fine. The scene objects are displayed.

Note that using EditorGUIUtility.LookLikeInspector(); will make the controls look like default inspector controls. We are moving away from that ourselves though; you'll notice that a lot of components in Unity 3 have different look; for example the Camera component, Light component, and some more.

Comment
Add comment · Show 3 · 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 Howard · Jan 19, 2011 at 04:36 PM 0
Share

The root of the problem is that I would like to enforce that node.NextNode.PrevNode == node. I think the correct way to do this is by using accessors ins$$anonymous$$d of public members, unfortunately, accessors cannot be serialized in the inspector(?). That was where my editor script comes in, it's basically a way to let me edit members and run additional code during the set so that I can always be sure that NextNodes and PrevNodes are always in sync, even across different GameObjects. If I could just make the raw members public I wouldn't have to bother with the editor script =]

avatar image runevision ♦♦ · Jan 20, 2011 at 09:48 AM 0
Share

The custom inspector I posted DOES use the properties and thus all assignment through the Inspector will ensure the list is linked correctly. I just remembered that you don't need to make the variables public either, you can use the [SerializeField] attribute ins$$anonymous$$d. I have edited my answer to point this out.

avatar image Howard · Jan 20, 2011 at 03:03 PM 0
Share

Thank you perfect!

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

No one has followed this question yet.

Related Questions

Unexpected selection state in custom inspector? 1 Answer

Is there an event being fired off when the Inspector is being resized? 1 Answer

CustomPropertyDrawer with UnityEvent 1 Answer

Custom Material Editor 1 Answer

Create an Editor Window like Mecanim 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