溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Unity游戲開發(fā)如何實現(xiàn)背包系統(tǒng)

發(fā)布時間:2022-08-12 11:11:28 來源:億速云 閱讀:235 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細介紹“Unity游戲開發(fā)如何實現(xiàn)背包系統(tǒng)”,內(nèi)容詳細,步驟清晰,細節(jié)處理妥當(dāng),希望這篇“Unity游戲開發(fā)如何實現(xiàn)背包系統(tǒng)”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

    引言

    背包是游戲中經(jīng)常使用的一個組件,它負責(zé)管理玩家在游戲中所獲得的道具。一個完整的背包系統(tǒng)應(yīng)當(dāng)具有將物品放置進背包、對背包內(nèi)物品進行管理和使用背包內(nèi)物品等功能。而往往一個背包系統(tǒng)的邏輯關(guān)系較為復(fù)雜,如果把所有功能都放在一個腳本中實現(xiàn)會使代碼顯得十分冗雜且缺乏邏輯。所以在背包系統(tǒng)的設(shè)計過程中,我們常將其分解為數(shù)據(jù)、邏輯和UI三部分分別來進行完成。

    一、UI設(shè)計

    以Cotton Puzzle中的背包設(shè)計為例,我們需要有物品展示欄、物品切換按鍵和物品提示信息等部分。

    Unity游戲開發(fā)如何實現(xiàn)背包系統(tǒng)

    在Canvas中創(chuàng)建ItemHolder,在ItemHolder中創(chuàng)建LeftButton和RightButton控制物品的左右切換、Slot來控制物品的顯示以及ItemToolTip來顯示物品的提示信息。

    二、UI

    ==創(chuàng)建InventoryUI腳本并掛在ItemHolder上以對整個背包UI進行管理。== 首先,確定InventoryUI可以控制的組件并定義當(dāng)前所顯示的物品序號,由于ItemToolTip的顯示與否和Slot直接相關(guān)聯(lián),所以可以通過控制Slot間接控制ItemToolTip,在InventoryUI中便不再單獨對其進行控制。

    //InventoryUI.cs
        public Button leftButton;
        public Button rightButton;
        public SlotUI slotUI;
        public int currentItemIndex;//當(dāng)前物品序號

    2.1 Slot中的物品顯示

    //InventoryUI.cs
        /// <summary>
        /// 更新Slot中物品圖片
        /// </summary>
        /// <param name="itemDetails"></param>
        /// <param name="index"></param>
        private void OnUpdateUIEvent(ItemDetails itemDetails, int index)
        {
            if (itemDetails == null)//當(dāng)前物品為空
            {
                slotUI.SetEmpty();
                currentItemIndex = -1;
                leftButton.interactable = false;
                rightButton.interactable=false;
            }
            else
            {
                currentItemIndex = index;
                slotUI.SetItem(itemDetails);
                if (index > 0)
                    leftButton.interactable = true;
                if (currentItemIndex == -1)
                {
                    leftButton.interactable = false;
                    rightButton.interactable = false;
                }
            }
        }

    定義UpdateUIEvent事件來實時管理Slot中顯示的物品(通過調(diào)用SlotUI中實現(xiàn)的SetEmpty()和SetItem(itemDetails)方法實現(xiàn))和左右按鈕的可使用情況。

    //InventoryUI.cs
        private void OnEnable()
        {
            EventHandler.UpdateUIEvent += OnUpdateUIEvent;
        }
        private void OnDisable()
        {
            EventHandler.UpdateUIEvent -= OnUpdateUIEvent;
        }

    2.2 物品切換

    //InventoryUI.cs
        /// <summary>
        /// 左右按鈕使用事件
        /// </summary>
        /// <param name="amount"></param>
        public void SwitchItem(int amount)
        {
            var index = currentItemIndex + amount;
            if(index< currentItemIndex)
            {
                leftButton.interactable = false;
                rightButton.interactable = true;
            }
            else if(index> currentItemIndex)
            {
                leftButton.interactable = true;
                rightButton.interactable = false;
            }
            else
            {
                leftButton.interactable = true;
                rightButton.interactable = true;
            }
            EventHandler.CallChangeItemEvent(index);
        }

    2.3 SlotUI的實現(xiàn)

    在SlotUI中需要實現(xiàn)將Slot圖片設(shè)置為指定物品(包含物品為空的情況)、鼠標(biāo)點擊反饋、鼠標(biāo)移入移出反饋(這里主要要實現(xiàn)當(dāng)鼠標(biāo)移入顯示物品文字描述信息,移出取消顯示的功能)。

    //SlotUI.cs
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.EventSystems;
    public class SlotUI : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
    {
        public Image itemImage;
        public ItemDetails currentItem;
        public ItemToolTip toolTip;
        private bool isClicked;
        /// <summary>
        /// 設(shè)置Slot圖片為指定item
        /// </summary>
        /// <param name="itemDetails"></param>
        public void SetItem(ItemDetails itemDetails)
        {
            currentItem = itemDetails;
            this.gameObject.SetActive(true);
            itemImage.sprite = itemDetails.itemSprite;
            itemImage.SetNativeSize();
        }
        /// <summary>
        /// 設(shè)置Slot圖片為空
        /// </summary>
        public void SetEmpty()
        {
            this.gameObject.SetActive(false);
        }
        public void OnPointerClick(PointerEventData eventData)
        {
            isClicked = !isClicked;
            EventHandler.CallItemSelectedEvent(currentItem, isClicked);
        }
        public void OnPointerEnter(PointerEventData eventData)
        {
            if (this.gameObject.activeInHierarchy)
            {
                toolTip.gameObject.SetActive(true);
                toolTip.UpdateItemName(currentItem.itemName);
            }
        }
        public void OnPointerExit(PointerEventData eventData)
        {
            toolTip.gameObject.SetActive(false);
        }
    }

    2.4 物品描述信息的展示

    首先我們需要定義一個變量來記錄物品的信息。這里我們在ItemToolTip下創(chuàng)建一個Text來記錄文本信息。

    //ItemToolTip.cs
        public Text itemNameText;

    接下來定義方法根據(jù)目前Slot所展示的物品名字來修改Text的內(nèi)容。

    //ItemToolTip.cs
        public void UpdateItemName(ItemName itemName)
        {
            itemNameText.text = itemName switch
            {
                ItemName.Key => "信箱鑰匙",
                ItemName.Ticket => "一張船票",
                _ => ""
            };
        }

    為了方便使用我們將物品名寫成了枚舉變量,定義在Enums腳本中,方便在其他腳本中也可以使用。

    //Enums.cs
    /// <summary>
    /// 物品名
    /// </summary>
    public enum ItemName
    {
        None,
        Key,
        Ticket,
    }

    三、數(shù)據(jù)

    首先為了我們能夠在unity中更加直觀地對數(shù)據(jù)進行修改,利用以下代碼在unity的菜單下創(chuàng)建數(shù)據(jù)子菜單,并序列化對象。每個ItemDetails包含物品名(itemName)和物品貼圖(itemSprite)兩個屬性。

    //ItemDataList.cs
    [CreateAssetMenu(fileName ="ItemDataList",menuName = "Inventory/ItemDataList")]
    /// <summary>
    /// 對象序列化
    /// </summary>
    [System.Serializable]
    public class ItemDetails
    {
        public ItemName itemName;
        public Sprite itemSprite;
    }

    在unity中可以直接新建一個ItemDataList的數(shù)據(jù)對象,創(chuàng)建方式為:右鍵 -> Create ->Inventory -> ItemDataList

    Unity游戲開發(fā)如何實現(xiàn)背包系統(tǒng)

    定義GetItemDetails根據(jù)物品名獲取ItemDetails 對象。

    //ItemDataList.cs
        public List<ItemDetails> itemDetailsList = new List<ItemDetails>();
        public ItemDetails GetItemDetails(ItemName itemName)
        {
            return itemDetailsList.Find(i => i.itemName.Equals(itemName));
        }

    四、邏輯

    對于場景中的物體,在鼠標(biāo)點擊后需要能夠被添加到背包內(nèi)并在原有位置消失??赏ㄟ^ItemClicked()函數(shù)來實現(xiàn)。

    //Item.cs
        public ItemName itemName;
        public void ItemClicked()
        {
            //隱藏鼠標(biāo)點擊物體
            this.gameObject.SetActive(false);
            //將物品添加到背包
            InventoryManager.Instance.AddItem(itemName);
        }

    最后,需要定義一個腳本InventoryManager對背包系統(tǒng)的UI、數(shù)據(jù)進行一個==統(tǒng)一的管理==。

    //InventoryManager.cs
        [SerializeField] private List<ItemName> itemList = new List<ItemName>();
        public ItemDataList itemData;//通過物品名在物品列表中查找相應(yīng)物品

    (1)在新加載游戲的時候需要清空物品列表

        private void OnStartNewGameEvent(int gameWeek)
        {
            itemList.Clear();
        }

    (2)當(dāng)物品被使用時需要將物品移除背包并更新UI

        private void OnItemUsedEvent(ItemName itemName)
        {
            var index = GetItemIndex(itemName);
            itemList.RemoveAt(index);
            if (itemList.Count == 0)
                EventHandler.CallUpdateUIEvent(null, -1);
        }

    (3)當(dāng)場景加載之后,需要將目前背包中有的物品進行更新

        private void OnAfterSceneLoadedEvent()
        {
            if (itemList.Count == 0)
                EventHandler.CallUpdateUIEvent(null, -1);
            else
            {
                for (int i = 0; i < itemList.Count; i++)
                {
                    EventHandler.CallUpdateUIEvent(itemData.GetItemDetails(itemList[i]), i);
                }
            }
        }

    (4)當(dāng)使用Button在背包中左右切換物品時,需要實時更改物品的圖片并判斷是否越界

        private void OnChangeItemEvent(int index)
        {
            if (index >= 0 && index < itemList.Count)
            {
                ItemDetails item = itemData.GetItemDetails(itemList[index]);
                EventHandler.CallUpdateUIEvent(item, index);
            }
            else
            {
                Debug.Log("越界!");
            }
        }

    注冊這些事件:

        private void OnEnable()
        {
            EventHandler.ChangeItemEvent += OnChangeItemEvent;
            EventHandler.AfterSceneLoadedEvent += OnAfterSceneLoadedEvent;
            EventHandler.ItemUsedEvent += OnItemUsedEvent;
            EventHandler.StartNewGameEvent += OnStartNewGameEvent;
        }
        private void OnDisable()
        {
            EventHandler.ChangeItemEvent -= OnChangeItemEvent;
            EventHandler.AfterSceneLoadedEvent -= OnAfterSceneLoadedEvent;
            EventHandler.ItemUsedEvent -= OnItemUsedEvent;
            EventHandler.StartNewGameEvent -= OnStartNewGameEvent;
        }

    另外有一些工具函數(shù)需要實現(xiàn):

        public void AddItem(ItemName itemName)
        {
            if(!itemList.Contains(itemName))//列表中不包含物品則添加到列表中
            { 
                itemList.Add(itemName);
            }
            //UI顯示
            EventHandler.CallUpdateUIEvent(itemData.GetItemDetails(itemName), itemList.Count - 1);
        }
        /// &lt;summary&gt;
        /// 獲取物品在列表中的序號
        /// &lt;/summary&gt;
        /// &lt;param name="itemName"&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        private int GetItemIndex(ItemName itemName)
        {
            for(int i=0;i&lt;itemList.Count;i++)
            {
                if(itemName.Equals(itemList[i]))
                    return i;
            }
            return -1;
        }

    讀到這里,這篇“Unity游戲開發(fā)如何實現(xiàn)背包系統(tǒng)”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI