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鍵再點擊血量瓶的話,會發現我們只取下一半的血量瓶。










留言
張貼留言