目录
14、太阳花UI功能实现
将太阳保存成预制体
同时在GameConf中添加这个预制体
创建一个管理植物的脚本
由于忘了在管理类GridManager.cs中添加单例模式,所以加上
在UIPlantGrid.cs中更新代码
……
public class UIPlantGrid : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerClickHandler
{
……
// 是否可以放置植物
private bool canPlace;
// 是否需要放置植物
private bool wantPlace;
// 用来创建的植物
private GameObject plant;
// 在网格中的植物,是透明的
private GameObject plantInGrid;
public PlantType cardPlantType; // 当前卡片所对应的植物类型
// CanPlace被修改时执行
public bool CanPlace
{
get => canPlace;
set
{
canPlace = value;
if (!canPlace)
{
// 完全遮住,表示不可以控制
maskImg.fillAmount = 1;
// 开始冷却
CDEnter();
}
else
{
maskImg.fillAmount = 0;
}
}
}
// wantPlace被修改时执行
public bool WantPlace
{
get => wantPlace;
set
{
wantPlace = value;
if (wantPlace)
{
// 获取预制体
GameObject tmpPlant = PlantManager.instance.GetPlantForType(PlantType.SunFlower);
// 开始实例化
plant = Instantiate(tmpPlant, Vector3.zero, Quaternion.identity, PlantManager.instance.transform);
}
else
{
Destroy(plant.gameObject);
plant = null;
}
}
}
……
private void Update()
{
// 如果需要放置植物,并且要放置的植物不能为空
if (WantPlace && plant != null)
{
// 让植物跟随我们的鼠标
Vector3 mousePoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
plant.transform.position = new Vector3(mousePoint.x, mousePoint.y, 0);
// 如果我距离网格比较近,需要在网格上出现一个透明的植物,当前鼠标的世界坐标和距离鼠标最近的网格的世界坐标的距离
if (Vector2.Distance(mousePoint, GridManager.instance.GetGridPointByMouse()) < 3)
{
if (plantInGrid == null)
{
plantInGrid = Instantiate(plant, GridManager.instance.GetGridPointByMouse(),
Quaternion.identity, PlantManager.instance.transform);
}
else
{
plantInGrid.transform.position = GridManager.instance.GetGridPointByMouse();
}
}
else
{
if (plantInGrid != null)
{
Destroy(plantInGrid.gameObject);
plantInGrid = null;
}
}
}
}
private void CDEnter()
{
……
}
// 计算冷却时间
IEnumerator CalCD()
{
……
}
// 鼠标移入执行
public void OnPointerEnter(PointerEventData eventData)
{
……
}
// 鼠标移出执行
public void OnPointerExit(PointerEventData eventData)
{
……
}
// 点击后放置植物
public void OnPointerClick(PointerEventData eventData)
{
if (!CanPlace) return;
WantPlace = true;
}
}
测试
15、实现太阳花的放置实现
更新SunFlower.cs代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SunFlower : MonoBehaviour
{
private Animator animator;
private SpriteRenderer spriteRenderer;
private void Start()
{
}
// 查找自身相关组件
private void Find()
{
animator = GetComponent<Animator>();
spriteRenderer = GetComponent<SpriteRenderer>();
}
// 创建时的初始化
public void InitForCreate(bool inGrid)
{
// 获取组件
Find();
// 拖拽时不播放动画
animator.speed = 0;
if (inGrid)
{
spriteRenderer.sortingOrder = -1;
spriteRenderer.color = new Color(1, 1, 1, 0.6f);
}
}
// 放置植物的初始化
public void InitForPlace()
{
// 恢复动画
animator.speed = 1;
spriteRenderer.sortingOrder = 0;
InvokeRepeating("CreateSun",3,3);
}
// 创建阳光
private void CreateSun()
{
// 父物体选择自身
Sun sun = GameObject.Instantiate<GameObject>(GameManager.instance.GameConf.Sun, transform.position, Quaternion.identity,
transform).GetComponent<Sun>();
// 生成阳光后跳跃
sun.JumpAnimation();
}
}
更新UIPlantGrid.cs代码
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngineInternal;
public class UIPlantGrid : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerClickHandler
{
……
// 是否需要放置植物
private bool wantPlace;
// 用来创建的植物
private GameObject plant;
// 在网格中的植物,是透明的
private GameObject plantInGrid;
……
// wantPlace被修改时执行
public bool WantPlace
{
get => wantPlace;
set
{
wantPlace = value;
if (wantPlace)
{
// 获取预制体
GameObject tmpPlant = PlantManager.instance.GetPlantForType(PlantType.SunFlower);
// 开始实例化
plant = Instantiate(tmpPlant, Vector3.zero, Quaternion.identity, PlantManager.instance.transform);
// 不在网格中的植物,也就是拖拽的植物
plant.GetComponent<SunFlower>().InitForCreate(false);
}
else
{
if (plant != null)
{
Destroy(plant.gameObject);
plant = null;
}
}
}
}
private void Start()
{
……
}
private void Update()
{
// 如果需要放置植物,并且要放置的植物不能为空
if (WantPlace && plant != null)
{
// 让植物跟随我们的鼠标
Vector3 mousePoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// 拖拽的植物实时跟着鼠标动
plant.transform.position = new Vector3(mousePoint.x, mousePoint.y, 0);
// 如果我距离网格比较近,需要在网格上出现一个透明的植物,当前鼠标的世界坐标和距离鼠标最近的网格的世界坐标的距离
if (Vector2.Distance(mousePoint, GridManager.instance.GetGridPointByMouse()) < 1.5)
{
if (plantInGrid == null)
{
plantInGrid = Instantiate(plant, GridManager.instance.GetGridPointByMouse(),
Quaternion.identity, PlantManager.instance.transform);
// 在网格中的拟创建的虚拟植物
plantInGrid.GetComponent<SunFlower>().InitForCreate(true);
}
// 由于已经创建,所以只需要改变它的位置到其余网格中
else
{
plantInGrid.transform.position = GridManager.instance.GetGridPointByMouse();
}
}
else
{
if (plantInGrid != null)
{
Destroy(plantInGrid.gameObject);
plantInGrid = null;
}
}
// 如果点击鼠标需要放置植物
if (Input.GetMouseButtonDown(0))
{
// 既然已经点击,那么把拖拽中的植物,放在网格点上
plant.transform.position = GridManager.instance.GetGridPointByMouse();
// 实现真正的放置
plant.GetComponent<SunFlower>().InitForPlace();
// 然后将存储太阳花GameObject的plant清空,和已经放置的植物实际上没有关系了
plant = null;
// 将网格中的虚拟植物销毁
Destroy(plantInGrid.gameObject);
plantInGrid = null;
// 不需要种植了,那么状态改变销毁plant
WantPlace = false;
}
}
}
private void CDEnter()
{
……
}
// 计算冷却时间
IEnumerator CalCD()
{
……
}
// 鼠标移入执行
public void OnPointerEnter(PointerEventData eventData)
{
……
}
// 鼠标移出执行
public void OnPointerExit(PointerEventData eventData)
{
……
}
// 点击后放置植物
public void OnPointerClick(PointerEventData eventData)
{
if (!CanPlace) return;
if (!WantPlace)
{
WantPlace = true;
}
}
}