2026-03-26 인벤토리
This commit is contained in:
33
Assets/02_Scripts/Item/Item.cs
Normal file
33
Assets/02_Scripts/Item/Item.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using UnityEngine;
|
||||
|
||||
public enum ItemType
|
||||
{
|
||||
EQUIPMENT = 0,
|
||||
CONSUMABLE = 1
|
||||
}
|
||||
|
||||
[CreateAssetMenu(fileName = "New Item", menuName = "Item")]
|
||||
public class Item : ScriptableObject
|
||||
{
|
||||
public string ItemId;
|
||||
public ItemType ItemType;
|
||||
public int SortId;
|
||||
public string ItemName;
|
||||
public Sprite Icon; //인벤토리용 2D 아이콘
|
||||
[TextArea] public string Description;
|
||||
public bool IsStackable; // 중첩 가능 여부
|
||||
public int MaxStack = 99; //장비는 1개
|
||||
public int Rarity = 1; //기본등급 1
|
||||
|
||||
// 월드용 데이터
|
||||
public GameObject PrefabVisible; // 월드상에서 보일 아이템의 프리팹
|
||||
public GameObject PrefabTuning; // 위치,회전 등이 조정된 모델
|
||||
public GameObject PrefabWild; // 아무런 조정도 하지 않은 아이템의 진짜 원본
|
||||
|
||||
public Vector3 WorldScale = Vector3.one; // 아이템마다 다른 크기 조절이 필요할 때
|
||||
public Vector3 WorldRotation = Vector3.zero;
|
||||
|
||||
[Header("Collider Settings")]
|
||||
public Vector3 ColliderCenter = Vector3.zero;
|
||||
public Vector3 ColliderSize = Vector3.one;
|
||||
}
|
||||
2
Assets/02_Scripts/Item/Item.cs.meta
Normal file
2
Assets/02_Scripts/Item/Item.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f26678279b3061489f872b3da046a05
|
||||
21
Assets/02_Scripts/Item/ItemInstance.cs
Normal file
21
Assets/02_Scripts/Item/ItemInstance.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class ItemInstance
|
||||
{
|
||||
public Item Data; // 원본 ScriptableObject 참조 (이름, 아이콘 등 불변 데이터)
|
||||
|
||||
// 개별적으로 변하는 데이터들
|
||||
public int EnhancementLevel; // 강화 수치
|
||||
public int Durability; // 내구도
|
||||
public int CurrentStack; // 현재 수량 (중첩 아이템일 경우)
|
||||
|
||||
//생성자
|
||||
public ItemInstance(Item sourceData, int stack = 1)
|
||||
{
|
||||
this.Data = sourceData;
|
||||
this.CurrentStack = stack;
|
||||
this.EnhancementLevel = -1;// 기본 강화 수치 (-1은 강화수치가 없는 아이템)
|
||||
this.Durability = -1; // 기본 내구도 (-1은 내구도가 없는 아이템)
|
||||
}
|
||||
}
|
||||
2
Assets/02_Scripts/Item/ItemInstance.cs.meta
Normal file
2
Assets/02_Scripts/Item/ItemInstance.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e19279917301c134f9d0cf2067c09fac
|
||||
105
Assets/02_Scripts/Item/WorldItem.cs
Normal file
105
Assets/02_Scripts/Item/WorldItem.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using NUnit.Framework.Interfaces;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class WorldItem : MonoBehaviour
|
||||
{
|
||||
// 실제 아이템 데이터 (강화 수치, 수량 등을 포함)
|
||||
public ItemInstance ItemInstance;
|
||||
private GameObject ModelPrefab; //월드 좌표는 사용하지 않는다 (복잡한 구조를 쉽게 가져오기 위해 Prefab으로 선언)
|
||||
private BoxCollider _boxCollider;
|
||||
|
||||
private float _rotationSpeed; // 회전 속도
|
||||
private float _bounceAmplitude; // 오르내리는 높이
|
||||
private float _bounceFrequency; // 오르내리는 속도
|
||||
private Vector3 _startPos;
|
||||
|
||||
[Header("Only Test")]
|
||||
[SerializeField] private Item _testField_OriginItem;
|
||||
[SerializeField] private int _testField_ItemStack = 1;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_boxCollider = GetComponent<BoxCollider>();
|
||||
if (_boxCollider == null) _boxCollider = gameObject.AddComponent<BoxCollider>();
|
||||
if (_boxCollider != null) _boxCollider.isTrigger = true;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
//테스트용
|
||||
if (ItemInstance == null || ItemInstance.Data == null)
|
||||
{
|
||||
ItemInstance Item = new ItemInstance(_testField_OriginItem, _testField_ItemStack);
|
||||
SetItem(Item);
|
||||
}
|
||||
|
||||
_rotationSpeed = GameManager.Instance.ItemRotationSpeed;
|
||||
_bounceAmplitude = GameManager.Instance.ItemBounceAmplitude;
|
||||
_bounceFrequency = GameManager.Instance.ItemBounceFrequency;
|
||||
|
||||
_startPos = transform.position;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// Y축을 기준으로 매 프레임 회전
|
||||
transform.Rotate(Vector3.up * _rotationSpeed * Time.deltaTime);
|
||||
|
||||
// 위아래로 둥둥 떠있는 듯한 느낌
|
||||
float newY = _startPos.y + Mathf.Sin(Time.time * _bounceFrequency) * _bounceAmplitude;
|
||||
transform.position = new Vector3(_startPos.x, newY, _startPos.z);
|
||||
}
|
||||
|
||||
// 아이템 데이터를 이 오브젝트에 주입하는 메서드
|
||||
public void SetItem(ItemInstance instance)
|
||||
{
|
||||
ItemInstance = instance;
|
||||
|
||||
// 기존 모델 지우기
|
||||
foreach (Transform child in transform) Destroy(child.gameObject);
|
||||
|
||||
if (instance.Data != null)
|
||||
{
|
||||
ModelPrefab = Instantiate(instance.Data.PrefabVisible, transform); //원본데이터에서 복제하여 자식으로 배치
|
||||
ModelPrefab.transform.localPosition = Vector3.zero;
|
||||
ModelPrefab.transform.localRotation = Quaternion.identity;
|
||||
ModelPrefab.transform.localScale = instance.Data.WorldScale;
|
||||
ModelPrefab.transform.localRotation = Quaternion.Euler(instance.Data.WorldRotation);
|
||||
|
||||
// 2. [핵심] 데이터에 저장된 값을 그대로 콜라이더에 주입
|
||||
if (_boxCollider != null)
|
||||
{
|
||||
_boxCollider.center = instance.Data.ColliderCenter;
|
||||
_boxCollider.size = instance.Data.ColliderSize;
|
||||
}
|
||||
}
|
||||
|
||||
gameObject.layer = LayerMask.NameToLayer("Item");
|
||||
}
|
||||
|
||||
// 플레이어가 아이템을 획득할 때 호출
|
||||
public void PickUp()
|
||||
{
|
||||
GameManager.Instance.Inventory.AddItem(this.ItemInstance);
|
||||
|
||||
PlayPickupEffect();
|
||||
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void PlayPickupEffect()
|
||||
{
|
||||
// 이펙트 프리팹을 소환하거나 소리를 재생
|
||||
Debug.Log($"{ItemInstance.Data.ItemName} 획득 이펙트 재생!");
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (other.CompareTag("Player"))
|
||||
{
|
||||
PickUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
Assets/02_Scripts/Item/WorldItem.cs.meta
Normal file
2
Assets/02_Scripts/Item/WorldItem.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5c8828a71cdaf64ba889ff392c6fb1f
|
||||
Reference in New Issue
Block a user