Creazione di inventario e sistema di creazione di oggetti in Unity

In questo tutorial, mostrerò come creare un sistema di inventario e creazione di oggetti in stile Minecraft in Unity.

La creazione di oggetti nei videogiochi è un processo di combinazione di oggetti specifici (solitamente più semplici) in oggetti più complessi, con proprietà nuove e migliorate. Ad esempio, combinando legno e pietra in un piccone, o combinando lamiera e legno in una spada.

Il sistema di creazione riportato di seguito è ottimizzato per dispositivi mobili e completamente automatizzato, il che significa che funzionerà con qualsiasi layout dell'interfaccia utente e con la possibilità di creare ricette di creazione personalizzate.

Sharp Coder Lettore video

Passaggio 1: imposta l'interfaccia utente di creazione

Iniziamo configurando l'interfaccia utente di creazione:

  • Crea una nuova tela (Unity Barra delle applicazioni superiore: GameObject -> UI -> Canvas)
  • Crea una nuova immagine facendo clic con il pulsante destro del mouse su Oggetto Canvas -> UI -> Immagine
  • Rinominare l'oggetto immagine in "CraftingPanel" e modificare la sua immagine sorgente in quella predefinita "UISprite"
  • Cambia i valori "CraftingPanel" RectTransform in (Pos X: 0 Pos Y: 0 Larghezza: 410 Altezza: 365)

  • Crea due oggetti all'interno di "CraftingPanel" (tasto destro su CraftingPanel -> Crea vuoto, 2 volte)
  • Rinominare il primo oggetto in "CraftingSlots" e modificare i suoi valori RectTransform in ("Allineamento in alto a sinistra" Pivot X: 0 Pivot Y: 1 Pos X: 50 Pos Y: -35 Larghezza: 140 Altezza: 140). Questo oggetto conterrà slot di creazione.
  • Rinominare il secondo oggetto in "PlayerSlots" e modificare i suoi valori RectTransform in ("Top Allunga orizzontalmente" Pivot X: 0,5 Pivot Y: 1 Sinistra: 0 Pos Y: -222 Destra: 0 Altezza: 100). Questo oggetto conterrà gli slot dei giocatori.

Titolo della sezione:

  • Crea un nuovo testo facendo clic con il pulsante destro del mouse su "PlayerSlots" Oggetto -> UI -> Testo e rinominalo in "SectionTitle"
  • Cambia i valori "SectionTitle" RectTransform in ("Allinea in alto a sinistra" Pivot X: 0 Pivot Y: 0 Pos X: 5 Pos Y: 0 Larghezza: 160 Altezza: 30)
  • Cambia il testo "SectionTitle" in "Inventory" e imposta la dimensione del carattere su 18, l'allineamento su al centro a sinistra e il colore su (0,2, 0,2, 0,2, 1)
  • Duplica l'oggetto "SectionTitle", cambia il suo testo in "Crafting" e spostalo sotto l'oggetto "CraftingSlots", quindi imposta gli stessi valori RectTransform del precedente "SectionTitle".

Slot di creazione:

Lo slot di creazione sarà composto da un'immagine di sfondo, un'immagine di un oggetto e un testo di conteggio:

  • Crea una nuova immagine facendo clic con il pulsante destro del mouse su Oggetto Canvas -> UI -> Immagine
  • Rinomina la nuova immagine in "slot_template", imposta i suoi valori RectTransform su (Post X: 0 Pos Y: 0 Larghezza: 40 Altezza: 40) e cambia il suo colore in (0.32, 0.32, 0.32, 0.8)
  • Duplica "slot_template" e rinominalo in "Item", spostalo all'interno dell'oggetto "slot_template", modifica le sue dimensioni RectTransform in (Larghezza: 30 Altezza: 30) e Colore in (1, 1, 1, 1)
  • Crea un nuovo testo facendo clic con il pulsante destro del mouse su "slot_template" Oggetto -> UI -> Testo e rinominalo in "Count"
  • Modificare i valori "Count" RectTransform in ("Allineamento in basso a destra" Pivot X: 1 Pivot Y: 0 Pos X: 0 Pos Y: 0 Larghezza: 30 Altezza: 30)
  • Imposta "Count" Testo su un numero casuale (es. 12), Stile carattere su Grassetto, Dimensione carattere su 14, Allineamento in basso a destra e Colore su (1, 1, 1, 1)
  • Aggiungi il componente Ombra al testo "Count" e imposta Colore effetto su (0, 0, 0, 0,5)

