using UnityEngine;
using UnityEditor;
using TMPro;
///
/// Инструмент создания предметов.
/// Tools > Item Builder
///
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;
// Pickup
private float interactRange = 2.5f;
[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 (оставь пустым для GUID)", 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);
interactRange = EditorGUILayout.FloatField("Дальность подбора (E)", interactRange);
GUILayout.Space(20);
// Кнопки
GUI.color = Color.green;
if (GUILayout.Button("Создать ItemData (ScriptableObject)"))
CreateItemData();
GUI.color = Color.cyan;
if (GUILayout.Button("Создать WorldItem в сцене"))
CreateWorldItem();
GUI.color = Color.yellow;
if (GUILayout.Button("Создать WorldItem как префаб"))
CreateItemPrefab();
GUI.color = Color.white;
GUILayout.Space(10);
EditorGUILayout.HelpBox(
"Подбор предметов — только по кнопке E (авто-pickup при касании убран намеренно).\n" +
"1. Заполните данные → Создайте ItemData\n" +
"2. Назначьте ItemData в InventoryManager.itemDatabase\n" +
"3. Создайте WorldItem для размещения предметов на сцене",
MessageType.Info);
}
void CreateItemData()
{
if (string.IsNullOrEmpty(itemName))
{
EditorUtility.DisplayDialog("Ошибка", "Введите название предмета", "OK");
return;
}
var item = ScriptableObject.CreateInstance();
item.id = string.IsNullOrEmpty(itemId) ? System.Guid.NewGuid().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 folder = "Assets/Inventory/Items";
if (!System.IO.Directory.Exists(folder))
System.IO.Directory.CreateDirectory(folder);
string path = $"{folder}/{itemName}.asset";
AssetDatabase.CreateAsset(item, path);
AssetDatabase.SaveAssets();
Selection.activeObject = item;
Debug.Log($"[ItemBuilder] Создан: {itemName} → {path}");
}
void CreateWorldItem()
{
var itemGO = new GameObject(itemName);
// Визуал
GameObject visual;
if (modelPrefab != null)
{
visual = (GameObject)PrefabUtility.InstantiatePrefab(modelPrefab, itemGO.transform);
}
else
{
visual = GameObject.CreatePrimitive(PrimitiveType.Cube);
visual.transform.SetParent(itemGO.transform, false);
visual.transform.localScale = Vector3.one * 0.3f;
DestroyImmediate(visual.GetComponent());
}
visual.name = "Visual";
visual.transform.localPosition = Vector3.zero;
// WorldItem компонент
var worldItem = itemGO.AddComponent();
worldItem.interactRange = interactRange;
// Trigger-коллайдер для OverlapSphere (не для авто-pickup!)
var col = itemGO.AddComponent();
col.radius = 0.5f;
col.isTrigger = true;
itemGO.transform.position = Vector3.zero;
Selection.activeGameObject = itemGO;
Debug.Log($"[ItemBuilder] Создан WorldItem: {itemName}");
}
void CreateItemPrefab()
{
string path = EditorUtility.SaveFilePanelInProject(
"Сохранить WorldItem префаб",
itemName,
"prefab",
"Выберите место сохранения");
if (string.IsNullOrEmpty(path)) return;
var prefabGO = new GameObject(itemName);
// Визуал
GameObject visual;
if (modelPrefab != null)
{
visual = (GameObject)PrefabUtility.InstantiatePrefab(modelPrefab, prefabGO.transform);
}
else
{
visual = GameObject.CreatePrimitive(PrimitiveType.Cube);
visual.transform.SetParent(prefabGO.transform, false);
visual.transform.localScale = Vector3.one * 0.3f;
DestroyImmediate(visual.GetComponent());
}
visual.name = "Visual";
visual.transform.localPosition = Vector3.zero;
var worldItem = prefabGO.AddComponent();
worldItem.interactRange = interactRange;
var col = prefabGO.AddComponent();
col.radius = 0.5f;
col.isTrigger = true;
GameObject savedPrefab = PrefabUtility.SaveAsPrefabAsset(prefabGO, path);
DestroyImmediate(prefabGO);
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));
}
}