AttributeStatus.cs 13 KB

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