Unity로 인벤토리 및 아이템 제작 시스템 만들기

이 튜토리얼에서는 Unity에서 마인크래프트 스타일 인벤토리와 아이템 제작 시스템을 만드는 방법을 보여 드리겠습니다.

비디오 게임에서 아이템 제작은 특정(보통 단순한) 아이템을 새롭고 향상된 속성을 지닌 더 복잡한 아이템으로 결합하는 프로세스입니다. 예를 들어, 나무와 돌을 결합하여 곡괭이를 만들거나, 금속판과 나무를 결합하여 검을 만들 수 있습니다.

아래 제작 시스템은 모바일 친화적이며 완전 자동화되어 있습니다. 즉, 모든 UI 레이아웃에서 작동하고 맞춤형 제작 레시피를 만들 수 있다는 의미입니다.

Sharp Coder 비디오 플레이어

1단계: 제작 UI 설정

제작 UI를 설정하는 것부터 시작합니다.

  • 새 캔버스를 만듭니다(Unity 상위 작업 표시줄: GameObject -> UI -> 캔버스)
  • 캔버스 개체 -> UI -> 이미지를 마우스 오른쪽 버튼으로 클릭하여 새 이미지를 만듭니다.
  • 이미지 개체의 이름을 "CraftingPanel"으로 바꾸고 소스 이미지를 기본값으로 변경합니다. "UISprite"
  • "CraftingPanel" RectTransform 값을 (Pos X: 0 Pos Y: 0 Width: 410 Height: 365)로 변경합니다.

  • "CraftingPanel" 안에 두 개의 개체를 만듭니다. (CraftingPanel을 마우스 오른쪽 버튼으로 클릭 -> 빈 항목 만들기, 2번)
  • 첫 번째 개체의 이름을 "CraftingSlots"로 바꾸고 RectTransform 값을 ("Top Left align" Pivot X: 0 Pivot Y: 1 Pos X: 50 Pos Y: -35 Width: 140 Height: 140)으로 변경합니다. 이 개체에는 제작 슬롯이 포함됩니다.
  • 두 번째 개체의 이름을 "PlayerSlots"으로 바꾸고 RectTransform 값을 ("Top Stretch Horizontally" Pivot X: 0.5 Pivot Y: 1 Left: 0 Pos Y: -222 Right: 0 Height: 100)으로 변경합니다. 이 개체에는 플레이어 슬롯이 포함됩니다.

섹션 제목:

  • "PlayerSlots" 개체 -> UI -> 텍스트를 마우스 오른쪽 버튼으로 클릭하여 새 텍스트를 만들고 이름을 다음으로 바꿉니다. "SectionTitle"
  • "SectionTitle" RectTransform 값을 ("Top Left align" Pivot X: 0 Pivot Y: 0 Pos X: 5 Pos Y: 0 Width: 160 Height: 30)으로 변경합니다.
  • "SectionTitle" 텍스트를 "Inventory"으로 변경하고 글꼴 크기를 18로, 정렬을 왼쪽 중간으로, 색상을 (0.2, 0.2, 0.2, 1)로 설정합니다.
  • "SectionTitle" 개체를 복제하고 텍스트를 "Crafting"로 변경한 다음 "CraftingSlots" 개체 아래로 이동한 다음 이전 "SectionTitle"와 동일한 RectTransform 값을 설정합니다.

제작 슬롯:

