5-16 Character Property Panel
本章要來講講顯示人物屬性的視窗,主要是從背包內裝上裝備後,必須要更新人物屬性數值。首先,讓我們在Character Panel中新增一個UI/Panel。
新的Panel取名為Property Panel,然後在底下新增一個UI/Text,這是要用來顯示人數屬性的。
然後,Text的Anchor Presets請設定成stretch stretch。
然後請大家自己調整一下文字的大小、顏色。
最後,大致上做成如下圖的模樣,Property Panel的背景底圖就請大家自己找找吧。
接著,新增一個Script名為CharacterProperty.cs。
CharacterProperty.cs的原始碼如下:
然後將CharacterProperty.cs拉進Text底下。
接著修改InventorySystem.cs,主要變動的地方如下圖,僅是新增了一個方法用來呼叫CharacterProperty的UpdatePropertyText方法。
InventorySystem.cs:
修改完以後,記得在Canvas的InventorySystem中,要設定Character Property屬性,將Text拉進去。
最後,我們在EquipmentSlot.cs中,有一些穿脫裝備的地方需要更新人物屬性。
新的Panel取名為Property Panel,然後在底下新增一個UI/Text,這是要用來顯示人數屬性的。
然後,Text的Anchor Presets請設定成stretch stretch。
然後請大家自己調整一下文字的大小、顏色。
最後,大致上做成如下圖的模樣,Property Panel的背景底圖就請大家自己找找吧。
接著,新增一個Script名為CharacterProperty.cs。
CharacterProperty.cs的原始碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace RPG.Inventory{ public class CharacterProperty : MonoBehaviour { [SerializeField] int baseStrength = 10; [SerializeField] int baseIntellect = 10; [SerializeField] int baseAgility = 10; [SerializeField] int baseStamina = 10; Text propertyText; InventorySystem inventorySystem; void Start(){ propertyText = GetComponent<text> (); inventorySystem = GetComponentInParent<inventorysystem> (); } public void UpdatePropertyText(){ int strength = 0; int intellect = 0; int agility = 0; int stamina = 0; Slot[] slotList = inventorySystem.GetSlotList (); if (slotList.Length == 0) { return ; } foreach (Slot slot in slotList) { EquipmentSlot equipmentSlot = (slot as EquipmentSlot); if (equipmentSlot && slot.transform.childCount > 0) { Item item = slot.transform.GetComponentInChildren<itemui> ().Item; if (item is Equipment) { Equipment equipment = (item as Equipment); strength += equipment.Strength; intellect += equipment.Intellect; agility += equipment.Agility; stamina += equipment.Stamina; } } } strength += baseStrength; intellect += baseIntellect; agility += baseAgility; stamina += baseStamina; string text = string .Format ( "力量:{0}\n智力:{1}\n敏捷:{2}\n體力:{3}" , strength, intellect, agility, stamina); propertyText.text = text; } } } </itemui></inventorysystem></text> |
然後將CharacterProperty.cs拉進Text底下。
接著修改InventorySystem.cs,主要變動的地方如下圖,僅是新增了一個方法用來呼叫CharacterProperty的UpdatePropertyText方法。
InventorySystem.cs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.UI; using UnityEngine.EventSystems; namespace RPG.Inventory{ public class InventorySystem : MonoBehaviour { [SerializeField] ToolTip toolTip; [SerializeField] ItemUI pickedItem; [SerializeField] CharacterProperty characterProperty; public bool isPickedItem = false ; ItemList itemList; Slot[] slotList; void Start () { ParseItemsJson (); slotList = GetComponentsInChildren<slot> (); } void Update(){ PressGToAddItem (); MovePickedItemByMousePosition (); DiscardPickedItem (); } public void PickupItem(Item item, int amount){ pickedItem.SetItem (item, amount); pickedItem.Show (); toolTip.Hide (); isPickedItem = true ; } public void ReducePickedItem( int amount){ pickedItem.ReduceAmount(amount); if (pickedItem.Amount <= 0) { isPickedItem = false ; pickedItem.Hide (); } } public void WearingEquipment(ItemUI equipmentToWear){ if ((equipmentToWear.Item is Equipment) == false ) { return ; } foreach (Slot slot in slotList){ EquipmentSlot equipmentSlot = (slot as EquipmentSlot); if (equipmentSlot && equipmentSlot.EquipmentTypeIsEqual (equipmentToWear.Item)){ if (equipmentSlot.transform.childCount > 0) { // 人物已配戴裝備了,將裝備與背包的裝備交換 equipmentSlot.GetComponentInChildren<itemui> ().ExchangeItem(equipmentToWear); } else { // 人物未配戴裝備,直接穿上 equipmentSlot.StoreItem (equipmentToWear.Item); // 銷毀背包內的裝備 Destroy (equipmentToWear.gameObject); } break ; } } UpdatePropertyText (); } public ItemUI GetPickedItem(){ return pickedItem; } public Slot[] GetSlotList(){ return slotList; } public void ShowToolTip( string content){ toolTip.Show (content); } public void HideToolTip(){ toolTip.Hide (); } public void UpdatePropertyText(){ characterProperty.UpdatePropertyText (); } public bool StoreItem( int id){ Item item = GetItemByID (id); return StoreItem (item); } public bool StoreItem(Item item){ if (item == null ) { return false ; } // 若物品的儲存容量為1,則將該物品直接放進空的Slot if (item.Capacity == 1) { return StoreItemInEmptySlot (item); } // 將相同的Item放在同一個Slot return StoreItemInSameSlot(item); } private void PressGToAddItem(){ // 測試程式碼,手動生成物品 if (Input.GetKeyDown (KeyCode.G)) { StoreItem (Random.Range(1,17)); } } private void MovePickedItemByMousePosition(){ if (isPickedItem) { // 將滑鼠座標轉換成Canvas上的座標 Vector2 position; Canvas canvas = GetComponentInParent<canvas> (); RectTransformUtility.ScreenPointToLocalPointInRectangle ( canvas.transform as RectTransform, Input.mousePosition, null , out position); pickedItem.SetLocalPosition (position); } } private void DiscardPickedItem(){ // 處理物品丟棄 // IsPointerOverGameObject(-1)判斷滑鼠左鍵是否有碰到GameObject if (pickedItem && Input.GetMouseButtonDown (0) && EventSystem.current.IsPointerOverGameObject(-1) == false ) { // TODO 跟Slot.cs的PickupAllSlotItem相衝突,若用DestroyImmediate會導致此方法被呼叫 isPickedItem = false ; pickedItem.Hide (); } } private bool StoreItemInSameSlot(Item item){ foreach (Slot slot in slotList) { if (slot.transform.childCount >= 1 && slot.GetItemID () == item.ID && slot.IsFilled () == false ) { // 將新Item與同一個Item放在一起 slot.StoreItem (item); return true ; } } // 若背包內不存在相同的Item,則放進空的Slot return StoreItemInEmptySlot (item); } private bool StoreItemInEmptySlot(Item item){ foreach (Slot slot in slotList) { if (slot.transform.childCount == 0) { // 將Item存進該Slot slot.StoreItem (item); return true ; } } Debug.LogError ( "No Empty Slot." ); return false ; } private Item GetItemByID( int id){ foreach (Item entity in itemList.ConsumableEntityList) { if (entity.ID == id) { return entity; } } foreach (Item entity in itemList.EquipmentEntityList) { if (entity.ID == id) { return entity; } } foreach (Item entity in itemList.MaterialEntityList) { if (entity.ID == id) { return entity; } } return null ; } private void ParseItemsJson(){ // 從Resource資料夾中讀取Items.json TextAsset json = Resources.Load<textasset> ( "Items" ); // 解析Json格式 itemList = JsonUtility.FromJson <itemlist>(json.text); } } } </itemlist></textasset></canvas></itemui></slot> |
修改完以後,記得在Canvas的InventorySystem中,要設定Character Property屬性,將Text拉進去。
最後,我們在EquipmentSlot.cs中,有一些穿脫裝備的地方需要更新人物屬性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; namespace RPG.Inventory{ public class EquipmentSlot : Slot { [SerializeField] public EquipmentType equipmentType; public override void OnPointerDown(PointerEventData eventData){ // 使用滑鼠右鍵自動脫下裝備 if (eventData.button == PointerEventData.InputButton.Right && invetorySystem.isPickedItem == false && transform.childCount > 0) { ItemUI clickedItemUI = GetComponentInChildren<itemui> (); invetorySystem.StoreItem (clickedItemUI.Item); DestroyImmediate (clickedItemUI.gameObject); invetorySystem.UpdatePropertyText (); } if (eventData.button != PointerEventData.InputButton.Left) { return ; } if (invetorySystem.isPickedItem == true ) { Item pickedItem = invetorySystem.GetPickedItem ().Item; // 判斷手上的裝備類型是否與該Slot的裝備類型相同 if (EquipmentTypeIsEqual (pickedItem)) { if (transform.childCount > 0) { // 若裝備槽有東西,將手上的物品與裝備槽交換 ItemUI clickedItemUI = transform.GetChild (0).GetComponent<itemui> (); invetorySystem.GetPickedItem ().ExchangeItem (clickedItemUI); invetorySystem.UpdatePropertyText (); } else { // 若裝備槽沒東西,直接把手上的東西放進去 PutInOneItem(); invetorySystem.UpdatePropertyText (); } } } else { if (transform.childCount > 0) { // 若裝備槽有東西,將裝備拿到手上 ItemUI clickedItemUI = transform.GetChild (0).GetComponent<itemui> (); PickupAllSlotItem(clickedItemUI); invetorySystem.UpdatePropertyText (); } } } public bool EquipmentTypeIsEqual(Item item){ return item is Equipment && (item as Equipment).TheEquipmentType == equipmentType; } } } </itemui></itemui></itemui> |
留言
張貼留言