本章节修复了骷髅在玩家死亡后依旧进行攻击,为骷髅添加了随机快慢攻击
源代码
SkeletonBattleState.cs
using UnityEngine;
public class SkeletonBattleState : EnemyState
{
private Transform player;
private Enemy_Skeleton enemy;
private int moveDir;
public SkeletonBattleState(Enemy _enemyBase, EnemyStateMachine _stateMachine, string _animBoolName, Enemy_Skeleton _enemy) : base(_enemyBase, _stateMachine, _animBoolName)
{
this.enemy = _enemy;
}
public override void Enter()
{
base.Enter();
player = PlayerManager.instance.player.transform;
//玩家死亡时无法攻击玩家尸体
if (player.GetComponent<PlayerStats>().isDead)
stateMachine.ChangeState(enemy.moveState);
}
public override void Exit()
{
base.Exit();
}
public override void Update()
{
base.Update();
if (enemy.IsPlayerDetected())
{
stateTimer = enemy.battleTime;
if (enemy.IsPlayerDetected().distance < enemy.attackDistance)
{
if (CanAttack())
{
stateMachine.ChangeState(enemy.attackState);
}
}
}
else
{
if (stateTimer < 0 || Vector2.Distance(player.transform.position, enemy.transform.position) > enemy.abandonDistance)
{
stateMachine.ChangeState(enemy.idleState);
}
}
if (player.position.x > enemy.transform.position.x)
{
moveDir = 1;
}
else if (player.position.x < enemy.transform.position.x)
{
moveDir = -1;
}
enemy.SetVelocity(moveDir * enemy.moveSpeed, enemy.rb.velocity.y);
}
private bool CanAttack()
{
if (Time.time >= enemy.lastTimeAttacked + enemy.attackCooldown)
{
//随机攻击冷却时间
enemy.attackCooldown = Random.Range(enemy.minAttackCooldown, enemy.maxAttackCooldown);
return true;
}
return false;
}
}
Enemy.cs
新增两个变量
public float minAttackCooldown;
public float maxAttackCooldown;
完整代码
using System.Collections;
using UnityEngine;
public class Enemy : Entity
{
[SerializeField] protected LayerMask whatIsPlayer;
[Header("Stunned info")]
public float stunDuration;
public Vector2 stunDirection;
protected bool canBeStunned;
[SerializeField] protected GameObject counterImage;
[Header("Move info")]
public float moveSpeed;
public float idleTiem;
public float battleTime;
private float defaultMoveSpeed;
public float abandonDistance;
public float attantionDistance;
[Header("Attack info")]
public float attackDistance;
public float attackCooldown;
public float minAttackCooldown;
public float maxAttackCooldown;
[HideInInspector] public float lastTimeAttacked;
public EnemyStateMachine stateMachine { get; private set; }
public string lastAnimBoolName { get; private set; }
protected override void Awake()
{
base.Awake();
stateMachine = new EnemyStateMachine();
defaultMoveSpeed = moveSpeed;
}
protected override void Update()
{
base.Update();
stateMachine.currentState.Update();
}
public virtual void AssignLastAnimName(string _animBoolName) => lastAnimBoolName = _animBoolName;
public override void SlowEnitityBy(float _slowPercentage, float _slowDuration)
{
base.SlowEnitityBy(_slowPercentage, _slowDuration);
moveSpeed = moveSpeed * (1 - _slowPercentage);
anim.speed = anim.speed * (1 - _slowPercentage);
Invoke("ReturnDefaultSpeed", _slowDuration);
}
public override void ReturnDefaultSpeed()
{
base.ReturnDefaultSpeed();
moveSpeed = defaultMoveSpeed;
}
public virtual void FreezeTime(bool _timeFrozen)
{
if (_timeFrozen)
{
moveSpeed = 0;
anim.speed = 0;
}
else
{
moveSpeed = defaultMoveSpeed;
anim.speed = 1;
}
}
public virtual void FreezeTimeFor(float _duration) => StartCoroutine(FreezeTimeCoroutine(_duration));
protected virtual IEnumerator FreezeTimeCoroutine(float _seconds)
{
FreezeTime(true);
yield return new WaitForSeconds(_seconds);
FreezeTime(false);
}
#region Counter Attack Window
public virtual void OpenCounterAttackWindow()
{
canBeStunned = true;
counterImage.SetActive(true);
}
public virtual void CloseCounterAttackWindow()
{
canBeStunned = false;
counterImage.SetActive(false);
}
#endregion
public virtual bool CanBeStunned()
{
if (canBeStunned)
{
CloseCounterAttackWindow();
return true;
}
return false;
}
public virtual void AnimationFinishTrigger() => stateMachine.currentState.AnimationFinishTrigger();
public virtual RaycastHit2D IsPlayerDetected() => Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, 50, whatIsPlayer);
protected override void OnDrawGizmos()
{
base.OnDrawGizmos();
Gizmos.color = Color.yellow;
Gizmos.DrawLine(transform.position, new Vector3(transform.position.x + attackDistance * facingDir, transform.position.y));
}
}