5-20 Change Weapon Config When Equipping Weapon
前面我們花了大量的篇幅製作了背包系統,現在就要來將背包系統跟我們遊戲中的武器系統進行整合,首先,我的背包系統換了一個新的介面,所以不要覺得奇怪為什麼變漂亮了XDD我是從這邊買的,如果大家也喜歡的話歡迎購買唷~我沒有在廣告,這介面也不是我做的。
https://assetstore.unity.com/packages/2d/gui/arrow-mobile-ui-for-ugui-64369
這次的修改沒有很複雜,主要在InventorySystem.cs的WearingEquipment方法中,呼叫WeaponSystem用來更換武器的方法。所以,重點在於要將JSON資訊跟Weapon綁定在一起。如果不懂我是怎麼在WeaponSystem更換武器的話,可以先看看以前的文章:
4-3 Weapon Pickup Points
https://rpgcorecombat.blogspot.tw/2018/01/4-3-weapon-pickup-points.html
首先,我先將本次要測試更換的Simple Bow跟Orc Sword放到Resources資料夾。
然後修改JSON格式,多新增一個欄位EquipmentAssetsPath。
以下提供我目前完整的JSON格式:
然後記得在Equipment.cs中也要跟著多增加一個變數:
最後是換裝的程式碼,我用Resources.Load方法讀取放置在Resources資料夾內的武器設定(Weapon.cs),然後使用WeaponSystem.PutWeaponInHand方法更換武器。
這樣就完成啦!以下提供完整的InventorySystem.cs程式碼:
然後來執行遊戲測試看看吧,裝備劍的時候,就會把Orc Sword裝備上去。
裝備弓的時候,Simple Bow就會裝備上去。
https://assetstore.unity.com/packages/2d/gui/arrow-mobile-ui-for-ugui-64369
這次的修改沒有很複雜,主要在InventorySystem.cs的WearingEquipment方法中,呼叫WeaponSystem用來更換武器的方法。所以,重點在於要將JSON資訊跟Weapon綁定在一起。如果不懂我是怎麼在WeaponSystem更換武器的話,可以先看看以前的文章:
4-3 Weapon Pickup Points
https://rpgcorecombat.blogspot.tw/2018/01/4-3-weapon-pickup-points.html
首先,我先將本次要測試更換的Simple Bow跟Orc Sword放到Resources資料夾。
然後修改JSON格式,多新增一個欄位EquipmentAssetsPath。
以下提供我目前完整的JSON格式:
{"ConsumableEntityList":[ { "ID":1, "Name":"血量瓶", "ItemTypeString":"Consumable", "ItemQualityString":"Common", "Description":"+ 25 HP", "Capacity":10, "BuyPrice":10, "SellPrice":10, "Sprite":"Sprites/Items/hp", "HP":10, "MP":0 }, { "ID":2, "Name":"能量瓶", "ItemTypeString":"Consumable", "ItemQualityString":"Common", "Description":"+ 50 MP", "Capacity":10, "BuyPrice":10, "SellPrice":10, "Sprite":"Sprites/Items/mp", "HP":0, "MP":10 } ], "EquipmentEntityList":[ { "ID":3, "Name":"胸甲", "ItemTypeString":"Equipment", "ItemQualityString":"Rare", "Description":"+ 50 DEF", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/armor", "Strength":10, "Intellect":0, "Agility":10, "Stamina":50, "EquipmentTypeString":"Armor", "EquipmentAssetsPath":"" }, { "ID":4, "Name":"皮腰帶", "ItemTypeString":"Equipment", "ItemQualityString":"Epic", "Description":"+ 20 AGI +50 STA", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/belts", "Strength":0, "Intellect":0, "Agility":20, "Stamina":50, "EquipmentTypeString":"Belt", "EquipmentAssetsPath":"" }, { "ID":5, "Name":"靴子", "ItemTypeString":"Equipment", "ItemQualityString":"Legendary", "Description":"+ 50 AGI", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/boots", "Strength":0, "Intellect":0, "Agility":50, "Stamina":0, "EquipmentTypeString":"Boots", "EquipmentAssetsPath":"" }, { "ID":6, "Name":"護腕", "ItemTypeString":"Equipment", "ItemQualityString":"Rare", "Description":"+ 50 STA", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/bracers", "Strength":0, "Intellect":0, "Agility":0, "Stamina":50, "EquipmentTypeString":"Bracer", "EquipmentAssetsPath":"" }, { "ID":7, "Name":"手套", "ItemTypeString":"Equipment", "ItemQualityString":"Common", "Description":"+20 STR + 50 STA", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/gloves", "Strength":20, "Intellect":0, "Agility":0, "Stamina":50, "EquipmentTypeString":"OffHand", "EquipmentAssetsPath":"" }, { "ID":8, "Name":"頭盔", "ItemTypeString":"Equipment", "ItemQualityString":"Artifact", "Description":"+20 STR + 100 STA", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/helmets", "Strength":20, "Intellect":0, "Agility":0, "Stamina":100, "EquipmentTypeString":"Head", "EquipmentAssetsPath":"" }, { "ID":9, "Name":"項鍊", "ItemTypeString":"Equipment", "ItemQualityString":"Rare", "Description":"+20 STR + 50 STA", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/necklace", "Strength":20, "Intellect":0, "Agility":0, "Stamina":50, "EquipmentTypeString":"Neck", "EquipmentAssetsPath":"" }, { "ID":10, "Name":"戒指", "ItemTypeString":"Equipment", "ItemQualityString":"Common", "Description":"+30 INT", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/rings", "Strength":0, "Intellect":30, "Agility":0, "Stamina":0, "EquipmentTypeString":"Ring", "EquipmentAssetsPath":"" }, { "ID":11, "Name":"褲子", "ItemTypeString":"Equipment", "ItemQualityString":"Uncommon", "Description":"+50 STA", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/pants", "Strength":0, "Intellect":0, "Agility":0, "Stamina":50, "EquipmentTypeString":"Leg", "EquipmentAssetsPath":"" }, { "ID":12, "Name":"護肩", "ItemTypeString":"Equipment", "ItemQualityString":"Legendary", "Description":"+50 STA", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/shoulders", "Strength":0, "Intellect":0, "Agility":0, "Stamina":50, "EquipmentTypeString":"Shoulder", "EquipmentAssetsPath":"" }, { "ID":13, "Name":"斧子", "ItemTypeString":"Equipment", "ItemQualityString":"Rare", "Description":"+50 STR", "Capacity":1, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/axe", "Damage":50, "EquipmentTypeString":"OffHand", "EquipmentAssetsPath":"" }, { "ID":14, "Name":"劍", "ItemTypeString":"Equipment", "ItemQualityString":"Rare", "Description":"+60 STR", "Capacity":1, "BuyPrice":50, "SellPrice":50, "Sprite":"Sprites/Items/sword", "Damage":60, "EquipmentTypeString":"MainHand", "EquipmentAssetsPath":"WeaponConfig/Orc Sword" }, { "ID":15, "Name":"弓", "ItemTypeString":"Equipment", "ItemQualityString":"Rare", "Description":"+60 STR", "Capacity":1, "BuyPrice":50, "SellPrice":50, "Sprite":"Sprites/Items/bow", "Damage":60, "EquipmentTypeString":"MainHand", "EquipmentAssetsPath":"WeaponConfig/Simple Bow" } ], "MaterialEntityList":[ { "ID":315, "Name":"鍛造秘笈", "ItemTypeString":"Material", "ItemQualityString":"Artifact", "Description":"合成一把斧子的鍛造秘笈", "Capacity":10, "BuyPrice":100, "SellPrice":10, "Sprite":"Sprites/Items/book" }, { "ID":316, "Name":"鍛造秘笈", "ItemTypeString":"Material", "ItemQualityString":"Artifact", "Description":"合成一個頭盔的鍛造秘笈", "Capacity":10, "BuyPrice":100, "SellPrice":10, "Sprite":"Sprites/Items/scroll" }, { "ID":317, "Name":"鐵塊", "ItemTypeString":"Material", "ItemQualityString":"Rare", "Description":"合成裝備使用的鐵塊", "Capacity":100, "BuyPrice":20, "SellPrice":10, "Sprite":"Sprites/Items/ingots" } ]}
然後記得在Equipment.cs中也要跟著多增加一個變數:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Text; namespace RPG.Inventory{ [Serializable] public class Equipment : Item { public int Strength; public int Intellect; public int Agility; public int Stamina; public string EquipmentTypeString; public string EquipmentAssetsPath; [NonSerialized] public EquipmentType TheEquipmentType; public override void OnAfterDeserialize(){ TheItemType = (ItemType)System.Enum.Parse (typeof(ItemType), ItemTypeString); TheItemQuality = (ItemQuality)System.Enum.Parse (typeof(ItemQuality), ItemQualityString); TheEquipmentType = (EquipmentType)System.Enum.Parse (typeof(EquipmentType), EquipmentTypeString); } public override string GetToolTipText (){ string text = base.GetToolTipText (); StringBuilder newText = new StringBuilder (text); string equipmentTypeText = String.Empty; switch (TheEquipmentType) { case EquipmentType.Armor: equipmentTypeText = "胸部"; break; case EquipmentType.Belt: equipmentTypeText = "腰帶"; break; case EquipmentType.Boots: equipmentTypeText = "靴子"; break; case EquipmentType.Bracer: equipmentTypeText = "護腕"; break; case EquipmentType.Head: equipmentTypeText = "頭部"; break; case EquipmentType.Leg: equipmentTypeText = "腿部"; break; case EquipmentType.Neck: equipmentTypeText = "脖子"; break; case EquipmentType.OffHand: equipmentTypeText = "副手"; break; case EquipmentType.Ring: equipmentTypeText = "戒指"; break; case EquipmentType.Shoulder: equipmentTypeText = "護肩"; break; } newText.AppendFormat ("\n\n裝備類型:{0} \n",equipmentTypeText); newText.AppendFormat ("力量:{0} \n", Strength); newText.AppendFormat ("智力:{0} \n", Intellect); newText.AppendFormat ("敏捷:{0} \n", Agility); newText.AppendFormat ("體力:{0} \n", Stamina); return newText.ToString(); } } public enum EquipmentType{ Head, Neck, Armor, Ring, Leg, Bracer, Boots, Shoulder, Belt, OffHand, MainHand } }
最後是換裝的程式碼,我用Resources.Load方法讀取放置在Resources資料夾內的武器設定(Weapon.cs),然後使用WeaponSystem.PutWeaponInHand方法更換武器。
這樣就完成啦!以下提供完整的InventorySystem.cs程式碼:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Text; using RPG.Character; using RPG.Weapons; namespace RPG.Inventory{ public class InventorySystem : MonoBehaviour { [SerializeField] ToolTip toolTip; [SerializeField] ItemUI pickedItem; [SerializeField] CharacterProperty characterProperty; public bool isPickedItem = false; ItemList itemList; ForgeFormulaList forgeFormulaList; Slot[] slotList; int coinAmount = 1000; Text coinText; void Start () { ParseItemsJson (); ParseForgeFormulaJson (); slotList = GetComponentsInChildren(); coinText = GameObject.Find ("Coin").GetComponentInChildren (); coinText.text = coinAmount.ToString(); InitialVendorItem (); } void Update(){ PressGToAddItem (); MovePickedItemByMousePosition (); DiscardPickedItem (); } public void SaveInventory(){ StringBuilder saveData = new StringBuilder (); foreach (Slot slot in slotList) { if (slot is VendorSlot) { // 如果是商店類型的Slot則不需要儲存狀態,所以儲存為沒有物品的0 saveData.Append ("0-"); } else if (slot.transform.childCount > 0) { // Slot內有物品,儲存ID跟數量 ItemUI itemUI = slot.GetComponentInChildren (); saveData.Append (itemUI.Item.ID + "," + itemUI.Amount + "-"); } else { // Slot內沒有物品,儲存0 saveData.Append ("0-"); } } PlayerPrefs.SetString (this.gameObject.name, saveData.ToString()); PlayerPrefs.SetInt ("CoinAmount", coinAmount); } public void LoadInventory(){ if (PlayerPrefs.HasKey (this.gameObject.name)) { string savaData = PlayerPrefs.GetString (this.gameObject.name); string[] itemArray = savaData.Split ('-'); // Length - 1是因為最後一個沒有資料 for (int i = 0; i < itemArray.Length - 1; i++) { if (itemArray [i] != "0") { string[] itemInfo = itemArray [i].Split (','); // 取得物品的ID跟數量 int id = int.Parse (itemInfo[0]); int amount = int.Parse (itemInfo[1]); Item item = GetItemByID (id); // 將物品生成在指定的Slot for (int j = 0; j < amount; j++) { slotList [i].StoreItem (item); } } } } if (PlayerPrefs.HasKey ("CoinAmount")) { coinAmount = PlayerPrefs.GetInt ("CoinAmount"); coinText.text = coinAmount.ToString (); } } private bool ConsumeCoin(int amount){ if (coinAmount > 0) { coinAmount -= amount; coinText.text = coinAmount.ToString (); return true; } return false; } private void EarnCoin(int amount){ coinAmount += amount; coinText.text = coinAmount.ToString (); } public void BuyItem(Item item){ bool isSuccess = ConsumeCoin (item.BuyPrice); if (isSuccess) { StoreItem (item); } } public void SellItem(int sellAmount){ int sellPrice = pickedItem.Item.SellPrice * sellAmount; ReducePickedItem (sellAmount); EarnCoin (sellPrice); } 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)){ // 換裝備的時候更換Player的武器 Weapon weaponConfig = Resources.Load ((equipmentToWear.Item as Equipment).EquipmentAssetsPath); if (weaponConfig != null) { FindObjectOfType () .GetComponent ().PutWeaponInHand (weaponConfig); } if (equipmentSlot.transform.childCount > 0) { // 人物已配戴裝備了,將裝備與背包的裝備交換 equipmentSlot.GetComponentInChildren ().ExchangeItem(equipmentToWear); } else { if (isPickedItem == true) { // 若使用Drag-Drop的方式穿上裝備,要記得再將pickedItem設定為false isPickedItem = false; pickedItem.Hide (); } // 人物未配戴裝備,直接穿上 equipmentSlot.StoreItem (equipmentToWear.Item); } 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 bool StoreItemInSameSlot(Item item){ foreach (Slot slot in slotList) { // 避開VendorSlot if (slot is VendorSlot) { continue; } 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) { // 避開VendorSlot if (slot is VendorSlot) { continue; } if (slot.transform.childCount == 0) { // 將Item存進該Slot slot.StoreItem (item); return true; } } Debug.LogError ("No Empty Slot."); return false; } public void ForgeItem(){ List materialsIDList = new List (); List forgeSlotList = new List (); // 取得Forge Slot內的Item foreach (Slot slot in slotList) { ForgeSlot forgeSlot = (slot as ForgeSlot); if (forgeSlot && slot.transform.childCount > 0) { ItemUI currentItemUI = slot.transform.GetComponentInChildren (); for (int i = 0; i < currentItemUI.Amount; i++) { materialsIDList.Add (currentItemUI.Item.ID); forgeSlotList.Add (forgeSlot); } } } // 檢查item組合是否匹配任一鍛造公式 foreach (ForgeFormula formula in forgeFormulaList.ForgeFormulaEntityList) { if (formula.MatchFormula (materialsIDList)) { // 符合公式,存入鍛造物品到背包內 StoreItem (formula.ResultID); // 消耗材料 ConsumeMaterials(formula, forgeSlotList); break; } } } private void ConsumeMaterials(ForgeFormula formula, List forgeSlotList){ List requireList = formula.GetRequireList(); foreach (int ID in requireList) { foreach (ForgeSlot forgeSlot in forgeSlotList) { if (forgeSlot.transform.childCount > 0 && forgeSlot.GetItemID() == ID) { ItemUI itemUI = forgeSlot.GetComponentInChildren (); itemUI.ReduceAmount (1); if (itemUI.Amount <= 0) { DestroyImmediate (itemUI.gameObject); } break; } } } } private void PressGToAddItem(){ // 測試程式碼,手動生成物品 if (Input.GetKeyDown (KeyCode.G)) { StoreItem (Random.Range(1,18)); } } private void InitialVendorItem(){ Item[] vendorItemList = new Item[8]; // 手動初始化要放入商店的物品 vendorItemList [0] = GetItemByID (1); vendorItemList [1] = GetItemByID (2); vendorItemList [2] = GetItemByID (3); vendorItemList [3] = GetItemByID (4); vendorItemList [4] = GetItemByID (5); vendorItemList [5] = GetItemByID (6); vendorItemList [6] = GetItemByID (7); vendorItemList [7] = GetItemByID (8); foreach (Item item in vendorItemList) { foreach (Slot slot in slotList) { // 限定Slot類型為VendorSlot VendorSlot vendorSlot = (slot as VendorSlot); // 如果同類型物品疊加在一起 if (vendorSlot && slot.transform.childCount >= 1 && slot.GetItemID () == item.ID && slot.IsFilled () == false) { slot.StoreItem (item); break; } // 如果沒有同類物品,則放入空Slot else if (vendorSlot && slot.transform.childCount == 0) { slot.StoreItem (item); break; } } } } private void MovePickedItemByMousePosition(){ if (isPickedItem) { // 將滑鼠座標轉換成Canvas上的座標 Vector2 position; Canvas canvas = GetComponentInParent
然後來執行遊戲測試看看吧,裝備劍的時候,就會把Orc Sword裝備上去。
裝備弓的時候,Simple Bow就會裝備上去。
留言
張貼留言