제작 슬롯은 배경 이미지, 아이템 이미지, 개수 텍스트로 구성됩니다.

  • 캔버스 개체 -> UI -> 이미지를 마우스 오른쪽 버튼으로 클릭하여 새 이미지를 만듭니다.
  • 새 이미지의 이름을 "slot_template"으로 바꾸고 RectTransform 값을 (Post X: 0 Pos Y: 0 Width: 40 Height: 40)로 설정하고 색상을 (0.32, 0.32, 0.32, 0.8)로 변경합니다.
  • "slot_template"을 복제하고 이름을 "Item"로 바꾸고, "slot_template" 개체 내부로 이동하고, RectTransform 크기를 (너비: 30 높이: 30)으로, 색상을 (1, 1, 1, 1)로 변경합니다.
  • "slot_template" 개체 -> UI -> 텍스트를 마우스 오른쪽 버튼으로 클릭하여 새 텍스트를 만들고 이름을 다음으로 바꿉니다. "Count"
  • "Count" RectTransform 값을 ("하단 오른쪽 정렬" Pivot X: 1 Pivot Y: 0 Pos X: 0 Pos Y: 0 Width: 30 Height: 30)으로 변경합니다.
  • "Count" 텍스트를 임의의 숫자(예: 12)로 설정하고, 글꼴 스타일을 굵게, 글꼴 크기를 14로, 정렬을 오른쪽 하단으로, 색상을 (1, 1, 1, 1)로 설정합니다.
  • "Count" 텍스트에 그림자 구성요소를 추가하고 효과 색상을 (0, 0, 0, 0.5)로 설정합니다.

최종 결과는 다음과 같아야 합니다.

결과 슬롯(결과를 만드는 데 사용됩니다):

  • "slot_template" 개체를 복제하고 이름을 다음으로 바꿉니다. "result_slot_template"
  • "result_slot_template"의 너비와 높이를 50으로 변경합니다.

제작 버튼 및 추가 그래픽:

  • "CraftingSlots" 개체 -> UI -> 버튼을 마우스 오른쪽 버튼으로 클릭하여 새 버튼을 만들고 이름을 다음으로 바꿉니다. "CraftButton"
  • "CraftButton" RectTransform 값을 ("가운데 왼쪽 정렬" Pivot X: 1 Pivot Y: 0.5 Pos X: 0 Pos Y: 0 Width: 40 Height: 40)으로 설정합니다.
  • "CraftButton"의 텍스트를 다음으로 변경하세요. "Craft"

  • "CraftingSlots" 개체 -> UI -> 이미지를 마우스 오른쪽 버튼으로 클릭하여 새 이미지를 만들고 이름을 다음으로 바꿉니다. "Arrow"
  • "Arrow" RectTransform 값을 ("가운데 오른쪽 정렬" Pivot X: 0 Pivot Y: 0.5 Pos X: 10 Pos Y: 0 Width: 30 Height: 30)으로 설정합니다.

소스 이미지는 아래 이미지를 사용할 수 있습니다(다운로드하려면 마우스 오른쪽 버튼 클릭 -> 다른 이름으로 저장..). 가져온 후 텍스처 유형을 "Sprite (2D and UI)"으로 설정하고 필터 모드를 다음으로 설정합니다. "Point (no filter)"

화살표 오른쪽 아이콘 픽셀

  • "CraftingSlots" -> 빈 만들기를 마우스 오른쪽 버튼으로 클릭하고 이름을 "ResultSlot"으로 바꾸면 이 개체에 결과 슬롯이 포함됩니다.
  • "ResultSlot" RectTransform 값을 ("가운데 오른쪽 정렬" Pivot X: 0 Pivot Y: 0.5 Pos X: 50 Pos Y: 0 Width: 50 Height: 50)으로 설정합니다.

UI 설정이 준비되었습니다.

2단계: 프로그램 제작 시스템

이 제작 시스템은 SC_ItemCrafting.cs 및 SC_SlotTemplate.cs라는 2개의 스크립트로 구성됩니다.

  • 새 스크립트를 만들고 이름을 "SC_ItemCrafting"으로 지정한 다음 그 안에 아래 코드를 붙여넣습니다.

SC_ItemCrafting.cs

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

public class SC_ItemCrafting : MonoBehaviour
{
    public RectTransform playerSlotsContainer;
    public RectTransform craftingSlotsContainer;
    public RectTransform resultSlotContainer;
    public Button craftButton;
    public SC_SlotTemplate slotTemplate;
    public SC_SlotTemplate resultSlotTemplate;

