攻击的逻辑就是,当我们操控的角色播放攻击动画时触碰到了敌人,就造成了攻击。因此可以把攻击拆分为两部分,第一部分是如何触发敌人受到攻击的判定,第二部分是敌人的受击反馈。这两部分是可以分开实现的。

实现攻击判定

攻击判定说白了就是我们希望能够捕捉到玩家的攻击动作的图片和敌人图片发生了碰撞的事件,OnTriggerEnter2D函数就很适合这个任务。

OnTriggerEnter2D

OnTriggerEnter2D 是 Unity 中用于2D物理触发器检测的回调函数。

image-20250527114723437

作用

当一个带有 Collider2DisTriggertrue 的物体,与另一个带有 Collider2DRigidbody2D 的物体发生重叠时,Unity 会自动调用这个函数。就

函数签名

1
void OnTriggerEnter2D(Collider2D collision)
  • collision 参数表示进入触发器的另一个碰撞体。

常见用途

  • 检测攻击命中,当敌人的碰撞体进入到玩家攻击的碰撞体时,就触发了玩家的OnTriggerEnter2D函数,玩家根据传入的collision参数就可以触发敌人身上的代码。
  • 检测角色进入某个区域(如陷阱、拾取物品等)。

Attack脚本

我们实现一个Attack脚本,包含了攻击的一些属性和OnTrigger方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Attack : MonoBehaviour
{
public float damage; //攻击造成的伤害
public float power; //攻击的击退力,和受击反馈相关
public int dir; //攻击的方向,也就是敌人被击中后后退的反方向

private Entity attacker; //发动攻击的对象

void Awake()
{
attacker = GetComponentInParent<Entity>();

}

void OnTriggerEnter2D(Collider2D collision)
{
Entity rival = collision.GetComponent<Entity>(); //通过collision拿到受到攻击的对象
dir = attacker.facingDir; //攻击的方向
if (rival != null)
rival.TakeDamage(this); //触发受击者的受击反馈,在后面实现
}
}

添加攻击判定框

在Animator下添加AttackArea子物体,AttackArea在默认情况下不勾选生效,为它添加Collider2D,记得勾选isTrigger。接着在动画窗口,通过AddProperty为动画添加关键帧属性,选择合适的动画帧为它添加关键帧,让AttackArea生效,以及调整攻击判定框的位置和大小。再将Attack脚本挂载到AttackArea。

image-20250527120139440

实现思路

  • 通过给角色添加带有Collider2D以及重写了OnTriggerEnter方法的脚本的子物体,实现区别于玩家本体的攻击碰撞判定。
  • 使用动画关键帧技术达到限制攻击检测出现时机的效果。

实现受击反馈

因为受到攻击是所有游戏内人物共有行为,因此我们将TakeDamage函数写在Entity中。

1
2
3
4
public virtual void TakeDamage(Attack attack)
{
Debug.Log(this.name+"Take Damage");
}

在Skeleton中重写

1
2
3
4
5
6
7
public override void TakeDamage(Attack attack)
{
SetZeroVelocity();
rigidBody.AddForce(new Vector2(attack.power * attack.dir, 0), ForceMode2D.Impulse);
fxAnimator.SetTrigger("TakeDamage");
stateMachine.ChangeState(hurtState);
}