小白贪狼做塔防(1)
2017-10-20 本文已影响107人
貪狼大人
最近学习到了项目期,分配了组员之后,我们经过一番推敲,决定做一个塔防类型游戏,首先我们先建立了游戏场景(第一关)。
游戏场景
然后由我着手防御塔的建造,升级,卖掉功能的实现。接到任务的第一刻,我本来是打算使用世界坐标下的Canvas。
Canvas
在Canvas上添加Text组件
然后设置按钮,并编写代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BuyButton : MonoBehaviour {
public Canvas cv;
void Awake()
{
//cv = GameObject.Find("Canvas").GetComponent<Canvas>();
//cv.enabled = true;
}
//cv.GetComponent<Text>().储存要建造的防御塔名字并传给Canvas的Text,以便防御塔知道你想建造的塔的名字(用在动态实例化)你的操作。
public void OnClick()
{
cv.GetComponent<Text>().text = transform.GetChild(0).GetComponent<Text>().text;
}
public void OnDestory()
{
cv.GetComponent<Text>().text = "Destory";
}
public void OnLvUp()
{
cv.GetComponent<Text>().text = "LvUp";
}
}
脚本拖在这里
貌似很丑哈,这不重要
然后通过点击防御塔基座“呼叫”Canvas,使其从隐藏状态变为显示状态,并且在所点击的防御塔上方出现。但是当时我一时脑抽,没想到怎么解决点击防御塔基座,呼叫出Canvas之后,该怎么将需要建造的防御塔建在呼叫他的防御塔基座上(当然在我想到另一只能够办法并实现后,我又想出了这个,吐血,方法就是点击了防御塔基座之后,呼叫出Canvas,并在Canvas的脚本里,加上public Transform a;,然后在呼叫时,加上一句画布.a=防御塔基座.transform,然后再点击按钮就可以将想要做的操作影响到正确的的塔了,不过我懒得改已经做好的方案二,就没做这个方法)
之后,我在防御塔上挂载了Tower脚本以便储存当前防御塔的一些状态及属性
脚本在此:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Tower : MonoBehaviour {
public bool isBiuld;
public int level;
//这句没用忘了删除了,尴尬,图都截了
public int NO;
//存基座上塔的名字
public string towername;
void Start ()
{
//初始化(基座无塔,等级为0)
isBiuld = false;
level = 0;
}
}
然后我们在摄像机上挂载两个脚本(其实这两个可以合并成一个,我懒得改)
拖到相机上
BuyTower脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BuyTower : MonoBehaviour
{
public Canvas cv;
}
//惊不惊喜意不意外,就一句代码我也懒得合到另一个脚本里,你们要合并哦,别学我
CreatTower脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class CreatTower : MonoBehaviour
{
//public GameObject tower;
private GameObject tw;
private GameObject ntw;
//private GameObject o;
public bool haveTower;
private Ray ray;
private RaycastHit hitInfo;
private BuyTower bt;
MyLinkList<GameObject> myLinkList = new MyLinkList<GameObject>();
void Start()
{
gameObj = transform.GetComponent<CreatTower>();
bt = transform.GetComponent<BuyTower>();
haveTower = false;
}
GameObject o = null;
CreatTower gameObj;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hitInfo))
{
//gameObj = Camera.main.GetComponent<CreatTower>();
if (IsPointerOverGameObject(Input.mousePosition))
{
return;
}
if (hitInfo.collider.gameObject.tag == "Tower")
{
//gameObj.tw = (GameObject)Resources.Load("Prefabs_Turrets/" + bt.cv.GetComponent<Text>().text + hitInfo.collider.gameObject.GetComponent<Tower>().level.ToString());
haveTower = hitInfo.collider.gameObject.GetComponent<Tower>().isBiuld;
if (!haveTower && bt.cv.GetComponent<Text>().text != "" && bt.cv.GetComponent<Text>().text != "Destory"&& bt.cv.GetComponent<Text>().text != "LvUp")
{
Biuld();
}
else if (haveTower && (hitInfo.collider.gameObject.GetComponent<Tower>().level) < 3 && bt.cv.GetComponent<Text>().text == "LvUp")
{
Up();
}
else if (haveTower && bt.cv.GetComponent<Text>().text == "Destory")
{
Des();
hitInfo.collider.gameObject.GetComponent<Tower>().level = 0;
}
}
}
}
}
}
大家应该也注意到了,我添加了一个防UI穿透的事件监测。
/// <summary>
/// UI穿透检测,返回穿透了几层UI
/// </summary>
/// <param name="screenPosition"></param>参数为鼠标位置
/// <returns></returns>
public bool IsPointerOverGameObject(Vector2 screenPosition)
{
//实例化点击事件
PointerEventData eventDataCurrentPosition = new PointerEventData(UnityEngine.EventSystems.EventSystem.current);
//将点击位置的屏幕坐标赋值给点击事件
eventDataCurrentPosition.position = new Vector2(screenPosition.x, screenPosition.y);
List<RaycastResult> results = new List<RaycastResult>();
//向点击处发射射线
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
return results.Count > 1;//不计Canvas的那一层,剩下的Ui被点击时,不继续执行常规函数
}
防穿透
因为功能实现之后,发现,点击UI是,发生UI穿透,造成逻辑混乱,于是加上它就好了。
关于Biuld,Destory,Up的逻辑和函数代码我会在下一篇讲解。