RockRoller.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. using Base.Common;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using cfg;
  6. using TMPro;
  7. public class RockRoller : Enemy
  8. {
  9. public int hitTime = 1;
  10. public int curHitTime = 0;
  11. public RockAttackTrigger attackTrigger0;
  12. public AttackTrigger attackEnemyTrigger0;
  13. public List<TargetType> initialTargetTypes = new List<TargetType>();
  14. public GameObject stone;
  15. public string smallStone;
  16. public float baseRotateSpeed = 90f;
  17. public float rotateMul = 1f;
  18. public float rotateDirection = -1f;
  19. public float dieTime = 0.1f;
  20. public float deathTimer = 0f;
  21. public bool isDying;
  22. public bool isFalled = false;
  23. public Enemy owner;
  24. public bool isGather = false;
  25. public float gatherTime = 1f;
  26. public float gatherTimer = 0f;
  27. public bool isWeak = false;
  28. public float weakTime = 1f;
  29. public float weakTimer = 0f;
  30. public float addForce = 1f;
  31. public bool isBig;
  32. private string enemyStr;
  33. public override void Init()
  34. {
  35. base.Init();
  36. }
  37. private void Awake()
  38. {
  39. base.Awake();
  40. InitializeComponents();
  41. InitializeAttackMethods();
  42. InitializeTargetTypes();
  43. InitializeStoneReference();
  44. }
  45. private void InitializeComponents()
  46. {
  47. TryGetComponent<Rigidbody>(out rb);
  48. }
  49. private void InitializeAttackMethods()
  50. {
  51. if (attackTrigger0 != null && attackTrigger0.attackMethod.attackInfo.damage == 0 &&
  52. attackEnemyTrigger0 != null && attackEnemyTrigger0.attackMethod.attackInfo.damage == 0)
  53. {
  54. attackTrigger0.attackMethod = attackController.attackMethod_march[0];
  55. attackEnemyTrigger0.attackMethod = attackController.attackMethod_summon[0];
  56. }
  57. }
  58. private void InitializeTargetTypes()
  59. {
  60. if (attackController != null && attackController.targetTypes != null)
  61. {
  62. initialTargetTypes.Clear();
  63. initialTargetTypes.AddRange(attackController.targetTypes);
  64. }
  65. }
  66. private void InitializeStoneReference()
  67. {
  68. if (stone == null)
  69. {
  70. stone = gameObject;
  71. }
  72. enemyStr = $"Prefab/Enemy/{smallStone}";
  73. }
  74. protected override void OnEnable()
  75. {
  76. base.OnEnable();
  77. ResetState();
  78. }
  79. private void ResetState()
  80. {
  81. hitFeedbackSystem.canBeHitStun = false;
  82. hitFeedbackSystem.canFreeze = false;
  83. isDying = false;
  84. isFalled = false;
  85. deathTimer = 0f;
  86. gatherTimer = 0f;
  87. isGather = false;
  88. weakTimer = 0f;
  89. isWeak = false;
  90. rotateDirection = -1f;
  91. curHitTime = 0;
  92. if (attackEnemyTrigger0 != null)
  93. attackEnemyTrigger0.gameObject.SetActive(false);
  94. if (attackTrigger0 != null)
  95. attackTrigger0.gameObject.SetActive(true);
  96. ResetTargetTypes();
  97. }
  98. private void ResetTargetTypes()
  99. {
  100. if (attackController != null && attackController.targetTypes != null)
  101. {
  102. attackController.targetTypes.Clear();
  103. attackController.targetTypes.AddRange(initialTargetTypes);
  104. }
  105. }
  106. public void Update()
  107. {
  108. UpdateHitFeedback();
  109. if (owner == null) return;
  110. HandleOwnerSpecialState();
  111. Rotate();
  112. }
  113. public void Rotate()
  114. {
  115. if (stone == null) return;
  116. float currentSpeed = baseRotateSpeed;
  117. if (rb != null)
  118. {
  119. currentSpeed = rb.velocity.magnitude * rotateMul * baseRotateSpeed;
  120. currentSpeed = Mathf.Clamp(currentSpeed, 0, baseRotateSpeed * 5);
  121. }
  122. stone.transform.Rotate(Vector3.forward, rotateDirection * currentSpeed * Time.deltaTime);
  123. }
  124. private void UpdateHitFeedback()
  125. {
  126. hitFeedbackSystem.canBeHitStun = false;
  127. hitFeedbackSystem.canFreeze = false;
  128. }
  129. private void HandleOwnerSpecialState()
  130. {
  131. if (owner.state == CharacterState.SpecialStatus_BlowUp)
  132. {
  133. if (attackTrigger0 != null)
  134. attackTrigger0.gameObject.SetActive(false);
  135. UpdateTargetTypesForAttack();
  136. }
  137. }
  138. private void UpdateTargetTypesForAttack()
  139. {
  140. if (attackController != null)
  141. {
  142. attackController.targetTypes.Clear();
  143. attackController.targetTypes.Add(TargetType.Enemy);
  144. attackController.targetTypes.Add(TargetType.EnemyTower);
  145. }
  146. }
  147. public override void FixedUpdate()
  148. {
  149. OnState();
  150. HandleDyingState();
  151. }
  152. private void HandleDyingState()
  153. {
  154. if (owner != null && owner.state == CharacterState.SpecialStatus_BlowUp &&
  155. owner.attributeStatus.hitState == 1 && !isDying)
  156. {
  157. StartDying();
  158. }
  159. if (isDying)
  160. {
  161. deathTimer += Time.deltaTime;
  162. if (deathTimer >= dieTime)
  163. {
  164. HandleDeath();
  165. }
  166. }
  167. }
  168. private void StartDying()
  169. {
  170. if (attackEnemyTrigger0 != null)
  171. attackEnemyTrigger0.gameObject.SetActive(true);
  172. isDying = true;
  173. isFalled = true;
  174. deathTimer = 0f;
  175. }
  176. private void HandleDeath()
  177. {
  178. if (isBig && isFalled)
  179. {
  180. SpawnSmallStones();
  181. }
  182. if (owner != null && curHitTime >= hitTime)
  183. {
  184. owner.gameObject.SetActive(false);
  185. }
  186. isDying = false;
  187. }
  188. private void SpawnSmallStones()
  189. {
  190. attackEnemyTrigger0.gameObject.SetActive(false);
  191. ResetTargetTypes();
  192. SingleEnemyConfig cfgEnemy = GameManager.instance.allCfgData.CfgEnemy.Get("小滚石怪");
  193. // 生成第一个小石头
  194. GameObject enemyObj = Util.Instantiate(enemyStr, transform.position - new Vector3(-1, 0, 0), active: true);
  195. ConfigureSmallStone(enemyObj, cfgEnemy);
  196. // 生成第二个小石头
  197. GameObject enemyObj1 = Util.Instantiate(enemyStr, transform.position - new Vector3(1, 0, 0), active: true);
  198. ConfigureSmallStone(enemyObj1, cfgEnemy);
  199. isFalled = false;
  200. }
  201. private void ConfigureSmallStone(GameObject stoneObj, SingleEnemyConfig cfgEnemy)
  202. {
  203. RockRoller rock = stoneObj.GetComponent<RockRoller>();
  204. if (rock != null)
  205. {
  206. rock.attackTrigger0.attackMethod.attackInfo.damage = cfgEnemy.AttackMarch[0];
  207. rock.attackEnemyTrigger0.attackMethod.attackInfo.damage = cfgEnemy.AttackSummon;
  208. rock.owner.moveSpeed = Random.Range(cfgEnemy.MinMoveSpeed, cfgEnemy.MaxMoveSpeed);
  209. }
  210. }
  211. public override void ChangeState(CharacterState newState)
  212. {
  213. if (state == newState || newState == CharacterState.FramePause)
  214. {
  215. return;
  216. }
  217. ExitCurrentState();
  218. EnterNewState(newState);
  219. }
  220. private void ExitCurrentState()
  221. {
  222. switch (state)
  223. {
  224. case CharacterState.Idle:
  225. rb.velocity = Vector3.zero;
  226. break;
  227. case CharacterState.Die:
  228. isDie = false;
  229. break;
  230. }
  231. }
  232. private void EnterNewState(CharacterState newState)
  233. {
  234. CharacterState oldState = state;
  235. state = newState;
  236. switch (newState)
  237. {
  238. case CharacterState.Idle:
  239. EnterIdleState();
  240. break;
  241. case CharacterState.Rush:
  242. EnterRushState();
  243. break;
  244. case CharacterState.Rise:
  245. EnterRiseState();
  246. break;
  247. case CharacterState.Fall:
  248. EnterFallState();
  249. break;
  250. case CharacterState.Die:
  251. EnterDieState();
  252. break;
  253. case CharacterState.SpecialStatus_BlowUp:
  254. EnterBlowUpState();
  255. break;
  256. }
  257. }
  258. private void EnterIdleState()
  259. {
  260. rotateDirection = -1f;
  261. rb.velocity = Vector3.zero;
  262. if (attackEnemyTrigger0 != null) attackEnemyTrigger0.gameObject.SetActive(false);
  263. if (attackTrigger0 != null) attackTrigger0.gameObject.SetActive(false);
  264. }
  265. private void EnterRushState()
  266. {
  267. rb.velocity = Vector3.zero;
  268. if (attackEnemyTrigger0 != null) attackEnemyTrigger0.gameObject.SetActive(false);
  269. if (attackTrigger0 != null) attackTrigger0.gameObject.SetActive(true);
  270. }
  271. private void EnterRiseState()
  272. {
  273. isGather = true;
  274. gatherTimer = 0f;
  275. }
  276. private void EnterFallState()
  277. {
  278. rotateDirection = 1f;
  279. weakTimer = 0f;
  280. }
  281. private void EnterDieState()
  282. {
  283. isDie = true;
  284. dieKeepTime = totalDieKeepTime;
  285. if (GameManager.instance.gameType != GameType.GameEnd)
  286. {
  287. DropSouls();
  288. }
  289. }
  290. private void EnterBlowUpState()
  291. {
  292. rotateDirection = 1f;
  293. curHitTime += 1;
  294. isDying = false;
  295. isFalled = true;
  296. deathTimer = 0f;
  297. if (owner != null) owner.attributeStatus.hitState = 0;
  298. }
  299. public override void OnState()
  300. {
  301. switch (state)
  302. {
  303. case CharacterState.Idle:
  304. ChangeState(CharacterState.Rise);
  305. break;
  306. case CharacterState.Rise:
  307. HandleRiseState();
  308. break;
  309. case CharacterState.Rush:
  310. HandleRushState();
  311. break;
  312. case CharacterState.Fall:
  313. HandleFallState();
  314. break;
  315. case CharacterState.SpecialStatus_BlowUp:
  316. attributeStatus.SpecialStateEffect(SpecialState.BlownUp);
  317. break;
  318. case CharacterState.Die:
  319. dieKeepTime -= Time.deltaTime;
  320. if (dieKeepTime <= 0)
  321. {
  322. if (killer != null && killer.GetComponent<Demonic>())
  323. {
  324. SoldierType st = killer.GetComponent<Demonic>().soldierType;
  325. SoldierEXP.expInstance.AddEXP(st, (int)(exp * LevelSelect.EXPRatio + 0.5f));
  326. }
  327. if (dieEffect)
  328. {
  329. PoolManager.Instantiate(dieEffect, transform.position);
  330. }
  331. GameManager gameManager = GameManager.instance;
  332. if (gameManager.gameType == GameType.GameEnd)
  333. {
  334. GameObject fx = PoolManager.Instantiate(gameManager.dropGoldFX);
  335. fx.transform.position = transform.position;
  336. GameObject injuryNum = PoolManager.Instantiate(gameManager.dropGoldText);
  337. injuryNum.transform.position = new Vector3(
  338. transform.position.x + injuryNumPos_march.x + Random.Range(-injuryNumRandom_march.x / 2f, injuryNumRandom_march.x / 2f),
  339. transform.position.y + injuryNumPos_march.y + Random.Range(-injuryNumRandom_march.y / 2f, injuryNumRandom_march.y / 2f),
  340. transform.position.z);
  341. TextMeshProUGUI text = injuryNum.GetComponentInChildren<TextMeshProUGUI>();
  342. text.text = $"+{gameManager.enemyGoldDrop}";
  343. }
  344. gameObject.SetActive(false);
  345. break;
  346. }
  347. break;
  348. break;
  349. }
  350. }
  351. private void HandleRiseState()
  352. {
  353. if (isGather && gatherTimer < gatherTime)
  354. {
  355. gatherTimer += Time.deltaTime;
  356. }
  357. else
  358. {
  359. Debug.Log("gatherFinsh");
  360. isGather = false;
  361. ChangeState(CharacterState.Rush);
  362. }
  363. }
  364. private void HandleRushState()
  365. {
  366. Vector3 velocity = rb.velocity;
  367. if (Mathf.Abs(velocity.x) < moveSpeed)
  368. {
  369. velocity.x += addForce;
  370. }
  371. rb.velocity = velocity;
  372. }
  373. private void HandleFallState()
  374. {
  375. if (!foot.TrigGround)
  376. {
  377. isWeak = true;
  378. }
  379. if (isWeak && weakTimer < weakTime && foot.TrigGround)
  380. {
  381. rb.velocity = Vector3.zero;
  382. weakTimer += Time.deltaTime;
  383. }
  384. else if (weakTimer >= weakTime)
  385. {
  386. isWeak = false;
  387. ChangeState(CharacterState.Idle);
  388. }
  389. }
  390. public void OnDisable()
  391. {
  392. EnemyCreater.instance.OnEnemyRecycle(this);
  393. ResetState();
  394. }
  395. }