아이템 생성 및 삭제

# 학습 과정 소개

이번 과정에서는 아이템 생성과 삭제 기능을 알아봅니다. 제작할 예제는 다음과 같습니다.

  * 맵에 놓인 아이템을 먹을 때마다 인벤토리에 랜덤한 아이템이 생성
  * 아이템을 먹으면, 5초 뒤 아이템이 놓여있던 자리에 다시 생성
  * 맵에 놓인 다른 아이템을 먹을 때마다 인벤토리에 있는 모든 아이템 삭제



# 아이템 테이블 만들기

먼저 개별 아이템을 만들어 봅시다. 개별 아이템은 아이템 테이블에서 정의할 수 있습니다. 아이템 테이블은 DataSet으로 만듭니다. Workspace - MyDesk에서 콘텍스트 메뉴를 열어 Create DataSet을 선택합니다. 그리고 이름을 UserItemDataSet으로 설정합니다. [png](1659661729006e5721ddcf57b483b988411014b023136)   


> 더 알아보기 아이템을 생성할 때, 아이템 테이블에 정의된 데이터를 넘겨주는데, 만일 아이템 테이블을 다른 이름으로 만들면, 데이터를 넘길 수 없습니다. 따라서 아이템 테이블의 이름은 반드시 UserItemDataSet으로 생성합니다.

  
생성된 **UserItemDataSet**을 더블 클릭하여 데이터 에디터를 엽니다. 우선 컬럼 2개를 추가하고 컬럼 명을 다음과 같이 설정합니다. [png](163470329201303a32b2e6abd46be91bb61406acce0cc)   
> **더 알아보기** 아이템에서 **Name, IconRUID, Description**은 꼭 필요한 데이터이므로, 위와 동일한 이름으로 생성하세요.   
여기에 제작 중인 게임에 필요한 아이템 관련 데이터들을 추가합니다. 이번 예제에서는 **MaxStackCount, EffectAmount** 컬럼을 추가하겠습니다. [png](163470336846867242a6390754c5694eaac3cd773da56)   
각 컬럼 아래에 아이템을 만들고 데이터를 작성합니다. [png](1656659510837b79b1579311e41a29c7cfdd31709bde7)   
아이템 아이콘으로 사용할 이미지를 **Workspace**에 추가합니다. [png](163470407132182780528c94e4a88b622e8d63bf3c3f9) [png](16347040853985fca895297de463887ac192f38bcdca2) [png](1634704096454abc93bc20fb14144bdc2ab9d9311482e) [png](1634704110489ee2e5ad6aa8544abb51ffa5bff0398a2) [png](1634704122717081685317e9a425d9355cdc45ce05ce6)   
**Workspace - MyDesk**에서 콘텍스트 메뉴를 열어 **Import From - Import Image**를 선택하고 이미지를 추가합니다. [png](16878275447201b5a1f02e9c140018a1ed696ef1c8e69) [png](165665937154925a357cbc58a4577b508c57c30a2c163)   
이미지 RUID를 아이템 테이블의 **IconRUID**에 입력합니다. 이미지의 RUID는 각 이미지의 콘텍스트 메뉴에서 **Copy RUID**를 클릭해 복사할 수 있습니다. [png](16878279122598c71d67dc23e4ea6981bf22394a22507)   
복사한 RUID를 아이템 테이블의 **IconRUID**에 붙여넣기 합니다. [png](165665958375411fb5a6f0fd74ab09659dc62686d344d) 

# ItemType 생성

Workspace - MyDesk에서 콘텍스트 메뉴를 열고 Create Scripts - Create ItemType을 클릭해 새로운 ItemType을 생성합니다. 새 ItemType의 이름을 Potion으로 설정합니다.   


> Tip 아래 좌측 예시처럼 제작하는 게임 환경에 따라 개별 아이템 단위로 ItemType을 생성할 수도 있지만, 일반적으로는 우측 예시와 같이 동일한 유형별로 ItemType을 생성하는 것을 추천합니다. [png](16357553281761f7ea579470447b79b837aeb3f0bc3fa) [png](1635755340293013f41e698e14213b3b7f609fc657fa6)

생성한 ItemType인 Potion을 열고 포션 타입 아이템에 필요한 프로퍼티를 추가합니다. [png](163470344820046b9ef55b9db485495f82429417850eb)   
`OnCreate()` 함수를 추가한 뒤, 내용을 작성합니다. [png](16357553544880d1191f6ddc446598724d2fce9e3ef88)   

    
    
    @Component
    script ItemDataInitializer extends Component
        method void OnCreate()
        self.Name = self.ItemTableData:GetItem("Name")
        self.MaxStackCount = tonumber(self.ItemTableData:GetItem("MaxStackCount"))
        self.EffectAmount = tonumber(self.ItemTableData:GetItem("EffectAmount"))
        log("Item is Created!")
        end
    end
    

  
>**더 알아보기** > 아이템 생성 시 OnCreate가 호출되며, 아이템 테이블의 데이터가 아이템 객체로 넘어옵니다. > 아이템 객체로 넘어온 데이터는 self.ItemTableData:GetItem("컬럼명") 형식으로 접근할 수 있습니다. 

위에 생성한 ItemType을 복제하여 다음 세 가지 ItemType을 새로 추가합니다. [png](1687829481362e88637cb403f453e851344c7d782fd0c)

