fack
This commit is contained in:
262
Assets/Inventory/Scripts/ItemGenerator.cs
Normal file
262
Assets/Inventory/Scripts/ItemGenerator.cs
Normal file
@@ -0,0 +1,262 @@
|
||||
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>();
|
||||
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<ItemData> GenerateAll(List<ItemGenerator> generators)
|
||||
{
|
||||
var items = new List<ItemData>();
|
||||
foreach (var generator in generators)
|
||||
{
|
||||
if (generator != null)
|
||||
{
|
||||
items.Add(generator.GenerateItemData());
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Предмет в мире - подбирается игроком
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Подобрать предмет вручную (по кнопке)
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выбросить предмет с силой
|
||||
/// </summary>
|
||||
public void Throw(Vector3 velocity)
|
||||
{
|
||||
var rb = GetComponent<Rigidbody>();
|
||||
if (rb == null) rb = gameObject.AddComponent<Rigidbody>();
|
||||
rb.linearVelocity = velocity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Точка спавна предмета
|
||||
/// </summary>
|
||||
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<GameObject>("Prefabs/WorldItem");
|
||||
if (prefab != null)
|
||||
{
|
||||
var worldItem = Instantiate(prefab, transform.position, Quaternion.identity).GetComponent<WorldItem>();
|
||||
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
|
||||
Reference in New Issue
Block a user