一、整体思路
当植物栏的植物处于可以种植状态,这个时候植物UI身上有button组件。在被button的事件监听的函数中,调用种植植物的处理函数。
种植的过程:鼠标点击植物栏的对应植物的UI,这个时候生成一个可以跟随鼠标位置移动的植物预制体(此处的植物预制体不是UI预制体,是可以种植到场景中发挥作用的植物预制体)。当植物处于跟随鼠标的状态时,要禁止一些功能的启用(如:动画不能播放,will complete。)
二、具体实现
1.植物状态:
将植物设置为两种状态,一种是Disable状态--表示植物当前在跟随鼠标移动,有些功能不用启动。一种是Enable状态--表示植物种植了,所有功能都需要启动。创建一个脚本Plant控制植物状态的切换(挂载到植物物体身上,当植物UI被点击时,植物被实例化)。
2.植物的点击生成:
检测植物UI是可种植状态,当button监听到该植物UI 被点击后,实例化一个对应的植物。因为该脚本应该是管控所有的植物而不是一个,所以应该单独创建一个脚本(HandManger)。既然是管理所有植物,就要想办法判断要生成的植物具体是哪个。实现思路,当具体植物的UI被点击后,让其监听的Onclick函数调用HandManger脚本中的某个函数,让其独有信息传过去,并且在HandManger脚本中对其独有信息进行匹配,匹配到了就生成。
3.各个脚本的意义
植物ImageUI脚本(Card Control):控制所能见到的信息(不同显示效果的切换),存放了植物类型的信息PlantType枚举类型(将鼠标点击的植物信息共享出来--让Hand Manger使用)。
Plant脚本:挂载到植物身上,限定植物的类型Plant Type。实现植物状态的切换PlantState。
Hand Manger脚本:控制植物的实例化,控制植物跟随鼠标。根据ImageUI的植物信息,匹配Plant的信息,实例化对应的Plant。
三、具体代码
1.更新了day01中的Card Control中的部分代码
public void Onclick()
{
if (needSun > SunManger.instance.SunPoint) return;
//TODO 当被点击时,阳光减少,并种植
bool isSuccess = HandManger.instance.AddPlant(plantType);
if(isSuccess)
{
//HandManger.instance.FollowCursor();
SunManger.instance.Subsun(needSun);
//状态进入冷却
TransitionToCooling();
}
}
}
2.Plant脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static CardControl;
public class Plant : MonoBehaviour
{
// Start is called before the first frame update
enum PlantState
{
Disable,
Enable,
}
PlantState plantState = PlantState.Disable;
public PlantType plantType = PlantType.Sunflower;
void Start()
{
TransitionToDiable();
}
// Update is called once per frame
void Update()
{
switch (plantState)
{
case PlantState.Disable:
UpdateDisable();
break;
case PlantState.Enable:
UpdateEnable();
break;
default:
break;
}
}
void UpdateDisable()
{
}
void UpdateEnable()
{
}
void TransitionToDiable()
{
plantState = PlantState.Disable;
gameObject.GetComponent<Animator>().enabled = false;
}
}
3.Hand Manger脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static CardControl;
public class HandManger : MonoBehaviour
{
// Start is called before the first frame update
public static HandManger instance { get; private set; }
public List<Plant> plantPrefabList;
private GameObject currentPlant;
private void Awake()
{
instance = this;
}
void Start()
{
}
// Update is called once per frame
void Update()
{
FollowCursor();
}
public bool AddPlant(PlantType plantType)
{
if(currentPlant != null)
{
return false;
}
Plant plant = GetPlantPrefab(plantType);
if(plant == null)
{
print("植物不存在");return false;
}
currentPlant = GameObject.Instantiate(plant.gameObject);
return false;
}
private Plant GetPlantPrefab(PlantType plantType)
{
foreach (Plant plant in plantPrefabList)
{
if (plant.plantType == plantType)
{
//返回该植物Plant组件
return plant;
}print("检测一次");
}return null;
}
public void FollowCursor()
{
if (currentPlant == null) return;
Vector3 mouseWorldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mouseWorldPosition.z = 0;
currentPlant.transform.position = mouseWorldPosition;
}
}