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 /
avatar image
0
Question by david_31 · Nov 11, 2017 at 04:42 PM · script.inspectorattach

Problem in assigning component to variable

There are two scripts A and B which extend C class and C extends MonoBehaviour and there is a G1 gameobject that has A and B scripts. And there is D script that has public C cVariable and is attached to G2 gameobject. In the inspector of the G2 I want to assign B component of G1 to cVariable of D script. But the A script is placed higher than B script and also can be assigned to cVariable. When I click on the little circle of the cVariable object field or drag my G1 gameobject to this field unity brings only A component. So how can I choose between A and B without moving up B script in the G1 inspector?

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

Answer by Bunny83 · Nov 11, 2017 at 06:49 PM

Of course you can do this in the editor. To me the question was quite clear. ^^

The trick is to use two inspector windows and lock one of them so you can actually inspect the two gameobjects at once. Now you can simply drag the component instance directly. I've made an animated GIF some time ago that should be more clear:

So you simply grab the components "header" and drag it to your variable. Ideally it would be nice if Unity would show some sort of popup / dropdown when you drop a gameobject that has multiple possible targets so you can choose one.

Of course it gets easier when the target script is on the same gameobject as you can directly drag the components. However if they are on different gameobjects you have to use two inspectors. In my gif example the variable type is actually "UnityEngine.Object" so we could assign any component, Mesh, Material or GameObject. So when just dragging a gameobject from the hierarchy it would assign the gameobject itself.


edit

Ok, big update

Since i said above that it would be awesome if Unity showed some sort of dropdown to select the object you want, i quickly implemented a PropertyDrawer for ObjectFields which does exactly that.


Note: When you use the attribute "ObjectDropdownAttribute" on a serialized reference type field (only types derived from UnityEngine.Object of course) you can now hold "SHIFT" while dropping an object on the field. This will trigger my custom dropdown logic. It will filter out all components / objects which are assignable to the field type.


Instead of the "ObjectDropdown" attribute you can also use the "ObjectDropdownFilter" attribute which allows you to specify an additional filter type on the field. This is useful for limiting components which should implement a certain interface.


First of all here's the PropertyDrawer (dropbox download). This script need to be placed in an editor folder:

 //ObjectSelectorDropdown.cs
 using System.Collections.Generic;
 using System.Reflection;
 using UnityEngine;
 using UnityEditor;
 
 namespace B83.PropertyDrawers
 {
     [CustomPropertyDrawer(typeof(ObjectDropdownAttribute))]
     public class ObjectSelectorDropdown : PropertyDrawer
     {
         List<Object> m_List = new List<Object>();
         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
         {
             Event e = Event.current;
             if (property.propertyType == SerializedPropertyType.ObjectReference)
             {
                 if ((e.type == EventType.DragPerform ||
                     e.type == EventType.DragExited ||
                     e.type == EventType.DragUpdated ||
                     e.type == EventType.Repaint) &&
                     position.Contains(e.mousePosition) && e.shift)
                 {
                     if (DragAndDrop.objectReferences != null)
                     {
                         m_List.Clear();
                         foreach (var o in DragAndDrop.objectReferences)
                         {
                             m_List.Add(o);
                             var go = o as GameObject;
                             if (go == null && o is Component)
                             {
                                 go = ((Component)o).gameObject;
                                 m_List.Add(go);
                             }
                             if (go != null)
                                 foreach (var c in go.GetComponents<Component>())
                                     if (c != o)
                                         m_List.Add(c);
                         }
                         var fieldInfo = property.GetPropertyReferenceType();
                         if (fieldInfo != null)
                         {
                             var type = fieldInfo.FieldType;
                             for (int i = m_List.Count - 1; i >= 0; i--)
                             {
                                 if (m_List[i] == null || !type.IsAssignableFrom(m_List[i].GetType()))
                                     m_List.RemoveAt(i);
                             }
                         }
                         var att = attribute as ObjectDropdownFilterAttribute;
                         if (att != null)
                         {
                             var type = att.filterType;
                             for (int i = m_List.Count - 1; i >= 0; i--)
                             {
                                 if (!type.IsAssignableFrom(m_List[i].GetType()))
                                     m_List.RemoveAt(i);
                             }
                         }
                         if (m_List.Count == 0)
                             DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
                         else
                         {
                             DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                             if (e.type == EventType.DragPerform)
                             {
                                 GenericMenu gm = new GenericMenu();
                                 GenericMenu.MenuFunction2 func = (o) => {
                                     property.objectReferenceValue = (Object)o;
                                     property.serializedObject.ApplyModifiedProperties();
                                 };
                                 foreach (var item in m_List)
                                     gm.AddItem(new GUIContent(item.name+"("+item.GetType().Name+")"), false, func, item);
                                 gm.ShowAsContext();
                                 e.Use();
                             }
                         }
                         m_List.Clear();
                     }
                 }
                 EditorGUI.ObjectField(position, property, label);
             }
             else
                 EditorGUI.PropertyField(position, property, label);
         }
     }
 
     public static class SerializedPropertyExt
     {
         public static FieldInfo GetPropertyReferenceType(this SerializedProperty aProperty)
         {
             var currentType = aProperty.serializedObject.targetObject.GetType();
             FieldInfo fi = null;
             var parts = aProperty.propertyPath.Split('.');
             foreach (string fieldName in parts)
             {
                 fi = currentType.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                 if (fi == null)
                     return null;
                 currentType = fi.FieldType;
             }
             return fi;
         }
     }
 }


