Boss.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. using Spine.Unity;
  2. using Spine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using TMPro;
  7. public enum AttackState
  8. {
  9. Idle = 0, //待机
  10. Attack = 1, //攻击
  11. Die = 2, //死亡
  12. Weak = 3, //虚弱
  13. }
  14. public enum AttackCategories
  15. {
  16. A = 0,
  17. B = 1,
  18. }
  19. public class Boss : MoveCharacter
  20. {
  21. [Space(30)]
  22. [Header("Boss属性")]
  23. [Header("当前索敌是对塔还是对玩家")]
  24. public TargetType curTarget;
  25. public PlayerController pc;
  26. [Header("Boss攻击规律")]
  27. public string circulate; //循环配置
  28. private int len;
  29. public AttackCategories[] categories; //循环大类
  30. private AttackCategories curCategory; //当前攻击大类
  31. public int curCategoryID;
  32. public float minInterval, maxInterval; //间隔时间
  33. private float curInterval;
  34. public override void Init()
  35. {
  36. //确保组件不丢失
  37. if (!ani)
  38. {
  39. ani = GetComponentInChildren<Animator>();
  40. }
  41. //血量重置
  42. hp = totalHp;
  43. uiHp.Show(hp, totalHp);
  44. ChangeState(CharacterState.Idle);
  45. curInterval = Random.Range(minInterval, maxInterval);
  46. //玩家
  47. pc = PlayersInput.instance[0];
  48. }
  49. public virtual void Start()
  50. {
  51. len = circulate.Length;
  52. Init();
  53. int cur = 0;
  54. categories = new AttackCategories[len];
  55. foreach(char c in circulate)
  56. {
  57. switch (c)
  58. {
  59. case 'A':
  60. categories[cur] = AttackCategories.A;
  61. break;
  62. case 'B':
  63. categories[cur] = AttackCategories.B;
  64. break;
  65. default:
  66. break;
  67. }
  68. cur++;
  69. }
  70. curCategory = categories[0];
  71. }
  72. public override void BeHit(int damage)
  73. {
  74. hp -= damage;
  75. //伤害跳字
  76. if (showInjuryNum)
  77. {
  78. GameObject injuryNum = Instantiate(injuryNumText);
  79. injuryNum.transform.position = new Vector3(transform.position.x + Random.Range(-1f, 1f), transform.position.y + 1, transform.position.z);
  80. TextMeshProUGUI text = injuryNum.GetComponentInChildren<TextMeshProUGUI>();
  81. text.text = damage.ToString();
  82. if (gameObject.CompareTag("Player"))
  83. {
  84. text.color = Color.red;
  85. }
  86. }
  87. uiHp.Show(hp, totalHp);
  88. if (hp <= 0)
  89. {
  90. ChangeState(CharacterState.Die);
  91. }
  92. }
  93. public virtual void Attack()
  94. {
  95. }
  96. public override void ChangeState(CharacterState newState)
  97. {
  98. if (newState == state)
  99. {
  100. return;
  101. }
  102. switch (state)
  103. {
  104. case CharacterState.Run:
  105. rb.velocity = Vector3.zero;
  106. break;
  107. default:
  108. break;
  109. }
  110. state = newState;
  111. switch (newState)
  112. {
  113. case CharacterState.Idle:
  114. ani.Play("idle", 0, 0);
  115. break;
  116. case CharacterState.Run:
  117. ToMove();
  118. break;
  119. case CharacterState.Die:
  120. ani.Play("die", 0, 0);
  121. gameObject.SetActive(false);
  122. break;
  123. case CharacterState.Attack:
  124. Attack();
  125. break;
  126. default:
  127. break;
  128. }
  129. }
  130. public override void OnState()
  131. {
  132. switch (state)
  133. {
  134. case CharacterState.Idle:
  135. curInterval -= Time.deltaTime;
  136. if (curInterval <= 0)
  137. {
  138. RandomAttackState();
  139. }
  140. break;
  141. case CharacterState.Run:
  142. OnMove();
  143. break;
  144. default:
  145. break;
  146. }
  147. }
  148. public virtual void ToMove()
  149. {
  150. }
  151. public virtual void OnMove()
  152. {
  153. }
  154. public void CheckTarget()
  155. {
  156. Character curTar = null;
  157. switch (curTarget)
  158. {
  159. case TargetType.Tower:
  160. float minDis = -1;
  161. foreach(GameObject g in TowerMap.myTowers)
  162. {
  163. float dis = Vector2.Distance(g.transform.position, transform.position);
  164. if (minDis == -1 || dis < minDis)
  165. {
  166. minDis = dis;
  167. curTar = g.GetComponent<Character>();
  168. }
  169. }
  170. break;
  171. case TargetType.Player:
  172. PlayerController p1 = PlayersInput.instance[0];
  173. bool p1Alive = (p1 != null && !p1.isRevive);
  174. float dis1 = Vector2.Distance(transform.position, p1.transform.position);
  175. curTar = p1;
  176. break;
  177. default:
  178. break;
  179. }
  180. targetCharacter = curTar;
  181. }
  182. public virtual void RandomAttackType(AttackCategories cate)
  183. {
  184. }
  185. public void RandomAttackState()
  186. {
  187. switch (curCategory)
  188. {
  189. case AttackCategories.A:
  190. RandomAttackType(AttackCategories.A);
  191. break;
  192. case AttackCategories.B:
  193. RandomAttackType(AttackCategories.B);
  194. break;
  195. default:
  196. break;
  197. }
  198. curCategoryID++;
  199. if (curCategoryID == len)
  200. {
  201. curCategoryID = 0;
  202. }
  203. curCategory = categories[curCategoryID];
  204. ChangeState(CharacterState.Attack);
  205. }
  206. public void EndCurAttackState(bool hasIntervalTime)
  207. {
  208. //和下一个动作有没有间隔
  209. if (hasIntervalTime)
  210. {
  211. curInterval = Random.Range(minInterval, maxInterval);
  212. }
  213. ChangeState(CharacterState.Idle);
  214. }
  215. }