Exemplo n.º 1
0
        public static void Show(SerializedProperty prop, List <MonoBehaviour> monos)
        {
            if (monos == null ||
                monos.Count == 0 ||
                prop == null)
            {
                return;
            }

            InterfacePicker picker = GetWindow <InterfacePicker>(true);

            picker._propertyPath = prop.propertyPath;
            picker._target       = prop.serializedObject.targetObject;
            picker._monoInspectors?.ForEach((mi) => mi.Destroy());
            picker._monoInspectors = new List <MonoInspector>();
            picker.titleContent    = new GUIContent(monos[0].gameObject.name);
            monos.ForEach((m) => picker._monoInspectors.Add(new MonoInspector(m)));

            picker.ShowUtility();
        }
Exemplo n.º 2
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            if (property.serializedObject.isEditingMultipleObjects)
            {
                return;
            }

            if (property.propertyType != SerializedPropertyType.ObjectReference)
            {
                EditorGUI.LabelField(position, label.text, "InterfaceType Attribute can only be used with MonoBehaviour Components.");
                return;
            }

            EditorGUI.BeginProperty(position, label, property);

            Type[] attTypes = GetInterfaceTypes(property);

            // Pick a specific component
            MonoBehaviour oldComponent     = property.objectReferenceValue as MonoBehaviour;
            string        oldComponentName = "";

            GameObject temporaryGameObject = null;

            string attTypesName = GetTypesName(attTypes);

            if (Event.current.type == EventType.Repaint)
            {
                if (oldComponent == null)
                {
                    temporaryGameObject = new GameObject("None (" + attTypesName + ")");
                    oldComponent        = temporaryGameObject.AddComponent <InterfaceMono>();
                }
                else
                {
                    oldComponentName  = oldComponent.name;
                    oldComponent.name = oldComponentName + " (" + attTypesName + ")";
                }
            }

            Component     currentComponent = EditorGUI.ObjectField(position, label, oldComponent, typeof(Component), true) as Component;
            MonoBehaviour currentMono      = currentComponent as MonoBehaviour;

            if (Event.current.type == EventType.Repaint)
            {
                if (temporaryGameObject != null)
                {
                    GameObject.DestroyImmediate(temporaryGameObject);
                }
                else
                {
                    oldComponent.name = oldComponentName;
                }
            }

            // If a component is assigned, make sure it is the interface we are looking for.
            if (currentMono != null)
            {
                // Make sure component is of the right interface
                if (!IsAssignableFromTypes(currentMono.GetType(), attTypes))
                {
                    // Component failed. Check game object.
                    foreach (Type attType in attTypes)
                    {
                        currentMono = currentMono.gameObject.GetComponent(attType) as MonoBehaviour;
                        if (currentMono == null)
                        {
                            break;
                        }
                    }
                }

                // Item failed test. Do not override old component
                if (currentMono == null)
                {
                    if (oldComponent != null && !IsAssignableFromTypes(oldComponent.GetType(), attTypes))
                    {
                        temporaryGameObject = new GameObject("None (" + attTypesName + ")");
                        MonoBehaviour temporaryComponent = temporaryGameObject.AddComponent <InterfaceMono>();
                        currentMono = EditorGUI.ObjectField(position, label, temporaryComponent, typeof(MonoBehaviour), true) as MonoBehaviour;
                        GameObject.DestroyImmediate(temporaryGameObject);
                    }
                }
            }
            else if (currentComponent is Transform)
            {
                // If assigned component is a Transform, this means a GameObject was dragged into the property field.
                // Find all matching components on the transform's GameObject and open the picker window.

                List <MonoBehaviour> monos = new List <MonoBehaviour>();
                monos.AddRange(currentComponent.gameObject.GetComponents <MonoBehaviour>().
                               Where((mono) => IsAssignableFromTypes(mono.GetType(), attTypes)));

                if (monos.Count > 1)
                {
                    EditorApplication.delayCall += () => InterfacePicker.Show(property, monos);
                }
                else
                {
                    currentMono = monos.Count == 1 ? monos[0] : null;
                }
            }

            if (currentComponent == null || currentMono != null)
            {
                property.objectReferenceValue = currentMono;
            }

            EditorGUI.EndProperty();
        }