ZoneSpawnerLogic.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityGameFramework.Runtime;
  5. using GameFramework.Event;
  6. namespace YLBattle
  7. {
  8. public class ZoneSpawnerLogic : MonoBehaviour
  9. {
  10. /// <summary>
  11. /// 专属GUID生成器
  12. /// </summary>
  13. protected static int _SGuid = 0;
  14. //protected static int SpawnerGUID { get { return ++_SGuid; } }
  15. protected static int CaretSpawnerGUID { get { return _SGuid; } }
  16. /// <summary>
  17. /// 孵化器ID
  18. /// </summary>
  19. //protected int spawnerId = 0;
  20. protected bool isClose = false;
  21. public bool IsClose { get { return isClose; } set { isClose = value; } }
  22. /// <summary>
  23. /// 运行时间
  24. /// </summary>
  25. public float runTime = 0;
  26. protected int nowUnitNum { get { return roleList.Count; } }
  27. protected int nowPointIndex = 0;
  28. protected List<Role> roleList = null;
  29. protected bool isStart = false; // 是否开始
  30. public ZoneSpawner spawnerInfo;
  31. /// <summary>
  32. /// 近战攻击角色
  33. /// </summary>
  34. private List<Role> mNearAttackRoles = new List<Role>();
  35. /// <summary>
  36. /// 远程攻击角色
  37. /// </summary>
  38. private List<Role> mFarAttackRoles = new List<Role>();
  39. //private List<SceneEventAreaLock> mAreaLocks = new List<SceneEventAreaLock>();
  40. private bool isCreateComplete = false;
  41. private Dictionary<int, SpawnerPatrolPoint> patrolDict;
  42. private SceneEventAreaLockLogic areaLock;
  43. private void Awake()
  44. {
  45. roleList = new List<Role>();
  46. patrolDict = new Dictionary<int, SpawnerPatrolPoint>();
  47. //spawnerId = CaretSpawnerGUID;
  48. spawnerInfo = this.gameObject.GetComponent<ZoneSpawner>();
  49. SpawnerSystem.Instance.Add(this);
  50. isCreateComplete = false;
  51. }
  52. private void Start()
  53. {
  54. EventComponent eventCmpt = GameEntry.GetComponent<EventComponent>();
  55. eventCmpt.Subscribe(BattleEventRemoveUnit.EventId, RemoveMonsterByEvent);
  56. SpawnerPatrolPoint[] ppoints = this.GetComponentsInChildren<SpawnerPatrolPoint>();
  57. // 初始化巡逻点
  58. foreach(var item in ppoints)
  59. {
  60. this.AddPatrolPoint(item);
  61. }
  62. if (spawnerInfo.areaLockIndex != 0)
  63. {
  64. areaLock = AIManager.Instance.GetAreaLockCmpt(spawnerInfo.areaLockIndex);
  65. }
  66. if (spawnerInfo.triggerType == ESpawnerTriggerType.TRIGGER_DEFAULT)
  67. {
  68. this.isStart = true;
  69. }
  70. if (!spawnerInfo.isEnable)
  71. {
  72. this.enabled = false;
  73. }
  74. if (spawnerInfo.enableType == ESpawnerEnableType.Enable_TC_DEFAULT)
  75. {
  76. bool isOk = false;
  77. List<TaskCardVo> taskVos = UserProxy.Instance.player.collectTaskCard.GetActivingCards();
  78. foreach (var item in taskVos)
  79. {
  80. if (int.Parse(item.typeId) != spawnerInfo.requirementTaskId)
  81. {
  82. continue;
  83. }
  84. List<Ins_TaskStepVo> stepVos = item.curSteps;
  85. foreach (var step in stepVos)
  86. {
  87. if (step.typeId == spawnerInfo.requirementStepId)
  88. {
  89. if (!step.isFinish())
  90. {
  91. isOk = true;
  92. }
  93. }
  94. }
  95. }
  96. if (!isOk)
  97. {
  98. this.isStart = true;
  99. this.enabled = true;
  100. }
  101. }
  102. runTime = spawnerInfo.produceTime;
  103. sm_gate gateMo = sm_gate.GetMoById(UserProxy.Instance.player.newMap.curMapId);
  104. if ((BattleDefine.EBattleSceneType)int.Parse(gateMo.battleType) == BattleDefine.EBattleSceneType.EBattleType_Endless ||
  105. (BattleDefine.EBattleSceneType)int.Parse(gateMo.battleType) == BattleDefine.EBattleSceneType.EBattleType_Defense)
  106. {
  107. return;
  108. }
  109. // 通过网络数据刷新关卡数据
  110. if (MapTcpProxy.Instance.Peer.MapData.spnSys != null)
  111. {
  112. Dictionary<int, NetData.Info_Map_Spawner> tbDict = MapTcpProxy.Instance.Peer.MapData.spnSys.GetAllSpawner();
  113. if(!tbDict.ContainsKey(spawnerInfo.index))
  114. {
  115. return;
  116. }
  117. Dictionary<int, Info_Map_RoleData> rDict = tbDict[this.spawnerInfo.index].roleDict;
  118. runTime = 0;
  119. foreach (var roleData in rDict)
  120. {
  121. sm_hero monster = sm_hero.GetMoByID(roleData.Value.tid);
  122. Vector3 pos = new Vector3(roleData.Value.posX, roleData.Value.posY, roleData.Value.posZ);
  123. RoleManager.Instance.CreateMonster(spawnerInfo.point, monster, roleData.Value.dropId, pos, pos, 0, roleData.Value.rType,
  124. (role) =>
  125. {
  126. role.SetPropertyFinal(null, EBattleProperty.HP, roleData.Value.hp);
  127. role.mBehaviorTree.SetVariableValue("WanderType", spawnerInfo.waitType); // 0静止1随机 2路径点巡逻,配合WanderPoints使用
  128. List<Transform> trasList = new List<Transform>();
  129. for (int i = 1; i <= patrolDict.Count; ++i)
  130. {
  131. trasList.Add(patrolDict[i].transform);
  132. }
  133. role.mBehaviorTree.SetVariableValue("WanderPoints", trasList);// WanderType类型2追加参数
  134. roleList.Add(role);
  135. });
  136. }
  137. this.isClose = tbDict[this.spawnerInfo.index].isClose;
  138. this.isCreateComplete = tbDict[this.spawnerInfo.index].isComplate;
  139. this.enabled = tbDict[this.spawnerInfo.index].isEnable;
  140. this.runTime = tbDict[this.spawnerInfo.index].runTime;
  141. }
  142. // 如果是副本 修正 isFill 填充怪物为false
  143. string[] spaName = this.transform.parent.name.Split('_');
  144. if (spaName.Length >= 2)
  145. {
  146. spawnerInfo.isFill = false;
  147. }
  148. }
  149. private void OnDestroy()
  150. {
  151. EventComponent eventCmpt = GameEntry.GetComponent<EventComponent>();
  152. if (eventCmpt.Check(BattleEventRemoveUnit.EventId, RemoveMonsterByEvent))
  153. {
  154. eventCmpt.Unsubscribe(BattleEventRemoveUnit.EventId, RemoveMonsterByEvent);
  155. }
  156. }
  157. private void Update()
  158. {
  159. if (!isStart)
  160. {
  161. return;
  162. }
  163. if (isClose)
  164. {
  165. return;
  166. }
  167. if (isCreateComplete)
  168. {
  169. return;
  170. }
  171. if (spawnerInfo.spawnType == ESpawnerCreateType.CREATE_DEFAULT)
  172. {
  173. isCreateComplete = true;
  174. StartCoroutine("CreateAllUnit");
  175. }
  176. else if (spawnerInfo.spawnType == ESpawnerCreateType.CREATE_LINE)
  177. {
  178. if(spawnerInfo.produceType == SpawnerNodeBase.ProduceType.Incomplete)
  179. {
  180. this.runTime += Time.deltaTime;
  181. if (runTime > spawnerInfo.produceTime)
  182. {
  183. runTime = 0;
  184. StartCoroutine("CreateMaxNumUnit");
  185. }
  186. }
  187. else if (spawnerInfo.produceType == SpawnerNodeBase.ProduceType.Clean)
  188. {
  189. if(roleList.Count == 0)
  190. {
  191. this.runTime += Time.deltaTime;
  192. if (runTime > spawnerInfo.produceTime)
  193. {
  194. runTime = 0;
  195. StartCoroutine("CreateMaxNumUnit");
  196. }
  197. }
  198. }
  199. }
  200. else if (spawnerInfo.spawnType == ESpawnerCreateType.CREATE_QUEUE)
  201. {
  202. // 读取存储怪物队列数据信息
  203. }
  204. }
  205. public virtual IEnumerator CreateAllUnit()
  206. {
  207. for (int i = 0; i < spawnerInfo.maxNum; ++i)
  208. {
  209. CreateUnit();
  210. yield return new WaitForSeconds(0.1f);
  211. }
  212. isClose = true;
  213. }
  214. public virtual IEnumerator CreateMaxNumUnit()
  215. {
  216. for (int i = roleList.Count; i < spawnerInfo.maxNum; ++i)
  217. {
  218. CreateUnit();
  219. yield return new WaitForSeconds(0.1f);
  220. }
  221. }
  222. /// <summary>
  223. /// 创建单位
  224. /// </summary>
  225. /// <param name="complete">是否为一次性创建完成</param>
  226. /// <returns></returns>
  227. public void CreateUnit()
  228. {
  229. if (isClose)
  230. {
  231. return;
  232. }
  233. spawnerInfo.createCount += 1;
  234. SpawnPoint point = GetSpawnerPoint();
  235. PointNext();
  236. if (point.unitId == 0)
  237. {
  238. return;
  239. }
  240. Vector3 pos = point.transform.Find("Cube").transform.position;
  241. Quaternion qua = point.transform.Find("Cube").transform.rotation;
  242. sm_hero monster = sm_hero.GetMoByID(point.unitId);
  243. RoleManager.Instance.CreateUnitBySpawner(spawnerInfo.index, monster, point.dropId, pos, qua, point.readius, point.roleType,
  244. (role) =>
  245. {
  246. role.mBehaviorTree.SetVariableValue("WanderType", spawnerInfo.waitType); // 0静止1随机 2路径点巡逻,配合WanderPoints使用
  247. List<Transform> trasList = new List<Transform>();
  248. for(int i = 1; i <= patrolDict.Count; ++i)
  249. {
  250. trasList.Add(patrolDict[i].transform);
  251. }
  252. role.mBehaviorTree.SetVariableValue("WanderPoints", trasList);// WanderType类型2追加参数
  253. role.bubType = point.bubbleType;
  254. role.bubStr = point.bubbleText;
  255. role.spawnerID = this.spawnerInfo.index;
  256. roleList.Add(role);
  257. // 地图怪物同步
  258. MapTcpProxy.Instance.Peer.MapData.spnSys.ResetData();
  259. if (MapTcpProxy.Instance.Peer.MapData.spnSys._spawnerDict.ContainsKey(spawnerInfo.index))
  260. {
  261. MapTcpProxy.Instance.Peer.ReportDataChange(MapTcpProxy.Instance.Peer.MapData.spnSys._spawnerDict[spawnerInfo.index]);
  262. }
  263. // 创建对话气泡框
  264. SceneBubbleWindow buCmpt = role.gameObject.AddComponent<SceneBubbleWindow>();
  265. buCmpt.SetContent(point.bubbleText);
  266. buCmpt.SetEnableType(point.bubbleType);
  267. });
  268. }
  269. public SpawnPoint GetSpawnerPoint()
  270. {
  271. return spawnerInfo.spawnList[nowPointIndex];
  272. }
  273. public List<Role> GetAllRole()
  274. {
  275. return roleList;
  276. }
  277. /// <summary>
  278. /// 激活本孵化器
  279. /// </summary>
  280. /// <param name="index"></param>
  281. public void EnableSpawner()
  282. {
  283. this.enabled = true;
  284. this.StartSpawner();
  285. }
  286. public bool PointNext()
  287. {
  288. ++nowPointIndex;
  289. if (nowPointIndex >= spawnerInfo.spawnList.Count)
  290. {
  291. nowPointIndex = 0;
  292. }
  293. if (!spawnerInfo.isFill)
  294. {
  295. if (spawnerInfo.createCount >= spawnerInfo.maxNum)
  296. {
  297. isClose = true;
  298. isCreateComplete = true;
  299. nowPointIndex = 0;
  300. }
  301. }
  302. return !isCreateComplete;
  303. }
  304. public void Reset()
  305. {
  306. //foreach (var item in roleList)
  307. //{
  308. // RoleManager.Instance.DestoryRole(item);
  309. //}
  310. //IsClose = false;
  311. //nowPointIndex = 0;
  312. }
  313. public bool IsCreateFinish()
  314. {
  315. return isCreateComplete;
  316. }
  317. public int GetMonsterNumber()
  318. {
  319. return roleList.Count;
  320. }
  321. public bool IsLastNode()
  322. {
  323. return spawnerInfo.isLastNode;
  324. }
  325. public void StartSpawner()
  326. {
  327. this.isStart = true;
  328. }
  329. public void OnTriggerEnter(Collider collider)
  330. {
  331. if (collider.gameObject.layer == LayerMask.NameToLayer("Player"))
  332. {
  333. foreach (var r in roleList)
  334. {
  335. // 创建对话气泡框
  336. if (r.bubType == SpawnPoint.BubbleType.Area && !r.bubEnable)
  337. {
  338. SceneBubbleWindow buCmpt = r.gameObject.AddComponent<SceneBubbleWindow>();
  339. buCmpt.SetContent(r.bubStr);
  340. buCmpt.SetEnableType(r.bubType);
  341. r.bubEnable = true;
  342. }
  343. }
  344. }
  345. if (spawnerInfo.triggerType != ESpawnerTriggerType.TRIGGER_COLLIDER)
  346. {
  347. return;
  348. }
  349. Role role = collider.GetComponent<Role>();
  350. if (role == null || !role.IsHero)
  351. {
  352. return;
  353. }
  354. this.isStart = true;
  355. }
  356. public void OnTriggerExit(Collider collider)
  357. {
  358. if (collider.gameObject.layer == LayerMask.GetMask("Enemy"))
  359. {
  360. }
  361. }
  362. /// <summary>
  363. /// 初始化
  364. /// </summary>
  365. public void Init()
  366. {
  367. spawnerInfo.mPointMos.Clear();
  368. }
  369. public int GetPointMaxNumber()
  370. {
  371. return this.transform.childCount;
  372. }
  373. public Transform GetPointMOByIndex(int index)
  374. {
  375. return this.transform.GetChild(index);
  376. }
  377. public bool CreateMonsterByPoint()
  378. {
  379. foreach (var item in spawnerInfo.mPointMos)
  380. {
  381. sm_hero monster = sm_hero.GetMoByID(item.Value.unitId);
  382. Vector3 pos = item.Value.transform.position;
  383. float readius = item.Value.readius;
  384. RoleManager.Instance.CreateMonster(spawnerInfo.point, monster, item.Value.dropId, pos, pos, readius, RoleType.Boss);
  385. }
  386. EventComponent nowEvent = GameEntry.GetComponent<EventComponent>();
  387. nowEvent.FireNow(this, new NoviceEventSpawnerIndex(spawnerInfo.point));
  388. return true;
  389. }
  390. public void RemoveMonsterByEvent(object sender, GameEventArgs e)
  391. {
  392. if (roleList.Count == 0)
  393. {
  394. return;
  395. }
  396. BattleEventRemoveUnit rmEvent = e as BattleEventRemoveUnit;
  397. if(roleList.Remove(rmEvent.role) != true)
  398. {
  399. return;
  400. }
  401. ;
  402. if (roleList.Count == 0)
  403. {
  404. // 禁区组件开启
  405. AIManager.Instance.RemoveAreaLockCmpt(spawnerInfo.areaLockIndex);
  406. // 激活下组孵化器
  407. foreach (var item in spawnerInfo.enableSpawnerList)
  408. {
  409. if (item != null)
  410. {
  411. item.enabled = true;
  412. item.gameObject.GetComponent<ZoneSpawnerLogic>().StartSpawner();
  413. }
  414. }
  415. // 关闭本孵化器
  416. if (spawnerInfo.spawnType != ESpawnerCreateType.CREATE_LINE)
  417. {
  418. this.enabled = false;
  419. this.spawnerInfo.isLastNode = true;
  420. }
  421. }
  422. // 地图怪物同步
  423. MapTcpProxy.Instance.Peer.MapData.spnSys.ResetData();
  424. if(MapTcpProxy.Instance.Peer.MapData.spnSys._spawnerDict.ContainsKey(spawnerInfo.index))
  425. {
  426. MapTcpProxy.Instance.Peer.ReportDataChange(MapTcpProxy.Instance.Peer.MapData.spnSys._spawnerDict[spawnerInfo.index]);
  427. }
  428. }
  429. /// <summary>
  430. /// 获取孵化器所孵化所有怪物
  431. /// </summary>
  432. /// <returns></returns>
  433. public int GetMonsterMaxNumber()
  434. {
  435. return spawnerInfo.mPointMos.Count;
  436. }
  437. public void AddPatrolPoint(SpawnerPatrolPoint point)
  438. {
  439. int index = int.Parse(point.name.Split('_')[1]);
  440. patrolDict[index] = point;
  441. MeshRenderer render = point.GetComponent<MeshRenderer>();
  442. render.enabled = false;
  443. }
  444. public bool IsCleanComplete()
  445. {
  446. return IsCreateFinish() && this.roleList.Count == 0;
  447. }
  448. }
  449. }