AttributeStatus.cs 15 KB

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