EnemyCreater.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using cfg;
  5. using System.Threading.Tasks;
  6. using Base.Common;
  7. using System.Linq;
  8. public class EnemyCreater : MonoBehaviour
  9. {
  10. public static EnemyCreater instance;
  11. [SerializeField]public List<SingleCreateEnemyConfig> cfgCreateEnemy;
  12. public List<SingleCreateBuildingConfig> cfgCreateBuilding;
  13. public List<bool> createdEnemy;
  14. public List<float> createEnemyTime;
  15. public List<bool> createdBuilding;
  16. public List<float> createBuildingTime;
  17. public Dictionary<int, List<Enemy>> enemyDic;
  18. public Dictionary<int, GameObject> buildingDic;
  19. private LevelSelect.Level curLevel;
  20. [Header("传送门")]
  21. public float portalsCreateTime = 10; //传送门提前出现时间
  22. public Transform portalUIParent; //传送门出现提示UI的父物体
  23. private void Awake()
  24. {
  25. if (!instance)
  26. {
  27. instance = this;
  28. }
  29. else
  30. {
  31. DestroyImmediate(gameObject);
  32. return;
  33. }
  34. enemyDic = new Dictionary<int, List<Enemy>>();
  35. buildingDic = new Dictionary<int, GameObject>();
  36. }
  37. private void Start()
  38. {
  39. curLevel = GetComponent<LevelSelect>().levelConfig[GetComponent<LevelSelect>().curLevelID];
  40. cfgCreateEnemy = GameManager.instance.allCfgData.CfgCreateEnemy.DataList;
  41. cfgCreateBuilding = GameManager.instance.allCfgData.CfgCreateBuilding.DataList;
  42. createdEnemy = new List<bool>();
  43. createdBuilding = new List<bool>();
  44. for (int i = 0; i < cfgCreateEnemy.Count; i++)
  45. {
  46. createdEnemy.Add(false);
  47. createEnemyTime.Add(cfgCreateEnemy[i].Time);
  48. }
  49. for (int i = 0; i < cfgCreateBuilding.Count; i++)
  50. {
  51. createdBuilding.Add(false);
  52. createBuildingTime.Add(cfgCreateBuilding[i].Time);
  53. }
  54. }
  55. public void OnGameTimeChange(float gameTime)
  56. {
  57. for (int i = 0; i < cfgCreateEnemy.Count; i++)
  58. {
  59. if (cfgCreateEnemy[i].LevelID == curLevel.enemyExcelID)
  60. {
  61. if (createEnemyTime[i] != 0)
  62. {
  63. if (createEnemyTime[i] + cfgCreateEnemy[i].DelayTime <= gameTime && !createdEnemy[i])
  64. {
  65. createdEnemy[i] = true;
  66. StartCreateEnemy(i);
  67. }
  68. }
  69. else
  70. {
  71. GameObject result = null;
  72. buildingDic.TryGetValue(cfgCreateEnemy[i].BuildingID, out result);
  73. if (result != null)
  74. {
  75. //根据防御塔血量出怪
  76. EnemyTower enemyTower = result.GetComponent<EnemyTower>();
  77. if (enemyTower != null && !createdEnemy[i] && enemyTower.hp * 100 <= enemyTower.totalHp * cfgCreateEnemy[i].BuildingHP)
  78. {
  79. if (cfgCreateEnemy[i].DelayTime == 0)
  80. {
  81. createdEnemy[i] = true;
  82. StartCreateEnemy(i);
  83. }
  84. else
  85. {
  86. createEnemyTime[i] = gameTime;
  87. }
  88. }
  89. //根据传送门血量出怪
  90. CoreCharacter coreCharacter = result.GetComponentInChildren<CoreCharacter>();
  91. PortalsCreater portalsCreater = result.GetComponent<PortalsCreater>();
  92. if (coreCharacter != null && !createdEnemy[i] && portalsCreater.createTimeCountDown < 0 && coreCharacter.hp * 100 <= coreCharacter.totalHp * cfgCreateEnemy[i].BuildingHP)
  93. {
  94. if (cfgCreateEnemy[i].DelayTime == 0)
  95. {
  96. createdEnemy[i] = true;
  97. StartCreateEnemy(i);
  98. }
  99. else
  100. {
  101. createEnemyTime[i] = gameTime;
  102. }
  103. }
  104. }
  105. }
  106. }
  107. }
  108. for (int i = 0; i < cfgCreateBuilding.Count; i++)
  109. {
  110. if (cfgCreateBuilding[i].LevelID == curLevel.buildingExcelID)
  111. {
  112. if (createBuildingTime[i] != 0)
  113. {
  114. if (!createdBuilding[i]
  115. && (cfgCreateBuilding[i].Type == 0 && createBuildingTime[i] + cfgCreateBuilding[i].DelayTime - portalsCreateTime <= gameTime
  116. || cfgCreateBuilding[i].Type == 1 && createBuildingTime[i] + cfgCreateBuilding[i].DelayTime <= gameTime))
  117. {
  118. createdBuilding[i] = true;
  119. if (gameTime < portalsCreateTime)
  120. {
  121. StartCreateBuilding(i, createBuildingTime[i] - gameTime);
  122. }
  123. else
  124. {
  125. StartCreateBuilding(i, portalsCreateTime);
  126. }
  127. }
  128. }
  129. else
  130. {
  131. GameObject result = null;
  132. buildingDic.TryGetValue(cfgCreateBuilding[i].RefreshBuildingID, out result);
  133. if (result != null)
  134. {
  135. //根据防御塔血量出怪
  136. EnemyTower enemyTower = result.GetComponent<EnemyTower>();
  137. if (enemyTower != null && !createdBuilding[i] && enemyTower.hp * 100 <= enemyTower.totalHp * cfgCreateBuilding[i].RefreshBuildingHP)
  138. {
  139. if (cfgCreateBuilding[i].DelayTime == 0)
  140. {
  141. createdBuilding[i] = true;
  142. StartCreateBuilding(i, portalsCreateTime);
  143. }
  144. else
  145. {
  146. createBuildingTime[i] = gameTime;
  147. }
  148. }
  149. //根据传送门血量出怪
  150. CoreCharacter coreCharacter = result.GetComponentInChildren<CoreCharacter>();
  151. PortalsCreater portalsCreater = result.GetComponent<PortalsCreater>();
  152. if (coreCharacter != null && !createdBuilding[i] && portalsCreater.createTimeCountDown < 0 && coreCharacter.hp * 100 <= coreCharacter.totalHp * cfgCreateBuilding[i].RefreshBuildingHP)
  153. {
  154. if (cfgCreateBuilding[i].DelayTime == 0)
  155. {
  156. createdBuilding[i] = true;
  157. StartCreateBuilding(i, portalsCreateTime);
  158. }
  159. else
  160. {
  161. createBuildingTime[i] = gameTime;
  162. }
  163. }
  164. }
  165. }
  166. }
  167. }
  168. }
  169. public void StartCreateBuilding(int id,float createTime)
  170. {
  171. SingleCreateBuildingConfig singleCreateBuilding = cfgCreateBuilding[id];
  172. if (!instance)
  173. {
  174. return;
  175. }
  176. switch (singleCreateBuilding.Type)
  177. {
  178. case 0:
  179. List<float> pos = singleCreateBuilding.Position.Concat(singleCreateBuilding.Position1).ToList();
  180. CreatePortal(singleCreateBuilding.ID, singleCreateBuilding.BuildingID, pos, singleCreateBuilding.Scale, singleCreateBuilding.HPRatio, createTime, singleCreateBuilding.DisappearTime);
  181. break;
  182. case 1:
  183. Vector3 positon = new Vector3(singleCreateBuilding.Position[0], singleCreateBuilding.Position[1], singleCreateBuilding.Position[2]);
  184. CreateEnemyTower(singleCreateBuilding.ID, singleCreateBuilding.BuildingID, singleCreateBuilding.HPRatio, singleCreateBuilding.AttackRatio, positon, singleCreateBuilding.DisappearTime);
  185. break;
  186. }
  187. }
  188. public async void StartCreateEnemy(int id)
  189. {
  190. SingleCreateEnemyConfig singleCreateEnemy = cfgCreateEnemy[id];
  191. for (int i = 0; i < singleCreateEnemy.Count; i++)
  192. {
  193. if (!instance)
  194. {
  195. return;
  196. }
  197. Vector3 pos = Vector3.zero;
  198. switch (singleCreateEnemy.Type)
  199. {
  200. case 0:
  201. pos = new Vector3(
  202. singleCreateEnemy.Position[0],
  203. singleCreateEnemy.Position[1]
  204. + Random.Range(-singleCreateEnemy.YRandomRange / 2, singleCreateEnemy.YRandomRange / 2),
  205. singleCreateEnemy.Position[2]
  206. + Random.Range(-singleCreateEnemy.ZRandomRange / 2, singleCreateEnemy.ZRandomRange / 2));
  207. break;
  208. case 1:
  209. GameObject building = buildingDic[singleCreateEnemy.BuildingID];
  210. pos = building.transform.position;
  211. pos.y += Random.Range(0, singleCreateEnemy.YRandomRange);
  212. pos.z += Random.Range(0, singleCreateEnemy.ZRandomRange);
  213. PortalsCreater portalsCreater = building.GetComponent<PortalsCreater>();
  214. if (portalsCreater != null)
  215. {
  216. portalsCreater.enemyNumber -= 1;
  217. portalsCreater.enemyNumberText.text = portalsCreater.enemyNumber.ToString();
  218. }
  219. break;
  220. }
  221. CreateEnemy(singleCreateEnemy.EnemyID, pos, singleCreateEnemy.HPRatio, singleCreateEnemy.AttackRatio);
  222. await Task.Delay((int)(singleCreateEnemy.TimeInterval * 1000));
  223. }
  224. }
  225. public void CreateEnemyTower(int ID, int buildingID, float hpRatio, float attackRatio, Vector3 pos, float disappearTime)
  226. {
  227. SingleBuildingConfig cfgBuilding = GameManager.instance.allCfgData.CfgBuilding.Get(buildingID);
  228. GameObject towerObj = Util.Instantiate(cfgBuilding.BuildingPrefab);
  229. towerObj.transform.position = pos;
  230. EnemyTower enemyTower = towerObj.GetComponent<EnemyTower>();
  231. buildingDic.Add(ID, towerObj);
  232. enemyTower.totalHp = (int)(cfgBuilding.HP * hpRatio);
  233. enemyTower.hp = enemyTower.totalHp;
  234. AttackInfo attackInfo = enemyTower.attack1Infos[0];
  235. attackInfo.damage = (int)(cfgBuilding.Attack * attackRatio);
  236. enemyTower.attack1Infos[0] = attackInfo;
  237. if(disappearTime > 0)
  238. {
  239. enemyTower.haveDisappearTime = true;
  240. enemyTower.disappearTime = disappearTime;
  241. }
  242. }
  243. public void CreatePortal(int ID, int buildingID, List<float> pos, List<float> scale, float hpRatio, float createTime, float disappearTime)
  244. {
  245. SingleBuildingConfig cfgBuilding = GameManager.instance.allCfgData.CfgBuilding.Get(buildingID);
  246. GameObject portalObj = Util.Instantiate(cfgBuilding.BuildingPrefab);
  247. PortalsCreater portalsCreater = portalObj.GetComponent<PortalsCreater>();
  248. portalsCreater.id = ID;
  249. buildingDic.Add(ID, portalObj);
  250. portalsCreater.totalHp = (int)(cfgBuilding.HP * hpRatio);
  251. portalsCreater.enemyCreater = this;
  252. portalsCreater.portalUIParent = portalUIParent;
  253. portalsCreater.Init(pos,scale,createTime);
  254. if (portalsCreater.enemyNumber == 0)
  255. {
  256. portalsCreater.enemyNumberText.transform.parent.gameObject.SetActive(false);
  257. if (portalsCreater.onlyEnemy)
  258. {
  259. portalsCreater.coreCharacter.CoreBreak();
  260. }
  261. }
  262. if(disappearTime > 0)
  263. {
  264. portalsCreater.haveDisappearTime = true;
  265. portalsCreater.disappearTime = disappearTime + createTime;
  266. }
  267. }
  268. public void CreateEnemy(int enemyId, Vector3 pos, float hpRatio, float attackRatio)
  269. {
  270. SingleEnemyConfig cfgEnemy = GameManager.instance.allCfgData.CfgEnemy.Get(enemyId);
  271. GameObject enemyObj = Util.Instantiate(cfgEnemy.EnemyPrefab, pos);
  272. if (enemyId > 1000)
  273. {
  274. Boss boss = enemyObj.GetComponentInChildren<Boss>();
  275. }
  276. else
  277. {
  278. Enemy enemy = enemyObj.GetComponent<Enemy>();
  279. enemy.id = enemyId;
  280. if (!enemyDic.ContainsKey(enemyId))
  281. {
  282. enemyDic.Add(enemyId, new List<Enemy>());
  283. }
  284. enemyDic[enemyId].Add(enemy);
  285. enemy.totalHp = (int)(cfgEnemy.HP * hpRatio);
  286. enemy.minMoveSpeed = cfgEnemy.MinMoveSpeed;
  287. enemy.maxMoveSpeed = cfgEnemy.MaxMoveSpeed;
  288. for (int i = 0; i < cfgEnemy.Attack1.Count; i++)
  289. {
  290. AttackInfo attackInfo = enemy.attack1Infos[i];
  291. attackInfo.damage = (int)(cfgEnemy.Attack1[i] * attackRatio);
  292. enemy.attack1Infos[i] = attackInfo;
  293. }
  294. for (int i = 0; i < cfgEnemy.Attack1.Count; i++)
  295. {
  296. AttackInfo attackInfo = enemy.attack2Infos[i];
  297. attackInfo.damage = (int)(cfgEnemy.Attack2[i] * attackRatio);
  298. enemy.attack2Infos[i] = attackInfo;
  299. }
  300. if (enemy.canFly)
  301. {
  302. enemy.flyHeight = enemy.transform.position.y;
  303. }
  304. enemy.Init();
  305. enemy.SetSortingOrder(enemy.baseSortingOrder + enemyDic[enemyId].Count);
  306. }
  307. }
  308. public void OnEnemyRecycle(Enemy enemy)
  309. {
  310. if (!enemyDic.ContainsKey(enemy.id))
  311. {
  312. return;
  313. }
  314. enemyDic[enemy.id].Remove(enemy);
  315. for (int i = 0; i < enemyDic[enemy.id].Count; i++)
  316. {
  317. enemyDic[enemy.id][i].SetSortingOrder(enemy.baseSortingOrder + i);
  318. }
  319. }
  320. public Enemy GetMinDisOtherEnemy(Enemy self)
  321. {
  322. Enemy minDisEnemy = null;
  323. foreach (var item in enemyDic)
  324. {
  325. for (int i = 0; i < item.Value.Count; i++)
  326. {
  327. if (item.Value[i] != self && !item.Value[i].isDie && item.Value[i].gameObject.activeInHierarchy)
  328. {
  329. if (!minDisEnemy || (minDisEnemy.transform.position - self.transform.position).magnitude
  330. > (item.Value[i].transform.position - self.transform.position).magnitude)
  331. {
  332. minDisEnemy = item.Value[i];
  333. }
  334. }
  335. }
  336. }
  337. return minDisEnemy;
  338. }
  339. }