    [System.Serializable]
    public class SlotContainer
    {
        public Sprite itemSprite; //Sprite of the assigned item (Must be the same sprite as in items array), or leave null for no item
        public int itemCount; //How many items in this slot, everything equal or under 1 will be interpreted as 1 item
        [HideInInspector]
        public int tableID;
        [HideInInspector]
        public SC_SlotTemplate slot;
    }

    [System.Serializable]
    public class Item
    {
        public Sprite itemSprite;
        public bool stackable = false; //Can this item be combined (stacked) together?
        public string craftRecipe; //Item Keys that are required to craft this item, separated by comma (Tip: Use Craft Button in Play mode and see console for printed recipe)
    }

    public SlotContainer[] playerSlots;
    SlotContainer[] craftSlots = new SlotContainer[9];
    SlotContainer resultSlot = new SlotContainer();
    //List of all available items
    public Item[] items;

    SlotContainer selectedItemSlot = null;

    int craftTableID = -1; //ID of table where items will be placed one at a time (ex. Craft table)
    int resultTableID = -1; //ID of table from where we can take items, but cannot place to

    ColorBlock defaultButtonColors;

    // Start is called before the first frame update
    void Start()
    {
        //Setup slot element template
        slotTemplate.container.rectTransform.pivot = new Vector2(0, 1);
        slotTemplate.container.rectTransform.anchorMax = slotTemplate.container.rectTransform.anchorMin = new Vector2(0, 1);
        slotTemplate.craftingController = this;
        slotTemplate.gameObject.SetActive(false);
        //Setup result slot element template
        resultSlotTemplate.container.rectTransform.pivot = new Vector2(0, 1);
        resultSlotTemplate.container.rectTransform.anchorMax = resultSlotTemplate.container.rectTransform.anchorMin = new Vector2(0, 1);
        resultSlotTemplate.craftingController = this;
        resultSlotTemplate.gameObject.SetActive(false);

        //Attach click event to craft button
        craftButton.onClick.AddListener(PerformCrafting);
        //Save craft button default colors
        defaultButtonColors = craftButton.colors;

        //InitializeItem Crafting Slots
        InitializeSlotTable(craftingSlotsContainer, slotTemplate, craftSlots, 5, 0);
        UpdateItems(craftSlots);
        craftTableID = 0;

        //InitializeItem Player Slots
        InitializeSlotTable(playerSlotsContainer, slotTemplate, playerSlots, 5, 1);
        UpdateItems(playerSlots);

        //InitializeItemResult Slot
        InitializeSlotTable(resultSlotContainer, resultSlotTemplate, new SlotContainer[] { resultSlot }, 0, 2);
        UpdateItems(new SlotContainer[] { resultSlot });
        resultTableID = 2;

        //Reset Slot element template (To be used later for hovering element)
        slotTemplate.container.rectTransform.pivot = new Vector2(0.5f, 0.5f);
        slotTemplate.container.raycastTarget = slotTemplate.item.raycastTarget = slotTemplate.count.raycastTarget = false;
    }

    void InitializeSlotTable(RectTransform container, SC_SlotTemplate slotTemplateTmp, SlotContainer[] slots, int margin, int tableIDTmp)
    {
        int resetIndex = 0;
        int rowTmp = 0;
        for (int i = 0; i < slots.Length; i++)
        {
            if (slots[i] == null)
            {
                slots[i] = new SlotContainer();
            }
            GameObject newSlot = Instantiate(slotTemplateTmp.gameObject, container.transform);
            slots[i].slot = newSlot.GetComponent<SC_SlotTemplate>();
            slots[i].slot.gameObject.SetActive(true);
            slots[i].tableID = tableIDTmp;

            float xTmp = (int)((margin + slots[i].slot.container.rectTransform.sizeDelta.x) * (i - resetIndex));
            if (xTmp + slots[i].slot.container.rectTransform.sizeDelta.x + margin > container.rect.width)
            {
                resetIndex = i;
                rowTmp++;
                xTmp = 0;
            }
            slots[i].slot.container.rectTransform.anchoredPosition = new Vector2(margin + xTmp, -margin - ((margin + slots[i].slot.container.rectTransform.sizeDelta.y) * rowTmp));
        }
    }

