using UnityEngine; using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; #endif public class ItemGenerator : MonoBehaviour { [Header("Item Template")] public string itemId = ""; public string itemName = ""; public string description = ""; public ItemType itemType = ItemType.Material; public Sprite icon; public GameObject modelPrefab; public int maxStack = 64; public bool isCraftable; [Header("Crafting (if craftable)")] public string[] craftIngredients; public int[] craftAmounts; public string craftResultId; public int craftResultAmount = 1; public ItemData GenerateItemData() { if (string.IsNullOrEmpty(itemId)) { itemId = System.Guid.NewGuid().ToString(); } var itemData = ScriptableObject.CreateInstance(); itemData.id = itemId; itemData.itemName = itemName; itemData.description = description; itemData.type = itemType; itemData.modelPrefab = modelPrefab; itemData.icon = icon; itemData.maxStack = maxStack; itemData.isCraftable = isCraftable; if (isCraftable && craftIngredients != null && craftIngredients.Length > 0) { itemData.craftingRecipe = new ItemData.CraftingRecipe { ingredients = craftIngredients, amounts = craftAmounts, resultId = craftResultId, resultAmount = craftResultAmount }; } return itemData; } public static List GenerateAll(List generators) { var items = new List(); foreach (var generator in generators) { if (generator != null) { items.Add(generator.GenerateItemData()); } } return items; } } /// /// Предмет в мире - подбирается игроком /// public class WorldItem : MonoBehaviour { public ItemData itemData; public int amount = 1; [Header("Settings")] public float pickupDelay = 0f; public bool useFactory = true; private bool _canPickup; public void Setup(ItemData data, int count) { itemData = data; amount = count; if (data.modelPrefab != null) { var model = Instantiate(data.modelPrefab, transform); model.transform.localPosition = Vector3.zero; } // Задержка перед подбором if (pickupDelay > 0) Invoke(nameof(EnablePickup), pickupDelay); else _canPickup = true; } private void EnablePickup() => _canPickup = true; void OnTriggerEnter(Collider other) { TryPickup(other); } void OnControllerColliderHit(ControllerColliderHit hit) { TryPickup(hit.controller); } /// /// Подобрать предмет вручную (по кнопке) /// public bool TryPickupByButton() { Debug.Log($"[TryPickup] _canPickup={_canPickup}, itemData={itemData?.itemName}, amount={amount}, Instance={InventoryManager.Instance != null}"); if (!_canPickup) { Debug.LogWarning("[TryPickup] Cannot pickup - not ready yet"); return false; } if (itemData == null) { Debug.LogWarning("[TryPickup] itemData is null!"); return false; } if (InventoryManager.Instance == null) { Debug.LogWarning("[TryPickup] InventoryManager.Instance is null!"); return false; } int remaining = InventoryManager.Instance.AddItem(itemData, amount); Debug.Log($"[TryPickup] AddItem returned remaining={remaining}"); if (remaining <= 0) { Destroy(gameObject); return true; } else { amount = remaining; return false; } } void TryPickup(Collider other) { if (!_canPickup) return; if (other == null) return; if (!other.CompareTag("Player")) return; if (useFactory && InventoryItemFactory.Instance != null) { InventoryItemFactory.Instance.PickupItem(this, this); } else { // Fallback - старый способ int remaining = InventoryManager.Instance.AddItem(itemData, amount); if (remaining <= 0) { Destroy(gameObject); } else { amount = remaining; } } } /// /// Выбросить предмет с силой /// public void Throw(Vector3 velocity) { var rb = GetComponent(); if (rb == null) rb = gameObject.AddComponent(); rb.linearVelocity = velocity; } } /// /// Точка спавна предмета /// public class ItemSpawner : MonoBehaviour { public ItemData item; public int amount = 1; public float despawnTime = 300f; public bool spawnOnStart = false; public bool useFactory = true; public void Setup(ItemData itemData, int itemAmount, float despawn) { item = itemData; amount = itemAmount; despawnTime = despawn; } void Start() { if (spawnOnStart) Spawn(); } public void Spawn() { if (useFactory && InventoryItemFactory.Instance != null) { var worldItem = InventoryItemFactory.Instance.CreateWorldItem(item, amount, transform.position); if (worldItem != null && despawnTime > 0) { Destroy(worldItem.gameObject, despawnTime); } } else { // Fallback - старый способ var prefab = Resources.Load("Prefabs/WorldItem"); if (prefab != null) { var worldItem = Instantiate(prefab, transform.position, Quaternion.identity).GetComponent(); worldItem.Setup(item, amount); Destroy(worldItem.gameObject, despawnTime); } } } public void Despawn() { Destroy(gameObject); } } #if UNITY_EDITOR [CustomEditor(typeof(ItemGenerator))] public class ItemGeneratorEditor : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); if (GUILayout.Button("Generate ItemData")) { var generator = (ItemGenerator)target; var itemData = generator.GenerateItemData(); string path = $"Assets/Inventory/Items/{itemData.itemName}.asset"; AssetDatabase.CreateAsset(itemData, path); AssetDatabase.SaveAssets(); Debug.Log($"Created item: {itemData.itemName} at {path}"); } } } #endif