当前位置:   article > 正文

[Unity2D入门教程]简单制作仿植物大战僵尸游戏之⑥制作游戏失败和成功后执行的代码_unity 2d教程

unity 2d教程

在创建完我们所需要的敌人和防御者以后,我们还要为我们游戏场景添加失败和成功后添加新的Canvas以及播放下一关的场景,我们现在就来实现一下吧

制作游戏成功:

首先创建一个Canvas叫Level Complete Canvas,然后给它添加文字和阴影图片

除此之外我们还要在之前的Main Canvas(之前的,改了个名而已)创建新UI Slider,然后把Handle部分换一张SPrite比如狐狸那张,然后改变background和fill的颜色

 

制作失败的Canvas:

前面的和成功的Canvas一样,唯一不同的是要创建两个Button,一个是返回一个是重新开始本关

因此我们要创建两个Public方法供Button调用,这里我们创建个空对象就叫LevelController来管理我们的关卡

给它一个同名的脚本:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class LevelController : MonoBehaviour
  5. {
  6. [SerializeField] float waitToLoad = 3f;
  7. [SerializeField] GameObject winLabel;
  8. [SerializeField] GameObject lostLabel;
  9. int numberOfAttackers = 0;
  10. bool levelTimerFinished = false; //判断滑动条的Value是否到1
  11. private void Start()
  12. {
  13. //先把输赢的canvas隐藏
  14. winLabel.SetActive(false);
  15. lostLabel.SetActive(false);
  16. }
  17. public void AttackerSpawn() //给Attacker调用
  18. {
  19. numberOfAttackers++;
  20. }
  21. public void AttackerKilled() //同样给attacker调用
  22. {
  23. numberOfAttackers--;
  24. if (numberOfAttackers <= 0 && levelTimerFinished)
  25. {
  26. StartCoroutine(HandleWinCondition());
  27. }
  28. }
  29. IEnumerator HandleWinCondition() //当关卡成功时候
  30. {
  31. winLabel.SetActive(true);
  32. GetComponent<AudioSource>().Play();
  33. yield return new WaitForSeconds(waitToLoad);
  34. FindObjectOfType<LevelLoader>().LoadNextScene();
  35. }
  36. public void HandleLoseCondition() //当关卡失败后
  37. {
  38. lostLabel.SetActive(true);
  39. Time.timeScale = 0;
  40. }
  41. public void LevelTimerFinished() //滑动条的值为1时候
  42. {
  43. levelTimerFinished = true;
  44. StopSpawners();
  45. }
  46. private void StopSpawners() //停止生产敌人
  47. {
  48. AttackSpawner[] spawnArray = FindObjectsOfType<AttackSpawner>();
  49. foreach (var spawner in spawnArray)
  50. {
  51. spawner.StopSpawning();
  52. }
  53. }
  54. }

然后再挂载到上面

那我们怎么判断关卡是不是失败呢?和植物大战僵尸一样,当进入房子的敌人超过一定数量时游戏直接判负,显示游戏失败。 这里用一个空对象给它一个Trigger

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class DamageCollider : MonoBehaviour
  5. {
  6. private void OnTriggerEnter2D(Collider2D other)
  7. {
  8. FindObjectOfType<Lives>().TakeLife();
  9. }
  10. }

在Main Canvas时我们又创建一个Text

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. public class Lives : MonoBehaviour
  6. {
  7. [SerializeField] int damage = 1;
  8. [SerializeField] int lives = 5;
  9. Text livesText;
  10. private void Start()
  11. {
  12. livesText = GetComponent<Text>();
  13. UpdateDisplay();
  14. }
  15. private void UpdateDisplay()
  16. {
  17. livesText.text = lives.ToString();
  18. }
  19. public void TakeLife()
  20. {
  21. lives -= damage;
  22. UpdateDisplay();
  23. if (lives <= 0)
  24. {
  25. FindObjectOfType<LevelController>().HandleLoseCondition();
  26. //FindObjectOfType<LevelLoader>().LoadYouLose();
  27. }
  28. }
  29. }

之前的LevelLoader已经不需要了,取而代之的是LevelController

 制作完以上两点后,我们也可以设置一个让不同路生成不同种类的敌人。用数组的形式在AttackerSpawner上

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class AttackSpawner : MonoBehaviour
  5. {
  6. [SerializeField] Attacker[] attackPrefabArray;
  7. [SerializeField] float minSpawnDelay = 1f;
  8. [SerializeField] float maxSpawnDelay = 5f;
  9. bool spawn = true;
  10. IEnumerator Start()
  11. {
  12. while (spawn)
  13. {
  14. yield return new WaitForSeconds(Random.Range(minSpawnDelay, maxSpawnDelay)); //延迟生成Attacker对象
  15. SpawnAttack();
  16. }
  17. }
  18. private void SpawnAttack()
  19. {
  20. var attackerIndex = Random.Range(0, attackPrefabArray.Length);
  21. Spawn(attackPrefabArray[attackerIndex]);
  22. }
  23. public void StopSpawning()
  24. {
  25. spawn = false;
  26. }
  27. private void Spawn(Attacker myAttacker)
  28. {
  29. Attacker newattacker = Instantiate(myAttacker, transform.position, transform.rotation) as Attacker;
  30. newattacker.transform.SetParent(transform); //并把对象转化为我们Spawenr的子对象,简化hierarchy窗口
  31. }
  32. }
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. public class Attacker : MonoBehaviour
  6. {
  7. GameObject currentTarget;
  8. [Range(0, 5)]
  9. float currentSpeed = 1f;
  10. private void Awake()
  11. {
  12. FindObjectOfType<LevelController>().AttackerSpawn();
  13. }
  14. private void OnDestroy()
  15. {
  16. LevelController level = FindObjectOfType<LevelController>();
  17. if (level != null)
  18. {
  19. level.AttackerKilled();
  20. }
  21. }
  22. void Update()
  23. {
  24. transform.Translate(Vector2.left * currentSpeed * Time.deltaTime);
  25. UpdateAnimationState();
  26. }
  27. private void UpdateAnimationState()
  28. {
  29. if (!currentTarget)
  30. {
  31. GetComponent<Animator>().SetBool("isAttacking", false);
  32. }
  33. }
  34. public void SetMovementSpeed(float speed)
  35. {
  36. currentSpeed = speed;
  37. }
  38. public void Attack(GameObject target)
  39. {
  40. GetComponent<Animator>().SetBool("isAttacking", true); //播放吃植物动画
  41. currentTarget = target;//锁定植物
  42. }
  43. public void StrikeCurrentTarget(float damage)
  44. {
  45. if (!currentTarget) return;
  46. Health health = currentTarget.GetComponent<Health>();
  47. if (health)
  48. {
  49. health.DealDamage(damage);//扣植物的血
  50. }
  51. }
  52. }

游戏效果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/770482
推荐阅读
相关标签
  

闽ICP备14008679号