using UnityEngine; using UnityEngine.UI; using UnityEditor; using TMPro; public class ItemBuilderTool : EditorWindow { // Основные данные private string itemName = "NewItem"; private string itemId = ""; private string description = ""; private ItemType itemType = ItemType.Material; // Визуал private GameObject modelPrefab; private Sprite icon; private Color previewColor = Color.gray; // Свойства private int maxStack = 64; private int value = 1; private float weight = 1f; private bool isDroppable = true; private bool isStackable = true; // Префаб private GameObject worldItemPrefab; [MenuItem("Tools/Item Builder")] public static void ShowWindow() { GetWindow("Конструктор Предметов"); } void OnGUI() { GUILayout.Label("Создание предмета", EditorStyles.boldLabel); // Основные данные GUILayout.Label("Основное", EditorStyles.miniBoldLabel); itemName = EditorGUILayout.TextField("Название", itemName); itemId = EditorGUILayout.TextField("ID", itemId); description = EditorGUILayout.TextField("Описание", description); itemType = (ItemType)EditorGUILayout.EnumPopup("Тип предмета", itemType); GUILayout.Space(10); // Визуал GUILayout.Label("Визуал", EditorStyles.miniBoldLabel); modelPrefab = (GameObject)EditorGUILayout.ObjectField("3D модель", modelPrefab, typeof(GameObject), false); icon = (Sprite)EditorGUILayout.ObjectField("Иконка", icon, typeof(Sprite), false); if (icon == null) { previewColor = EditorGUILayout.ColorField("Цвет иконки", previewColor); } GUILayout.Space(10); // Свойства GUILayout.Label("Свойства", EditorStyles.miniBoldLabel); maxStack = EditorGUILayout.IntField("Макс. стек", maxStack); value = EditorGUILayout.IntField("Цена", value); weight = EditorGUILayout.FloatField("Вес", weight); isDroppable = EditorGUILayout.Toggle("Можно выбросить", isDroppable); isStackable = EditorGUILayout.Toggle("Стек", isStackable); GUILayout.Space(10); // Префаб GUILayout.Label("Префаб предмета в мире", EditorStyles.miniBoldLabel); worldItemPrefab = (GameObject)EditorGUILayout.ObjectField("WorldItem Prefab", worldItemPrefab, typeof(GameObject), false); GUILayout.Space(20); // Кнопки GUI.color = Color.green; if (GUILayout.Button("Создать ItemData")) { CreateItemData(); } GUI.color = Color.cyan; if (GUILayout.Button("Создать WorldItem в сцене")) { CreateWorldItem(); } GUI.color = Color.yellow; if (GUILayout.Button("Создать префаб")) { CreateItemPrefab(); } GUI.color = Color.white; GUILayout.Space(10); EditorGUILayout.HelpBox( "1. Заполните данные предмета\n" + "2. Назначьте модель и иконку\n" + "3. Создайте ItemData или префаб", MessageType.Info); } void CreateItemData() { if (string.IsNullOrEmpty(itemName)) { EditorUtility.DisplayDialog("Ошибка", "Введите название предмета", "OK"); return; } var item = ScriptableObject.CreateInstance(); item.id = string.IsNullOrEmpty(itemId) ? GUID.Generate().ToString() : itemId; item.itemName = itemName; item.description = description; item.type = itemType; item.modelPrefab = modelPrefab; item.icon = icon != null ? icon : CreatePlaceholderIcon(); item.maxStack = maxStack; item.value = value; item.weight = weight; item.isDroppable = isDroppable; item.isStackable = isStackable; // Сохраняем string path = $"Assets/Inventory/Items/{itemName}.asset"; string folder = System.IO.Path.GetDirectoryName(path); if (!System.IO.Directory.Exists(folder)) { System.IO.Directory.CreateDirectory(folder); } AssetDatabase.CreateAsset(item, path); AssetDatabase.SaveAssets(); Selection.activeObject = item; Debug.Log($"[ItemBuilder] Создан: {itemName}"); } void CreateWorldItem() { if (modelPrefab == null) { // Создаём простой визуал var itemGO = new GameObject(itemName); var visual = GameObject.CreatePrimitive(PrimitiveType.Cube); visual.name = "Visual"; visual.transform.SetParent(itemGO.transform); visual.transform.localPosition = Vector3.zero; visual.transform.localScale = Vector3.one * 0.3f; DestroyImmediate(visual.GetComponent()); var worldItem = itemGO.AddComponent(); var col = itemGO.AddComponent(); col.radius = 0.5f; col.isTrigger = true; itemGO.transform.position = Vector3.zero; Selection.activeGameObject = itemGO; } else { var itemGO = Instantiate(modelPrefab); itemGO.name = itemName; itemGO.AddComponent(); itemGO.transform.position = Vector3.zero; Selection.activeGameObject = itemGO; } Debug.Log($"[ItemBuilder] Создан WorldItem: {itemName}"); } void CreateItemPrefab() { string path = EditorUtility.SaveFilePanelInProject( "Сохранить префаб", itemName, "prefab", "Выберите место"); if (string.IsNullOrEmpty(path)) return; GameObject prefab; if (modelPrefab != null) { prefab = Instantiate(modelPrefab); prefab.name = itemName; } else { prefab = new GameObject(itemName); var visual = GameObject.CreatePrimitive(PrimitiveType.Cube); visual.name = "Visual"; visual.transform.SetParent(prefab.transform); visual.transform.localPosition = Vector3.zero; visual.transform.localScale = Vector3.one * 0.3f; DestroyImmediate(visual.GetComponent()); } prefab.AddComponent(); var col = prefab.GetComponent(); if (col == null) { var sphere = prefab.AddComponent(); sphere.radius = 0.5f; sphere.isTrigger = true; } GameObject savedPrefab = PrefabUtility.SaveAsPrefabAsset(prefab, path); DestroyImmediate(prefab); Selection.activeObject = savedPrefab; Debug.Log($"[ItemBuilder] Префаб сохранён: {path}"); } Sprite CreatePlaceholderIcon() { var tex = new Texture2D(64, 64); var colors = new Color[64 * 64]; for (int i = 0; i < colors.Length; i++) { colors[i] = previewColor; } tex.SetPixels(colors); tex.Apply(); return Sprite.Create(tex, new Rect(0, 0, 64, 64), new Vector2(0.5f, 0.5f)); } }