コード例 #1
0
    void OnGUI()
    {
        var        currentPrefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
        GameObject obj = currentPrefabStage != null ? currentPrefabStage.prefabContentsRoot : Selection.activeGameObject;

        if (!obj)
        {
            EditorGUILayout.HelpBox(startGamePrefabInfo, MessageType.Info);
            return;
        }

        if (!EditorSceneManager.IsPreviewSceneObject(obj))
        {
            // это не режим редактирования префаба (т.е. либо asset, либо на сцене)
            bool isGamePrefab = obj.transform.root.gameObject.tag == "GamePrefab";

            if (isGamePrefab)
            {
                // это игровой префаб (либо asset, либо на сцене)
                if (PrefabUtility.IsPartOfPrefabAsset(obj) || PrefabUtility.IsPartOfPrefabInstance(obj))
                {
                    // проверяем, существует ли префаб ассет
                    string path = AssetDatabase.GetAssetPath(obj);

                    if (PrefabUtility.IsPartOfPrefabInstance(obj))
                    {
                        // этот префаб на сцене - находим его источник в ассетах (если он существует, т.к. редактировать надо именно его)
                        path = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(obj);
                    }

                    if (!string.IsNullOrEmpty(path))
                    {
                        // юнити префаб для этого игрового префаба существует в ассетах, будем редактировать его
                        //obj = obj.transform.root.gameObject;
                        if (GUILayout.Button("Edit game prefab"))
                        {
                            FlushEditors();

                            // открываем префаб из ассетов на редактирование
                            Type t = typeof(UnityEditor.Experimental.SceneManagement.PrefabStageUtility);
                            System.Reflection.MethodInfo mi = t.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
                                                              .Single(m =>
                                                                      m.Name == "OpenPrefab" &&
                                                                      m.GetParameters().Length == 1 &&
                                                                      m.GetParameters()[0].ParameterType == typeof(string)
                                                                      );
                            mi.Invoke(null, new object[] { path });

                            UnityEditor.Experimental.SceneManagement.PrefabStage.prefabStageClosing -= OnSceneClosing;
                            UnityEditor.Experimental.SceneManagement.PrefabStage.prefabStageClosing += OnSceneClosing;
                        }
                    }
                    else
                    {
                        EditorGUILayout.HelpBox("Selected object has no prefab asset file associated with it. Check if it should be a GamePrefab, and if it should - make proper Unity prefab out of this object.", MessageType.Warning);
                    }
                }
                else
                {
                    // этот игровой префаб не юнити префаб, т.е. связь разорвана была видимо
                    // можно предупредить об этом
                    EditorGUILayout.HelpBox("Selected object is GamePrefab, but not the Unity prefab. Check if GamePrefab tag on this object is requiered, and if it is - make proper Unity prefab out of this object.", MessageType.Warning);
                }
            }
            else
            {
                // этот объект - не игровой префаб, можно сделать его игровым префабом
                if (PrefabUtility.IsPartOfModelPrefab(obj))
                {
                    if (GUILayout.Button("Make Generic Game Prefab"))
                    {
                        MakePrefab(obj);
                    }

                    GUILayout.BeginHorizontal();
                    prefabName = GUILayout.TextField(prefabName);

                    if (GUILayout.Button("Make Cloth Game Prefab"))
                    {
                        string prefabPath = AssetDatabase.GetAssetPath(MakePrefab(obj));

                        GameObject prefabRoot = PrefabUtility.LoadPrefabContents(prefabPath);

                        // Создаем одежду - надо сначала проверить условия

                        // Скрываем риг, создаем pickup и item для него
                        GetRig(prefabRoot)?.SetActive(false);

                        prefabRoot.AddComponent <BoxCollider>();

                        var pickup = prefabRoot.AddComponent <ItemPickup>();
                        pickup.item      = PickupItemEditor.CreateItem(prefabRoot.name, prefabPath);
                        pickup.item.icon = GetDefaultIcon();

                        // радиус равен bounds сетки пополам
                        // fit collider позже

                        var equip = prefabRoot.AddComponent <Equippable>();
                        // hidden не ищем, т.к. риг скрыли уже
                        equip.equip = prefabRoot.GetComponentInChildren <SkinnedMeshRenderer>().gameObject.AddComponent <Equipmentizer>();
                        equip.equip.gameObject.SetActive(false);

                        var lying = prefabRoot.GetComponentsInChildren <Renderer>().First((x) => !x.GetComponent <Equipmentizer>());
                        if (lying)
                        {
                            pickup.worldView = lying.transform;
                        }

                        EquippableEditor.SetupEvents(equip);

                        ColliderFitter.FitCollider(prefabRoot, false);

                        var bounds = pickup.worldView.GetComponent <Renderer>().bounds;
                        if (bounds.extents.x > bounds.extents.z)
                        {
                            pickup.radius = bounds.extents.x;
                        }
                        else
                        {
                            pickup.radius = bounds.extents.z;
                        }

                        PrefabUtility.SaveAsPrefabAsset(prefabRoot, prefabPath);
                        PrefabUtility.UnloadPrefabContents(prefabRoot);
                    }

                    GUILayout.EndHorizontal();
                }
                else
                {
                    EditorGUILayout.HelpBox(startGamePrefabInfo, MessageType.Info);
                }
            }
        }
        else
        {
            // мы в режиме редактирования префаба - редактируем game prefab

            // rename game prefa (asset)
            GUILayout.BeginHorizontal();
            {
                obj.name = GUILayout.TextField(obj.name);
                string currentName = System.IO.Path.GetFileNameWithoutExtension(currentPrefabStage.prefabAssetPath);
                if (obj.name != currentName && GUILayout.Button("Apply", GUILayout.Width(150f)))
                {
                    AssetDatabase.RenameAsset(currentPrefabStage.prefabAssetPath, obj.name);
                }
            }
            GUILayout.EndHorizontal();

            // Body-rig - для персонажей и одежды
            var rig = GetRig(obj);
            if (rig && (GUILayout.Button(rig.activeSelf ? disableRigButton : enableRigButton)))
            {
                rig.SetActive(!rig.activeSelf);
            }

            // Компоненты игрового префаба, которые могут быть на нем
            GetForcedComponentEditor(obj, ref desc)?.OnInspectorGUI();
            GetComponentEditor(obj, "It is equippable", "It is not equippable", ref equip)?.OnInspectorGUI();
            GetComponentEditor(obj, "Can pick it up", "Can not pick that up", ref pickup)?.OnInspectorGUI();
        }
    }
