5-10 Click To Pickup Item
本篇要介紹用滑鼠點擊背包內的物體後,會將物體選取起來,如果按住Z鍵再選擇物體的話,只會選擇一半的物體。選取起來的物體,會跟著滑鼠的鼠標移動。因為這個功能同時修改的部分比較多,所以會分多篇文章介紹,本篇先介紹選取,後續篇再介紹放下。
首先在Canvas底下創造一個PickedItem,這個物件是前面章節所介紹名為的Item的Prefab,如果不知道這個Prefab怎麼製作,請先看看以前的文章:
PickedItem預設要不啟用,所以請大家在Inspector視窗中將勾勾取消。
首先簡單介紹一下Slot修改後的程式碼,主要是繼承IPointerDownHandler,並覆寫OnPointerDown方法,該方法可以偵測滑鼠按下的事件。
然後實作內容中,先用transform.childCount確認Slot內是否有Item,再用InvntorySystem類中的bool屬性isPickedItem判斷目前是否處於『Picked』狀態,如果為非,則可以將Slot內的物體取出來。其他行則有撰寫註解,請大家自己閱讀。
在InventorySystem類中,則主要新增了PickupItem方法,此方法用來將滑鼠點中的Item屬性設定到PickedItem上面。
以下提供本次修改的完整程式碼。
Slot.cs:
InventorySystem.cs:
ItemUI.cs:
程式碼修改完成後,於KanpsackPanel的InventorySystem中,我們必須將剛剛新增到Canvas底下的PickedItem拉進參數,如下圖。
接著,讓我們執行遊戲看看吧。用滑鼠點擊腰帶後,腰帶被從背包上取下來了。
移動滑鼠時,這個腰帶也會跟著滑鼠移動。
如果是按住Z鍵再點擊血量瓶的話,會發現我們只取下一半的血量瓶。
首先在Canvas底下創造一個PickedItem,這個物件是前面章節所介紹名為的Item的Prefab,如果不知道這個Prefab怎麼製作,請先看看以前的文章:
5-6 Knapsack User Interface
製作完成後,應該會在場景中看見如下圖的PickedItem物件,這是要用在滑鼠點擊物體後,會依照物體的資訊顯示在PickedItem上面,並將原本點擊的Slot上的Item移除。
PickedItem預設要不啟用,所以請大家在Inspector視窗中將勾勾取消。
首先簡單介紹一下Slot修改後的程式碼,主要是繼承IPointerDownHandler,並覆寫OnPointerDown方法,該方法可以偵測滑鼠按下的事件。
然後實作內容中,先用transform.childCount確認Slot內是否有Item,再用InvntorySystem類中的bool屬性isPickedItem判斷目前是否處於『Picked』狀態,如果為非,則可以將Slot內的物體取出來。其他行則有撰寫註解,請大家自己閱讀。
在InventorySystem類中,則主要新增了PickupItem方法,此方法用來將滑鼠點中的Item屬性設定到PickedItem上面。
以下提供本次修改的完整程式碼。
Slot.cs:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; namespace RPG.Inventory{ public class Slot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler { [SerializeField] GameObject itemPrefab; public void StoreItem(Item item){ // 若Slot底下沒有Item,則Instantiate一個 if (transform.childCount == 0) { GameObject itemObject = Instantiate (itemPrefab, transform); itemObject.GetComponentInChildren().SetItem (item); } else { // 已存在該Item,所以增加數量即可 transform.GetComponentInChildren ().AddAmount (); } } public int GetItemID(){ return transform.GetComponentInChildren ().Item.ID; } public bool IsFilled(){ ItemUI itemUI = transform.GetComponentInChildren (); return itemUI.Amount >= itemUI.Item.Capacity; } public void OnPointerEnter(PointerEventData eventData){ if (transform.childCount > 0) { Item item = GetComponentInChildren ().Item; GetComponentInParent ().ShowToolTip (item.GetToolTipText ()); } } public void OnPointerExit(PointerEventData eventData){ GetComponentInParent ().HideToolTip (); } public void OnPointerDown(PointerEventData eventData){ InventorySystem invetorySystem = GetComponentInParent (); if (transform.childCount > 0) { // 取得目前滑鼠點擊Slot的ItemUI ItemUI currentItemUI = GetComponentInChildren (); if (invetorySystem.isPickedItem == false) { if (Input.GetKey (KeyCode.Z)) { // 壓住Z鍵時,只會取出一半的數量 int amountToPick = (currentItemUI.Amount+1) / 2; int amountRemained = currentItemUI.Amount - amountToPick; // 將PickedItem的ItemUI設置為目前滑鼠點中的ItemUI invetorySystem.PickupItem (currentItemUI.Item, amountToPick); if (amountRemained == 0) { Destroy (currentItemUI.gameObject); } else { currentItemUI.SetAmount (amountRemained); } } else { // 將PickedItem的ItemUI設置為目前滑鼠點中的ItemUI invetorySystem.PickupItem(currentItemUI.Item, currentItemUI.Amount); // 因為已經選中物體了,要將Slot內的ItemUI刪除 Destroy (currentItemUI.gameObject); } } } } } }
InventorySystem.cs:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.UI; namespace RPG.Inventory{ public class InventorySystem : MonoBehaviour { [SerializeField] ToolTip toolTip; [SerializeField] ItemUI pickedItem; public bool isPickedItem = false; ItemList itemList; Slot[] slotList; void Start () { ParseItemsJson (); slotList = GetComponentsInChildren(); // 測試程式碼,手動生成物品 StoreItem (1); StoreItem (2); StoreItem (1); StoreItem (3); StoreItem (4); StoreItem (5); StoreItem (6); StoreItem (7); StoreItem (8); StoreItem (9); StoreItem (10); StoreItem (11); StoreItem (12); StoreItem (7); StoreItem (8); StoreItem (9); StoreItem (13); StoreItem (14); StoreItem (15); StoreItem (16); StoreItem (17); } void Update(){ if (isPickedItem) { // 將滑鼠座標轉換成Canvas上的座標 Vector2 position; Canvas canvas = GetComponentInParent
ItemUI.cs:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace RPG.Inventory{ public class ItemUI : MonoBehaviour{ public Item Item { get; set; } public int Amount { get; set; } public void SetItem(Item item, int amount = 1){ this.Item = item; this.Amount = amount; GetComponentInChildren().sprite = Resources.Load (item.Sprite); GetComponentInChildren ().text = Amount.ToString(); } public void AddAmount(int amount = 1){ this.Amount += amount; GetComponentInChildren ().text = Amount.ToString(); } public void SetAmount(int amount){ this.Amount = amount; GetComponentInChildren ().text = Amount.ToString(); } public void Show(){ gameObject.SetActive (true); } public void Hide(){ gameObject.SetActive (false); } public void SetLocalPosition(Vector3 localPosition){ transform.localPosition = localPosition; } } }
程式碼修改完成後,於KanpsackPanel的InventorySystem中,我們必須將剛剛新增到Canvas底下的PickedItem拉進參數,如下圖。
接著,讓我們執行遊戲看看吧。用滑鼠點擊腰帶後,腰帶被從背包上取下來了。
移動滑鼠時,這個腰帶也會跟著滑鼠移動。
如果是按住Z鍵再點擊血量瓶的話,會發現我們只取下一半的血量瓶。
留言
張貼留言