In addition you need this script as well which defines the attributes (dropbox download). This script must not be in an editor folder but simply part of your normal runtime scripts

 // ObjectDropdownAttribute.cs
 using UnityEngine;
 
 public class ObjectDropdownAttribute : PropertyAttribute
 {
 }
 public class ObjectDropdownFilterAttribute : PropertyAttribute
 {
     public System.Type filterType;
     public ObjectDropdownFilterAttribute(System.Type aType)
     {
         filterType = aType;
     }
 }


Usage

 public class SomeScript : MonoBehaviour
 {
     [ObjectDropdown]
     public SomeBaseClass objRef;
 }


If you attach the ObjectDropdown attribute like this you can still use the object field as usual. However if you hold down SHIFT before you drop an object on the field you will actually get a dropdown menu which lets you select one of the compatible objects / components available.

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 david_31 · Nov 12, 2017 at 10:17 AM 0
Share

Thank you very much!!!

avatar image
0

Answer by hrgchris · Nov 11, 2017 at 05:01 PM

Hi

Wow - with respect, that was the most confusingly asked question I've ever heard :) For future reference, feel free to use actual names for examples, and a screen shot speaks a 1000 words!

Anyway, I think what you're asking is:

  • you have a base class, Animal, derived from Monobehaviour

  • you have 2 derived classes, Dog and Cat

  • you have a single game object (animals) that has both Dog and Cat components attached

  • you have another component on another game object (animalref) that has a field of type Animal

  • how can you make sure that your Animal field on animalref points to the Dog, not the Cat or visa versa

Unfortunately, the answer is I believe that you can't in the UI. In thoery if you knew exactly what you wanted you could add an 'OnValidate' function to your 'animalref' that looked up the correct thing in code. That said, I would recommend just having a bit of a rethink about how you structure your scene in this case - best to work with unity, not against it!

-Chris

Comment
Add comment · Show 5 · 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 david_31 · Nov 11, 2017 at 05:14 PM 0
Share

Sorry for such dumbly-written question, I just don't know English very well! $$anonymous$$y problem is that Dog script is first script and Cat is second script attached to gameobject (animals). I want to attach Cat to Animal, but I can't cause unity takes only first script of type Animal which is Dog and doesn't let me to choose between Dog and Cat.

avatar image hrgchris david_31 · Nov 11, 2017 at 05:23 PM 0
Share

Hi $$anonymous$$. No problem on the question - that's why I mentioned a screen shot, as pictures can be much better at communicating a problem, especially when language is an issue.

I understand the issue, and as I say, I don't think it is something you can do in the Unity UI. You may be able to write some code that specifically links your objects together, but my advice is to take a step back and have a rethink first. There is probably a way of achieving your goal without having these 2 scripts on the same game object, which is how Unity 'wants' you to work.

avatar image david_31 hrgchris · Nov 11, 2017 at 05:37 PM 0
Share

Ok in my case I have a Tank and CameraControl scripts (simple $$anonymous$$onoBehaviour scripts derived from $$anonymous$$onoBehaviour) which are attached to Tank gameobject. I have a Game script attached to Game gameobject. It is for pausing game and when game is being paused Game script should disable some Behaviours including Tank and CameraControl and for this I added List of Behaviours which is public and shown in the Inspector of the Game gameobject. I assign Tank script to Element 0 by draging tank gameobject to Element 0. I also want to assign CameraControl script to Element 2 but unity assigns Tank script again, cause Tank is also Behaviour and it is the first script of Tank gameobject. Thank you for helping me Chris!

this is the inspector of my tank

this is the inspector of my Game gameobject Activatable behaviours is my list of behaviours

Show more comments

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

76 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

Related Questions

Text in the scene is not being updated! 0 Answers

Add AudioSource-Like Range to Script 1 Answer

My Net Manager inspector ineffective? 0 Answers

Attach player to object and disable player movement 1 Answer

How to find in what Scripts or components an Object is connected 0 Answers


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