AttributeStatus.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using System;
  4. using Sirenix.OdinInspector;
  5. //各个状态
  6. public enum SpecialState
  7. {
  8. Null = -1,
  9. FloatState = 0,
  10. BlownUp = 1,
  11. ShotDown = 2,
  12. Weak = 3,
  13. }
  14. public class AttributeStatus : MonoBehaviour
  15. {
  16. //组件
  17. private MoveCharacter character;
  18. private Rigidbody rb;
  19. private Foot foot;
  20. private HitFeedbackSystem hitFeedbackSystem;
  21. //behit参数
  22. [DisplayOnly] public bool canChangeHitStun;
  23. [DisplayOnly] public SpecialState curSpecialStates = SpecialState.Null;
  24. [LabelText("控制时间")] [DisplayOnly] public float attributeTime;
  25. [TabGroup("漂浮")]
  26. [DisplayOnly] public int floatingState; //0:不漂浮;1:漂浮中;2:飘着;3:掉下去
  27. private Vector3 origPos; //初始位置
  28. private float curHeight; //当前所在高度
  29. private float riseTime; //上升时间
  30. private float backSpeed; //返回速度
  31. private float rotateSpeed; //旋转速度
  32. private float rotateDir; //旋转方向
  33. private float height; //漂浮高度
  34. private float rise = 1;
  35. private float normalFallSpeed = 15f;
  36. [TabGroup("击飞击落")] [DisplayOnly] public int hitState;
  37. [TabGroup("击飞击落")] [DisplayOnly] public bool isFly;
  38. [TabGroup("击飞击落")] [LabelText("X方向阻力")] public float decelerationRatioX = 2f;
  39. [TabGroup("击飞击落")] [LabelText("Y方向阻力")] public float decelerationRatioY = 15f;
  40. [TabGroup("易伤")]
  41. [DisplayOnly] public bool haveVulnerable;
  42. [TabGroup("易伤")]
  43. [DisplayOnly] public float vulnerableTime;
  44. private float vulnerableRate;
  45. //抗性
  46. [Serializable]
  47. public struct Resistances
  48. {
  49. //控制效果抗性
  50. [Range(0, 1)]
  51. [LabelText("漂浮抗性")]
  52. public float Float;
  53. [Range(0, 1)]
  54. [LabelText("击飞抗性")]
  55. public float BlowUp;
  56. [Range(0, 1)]
  57. [LabelText("击落抗性")]
  58. public float ShotDown;
  59. [Range(0, 1)]
  60. [LabelText("击晕抗性")]
  61. public float Weak;
  62. [Space]
  63. //非控制效果抗性
  64. [LabelText("护甲值")] public int armor;
  65. }
  66. [LabelText("抗性")] public Resistances resistances;
  67. private void Awake()
  68. {
  69. character = GetComponentInParent<MoveCharacter>();
  70. rb = character.rb;
  71. foot = character.foot;
  72. hitFeedbackSystem = GetComponent<HitFeedbackSystem>();
  73. }
  74. public void Update()
  75. {
  76. //易伤
  77. vulnerableTime -= Time.deltaTime;
  78. if (vulnerableTime <= 0)
  79. {
  80. haveVulnerable = false;
  81. }
  82. }
  83. public void AddSpecialState(AttackInfo attackInfo, Character attackFrom)
  84. {
  85. if (canChangeHitStun)
  86. {
  87. canChangeHitStun = false;
  88. hitFeedbackSystem.EnterHitStun(attackFrom);
  89. return;
  90. }
  91. hitFeedbackSystem.canHitStun = false;
  92. switch (curSpecialStates)
  93. {
  94. case SpecialState.FloatState:
  95. AddFloat(attackInfo.floatState);
  96. break;
  97. case SpecialState.BlownUp:
  98. if (rb.useGravity)
  99. {
  100. AddBlowUp(attackInfo.blowUp, attackFrom.bodyTrans.localScale.x < 0 ? -1 : 1);
  101. //虾兵特殊攻击先留着
  102. //AddBlowUp(attackInfo.blowUp, attackFrom.transform.position.x < character.transform.position.x ? -1 : 1);
  103. }
  104. break;
  105. case SpecialState.ShotDown:
  106. if (!rb.useGravity)
  107. {
  108. AddShotDown(attackInfo.shotDown, attackFrom.bodyTrans.localScale.x < 0 ? -1 : 1);
  109. //虾兵特殊攻击先留着
  110. //AddShotDown(attackInfo.shotDown, attackFrom.transform.position.x < character.transform.position.x ? -1 : 1);
  111. }
  112. break;
  113. case SpecialState.Weak:
  114. AddWeak(attackInfo.weak);
  115. break;
  116. }
  117. }
  118. //CharacterState为SpecialStatus时调用此函数
  119. public void SpecialStateEffect(SpecialState specialState)
  120. {
  121. switch (specialState)
  122. {
  123. //漂浮
  124. case SpecialState.FloatState:
  125. switch (floatingState)
  126. {
  127. case 1:
  128. character.transform.localEulerAngles += new Vector3(0, 0, 1) * rotateDir * rotateSpeed * Time.deltaTime;
  129. curHeight = Mathf.SmoothDamp(curHeight, height, ref rise, riseTime);
  130. character.transform.position = new Vector3(origPos.x, curHeight, origPos.z);
  131. if (curHeight >= height - 0.02f)
  132. {
  133. floatingState = 2;
  134. height = character.transform.position.y;
  135. }
  136. break;
  137. case 2:
  138. character.transform.localEulerAngles += new Vector3(0, 0, 1) * rotateDir * rotateSpeed * Time.deltaTime;
  139. break;
  140. case 3:
  141. if (character.transform.position.y >= origPos.y + 0.05f)
  142. {
  143. curHeight -= normalFallSpeed * Time.deltaTime;
  144. character.transform.position = new Vector3(origPos.x, curHeight, origPos.z);
  145. }
  146. else if (foot.TrigGround || curHeight <= origPos.y + 0.05f)
  147. {
  148. floatingState = 0;
  149. character.isAdjustHeight = 1;
  150. OutSpecialState();
  151. return;
  152. }
  153. break;
  154. }
  155. PlayerController playerController = GetComponent<PlayerController>();
  156. if (playerController != null)
  157. {
  158. if (playerController.mp > 0)
  159. {
  160. playerController.lostMp += playerController.mpReplySpeed * Time.deltaTime;
  161. playerController.mp -= playerController.mpReplySpeed * Time.deltaTime;
  162. }
  163. if (playerController.lostMp >= playerController.addMp)
  164. {
  165. Instantiate(playerController.soul, character.transform.position, new Quaternion(0, 0, 0, 0), null);
  166. playerController.lostMp = 0;
  167. }
  168. }
  169. attributeTime -= Time.deltaTime;
  170. if (attributeTime <= 0)
  171. {
  172. character.transform.localEulerAngles = Vector3.zero;
  173. floatingState = 3;
  174. rb.useGravity = true;
  175. }
  176. break;
  177. //击飞
  178. case SpecialState.BlownUp:
  179. //击落
  180. case SpecialState.ShotDown:
  181. switch (hitState)
  182. {
  183. case 0:
  184. Vector3 vel = rb.velocity;
  185. if (isFly && foot.TrigGround && vel.y <= 0.01f)
  186. {
  187. vel = Vector3.zero;
  188. character.ani.Play("weak", 0, 0);
  189. hitState = 1;
  190. }
  191. else
  192. {
  193. vel.x -= decelerationRatioX * Time.deltaTime;
  194. vel.y -= decelerationRatioY * Time.deltaTime;
  195. isFly = true;
  196. }
  197. rb.velocity = vel;
  198. break;
  199. case 1:
  200. //眩晕状态
  201. if (attributeTime <= 0)
  202. {
  203. character.isAdjustHeight = 1;
  204. OutSpecialState();
  205. }
  206. else
  207. {
  208. rb.velocity = Vector3.zero;
  209. attributeTime -= Time.deltaTime;
  210. }
  211. break;
  212. }
  213. break;
  214. //眩晕
  215. case SpecialState.Weak:
  216. if (attributeTime <= 0)
  217. {
  218. OutSpecialState();
  219. }
  220. else
  221. {
  222. rb.velocity = Vector3.zero;
  223. attributeTime -= Time.deltaTime;
  224. }
  225. break;
  226. }
  227. }
  228. public void OutSpecialState()
  229. {
  230. curSpecialStates = SpecialState.Null;
  231. if (character.canFly)
  232. {
  233. rb.useGravity = false;
  234. rb.constraints = RigidbodyConstraints.FreezeRotation | RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezePositionY;
  235. }
  236. character.ChangeState(CharacterState.Idle);
  237. }
  238. public int DamageCalculation(int damage)
  239. {
  240. damage = (int)(damage * (1 + vulnerableRate) + 0.5f);
  241. return damage;
  242. }
  243. //判断优先级,ture为优先级高于当前控制
  244. public bool PriorityOrder(SpecialState specialState)
  245. {
  246. if (curSpecialStates == SpecialState.Null)
  247. {
  248. curSpecialStates = specialState;
  249. return true;
  250. }
  251. else
  252. {
  253. if (curSpecialStates >= specialState)
  254. {
  255. curSpecialStates = specialState;
  256. return true;
  257. }
  258. else
  259. {
  260. canChangeHitStun = true;
  261. return false;
  262. }
  263. }
  264. }
  265. //受到漂浮
  266. public void AddFloat(AttackInfo.FloatState floatState)
  267. {
  268. rb.useGravity = false;
  269. floatingState = 1;
  270. origPos = character.transform.position;
  271. curHeight = origPos.y;
  272. riseTime = UnityEngine.Random.Range(floatState.upTime.x, floatState.upTime.y);
  273. backSpeed = UnityEngine.Random.Range(floatState.backSpeed.x, floatState.backSpeed.y);
  274. if (gameObject.tag == "Enemy" || gameObject.tag == "Player")
  275. {
  276. backSpeed = -backSpeed;
  277. }
  278. rotateSpeed = UnityEngine.Random.Range(floatState.rotateSpeed.x, floatState.rotateSpeed.y);
  279. rotateDir = (1.5f - UnityEngine.Random.Range(1, 3)) * 2;
  280. height = UnityEngine.Random.Range(floatState.height.x, floatState.height.y);
  281. attributeTime = floatState.time * (1 - resistances.Float);
  282. character.ChangeState(CharacterState.SpecialStatus_Float);
  283. character.ChangeStateText(CharacterState.SpecialStatus_Float);
  284. }
  285. //受到击飞
  286. public void AddBlowUp(AttackInfo.BlowUp blowUp, float dir)
  287. {
  288. attributeTime = blowUp.time * (1 - resistances.BlowUp);
  289. Vector3 vec3 = blowUp.dir.normalized;
  290. if (dir < 0)
  291. {
  292. vec3.x = -vec3.x;
  293. }
  294. rb.useGravity = true;
  295. rb.constraints = RigidbodyConstraints.FreezeRotation | RigidbodyConstraints.FreezePositionZ;
  296. rb.velocity = Vector3.zero;
  297. rb.AddForce(vec3 * blowUp.force * (1 - resistances.BlowUp), ForceMode.Impulse);
  298. character.ani.Play("hitted", 0, 0);
  299. hitState = 0;
  300. isFly = false;
  301. character.ChangeState(CharacterState.SpecialStatus_BlowUp);
  302. character.ChangeStateText(CharacterState.SpecialStatus_BlowUp);
  303. }
  304. //受到击落
  305. public void AddShotDown(AttackInfo.ShotDown shotDown, float dir)
  306. {
  307. attributeTime = shotDown.time * (1 - resistances.ShotDown);
  308. Vector3 vec3 = shotDown.dir.normalized;
  309. if (dir < 0)
  310. {
  311. vec3.x = -vec3.x;
  312. }
  313. rb.useGravity = true;
  314. rb.constraints = RigidbodyConstraints.FreezeRotation | RigidbodyConstraints.FreezePositionZ;
  315. rb.velocity = Vector3.zero;
  316. rb.AddForce(vec3 * shotDown.force * (1 - resistances.ShotDown), ForceMode.Impulse);
  317. character.ani.Play("hitted", 0, 0);
  318. hitState = 0;
  319. isFly = false;
  320. character.ChangeState(CharacterState.SpecialStatus_ShotDown);
  321. character.ChangeStateText(CharacterState.SpecialStatus_ShotDown);
  322. }
  323. //受到击晕
  324. public void AddWeak(AttackInfo.Weak weak)
  325. {
  326. attributeTime = weak.time * (1 - resistances.Weak);
  327. character.ani.Play("weak", 0, 0);
  328. character.ChangeState(CharacterState.SpecialStatus_Weak);
  329. character.ChangeStateText(CharacterState.SpecialStatus_Weak);
  330. }
  331. //受到穿甲
  332. public int AddArmor(AttackInfo.Armor armor, int damage)
  333. {
  334. //计算护甲减免
  335. int am = resistances.armor;
  336. if (am > 0)
  337. {
  338. am = am - armor.rate;
  339. if (am < 0)
  340. {
  341. am = 0;
  342. }
  343. }
  344. return am;
  345. }
  346. //受到易伤
  347. public void AddVulnerable(AttackInfo.Vulnerable vulnerable)
  348. {
  349. vulnerableTime = vulnerable.time;
  350. vulnerableRate = vulnerable.rate;
  351. haveVulnerable = true;
  352. }
  353. }