    //Update Table UI
    void UpdateItems(SlotContainer[] slots)
    {
        for (int i = 0; i < slots.Length; i++)
        {
            Item slotItem = FindItem(slots[i].itemSprite);
            if (slotItem != null)
            {
                if (!slotItem.stackable)
                {
                    slots[i].itemCount = 1;
                }
                //Apply total item count
                if (slots[i].itemCount > 1)
                {
                    slots[i].slot.count.enabled = true;
                    slots[i].slot.count.text = slots[i].itemCount.ToString();
                }
                else
                {
                    slots[i].slot.count.enabled = false;
                }
                //Apply item icon
                slots[i].slot.item.enabled = true;
                slots[i].slot.item.sprite = slotItem.itemSprite;
            }
            else
            {
                slots[i].slot.count.enabled = false;
                slots[i].slot.item.enabled = false;
            }
        }
    }

    //Find Item from the items list using sprite as reference
    Item FindItem(Sprite sprite)
    {
        if (!sprite)
            return null;

        for (int i = 0; i < items.Length; i++)
        {
            if (items[i].itemSprite == sprite)
            {
                return items[i];
            }
        }

        return null;
    }

    //Find Item from the items list using recipe as reference
    Item FindItem(string recipe)
    {
        if (recipe == "")
            return null;

        for (int i = 0; i < items.Length; i++)
        {
            if (items[i].craftRecipe == recipe)
            {
                return items[i];
            }
        }

        return null;
    }

    //Called from SC_SlotTemplate.cs
    public void ClickEventRecheck()
    {
        if (selectedItemSlot == null)
        {
            //Get clicked slot
            selectedItemSlot = GetClickedSlot();
            if (selectedItemSlot != null)
            {
                if (selectedItemSlot.itemSprite != null)
                {
                    selectedItemSlot.slot.count.color = selectedItemSlot.slot.item.color = new Color(1, 1, 1, 0.5f);
                }
                else
                {
                    selectedItemSlot = null;
                }
            }
        }
        else
        {
            SlotContainer newClickedSlot = GetClickedSlot();
            if (newClickedSlot != null)
            {
                bool swapPositions = false;
                bool releaseClick = true;

                if (newClickedSlot != selectedItemSlot)
                {
                    //We clicked on the same table but different slots
                    if (newClickedSlot.tableID == selectedItemSlot.tableID)
                    {
                        //Check if new clicked item is the same, then stack, if not, swap (Unless it's a crafting table, then do nothing)
                        if (newClickedSlot.itemSprite == selectedItemSlot.itemSprite)
                        {
                            Item slotItem = FindItem(selectedItemSlot.itemSprite);
                            if (slotItem.stackable)
                            {
                                //Item is the same and is stackable, remove item from previous position and add its count to a new position
                                selectedItemSlot.itemSprite = null;
                                newClickedSlot.itemCount += selectedItemSlot.itemCount;
                                selectedItemSlot.itemCount = 0;
                            }
                            else
                            {
                                swapPositions = true;
                            }
                        }
                        else
                        {
                            swapPositions = true;
                        }
                    }
                    else
                    {
                        //Moving to different table
                        if (resultTableID != newClickedSlot.tableID)
                        {
                            if (craftTableID != newClickedSlot.tableID)
                            {
                                if (newClickedSlot.itemSprite == selectedItemSlot.itemSprite)
                                {
                                    Item slotItem = FindItem(selectedItemSlot.itemSprite);
                                    if (slotItem.stackable)
                                    {
                                        //Item is the same and is stackable, remove item from previous position and add its count to a new position
                                        selectedItemSlot.itemSprite = null;
                                        newClickedSlot.itemCount += selectedItemSlot.itemCount;
                                        selectedItemSlot.itemCount = 0;
                                    }
                                    else
                                    {
                                        swapPositions = true;
                                    }
                                }
                                else
                                {
                                    swapPositions = true;
                                }
                            }
                            else
                            {
                                if (newClickedSlot.itemSprite == null || newClickedSlot.itemSprite == selectedItemSlot.itemSprite)
                                {
                                    //Add 1 item from selectedItemSlot
                                    newClickedSlot.itemSprite = selectedItemSlot.itemSprite;
                                    newClickedSlot.itemCount++;
                                    selectedItemSlot.itemCount--;
                                    if (selectedItemSlot.itemCount <= 0)
                                    {
                                        //We placed the last item
                                        selectedItemSlot.itemSprite = null;
                                    }
                                    else
                                    {
                                        releaseClick = false;
                                    }
                                }
                                else
                                {
                                    swapPositions = true;
                                }
                            }
                        }
                    }
                }

                if (swapPositions)
                {
                    //Swap items
                    Sprite previousItemSprite = selectedItemSlot.itemSprite;
                    int previousItemConunt = selectedItemSlot.itemCount;

                    selectedItemSlot.itemSprite = newClickedSlot.itemSprite;
                    selectedItemSlot.itemCount = newClickedSlot.itemCount;

                    newClickedSlot.itemSprite = previousItemSprite;
                    newClickedSlot.itemCount = previousItemConunt;
                }

                if (releaseClick)
                {
                    //Release click
                    selectedItemSlot.slot.count.color = selectedItemSlot.slot.item.color = Color.white;
                    selectedItemSlot = null;
                }

                //Update UI
                UpdateItems(playerSlots);
                UpdateItems(craftSlots);
                UpdateItems(new SlotContainer[] { resultSlot });
            }
        }
    }

