You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.9 KiB
81 lines
2.9 KiB
using System;
|
|
using UnityEngine;
|
|
|
|
[Serializable]
|
|
public class EnemyIdle : State<Character>
|
|
{
|
|
StatData actionDelayStat;
|
|
float actionDelayTime => actionDelayStat != null ? actionDelayStat.Value : 0;
|
|
float actionDelayElapsedTime;
|
|
bool IsInActionDelay => actionDelayTime > actionDelayElapsedTime;
|
|
|
|
StatData attackDistanceStat;
|
|
|
|
EnemyChasePlayer chaseState;
|
|
EnemyAttack attackState;
|
|
EnemyCastSkill castSkillState;
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
Owner.Excutor.Data.TryGetStat(StatID.ActionDelay, out actionDelayStat);
|
|
Owner.Excutor.Data.TryGetStat(StatID.AttackDistance, out attackDistanceStat);
|
|
|
|
Owner.TryGetState(out chaseState);
|
|
Owner.TryGetState(out attackState);
|
|
Owner.TryGetState(out castSkillState);
|
|
|
|
Debug.Assert(chaseState != null, "chase state not exist");
|
|
Debug.Assert(attackState != null, "attack state not exist");
|
|
Debug.Assert(castSkillState != null, "cast skill state not exist");
|
|
|
|
actionDelayElapsedTime = actionDelayTime;
|
|
Debug.Assert(Owner.Excutor.SkeletonAnimation.TryGetAnimation("idle", out Spine.Animation _), "idle animation not exist");
|
|
}
|
|
|
|
public override void Enter()
|
|
{
|
|
Owner.Excutor.IsBattleReady = true;
|
|
Owner.Excutor.SkeletonAnimation.AnimationState.SetAnimation(0, "idle", true);
|
|
}
|
|
|
|
public override void Excute()
|
|
{
|
|
actionDelayElapsedTime = MathF.Min(actionDelayElapsedTime + Time.fixedDeltaTime, actionDelayTime);
|
|
|
|
if (IsInActionDelay) return;
|
|
|
|
if (castSkillState.TryGetCurrentTopSkill(out var topSkill) && !topSkill.IsInCoolTime) // if there is a skill to cast
|
|
{
|
|
topSkill.transform.position = Owner.Excutor.CenterPivot;
|
|
if (topSkill.IsTargetExistInCastRange())
|
|
{
|
|
Owner.ChangeState<EnemyCastSkill>();
|
|
actionDelayElapsedTime = 0f;
|
|
}
|
|
else if (TargetFinder.TryFindNearest(Owner.Excutor.Position, Owner.Excutor.TargetTags, out var nearest))
|
|
{
|
|
chaseState.SetTarget(nearest as Entity, topSkill.CastDistance);
|
|
Owner.ChangeState<EnemyChasePlayer>();
|
|
}
|
|
}
|
|
else if(attackDistanceStat != null)
|
|
{
|
|
if (!TargetFinder.TryFindNearest(Owner.Excutor.Position, Owner.Excutor.TargetTags, out var nearest)) return;
|
|
|
|
float attackDistance = attackDistanceStat.Value;
|
|
|
|
Vector2 to = (nearest as Entity).Position - Owner.Excutor.Position;
|
|
if(to.sqrMagnitude <= attackDistance * attackDistance)
|
|
{
|
|
attackState.Target = nearest;
|
|
Owner.ChangeState<EnemyAttack>();
|
|
actionDelayElapsedTime = 0f;
|
|
}
|
|
else
|
|
{
|
|
chaseState.SetTarget(nearest as Entity, attackDistance);
|
|
Owner.ChangeState<EnemyChasePlayer>();
|
|
}
|
|
}
|
|
}
|
|
}
|