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(); } }
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); } } }