前言
欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第26篇中,我们将探索如何用unity制作一个unity2d横版卷轴动作类游戏,我会附带项目源码,以便你更好理解它。
本节主要是添加敌人,人物受伤合死亡
添加敌人
素材切片
配置刚体和新增触发器,判断对玩家造成伤害
新增敌人身体碰撞体,碰撞体我们只要在野猪脚下放置一点就可以了,因为他的作用只是不让我们的野猪不掉下去
我们希望敌人身体和敌人身体、敌人身体和玩家之间不发生碰撞,可以去除图层之间的碰撞,注意前面要设置好对应的图层
新增Attack,攻击代码
public class Attack : MonoBehaviour { public int damage; private void OnTriggerStay2D(Collider2D other) { other.GetComponent<Character>()?.TakeDamage(this); } }
给敌人配置代码脚本
新增属性代码,人物和敌人都可以挂载这个代码
public class Character : MonoBehaviour { [Header("基本属性")] public float maxHealth;// 最大生命值 public float currentHealth;// 当前生命值 [Header("受伤无敌")] public float invulnerableDuration;// 无敌持续时间 public 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; //TODO: 死亡逻辑 } } private IEnumerator InvulnerableTimer() { invulnerable = true; // 设为无敌状态 yield return new WaitForSeconds(invulnerableDuration); // 等待无敌持续时间 invulnerable = false; // 取消无敌状态 } }
给玩家配置血量和2秒的无敌
效果,玩家触碰后会扣除当前的血量
受击动画
这里有两种方式
第一种 配置闪烁动画
新增动画图层 混合设置为叠加 权重设置为1
配置闪烁动画,在不同阶段给角色设置不同的透明度
第二种
配置图层为1 覆盖
配置击退动画
触发条件
修改PlayerAnimation
//播放受击动画 public void PlayHurt(){ anim.SetTrigger("hurt"); }
修改Character, 新增受伤事件,传入一个tranform,预留做人物受伤反弹效果
public UnityEvent<Transform> OnTakeDamage; public void TakeDamage(Attack attacker) { if (invulnerable) return; Debug.Log(gameObject.name + "受伤"); if (currentHealth - attacker.damage > 0)// 如果扣除伤害后生命值大于0 { currentHealth -= attacker.damage;// 扣除伤害值 StartCoroutine(InvulnerableTimer()); // 启动无敌状态计时器 //执行受伤 OnTakeDamage?.Invoke(attacker.transform); } else { currentHealth = 0; //TODO: 死亡逻辑 } }
配置
配置闪红效果
效果
受伤击退效果
修改PlayerController,定义受伤击退效果和受伤禁止移动
public float hurtForce;//击退力 public bool isHurt;//是否受伤 private void FixedUpdate() { //受伤禁止移动 if(!isHurt) Move(); } //击退 public void GetHurt(Transform attacker){ isHurt = true; rb.velocity = Vector2.zero; Vector2 dir = new Vector2((transform.position.x - attacker.position.x), 0).normalized; rb.AddForce(dir * hurtForce, ForceMode2D.Impulse); }
配置
运行测试会,发现人物停不下来而且无法操作,那是因为我们把isHurt=true之后,并没有地方将他还原回false
我们可以在animator创建动画状态机控制
在动画播放完时,设置isHurt我为false
效果
人物死亡
配置死亡动画 和过渡条件
重新开始游戏玩家想要活过来,所以需要退出
修改Character
public UnityEvent OnDie; public void TakeDamage(Attack attacker) { if (invulnerable) return; Debug.Log(gameObject.name + "受伤"); if (currentHealth - attacker.damage > 0)// 如果扣除伤害后生命值大于0 { currentHealth -= attacker.damage;// 扣除伤害值 StartCoroutine(InvulnerableTimer()); // 启动无敌状态计时器 //执行受伤 OnTakeDamage?.Invoke(attacker.transform); } else { currentHealth = 0; // 死亡逻辑 OnDie?.Invoke(); } }
修改PlayerController,死亡禁止玩家操作
public bool isDead;//是否死亡 //死亡 public void PlayerDead(){ isDead = true; inputControl.Player.Disable(); }
修改PlayerAnimation,播放死亡动画
private PlayerController playerController; playerController = GetComponent<PlayerController>(); public void SetAnimation() { // 。。。 anim.SetBool("isDead", playerController.isDead); }
配置
记得取消死亡动画循环播放
效果
源码
源码不出意外的话我会放在最后一节