第十一章 裝備購買、經驗條以及環境碰撞器
本章內容較零散,主要是完善幾個功能,即藉助之前做好的裝備系統實現裝備商店與物品欄的交互,以及經驗條和環境碰撞器的添加。
11.1 裝備購買功能
我們首先添加商店NPC,類似藥品商人,可參考7.2.1節(
鏈接)
添加完NPC後,正式進入裝備商店的設計。由於裝備比藥品多,需要要裝備商店的UI要結合藥品商店和技能列表的下拉功能,如下左圖所示。
在UI root下新建EquipmentShop作爲裝備商店的UI。將UI界面下Skill的SkillGrid和ScrollBar、DrugShop下的一個Item(上右圖中(1)),複製一份到EquipmentShop下,將DrugShop中的Item改名爲EquipmentShopItem(上右圖中(2))
爲EquipmentShopItem創建一個腳本EquipmentShopItem,用以顯示物品信息,代碼如下
using UnityEngine;
using System.Collections;
public class EquipmentShopItem : MonoBehaviour {
public static EquipmentShopItem _instance;
private int id;
private ObjectsInfo.ObjectInfo info;
private UISprite icon_name; //添加各子物體的引用
private UILabel equipment_label;
private UILabel equipment_buyMoney;
private UILabel equipment_describe;
void Awake()
{
_instance = this;
}
public void SetId(int id) //通過id更新EquipmentShopItem下子物體的信息
{
InitProperty ();
this.id = id;
info = ObjectsInfo._instance.GetObjectInfoFromDict (id);
icon_name.spriteName = info.icon_name;
equipment_label.text = info.name;
equipment_buyMoney.text = info.price_buy.ToString();
if (info.attack > 0)
{
equipment_describe.text = "+Attack:" + info.attack;
}
else if (info.defense > 0)
{
equipment_describe.text = "+Defense:" + info.defense;
}
else if(info.speed > 0)
{
equipment_describe.text = "Speed:" + info.speed;
}
}
void InitProperty() //初始化子物體
{
icon_name = transform.Find ("Equip").GetComponent<UISprite> ();
equipment_label = transform.Find ("EquipLabel").GetComponent<UILabel> ();
equipment_buyMoney = transform.Find ("BuyMoney").GetComponent<UILabel> ();
equipment_describe = transform.Find ("Describe").GetComponent<UILabel> ();
}
}
之後需要通過訪問ObjectsInfoInList中的裝備信息,在EquipmentShop腳本中新建一個數組,用以管理所有的裝備id(2001~2012),並添加一個grid引用,用於管理grid並實現動態添加裝備的功能。
public GameObject equipmentItemPrefab;
public int[] EquipmentID;
public UIGrid grid;
將動態創建裝備寫成一個函數,命名爲InitEquipShop,代碼如下(參考9.2.1的Grid,
鏈接)
void InitEquipShop()
{
foreach (int id in EquipmentID) //遍歷所有裝備id並創建
{
GameObject itemGO = NGUITools.AddChild(grid.gameObject,equipmentItemPrefab);
grid.AddChild(itemGO.transform);
itemGO.GetComponent<EquipmentShopItem>().SetId(id);
}
}
結果如下圖所示。
購買裝備同樣參照藥品的購買。我們在EquipmentShop腳本中新建一個函數OnBuyButtonClick(),並賦值給Prefab中的EquipmentShopItem的BuyButton,訪問EquipmentShop中的Buy()函數,它們各自的實現如下
public void OnBuyButtonClick()
{
EquipmentShop._instance.Buy (id);
}
public void Buy(int id)
{
int buyMoney = ObjectsInfo._instance.GetObjectInfoFromDict (id).price_buy; //獲取裝備價格
bool success = Inventory._instance.IsGetCoinSuccess (buyMoney); //判斷當前剩餘金額是否大於裝備價格
if (success)
{
Inventory._instance.GetId(id);
}
}
即可實現購買功能(這裏的功能完全可以在OnBuyButtonClick()函數中直接實現,多此一舉的原因主要是因爲面向對象的編程方式,在EquipmentShop進行購買會更易於維護)
11.2 經驗條的顯示
經驗條用Colored Progress Bar顯示,並添加一個EXPBar腳本控制,代碼如下。
using UnityEngine;
using System.Collections;
public class EXPBar : MonoBehaviour {
public static EXPBar _instance;
private UISlider progress;
void Awake()
{
_instance = this;
progress = this.GetComponent<UISlider> (); //取得進度條信息
}
public void SetValue(float value)
{
progress.value = value; //改變進度條的顯示
}
}
經驗條涉及到經驗屬性,因此在PlayerStatus中添加這一屬性,並通過一個函數控制
public float expCurrent = 0; //當前經驗
public void GetExp(float exp)
{
this.expCurrent += exp; //當前exp加上殺怪獲取
int totalExp = 100 + this.level * 30; //等級與經驗的對應公式
while (this.expCurrent >= totalExp) //用while循環判斷角色是否連升多級,若是,每升級一次,都增加技能點,並更新expCurrent的顯示
{
++level;
expCurrent -= totalExp;
point_remain += 5;
totalExp = 100 + this.level * 30;
}
EXPBar._instance.SetValue (this.expCurrent / totalExp); //更新進度條的顯示
}
在之後擊殺怪物時,我們再完善這一功能。
11.3 給環境添加碰撞器
現在角色在移動時可以穿越障礙物、直接過河等操作,這顯然是不合理的,如下圖所示
因此本節對此問題進行改善。我們在Hierarchy中添加一個空的Empty,命名爲Colliders,作爲碰撞器的存儲位置,新建一個3D的Cube,作爲碰撞器,如下左圖所示。通過Crrl+D複製,以達到地圖邊界創建的效果,如下右圖
對於一些可以行走的地方,例如橋,我們需要添加Mesh Collider,並更改它的Tag爲Ground以實現在橋上的行走效果。爲了去除圍牆的顯示效果,我們將Mesh Filter和Mesh Render移出即可。