Enemy.cs 33 KB

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