Il risultato finale dovrebbe assomigliare a questo:

Slot dei risultati (che verrà utilizzato per creare risultati):

  • Duplica l'oggetto "slot_template" e rinominalo in "result_slot_template"
  • Cambia la larghezza e l'altezza di "result_slot_template" in 50

Pulsante di creazione e grafica aggiuntiva:

  • Crea un nuovo pulsante facendo clic con il pulsante destro del mouse su "CraftingSlots" Oggetto -> UI -> Pulsante e rinominalo in "CraftButton"
  • Imposta i valori "CraftButton" RectTransform su ("Allinea al centro a sinistra" Pivot X: 1 Pivot Y: 0,5 Pos X: 0 Pos Y: 0 Larghezza: 40 Altezza: 40)
  • Cambia testo da "CraftButton" a "Craft"

  • Crea una nuova immagine facendo clic con il pulsante destro del mouse su "CraftingSlots" Oggetto -> UI -> Immagine e rinominala in "Arrow"
  • Imposta i valori "Arrow" RectTransform su ("Allinea al centro a destra" Pivot X: 0 Pivot Y: 0,5 Pos X: 10 Pos Y: 0 Larghezza: 30 Altezza: 30)

Per l'immagine sorgente, puoi utilizzare l'immagine qui sotto (tasto destro -> Salva con nome... per scaricarla). Dopo l'importazione, imposta il tipo di texture su "Sprite (2D and UI)" e la modalità filtro su "Point (no filter)"

Pixel dell'icona freccia destra

  • Fare clic con il tasto destro su "CraftingSlots" -> Crea vuoto e rinominarlo in "ResultSlot", questo oggetto conterrà lo slot del risultato
  • Imposta i valori "ResultSlot" RectTransform su ("Allinea al centro a destra" Pivot X: 0 Pivot Y: 0,5 Pos X: 50 Pos Y: 0 Larghezza: 50 Altezza: 50)

La configurazione dell'interfaccia utente è pronta.

Passaggio 2: sistema di creazione del programma

Questo sistema di creazione sarà composto da 2 script, SC_ItemCrafting.cs e SC_SlotTemplate.cs

  • Crea un nuovo script, chiamalo "SC_ItemCrafting" quindi incolla al suo interno il codice seguente:

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);
            }
        }
    }
}
  • Crea un nuovo script, chiamalo "SC_SlotTemplate" quindi incolla al suo interno il codice seguente:

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();
    }
}

Preparazione dei modelli di slot:

  • Collega lo script SC_SlotTemplate all'oggetto "slot_template" e assegna le sue variabili (il componente Immagine sullo stesso oggetto va alla variabile "Container", l'immagine figlio "Item" va alla variabile "Item" e un figlio "Count" Il testo va alla variabile "Count")
  • Ripeti la stessa procedura per l'oggetto "result_slot_template" (collegagli lo script SC_SlotTemplate e assegna le variabili allo stesso modo).

Preparazione del sistema artigianale:

  • Collega lo script SC_ItemCrafting all'oggetto Canvas e assegna le sue variabili (l'oggetto "PlayerSlots" va alla variabile "Player Slots Container", l'oggetto "CraftingSlots" va alla variabile "Crafting Slots Container", l'oggetto "ResultSlot" va alla variabile "Result Slot Container" variabile, "CraftButton" L'oggetto va alla variabile "Craft Button", "slot_template" L'oggetto con lo script SC_SlotTemplate allegato va alla variabile "Slot Template" e l'oggetto "result_slot_template" con lo script SC_SlotTemplate allegato va alla variabile "Result Slot Template"):

Come hai già notato, ci sono due array vuoti denominati "Player Slots" e "Items". "Player Slots" conterrà il numero di slot disponibili (con oggetto o vuoti) e "Items" conterrà tutti gli oggetti disponibili insieme alle relative ricette (opzionale).

