Unity实战案例全解析:PVZ 植物放置分析

前篇: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();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值