using System.Collections.Generic;
|
using System;
|
using UnityEngine;
|
using UnityEngine.Events;
|
|
using System.Collections;
|
using vnxbqy.UI;
|
|
|
public class GAMgr : SingletonMonobehaviour<GAMgr>
|
{
|
private List<GActor> reAdjustPosList = new List<GActor>();
|
|
public void AddReJustPosActor(GActor actor)
|
{
|
if (actor == null)
|
{
|
#if UNITY_EDITOR
|
Debug.LogFormat("<color=red>矫正坐标 => 要添加的目标是空的.</color>");
|
#endif
|
return;
|
}
|
|
if (reAdjustPosList.Contains(actor))
|
{
|
#if UNITY_EDITOR
|
Debug.LogFormat("<color=red>矫正坐标 => 已添加过目标: {0}/{1}</color>", actor.GetType(), actor.ServerInstID);
|
#endif
|
return;
|
}
|
|
reAdjustPosList.Add(actor);
|
}
|
|
public void DoReAdjustPos()
|
{
|
var _model = ModelCenter.Instance.GetModel<TaskModel>();
|
foreach (var actor in reAdjustPosList)
|
{
|
var _func = actor as GA_NpcFunc;
|
if (_func != null)
|
{
|
bool _needHide = _func.NpcConfig.Show == 0;
|
if (_model.NPCShowDic.ContainsKey(_func.NpcConfig.NPCID))
|
{
|
if (_model.NPCShowDic[_func.NpcConfig.NPCID] == 1)
|
{
|
_needHide = false;
|
}
|
}
|
|
if (_needHide)
|
{
|
continue;
|
}
|
}
|
|
actor.AdjustPos((ushort)actor.ActorInfo.serverBornPos.x, (ushort)actor.ActorInfo.serverBornPos.y);
|
}
|
}
|
|
public void ClearReJustActor()
|
{
|
if (reAdjustPosList.Count > 0)
|
{
|
reAdjustPosList.Clear();
|
}
|
}
|
|
private List<BossSkillTip_JudgeSummon> m_BossSkillTipList = new List<BossSkillTip_JudgeSummon>();
|
|
public Dictionary<int, string> s_NpcID2BundleName = new Dictionary<int, string>();
|
public Dictionary<int, string> s_NpcID2Assetname = new Dictionary<int, string>();
|
|
public event UnityAction<uint> OnGActorRequest;
|
public event UnityAction<uint> OnGActorServerDie;
|
|
public event UnityAction<uint> OnFightNpcRequest;
|
public event UnityAction<uint> OnFightNpcRelease;
|
|
// 由角色池生成的prefab列表. 用来卸载用的.
|
public List<GameObject> needDestroyPrefabList = new List<GameObject>();
|
public List<GActorFight> needDieList = new List<GActorFight>();
|
public void AddNeedDestroyPrefab(GameObject go)
|
{
|
if (go && !needDestroyPrefabList.Contains(go))
|
{
|
needDestroyPrefabList.Add(go);
|
// Debug.LogFormat("添加需要销毁的对象: {0}", go.name);
|
}
|
//else
|
//{
|
// Debug.LogFormat("X 无法添加需要销毁的对象: {0}", go.name);
|
//}
|
}
|
|
public void RemoveNeedDestroyPrefab(GameObject go)
|
{
|
if (go && needDestroyPrefabList.Contains(go))
|
{
|
needDestroyPrefabList.Remove(go);
|
// Debug.LogFormat("移除想销毁的对象: {0}", go.name);
|
}
|
//else
|
//{
|
// Debug.LogFormat("X 无法移除想销毁的对象: {0}", go.name);
|
//}
|
}
|
|
// id池
|
private IDFactory m_ClientId;
|
private IDFactory m_SimulateServerID;
|
// 回收池
|
private Dictionary<byte, Stack<GActor>> m_Free;
|
// 分组角色
|
private Dictionary<byte, List<GActor>> m_Group;
|
// 分类型角色
|
private Dictionary<byte, List<GActor>> m_Type;
|
// 所有对象
|
private List<GActor> m_AllList;
|
// 服务器id对应当前客户端角色id
|
private Dictionary<uint, uint> m_Sid2Cid;
|
// 客户端id对应相应角色
|
private Dictionary<uint, GActor> m_Cid2GA;
|
|
private List<uint> m_OffLineList;
|
|
// 服务端通知的死亡目标对应的客户端id,
|
// 这里为了处理可能出现的无法死亡现象,对每一只目标进行计时,强制其死亡
|
private List<uint> serverDeadList = new List<uint>();
|
private Dictionary<uint, float> serverDeadDict = new Dictionary<uint, float>();
|
|
public Dictionary<uint, float> atkOtherPlayerDict = new Dictionary<uint, float>();
|
public Dictionary<uint, float> otherPlayerAtkHeroDict = new Dictionary<uint, float>();
|
|
// 保证只初始化一次
|
private bool m_Inited = false;
|
public void Init()
|
{
|
if (!m_Inited)
|
{
|
m_ClientId = new IDFactory(1);
|
m_SimulateServerID = new IDFactory(900000);
|
m_Free = new Dictionary<byte, Stack<GActor>>();
|
m_Group = new Dictionary<byte, List<GActor>>();
|
m_Type = new Dictionary<byte, List<GActor>>();
|
m_AllList = new List<GActor>();
|
m_Sid2Cid = new Dictionary<uint, uint>();
|
m_Cid2GA = new Dictionary<uint, GActor>();
|
m_OffLineList = new List<uint>();
|
m_Inited = true;
|
|
SystemSetting.Instance.playerSyncCountChangeEvent += OnPlayerSyncCountChange;
|
SystemSetting.Instance.OnSettingChanged += OnSettingChanged;
|
SystemSetting.Instance.qualityLevelChangeEvent += OnQualityLevelChange;
|
}
|
}
|
|
private void OnQualityLevelChange()
|
{
|
List<GActor> _list = GetTypeList(E_ActorClassType.Pet);
|
|
GA_Player _player = null;
|
if (_list != null && _list.Count > 0)
|
{
|
//Debug.LogFormat("共有: {0} 只宠物", _petList.Count);
|
foreach (var _pet in _list)
|
{
|
var _parentID = _pet.ActorInfo.ownerSID;
|
if (_parentID == PlayerDatas.Instance.PlayerId)
|
{
|
continue;
|
}
|
|
_player = GetBySID(_parentID) as GA_Player;
|
if (_player == null || !_player.ShowOrHide)
|
{
|
_pet.ShowOrHideModel(false);
|
_pet.HideEffect();
|
//Debug.LogFormat("宠物: {0} 的拥有者: {1} 不可见, 这里隐藏.", _pet.ServerInstID, _parentID);
|
continue;
|
}
|
|
var _index = BattleEffectPlayRule.Instance.GetIndex(_parentID);
|
if (_index != -1 && _index < BattleEffectPlayRule.Instance.petLimit)
|
{
|
_pet.ShowOrHideModel(true);
|
//Debug.LogFormat("宠物: {0} 的拥有者: {1} 在列表中且位于: {2}, 小于限制数量: {3}", _pet.ServerInstID, _parentID, _index, BattleEffectPlayRule.Instance.petLimit);
|
}
|
else
|
{
|
_pet.ShowOrHideModel(false);
|
//Debug.LogFormat("宠物: {0} 的拥有者: {1} 在列表中且位于: {2}, 大于限制数量: {3}", _pet.ServerInstID, _parentID, _index, BattleEffectPlayRule.Instance.petLimit);
|
}
|
|
if (_index != -1 && _index < BattleEffectPlayRule.Instance.petEffectLimit)
|
{
|
_pet.ShowEffect();
|
}
|
else
|
{
|
_pet.HideEffect();
|
}
|
}
|
}
|
|
_list = GetTypeList(E_ActorClassType.Player);
|
if (_list != null && _list.Count > 0)
|
{
|
//Debug.LogFormat("共有: {0} 只守护", _list.Count);
|
foreach (var _chkPlayer in _list)
|
{
|
_player = _chkPlayer as GA_Player;
|
if (_chkPlayer == null || !_chkPlayer.ShowOrHide)
|
{
|
_player.SwitchGuard(0);
|
_player.HideHorseEffect();
|
//Debug.LogFormat("_list: {0} 的拥有者: {1} 不可见, 这里隐藏.", _chkPlayer.ServerInstID, _player.ServerInstID);
|
continue;
|
}
|
|
var _index = BattleEffectPlayRule.Instance.GetIndex(_player.ServerInstID);
|
if (_index != -1 && _index < BattleEffectPlayRule.Instance.petLimit)
|
{
|
_player.SwitchGuard((uint)_player.serverGuardId);
|
//Debug.LogFormat("_list: {0} 的拥有者: {1} 在列表中且位于: {2}, 小于限制数量: {3}", _chkPlayer.ServerInstID, _player.ServerInstID, _index, BattleEffectPlayRule.Instance.petLimit);
|
}
|
else
|
{
|
_player.SwitchGuard(0);
|
//Debug.LogFormat("_list: {0} 的拥有者: {1} 在列表中且位于: {2}, 大于限制数量: {3}", _chkPlayer.ServerInstID, _player.ServerInstID, _index, BattleEffectPlayRule.Instance.petLimit);
|
}
|
|
if (_index != -1 && _index < BattleEffectPlayRule.Instance.horseEffectLimit)
|
{
|
_player.ShowHorseEffect();
|
_player.ShowWeaponEffect();
|
_player.ShowSecondaryEffect();
|
//Debug.LogFormat("_list: {0} 的拥有者: {1} 在列表中且位于: {2}, 小于限制数量: {3}", _chkPlayer.ServerInstID, _player.ServerInstID, _index, BattleEffectPlayRule.Instance.petLimit);
|
}
|
else
|
{
|
_player.HideHorseEffect();
|
_player.HideWeaponEffect();
|
_player.HideSecondaryEffect();
|
//Debug.LogFormat("_list: {0} 的拥有者: {1} 在列表中且位于: {2}, 大于限制数量: {3}", _chkPlayer.ServerInstID, _player.ServerInstID, _index, BattleEffectPlayRule.Instance.petLimit);
|
}
|
}
|
}
|
}
|
|
public void AddOffLinePlayer(uint sid)
|
{
|
if (m_OffLineList.Contains(sid))
|
{
|
return;
|
}
|
|
m_OffLineList.Add(sid);
|
}
|
|
public void RemoveOffLinePlayer(uint sid)
|
{
|
if (m_OffLineList.Contains(sid))
|
{
|
m_OffLineList.Remove(sid);
|
}
|
}
|
|
public void ClearOffLinePlayer()
|
{
|
m_OffLineList.Clear();
|
}
|
|
private float m_UpdateOffLineInterval;
|
private List<uint> m_CacheList = new List<uint>();
|
private List<uint> m_ContaintList = new List<uint>();
|
|
private void UpdateOffLinePlayer()
|
{
|
if (m_OffLineList == null || m_OffLineList.Count == 0)
|
{
|
return;
|
}
|
|
if (Time.realtimeSinceStartup - m_UpdateOffLineInterval > 2)
|
{
|
m_CacheList.Clear();
|
m_ContaintList.Clear();
|
|
int _count = Mathf.Min(m_OffLineList.Count, 4);
|
|
//Debug.LogFormat("此次将会有: {0} 个挂机者释放技能", _count);
|
|
for (int i = 0; i < m_OffLineList.Count; ++i)
|
{
|
m_CacheList.Add(m_OffLineList[i]);
|
}
|
|
int _time = 0;
|
|
while (m_ContaintList.Count < _count)
|
{
|
int _index = UnityEngine.Random.Range(0, m_CacheList.Count);
|
m_ContaintList.Add(m_CacheList[_index]);
|
//Debug.LogFormat("添加对象: {0}, 已添加: {1} 个", m_CacheList[_index], m_ContaintList.Count);
|
m_CacheList.RemoveAt(_index);
|
if (_time > _count)
|
{
|
//Debug.LogFormat("共添加了: {0} 个玩家", m_ContaintList.Count);
|
break;
|
}
|
_time++;
|
}
|
|
GA_Player _player = null;
|
for (int i = 0; i < m_ContaintList.Count; ++i)
|
{
|
_player = GetBySID(m_ContaintList[i]) as GA_Player;
|
if (_player == null)
|
{
|
continue;
|
}
|
|
_player.UpdateOffLineAction();
|
}
|
|
m_UpdateOffLineInterval = Time.realtimeSinceStartup;
|
}
|
}
|
|
private void OnSettingChanged(SystemSwitch type, bool value)
|
{
|
//普通小怪关闭时最多显示4个
|
int defaultCnt = 4;
|
int showCnt = 0;
|
if (type == SystemSwitch.HideMonster)
|
{
|
List<GActor> _nomrlNPCList = GetTypeList(E_ActorClassType.NpcFightNorm);
|
GActorNpcFight _npcFight;
|
if (_nomrlNPCList != null)
|
{
|
for (int i = 0; i < _nomrlNPCList.Count; ++i)
|
{
|
_npcFight = _nomrlNPCList[i] as GActorNpcFight;
|
if (_npcFight == null
|
|| _npcFight is GA_Pet)
|
{
|
continue;
|
}
|
|
//此处的value时反的
|
if (value == true && showCnt < defaultCnt)
|
{
|
_npcFight.ShowOrHideModel(true);
|
}
|
else
|
{
|
_npcFight.ShowOrHideModel(!value);
|
}
|
showCnt++;
|
}
|
}
|
}
|
}
|
|
private List<GActor> m_CheckPlayerList = new List<GActor>();
|
|
public void OnPlayerSyncCountChange()
|
{
|
int _limitCount = SystemSetting.Instance.GetPlayerSyncCount();
|
|
int _teamCount = 0;
|
int _familyCount = 0;
|
|
List<GActor> _playerList = GetTypeList(E_ActorClassType.Player);
|
|
if (_playerList == null)
|
{
|
return;
|
}
|
|
m_CheckPlayerList.Clear();
|
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
GActorFight _player = null;
|
|
int _curCount = _playerList.Count;
|
|
for (int i = _curCount - 1; i >= 0; --i)
|
{
|
_player = GetTypeList(E_ActorClassType.Player)[i] as GActorFight;
|
if (atkOtherPlayerDict.ContainsKey(_player.ServerInstID)
|
|| otherPlayerAtkHeroDict.ContainsKey(_player.ServerInstID))
|
{
|
if (m_CheckPlayerList.Count >= _limitCount)
|
{
|
_player.ShowOrHideModel(false);
|
}
|
else
|
{
|
m_CheckPlayerList.Add(_player);
|
_player.ShowOrHideModel(true);
|
}
|
}
|
}
|
|
_limitCount -= m_CheckPlayerList.Count;
|
m_CheckPlayerList.Clear();
|
|
for (int i = _curCount - 1; i >= 0; --i)
|
{
|
_player = GetTypeList(E_ActorClassType.Player)[i] as GActorFight;
|
if (_hero.ActorInfo.teamID != 0
|
&& _player.ActorInfo.teamID == _hero.ActorInfo.teamID)
|
{
|
if (m_CheckPlayerList.Count >= _limitCount)
|
{
|
_player.ShowOrHideModel(false);
|
}
|
else
|
{
|
m_CheckPlayerList.Add(_player);
|
_player.ShowOrHideModel(true);
|
}
|
}
|
}
|
|
_teamCount = m_CheckPlayerList.Count;
|
m_CheckPlayerList.Clear();
|
|
for (int i = _curCount - 1; i >= 0; --i)
|
{
|
_player = GetTypeList(E_ActorClassType.Player)[i] as GActorFight;
|
|
// 排除队友
|
if (_hero.ActorInfo.teamID != 0
|
&& _player.ActorInfo.teamID == _hero.ActorInfo.teamID)
|
{
|
continue;
|
}
|
|
if (_hero.ActorInfo.familyID != 0
|
&& _player.ActorInfo.familyID == _hero.ActorInfo.familyID)
|
{
|
|
if (m_CheckPlayerList.Count + _teamCount < _limitCount)
|
{
|
_player.ShowOrHideModel(true);
|
m_CheckPlayerList.Add(_player);
|
}
|
else
|
{
|
_player.ShowOrHideModel(false);
|
}
|
}
|
}
|
|
_familyCount = m_CheckPlayerList.Count;
|
m_CheckPlayerList.Clear();
|
|
//Debug.LogFormat("队友人数: {0}, 仙盟人数: {1}, 限制人数: {2}", _teamCount, _familyCount, _limitCount);
|
|
_limitCount = _limitCount - _teamCount - _familyCount;
|
|
//Debug.LogFormat("还需要判断的人数: {0}", _limitCount);
|
|
|
for (int i = 0; i < _curCount; ++i)
|
{
|
_player = GetTypeList(E_ActorClassType.Player)[i] as GActorFight;
|
|
if ((_hero.ActorInfo.familyID != 0 && _player.ActorInfo.familyID == _hero.ActorInfo.familyID)
|
|| (_hero.ActorInfo.teamID != 0 && _player.ActorInfo.teamID == _hero.ActorInfo.teamID)
|
|| atkOtherPlayerDict.ContainsKey(_player.ServerInstID)
|
|| otherPlayerAtkHeroDict.ContainsKey(_player.ServerInstID))
|
{
|
continue;
|
}
|
|
m_CheckPlayerList.Add(_player);
|
}
|
|
//Debug.LogFormat("计算出的人数: {0}", m_CheckPlayerList.Count);
|
|
if (m_CheckPlayerList.Count > 0)
|
{
|
m_CheckPlayerList.Sort((p1, p2) =>
|
{
|
float _d1 = MathUtility.DistanceSqrtXZ(p1.Pos, _hero.Pos);
|
float _d2 = MathUtility.DistanceSqrtXZ(p2.Pos, _hero.Pos);
|
return _d1 < _d2 ? -1 : 1;
|
});
|
|
for (int i = 0; i < m_CheckPlayerList.Count; ++i)
|
{
|
_player = m_CheckPlayerList[i] as GActorFight;
|
if (i < _limitCount)
|
{
|
_player.ShowOrHideModel(true);
|
}
|
else
|
{
|
_player.ShowOrHideModel(false);
|
}
|
}
|
}
|
}
|
|
public void UnInit()
|
{
|
ClearOffLinePlayer();
|
|
for (int i = m_AllList.Count - 1; i >= 0; --i)
|
{
|
if (i >= m_AllList.Count)
|
{
|
//其他地方做了协程删除,可能导致此处错误
|
continue;
|
}
|
|
if (m_AllList[i] == null)
|
continue;
|
|
// 玩家控制英雄不清理
|
if (m_AllList[i].ServerInstID == PlayerDatas.Instance.PlayerId)
|
{
|
continue;
|
}
|
|
m_Sid2Cid.Remove(m_AllList[i].ServerInstID);
|
Release(m_AllList[i]);
|
}
|
|
// 对所有记录的资源进行销毁
|
for (int i = needDestroyPrefabList.Count - 1; i >= 0; --i)
|
{
|
if (i >= needDestroyPrefabList.Count)
|
{
|
continue;
|
}
|
|
if (needDestroyPrefabList[i] == null)
|
{
|
needDestroyPrefabList.RemoveAt(i);
|
continue;
|
}
|
GameObjectPoolManager.Instance.Release(needDestroyPrefabList[i]);
|
needDestroyPrefabList.RemoveAt(i);
|
}
|
|
m_ClientId.Clear();
|
m_SimulateServerID.Clear();
|
|
#if UNITY_EDITOR
|
DebugUnInit();
|
#endif
|
|
}
|
|
public T RequestPlayer<T>(uint serverInstID, E_ActorGroup group, GameNetPackBasic package) where T : GActor
|
{
|
byte _actorClassType = GetActorClassType(typeof(T));
|
|
GActor _actor = GetPoolActor(_actorClassType);
|
|
if (_actor == null)
|
{
|
switch ((E_ActorClassType)_actorClassType)
|
{
|
case E_ActorClassType.Hero:
|
_actor = new GA_Hero();
|
break;
|
case E_ActorClassType.Player:
|
_actor = new GA_Player();
|
break;
|
case E_ActorClassType.PlayerXmzz:
|
_actor = new GA_PlayerXMZZ();
|
break;
|
case E_ActorClassType.PlayerZZ:
|
_actor = new GA_NpcFightZZPlayer();
|
break;
|
case E_ActorClassType.PlayerSgzcRobot:
|
_actor = new GA_NpcFightSgzcZZ();
|
break;
|
case E_ActorClassType.PVPClientPlayer:
|
_actor = new GA_PVPClientPlayer();
|
break;
|
case E_ActorClassType.ILClientPlayer:
|
_actor = new GA_ILClientPlayer();
|
ArenaManager.iLClientPlayer = _actor as GA_ILClientPlayer;
|
break;
|
}
|
}
|
|
if (_actor != null)
|
{
|
if ((E_ActorClassType)_actorClassType == E_ActorClassType.Hero)
|
{
|
_actor.Init(serverInstID, 0, group, package);
|
}
|
else
|
{
|
_actor.Init(serverInstID, m_ClientId.Request(), group, package);
|
}
|
|
BuildManagerRelation(_actor, _actorClassType);
|
|
if (OnGActorRequest != null)
|
{
|
OnGActorRequest(serverInstID);
|
}
|
}
|
|
return _actor as T;
|
}
|
|
internal uint GetCIDBySID(uint serverInstID)
|
{
|
if (m_Sid2Cid.ContainsKey(serverInstID))
|
{
|
return m_Sid2Cid[serverInstID];
|
}
|
return 0;
|
}
|
|
public T RequestNpcNoFight<T>(uint serverInstID, uint npcID, E_ActorGroup group, GameNetPackBasic package) where T : GActorNpcNoFight
|
{
|
byte _actorClassType = GetActorClassType(typeof(T));
|
|
GActorNpcNoFight _actor = GetPoolActor(_actorClassType) as GActorNpcNoFight;
|
|
if (_actor == null)
|
{
|
switch ((E_ActorClassType)_actorClassType)
|
{
|
case E_ActorClassType.Guard:
|
_actor = new GA_Guard();
|
break;
|
case E_ActorClassType.NpcFunc:
|
_actor = new GA_NpcFunc();
|
break;
|
case E_ActorClassType.NpcCollect:
|
_actor = new GA_NpcCollect();
|
break;
|
case E_ActorClassType.NpcSummonFunc:
|
_actor = new GA_NpcSummonFunc();
|
break;
|
case E_ActorClassType.NpcTouchKilled:
|
_actor = new GA_NpcTouchKilled();
|
break;
|
}
|
}
|
|
if (_actor != null)
|
{
|
_actor.Init(serverInstID, m_ClientId.Request(), group, package);
|
|
BuildManagerRelation(_actor, _actorClassType);
|
}
|
|
return _actor as T;
|
}
|
|
public T RequestNPCFight<T>(uint serverInstID, uint npcID, E_ActorGroup group, GameNetPackBasic package) where T : GActorNpcFight
|
{
|
|
byte _actorClassType = GetActorClassType(typeof(T));
|
|
GActorNpcFight _actor = GetPoolActor(_actorClassType) as GActorNpcFight;
|
|
if (_actor == null)
|
{
|
switch ((E_ActorClassType)_actorClassType)
|
{
|
case E_ActorClassType.Pet:
|
_actor = new GA_Pet();
|
break;
|
case E_ActorClassType.NpcFightNorm:
|
_actor = new GA_NpcFightNorm();
|
break;
|
case E_ActorClassType.NpcFightBoss:
|
_actor = new GA_NpcFightBoss();
|
break;
|
case E_ActorClassType.NpcClientFightBoss:
|
_actor = new GA_NpcClientFightBoss();
|
break;
|
case E_ActorClassType.NpcClientFightNorm:
|
_actor = new GA_NpcClientFightBoss();
|
break;
|
case E_ActorClassType.NpcFightVirtualPlayer:
|
_actor = new GA_NpcFightVirtualPlayer();
|
break;
|
case E_ActorClassType.NpcSummonFight:
|
_actor = new GA_NpcSummonFight();
|
break;
|
}
|
}
|
|
if (_actor != null)
|
{
|
_actor.Init(serverInstID,
|
_actorClassType == (int)E_ActorClassType.Pet ? serverInstID : m_ClientId.Request(),
|
group,
|
package);
|
|
BuildManagerRelation(_actor, _actorClassType);
|
|
#if UNITY_EDITOR
|
string _content = string.Format("GAMgr => 对角色 SID: {0}, CID: {1} 进行初始化", serverInstID, _actor.ClientInstID);
|
RuntimeLogUtility.AddLog_Green(_content, serverInstID);
|
#endif
|
|
if (OnFightNpcRequest != null)
|
{
|
OnFightNpcRequest(npcID);
|
}
|
|
}
|
|
return _actor as T;
|
}
|
|
public T ReqClntNoFightNpc<T>(uint npcID, E_ActorGroup group) where T : GActorNpcNoFight
|
{
|
uint serverInstID = m_SimulateServerID.Request();
|
byte _actorClassType = GetActorClassType(typeof(T));
|
|
GActorNpcNoFight _actor = GetPoolActor(_actorClassType) as GActorNpcNoFight;
|
|
if (_actor == null)
|
{
|
switch ((E_ActorClassType)_actorClassType)
|
{
|
case E_ActorClassType.NpcClientFunc:
|
_actor = new GA_NpcClientFunc();
|
break;
|
case E_ActorClassType.NpcClientCollect:
|
_actor = new GA_NpcClientCollect();
|
break;
|
}
|
}
|
|
if (_actor != null)
|
{
|
_actor.InitNpcConfig((int)npcID);
|
_actor.Init(serverInstID, m_ClientId.Request(), group, null);
|
|
BuildManagerRelation(_actor, _actorClassType);
|
}
|
|
return _actor as T;
|
}
|
|
public T ReqClntFightNpc<T>(uint npcID, E_ActorGroup group) where T : GActorNpcFight
|
{
|
uint serverInstID = m_SimulateServerID.Request();
|
byte _actorClassType = GetActorClassType(typeof(T));
|
|
GActorNpcFight _actor = GetPoolActor(_actorClassType) as GActorNpcFight;
|
|
if (_actor == null)
|
{
|
switch ((E_ActorClassType)_actorClassType)
|
{
|
case E_ActorClassType.NpcClientFightBoss:
|
_actor = new GA_NpcClientFightBoss();
|
break;
|
case E_ActorClassType.NpcClientFightNorm:
|
_actor = new GA_NpcClientFightNorm();
|
break;
|
}
|
}
|
|
if (_actor != null)
|
{
|
_actor.InitNpcConfig((int)npcID);
|
_actor.Init(serverInstID, m_ClientId.Request(), group, null);
|
|
BuildManagerRelation(_actor, _actorClassType);
|
}
|
|
return _actor as T;
|
}
|
|
public T ReqClntPlayer<T>(GActorPlayerBase.PlayerInfo info, E_ActorGroup group) where T : GActorPlayerBase
|
{
|
uint serverInstID = m_SimulateServerID.Request();
|
byte _actorClassType = GetActorClassType(typeof(T));
|
|
GActorPlayerBase _actor = null;
|
|
if ((E_ActorClassType)_actorClassType == E_ActorClassType.PVPClientPlayer)
|
{
|
_actor = GetPoolActor(_actorClassType) as GA_PVPClientPlayer;
|
|
if (_actor == null)
|
{
|
_actor = new GA_PVPClientPlayer();
|
}
|
|
if (_actor != null)
|
{
|
(_actor as GA_PVPClientPlayer).Init(serverInstID, m_ClientId.Request(), info, group);
|
BuildManagerRelation(_actor, _actorClassType);
|
}
|
}
|
else if ((E_ActorClassType)_actorClassType == E_ActorClassType.ILClientPlayer)
|
{
|
_actor = GetPoolActor(_actorClassType) as GA_ILClientPlayer;
|
|
if (_actor == null)
|
{
|
_actor = new GA_ILClientPlayer();
|
ArenaManager.iLClientPlayer = _actor as GA_ILClientPlayer;
|
}
|
|
if (_actor != null)
|
{
|
(_actor as GA_ILClientPlayer).Init(serverInstID, m_ClientId.Request(), info, group);
|
BuildManagerRelation(_actor, _actorClassType);
|
}
|
}
|
else if ((E_ActorClassType)_actorClassType == E_ActorClassType.JiaPlayer)
|
{
|
_actor = GetPoolActor(_actorClassType) as GA_JiaPlayer;
|
|
if (_actor == null)
|
{
|
_actor = new GA_JiaPlayer();
|
}
|
|
if (_actor != null)
|
{
|
(_actor as GA_JiaPlayer).Init(serverInstID, m_ClientId.Request(), info, group);
|
BuildManagerRelation(_actor, _actorClassType);
|
}
|
}
|
else
|
{
|
_actor = GetPoolActor(_actorClassType) as GA_PlayerClient;
|
|
if (_actor == null)
|
{
|
_actor = new GA_PlayerClient();
|
}
|
|
if (_actor != null)
|
{
|
(_actor as GA_PlayerClient).Init(serverInstID, m_ClientId.Request(), info, group);
|
BuildManagerRelation(_actor, _actorClassType);
|
}
|
}
|
|
return _actor as T;
|
}
|
|
public void CreateBossTipReleaseHandler(int skillId)
|
{
|
BossSkillTip_JudgeSummon _handler = new BossSkillTip_JudgeSummon(skillId);
|
m_BossSkillTipList.Add(_handler);
|
}
|
|
private GActor GetPoolActor(byte actorClassType)
|
{
|
GActor _actor = null;
|
Stack<GActor> _freeStack = null;
|
if (m_Free.TryGetValue(actorClassType, out _freeStack))
|
{
|
if (_freeStack.Count > 0)
|
{
|
_actor = _freeStack.Pop();
|
_actor.Root.SetParent(null);
|
DontDestroyOnLoad(_actor.Root);
|
}
|
}
|
|
return _actor;
|
}
|
public void ServerDieFail(uint serverInstID)
|
{
|
if (m_Sid2Cid.ContainsKey(serverInstID))
|
{
|
m_Sid2Cid.Remove(serverInstID);
|
}
|
}
|
/// <summary>
|
/// 服务度死亡
|
/// 用于断开与客户端对象的关联
|
/// 以便新的服务端对象创建不会影响旧的客户端对象
|
/// </summary>
|
/// <param name="serverInstID">服务器对象ID</param>
|
public void ServerDie(uint serverInstID)
|
{
|
if (m_Sid2Cid.ContainsKey(serverInstID))
|
{
|
//if (!serverDeadList.Contains(m_Sid2Cid[serverInstID]))
|
//{
|
// serverDeadList.Add(m_Sid2Cid[serverInstID]);
|
// serverDeadDict.Add(m_Sid2Cid[serverInstID], Time.realtimeSinceStartup);
|
// Debug.LogFormat("死亡处理添加了: {0}", m_Sid2Cid[serverInstID]);
|
//}
|
|
m_Sid2Cid.Remove(serverInstID);
|
|
if (OnGActorServerDie != null)
|
{
|
OnGActorServerDie(serverInstID);
|
}
|
|
#if UNITY_EDITOR
|
string _content = string.Format("GAMgr => 对角色 SID: {0} 进行服务端死亡处理逻辑", serverInstID);
|
RuntimeLogUtility.AddLog_Green(_content, serverInstID);
|
#endif
|
}
|
}
|
/// <summary>
|
/// 释放
|
/// 释放的时机为真正需要从场景中移除
|
/// 一般为死亡结束,或者立即消失
|
/// * 此方法前, 应该已经解除了服务端ID与客户端的联系
|
/// </summary>
|
/// <param name="actor"></param>
|
public void Release(GActor actor)
|
{
|
#if UNITY_EDITOR
|
string _content = string.Format("GAMgr => 对角色 SID: {0}, CID: {1} 进行了回收", actor.ServerInstID, actor.ClientInstID);
|
if (actor is GActorNpcFight)
|
{
|
Debug.Log(_content);
|
}
|
RuntimeLogUtility.AddLog_Green(_content, actor.ServerInstID);
|
#endif
|
bool _needReSyncPlayerCount = false;
|
|
if (PlayerDatas.Instance.hero != null && actor is GA_Player)
|
{
|
if (actor.ActorInfo.teamID == PlayerDatas.Instance.hero.ActorInfo.teamID
|
|| actor.ActorInfo.familyID == PlayerDatas.Instance.hero.ActorInfo.familyID)
|
{
|
_needReSyncPlayerCount = true;
|
}
|
}
|
|
// 执行卸载
|
actor.UnInit();
|
|
// 对象回收
|
byte _actorClassType = GetActorClassType(actor.GetType());
|
Stack<GActor> _stack = null;
|
if (!m_Free.TryGetValue(_actorClassType, out _stack))
|
{
|
_stack = new Stack<GActor>();
|
m_Free.Add(_actorClassType, _stack);
|
}
|
if (m_Free[_actorClassType].Contains(actor))
|
{
|
Debug.LogWarningFormat("执行角色回收, 对象已在回收池里了...");
|
}
|
else
|
{
|
m_Free[_actorClassType].Push(actor);
|
}
|
|
actor.Pos = Constants.Special_Hide_Position;
|
actor.Root.SetParent(transform);
|
|
// 组列表移除
|
List<GActor> _list = null;
|
if (m_Group.TryGetValue((byte)actor.Group, out _list))
|
{
|
if (_list.Contains(actor))
|
{
|
_list.Remove(actor);
|
}
|
}
|
|
// 类型列表移除
|
if (m_Type.TryGetValue(_actorClassType, out _list))
|
{
|
if (_list.Contains(actor))
|
{
|
_list.Remove(actor);
|
}
|
}
|
|
// 全列表移除
|
if (m_AllList.Contains(actor))
|
{
|
m_AllList.Remove(actor);
|
}
|
|
// id对象字典移除
|
if (m_Cid2GA.ContainsKey(actor.ClientInstID))
|
{
|
m_Cid2GA.Remove(actor.ClientInstID);
|
}
|
|
var _npcfight = actor as GActorNpcFight;
|
|
if (_npcfight != null)
|
{
|
if (OnFightNpcRelease != null)
|
{
|
OnFightNpcRelease((uint)_npcfight.NpcConfig.NPCID);
|
}
|
}
|
|
if (_needReSyncPlayerCount)
|
{
|
OnPlayerSyncCountChange();
|
}
|
}
|
|
public void ReleaseAll()
|
{
|
for (int i = m_AllList.Count - 1; i >= 0; --i)
|
{
|
if (i >= m_AllList.Count)
|
{
|
//其他地方做了协程删除,可能导致此处错误
|
continue;
|
}
|
if (m_AllList[i] == null)
|
continue;
|
Release(m_AllList[i]);
|
}
|
|
serverDeadList.Clear();
|
|
#if UNITY_EDITOR
|
DebugUnInit();
|
#endif
|
}
|
|
public GActor GetBySID(uint serverInstID)
|
{
|
if (m_Sid2Cid.ContainsKey(serverInstID))
|
{
|
if (m_Cid2GA.ContainsKey(m_Sid2Cid[serverInstID]))
|
{
|
return m_Cid2GA[m_Sid2Cid[serverInstID]];
|
}
|
}
|
return null;
|
}
|
|
public GActor GetByCID(uint clientInstID)
|
{
|
if (m_Cid2GA.ContainsKey(clientInstID))
|
{
|
return m_Cid2GA[clientInstID];
|
}
|
return null;
|
}
|
|
public GActor GetCloserCollectNpc(Vector3 center)
|
{
|
List<GActor> _list = GetTypeList(E_ActorClassType.NpcCollect);
|
|
if (_list == null || _list.Count == 0)
|
{
|
return null;
|
}
|
|
_list.Sort((GActor a1, GActor a2) =>
|
{
|
float _d1 = MathUtility.DistanceSqrtXZ(center, a1.Pos);
|
float _d2 = MathUtility.DistanceSqrtXZ(center, a2.Pos);
|
return _d1 < _d2 ? -1 : 1;
|
});
|
|
return _list[0];
|
}
|
|
public GActor GetCloserFightNpc(Vector3 center)
|
{
|
List<GActor> _list = GetTypeList(E_ActorClassType.NpcFightNorm);
|
|
if (_list == null || _list.Count == 0)
|
{
|
return null;
|
}
|
|
_list.Sort((GActor a1, GActor a2) =>
|
{
|
float _d1 = MathUtility.DistanceSqrtXZ(center, a1.Pos);
|
float _d2 = MathUtility.DistanceSqrtXZ(center, a2.Pos);
|
return _d1 < _d2 ? -1 : 1;
|
});
|
|
return _list[0];
|
}
|
|
/// <summary>
|
/// 获取离给定坐标最近的NPC对象
|
/// </summary>
|
/// <param name="pos"></param>
|
/// <param name="npcID"></param>
|
/// <returns></returns>
|
public GActor GetCloserNPC(Vector3 pos, int npcID = 0)
|
{
|
m_AllList.Sort((GActor a1, GActor a2) =>
|
{
|
float _d1 = MathUtility.DistanceSqrtXZ(pos, a1.Pos);
|
float _d2 = MathUtility.DistanceSqrtXZ(pos, a2.Pos);
|
return _d1 < _d2 ? -1 : 1;
|
});
|
|
NPCConfig _npcConfig = NPCConfig.Get(npcID);
|
if (_npcConfig == null)
|
{
|
return null;
|
}
|
for (int i = 0; i < m_AllList.Count; ++i)
|
{
|
if (i >= m_AllList.Count)
|
{
|
//其他地方做了协程删除,可能导致此处错误
|
continue;
|
}
|
if (m_AllList[i] == null)
|
{
|
continue;
|
}
|
if (m_AllList[i].ActorType != GameObjType.gotNPC)
|
{
|
continue;
|
}
|
|
if (m_AllList[i].ActorInfo == null)
|
{
|
continue;
|
}
|
|
if (m_AllList[i].ActorInfo.serverDie)
|
{
|
continue;
|
}
|
|
if (_npcConfig.NPCType == (int)E_NpcType.Fight)
|
{
|
GActorNpcFight _fight = m_AllList[i] as GActorNpcFight;
|
if (_fight != null && _fight.ActorInfo != null && !_fight.ActorInfo.serverDie)
|
{
|
if (npcID == 0)
|
{
|
return _fight;
|
}
|
else if (_fight.NpcConfig != null && _fight.NpcConfig.NPCID == npcID)
|
{
|
return _fight;
|
}
|
}
|
}
|
else
|
{
|
GActorNpcNoFight _noFight = m_AllList[i] as GActorNpcNoFight;
|
if (_noFight != null)
|
{
|
if (_noFight.NpcConfig != null && _noFight.NpcConfig.NPCID == npcID)
|
{
|
return _noFight;
|
}
|
}
|
}
|
}
|
|
|
return null;
|
}
|
|
public List<GActor> GetGroupList(E_ActorGroup group)
|
{
|
if (m_Group.ContainsKey((byte)group))
|
{
|
return m_Group[(byte)group];
|
}
|
return null;
|
}
|
|
public List<GActor> GetTypeList(E_ActorClassType type)
|
{
|
List<GActor> _list = null;
|
if (m_Type.TryGetValue((byte)type, out _list))
|
{
|
return _list;
|
}
|
return null;
|
}
|
|
public GActorFight GetGroupCloestTarget(Vector3 chkPos, E_ActorGroup group)
|
{
|
List<GActor> _enemyList = GetGroupList(group);
|
|
if (_enemyList != null && _enemyList.Count > 0)
|
{
|
_enemyList.Sort((GActor a1, GActor a2) =>
|
{
|
|
float _d1 = MathUtility.DistanceSqrtXZ(a1.Pos, chkPos);
|
float _d2 = MathUtility.DistanceSqrtXZ(a2.Pos, chkPos);
|
|
if (_d1 < _d2)
|
{
|
return -1;
|
}
|
else if (_d1 > _d2)
|
{
|
return 1;
|
}
|
|
return 0;
|
});
|
|
return _enemyList[0] as GActorFight;
|
}
|
|
return null;
|
}
|
|
public List<GActor> GetAll()
|
{
|
return m_AllList;
|
}
|
|
|
public void DoUpdate()
|
{
|
for (int i = m_AllList.Count - 1; i >= 0; --i)
|
{
|
if (i >= m_AllList.Count)
|
{
|
//其他地方做了协程删除,可能导致此处错误
|
continue;
|
}
|
if (m_AllList[i] == null)
|
continue;
|
m_AllList[i].Update();
|
}
|
|
UpdateOffLinePlayer();
|
}
|
|
public void DoLateUpdate()
|
{
|
for (int i = m_AllList.Count - 1; i >= 0; --i)
|
{
|
if (i >= m_AllList.Count)
|
{
|
//其他地方做了协程删除,可能导致此处错误
|
continue;
|
}
|
if (m_AllList[i] == null)
|
continue;
|
m_AllList[i].LateUpdate();
|
}
|
}
|
|
public List<uint> _removeIdList = new List<uint>();
|
|
public void DoFixedUpdate()
|
{
|
for (int i = m_AllList.Count - 1; i >= 0; --i)
|
{
|
if (i >= m_AllList.Count)
|
{
|
//其他地方做了协程删除,可能导致此处错误
|
continue;
|
}
|
if (m_AllList[i] == null)
|
continue;
|
m_AllList[i].FixedUpdate();
|
}
|
|
for (int i = m_BossSkillTipList.Count - 1; i >= 0; --i)
|
{
|
if (m_BossSkillTipList[i] == null)
|
{
|
m_BossSkillTipList.RemoveAt(i);
|
continue;
|
}
|
|
m_BossSkillTipList[i].Update();
|
|
if (m_BossSkillTipList[i].IsFinished)
|
{
|
m_BossSkillTipList.RemoveAt(i);
|
}
|
}
|
|
_removeIdList.Clear();
|
|
foreach (uint _id in otherPlayerAtkHeroDict.Keys)
|
{
|
if (Time.realtimeSinceStartup - otherPlayerAtkHeroDict[_id] > 2f)
|
{
|
_removeIdList.Add(_id);
|
}
|
}
|
|
for (int i = 0; i < _removeIdList.Count; ++i)
|
{
|
if (otherPlayerAtkHeroDict.ContainsKey(_removeIdList[i]))
|
{
|
GA_Hero.CallOnStopBeAttacked(_removeIdList[i]);
|
otherPlayerAtkHeroDict.Remove(_removeIdList[i]);
|
}
|
}
|
|
_removeIdList.Clear();
|
|
foreach (uint _id in atkOtherPlayerDict.Keys)
|
{
|
if (Time.realtimeSinceStartup - atkOtherPlayerDict[_id] > 2f)
|
{
|
_removeIdList.Add(_id);
|
}
|
}
|
|
for (int i = 0; i < _removeIdList.Count; ++i)
|
{
|
if (atkOtherPlayerDict.ContainsKey(_removeIdList[i]))
|
{
|
atkOtherPlayerDict.Remove(_removeIdList[i]);
|
}
|
}
|
|
//if (serverDeadList.Count > 0)
|
//{
|
// GActor _deadActor = null;
|
// for (int i = serverDeadList.Count - 1; i >= 0; --i)
|
// {
|
// if (!serverDeadDict.ContainsKey(serverDeadList[i]))
|
// {
|
// Debug.LogFormat("死亡字典里没有: {0}", serverDeadList[i]);
|
// serverDeadList.RemoveAt(i);
|
// continue;
|
// }
|
|
// if (Time.realtimeSinceStartup - serverDeadDict[serverDeadList[i]] > 1)
|
// {
|
// _deadActor = GetByCID(serverDeadList[i]);
|
|
// if (_deadActor != null)
|
// {
|
// _deadActor.Die();
|
// }
|
|
// Debug.LogFormat("死亡处理了: {0}", serverDeadList[i]);
|
|
// serverDeadDict.Remove(serverDeadList[i]);
|
// serverDeadList.RemoveAt(i);
|
// }
|
// }
|
//}
|
}
|
|
public void DoDelayDie(GActorFight target)
|
{
|
StartCoroutine(DelayDie(target));
|
}
|
|
public IEnumerator DelayDie(GActorFight target)
|
{
|
float _delayTime = Time.realtimeSinceStartup;
|
while (Time.realtimeSinceStartup - _delayTime < 3)
|
{
|
yield return null;
|
}
|
|
if (!target.ActorInfo.serverDie)
|
{
|
//Debug.LogFormat("目标为: {0} 未死亡", target.ClientInstID);
|
yield break;
|
}
|
|
// Debug.Log("将要判断的目标为: " + target.ClientInstID);
|
|
foreach (var _cid in m_Sid2Cid.Values)
|
{
|
if (_cid == target.ClientInstID)
|
{
|
// Debug.LogFormat("目标为: {0} 存在于列表中", target.ClientInstID);
|
yield break;
|
}
|
}
|
|
byte _actorClassType = GetActorClassType(target.GetType());
|
Stack<GActor> _stack = null;
|
if (m_Free.TryGetValue(_actorClassType, out _stack))
|
{
|
if (!_stack.Contains(target))
|
{
|
Release(target);
|
// Debug.LogFormat("不在空闲, 移除: {0}", target.ClientInstID);
|
}
|
}
|
else
|
{
|
Release(target);
|
// Debug.LogFormat("直接移除: {0}", target.ClientInstID);
|
}
|
}
|
|
private void BuildManagerRelation(GActor _actor, byte _actorClassType)
|
{
|
// 加入组
|
List<GActor> _list = null;
|
if (!m_Group.TryGetValue((byte)_actor.Group, out _list))
|
{
|
_list = new List<GActor>();
|
m_Group.Add((byte)_actor.Group, _list);
|
}
|
_list.Add(_actor);
|
|
// 加入类型
|
if (!m_Type.TryGetValue(_actorClassType, out _list))
|
{
|
_list = new List<GActor>();
|
m_Type.Add(_actorClassType, _list);
|
}
|
_list.Add(_actor);
|
|
// 所有
|
m_AllList.Add(_actor);
|
|
#if UNITY_EDITOR
|
if (m_Sid2Cid.ContainsKey(_actor.ServerInstID))
|
{
|
Debug.LogErrorFormat("创建服务端对象: {0} 的时候, 发现客户端已存在此ID.", _actor.ServerInstID);
|
}
|
|
if (m_Cid2GA.ContainsKey(_actor.ClientInstID))
|
{
|
Debug.LogErrorFormat("创建客户端对象: {0} 的时候, 发现客户端已存在此ID.", _actor.ClientInstID);
|
}
|
#endif
|
// id对应关系确定
|
m_Sid2Cid[_actor.ServerInstID] = _actor.ClientInstID;
|
m_Cid2GA[_actor.ClientInstID] = _actor;
|
}
|
|
private byte GetActorClassType(Type _type)
|
{
|
if (_type == typeof(GA_Hero))
|
{
|
return (byte)E_ActorClassType.Hero;
|
}
|
else if (_type == typeof(GA_NpcFightNorm))
|
{
|
return (byte)E_ActorClassType.NpcFightNorm;
|
}
|
else if (_type == typeof(GA_NpcFightBoss))
|
{
|
return (byte)E_ActorClassType.NpcFightBoss;
|
}
|
else if (_type == typeof(GA_Guard))
|
{
|
return (byte)E_ActorClassType.Guard;
|
}
|
else if (_type == typeof(GA_Player))
|
{
|
return (byte)E_ActorClassType.Player;
|
}
|
else if (_type == typeof(GA_NpcSummonFunc))
|
{
|
return (byte)E_ActorClassType.NpcSummonFunc;
|
}
|
else if (_type == typeof(GA_NpcFunc))
|
{
|
return (byte)E_ActorClassType.NpcFunc;
|
}
|
else if (_type == typeof(GA_Pet))
|
{
|
return (byte)E_ActorClassType.Pet;
|
}
|
else if (_type == typeof(GA_NpcCollect))
|
{
|
return (byte)E_ActorClassType.NpcCollect;
|
}
|
else if (_type == typeof(GA_NpcTouchKilled))
|
{
|
return (byte)E_ActorClassType.NpcTouchKilled;
|
}
|
else if (_type == typeof(GA_NpcClientFightNorm))
|
{
|
return (byte)E_ActorClassType.NpcClientFightNorm;
|
}
|
else if (_type == typeof(GA_NpcClientFightBoss))
|
{
|
return (byte)E_ActorClassType.NpcClientFightBoss;
|
}
|
else if (_type == typeof(GA_NpcClientFunc))
|
{
|
return (byte)E_ActorClassType.NpcClientFunc;
|
}
|
else if (_type == typeof(GA_NpcFightVirtualPlayer))
|
{
|
return (byte)E_ActorClassType.NpcFightVirtualPlayer;
|
}
|
else if (_type == typeof(GA_NpcSummonFight))
|
{
|
return (byte)E_ActorClassType.NpcSummonFight;
|
}
|
else if (_type == typeof(GA_PlayerXMZZ))
|
{
|
return (byte)E_ActorClassType.PlayerXmzz;
|
}
|
else if (_type == typeof(GA_PlayerClient))
|
{
|
return (byte)E_ActorClassType.ClientPlayer;
|
}
|
else if (_type == typeof(GA_NpcFightZZPlayer))
|
{
|
return (byte)E_ActorClassType.PlayerZZ;
|
}
|
else if (_type == typeof(GA_NpcFightSgzcZZ))
|
{
|
return (byte)E_ActorClassType.PlayerSgzcRobot;
|
}
|
else if (_type == typeof(GA_PVPClientPlayer))
|
{
|
return (byte)E_ActorClassType.PVPClientPlayer;
|
}
|
else if (_type == typeof(GA_ILClientPlayer))
|
{
|
return (byte)E_ActorClassType.ILClientPlayer;
|
}
|
else if (_type == typeof(GA_NpcClientCollect))
|
{
|
return (byte)E_ActorClassType.NpcClientCollect;
|
}
|
else if (_type == typeof(GA_JiaPlayer))
|
{
|
return (byte)E_ActorClassType.JiaPlayer;
|
}
|
|
return (byte)E_ActorClassType.UnDefine;
|
}
|
|
/// <summary>
|
/// 默认由主角发起的寻找目标逻辑
|
/// </summary>
|
/// <param name="chkPos">检测点</param>
|
/// <param name="r">检测半径</param>
|
/// <param name="angle">检测角度</param>
|
/// <param name="lockNpcID">是否锁定NPCID</param>
|
/// <returns></returns>
|
public GActorFight FindAtkTarget(Vector3 chkPos,
|
float r,
|
float angle = 360,
|
int lockNpcID = -1)
|
{
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
// 如果在安全区则直接返回空
|
if (MapArea.IsInMapArea(_hero.CurMapArea, MapArea.E_Type.RebornSafe)
|
|| MapArea.IsInMapArea(_hero.CurMapArea, MapArea.E_Type.Safe))
|
{
|
return null;
|
}
|
|
GActorFight _actor = null;
|
|
// 判断模式, 是否优先搜索其他玩家目标对象
|
// 全体模式, 强制模式 需要对玩家进行预先判断
|
if ((E_AttackMode)PlayerDatas.Instance.baseData.AttackMode == E_AttackMode.All
|
|| (E_AttackMode)PlayerDatas.Instance.baseData.AttackMode == E_AttackMode.Family
|
|| PlayerDatas.Instance.maliciousAtkPlayer.Count > 0
|
|| ClientCrossServerOneVsOne.isClientCrossServerOneVsOne
|
|| ArenaManager.isArenaClient)
|
{
|
List<GActor> _list = GetGroupList(E_ActorGroup.Player);
|
DoFindTarget(_list, chkPos, r, ref _actor, angle, lockNpcID);
|
}
|
|
// 没有找到可攻击目标, 开始找BossNpc
|
if (_actor == null)
|
{
|
List<GActor> _list = GetTypeList(E_ActorClassType.NpcFightBoss);
|
DoFindTarget(_list, chkPos, r, ref _actor, angle, lockNpcID);
|
}
|
|
// 没有找到可攻击目标, 开始找客户端BossNpc
|
if (_actor == null)
|
{
|
List<GActor> _list = GetTypeList(E_ActorClassType.NpcClientFightBoss);
|
DoFindTarget(_list, chkPos, r, ref _actor, angle, lockNpcID);
|
}
|
|
// 没有找到可攻击目标, 开始找Npc
|
if (_actor == null)
|
{
|
List<GActor> _list = GetTypeList(E_ActorClassType.NpcFightNorm);
|
DoFindTarget(_list, chkPos, r, ref _actor, angle, lockNpcID);
|
}
|
|
// 没有找到可攻击目标, 开始找客户端Npc
|
if (_actor == null)
|
{
|
List<GActor> _list = GetTypeList(E_ActorClassType.NpcClientFightNorm);
|
DoFindTarget(_list, chkPos, r, ref _actor, angle, lockNpcID);
|
}
|
|
return _actor;
|
}
|
|
private void DoFindTarget(List<GActor> list,
|
Vector3 chkPos,
|
float r,
|
ref GActorFight target,
|
float angle = 360,
|
int lockNpcID = -1)
|
{
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
|
if (list == null || list.Count == 0)
|
{
|
target = null;
|
return;
|
}
|
|
// 先将列表所有对象进行从近到远排序
|
list.Sort((GActor a1, GActor a2) =>
|
{
|
float _chk1 = MathUtility.DistanceSqrtXZ(chkPos, a1.Pos);
|
float _chk2 = MathUtility.DistanceSqrtXZ(chkPos, a2.Pos);
|
return _chk1 < _chk2 ? -1 : 1;
|
});
|
|
GActorFight _other;
|
IOtherSelectable _selectable;
|
Vector3 _targetDir;
|
float _chkAngle;
|
float _chkDistSqrt;
|
int _index = -1;
|
for (int i = 0; i < list.Count; ++i)
|
{
|
if (list[i].ActorInfo.serverDie)
|
{
|
continue;
|
}
|
|
_other = list[i] as GActorFight;
|
|
if (_other == null || !_other.CanAtked())
|
{
|
continue;
|
}
|
|
_selectable = list[i] as IOtherSelectable;
|
|
if (_selectable != null && !_selectable.CanBeSelected())
|
{
|
continue;
|
}
|
|
if (lockNpcID > 0)
|
{
|
GActorNpcFight _npc = list[i] as GActorNpcFight;
|
if (_npc == null || _npc.NpcConfig.NPCID != lockNpcID)
|
{
|
continue;
|
}
|
}
|
|
// 判断距离
|
_chkDistSqrt = MathUtility.DistanceSqrtXZ(_other.Pos, chkPos);
|
if (_chkDistSqrt > Mathf.Pow(r, 2))
|
{
|
continue;
|
}
|
|
// 判断方向
|
_targetDir = MathUtility.ForwardXZ(list[i].Pos, chkPos);//(list[i].Pos - chkPos).normalized;
|
_chkAngle = Vector3.Angle(_targetDir, _hero.destForward);
|
if (_chkAngle <= angle * .5f)
|
{
|
_index = i;
|
break;
|
}
|
}
|
|
if (_index >= 0)
|
{
|
target = list[_index] as GActorFight;
|
}
|
else
|
{
|
target = null;
|
}
|
}
|
|
#if UNITY_EDITOR
|
|
/// <summary>
|
/// 检测是否没有卸载干净的情况
|
/// </summary>
|
private void DebugUnInit()
|
{
|
if (m_AllList.Count > 0)
|
{
|
Debug.LogWarningFormat("卸载后发现 m_AllList 还有 {0} 个对象", m_AllList.Count);
|
for (int i = 0; i < m_AllList.Count; ++i)
|
{
|
if (i >= m_AllList.Count)
|
{
|
//其他地方做了协程删除,可能导致此处错误
|
continue;
|
}
|
if (m_AllList[i] == null)
|
continue;
|
if (m_AllList[i].Root != null)
|
{
|
Debug.LogWarningFormat(" |-- " + m_AllList[i].Root.name);
|
}
|
}
|
}
|
|
if (m_Cid2GA.Count > 0)
|
{
|
Debug.LogWarningFormat("卸载后发现 m_Cid2GA 还有 {0} 个对象", m_Cid2GA.Count);
|
}
|
|
foreach (var _group in m_Group.Keys)
|
{
|
if (m_Group[_group] != null && m_Group[_group].Count > 0)
|
{
|
Debug.LogWarningFormat("卸载后发现组: {0} 还有 {1} 个对象", (E_ActorGroup)_group, m_Group[_group].Count);
|
}
|
}
|
|
foreach (var _type in m_Type.Keys)
|
{
|
if (m_Type[_type] != null && m_Type[_type].Count > 0)
|
{
|
Debug.LogWarningFormat("卸载后发现类别: {0} 还有 {1} 个对象", (E_ActorClassType)_type, m_Type[_type].Count);
|
}
|
}
|
}
|
|
#endif
|
}
|