前篇:Unity实战案例全解析:PVZ 植物卡片状态分析-CSDN博客
植物应该如何从卡牌状态转为实物?
其实就只需要考虑两个步骤加一个后续处理:
1.点击卡牌后就实例化
需要一个植物状态枚举,因为卡牌分为拿在手上和种植下去两种状态
//植物状态枚举
enum PlantsState {
Disable,
Enable
}
public class Plants : MonoBehaviour {
//拿到植物类型
public PlantType plantType;
PlantsState plantsState = PlantsState.Disable;
private void Awake() {
plantType = PlantType.Sun_Flower;
Translate2Disable();
}
private void Update() {
switch (plantsState) {
case PlantsState.Disable:
PlantDisableUpdate();
break;
case PlantsState.Enable:
PlantEnableUpdate();
break;
default:
break;
}
}
protected virtual void PlantEnableUpdate() {
}
protected virtual void PlantDisableUpdate() {
}
public void Translate2Disable() {
Debug.Log("关闭");
plantsState = PlantsState.Disable;
GetComponent<Animator>().enabled = false;
}
public void Translate2Enable() {
Debug.Log("开启");
plantsState = PlantsState.Enable;
GetComponent<Animator>().enabled = true;
}
}
同时可以创建一个放置管理器,创建一个List表存放植物
GetPlant是获取植物的类型
Addplant是为了获取并实例化该植物
FllowHand是为了将植物跟随鼠标,同时关闭植物的功能
OnClick里调用了Cell脚本的种植方法,将植物种下去
public class HandManger : MonoBehaviour
{
private static HandManger instance;
private HandManger() {
instance = this;
}
public static HandManger Instance => instance;
//植物预制体列表
public List<Plants> plantsPrefabList;
//当前鼠标内的植物
private Plants currentPlant;
private void Update() {
FllowHand();
}
//添加植物方法,并且加入一个返回值用来判断当前手上是否有植物
public bool AddPlant(PlantType plantType)
{
if(currentPlant != null) return false;
//获取植物
Plants plants =GetPlant(plantType);
if (plants == null)
{
Debug.Log("未得到对应类型的植物"); return false;
}
//实例化对应植物
currentPlant =GameObject.Instantiate(plants);
return true;
}
//判断类型获取植物类型
private Plants GetPlant(PlantType plantType)
{
foreach (Plants item in plantsPrefabList) {
if(item.plantType == plantType)
{
return item;
}
}
return null;
}
//跟随鼠标
private void FllowHand() {
if(currentPlant ==null) return;
//放在鼠标上的时候,不要有动画
currentPlant.Translate2Disable();
Vector3 handPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
handPos.z= 0;
currentPlant.transform.position = handPos;
}
//种植到单元格内
public void OnCellClick(Cell cells) {
if (currentPlant == null)
return ;
bool isPlaned = cells.AddPlant(currentPlant);
//种植成功
if(isPlaned ==true)
currentPlant = null;
}
}
2.放到草地上,同时开启其功能
草地的实现就是设置一个个碰撞器作为网格,考虑使用mesh组件,不然太多的碰撞器会消耗性能
Cell表示单元格,放到草地上就是将鼠标上的对象坐标转为单元格的坐标(因为单元格锚点默认在中心,可以在组件中调整)
该脚本的AddPlant是种植方法,但是没有触发就只能算是预处理
public class Cell : MonoBehaviour
{
//检查单元格内是否有植物
public Plants CellCurrentPlant;
//放置植物到单元格内
private void OnMouseDown() {
HandManger.Instance.OnCellClick(this);
}
//为单元格添加植物
public bool AddPlant(Plants plants)
{
if(CellCurrentPlant != null) {
return false;
}
CellCurrentPlant = plants;
CellCurrentPlant.transform.position = transform.position;
plants.Translate2Enable();
return true;
}
}
3.处理阳光消耗
这个函数是写在卡牌切换的脚本之中的,needSunPoint是植物卡牌上的所需要阳光数,可以对不同卡牌进行不同设置,其实就是一个植物卡牌的模板,修改一下皮肤,修改一下数值就算是新的植物了
public void OnClick()
{
//阳光不够则什么也不发生
if (needSunPoint > SunManger.Instance.SunPoint)
return;
//触发植物种植,如果植物被成功种下才触发减少阳光和进入cd状态
bool isSuccessPlant = HandManger.Instance.AddPlant(plantType);
if(isSuccessPlant == true)
{
//触发减少阳光
SunManger.Instance.SubSun(needSunPoint);
//转入cd状态
Translate2Cd();
}
}