    SlotContainer GetClickedSlot()
    {
        for (int i = 0; i < playerSlots.Length; i++)
        {
            if (playerSlots[i].slot.hasClicked)
            {
                playerSlots[i].slot.hasClicked = false;
                return playerSlots[i];
            }
        }

        for (int i = 0; i < craftSlots.Length; i++)
        {
            if (craftSlots[i].slot.hasClicked)
            {
                craftSlots[i].slot.hasClicked = false;
                return craftSlots[i];
            }
        }

        if (resultSlot.slot.hasClicked)
        {
            resultSlot.slot.hasClicked = false;
            return resultSlot;
        }

        return null;
    }

    void PerformCrafting()
    {
        string[] combinedItemRecipe = new string[craftSlots.Length];

        craftButton.colors = defaultButtonColors;

        for (int i = 0; i < craftSlots.Length; i++)
        {
            Item slotItem = FindItem(craftSlots[i].itemSprite);
            if (slotItem != null)
            {
                combinedItemRecipe[i] = slotItem.itemSprite.name + (craftSlots[i].itemCount > 1 ? "(" + craftSlots[i].itemCount + ")" : "");
            }
            else
            {
                combinedItemRecipe[i] = "";
            }
        }

        string combinedRecipe = string.Join(",", combinedItemRecipe);
        print(combinedRecipe);

        //Search if recipe match any of the item recipe
        Item craftedItem = FindItem(combinedRecipe);
        if (craftedItem != null)
        {
            //Clear Craft slots
            for (int i = 0; i < craftSlots.Length; i++)
            {
                craftSlots[i].itemSprite = null;
                craftSlots[i].itemCount = 0;
            }

            resultSlot.itemSprite = craftedItem.itemSprite;
            resultSlot.itemCount = 1;

            UpdateItems(craftSlots);
            UpdateItems(new SlotContainer[] { resultSlot });
        }
        else
        {
            ColorBlock colors = craftButton.colors;
            colors.selectedColor = colors.pressedColor = new Color(0.8f, 0.55f, 0.55f, 1);
            craftButton.colors = colors;
        }
    }

