Inventory – Item

  • by

RPG Game에서 자주 사용되는 아이템이나 인벤토리의 베이스를 구현해 보자

아이템은 캐릭터의 기본 스테이터스가 변화하는 용도로 사용할 예정이다.

(힘 증가, 체력 증가 등)

(아이템 클래스 다이어그램)


아이템 클래스 다이어그램

아이템 관련 데이터는 ScriptableObejct로 생성해 Inspector에서 관리할 예정이다.

Item은 아이템에 의한 캐릭터의 행동을 명시한다.

Item Object는 아이템의 설명과 캐릭터의 동작과 표현 방법을 명시한다.

Item Database Object는 Item Object를 List화하여 관리한다.

Item Buff는 실제 Item으로서 캐릭터에 적용 가능한 Buff를 지정한다.

– Item class와 Item Object class가 분리되어 있는 이유? (나중에 Data Save 등에 Json을 사용하기 쉽도록)

: Item Object는 json으로 저장하는데 귀찮은 부분이 많기 때문에

Item Class를 json으로 저장합니다.

1. Item Buff

– 직렬화된 클래스에서 생성

– Enum에서 적용할 수 있는 상태 또는 버프 유형을 나열합니다.

– 해당 아이템이 가질 수 있는 현재의 버프값 value / 최소치 min, 최대치 max 를 선언한다,

(값 값을 항목이 생성될 때 min-max 사이의 값으로 무작위로 설정되기 때문에)

– 생성자에서 min, max 값을 받고 Random 함수로 값을 결정합니다.

– 나중에 필요한 상태를 참조로 받고 value 값을 더하는 함수를 추가합니다.

(ItemBuff 스크립트)

더 보기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public enum CharacterAttribute
{
    Agility,
    Intellect,
    Stamina,
    Strength
}


(Serializable)
public class ItemBuff 
{
    public CharacterAttribute stat;
    public int value;

    (SerializeField)
    private int min;

    (SerializeField)
    private int max;

    //min-max 범위내에 랜덤 값을 갖는 아이템
    public int Min => min;
    public int Max => max;

    public ItemBuff(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;
    }
}

2. Item

– 직렬화된 클래스에서 생성한다.

(나중에 json으로 저장할 준비)

– 아이템간의 식별을 위한 id 값을 선언한다 (int)

– item 사이의 이름에 대한 name 값 선언 (string)

– 착용시 여러 효과를 받을 수 있기 때문에 Item Buff를 배열로 관리한다.

– 생성자 설정

1) 파라미터 없이 생성시에 id를 -1, 이름을 공백으로 둔다

2) ItemObject를 파라미터로서 받아, 생성시,

– 받은 id, name, buff를 등록한다.

(Item 스크립트)

더 보기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

(Serializable)
public class Item 
{
    public int id = -1;
    public string name;

    public ItemBuff() buffs;

    public Item()
    {
        id = -1;
        name = "";
    }

    public Item(ItemObject itemObject)
    {
        name = itemObject.name;
        id = itemObject.data.id;

        buffs = new ItemBuff(itemObject.data.buffs.Length);

        for (int i = 0; i < buffs.Length; i++)
        {
            buffs(i) = new ItemBuff(itemObject.data.buffs(i).Min, itemObject.data.buffs(i).Max)
            {
                stat = itemObject.data.buffs(i).stat
            };
        }
    }
}

3. Item Object

– ScriptableObject를 상속하고 구현합니다.

– 사용 가능한 ItemType을 나열합니다.

– bool형으로 현재의 아이템이 개수의 중첩이 가능한가 표기한다.

(물약 같은 경우는 한칸에 갯수만큼 증가하기 때문에)

– 아이템의 Sprite icon/캐릭터에 첨부된 model GameObject를 선언한다.

– Item 데이터 생성 (임시 => Insepctor로 조작, 변경 가능)

– 관련 boneName을 list로 가지고 있습니다.

(.이 부분은 나중에 추가 예정)

– 문자열로이 항목의 설명을 쉽게 기록합니다.

– OnValidate 함수에서 Inspector로 데이터 설정을 변경하면 함수를 호출합니다.

:boneName을 초기화하고 modelPrefab의 bone 위치를 받습니다.

: 이 후 받은 책을 boneName에 추가합니다.

– CreateItem 함수로 실제로 이 아이템 데이터를 생성합니다.

(ItemObject 스크립트)

더 보기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum ItemType
{
    Helmet,
    Face,
    Body,
    Cloak,
    LeftWeapon,
    RightWeapon,
    Food,
    Default
}


(CreateAssetMenu(fileName ="New Item", menuName = "Inventory System/Items/New Item"))
public class ItemObject : ScriptableObject
{
    public ItemType type;
    //물약같은거면 여러개 갖고 있는 경우 체크
    public bool stackable;

    public Sprite icon;
    //캐릭터에게 부착 or 표시되어야할 3d prefab
    public GameObject modelPrefab;

    //동작
    public Item data = new Item();

    public List<string> boneNames = new List<string>();

    (TextArea(15, 20))
    public string description;

    //데이터 설정을 변경하면 호출되는 함수
    private void 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 CreateItem()
    {
        Item newItem = new Item(this);
        return new Item();
    }
}

4. Item Object Database

– ItemObject를 나열하고 관리하는 역할을 한다.

– ScriptableObject를 상속하고 구현합니다.

– OnValidate에서 실제 List에 ItemObject가 등록될 때마다 id값을 설정하는 역할을 한다.

(아이템 타입별로 구간을 크게 나누어 더하기도 하지만 지금은 단순히 1씩 증가시킨 값을 넣어준다)

(Item Object Database)

더 보기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

(CreateAssetMenu(fileName ="New Item Database", menuName ="Inventory System/Database"))
public class ItemObjectDatabase : ScriptableObject
{
    public ItemObject() itemObjects;

    public void OnValidate()
    {
        for(int i =0;i < itemObjects.Length; i++)
        {
            itemObjects(i).data.id = i;
        }
    }
}

– 결과

: ScriptableObject에서 Item Object를 생성한 모습과 Item Object Database를 생성한 후 Item Object를 등록한 모습이다

: 각 아이템을 생성하여 아이콘 이미지나 버프 효과 등을 설정할 수 있게 되었고, 이것을 Database에 추가하여 관리할 수 있게 되었습니다.

항목 개체/항목 개체 데이터베이스 검사기 창의 모양