using UnityEngine;
|
|
public class AI_Npc_200 : SampleAI
|
{
|
public AI_Npc_200(GA_NpcClientFightNorm owner, Vector3 bornPosition) : base(owner, bornPosition)
|
{
|
m_SleepTime = .5f;
|
}
|
|
public override void Update()
|
{
|
if (m_Owner.isTalking || m_Owner.isStopAI)
|
{
|
return;
|
}
|
|
// ai休眠时间
|
if (Time.realtimeSinceStartup - m_LastThinkTime > m_SleepTime)
|
{
|
_Thinking();
|
}
|
|
// 是否正在释放技能
|
if (m_Owner.SkillMgr.CurCastSkill != null)
|
{
|
if (m_Owner.SkillMgr.CurCastSkill.SkillCompelete == false)
|
{
|
if (m_Owner.IsIdle())
|
{
|
m_Owner.SkillMgr.CurCastSkill.SkillCompelete = true;
|
}
|
return;
|
}
|
|
if (m_Owner.SkillMgr.CurCastSkill.SkillPreparing)
|
{
|
return;
|
}
|
|
if (m_Owner.NextAction == GAStaticDefine.Act_Warn)
|
{
|
return;
|
}
|
}
|
|
switch (m_AIStatus)
|
{
|
case E_AIStatus.Patrol:
|
_Patrol();
|
break;
|
case E_AIStatus.Attack:
|
_Attack();
|
break;
|
case E_AIStatus.MoveToBornPos:
|
MoveToBornPos();
|
break;
|
}
|
}
|
|
private void MoveToBornPos()
|
{
|
var _dis = MathUtility.DistanceSqrtXZ(m_Owner.Pos, BornPos);
|
if (_dis > 0.1f)
|
{
|
m_Owner.MoveToPosition(BornPos);
|
}
|
else
|
{
|
m_AIStatus = E_AIStatus.Patrol;
|
}
|
}
|
|
private byte atkStep;
|
private Vector3 atkPos;
|
|
private void _Attack()
|
{
|
if (m_AIStatus == E_AIStatus.MoveToBornPos)
|
{
|
return;
|
}
|
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
float _dis;
|
|
switch (atkStep)
|
{
|
case 0:
|
var _skill = m_Owner.SkillMgr.Get(m_BaseAtkSkillID);
|
_dis = _skill.skillInfo.config.AtkDist * .5f;
|
var _compareDis = MathUtility.DistanceSqrtXZ(_hero.Pos, m_Owner.Pos);
|
if (_compareDis < _dis * _dis)
|
{
|
atkStep = 1;
|
m_Owner.StopPathFind();
|
m_Owner.Forward = MathUtility.ForwardXZ(_hero.Pos, m_Owner.Pos);
|
}
|
else
|
{
|
if (m_Owner.posIndex != -1)
|
{
|
HeroRoundGird.Instance.Release(m_Owner.posIndex);
|
m_Owner.posIndex = -1;
|
}
|
var _node = HeroRoundGird.Instance.Request(m_Owner.ServerInstID, m_Owner.Pos, _dis);
|
if (_node != null)
|
{
|
atkPos = HeroRoundGird.Instance.GetRealPos(_node);
|
m_Owner.posIndex = _node.index;
|
}
|
_dis = MathUtility.DistanceSqrtXZ(atkPos, m_Owner.Pos);
|
if (_dis < 0.2f)
|
{
|
atkStep = 1;
|
m_Owner.StopPathFind();
|
m_Owner.Forward = MathUtility.ForwardXZ(_hero.Pos, m_Owner.Pos);
|
}
|
else
|
{
|
atkStep = 2;
|
}
|
}
|
|
break;
|
case 2:
|
_dis = MathUtility.DistanceSqrtXZ(atkPos, m_Owner.Pos);
|
if (_dis < 0.2f)
|
{
|
atkStep = 0;
|
}
|
else
|
{
|
m_Owner.MoveToPosition(atkPos);
|
}
|
break;
|
case 1:
|
if (Time.realtimeSinceStartup - m_LastAttackTime < m_Owner.NpcConfig.AtkInterval * Constants.F_GAMMA)
|
{
|
return;
|
}
|
|
m_Owner.CastSkill(m_BaseAtkSkillID);
|
atkStep = 0;
|
|
m_LastAttackTime = Time.realtimeSinceStartup;
|
|
break;
|
}
|
}
|
|
private byte patrolStep;
|
private float patrolWaitTime;
|
private float patrolWaitRandomTime;
|
private Vector3 randomPos;
|
private void _Patrol()
|
{
|
if (m_AIStatus == E_AIStatus.MoveToBornPos)
|
{
|
return;
|
}
|
|
switch (patrolStep)
|
{
|
case 0:
|
patrolWaitRandomTime = Random.Range(2f, 4f);
|
patrolWaitTime = Time.realtimeSinceStartup;
|
patrolStep = 1;
|
break;
|
case 1:
|
if (Time.realtimeSinceStartup - patrolWaitTime > patrolWaitRandomTime)
|
{
|
patrolStep = 2;
|
patrolWaitTime = Time.realtimeSinceStartup;
|
randomPos = BornPos + new Vector3(Random.Range(-2f, 2f), 0, Random.Range(-2f, 2f));
|
GActor.TryGetValidPos(randomPos, ref randomPos);
|
m_Owner.MoveToPosition(randomPos);
|
}
|
break;
|
case 2:
|
if (Time.realtimeSinceStartup - patrolWaitTime > 2)
|
{
|
patrolStep = 1;
|
}
|
break;
|
}
|
}
|
|
private void _Thinking()
|
{
|
if (m_AIStatus == E_AIStatus.MoveToBornPos)
|
{
|
return;
|
}
|
|
float _compareDis;
|
// 思考
|
var _hero = PlayerDatas.Instance.hero;
|
if (_hero == null || _hero.ActorInfo.serverDie)
|
{
|
// 主角不存在或者死亡了
|
// 在出生点附近
|
_compareDis = MathUtility.DistanceSqrtXZ(BornPos, m_Owner.Pos);
|
if (_compareDis < 4)
|
{
|
m_AIStatus = E_AIStatus.Patrol;
|
}
|
// 巡逻
|
// 不在出生点附近
|
else
|
{
|
// 回到出生点
|
m_AIStatus = E_AIStatus.MoveToBornPos;
|
}
|
}
|
else
|
{
|
_compareDis = MathUtility.DistanceSqrtXZ(m_Owner.Pos, BornPos);
|
|
if (_compareDis > m_KeepBornDistSqrt)
|
{
|
m_AIStatus = E_AIStatus.MoveToBornPos;
|
}
|
else
|
{
|
// 玩家在可见范围内
|
_compareDis = MathUtility.DistanceSqrtXZ(m_Owner.Pos, _hero.Pos);
|
if (_compareDis < m_KeepBornDistSqrt)
|
{
|
// 标识是否执行攻击逻辑
|
bool _doAttack = false;
|
// 自己是主动怪
|
if (m_Owner.NpcConfig.AtkType == 0)
|
{
|
_doAttack = true;
|
}
|
else
|
{
|
if (m_Owner.heroAttacked)
|
{
|
_doAttack = true;
|
}
|
}
|
|
if (_doAttack)
|
{
|
m_AIStatus = E_AIStatus.Attack;
|
}
|
else
|
{
|
// 主角不存在或者死亡了
|
// 在出生点附近
|
_compareDis = MathUtility.DistanceSqrtXZ(BornPos, m_Owner.Pos);
|
if (_compareDis < 4)
|
{
|
m_AIStatus = E_AIStatus.Patrol;
|
}
|
// 巡逻
|
// 不在出生点附近
|
else
|
{
|
// 回到出生点
|
m_AIStatus = E_AIStatus.MoveToBornPos;
|
atkStep = 0;
|
}
|
}
|
}
|
else
|
{
|
m_AIStatus = E_AIStatus.Patrol;
|
}
|
}
|
}
|
}
|
}
|