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

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>();
}
}
}
}