Enemy.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
  2. using Sirenix.OdinInspector;
  3. using Spine;
  4. using Spine.Unity;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using TMPro;
  8. using Unity.VisualScripting;
  9. using UnityEngine;
  10. public enum SearchState
  11. {
  12. NoTarget = 0, //搜索范围内没有目标
  13. InSearchScope = 1, //在搜索范围内发现目标,但不在攻击范围内
  14. InAttackScope = 2, //目标在攻击范围内
  15. }
  16. public class Enemy : MoveCharacter
  17. {
  18. [Space(30)]
  19. [Title("Enemy属性")]
  20. [LabelText("击杀提供的经验值")]
  21. public int exp;
  22. [LabelText("死亡特效")]
  23. public GameObject dieEffect;
  24. public string name;
  25. public int baseSortingOrder;
  26. int sortingOrder = 0;
  27. public bool isBack = false; //往反方向走
  28. public float jumpSpeed = 10;
  29. public float maxMoveSpeed, minMoveSpeed;
  30. public float runSpeed;
  31. [Header("击飞、屏幕反弹")]
  32. public bool isBeBlownUp; //被击飞
  33. public bool isBeReboundedX; //X方向被反弹
  34. public bool isBeReboundedY; //Y方向被反弹
  35. private bool hasBeReboundedX;
  36. private bool hasBeReboundedY;
  37. public float reboundXSpeed;
  38. public float reboundYSpeed;
  39. public int wallDamage;
  40. [Header("敌方英灵")]
  41. public Spirits.SpiritType type;
  42. [Header("敌方单位组件")]
  43. public SearchState searchState;
  44. [Header("攻击")]
  45. public float attackRatio;
  46. protected int curAttackID;
  47. public int len;
  48. protected float pastAttackTime;
  49. protected bool isConAttack; //连续攻击,不切idle动画
  50. [Header("掉落魂")]
  51. public int dropSoulMax = 3;
  52. public int dropSoulMin = 1;
  53. public int dropProbability = 100;
  54. public float dropSoulAngle = 60f;
  55. public override void Awake()
  56. {
  57. base.Awake();
  58. }
  59. protected virtual void Start()
  60. {
  61. len = attackController.attackMethod_march.Length;
  62. }
  63. protected virtual void OnEnable()
  64. {
  65. Init();
  66. }
  67. protected override void OnDisable()
  68. {
  69. base.OnDisable();
  70. EnemyCreater.instance.OnEnemyRecycle(this);
  71. }
  72. public override void Init()
  73. {
  74. base.Init();
  75. moveSpeed = Random.Range(minMoveSpeed, maxMoveSpeed);
  76. spinee.transform.rotation = Quaternion.identity;
  77. ChangeSearchState(SearchState.NoTarget);
  78. attributeStatus.curSpecialStates = SpecialState.Null;
  79. attributeStatus.attributeTime = 0;
  80. curAttackID = 0;
  81. attackController.curAttackMethod = attackController.attackMethod_march[0];
  82. }
  83. public override void FixedUpdate()
  84. {
  85. OnSearchState();
  86. OnState();
  87. }
  88. public override Vector3 GetMoveDir()
  89. {
  90. Vector3 moveDir = Vector3.zero;
  91. switch (searchState)
  92. {
  93. case SearchState.NoTarget:
  94. if (TowerMap.myTowers.Count == 0)
  95. {
  96. moveDir = Vector3.right;
  97. break;
  98. }
  99. float minDistance = Mathf.Infinity;
  100. int id = -1;
  101. for (int i = 0; i < TowerMap.myTowers.Count; i++)
  102. {
  103. Tower myTower = TowerMap.myTowers[i].GetComponent<Tower>();
  104. if (transform.position.y >
  105. myTower.transform.position.y + myTower.height)
  106. {
  107. continue;
  108. }
  109. float distance = Vector3.Distance(transform.position,
  110. TowerMap.myTowers[i].transform.position);
  111. if (distance < minDistance)
  112. {
  113. minDistance = distance;
  114. id = i;
  115. }
  116. }
  117. if (id == -1)
  118. {
  119. moveDir = Vector3.right;
  120. break;
  121. }
  122. if (bodyTrans.position.x > TowerMap.myTowers[id].transform.position.x)
  123. {
  124. moveDir = Vector3.left;
  125. }
  126. else
  127. {
  128. moveDir = Vector3.right;
  129. }
  130. break;
  131. case SearchState.InSearchScope:
  132. if (targetCharacter)
  133. {
  134. if (targetCharacter.transform.position.x - transform.position.x < -1)
  135. {
  136. moveDir = Vector3.left;
  137. }
  138. else if(targetCharacter.transform.position.x - transform.position.x >1)
  139. {
  140. moveDir = Vector3.right;
  141. }
  142. else
  143. {
  144. moveDir = bodyTrans.localScale.x > 0 ? Vector3.left : Vector3.right;
  145. }
  146. }
  147. else
  148. {
  149. moveDir = Vector3.zero;
  150. }
  151. break;
  152. case SearchState.InAttackScope:
  153. if (targetCharacter)
  154. {
  155. if (targetCharacter.transform.position.x - transform.position.x < 0)
  156. {
  157. moveDir = Vector3.left;
  158. }
  159. else
  160. {
  161. moveDir = Vector3.right;
  162. }
  163. }
  164. else
  165. {
  166. moveDir = Vector3.zero;
  167. }
  168. break;
  169. default:
  170. break;
  171. }
  172. if (!isBack)
  173. {
  174. return moveDir;
  175. }
  176. return -moveDir;
  177. }
  178. public virtual bool GetAttack()
  179. {
  180. if (searchState == SearchState.InAttackScope)
  181. {
  182. return true;
  183. }
  184. return false;
  185. }
  186. public bool GetJump()
  187. {
  188. return false;
  189. }
  190. public override void OnState()
  191. {
  192. base.OnState();
  193. if (state == CharacterState.FramePause)
  194. {
  195. return;
  196. }
  197. //hurtKeepTime -= Time.deltaTime;
  198. invincibleTime -= Time.deltaTime;
  199. pastAttackTime += Time.deltaTime;
  200. Vector3 leftDir = GetMoveDir();
  201. bool isAttack = GetAttack();
  202. Vector3 velocity = rb.velocity;
  203. Quaternion targetQt = Quaternion.Euler(Vector3.zero);
  204. switch (state)
  205. {
  206. case CharacterState.Idle:
  207. if (isAdjustHeight == 1)
  208. {
  209. ChangeState(CharacterState.Rise);
  210. break;
  211. }
  212. else if (isAttack)
  213. {
  214. if (pastAttackTime >= attackController.attackInterval)
  215. {
  216. Attack_march();
  217. }
  218. }
  219. else
  220. {
  221. if (!foot.TrigGround && !canFly)
  222. {
  223. if (rb.velocity.y > 0)
  224. {
  225. ChangeState(CharacterState.Rise);
  226. break;
  227. }
  228. else
  229. {
  230. ChangeState(CharacterState.Fall);
  231. break;
  232. }
  233. }
  234. if (leftDir.x > 0.3f || leftDir.x < -0.3f)
  235. {
  236. ChangeState(CharacterState.Run);
  237. break;
  238. }
  239. velocity.y = 0;
  240. if (!foot.haveGravity)
  241. {
  242. transform.position = new Vector3(transform.position.x, platformPosY, transform.position.z);
  243. targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
  244. }
  245. if (RotLerpTime < 1)
  246. {
  247. RotLerpTime += RotLerpSpeed * Time.deltaTime;
  248. transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
  249. }
  250. else
  251. {
  252. transform.rotation = targetQt;
  253. }
  254. rb.velocity = velocity * moveSpeedScale;
  255. }
  256. break;
  257. case CharacterState.Run:
  258. if (isAttack)
  259. {
  260. if (pastAttackTime >= attackController.attackInterval)
  261. {
  262. Attack_march();
  263. }
  264. else
  265. {
  266. ChangeState(CharacterState.Idle);
  267. }
  268. }
  269. else
  270. {
  271. if (!foot.TrigGround && !canFly)
  272. {
  273. if (rb.velocity.y > 0)
  274. {
  275. ChangeState(CharacterState.Rise);
  276. break;
  277. }
  278. else
  279. {
  280. ChangeState(CharacterState.Fall);
  281. break;
  282. }
  283. }
  284. if (leftDir.x < 0.3f && leftDir.x > -0.3f)
  285. {
  286. ChangeState(CharacterState.Idle);
  287. break;
  288. }
  289. if (leftDir.x > 0.3f)
  290. {
  291. velocity.x = moveSpeed;
  292. if (bodyTrans.localScale.x > 0)
  293. {
  294. Turn();
  295. }
  296. }
  297. else if (leftDir.x < -0.3f)
  298. {
  299. velocity.x = -moveSpeed;
  300. if (bodyTrans.localScale.x < 0)
  301. {
  302. Turn();
  303. }
  304. }
  305. velocity.y = 0;
  306. if (!foot.haveGravity)
  307. {
  308. transform.position = new Vector3(transform.position.x, platformPosY, transform.position.z);
  309. targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
  310. }
  311. if (RotLerpTime < 1)
  312. {
  313. RotLerpTime += RotLerpSpeed * Time.deltaTime;
  314. transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
  315. }
  316. else
  317. {
  318. transform.rotation = targetQt;
  319. }
  320. rb.velocity = velocity * moveSpeedScale;
  321. AdjustHeight();
  322. }
  323. break;
  324. case CharacterState.Rush:
  325. if (isAttack)
  326. {
  327. if (pastAttackTime >= attackController.attackInterval)
  328. {
  329. Attack_march();
  330. }
  331. else
  332. {
  333. ChangeState(CharacterState.Idle);
  334. }
  335. }
  336. else
  337. {
  338. if (!foot.TrigGround && !canFly)
  339. {
  340. if (rb.velocity.y > 0)
  341. {
  342. ChangeState(CharacterState.Rise);
  343. break;
  344. }
  345. else
  346. {
  347. ChangeState(CharacterState.Attack);
  348. break;
  349. }
  350. }
  351. if (leftDir.x < 0.3f && leftDir.x > -0.3f)
  352. {
  353. ChangeState(CharacterState.Idle);
  354. break;
  355. }
  356. if (leftDir.x > 0.3f)
  357. {
  358. //rb.velocity += Vector3.right * moveAcc * Time.deltaTime;
  359. rb.velocity = Vector3.right * runSpeed * moveSpeedScale;
  360. //if (rb.velocity.x > maxMoveSpeed)
  361. //{
  362. // rb.velocity = new Vector3(maxMoveSpeed, rb.velocity.y, rb.velocity.z);
  363. //}
  364. if (bodyTrans.localScale.x > 0)
  365. {
  366. Turn();
  367. }
  368. }
  369. else if (leftDir.x < -0.3f)
  370. {
  371. //rb.velocity -= Vector3.right * moveAcc * Time.deltaTime;
  372. rb.velocity = Vector3.left * runSpeed * moveSpeedScale;
  373. //if (rb.velocity.x < -maxMoveSpeed)
  374. //{
  375. // rb.velocity = new Vector3(-maxMoveSpeed, rb.velocity.y, rb.velocity.z);
  376. //}
  377. if (bodyTrans.localScale.x < 0)
  378. {
  379. Turn();
  380. }
  381. }
  382. //AdjustHeight();
  383. }
  384. break;
  385. case CharacterState.Rise:
  386. if (isAdjustHeight == 1)
  387. {
  388. AdjustHeight();
  389. if (!foot.haveGravity)
  390. {
  391. targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
  392. }
  393. if (RotLerpTime < 1)
  394. {
  395. RotLerpTime += RotLerpSpeed * Time.deltaTime;
  396. transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
  397. }
  398. else
  399. {
  400. transform.rotation = targetQt;
  401. }
  402. }
  403. else if (isAdjustHeight == 2)
  404. {
  405. ChangeState(CharacterState.Idle);
  406. isAdjustHeight = 0;
  407. }
  408. else
  409. {
  410. if (rb.velocity.y <= 0)
  411. {
  412. ChangeState(CharacterState.Fall);
  413. break;
  414. }
  415. velocity.y += extraRiseGravity * Time.deltaTime;
  416. if (leftDir.x > 0.3f)
  417. {
  418. velocity.x = moveSpeed;
  419. if (bodyTrans.localScale.x > 0)
  420. {
  421. Turn();
  422. }
  423. }
  424. else if (leftDir.x < -0.3f)
  425. {
  426. velocity.x = -moveSpeed;
  427. if (bodyTrans.localScale.x < 0)
  428. {
  429. Turn();
  430. }
  431. }
  432. rb.velocity = velocity * moveSpeedScale;
  433. }
  434. break;
  435. case CharacterState.Fall:
  436. if (foot.TrigGround || canFly)
  437. {
  438. ChangeState(CharacterState.Idle);
  439. break;
  440. }
  441. velocity.y += extraFallGravity * Time.deltaTime;
  442. if (leftDir.x > 0.3f)
  443. {
  444. velocity.x = moveSpeed;
  445. if (bodyTrans.localScale.x > 0)
  446. {
  447. Turn();
  448. }
  449. }
  450. else if (leftDir.x < -0.3f)
  451. {
  452. velocity.x = -moveSpeed;
  453. if (bodyTrans.localScale.x < 0)
  454. {
  455. Turn();
  456. }
  457. }
  458. rb.velocity = velocity * moveSpeedScale;
  459. break;
  460. case CharacterState.Attack:
  461. attackController.JudgeTriggerOnOff();
  462. if (attackController.attackTime <= 0)
  463. {
  464. isAttack = GetAttack();
  465. if (isAttack)
  466. {
  467. isConAttack = true;
  468. }
  469. ChangeState(CharacterState.Idle);
  470. break;
  471. }
  472. if (!foot.haveGravity)
  473. {
  474. targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
  475. }
  476. if (RotLerpTime < 1)
  477. {
  478. RotLerpTime += RotLerpSpeed * Time.deltaTime;
  479. transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
  480. }
  481. else
  482. {
  483. transform.rotation = targetQt;
  484. }
  485. break;
  486. case CharacterState.Die:
  487. //if (killer != null && killer.GetComponent<Demonic>())
  488. //{
  489. // SoldierType st = killer.GetComponent<Demonic>().soldierType;
  490. // SoldierEXP.expInstance.AddEXP(st, (int)(exp * LevelSelect.EXPRatio + 0.5f));
  491. //}
  492. //if (dieEffect)
  493. //{
  494. // PoolManager.Instantiate(dieEffect, transform.position);
  495. //}
  496. //GameManager gameManager = GameManager.instance;
  497. //if (gameManager.gameType == GameType.GameEnd)
  498. //{
  499. // GameObject fx = PoolManager.Instantiate(gameManager.dropGoldFX);
  500. // fx.transform.position = transform.position;
  501. // GameObject injuryNum = PoolManager.Instantiate(gameManager.dropGoldText);
  502. // injuryNum.transform.position = new Vector3(
  503. // transform.position.x + injuryNumPos_march.x + Random.Range(-injuryNumRandom_march.x / 2f, injuryNumRandom_march.x / 2f),
  504. // transform.position.y + injuryNumPos_march.y + Random.Range(-injuryNumRandom_march.y / 2f, injuryNumRandom_march.y / 2f),
  505. // transform.position.z);
  506. // TextMeshProUGUI text = injuryNum.GetComponentInChildren<TextMeshProUGUI>();
  507. // text.text = $"+{gameManager.enemyGoldDrop}";
  508. //}
  509. gameObject.SetActive(false);
  510. //dieKeepTime -= Time.deltaTime;
  511. //if (dieKeepTime <= 0)
  512. //{
  513. // if (killer!=null && killer.GetComponent<Demonic>())
  514. // {
  515. // SoldierType st = killer.GetComponent<Demonic>().soldierType;
  516. // SoldierEXP.expInstance.AddEXP(st, (int)(exp * LevelSelect.EXPRatio + 0.5f));
  517. // }
  518. // if (dieEffect)
  519. // {
  520. // PoolManager.Instantiate(dieEffect, transform.position);
  521. // }
  522. // GameManager gameManager = GameManager.instance;
  523. // if (gameManager.gameType == GameType.GameEnd)
  524. // {
  525. // GameObject fx = PoolManager.Instantiate(gameManager.dropGoldFX);
  526. // fx.transform.position = transform.position;
  527. // GameObject injuryNum = PoolManager.Instantiate(gameManager.dropGoldText);
  528. // injuryNum.transform.position = new Vector3(
  529. // transform.position.x + injuryNumPos_march.x + Random.Range(-injuryNumRandom_march.x / 2f, injuryNumRandom_march.x / 2f),
  530. // transform.position.y + injuryNumPos_march.y + Random.Range(-injuryNumRandom_march.y / 2f, injuryNumRandom_march.y / 2f),
  531. // transform.position.z);
  532. // TextMeshProUGUI text = injuryNum.GetComponentInChildren<TextMeshProUGUI>();
  533. // text.text = $"+{gameManager.enemyGoldDrop}";
  534. // }
  535. // gameObject.SetActive(false);
  536. // break;
  537. //}
  538. break;
  539. case CharacterState.HitStun:
  540. hitFeedbackSystem.HitStunUpdate();
  541. break;
  542. case CharacterState.SpecialStatus_Float:
  543. attributeStatus.SpecialStateEffect(SpecialState.FloatState);
  544. break;
  545. case CharacterState.SpecialStatus_BlowUp:
  546. attributeStatus.SpecialStateEffect(SpecialState.BlownUp);
  547. break;
  548. case CharacterState.SpecialStatus_ShotDown:
  549. attributeStatus.SpecialStateEffect(SpecialState.ShotDown);
  550. break;
  551. case CharacterState.SpecialStatus_Weak:
  552. attributeStatus.SpecialStateEffect(SpecialState.Weak);
  553. break;
  554. default:
  555. break;
  556. }
  557. }
  558. public override void ChangeState(CharacterState newState)
  559. {
  560. if (state == newState || newState == CharacterState.FramePause)
  561. {
  562. state = newState;
  563. return;
  564. }
  565. //Debug.Log("从" + state + "转向" + newState);
  566. switch (state)
  567. {
  568. case CharacterState.Idle:
  569. //transform.rotation = Quaternion.Euler(Vector3.zero);
  570. break;
  571. case CharacterState.Run:
  572. rb.velocity = Vector3.zero;
  573. //transform.rotation = Quaternion.Euler(Vector3.zero);
  574. break;
  575. case CharacterState.Rush:
  576. rb.velocity = Vector3.zero;
  577. break;
  578. case CharacterState.Rise:
  579. if (!canFly)
  580. {
  581. bodyCollider.SetActive(true);
  582. }
  583. break;
  584. case CharacterState.Fall:
  585. rb.velocity = Vector3.zero;
  586. break;
  587. //case CharacterState.Hurt:
  588. // break;
  589. case CharacterState.Attack:
  590. attackController.isAttackTriggerOn = false;
  591. attackController.curAttackMethod.attackTrigger.gameObject.SetActive(false);
  592. break;
  593. case CharacterState.Die:
  594. isDie = false;
  595. break;
  596. case CharacterState.FramePause:
  597. state = hitFeedbackSystem.curCharacterState;
  598. ChangeState(newState);
  599. return;
  600. default:
  601. break;
  602. }
  603. CharacterState oldState = state;
  604. state = newState;
  605. switch (newState)
  606. {
  607. case CharacterState.Idle:
  608. if (!isConAttack || attackController.attackInterval > 0)
  609. {
  610. if (!IsPlayingAnimation(AnimatorHash.ANIMATOR_idle))
  611. {
  612. ani.CrossFade(AnimatorHash.ANIMATOR_idle, 1);
  613. }
  614. }
  615. rb.velocity = Vector3.zero;
  616. break;
  617. case CharacterState.Run:
  618. ani.Play(AnimatorHash.ANIMATOR_walk, 0, 0);
  619. break;
  620. case CharacterState.Rush:
  621. ani.Play(AnimatorHash.ANIMATOR_rush, 0, 0);
  622. break;
  623. case CharacterState.Fall:
  624. ani.Play(AnimatorHash.ANIMATOR_fall, 0, 0);
  625. break;
  626. case CharacterState.Attack:
  627. break;
  628. case CharacterState.Rise:
  629. ani.Play(AnimatorHash.ANIMATOR_jump, 0, 0);
  630. nowCanFly = canFly;
  631. break;
  632. case CharacterState.Die:
  633. ani.Play(AnimatorHash.ANIMATOR_die, 0, 0);
  634. isDie = true;
  635. dieKeepTime = totalDieKeepTime;
  636. if(GameManager.instance.gameType != GameType.GameEnd)
  637. {
  638. DropSouls();
  639. }
  640. if (killer != null && killer.GetComponent<Demonic>())
  641. {
  642. SoldierType st = killer.GetComponent<Demonic>().soldierType;
  643. SoldierEXP.expInstance.AddEXP(st, (int)(exp * LevelSelect.EXPRatio + 0.5f));
  644. }
  645. if (dieEffect)
  646. {
  647. PoolManager.Instantiate(dieEffect, transform.position);
  648. }
  649. GameManager gameManager = GameManager.instance;
  650. if (gameManager.gameType == GameType.GameEnd)
  651. {
  652. GameObject fx = PoolManager.Instantiate(gameManager.dropGoldFX);
  653. fx.transform.position = transform.position;
  654. GameObject injuryNum = PoolManager.Instantiate(gameManager.dropGoldText);
  655. injuryNum.transform.position = new Vector3(
  656. transform.position.x + injuryNumPos_march.x + Random.Range(-injuryNumRandom_march.x / 2f, injuryNumRandom_march.x / 2f),
  657. transform.position.y + injuryNumPos_march.y + Random.Range(-injuryNumRandom_march.y / 2f, injuryNumRandom_march.y / 2f),
  658. transform.position.z);
  659. TextMeshProUGUI text = injuryNum.GetComponentInChildren<TextMeshProUGUI>();
  660. text.text = $"+{gameManager.enemyGoldDrop}";
  661. }
  662. if (GameManager.instance.isRockEnable)
  663. {
  664. int randomInt = Random.Range(0, 100);
  665. if (randomInt < GameManager.instance.rockProbability + GameManager.instance.myTreasuresTag[3] * GameManager.instance.rockLabelEffectRatio)
  666. {
  667. StoneStatue stoneStatue = PoolManager.Instantiate(Resources.Load<GameObject>("Prefab/StoneStatue"), transform.position).GetComponentInChildren<StoneStatue>();
  668. GameManager.instance.player.rebornSkills.Add(stoneStatue);
  669. if(charactertag == CharacterTag.Tank)
  670. {
  671. stoneStatue.bulletCount = 6;
  672. stoneStatue.transform.parent.localScale = Vector3.one * 1.5f;
  673. }
  674. else
  675. {
  676. stoneStatue.bulletCount = 3;
  677. stoneStatue.transform.parent.localScale = Vector3.one * 0.8f;
  678. }
  679. }
  680. }
  681. //if (GameManager.instance.isWoodEnable)
  682. //{
  683. // int randomInt = Random.Range(0, 100);
  684. // if (randomInt < GameManager.instance.woodProbability + GameManager.instance.myTreasuresTag[7] * GameManager.instance.woodLabelEffectRatio)
  685. // {
  686. // PoolManager.Instantiate(Resources.Load<GameObject>("Prefab/SoulFlower"), transform.position).GetComponent<SoulFlower>().Init(false);
  687. // }
  688. //}
  689. break;
  690. default:
  691. break;
  692. }
  693. }
  694. private bool IsPlayingAnimation(int animHash)
  695. {
  696. AnimatorStateInfo stateInfo = ani.GetCurrentAnimatorStateInfo(0);
  697. return stateInfo.shortNameHash == animHash;
  698. }
  699. public void DropSouls()
  700. {
  701. int dropSoulNum = Random.Range(dropSoulMin, dropSoulMax + 1);
  702. if (dropSoulNum > 1)
  703. {
  704. for (int i = 0; i < dropSoulNum; i++)
  705. {
  706. float angleInterval = dropSoulAngle / (float)(dropSoulNum - 1);
  707. float angle = 90 + ((float)i - (float)(dropSoulNum - 1) / 2) * angleInterval;
  708. angle = angle / 180 * Mathf.PI;
  709. GameObject soulObj = PoolManager.Instantiate(soulPrefab, transform.position);
  710. Vector3 dir = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0);
  711. Soul soul = soulObj.GetComponent<Soul>();
  712. soul.Burst(dir * soulStartSpeed);
  713. soul.type = type;
  714. }
  715. }
  716. else
  717. {
  718. int randomInt = Random.Range(0, 100);
  719. if (randomInt >= dropProbability)
  720. {
  721. return;
  722. }
  723. GameObject soulObj = PoolManager.Instantiate(soulPrefab, transform.position);
  724. Vector3 dir = Vector3.up;
  725. Soul soul = soulObj.GetComponent<Soul>();
  726. soul.Burst(dir * soulStartSpeed);
  727. soul.type = type;
  728. }
  729. }
  730. public void Jump()
  731. {
  732. SetUpSpeed(jumpSpeed);
  733. ani.Play(AnimatorHash.ANIMATOR_jump, 0, 0);
  734. }
  735. public void SetUpSpeed(float speed)
  736. {
  737. ChangeState(CharacterState.Rise);
  738. Vector3 velocity = rb.velocity;
  739. Vector3 leftDir = GetMoveDir();
  740. if (leftDir.x > 0.3f)
  741. {
  742. if (bodyTrans.localScale.x > 0)
  743. {
  744. Turn();
  745. }
  746. }
  747. else if (leftDir.x < -0.3f)
  748. {
  749. if (bodyTrans.localScale.x < 0)
  750. {
  751. Turn();
  752. }
  753. }
  754. velocity.y = speed;
  755. rb.velocity = velocity * moveSpeedScale;
  756. //animalAni.SetInteger("state", (int)PlayerState.Rise);
  757. }
  758. public virtual void ChangeSearchState(SearchState newState)
  759. {
  760. switch (searchState)
  761. {
  762. case SearchState.NoTarget:
  763. break;
  764. case SearchState.InSearchScope:
  765. break;
  766. case SearchState.InAttackScope:
  767. break;
  768. default:
  769. break;
  770. }
  771. searchState = newState;
  772. switch (searchState)
  773. {
  774. case SearchState.NoTarget:
  775. Character character0 = PlayersInput.instance[0];
  776. if (character0 && character0.attackController.beTargetCharacter.Exists(t => t == this))
  777. {
  778. character0.attackController.beTargetCharacter.Remove(this);
  779. }
  780. targetCharacter = null;
  781. break;
  782. case SearchState.InSearchScope:
  783. break;
  784. case SearchState.InAttackScope:
  785. break;
  786. default:
  787. break;
  788. }
  789. }
  790. public virtual bool SearchTarget()
  791. {
  792. targetCharacter = searchTrigger.GetTarget(attackController.targetTypes, attackController.curAttackMethod.canHitFly, attackController.curAttackMethod.searchMode);
  793. if (targetCharacter != null)
  794. {
  795. Character character0 = PlayersInput.instance[0];
  796. Character character1 = PlayersInput.instance[1];
  797. if (targetCharacter == character0
  798. && !character0.attackController.beTargetCharacter.Exists(t => t == this))
  799. {
  800. character0.attackController.beTargetCharacter.Add(this);
  801. }
  802. if (targetCharacter == character1
  803. && !character1.attackController.beTargetCharacter.Exists(t => t == this))
  804. {
  805. character1.attackController.beTargetCharacter.Add(this);
  806. }
  807. return true;
  808. }
  809. else
  810. {
  811. return false;
  812. }
  813. }
  814. public virtual void OnSearchState()
  815. {
  816. switch (searchState)
  817. {
  818. case SearchState.NoTarget:
  819. if (SearchTarget())
  820. {
  821. ChangeSearchState(SearchState.InSearchScope);
  822. break;
  823. }
  824. //向玩家基地移动
  825. break;
  826. case SearchState.InSearchScope:
  827. if (!SearchTarget())
  828. {
  829. targetCharacter = null;
  830. ChangeSearchState(SearchState.NoTarget);
  831. break;
  832. }
  833. attackDis = attackController.curAttackMethod.attackDistance + targetCharacter.beHitDistance;
  834. if (targetCharacter != null && Mathf.Abs(targetCharacter.transform.position.x - transform.position.x) <= attackDis)
  835. {
  836. ChangeSearchState(SearchState.InAttackScope);
  837. break;
  838. }
  839. break;
  840. case SearchState.InAttackScope:
  841. if (targetCharacter != null)
  842. {
  843. //判断是否在射程夹角内
  844. AttackController.AttackMethod am = attackController.curAttackMethod;
  845. if (am.attackType == AttackController.AttackType.Shoot
  846. && attackController.curAttackMethod.attackInfo.attackMethod_Type == AttackMethod_Type.Attack_March)
  847. {
  848. Vector3 dir = targetCharacter.beSearchTrigger.transform.position - transform.position;
  849. float angle = Vector3.Angle(dir, Vector3.left * bodyTrans.localScale.x);
  850. if ((dir.y > 0 && angle > am.maxUpAngle) || (dir.y < 0 && angle > am.maxDownAngle))
  851. {
  852. ChangeSearchState(SearchState.NoTarget);
  853. }
  854. }
  855. attackDis = attackController.curAttackMethod.attackDistance + targetCharacter.beHitDistance;
  856. if (!targetCharacter.gameObject.activeInHierarchy || targetCharacter.isDie
  857. || Mathf.Abs(targetCharacter.transform.position.x - transform.position.x) > attackDis)
  858. {
  859. ChangeSearchState(SearchState.NoTarget);
  860. }
  861. }
  862. else
  863. {
  864. ChangeSearchState(SearchState.NoTarget);
  865. }
  866. break;
  867. default:
  868. break;
  869. }
  870. }
  871. public void Attack_summon()
  872. {
  873. CheckTurn(GetMoveDir().x);
  874. attackController.Attack_summon();
  875. attackTarget = targetCharacter;
  876. }
  877. public virtual void Attack_march()
  878. {
  879. CheckTurn(GetMoveDir().x);
  880. attackController.Attack_march();
  881. if (curAttackID + 1 < len)
  882. {
  883. curAttackID += 1;
  884. }
  885. else if (attackController.curAttackMethod.attackInfo.attackMethod_Type == AttackMethod_Type.Attack_Summon)
  886. {
  887. curAttackID = 1;
  888. }
  889. else
  890. {
  891. curAttackID = 0;
  892. }
  893. attackTarget = targetCharacter;
  894. pastAttackTime = 0;
  895. }
  896. public void ChosePlayer()
  897. {
  898. float distance0 = Mathf.Infinity;
  899. float distance1 = Mathf.Infinity;
  900. PlayerController player0 = PlayersInput.instance[0];
  901. PlayerController player1 = PlayersInput.instance[1];
  902. if (player0 != null && !player0.isRevive)
  903. {
  904. distance0 = Mathf.Abs(player0.transform.position.x
  905. - transform.position.x);
  906. }
  907. if (player1 != null && !player1.isRevive)
  908. {
  909. distance1 = Mathf.Abs(player1.transform.position.x
  910. - transform.position.x);
  911. }
  912. if (distance0 == Mathf.Infinity && distance1 == Mathf.Infinity)
  913. {
  914. targetCharacter = null;
  915. return;
  916. }
  917. if (distance0 <= distance1)
  918. {
  919. targetCharacter = player0;
  920. if (!player0.attackController.beTargetCharacter.Exists(t => t == this))
  921. {
  922. player0.attackController.beTargetCharacter.Add(this);
  923. }
  924. }
  925. else
  926. {
  927. targetCharacter = player1;
  928. if (!player1.attackController.beTargetCharacter.Exists(t => t == this))
  929. {
  930. player1.attackController.beTargetCharacter.Add(this);
  931. }
  932. }
  933. }
  934. public override void BeHit(int damage)
  935. {
  936. base.BeHit(damage);
  937. }
  938. public override void BeHit(AttackController.AttackMethod attackMethod, Character attackFrom, int damage = -1)
  939. {
  940. base.BeHit(attackMethod, attackFrom, damage);
  941. }
  942. }