Elementi di impostazione:

Controlla gli sprite qui sotto (nel mio caso avrò 5 elementi):

Oggetto roccioso (roccia)

Articolo diamante (diamante)

Articolo in legno (legna)

Oggetto spada (spada)

Spada di diamante (spada di diamante)

  • Scarica ogni sprite (clic destro -> Salva con nome...) e importalo nel tuo progetto (nelle Impostazioni di importazione imposta il Tipo di texture su "Sprite (2D and UI)" e la Modalità filtro su "Point (no filter)"

  • In SC_ItemCrafting modifica la dimensione degli articoli su 5 e assegna ogni sprite alla variabile Item Sprite.

"Stackable" La variabile controlla se gli oggetti possono essere impilati insieme in uno slot (ad esempio, potresti voler consentire l'impilamento solo per materiali semplici come roccia, diamante e legno).

"Craft Recipe" la variabile controlla se questo oggetto può essere creato (vuoto significa che non può essere creato)

  • Per "Player Slots" imposta la dimensione dell'array su 27 (la soluzione migliore per l'attuale pannello di creazione, ma puoi impostare qualsiasi numero).

Quando premi Play, noterai che gli slot sono inizializzati correttamente, ma non sono presenti elementi:

Per aggiungere un oggetto a ciascuno slot dovremo assegnare un oggetto Sprite alla variabile "Item Sprite" e impostare "Item Count" su qualsiasi numero positivo (tutto sotto 1 e/o gli oggetti non impilabili verranno interpretati come 1):

  • Assegna lo sprite "rock" all'Elemento 0 / "Item Count" 14, lo sprite "wood" all'Elemento 1 / "Item Count" 8, lo sprite "diamond" all'Elemento 2 / "Item Count" 8 (assicurati che gli sprite siano gli stessi di nell'array "Items", altrimenti non funzionerà).

Gli oggetti ora dovrebbero apparire negli slot giocatore, puoi cambiare la loro posizione facendo clic sull'oggetto, quindi facendo clic sullo slot in cui desideri spostarlo.

Ricette di creazione:

Le ricette di creazione ti consentono di creare un oggetto combinando altri oggetti in un ordine specifico:

Il formato per la creazione della ricetta è il seguente: [item_sprite_name]([item count])*opzionale... ripetuto 9 volte, separato da virgola (,)

Un modo semplice per scoprire la ricetta è premere Riproduci, quindi posizionare gli oggetti nell'ordine che desideri creare, quindi premere "Craft", quindi premere (Ctrl + Maiusc + C) per aprire la console Unity e vedere la linea appena stampata (puoi fare clic su "Craft" più volte per ristampare la linea), la linea stampata è la ricetta di creazione.

Ad esempio, la combinazione seguente corrisponde a questa ricetta: roccia,,roccia,,roccia,,roccia,,legno (NOTA: potrebbe essere diverso per te se i tuoi sprite hanno nomi diversi).

Ricetta per la creazione di oggetti con spada

Useremo la ricetta sopra per creare una spada.

  • Copia la riga stampata e nell'array "Items" incollala nella variabile "Craft Recipe" sotto "sword" Articolo:

Ora, ripetendo la stessa combinazione, dovresti essere in grado di creare una spada.

La ricetta per una spada di diamante è la stessa, ma invece della roccia c'è il diamante:

Ispettore dell'unità della ricetta della spada dell'oggetto di diamante

Sistema di inventario Unity e creazione di oggetti

Il sistema di creazione è ora pronto.

Fonte
📁ItemCrafting.unitypackage36.13 KB
Articoli suggeriti
Codifica di un sistema di inventario semplice con il trascinamento della selezione dell'interfaccia utente in Unity
Introduzione alla macchina a stati in Unity
Come attivare un filmato in Unity
Creazione di oggetti da collezione e potenziamenti in Unity
Creazione di oggetti interattivi in ​​Unity
Creazione di classi e oggetti in Unity Code
Sistema Pick and Drop senza inventario in Unity