コード例 #2
0
    public override void OnInspectorGUI()
    {
        //CUSTOM PROPERTY EDITOR
        ItemPickup pickup = (target as ItemPickup);

        // create or assign item

        GUILayout.BeginHorizontal();

        if (pickup.item)
        {
            itemName = pickup.item.name;
        }
        else if (string.IsNullOrEmpty(itemName))
        {
            itemName = pickup.transform.root.name;
        }

        itemName = EditorGUILayout.TextField(itemName);
        if (pickup.item)
        {
            pickup.item.name = itemName;
        }
        pickup.item = EditorGUILayout.ObjectField(pickup.item, typeof(Item), false) as Item;

        if (pickup.item)
        {
            pickup.item.icon = EditorGUILayout.ObjectField(pickup.item.icon, typeof(Sprite), false) as Sprite;
        }

        GUILayout.EndHorizontal();

        if (!pickup.item)
        {
            if (GUILayout.Button("Create new item"))
            {
                pickup.item = CreateItem(itemName, UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage().prefabAssetPath);
            }
        }

        pickup.radius = EditorGUILayout.FloatField("radius", pickup.radius);


        if (pickup.worldView == null)
        {
            var rends = pickup.GetComponentsInChildren <Renderer>(true);
            foreach (var rend in rends)
            {
                if (!rend.GetComponent <Equipmentizer>() &&
                    GUILayout.Button("Make '" + rend.name + "' lay down"))
                {
                    pickup.worldView = rend.transform;
                    pickup.worldView.gameObject.SetActive(true);
                }
            }
        }
        else
        {
            GUILayout.BeginHorizontal();

            if (GUILayout.Button(pickup.worldView.gameObject.activeSelf ? "hide" : "show"))
            {
                pickup.worldView.gameObject.SetActive(!pickup.worldView.gameObject.activeSelf);
            }

            pickup.worldView = EditorGUILayout.ObjectField(pickup.worldView, typeof(Transform), true) as Transform;

            GUILayout.EndHorizontal();
        }

        BoxCollider collider = pickup.gameObject.GetComponent <BoxCollider>();

        if (collider == null)
        {
            collider = pickup.gameObject.AddComponent <BoxCollider>();
        }

        if (GUILayout.Button("Fit collider"))
        {
            ColliderFitter.FitCollider(collider.gameObject, false);
        }


        defaultEditor = EditorGUILayout.Foldout(defaultEditor, "-- default inspector --");

        if (defaultEditor)
        {
            base.OnInspectorGUI();

            if (colliderEditor == null)
            {
                colliderEditor = Editor.CreateEditor(collider);
            }
            colliderEditor.OnInspectorGUI();
        }
        else
        {
            if (colliderEditor == null)
            {
                DestroyImmediate(colliderEditor);
            }
        }
    }