    // Update is called once per frame
    void Update()
    {
        //Slot UI follow mouse position
        if (selectedItemSlot != null)
        {
            if (!slotTemplate.gameObject.activeSelf)
            {
                slotTemplate.gameObject.SetActive(true);
                slotTemplate.container.enabled = false;

                //Copy selected item values to slot template
                slotTemplate.count.color = selectedItemSlot.slot.count.color;
                slotTemplate.item.sprite = selectedItemSlot.slot.item.sprite;
                slotTemplate.item.color = selectedItemSlot.slot.item.color;
            }

            //Make template slot follow mouse position
            slotTemplate.container.rectTransform.position = Input.mousePosition;
            //Update item count
            slotTemplate.count.text = selectedItemSlot.slot.count.text;
            slotTemplate.count.enabled = selectedItemSlot.slot.count.enabled;
        }
        else
        {
            if (slotTemplate.gameObject.activeSelf)
            {
                slotTemplate.gameObject.SetActive(false);
            }
        }
    }
}
  • 새 스크립트를 만들고 이름을 "SC_SlotTemplate"로 지정한 다음 그 안에 아래 코드를 붙여넣습니다.

SC_SlotTemplate.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class SC_SlotTemplate : MonoBehaviour, IPointerClickHandler
{
    public Image container;
    public Image item;
    public Text count;

    [HideInInspector]
    public bool hasClicked = false;
    [HideInInspector]
    public SC_ItemCrafting craftingController;

    //Do this when the mouse is clicked over the selectable object this script is attached to.
    public void OnPointerClick(PointerEventData eventData)
    {
        hasClicked = true;
        craftingController.ClickEventRecheck();
    }
}

슬롯 템플릿 준비:

  • SC_SlotTemplate 스크립트를 "slot_template" 개체에 연결하고 해당 변수를 할당합니다(동일한 개체의 이미지 구성 요소는 "Container" 변수로 이동하고 하위 "Item" 이미지는 "Item" 변수로 이동하고 하위 "Count" 텍스트는 "Count" 변수로 이동합니다)
  • "result_slot_template" 개체에 대해 동일한 프로세스를 반복합니다(SC_SlotTemplate 스크립트를 개체에 연결하고 동일한 방식으로 변수 할당).

