인벤토리 시스템 - 스크립터블 오브젝트 사용
1. 아이템 시스템 구현하기
- ItemObject안에 있는 Item 클래스에 있는 buffs(ItemBuff)를 통해 캐릭터에 능력치 변화를 줌.
@ ItemBuffer_New 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public enum CharacterAttribute
{
Agility,
Intellect,
Stamina,
Strength
}
[Serializable]
public class ItemBuffer_New
{
public CharacterAttribute stat;
public int value;
[SerializeField]
private int min; // 동일한 아이템(단검)이어도 공격력이 1일수가 있고 3일수가 있음, 그 최솟값과 최댓값을 정하기 위한것.
[SerializeField]
private int max;
public int Min => min;
public int Max => max;
public ItemBuffer_New(int min, int max)
{
this.min = min;
this.max = max;
GenerateValue();
}
public void GenerateValue()
{
value = UnityEngine.Random.Range(min, max);
}
public void AddValue(ref int v)
{
v += value;
}
}
- 프로퍼티
public int Min => min;
public int Max => max;
- min, max의 값을 읽기전용으로 외부에서 접근 가능하게 함. 아래와 동일한 기능을 가진 코드.
public int Min
{
get { return min; }
}
public int Max
{
get { return max; }
}
- ref 키워드 : 메서드에 전달(호출)할때 메모리 주소를 전달해서 메소드 내부에서 변수의 값을 변경하면 호출한 쪽의 변수 값도 함께 변경됨.
int myValue = 10;
AddValue(ref myValue); // myValue의 값이 메서드 내에서 변경됨
public void AddValue(ref int v)
{
v += value;
}
- 위의 코드에서 myValue값이 AddValue를 ref키워드를 사용했기때문에 결과값이 10이 아니라 10 + value 값으로 변함.
- 아이템 오브젝트에서 복사해서 아이템 버프를 생성할 때에는 GenerateValue() 을 통해서 min값과 max값 사이에 랜덤한 능력치의 아이템 생성됨.
@ 이제 실제로 저장되어 데이터화 되는 item object를 구현해볼것임
item object는 스크립터블 오브젝트에서 상속을 받게 됨.
@ Item_New 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[Serializable]
public class Item_New
{
public int id = -1; // 아이템을 식별할 수 있는 id 값
public string name; // 아이템 이름
public ItemBuffer_New[] buffs; // 여러가지 버프가 있을수 있기 때문에 배열로 정함.
public Item_New()
{
id = -1; // 아이템 id가 -1이면 비어있는 아이템이라는 뜻
name = "";
}
public Item_New(ItemObject_New itemObject)// 아이템 오브젝트를 받아서 아이템 데이터에서 이 아이템을 새로 복사해서 생성한다는 생성자
{
name = itemObject.name;
id = itemObject.data.id;
buffs = new ItemBuffer_New[itemObject.data.buffs.Length];
for (int i = 0; i < buffs.Length; i++)
{
buffs[i] = new ItemBuffer_New(itemObject.data.buffs[i].Min, itemObject.data.buffs[i].Max)
{
stat = itemObject.data.buffs[i].stat
};
}
}
}
@ ItemObject_New 스크립트
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
public enum ItemType_New : int
{
Helmet = 0,
Chest = 1,
Pants = 2,
Boots = 3,
Pauldrons = 4,
Gloves = 5,
LeftWeapon = 6,
RightWeapon = 7,
Food,
Default,
}
[CreateAssetMenu(fileName = "New Item", menuName = "Inventory System/Items/New Item")]
public class ItemObject_New : ScriptableObject
{
public ItemType_New type; // 아이템 타입 정의
public bool stackable; // 물약과 같이 겹쳐서 표시될 수 있는 아이템을 의미
public Sprite icon;
public GameObject modelPrefab; // 캐릭터에게 부착되거나 같이 표시되어야 할 3D 오브젝트들을 의미
public Item_New data = new Item_New();
public List<string> boneNames = new List<string>(); // 캐릭터 조합 시스템에서 사용되는 변수
[TextArea(15, 20)]
public string description;
private void OnValidate() // OnValidate() : 데이터를 변경하게 되면 호출되는 함수
{
boneNames.Clear();
if(modelPrefab == null || modelPrefab.GetComponentInChildren<SkinnedMeshRenderer>() == null)
{
return;
}
SkinnedMeshRenderer renderer = modelPrefab.GetComponentInChildren<SkinnedMeshRenderer>();
Transform[] bones = renderer.bones;
foreach (Transform t in bones)
{
boneNames.Add(t.name);
}
}
public Item_New CreateItem() // 아이템을 추가, 생성해서 변환하는 함수
{
Item_New newItem = new Item_New(this);
return newItem;
}
}
스킨 렌더러가 존재한다면 이 렌더러에서 트랜스폼 bones를 가져옮.
@ ItemObjectDataBase_New 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Item DataBase_New", menuName = "Inventory System/Items/DataBase_New")]
public class ItemObjectDataBase_New : ScriptableObject
{
public ItemObject_New[] itemObjects;
public void OnValidate()
{
for (int i = 0; i < itemObjects.Length; i++) // 아이템을 생성한다음 id를 일일히 넣어주기 귀찮으니까 for문을 사용해서 일률적으로 id 값을 넣어줌.
{
itemObjects[i].data.id = i;
}
}
}
2. 인벤토리 시스템 구현하기
- 인벤토리 슬롯(InventorySlot)에서 아이템이 추가,삭제 될때마다 갱신 메세지를 발생시켜 액션들로 관리하고, 또 이 슬롯에 아이템 타입을 지정해서 지정된 아이템만 위치할 수 있도록 기능 구현.
- 인벤토리(Inventory) : 인벤토리 슬롯들을 리스트화 해서 관리함, 인벤토리 UI와 연결되는 부분
- 인벤토리 슬롯 구현
3. 인벤토리 UI 구현하기
- 인벤토리UI는 기본적으로 마우스 입력이 가장 중요하기에 이벤트 트리거를 반드시 게임 오브젝트에 컴포넌트로 추가되어 있어야 함.
[RequireComponent()] : 이 스크립트를 오브젝트에 넣으면 게임 오브젝트에 EventTrigger가 자동으로 추가됨. *누락 방지
4. 캐릭터 장비 교체 구현하기
5. 아이템 획득 & 사용 구현하기
캐릭터 오브젝트 주변에 원 퍼져 나가게 하기(스캔) (0) | 2024.05.27 |
---|---|
애니메이터 아바타 변경하기(Animator.Avatar, 캐릭터 교체) (1) | 2024.05.01 |
19장. 좀비 서바이벌 멀티 플레이어( 네트워크 게임 월드 구현 ) (1) | 2024.05.01 |
18장. 좀비 서바이벌(멀티플레이) (0) | 2024.04.29 |
17장. 좀비 서바이벌(아이템 생성, 포스트 프로세싱) (0) | 2024.04.22 |