# 인벤토리 UI 추가

이번에는 생성된 아이템을 표시할 인벤토리 UI를 추가합니다. 상단 메뉴에  버튼을 눌러 UI 에디터를 엽니다. Preset List에서 [인벤토리], [버튼모음] UI를 추가합니다. [png](1659959415239e86dd162e65c4b1e82086102ba82efd4)   
만일 Inventory 엔티티의 UIInventory 컴포넌트에 InventoryBtnPath가 비어있으면, [png](163453706197553d527cb3ea34392bc2829f15976f3d8) 햄버거 메뉴를 열어 Reset All Properties를 선택합니다. 그러면 아래와 같이 정상적인 경로가 설정됩니다. [png](16373057873214e1d4994f8834292a9904f34fb279d3c)

# 아이템 엔티티 배치 및 기능 추가

 버튼을 눌러 UI 편집모드를 종료하고, 맵에 타일과 아이템 엔티티를 다음과 같이 배치합니다. [png](1637756481320c2e0c4ab0011419b8c001eaa398df0b6)   
배치한 아이템 엔티티에 기능을 부여할 스크립트 컴포넌트를 생성합니다. 새 스크립트 컴포넌트의 이름을 GiftBox로 설정합니다. [png](1656659256401f67aae760e8b43a5b62fb01dcbc612e2)   
GiftBox 스크립트에 TriggerEnterEvent를 추가합니다. [png](16347043790103b40809a1bb9400ba0ff2c6ef72bf4ec)   
그리고 아래와 같이 내용을 작성합니다.
    
    
    @Component
    script RandomItemSpawner extends Component
        @EventSender("Self")
        handler HandleTriggerEnterEvent(TriggerEnterEvent event)
        -- Parameters
        local TriggerBodyEntity = event.TriggerBodyEntity
        --------------------------------------------------------
        --아이템 엔티티와 충돌한 엔티티의 인벤토리를 받고, 인벤토리가 없으면 리턴합니다.
        local inventory = TriggerBodyEntity.InventoryComponent
        if inventory == nil then return end
    
        --UserItemDataSet에 추가되어 있는 아이템들의 이름과 아이템 타입 명을 Table로 만들어 줍니다.
        local itemNames = {{"RedPotion",Potion},
            {"BluePotion",Potion},
            {"IronSword",Weapon},
            {"IronShield",Armor},
            {"GreenShirts",Clothes}}
    
        --아이템들 중 획득할 아이템을 랜덤으로 선정합니다.
        local index = _UtilLogic:RandomIntegerRange(1,5)
        local getItemName = itemNames[index]
    
        --아이템을 생성하여 충돌한 엔티티의 인벤토리에 넣어줍니다.
        _ItemService:CreateItem(getItemName[2],getItemName[1],inventory)
    
        --충돌한 엔티티의 인벤토리에 아이템이 생성되면, 해당 아이템을 없앤 뒤 5초 후 다시 나타나도록 예약을 걸어둡니다.
        local myEntityPath = self.Entity.Path
        _TimerService:SetTimerOnce(function()
                --Path는 이 컴포넌트가 붙어있는 엔티티의 Path를 넣어줍니다.
                local myEntity = _EntityService:GetEntityByPath(myEntityPath)
                myEntity:SetEnable(true)  
            end, 5)
    
        self.Entity:SetEnable(false)
        end
    end
    

  
**GiftBox** 컴포넌트와 **TriggerComponent**를 맵에 배치한 아이템 엔티티에 추가합니다. [png](1659662714941efaa23b3166645ae97fec8b1f42f581c)   
 **[시작]** 버튼을 누른 뒤 테스트해 봅시다. 아이템 엔티티에 캐릭터가 닿을 때마다 인벤토리 UI에 아이템이 생성되는 것을 확인합니다. [png](165665955361463219cb3037e43e6893464ccb78a94d4) 

# 아이템 삭제

Preset List에서 임의의 엔티티를 배치합니다. [png](1637756501388a259dddae19f4870bed5f7494303f2dc)   
그리고 ItemDelete라는 이름의 스크립트 컴포넌트를 추가합니다. [png](1637756514221ac0df63469bf4810bf3a6c4f7f31222a)   
ItemDelete 스크립트를 열고, TriggerEnterEvent를 추가합니다. [png](163775652372809172ca409f541e295bb35586ee89931)   
그리고 아래와 같이 내용을 작성합니다.
    
    
    @Component
    script TriggerInventoryClearer extends Component
        @EventSender("Self")
        handler HandleTriggerEnterEvent(TriggerEnterEvent event)
        --Parameters
        local TriggerBodyEntity = event.TriggerBodyEntity
        --------------------------------------------------------
        local inventory = TriggerBodyEntity.InventoryComponent
        local items = inventory:GetItemList()
    
        for index, item in pairs(items) do
        	_ItemService:RemoveItem(item)
        end
        end
    end
    

  
위에서 배치한 엔티티에 **TriggerComponent**와 **ItemDelete** 컴포넌트를 추가합니다. [png](16377565496814502cb717a044fa5be2239c99a623f8b)   
 **[시작]** 버튼을 누른 뒤 테스트해 봅시다. 좌측 엔티티에 캐릭터가 닿을 때마다 인벤토리에 추가된 모든 아이템이 삭제되는 것을 확인합니다.