제작 시스템 준비:

  • SC_ItemCrafting 스크립트를 캔버스 개체에 연결하고 해당 변수를 할당합니다. ("PlayerSlots" 개체는 "Player Slots Container" 변수로 이동하고, "CraftingSlots" 개체는 "Crafting Slots Container" 변수로 이동하고, "ResultSlot" 개체는 *h51로 이동합니다. * 변수, "CraftButton" 개체는 "Craft Button" 변수로 이동하고, "slot_template" SC_SlotTemplate 스크립트가 첨부된 개체는 "Slot Template" 변수로 이동하고, "result_slot_template" SC_SlotTemplate 스크립트가 첨부된 개체는 "Result Slot Template" 변수로 이동됩니다.

이미 알고 있듯이 "Player Slots" 및 "Items"이라는 두 개의 빈 배열이 있습니다. "Player Slots"에는 사용 가능한 슬롯 수(항목 포함 또는 비어 있음)가 포함되며 "Items"에는 레시피(선택 사항)와 함께 사용 가능한 모든 항목이 포함됩니다.

항목 설정:

아래의 스프라이트를 확인하세요(제 경우에는 5개의 항목이 있습니다).

록 아이템 (바위)

다이아몬드 아이템 (다이아몬드)

목재 아이템 (목재)

검 아이템 (검)

다이아몬드 검 (다이아몬드 검)

  • 각 스프라이트를 다운로드하고(오른쪽 클릭 -> 다른 이름으로 저장...) 프로젝트로 가져옵니다(가져오기 설정에서 텍스처 유형을 "Sprite (2D and UI)"으로 설정하고 필터 모드를 다음으로 설정). "Point (no filter)"

  • SC_ItemCrafting에서 Items Size를 5로 변경하고 각 스프라이트를 Item Sprite 변수에 할당합니다.

"Stackable" 변수는 항목을 하나의 슬롯에 함께 쌓을 수 있는지 여부를 제어합니다(예: 암석, 다이아몬드, 나무와 같은 단순한 재료에 대해서만 쌓기를 허용할 수 있습니다).

"Craft Recipe" 변수는 이 아이템을 제작할 수 있는지 여부를 제어합니다(비어 있으면 제작할 수 없음을 의미).

  • "Player Slots"의 경우 배열 크기를 27로 설정합니다(현재 Crafting Panel에 가장 적합하지만 임의의 숫자를 설정할 수 있음).

재생을 누르면 슬롯이 올바르게 초기화되었지만 항목이 없는 것을 확인할 수 있습니다.

각 슬롯에 항목을 추가하려면 항목 Sprite를 "Item Sprite" 변수에 할당하고 "Item Count"을 양수로 설정해야 합니다(1 미만의 모든 항목 및/또는 쌓을 수 없는 항목은 1로 해석됩니다).:

  • "rock" 스프라이트를 Element 0 / "Item Count" 14에 할당하고, "wood" 스프라이트를 Element 1 / "Item Count" 8에, "diamond" 스프라이트를 Element 2 / "Item Count" 8에 할당합니다(스프라이트가 다음과 동일한지 확인하세요). "Items" 배열에서 그렇지 않으면 작동하지 않습니다).

이제 아이템이 플레이어 슬롯에 나타나며, 아이템을 클릭한 다음 이동하려는 슬롯을 클릭하여 위치를 변경할 수 있습니다.

제작법:

제작법을 사용하면 특정 순서에 따라 다른 아이템을 결합하여 아이템을 만들 수 있습니다.

레시피 제작 형식은 다음과 같습니다: [item_sprite_name]([item count])*선택 사항... 9회 반복, 쉼표(,)로 구분

레시피를 찾는 쉬운 방법은 재생을 누르고 제작하려는 순서대로 항목을 배치한 다음 "Craft"을 누른 다음 (Ctrl + Shift + C)를 눌러 Unity 콘솔을 열고 다음을 확인하는 것입니다. 새로 인쇄된 라인("Craft"을 여러 번 클릭하여 라인을 다시 인쇄할 수 있음), 인쇄된 라인은 제작 레시피입니다.

예를 들어 아래 조합은 rock,,rock,,rock,,rock,,wood 레시피에 해당합니다(참고: 스프라이트의 이름이 다를 경우 이름이 다를 수 있습니다).

검 아이템 제작법

위의 레시피를 사용하여 검을 제작하겠습니다.

  • 인쇄된 줄을 복사하고 "Items" 배열의 "sword" 항목 아래 "Craft Recipe" 변수에 붙여넣습니다.

이제 동일한 조합을 반복하면 검을 만들 수 있습니다.

다이아몬드 검을 만드는 방법은 동일하지만 돌 대신 다이아몬드를 사용합니다.

다이아몬드 아이템 소드 레시피 Unity Inspector

Unity 인벤토리 시스템 및 아이템 제작

이제 제작 시스템이 준비되었습니다.

원천
📁ItemCrafting.unitypackage36.13 KB
추천 기사
Unity에서 UI 드래그 앤 드롭을 사용하여 간단한 인벤토리 시스템 코딩
Unity의 상태 머신 소개
Unity에서 컷씬을 트리거하는 방법
Unity로 턴제 게임 만들기
Unity에서 간단한 2D 불릿 시스템 만들기
Unity에서 수집품 및 파워업 만들기
Unity에서 터렛 컨트롤러 만들기