2D獵寶行動(類掃雷小遊戲)DAY 9
阿新 • • 發佈:2018-11-06
1.製作道具欄的圖示
2.完成UI的繪製並建立UI指令碼
建立MainPanel類
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class MainPanel : MonoBehaviour { private static MainPanel _instance; public Image armorIcon; public Image keyIcon; public Image arrowIcon; public Image swordIcon; public Image hoeIcon; public Image hoeBag; public Image tntIcon; public Image tntBag; public Image mapIcon; public Image mapBag; public Image grassIcon; public Text levelText; public Text hpText; public Text armorText; public Text keyText; public Text weaponText; public Text hoeText; public Text tntText; public Text mapText; public Text goldText; private void Awake() { _instance = this; } }
3.完成道具記錄變數和UI更新方法
完善UI程式碼
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; public class MainPanel : MonoBehaviour { private static MainPanel _instance; public Image armorIcon; public Image keyIcon; public Image arrowIcon; public Image arrowBg; public Image swordIcon; public Image hoeIcon; public Image hoeBag; public Image tntIcon; public Image tntBag; public Image mapIcon; public Image mapBag; public Image grassIcon; public Text levelText; public Text hpText; public Text armorText; public Text keyText; public Text weaponText; public Text hoeText; public Text tntText; public Text mapText; public Text goldText; public bool isHide = false; private void Awake() { _instance = this; } void Start() { UpdateUI(); } public void OnLevelButton() { if(isHide == false) { isHide = true; GetComponent<RectTransform>().DOAnchorPosY(-7, 0.5f); } else { isHide = false; GetComponent<RectTransform>().DOAnchorPosY(45, 0.5f); } } public void UpdateUI() { levelText.text = "Level" + GameManager._instance.lv; hpText.text = GameManager._instance.hp.ToString(); if(GameManager._instance.armor == 0) { armorIcon.gameObject.SetActive(false); armorText.gameObject.SetActive(false); } else { armorIcon.gameObject.SetActive(true); armorText.gameObject.SetActive(true); armorText.text = GameManager._instance.armor.ToString(); } if (GameManager._instance.key == 0) { keyIcon.gameObject.SetActive(false); keyText.gameObject.SetActive(false); } else { keyIcon.gameObject.SetActive(true); keyText.gameObject.SetActive(true); keyText.text = GameManager._instance.key.ToString(); } switch (GameManager._instance.weaponType) { case WeaponType.None: arrowBg.gameObject.SetActive(true); arrowIcon.gameObject.SetActive(false); swordIcon.gameObject.SetActive(false); weaponText.gameObject.SetActive(false); break; case WeaponType.Arrow: arrowBg.gameObject.SetActive(true); arrowIcon.gameObject.SetActive(true); swordIcon.gameObject.SetActive(false); weaponText.gameObject.SetActive(true); weaponText.text = GameManager._instance.arrow.ToString(); break; case WeaponType.Sword: arrowBg.gameObject.SetActive(false); arrowIcon.gameObject.SetActive(false); swordIcon.gameObject.SetActive(true); weaponText.gameObject.SetActive(false); break; } if (GameManager._instance.hoe == 0) { hoeIcon.gameObject.SetActive(false); hoeText.gameObject.SetActive(false); hoeBag.gameObject.SetActive(false); } else { hoeIcon.gameObject.SetActive(true); hoeText.gameObject.SetActive(true); hoeBag.gameObject.SetActive(true); hoeText.text = GameManager._instance.hoe.ToString(); } if (GameManager._instance.tnt == 0) { tntIcon.gameObject.SetActive(false); tntText.gameObject.SetActive(false); tntBag.gameObject.SetActive(false); } else { tntIcon.gameObject.SetActive(true); tntText.gameObject.SetActive(true); tntBag.gameObject.SetActive(true); tntText.text = GameManager._instance.tnt.ToString(); } if (GameManager._instance.map == 0) { mapIcon.gameObject.SetActive(false); mapText.gameObject.SetActive(false); mapBag.gameObject.SetActive(false); } else { mapIcon.gameObject.SetActive(true); mapText.gameObject.SetActive(true); mapBag.gameObject.SetActive(true); mapText.text = GameManager._instance.map.ToString(); } grassIcon.gameObject.SetActive(GameManager._instance.isGrass); goldText.text = GameManager._instance.gold.ToString(); } }
執行程式,如下圖:
3.處理道具的拾取
分別在金錢和道具類裡邊新增獲取方法
private void GetGold() { int x = 1; if (GameManager._instance.isGrass == true) x = 2; switch (goldType) { case GoldType.One: GameManager._instance.gold += 30 * x; break; case GoldType.Two: GameManager._instance.gold += 60 * x; break; case GoldType.Three: GameManager._instance.gold += 100 * x; break; case GoldType.Four: GameManager._instance.gold += 150 * x; break; case GoldType.Five: GameManager._instance.gold += 450 * x; break; case GoldType.Six: GameManager._instance.gold += 600 * x; break; case GoldType.Seven: GameManager._instance.gold += 1000 * x; break; } MainPanel._instance.UpdateUI(); }
private void GetTool()
{
switch (toolType)
{
case ToolType.Hp:
GameManager._instance.hp++;
break;
case ToolType.Armor:
GameManager._instance.armor++;
break;
case ToolType.Sword:
GameManager._instance.weaponType = WeaponType.Sword;
GameManager._instance.armor = 0;
break;
case ToolType.Map:
GameManager._instance.map++;
break;
case ToolType.Arrow:
GameManager._instance.weaponType = WeaponType.Arrow;
GameManager._instance.arrow++;
break;
case ToolType.Key:
GameManager._instance.key++;
break;
case ToolType.Tnt:
GameManager._instance.tnt++;
break;
case ToolType.Hoe:
GameManager._instance.hoe++;
break;
case ToolType.Grass:
GameManager._instance.isGrass = true;
break;
}
MainPanel._instance.UpdateUI();
}
在GamaManager中新增受到傷害的方法
public void TakeDamage()
{
if(armor > 0)
{
armor--;
}
else
{
hp--;
}
if(hp == 0)
{
DisplayAllTraps();
ani.SetBool("Die", true);
}
else
{
ani.SetTrigger("TakeDamage");
}
}
4.使用鑰匙和武器道具
修改門中的方法和製作開門特效預製體
public override void OnLeftMouseButton()
{
if (Vector3.Distance(transform.position, GameManager._instance.player.transform.position) < 1.5f)
{
if (GameManager._instance.key > 0)
{
GameManager._instance.key--;
MainPanel._instance.UpdateUI();
Instantiate(GameManager._instance.doorOpenEffect, transform);
ToNumberElement(true);
}
else
{
base.OnLeftMouseButton();
}
}
else
{
base.OnLeftMouseButton();
}
}
5.製作道具使用的範圍提示效果
6.使用單選按鈕組來選擇道具的使用
7.使用鋤頭、炸藥和地圖道具
新增使用道具的方法SelectGizmos
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SelectGizmos : MonoBehaviour {
public ToolType toolType;
private void OnMouseUp()
{
int x = (int)transform.position.x;
int y = (int)transform.position.y;
switch (toolType)
{
case ToolType.Map:
MainPanel._instance.hoeToggle.isOn = false;
GameManager._instance.map--;
MainPanel._instance.UpdateUI();
for (int i = x - 3; i < x + 3; i++)
{
for (int j = y - 3; j < y + 3; j++)
{
if (i >= 0 && i < GameManager._instance.w && j >= 0 && j < GameManager._instance.h && GameManager._instance.mapArray[i, j].elementContent != ElementContent.Exit)
{
if(GameManager._instance.mapArray[i, j].elementContent ==ElementContent.Trap&& GameManager._instance.mapArray[i, j].elementState != ElementState.Marked)
{
GameManager._instance.mapArray[i, j].OnRightMouseButton();
}
if (GameManager._instance.mapArray[i, j].elementContent != ElementContent.Trap && GameManager._instance.mapArray[i, j].elementState == ElementState.Marked)
{
GameManager._instance.mapArray[i, j].OnRightMouseButton();
}
}
}
}
break;
case ToolType.Tnt:
MainPanel._instance.tntToggle.isOn = false;
GameManager._instance.tnt--;
MainPanel._instance.UpdateUI();
for(int i = x - 1; i < x + 1; i++)
{
for(int j = y - 1; j < y + 1; j++)
{
if (i >= 0 && i < GameManager._instance.w && j >= 0 && j < GameManager._instance.h &&GameManager._instance.mapArray[i,j].elementContent!=ElementContent.Exit)
{
if(GameManager._instance.mapArray[i, j].elementType == ElementType.DoubleCovered)
{
((DoubleCoveredElement)GameManager._instance.mapArray[i, j]).UncoverElementSingle();
}
else
{
GameManager._instance.mapArray[i, j].ToNumberElement(true);
}
}
}
}
break;
case ToolType.Hoe:
MainPanel._instance.hoeToggle.isOn = false;
GameManager._instance.hoe--;
MainPanel._instance.UpdateUI();
for (int i = x - 1; i < x + 1; i++)
{
for (int j = y - 1; j < y + 1; j++)
{
if (i >= 0 && i < GameManager._instance.w && j >= 0 && j < GameManager._instance.h && GameManager._instance.mapArray[i, j].elementContent != ElementContent.Exit)
{
if (GameManager._instance.mapArray[i, j].elementType != ElementType.CantCovered)
{
((SingleCoveredElement)GameManager._instance.mapArray[i, j]).UncoverElementSingle();
}
else
{
if (GameManager._instance.mapArray[i, j].elementContent == ElementContent.SmallWall)
{
GameManager._instance.mapArray[i, j].ToNumberElement(true);
}
}
}
}
}
break;
default:
break;
}
}
}
執行程式,結果如下:
8.製作UI動效
修改更新UI的方法,並在其他地方進行引數修改
public void UpdateUI(params RectTransform[] rts)
{
foreach(RectTransform rt in rts)
{
rt.DOShakeScale(0.5f).onComplete += () =>
{
rt.localScale = new Vector3(1, 1, 1);
};
}
}
9.資源池的簡介與簡單資源池的建立
什麼是資源池
將一定數量的物件預先儲存在資源池中,當需要的時候使用,而不是每次都例項化一個物件,不用的時候再放回。例如一款射擊類遊戲,需要不斷的發射子彈,如果每發射一顆子彈,都要例項化一個物件,隨後再銷燬物件,再例項化物件,必然會消耗較大的記憶體。如果預先就將子彈例項化出一定的數量,並儲存在彈夾中,發射的時候,取出來發射,不用的時候,再放回彈夾。如此反覆利用,可以避免頻繁例項化和銷燬帶來的效能消耗。這裡的彈夾的概念就是資源池模式!
於是首先先給特效建立一個列舉型別
public enum EffectType
{
SmokeEffect,
UncoveredEffect,
GoldEffect,
DoorOpenEffect
}
然後建立資源池管理類,並進行初始化
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolManager : MonoBehaviour {
public static PoolManager _instance;
Dictionary<EffectType, List<GameObject>> poolListDic = new Dictionary<EffectType, List<GameObject>>();
List<GameObject> uncoveredEffectList = new List<GameObject>();
List<GameObject> smokeEffectList = new List<GameObject>();
List<GameObject> goldEffectList = new List<GameObject>();
List<GameObject> doorOpenEffectList = new List<GameObject>();
Dictionary<EffectType, int> poolListCapacityDic = new Dictionary<EffectType, int>();
int uncoveredEffectCapacity;
int smokeEffectCapacity = 5;
int goldEffectCapacity = 20;
int doorOpenEffectCapacity = 5;
Dictionary<EffectType, GameObject> effectGoDic = new Dictionary<EffectType, GameObject>();
private void Awake()
{
_instance = this;
poolListDic.Add(EffectType.UncoveredEffect, uncoveredEffectList);
poolListDic.Add(EffectType.SmokeEffect, uncoveredEffectList);
poolListDic.Add(EffectType.GoldEffect, uncoveredEffectList);
poolListDic.Add(EffectType.DoorOpenEffect, uncoveredEffectList);
uncoveredEffectCapacity = (int)(GameManager._instance.w * GameManager._instance.h * 0.2f);
poolListCapacityDic.Add(EffectType.UncoveredEffect, uncoveredEffectCapacity);
poolListCapacityDic.Add(EffectType.SmokeEffect, smokeEffectCapacity);
poolListCapacityDic.Add(EffectType.GoldEffect, goldEffectCapacity);
poolListCapacityDic.Add(EffectType.DoorOpenEffect, doorOpenEffectCapacity);
effectGoDic.Add(EffectType.UncoveredEffect, GameManager._instance.uncoveredEffect);
effectGoDic.Add(EffectType.SmokeEffect, GameManager._instance.smokeEffect);
effectGoDic.Add(EffectType.GoldEffect, GameManager._instance.goldEffect);
effectGoDic.Add(EffectType.DoorOpenEffect, GameManager._instance.doorOpenEffect);
}
}
10.完成資源池的功能
完成資源池的新增,重置。
public GameObject GetInstance(EffectType type, Transform t = null,bool worldPosStays = false)
{
List<GameObject> list;
poolListDic.TryGetValue(type, out list);
if (list.Count > 0)
{
GameObject tempGo = list[list.Count - 1];
tempGo.SetActive(true);
ResetInstance(tempGo);
if(t!= null)
{
tempGo.transform.SetParent(t, worldPosStays);
}
list.RemoveAt(list.Count - 1);
return tempGo;
}
else
{
GameObject go;
effectGoDic.TryGetValue(type, out go);
if (t != null)
{
return Instantiate(go, t, worldPosStays);
}
else
{
return Instantiate(go);
}
}
}
public void StoreInstance(EffectType type,GameObject go)
{
List<GameObject> list;
poolListDic.TryGetValue(type, out list);
int listCap;
poolListCapacityDic.TryGetValue(type, out listCap);
if (list.Count < listCap)
{
go.SetActive(false);
list.Add(go);
}
else
{
Destroy(go);
}
}
private void ResetInstance(GameObject go)
{
ParticleSystem ps = go.GetComponent<ParticleSystem>();
if(ps != null)
{
ps.Stop();
ps.Play();
}
foreach(Transform t in go.transform)
{
ParticleSystem tps = go.GetComponent<ParticleSystem>();
if (tps != null)
{
tps.Stop();
tps.Play();
}
}
}