using System.Collections.Generic;
|
|
using UnityEngine;
|
|
/// <summary>
|
/// 每隔一段时间检测周围目标脚本
|
/// </summary>
|
public class Bhv_FindEnemy : MonoBehaviour
|
{
|
[Tooltip("清空锁定目标的距离")]
|
public float reSetLockTargetDist;
|
[Tooltip("重新确定当前对象的距离")]
|
public float reFindSelectTargetDist;
|
[Tooltip("每次重新检测的间隔事件")]
|
public float reDoInterval = 0.3f;
|
|
private float m_LastChkTime;
|
|
private void Start()
|
{
|
FuncConfigConfig _funcConfig = FuncConfigConfig.Get("MaxTargetRange");
|
reSetLockTargetDist = float.Parse(_funcConfig.Numerical1);
|
|
JobSetupConfig _jobConfig = JobSetupConfig.Get(PlayerDatas.Instance.baseData.Job);
|
reFindSelectTargetDist = _jobConfig.MaxSwitchTargetDist * Constants.F_DELTA;
|
}
|
|
private void Update()
|
{
|
if (Time.time - m_LastChkTime < reDoInterval)
|
{
|
return;
|
}
|
|
m_LastChkTime = Time.time;
|
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
if (_hero == null)
|
{
|
return;
|
}
|
|
if (_hero.LockTarget != null)
|
{
|
// 判断是否要清空锁定目标
|
DoIfClearLockTarget();
|
return;
|
}
|
|
if (!_hero.aiHandler.IsAuto()
|
|| _hero.aiHandler.IsPause())
|
{
|
// 只有当前主角没有锁定目标的时候才进行搜怪
|
DoReFindSelectTarget();
|
}
|
}
|
|
private void DoIfClearLockTarget()
|
{
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
if (_hero.LockTarget is GA_NpcFightBoss
|
|| _hero.LockTarget is GA_NpcClientFightBoss)
|
{
|
return;
|
}
|
|
Vector3 _targetPos = _hero.LockTarget.Pos;
|
Vector3 _heroPos = _hero.Pos;
|
|
float _distSqrt = MathUtility.DistanceSqrtXZ(_targetPos, _heroPos);
|
|
if (_distSqrt > Mathf.Pow(reSetLockTargetDist, 2)
|
|| StatusMgr.Instance.IsInvisible(_hero.LockTarget.ServerInstID))
|
{
|
_hero.LockTarget = null;
|
}
|
}
|
|
private void DoReFindSelectTarget()
|
{
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
if (_hero.SelectTarget == null)
|
{
|
var _actor = GAMgr.Instance.FindAtkTarget(_hero.Pos, reSetLockTargetDist);
|
if (!(_actor is GActorFight))
|
{
|
_hero.SelectTarget = _actor;
|
}
|
else
|
{
|
if (_actor.CanAtked())
|
{
|
_hero.SelectTarget = _actor;
|
}
|
}
|
}
|
else
|
{
|
Vector3 _targetPos = _hero.SelectTarget.Pos;
|
Vector3 _heroPos = _hero.Pos;
|
|
float _distSqrt = MathUtility.DistanceSqrtXZ(_targetPos, _heroPos);
|
|
var _chkDis = reFindSelectTargetDist;
|
|
if (PlayerDatas.Instance.baseData.MapID == 31340 && _hero.SelectTarget is GA_NpcCollect)
|
{
|
_chkDis += 1;
|
}
|
|
if (_distSqrt > Mathf.Pow(_chkDis, 2))
|
{
|
var _actor = GAMgr.Instance.FindAtkTarget(_hero.Pos, reSetLockTargetDist);
|
if (!(_actor is GActorFight))
|
{
|
_hero.SelectTarget = _actor;
|
}
|
else
|
{
|
if (_actor.CanAtked())
|
{
|
_hero.SelectTarget = _actor;
|
if (_actor is GA_NpcFightBoss && _hero.LockTarget == null)
|
{
|
_hero.LockTarget = _actor;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
#region 界面切换目标
|
|
private List<uint> m_SelectedTarget = new List<uint>();
|
|
public void SwitchTarget()
|
{
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
if (_hero == null)
|
{
|
return;
|
}
|
|
if (_hero.IsRushing)
|
{
|
return;
|
}
|
|
if (_hero.SelectTarget != null)
|
{
|
if (!m_SelectedTarget.Contains(_hero.SelectTarget.ServerInstID))
|
{
|
m_SelectedTarget.Add(_hero.SelectTarget.ServerInstID);
|
}
|
}
|
|
GActorFight _fight = null;
|
uint _curResultID = 0;
|
uint _bestPlayerID = 0;
|
uint _bestNpcID = 0;
|
uint _bestTargetID = 0;// 有可能找不到的最优解, 此时用上面变量来决定最优解
|
|
if (PlayerDatas.Instance.baseData.AttackMode == (int)E_AttackMode.All
|
|| PlayerDatas.Instance.baseData.AttackMode == (int)E_AttackMode.Family
|
|| PlayerDatas.Instance.baseData.AttackMode == (int)E_AttackMode.Contest
|
|| PlayerDatas.Instance.maliciousAtkPlayer.Count > 0)
|
{
|
//Debug.LogFormat("当前模式: {0}, 开始搜索Player对象...", (E_AttackMode)PlayerDatas.Instance.baseData.AttackMode);
|
List<GActor> _actorList = GAMgr.Instance.GetGroupList(E_ActorGroup.Player);
|
|
if (_actorList != null)
|
{
|
_actorList.Sort(CompareDistance);
|
|
for (int i = 0; i < _actorList.Count; ++i)
|
{
|
_fight = _actorList[i] as GActorFight;
|
|
if (_fight == null || !_fight.CanAtked())
|
{
|
continue;
|
}
|
|
if (MathUtility.DistanceSqrtXZ(_hero.Pos, _fight.Pos)
|
> Mathf.Pow(reSetLockTargetDist, 2))
|
{
|
continue;
|
}
|
|
if (_bestPlayerID == 0)
|
{
|
_bestPlayerID = _fight.ServerInstID;
|
}
|
|
// 排除之前选择过的
|
if (m_SelectedTarget.Contains(_fight.ServerInstID))
|
{
|
continue;
|
}
|
|
// 确定此次解
|
_curResultID = _fight.ServerInstID;
|
|
break;
|
}
|
|
if (_curResultID != 0)
|
{
|
//Debug.LogFormat(" |-- 此次有最优解: {0}", _curResultID);
|
_bestTargetID = _curResultID;
|
}
|
//else if (_bestPlayerID != 0)
|
//{
|
// //Debug.LogFormat(" |-- 此次没有最优解, 使用所有Player里面的最优解: {0}", _bestPlayerID);
|
// _bestTargetID = _bestPlayerID;
|
|
// // 清空过滤列表
|
// m_SelectedTarget.Clear();
|
//}
|
}
|
}
|
|
// 在上面的角色选择中选不到目标, 即场上可见范围内是没有任何玩家的
|
// 开始判断NPC
|
if (_bestTargetID == 0)
|
{
|
//Debug.Log("没有找到任何Player对象, 开始搜索NPC对象");
|
|
List<GActor> _actorList = GAMgr.Instance.GetGroupList(E_ActorGroup.Enemy);
|
|
if (_actorList != null)
|
{
|
_actorList.Sort(CompareDistance);
|
|
for (int i = 0; i < _actorList.Count; ++i)
|
{
|
_fight = _actorList[i] as GActorFight;
|
|
if (_fight == null || !_fight.CanAtked())
|
{
|
continue;
|
}
|
|
if (MathUtility.DistanceSqrtXZ(_hero.Pos, _fight.Pos)
|
> Mathf.Pow(reSetLockTargetDist, 2))
|
{
|
continue;
|
}
|
|
if (_bestNpcID == 0)
|
{
|
_bestNpcID = _fight.ServerInstID;
|
}
|
|
// 排除之前选择过的
|
if (m_SelectedTarget.Contains(_fight.ServerInstID))
|
{
|
continue;
|
}
|
|
// 确定此次解
|
_curResultID = _fight.ServerInstID;
|
|
break;
|
}
|
|
if (_curResultID != 0)
|
{
|
//Debug.LogFormat(" |-- 此次有最优解: {0}", _curResultID);
|
_bestTargetID = _curResultID;
|
}
|
}
|
}
|
|
// 最后进行判断取哪个值
|
// 如果出现都选不中的情况, 有可能是所有的怪都被遍历了一遍了
|
if (_bestTargetID == 0)
|
{
|
// 这里判断是不是还有最优选中对象
|
if (_bestPlayerID != 0)
|
{
|
_bestTargetID = _bestPlayerID;
|
//Debug.LogFormat(" |-- 此次没有最优解, 使用所有Player里面的最优解: {0}", _bestPlayerID);
|
}
|
else if (_bestNpcID != 0)
|
{
|
_bestTargetID = _bestNpcID;
|
//Debug.LogFormat(" |-- 此次没有最优解, 使用所有NPC里面的最优解: {0}", _bestNpcID);
|
}
|
|
// 清空过滤列表
|
m_SelectedTarget.Clear();
|
}
|
|
if (_bestTargetID != 0)
|
{
|
_hero.LockTarget = GAMgr.Instance.GetBySID(_bestTargetID);
|
_hero.SelectTarget = _hero.LockTarget;
|
m_SelectedTarget.Add(_bestTargetID);
|
if (_hero.LockTarget != null)
|
{
|
GA_Hero.CallLockTargetChanged(_hero.LockTarget.ServerInstID);
|
}
|
}
|
}
|
|
public int CompareDistance(GActor a1, GActor a2)
|
{
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
if (_hero == null)
|
{
|
return 0;
|
}
|
|
float _chk1 = MathUtility.DistanceSqrtXZ(a1.Pos, _hero.Pos);
|
float _chk2 = MathUtility.DistanceSqrtXZ(a2.Pos, _hero.Pos);
|
|
if (_chk1 < _chk2)
|
{
|
return -1;
|
}
|
else if (_chk1 > _chk2)
|
{
|
return 1;
|
}
|
|
return 0;
|
}
|
|
#endregion
|
}
|