MoveCharacter.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. using Spine.Unity;
  2. using Spine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using TMPro;
  7. public class MoveCharacter : Character
  8. {
  9. [Header("材质")]
  10. public float matState = 1;
  11. public GameObject spinee;
  12. public MeshRenderer mesh;
  13. public Material[] mats;
  14. public Material[] outlineMats;
  15. public Material[] outline1Mats;
  16. [Header("组件")]
  17. public Foot foot;
  18. private ScreenShake ss;
  19. [Header("额外重力")]
  20. public float extraRiseGravity = 0; //上升时额外重力加速度
  21. public float extraFallGravity = -10; //下落时额外重力加速度
  22. [Header("属性")]
  23. public bool canMove = true;
  24. public float moveSpeed = 5;
  25. [Header("虚弱状态")]
  26. public float totalBeRepelValue;
  27. [HideInInspector]
  28. public float beRepelValue;
  29. public float weakTime;
  30. public float totalWeakTime;
  31. [HideInInspector]
  32. public float newTotalWeakTime;
  33. public float weakHitRate = 2;
  34. [HideInInspector]
  35. public Vector3 weakForce;
  36. [Header("易伤减伤")]
  37. public float easyToGetHit = 0.2f;
  38. public bool isDamageReduction;
  39. public float reductionDegree;
  40. public GameObject reductionEffect;
  41. [Header("被击飞减速度")]
  42. public float decelerationRatio = 1f;
  43. [Header("眩晕参数")]
  44. public float comaTime = 5;
  45. public float pastComaTime;
  46. [Header("漂浮")]
  47. public int floatState; //0:不漂浮;1:漂浮中;2:飘着;3:掉下去
  48. private float rise = 1;
  49. public float maxTime = 1.5f; //上升最大耗时
  50. public float minTime = 0.1f; //上升最小耗时
  51. public float maxHeight = 12; //最大上升高度
  52. public float minHeight = 7; //最小上升高度
  53. private float curHeight; //当前所在高度
  54. private Vector3 origPos; //初始位置
  55. private float origY;
  56. private float height; //漂浮高度
  57. public float floatTime = 20; //漂浮时间
  58. private float curTime; //漂浮已进行时长
  59. private float riseTime; //上升时间
  60. private float pastTime; //上升已用时间
  61. public float maxRotateSpeed = 20; //最大旋转速度
  62. public float minRotateSpeed = 5; //最小旋转速度
  63. private float rotateSpeed; //旋转速度
  64. private float rotateDir; //旋转方向
  65. private float backSpeed; //往后退的速度
  66. public bool isFloat; //正在漂浮中
  67. public float normalFallSpeed;
  68. [Header("临时血量")]
  69. public GameObject effect;
  70. private int temptHP;
  71. private int curHP;
  72. private float continueTime;
  73. private bool isTempt;
  74. [Header("魂")]
  75. public GameObject soulPrefab;
  76. public float soulStartSpeed = 1f;
  77. [Header("隐身")]
  78. public bool isInvisible;
  79. public float invisibleTime;
  80. public float velocityAddition;
  81. [Header("传送门")]
  82. public bool haveTransmit;
  83. [HideInInspector]
  84. public float transmitTime;
  85. public PortalsController portalsController;
  86. [Header("受到持续伤害")]
  87. public bool isSustainedInjury; //是否正在受到持续伤害
  88. [HideInInspector] public float sustainedInjuryTime; //存储持续伤害经过的时间
  89. public float sustainedInjury_IntervalTime; //每次伤害的间隔时间
  90. public int sustainedInjury_damage; //每次造成的伤害
  91. [Header("受到重伤")]
  92. public float heavyDamage;
  93. private void Awake()
  94. {
  95. spinee = bodyTrans.GetChild(0).gameObject;
  96. mesh = spinee.GetComponent<MeshRenderer>();
  97. mats = mesh.materials;
  98. origY = transform.position.y;
  99. ss = Camera.main.GetComponentInParent<ScreenShake>();
  100. }
  101. private void Start()
  102. {
  103. newTotalWeakTime = totalWeakTime;
  104. }
  105. //0:漂浮 1:正常 2:无敌
  106. public void ChangeMat(int state)
  107. {
  108. if((state == 0 && matState == 2) || (state == 2 && matState == 0))
  109. {
  110. return;
  111. }
  112. if (outline1Mats.Length == 0)
  113. {
  114. return;
  115. }
  116. if (spinee == null || mesh == null || mats == null)
  117. {
  118. spinee = transform.GetChild(0).GetChild(0).gameObject;
  119. mesh = spinee.GetComponent<MeshRenderer>();
  120. mats = mesh.materials;
  121. }
  122. switch (state)
  123. {
  124. case 0:
  125. mesh.materials = outlineMats;
  126. break;
  127. case 1:
  128. mesh.materials = mats;
  129. break;
  130. case 2:
  131. mesh.materials = outline1Mats;
  132. break;
  133. }
  134. matState = state;
  135. }
  136. public void FloatStateOn()
  137. {
  138. if (isInvisible)
  139. {
  140. return;
  141. }
  142. if (GetComponent<PlayerController>())
  143. {
  144. if (GetComponent<PlayerController>().isBaseBtnOut)
  145. {
  146. return;
  147. }
  148. }
  149. if (canMove)
  150. {
  151. canMove = false;
  152. isFloat = true;
  153. ChangeMat(0);
  154. curTime = 0;
  155. if (floatState == 0)
  156. {
  157. origPos = transform.position;
  158. origY = origPos.y;
  159. curHeight = origPos.y;
  160. }
  161. origPos.x = transform.position.x;
  162. ChangeState(CharacterState.Rise);
  163. floatState = 1;
  164. riseTime = Random.Range(minTime, maxTime);
  165. backSpeed = Random.Range(1, 4);
  166. if (gameObject.tag == "Enemy" || gameObject.tag == "Player")
  167. {
  168. backSpeed = -backSpeed;
  169. }
  170. rotateSpeed = Random.Range(minRotateSpeed, maxRotateSpeed);
  171. rotateDir = (1.5f - Random.Range(1, 3)) * 2;
  172. height = Random.Range(minHeight, maxHeight);
  173. }
  174. }
  175. private void RotateSelf()
  176. {
  177. transform.localEulerAngles += new Vector3(0, 0, 1) * rotateDir * rotateSpeed * Time.deltaTime;
  178. }
  179. public void CharacterFloat()
  180. {
  181. if (floatState == 1)
  182. {
  183. RotateSelf();
  184. curTime += Time.deltaTime;
  185. curHeight = Mathf.SmoothDamp(curHeight, height, ref rise, riseTime);
  186. transform.position = new Vector3(origPos.x, curHeight, origPos.z);
  187. if (curHeight >= height - 0.02f)
  188. {
  189. floatState = 2;
  190. pastTime = curTime;
  191. height = transform.position.y;
  192. ChangeState(CharacterState.Float);
  193. }
  194. }
  195. else if (floatState == 2)
  196. {
  197. RotateSelf();
  198. curTime += Time.deltaTime;
  199. transform.position = new Vector3(origPos.x + backSpeed * (curTime - pastTime), height, origPos.z);
  200. if (curTime >= floatTime)
  201. {
  202. transform.localEulerAngles = new Vector3(0, 0, 0);
  203. floatState = 3;
  204. origPos.x = transform.position.x;
  205. ChangeState(CharacterState.Fall);
  206. }
  207. }
  208. else if (floatState == 3)
  209. {
  210. if (transform.position.y >= origY + 0.05f)
  211. {
  212. curHeight -= normalFallSpeed * Time.deltaTime;
  213. transform.position = new Vector3(origPos.x, curHeight, origPos.z);
  214. }
  215. else if (foot.TrigGround || curHeight <= origY + 0.05f)
  216. {
  217. if (gameObject.layer == 7 && isInSoulTower)
  218. {
  219. ChangeState(CharacterState.LockSoul);
  220. }
  221. else
  222. {
  223. ChangeState(CharacterState.Idle);
  224. }
  225. ChangeMat(1);
  226. floatState = 0;
  227. isFloat = false;
  228. canMove = true;
  229. if (gameObject.tag == "Player")
  230. {
  231. GetComponentInParent<PlayerController>().soulCollector.enabled = true;
  232. }
  233. }
  234. }
  235. }
  236. public void GetTemptHP(int addTemptHP, float time)
  237. {
  238. isTempt = true;
  239. effect.SetActive(true);
  240. curHP = hp;
  241. totalHp += addTemptHP;
  242. hp += addTemptHP;
  243. temptHP = addTemptHP;
  244. continueTime = time;
  245. }
  246. private void LoseTemptHP()
  247. {
  248. isTempt = false;
  249. effect.SetActive(false);
  250. totalHp -= temptHP;
  251. if (hp > curHP)
  252. {
  253. hp = curHP;
  254. }
  255. }
  256. public virtual void Update()
  257. {
  258. if (isTempt)
  259. {
  260. continueTime -= Time.deltaTime;
  261. if (continueTime <= 0 || hp <= curHP)
  262. {
  263. LoseTemptHP();
  264. }
  265. }
  266. if (beLarger)
  267. {
  268. Enlarge();
  269. }
  270. if (floatState != 0)
  271. {
  272. CharacterFloat();
  273. }
  274. if (isInvisible)
  275. {
  276. invisibleTime -= Time.deltaTime;
  277. if(invisibleTime <= 0)
  278. {
  279. isInvisible = false;
  280. ChangeMat(1);
  281. }
  282. }
  283. if (haveTransmit)
  284. {
  285. transmitTime -= Time.deltaTime;
  286. if(transmitTime <=0)
  287. {
  288. haveTransmit = false;
  289. portalsController.rbs.Remove(rb);
  290. }
  291. }
  292. //受到持续伤害
  293. if (isSustainedInjury)
  294. {
  295. SustainedInjury();
  296. }
  297. }
  298. //伤害减免状态开启(减免程度,减免时长)
  299. public void DamageReductionStateOn(float degree, GameObject effect)
  300. {
  301. if (reductionEffect == null)
  302. {
  303. reductionEffect = Instantiate(effect, transform.position, new Quaternion(0, 0, 0, 0), transform);
  304. }
  305. reductionEffect.SetActive(true);
  306. isDamageReduction = true;
  307. reductionDegree = degree;
  308. canNotChangeHurt = true;
  309. }
  310. public void DamageReductionStateToOff(float onTime)
  311. {
  312. Invoke("DamageReductionStateOff", onTime);
  313. }
  314. private void DamageReductionStateOff()
  315. {
  316. isDamageReduction = false;
  317. reductionEffect.SetActive(false);
  318. canNotChangeHurt = false;
  319. }
  320. public override void BeHit(int damage, Vector3 force, bool changeHurt, float repelValue)
  321. {
  322. if (isInvisible)
  323. {
  324. return;
  325. }
  326. if (invincibleTime > 0)
  327. {
  328. return;
  329. }
  330. //漂浮易伤
  331. if (isFloat)
  332. {
  333. damage = (int)((1 + easyToGetHit) * damage);
  334. }
  335. //伤害减免
  336. if (isDamageReduction)
  337. {
  338. damage = (int)((1 - reductionDegree) * damage);
  339. }
  340. hp -= damage;
  341. //伤害跳字
  342. if (showInjuryNum)
  343. {
  344. GameObject injuryNum = Instantiate(injuryNumText);
  345. injuryNum.transform.position = new Vector3(transform.position.x + Random.Range(-1f, 1f), transform.position.y + 1, transform.position.z);
  346. TextMeshProUGUI text = injuryNum.GetComponentInChildren<TextMeshProUGUI>();
  347. text.text = damage.ToString();
  348. if (gameObject.CompareTag("Player"))
  349. {
  350. text.color = Color.red;
  351. if (debugAttackFrom)
  352. {
  353. Debug.Log("主角受到" + damage.ToString() + "点伤害");
  354. }
  355. }
  356. }
  357. uiHp.Show(hp, totalHp);
  358. if (hp <= 0)
  359. {
  360. ChangeState(CharacterState.Die);
  361. if (!canNotAddForce)
  362. {
  363. weakForce = force;
  364. }
  365. else
  366. {
  367. weakForce = Vector3.zero;
  368. }
  369. return;
  370. }
  371. if (canNotChangeHurt)
  372. {
  373. return;
  374. }
  375. if (changeHurt)
  376. {
  377. beRepelValue -= repelValue;
  378. if (state == CharacterState.Weak)
  379. {
  380. if (!canNotAddForce)
  381. {
  382. rb.AddForce(force * weakHitRate);
  383. ChangeState(CharacterState.Weak);
  384. }
  385. }
  386. else if (beRepelValue <= 0)
  387. {
  388. if (!canNotAddForce)
  389. {
  390. rb.AddForce(force);
  391. }
  392. ChangeState(CharacterState.Weak);
  393. }
  394. }
  395. if (gameObject.layer == 6) //屏幕红闪+抖动
  396. {
  397. if (ss == null)
  398. {
  399. ss = Camera.main.GetComponentInParent<ScreenShake>();
  400. }
  401. ss.enabled = true;
  402. if (isSustainedInjury || damage >= heavyDamage)
  403. {
  404. ss.HeavyShakeShine();
  405. }
  406. }
  407. }
  408. //受到持续伤害
  409. public void SustainedInjury()
  410. {
  411. sustainedInjuryTime += Time.deltaTime;
  412. if(sustainedInjuryTime >= sustainedInjury_IntervalTime)
  413. {
  414. sustainedInjuryTime = 0;
  415. BeHit(sustainedInjury_damage, Vector3.zero,false,0);
  416. }
  417. }
  418. }