Files
AppleHillsProduction/Assets/Editor/Tools/PrefabCreatorWindow.cs
2025-11-01 20:52:31 +01:00

169 lines
7.5 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEditor;
using UnityEngine;
using System.IO;
using Interactions;
using PuzzleS;
namespace Editor
{
public class PrefabCreatorWindow : EditorWindow
{
private string _prefabName = "NewPrefab";
private string _saveFolderPath = "Assets/Prefabs/Items";
private string _pickupSoFolderPath = "Assets/Data/Items";
private string _puzzleSoFolderPath = "Assets/Data/Puzzles";
private bool _addObjective;
private PickupItemData _pickupData;
private PuzzleStepSO _objectiveData;
private UnityEditor.Editor _soEditor;
private enum ItemType { None, Pickup, ItemSlot }
private ItemType _itemType = ItemType.None;
private bool _createNext = false;
[MenuItem("AppleHills/Item Prefab Creator")]
public static void ShowWindow()
{
var window = GetWindow<PrefabCreatorWindow>("Prefab Creator");
window.minSize = new Vector2(400, 400);
// Set default paths if not already set
if (string.IsNullOrEmpty(window._saveFolderPath))
window._saveFolderPath = "Assets/Prefabs/Items";
if (string.IsNullOrEmpty(window._pickupSoFolderPath))
window._pickupSoFolderPath = "Assets/Data/Items";
if (string.IsNullOrEmpty(window._puzzleSoFolderPath))
window._puzzleSoFolderPath = "Assets/Data/Puzzles";
}
private void OnGUI()
{
EditorGUILayout.LabelField("Prefab Creator", EditorStyles.boldLabel);
_prefabName = EditorGUILayout.TextField("Prefab Name", _prefabName);
// Prefab save folder
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Save Folder");
EditorGUILayout.SelectableLabel(_saveFolderPath, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
if (GUILayout.Button("Select...", GUILayout.Width(80)))
{
_saveFolderPath = PrefabEditorUtility.SelectFolder(_saveFolderPath, "Prefabs/Items");
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Add Components:", EditorStyles.boldLabel);
// Item type selection
var newType = (ItemType)EditorGUILayout.EnumPopup("Item Type", _itemType);
if (newType != _itemType)
{
_itemType = newType;
}
bool addObjective = EditorGUILayout.Toggle("ObjectiveStepBehaviour", _addObjective);
_addObjective = addObjective;
EditorGUILayout.Space();
// Pickup Data (for Pickup or ItemSlot)
if (_itemType == ItemType.Pickup || _itemType == ItemType.ItemSlot)
{
EditorGUILayout.LabelField("Pickup Data:", EditorStyles.boldLabel);
_pickupData = (PickupItemData)EditorGUILayout.ObjectField("PickupItemData", _pickupData, typeof(PickupItemData), false);
// Pickup SO save folder
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Save To");
EditorGUILayout.SelectableLabel(_pickupSoFolderPath, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
if (GUILayout.Button("Select...", GUILayout.Width(80)))
{
_pickupSoFolderPath = PrefabEditorUtility.SelectFolder(_pickupSoFolderPath, "Data/Items");
}
EditorGUILayout.EndHorizontal();
if (_pickupData == null && GUILayout.Button("Create New PickupItemData"))
{
_pickupData = PrefabEditorUtility.CreateScriptableAsset<PickupItemData>(_prefabName + "_pickup", _pickupSoFolderPath);
}
if (_pickupData != null)
{
PrefabEditorUtility.DrawScriptableObjectEditor(ref _soEditor, _pickupData);
}
}
// Objective Data
if (_addObjective)
{
EditorGUILayout.LabelField("Objective Data:", EditorStyles.boldLabel);
_objectiveData = (PuzzleStepSO)EditorGUILayout.ObjectField("PuzzleStepSO", _objectiveData, typeof(PuzzleStepSO), false);
// Puzzle SO save folder
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Save To");
EditorGUILayout.SelectableLabel(_puzzleSoFolderPath, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
if (GUILayout.Button("Select...", GUILayout.Width(80)))
{
_puzzleSoFolderPath = PrefabEditorUtility.SelectFolder(_puzzleSoFolderPath, "Data/Puzzles");
}
EditorGUILayout.EndHorizontal();
if (_objectiveData == null && GUILayout.Button("Create New PuzzleStepSO"))
{
_objectiveData = PrefabEditorUtility.CreateScriptableAsset<PuzzleStepSO>(_prefabName + "_puzzle", _puzzleSoFolderPath);
}
if (_objectiveData != null)
{
PrefabEditorUtility.DrawScriptableObjectEditor(ref _soEditor, _objectiveData);
}
}
GUILayout.FlexibleSpace();
EditorGUILayout.BeginHorizontal();
GUI.enabled = !string.IsNullOrEmpty(_prefabName) && !string.IsNullOrEmpty(_saveFolderPath);
if (GUILayout.Button("Create Prefab", GUILayout.Height(28)))
{
CreatePrefab();
}
_createNext = GUILayout.Toggle(_createNext, "Create Next", GUILayout.Width(100), GUILayout.Height(28));
GUI.enabled = true;
EditorGUILayout.EndHorizontal();
}
private void CreatePrefab()
{
var go = new GameObject(_prefabName);
// Note: No need to add InteractableBase separately - Pickup and ItemSlot inherit from it
go.AddComponent<BoxCollider>();
int interactableLayer = LayerMask.NameToLayer("Interactable");
if (interactableLayer != -1)
go.layer = interactableLayer;
go.AddComponent<SpriteRenderer>();
if (_itemType == ItemType.Pickup)
{
var pickup = go.AddComponent<Pickup>();
pickup.itemData = _pickupData;
}
else if (_itemType == ItemType.ItemSlot)
{
var slot = go.AddComponent<ItemSlot>();
slot.itemData = _pickupData;
}
if (_addObjective)
{
var obj = go.AddComponent<ObjectiveStepBehaviour>();
obj.stepData = _objectiveData;
}
string prefabPath = Path.Combine(_saveFolderPath, _prefabName + ".prefab").Replace("\\", "/");
var prefab = PrefabUtility.SaveAsPrefabAsset(go, prefabPath);
DestroyImmediate(go);
AssetDatabase.Refresh();
Selection.activeObject = prefab;
EditorGUIUtility.PingObject(prefab);
EditorUtility.DisplayDialog("Prefab Created", $"Prefab saved to {prefabPath}", "OK");
if (_createNext)
{
_prefabName = "NewPrefab";
_pickupData = null;
_objectiveData = null;
_itemType = ItemType.None;
_addObjective = false;
_soEditor = null;
GUI.FocusControl(null);
Repaint();
}
}
}
}