当前位置:   article > 正文

[Unity2D入门教程]简单制作仿植物大战僵尸游戏之⑤制作更多的敌人Attacker以及防御者Defender_unity 2d教程

unity 2d教程

制作更多的Defender:

  之前我们创建了一个向日葵和一个仙人掌,今天我们多创建两个

  首先是一个老头Gnome,我们让它的功能和仙人掌一样,所以我会尽量快点讲完,

 需要给它三个脚本Defender,Shooter,Health

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Defender : MonoBehaviour
  5. {
  6. [SerializeField] int starCost = 100;
  7. public int GetStarCost()
  8. {
  9. return starCost;
  10. }
  11. public void AddStars(int amount)
  12. {
  13. FindObjectOfType<StarsDisplay>().AddStars(amount);
  14. }
  15. }

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. public class Shooter : MonoBehaviour
  6. {
  7. [SerializeField] GameObject projectTile;
  8. [SerializeField] GameObject gun;
  9. AttackSpawner myLaneSpawner;
  10. Animator animator;
  11. private void Start()
  12. {
  13. animator = GetComponent<Animator>();
  14. SetLaneSpawner();
  15. }
  16. private void Update()
  17. {
  18. if(IsAttackerInLand())
  19. {
  20. animator.SetBool("isAttacking", true);
  21. }
  22. else
  23. {
  24. animator.SetBool("isAttacking", false);
  25. }
  26. }
  27. private void SetLaneSpawner()
  28. {
  29. AttackSpawner[] spawners = FindObjectsOfType<AttackSpawner>();
  30. //找到这行路的所有敌人
  31. foreach(var spawner in spawners)
  32. {
  33. //判断是不是在我们这一行
  34. bool IsCloseEnough = (Mathf.Abs( spawner.transform.position.y - transform.position.y ) <= Mathf.Epsilon);
  35. if (IsCloseEnough)
  36. {
  37. myLaneSpawner = spawner; //找到我这条路的生成敌人
  38. }
  39. }
  40. }
  41. private bool IsAttackerInLand()
  42. {
  43. //如果我这条路上的敌人数量小于等于0return false
  44. if(myLaneSpawner.transform.childCount <= 0)
  45. {
  46. return false;
  47. }
  48. else
  49. {
  50. return true;
  51. }
  52. }
  53. public void Fire()
  54. {
  55. Instantiate(projectTile, gun.transform.position, transform.rotation); //生成子弹
  56. }
  57. }

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. public class Health : MonoBehaviour
  6. {
  7. [SerializeField] float health = 100f;
  8. [SerializeField] GameObject deathVFX;
  9. public void DealDamage(float damage)
  10. {
  11. health -= damage;
  12. if(health <= 0)
  13. {
  14. TriggerDeathVFX();
  15. Destroy(gameObject);
  16. }
  17. }
  18. //生成爆炸特效
  19. private void TriggerDeathVFX()
  20. {
  21. if (!deathVFX) return;
  22. GameObject deathVFXObject = Instantiate(deathVFX, transform.position, transform.rotation);
  23. Destroy(deathVFXObject, 1f); //1秒后销毁生成的爆炸特效
  24. }
  25. }

然后给它碰撞框和动画并把参数都填上去后我们给它一个空对象Body创建组件Sprite Renderer。通过改变它的Sprite来制造动画。

斧头的Prefab如下

动画就让他旋转365°

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Projectile : MonoBehaviour
  5. {
  6. [SerializeField] float speed = 1f;
  7. [SerializeField] float damage = 50f;
  8. void Update()
  9. {
  10. transform.Translate(Vector2.right * speed * Time.deltaTime);
  11. }
  12. private void OnTriggerEnter2D(Collider2D other)
  13. {
  14. var health = other.GetComponent<Health>();
  15. var attacker = other.GetComponent<Attacker>();
  16. if(attacker && health)
  17. {
  18. health.DealDamage(damage);
  19. Destroy(gameObject);
  20. }
  21. }
  22. }

然后我们来创建一个墓碑GraveStone,相当于高坚果,它的血量非常厚可以挡住很久

除了前面的脚本还要给他一个独特的脚本,但只是给之后我们创建的敌人识别的

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class GraveStone : MonoBehaviour
  5. {
  6. private void OnTriggerStay2D(Collider2D other)
  7. {
  8. Attacker attacker = other.GetComponent<Attacker>();
  9. if (attacker)
  10. {
  11. }
  12. }
  13. }

给它做个动画就稍微改变一下它的Scale值

最后,别忘了把他们放到我们之前创建的Quad中

创建敌人:

  在创建新的敌人之前,我们需要让敌人都实现能吃植物的动画,因此我们创建一个鳄鱼的吃植物动画Lizard Attack把对应的素材拖进ANimation

我们选择添加动画事件,当执行那一帧的时候植物掉血。

吃植物时候速度为0 

这个是一口多少血

 

 创建一个Lizard给它

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Lizard : MonoBehaviour
  5. {
  6. private void OnTriggerEnter2D(Collider2D other)
  7. {
  8. GameObject otherGameObject = other.gameObject;
  9. if (otherGameObject.GetComponent<Defender>())
  10. {
  11. GetComponent<Attacker>().Attack(otherGameObject);
  12. }
  13. }
  14. }

Attacker脚本更新后如下:

  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. }

在完成了鳄鱼后,我们要创建一个特别的狐狸敌人:

同样先给他设置好动画

 给它添加好脚本后添加参数再创建一个名字叫fox的脚本

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Fox : MonoBehaviour
  5. {
  6. private void OnTriggerEnter2D(Collider2D other)
  7. {
  8. GameObject otherGameObject = other.gameObject;
  9. if (otherGameObject.GetComponent<GraveStone>()) //当遇到gravestone时他会跳过去
  10. {
  11. GetComponent<Animator>().SetTrigger("JumpTrigger");
  12. }
  13. else if (otherGameObject.GetComponent<Defender>()) //而其它的他会吃掉
  14. {
  15. GetComponent<Attacker>().Attack(otherGameObject);
  16. }
  17. }
  18. }

 同样我们也要为他创建动画事件

 

 

 


游戏效果:

可见跑的跑跳的跳,鳄鱼直接开吃,最下排的生成敌人给老头两斧头扔死了

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

闽ICP备14008679号