前言
本节主要实现植物和僵尸的攻击,阳光数和拾取阳光,卡牌拖拽优化,天上掉落阳光。
攻击
新增Attack,攻击代码
public class Attack : MonoBehaviour { public int damage; private void OnTriggerStay2D(Collider2D other) { other.GetComponent<Character>()?.TakeDamage(this); } }
新增Character属性代码,人物和敌人都可以挂载这个代码
public class Character : MonoBehaviour { [Header("基本属性")] public float maxHealth;// 最大生命值 private float currentHealth;// 当前生命值 [Header("受伤无敌")] public float invulnerableDuration;// 无敌持续时间 private bool invulnerable;// 是否处于无敌状态 private void Start() { currentHealth = maxHealth;// 初始化当前生命值为最大生命值 } public void TakeDamage(Attack attacker) { if (invulnerable) return; if (currentHealth - attacker.damage > 0)// 如果扣除伤害后生命值大于0 { currentHealth -= attacker.damage;// 扣除伤害值 StartCoroutine(InvulnerableTimer()); // 启动无敌状态计时器 } else { currentHealth = 0; } } private IEnumerator InvulnerableTimer() { invulnerable = true; // 设为无敌状态 yield return new WaitForSeconds(invulnerableDuration); // 等待无敌持续时间 invulnerable = false; // 取消无敌状态 } }
僵尸配置
植物和子弹配置
记得还要配置碰撞层级
效果
阳光数和拾取阳光
新增GameManager,管理阳光数,挂载一个空物体上
public class GameManager : MonoBehaviour { public static GameManager Instance { get; private set;} public int sunSum;//阳光总数 private void Awake() { Instance = this; } public void SetSunSum(int num){ sunSum += num; UIManager.Instance.Init(); } }
新增UIManager,控制阳光显示,,挂载一个空物体上
public class UIManager : MonoBehaviour { public static UIManager Instance { get; private set;} public TextMeshProUGUI sunSumText; private void Awake() { Instance = this; } private void Start() { Init(); } public void Init(){ sunSumText.text = GameManager.Instance.sunSum.ToString(); } }
修改Sun,拾取阳光,增加总阳光数
public class Sun : MonoBehaviour { //。。。 public int sun; //当鼠标或手指经过物体时触发 public void OnMouseOver() { Debug.Log("经过阳光"); GameManager.Instance.SetSunSum(sun); Destroy(gameObject); } }
配置,记得给阳光添加触发器,不然可能没效果
效果
卡牌拖拽优化
修改Card,阳光是否充足判断和放置植物扣除阳光
//。。。 void UpdateDarkBg() { if (progressBar.GetComponent<Image>().fillAmount == 0 && GameManager.Instance.sunSum >= useSun) { darkBg.SetActive(false); } else { darkBg.SetActive(true); } } //开始拖拽 public void OnBeginDrag(PointerEventData eventData) { Debug.Log("开始拖拽"); if (progressBar.GetComponent<Image>().fillAmount != 0 || GameManager.Instance.sunSum < useSun) return; //。。。 } //拖拽结束 public void OnEndDrag(PointerEventData eventData) { Debug.Log("拖拽结束"); //。。。 if (hit.collider != null && hit.collider.transform.childCount == 0) { //。。。 //扣除阳光 GameManager.Instance.SetSunSum(-useSun); } else { Destroy(thisObject); } }
效果
天上掉落阳光
修改Sun
public class Sun : MonoBehaviour { public float interval; //间隔 public int sun; public Vector3 targetPos;//目标位置 public float speed = 0.1f;//掉落速度 private bool isDestroy;//是否已经执行销毁计时 private void Update() { if (targetPos != Vector3.zero && Vector3.Distance(targetPos, transform.position) > 0.1f) { transform.position = Vector3.MoveTowards(transform.position, targetPos, speed); }else{ if(isDestroy == false) StartCoroutine(SetDestroy()); } } IEnumerator SetDestroy() { isDestroy = true; yield return new WaitForSeconds(interval); // 等待interval秒 Destroy(gameObject); } //当鼠标或手指经过物体时触发 public void OnMouseOver() { Debug.Log("经过阳光"); GameManager.Instance.SetSunSum(sun); Destroy(gameObject); } //设置目标位置 public void SetTargetPos(Vector3 pos) { targetPos = pos; } }
修改GameManager
private void Start() { //重复执行 InvokeRepeating("CreateSunDown", 10, 10); } //顶部随机位置创建掉落阳光 public void CreateSunDown() { //获取左下角、右上角的世界坐标 Vector3 leftBottom = Camera.main.ViewportToWorldPoint(Vector2.zero); Vector3 rightTop = Camera.main.ViewportToWorldPoint(Vector2.one); float x = Random.Range(leftBottom.x + 50, rightTop.x - 50); Vector3 bornPos = new Vector3(x, rightTop.y, 0); GameObject sun = Instantiate(sunPrefab, bornPos, Quaternion.identity); float y = Random.Range(leftBottom.y + 50, rightTop.y - 120); sun.GetComponent<Sun>().SetTargetPos(new Vector3(x, y, 0)); }
效果,这里为了测试,把掉落频率调高了
源码
源码不出意外的话我会放在最后一节