코드 리팩토링

재사용성 및 확장성을 고려하여 코드 전반을 리팩토링함
This commit is contained in:
2026-01-21 01:45:15 +09:00
parent b4ac8f600f
commit db5db4b106
45 changed files with 2775 additions and 248 deletions

View File

@@ -1,23 +1,118 @@
using UnityEngine;
/// <summary>
/// ScriptableObject defining item properties.
/// Implements IUsableItem and IEquippableItem for extensibility.
/// </summary>
[CreateAssetMenu(fileName = "New Item", menuName = "Inventory/Item")]
public class ItemData : ScriptableObject
public class ItemData : ScriptableObject, IUsableItem, IEquippableItem
{
[Header("Basic Info")]
public int itemID;
public string itemName;
public Sprite icon;
public float weight; // 아이템 개당 무게
public int maxStack = 99; // 최대 중첩 개수
public Sprite icon;
[TextArea] public string description;
[Header("Stack & Weight")]
public float weight = 1f;
public int maxStack = 99;
[Header("Visual Source")]
public GameObject originalBlockPrefab; // 이제 이것만 있으면 됩니다!
[Tooltip("Original prefab for dropped item visuals")]
public GameObject originalBlockPrefab;
[Header("Tool Settings")]
public bool isTool; // 도구 여부
public PlayerActionData toolAction; // 이 도구를 들었을 때 나갈 액션 (예: MiningActionData)
[Header("Item Behavior")]
[Tooltip("Defines what happens when the item is used")]
public ItemBehavior behavior;
[Header("Visual Settings")]
public GameObject toolPrefab; // 캐릭터 손에 스폰될 3D 프리팹
public Vector3 equipPositionOffset; // 손 위치 미세 조정
public Vector3 equipRotationOffset; // 손 회전 미세 조정
}
[Header("Equipment Settings")]
[Tooltip("Whether this item can be equipped (shows in hand)")]
public bool isEquippable;
[Tooltip("Prefab spawned in player's hand when equipped")]
public GameObject equipmentPrefab;
public Vector3 equipPositionOffset;
public Vector3 equipRotationOffset;
[Tooltip("Name of the transform to attach equipment to")]
public string attachmentPointName = "ToolAnchor";
#region IUsableItem Implementation
public bool IsConsumable => behavior != null && behavior.IsConsumable;
public bool CanUse(GameObject user, GameObject target)
{
return behavior != null && behavior.CanUse(user, target);
}
public void Use(GameObject user, GameObject target)
{
if (behavior != null)
{
behavior.Use(user, target);
}
}
public ActionDescriptor GetUseAction()
{
return behavior?.GetActionDescriptor();
}
#endregion
#region IEquippableItem Implementation
public GameObject GetEquipmentPrefab() => equipmentPrefab;
public Vector3 GetPositionOffset() => equipPositionOffset;
public Vector3 GetRotationOffset() => equipRotationOffset;
public string GetAttachmentPointName() => attachmentPointName;
public Transform FindAttachmentPoint(GameObject user)
{
if (string.IsNullOrEmpty(attachmentPointName))
return user.transform;
var transforms = user.GetComponentsInChildren<Transform>();
foreach (var t in transforms)
{
if (t.name == attachmentPointName)
return t;
}
return user.transform;
}
#endregion
#region Utility Properties
/// <summary>
/// Check if this item has any usable behavior.
/// </summary>
public bool HasBehavior => behavior != null;
/// <summary>
/// Check if this item can be equipped.
/// </summary>
public bool CanBeEquipped => isEquippable && equipmentPrefab != null;
#endregion
#region Utility Methods
/// <summary>
/// Get display name for UI.
/// </summary>
public string GetDisplayName() => string.IsNullOrEmpty(itemName) ? name : itemName;
/// <summary>
/// Get description for UI.
/// </summary>
public string GetDescription() => description;
/// <summary>
/// Calculate total weight for a stack.
/// </summary>
public float GetStackWeight(int count) => weight * count;
#endregion
}