231 lines
7.5 KiB
C#
231 lines
7.5 KiB
C#
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<ItemBuilderTool>("Конструктор Предметов");
|
||
}
|
||
|
||
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<ItemData>();
|
||
|
||
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<Collider>());
|
||
|
||
var worldItem = itemGO.AddComponent<WorldItem>();
|
||
var col = itemGO.AddComponent<SphereCollider>();
|
||
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<WorldItem>();
|
||
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<Collider>());
|
||
}
|
||
|
||
prefab.AddComponent<WorldItem>();
|
||
|
||
var col = prefab.GetComponent<Collider>();
|
||
if (col == null)
|
||
{
|
||
var sphere = prefab.AddComponent<SphereCollider>();
|
||
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));
|
||
}
|
||
} |