您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“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三部分分別來進行完成。
以Cotton Puzzle中的背包設(shè)計為例,我們需要有物品展示欄、物品切換按鍵和物品提示信息等部分。
在Canvas中創(chuàng)建ItemHolder,在ItemHolder中創(chuàng)建LeftButton和RightButton控制物品的左右切換、Slot來控制物品的顯示以及ItemToolTip來顯示物品的提示信息。
==創(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)前物品序號
//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; }
//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); }
在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); } }
首先我們需要定義一個變量來記錄物品的信息。這里我們在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, }
首先為了我們能夠在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
定義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); } /// <summary> /// 獲取物品在列表中的序號 /// </summary> /// <param name="itemName"></param> /// <returns></returns> private int GetItemIndex(ItemName itemName) { for(int i=0;i<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è)資訊頻道。
免責(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)容。