MoveCharacter.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  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 SkeletonMecanim playerMe;
  76. public Animator playerAni;
  77. public Animator playerCol;
  78. public Transform playerTran;
  79. public BeSearchTrigger playerBst;
  80. public GameObject playerBullet;
  81. public SearchTrigger playerST;
  82. public Foot playerFoot;
  83. public GameObject playerSpinee;
  84. public MeshRenderer playerMesh;
  85. public Material[] playerMats;
  86. public Material[] playerOut;
  87. [Header("魂")]
  88. public GameObject soulPrefab;
  89. public float soulStartSpeed = 1f;
  90. [Header("隐身")]
  91. public bool isInvisible;
  92. public float invisibleTime;
  93. public float velocityAddition;
  94. [Header("传送门")]
  95. public bool haveTransmit;
  96. [HideInInspector]
  97. public float transmitTime;
  98. public PortalsController portalsController;
  99. [Header("受到持续伤害")]
  100. public bool isSustainedInjury; //是否正在受到持续伤害
  101. [HideInInspector] public float sustainedInjuryTime; //存储持续伤害经过的时间
  102. public float sustainedInjury_IntervalTime; //每次伤害的间隔时间
  103. public int sustainedInjury_damage; //每次造成的伤害
  104. [Header("受到重伤")]
  105. public float heavyDamage;
  106. private void Awake()
  107. {
  108. spinee = bodyTrans.GetChild(0).gameObject;
  109. mesh = spinee.GetComponent<MeshRenderer>();
  110. mats = mesh.materials;
  111. origY = transform.position.y;
  112. ss = Camera.main.GetComponentInParent<ScreenShake>();
  113. }
  114. private void Start()
  115. {
  116. playerMe = mecanim;
  117. playerAni = ani;
  118. playerTran = bodyTrans;
  119. playerBst = beSearchTrigger;
  120. playerBullet = bulletPrefab;
  121. playerST = searchTrigger;
  122. playerFoot = foot;
  123. playerSpinee = spinee;
  124. playerMesh = mesh;
  125. playerMats = mats;
  126. playerOut = outlineMats;
  127. newTotalWeakTime = totalWeakTime;
  128. }
  129. //0:漂浮 1:正常 2:无敌
  130. public void ChangeMat(int state)
  131. {
  132. if((state == 0 && matState == 2) || (state == 2 && matState == 0))
  133. {
  134. return;
  135. }
  136. if (outline1Mats.Length == 0)
  137. {
  138. return;
  139. }
  140. if (spinee == null || mesh == null || mats == null)
  141. {
  142. spinee = transform.GetChild(0).GetChild(0).gameObject;
  143. mesh = spinee.GetComponent<MeshRenderer>();
  144. mats = mesh.materials;
  145. }
  146. switch (state)
  147. {
  148. case 0:
  149. mesh.materials = outlineMats;
  150. break;
  151. case 1:
  152. mesh.materials = mats;
  153. break;
  154. case 2:
  155. mesh.materials = outline1Mats;
  156. break;
  157. }
  158. matState = state;
  159. }
  160. public void FloatStateOn()
  161. {
  162. if (isInvisible || state == CharacterState.BaGua)
  163. {
  164. return;
  165. }
  166. if (GetComponent<PlayerController>())
  167. {
  168. if (GetComponent<PlayerController>().isBaseBtnOut)
  169. {
  170. return;
  171. }
  172. }
  173. if (canMove)
  174. {
  175. canMove = false;
  176. isFloat = true;
  177. ChangeMat(0);
  178. curTime = 0;
  179. if (floatState == 0)
  180. {
  181. origPos = transform.position;
  182. origY = origPos.y;
  183. curHeight = origPos.y;
  184. }
  185. origPos.x = transform.position.x;
  186. ChangeState(CharacterState.Rise);
  187. floatState = 1;
  188. riseTime = Random.Range(minTime, maxTime);
  189. backSpeed = Random.Range(1, 4);
  190. if (gameObject.tag == "Enemy" || gameObject.tag == "Player")
  191. {
  192. backSpeed = -backSpeed;
  193. }
  194. rotateSpeed = Random.Range(minRotateSpeed, maxRotateSpeed);
  195. rotateDir = (1.5f - Random.Range(1, 3)) * 2;
  196. height = Random.Range(minHeight, maxHeight);
  197. }
  198. }
  199. private void RotateSelf()
  200. {
  201. transform.localEulerAngles += new Vector3(0, 0, 1) * rotateDir * rotateSpeed * Time.deltaTime;
  202. }
  203. public void CharacterFloat()
  204. {
  205. if (floatState == 1)
  206. {
  207. RotateSelf();
  208. curTime += Time.deltaTime;
  209. curHeight = Mathf.SmoothDamp(curHeight, height, ref rise, riseTime);
  210. transform.position = new Vector3(origPos.x, curHeight, origPos.z);
  211. if (curHeight >= height - 0.02f)
  212. {
  213. floatState = 2;
  214. pastTime = curTime;
  215. height = transform.position.y;
  216. ChangeState(CharacterState.Float);
  217. }
  218. }
  219. else if (floatState == 2)
  220. {
  221. RotateSelf();
  222. curTime += Time.deltaTime;
  223. transform.position = new Vector3(origPos.x + backSpeed * (curTime - pastTime), height, origPos.z);
  224. if (curTime >= floatTime)
  225. {
  226. transform.localEulerAngles = new Vector3(0, 0, 0);
  227. floatState = 3;
  228. origPos.x = transform.position.x;
  229. ChangeState(CharacterState.Fall);
  230. }
  231. }
  232. else if (floatState == 3)
  233. {
  234. if (transform.position.y >= origY + 0.05f)
  235. {
  236. curHeight -= normalFallSpeed * Time.deltaTime;
  237. transform.position = new Vector3(origPos.x, curHeight, origPos.z);
  238. }
  239. else if (foot.TrigGround || curHeight <= origY + 0.05f)
  240. {
  241. if (gameObject.layer == 7 && isInSoulTower)
  242. {
  243. ChangeState(CharacterState.LockSoul);
  244. }
  245. else
  246. {
  247. ChangeState(CharacterState.Idle);
  248. }
  249. ChangeMat(1);
  250. floatState = 0;
  251. isFloat = false;
  252. canMove = true;
  253. if (gameObject.tag == "Player")
  254. {
  255. if (pc == null)
  256. {
  257. pc = GetComponentInParent<PlayerController>();
  258. }
  259. pc.soulCollector.enabled = true;
  260. }
  261. }
  262. }
  263. }
  264. public void GetTemptHP(int addTemptHP, float time)
  265. {
  266. isTempt = true;
  267. effect.SetActive(true);
  268. curHP = hp;
  269. totalHp += addTemptHP;
  270. hp += addTemptHP;
  271. temptHP = addTemptHP;
  272. continueTime = time;
  273. }
  274. private void LoseTemptHP()
  275. {
  276. isTempt = false;
  277. effect.SetActive(false);
  278. totalHp -= temptHP;
  279. if (hp > curHP)
  280. {
  281. hp = curHP;
  282. }
  283. }
  284. public virtual void Update()
  285. {
  286. if (isTempt)
  287. {
  288. continueTime -= Time.deltaTime;
  289. if (continueTime <= 0 || hp <= curHP)
  290. {
  291. LoseTemptHP();
  292. }
  293. }
  294. if (beLarger)
  295. {
  296. Enlarge();
  297. }
  298. if (floatState != 0)
  299. {
  300. CharacterFloat();
  301. }
  302. if (isInvisible)
  303. {
  304. invisibleTime -= Time.deltaTime;
  305. if(invisibleTime <= 0)
  306. {
  307. isInvisible = false;
  308. ChangeMat(1);
  309. }
  310. }
  311. if (haveTransmit)
  312. {
  313. transmitTime -= Time.deltaTime;
  314. if(transmitTime <=0)
  315. {
  316. haveTransmit = false;
  317. portalsController.rbs.Remove(rb);
  318. }
  319. }
  320. //受到持续伤害
  321. if (isSustainedInjury)
  322. {
  323. SustainedInjury();
  324. }
  325. }
  326. //伤害减免状态开启(减免程度,减免时长)
  327. public void DamageReductionStateOn(float degree, GameObject effect)
  328. {
  329. if (reductionEffect == null)
  330. {
  331. reductionEffect = Instantiate(effect, transform.position, new Quaternion(0, 0, 0, 0), transform);
  332. }
  333. reductionEffect.SetActive(true);
  334. isDamageReduction = true;
  335. reductionDegree = degree;
  336. canNotChangeHurt = true;
  337. }
  338. public void DamageReductionStateToOff(float onTime)
  339. {
  340. Invoke("DamageReductionStateOff", onTime);
  341. }
  342. private void DamageReductionStateOff()
  343. {
  344. isDamageReduction = false;
  345. reductionEffect.SetActive(false);
  346. canNotChangeHurt = false;
  347. }
  348. public override void BeHit(int damage, Vector3 force, bool changeHurt, float repelValue)
  349. {
  350. if (isInvisible)
  351. {
  352. return;
  353. }
  354. if (invincibleTime > 0)
  355. {
  356. return;
  357. }
  358. //漂浮易伤
  359. if (isFloat)
  360. {
  361. damage = (int)((1 + easyToGetHit) * damage);
  362. }
  363. //伤害减免
  364. if (isDamageReduction)
  365. {
  366. damage = (int)((1 - reductionDegree) * damage);
  367. }
  368. hp -= damage;
  369. //伤害跳字
  370. if (showInjuryNum)
  371. {
  372. GameObject injuryNum = Instantiate(injuryNumText);
  373. injuryNum.transform.position = new Vector3(transform.position.x + Random.Range(-1f, 1f), transform.position.y + 1, transform.position.z);
  374. TextMeshProUGUI text = injuryNum.GetComponentInChildren<TextMeshProUGUI>();
  375. text.text = damage.ToString();
  376. if (gameObject.CompareTag("Player"))
  377. {
  378. text.color = Color.red;
  379. if (debugAttackFrom)
  380. {
  381. Debug.Log("主角受到" + damage.ToString() + "点伤害");
  382. }
  383. }
  384. }
  385. uiHp.Show(hp, totalHp);
  386. if (hp <= 0)
  387. {
  388. ChangeState(CharacterState.Die);
  389. if (!canNotAddForce)
  390. {
  391. weakForce = force;
  392. }
  393. else
  394. {
  395. weakForce = Vector3.zero;
  396. }
  397. return;
  398. }
  399. if (canNotChangeHurt)
  400. {
  401. return;
  402. }
  403. if (changeHurt)
  404. {
  405. beRepelValue -= repelValue;
  406. if (state == CharacterState.Weak)
  407. {
  408. if (!canNotAddForce)
  409. {
  410. rb.AddForce(force * weakHitRate);
  411. ChangeState(CharacterState.Weak);
  412. }
  413. }
  414. else if (beRepelValue <= 0)
  415. {
  416. if (!canNotAddForce)
  417. {
  418. rb.AddForce(force);
  419. }
  420. ChangeState(CharacterState.Weak);
  421. }
  422. }
  423. if (gameObject.layer == 6) //屏幕红闪+抖动
  424. {
  425. if (ss == null)
  426. {
  427. ss = Camera.main.GetComponentInParent<ScreenShake>();
  428. }
  429. ss.enabled = true;
  430. if (isSustainedInjury || damage >= heavyDamage)
  431. {
  432. ss.HeavyShakeShine();
  433. }
  434. }
  435. }
  436. //受到持续伤害
  437. public void SustainedInjury()
  438. {
  439. sustainedInjuryTime += Time.deltaTime;
  440. if(sustainedInjuryTime >= sustainedInjury_IntervalTime)
  441. {
  442. sustainedInjuryTime = 0;
  443. BeHit(sustainedInjury_damage, Vector3.zero,false,0);
  444. }
  445. }
  446. }