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就會裝備上去。






留言
張貼留言