动画
动画状态机改成这样
当 run = true 的时候,从 beeFly 立马切换到 beeChase
当 run = false 的时候,从 beeChase 立马切换到 beeFly
当 hurt 触发的时候,从 Any State 立马切换到 beeHurt,当 beeHurt 完整播放一次之后,进入 Exit
当 attack 触发的时候,从 Any State 立马切换到 beeAttack,当 beeAttack 完整播放一次之后,进入 Exit
当 dead = true 的时候,从 Any State 立马切换到 beeDead
代码
BeeChaseState
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;
public class BeeChaseState : BaseState
{
private Attack attack;
private Vector3 target;
private Vector3 moveDir;
private bool isAttack;
private float attackRateCounter = 0;
public override void OnEnter(Enemy enemy)
{
currentEnemy = enemy;
currentEnemy.currentSpeed = currentEnemy.chaseSpeed;
currentEnemy.anim.SetBool("run", true);
attack = enemy.GetComponent<Attack>();
currentEnemy.lostTimeCounter = currentEnemy.lostTime;
}
public override void LogicUpdate()
{
if (currentEnemy.lostTimeCounter <= 0)
{
currentEnemy.SwitchState(NPCState.Patrol);
}
// attacker.position 是指玩家脚底的位置,这不是我们想要的,所以在 y 轴上要加 1.5
target = new Vector3(currentEnemy.attacker.position.x, currentEnemy.attacker.position.y + 1.5f, 0);
// 判断攻击距离
if ((target - currentEnemy.transform.position).magnitude <= attack.attackRange)
{
// 可以播放攻击动画了
isAttack = true;
// 先让蜜蜂停下来
if (!currentEnemy.isHurt)
{
currentEnemy.rb.velocity = Vector2.zero;
}
// 计时器
attackRateCounter -= Time.deltaTime;
if (attackRateCounter <= 0)
{
currentEnemy.anim.SetTrigger("attack");
attackRateCounter = attack.attackRate;
}
}
else
{
// 超出攻击范围
isAttack = false;
}
// 移动方向 = 目标位置 - 当前位置
moveDir = (target - currentEnemy.transform.position).normalized;
if (moveDir.x > 0)
{
currentEnemy.transform.localScale = new Vector3(
-1 * Mathf.Abs(currentEnemy.transform.localScale.x),
currentEnemy.transform.localScale.y,
currentEnemy.transform.localScale.z
);
}
else if (moveDir.x < 0)
{
currentEnemy.transform.localScale = new Vector3(
Mathf.Abs(currentEnemy.transform.localScale.x),
currentEnemy.transform.localScale.y,
currentEnemy.transform.localScale.z
);
}
}
public override void PhysicsUpdate()
{
if (!currentEnemy.isHurt &&
!currentEnemy.isDead &&
!currentEnemy.wait &&
!isAttack)
{
currentEnemy.rb.velocity = moveDir * currentEnemy.currentSpeed;
}
// 追击过程中是没有 wait 等待的
}
public override void OnExit()
{
currentEnemy.anim.SetBool("run", false);
}
}
OnEnter 的时候,设置敌人、设置速度、播放追逐动画、初始化 Attack 组件(因为 Attack 组件上面有个范围,在范围内的时候需要停下来攻击)、初始化 lostTimeCounter(避免蜜蜂刚进入追逐状态,立马就退出变回巡逻状态)
LogicUpdate 的时候,如果 lostTimeCounter 变 0 了,说明蜜蜂失去目标,返回到巡逻状态。接着蜜蜂和玩家的距离小于攻击范围的时候,就会停下来,并按 attackRate 标识的秒数攻击一次玩家。这个攻击动画需要注意一下,在蜜蜂伸出刺的时候,需要出现触发器,这个触发器上面也要绑定一个 Attack 组件。超出范围之后不进行攻击。同样移动的时候,也需要注意朝向
PhysicsUpdate 的时候,与巡逻时候一样,修改蜜蜂的速度。需要注意一下,攻击的时候也不能动
OnExit 的时候,就把动画状态机从 chase 改回到 patrol 即可
Bee
Bee 的 Awake 里面需要初始化 chaseState
属性
Attack
Character
Attack Point
项目相关代码
代码仓库:https://gitee.com/nbda1121440/2DAdventure.git
标签:攻击,localScale,transform,追击,Attack,蜜蜂,currentEnemy,时候 From: https://www.cnblogs.com/hellozjf/p/18034216