MoveCharacter.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  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. public float weakHitRate = 2;
  32. [HideInInspector]
  33. public Vector3 weakForce;
  34. [Header("易伤减伤")]
  35. public float easyToGetHit = 0.2f;
  36. public bool isDamageReduction;
  37. public float reductionDegree;
  38. public GameObject reductionEffect;
  39. [Header("被击飞减速度")]
  40. public float decelerationRatio = 1f;
  41. [Header("眩晕参数")]
  42. public float comaTime = 5;
  43. public float pastComaTime;
  44. [Header("漂浮")]
  45. public int floatState; //0:不漂浮;1:漂浮中;2:飘着;3:掉下去
  46. private float rise = 1;
  47. public float maxTime = 1.5f; //上升最大耗时
  48. public float minTime = 0.1f; //上升最小耗时
  49. public float maxHeight = 12; //最大上升高度
  50. public float minHeight = 7; //最小上升高度
  51. private float curHeight; //当前所在高度
  52. private Vector3 origPos; //初始位置
  53. private float origY;
  54. private float height; //漂浮高度
  55. public float floatTime = 20; //漂浮时间
  56. private float curTime; //漂浮已进行时长
  57. private float riseTime; //上升时间
  58. private float pastTime; //上升已用时间
  59. public float maxRotateSpeed = 20; //最大旋转速度
  60. public float minRotateSpeed = 5; //最小旋转速度
  61. private float rotateSpeed; //旋转速度
  62. private float rotateDir; //旋转方向
  63. private float backSpeed; //往后退的速度
  64. public bool isFloat; //正在漂浮中
  65. public float normalFallSpeed;
  66. [Header("临时血量")]
  67. public GameObject effect;
  68. private int temptHP;
  69. private int curHP;
  70. private float continueTime;
  71. private bool isTempt;
  72. [Header("变身前记录玩家属性")]
  73. public SkeletonMecanim playerMe;
  74. public Animator playerAni;
  75. public Animator playerCol;
  76. public Transform playerTran;
  77. public BeSearchTrigger playerBst;
  78. public GameObject playerBullet;
  79. public SearchTrigger playerST;
  80. public Foot playerFoot;
  81. public GameObject playerSpinee;
  82. public MeshRenderer playerMesh;
  83. public Material[] playerMats;
  84. public Material[] playerOut;
  85. [Header("魂")]
  86. public GameObject soulPrefab;
  87. public float soulStartSpeed = 1f;
  88. [Header("隐身")]
  89. public bool isInvisible;
  90. public float invisibleTime;
  91. public float velocityAddition;
  92. [Header("传送门")]
  93. public bool haveTransmit;
  94. [HideInInspector]
  95. public float transmitTime;
  96. public PortalsController portalsController;
  97. [Header("受到持续伤害")]
  98. public bool isSustainedInjury; //是否正在受到持续伤害
  99. [HideInInspector] public float sustainedInjuryTime; //存储持续伤害经过的时间
  100. public float sustainedInjury_IntervalTime; //每次伤害的间隔时间
  101. public int sustainedInjury_damage; //每次造成的伤害
  102. [Header("受到重伤")]
  103. public float heavyDamage;
  104. private void Awake()
  105. {
  106. spinee = bodyTrans.GetChild(0).gameObject;
  107. mesh = spinee.GetComponent<MeshRenderer>();
  108. mats = mesh.materials;
  109. origY = transform.position.y;
  110. ss = Camera.main.GetComponentInParent<ScreenShake>();
  111. }
  112. private void Start()
  113. {
  114. playerMe = mecanim;
  115. playerAni = ani;
  116. playerCol = aniCollider;
  117. playerTran = bodyTrans;
  118. playerBst = beSearchTrigger;
  119. playerBullet = bulletPrefab;
  120. playerST = searchTrigger;
  121. playerFoot = foot;
  122. playerSpinee = spinee;
  123. playerMesh = mesh;
  124. playerMats = mats;
  125. playerOut = outlineMats;
  126. }
  127. //0:漂浮 1:正常 2:无敌
  128. public void ChangeMat(int state)
  129. {
  130. if((state == 0 && matState == 2) || (state == 2 && matState == 0))
  131. {
  132. return;
  133. }
  134. if (outline1Mats.Length == 0)
  135. {
  136. return;
  137. }
  138. if (spinee == null || mesh == null || mats == null)
  139. {
  140. spinee = transform.GetChild(0).GetChild(0).gameObject;
  141. mesh = spinee.GetComponent<MeshRenderer>();
  142. mats = mesh.materials;
  143. }
  144. switch (state)
  145. {
  146. case 0:
  147. mesh.materials = outlineMats;
  148. break;
  149. case 1:
  150. mesh.materials = mats;
  151. break;
  152. case 2:
  153. mesh.materials = outline1Mats;
  154. break;
  155. }
  156. matState = state;
  157. }
  158. public void FloatStateOn()
  159. {
  160. if (isInvisible || state == CharacterState.BaGua)
  161. {
  162. return;
  163. }
  164. if (GetComponent<PlayerController>())
  165. {
  166. if (GetComponent<PlayerController>().isBaseBtnOut)
  167. {
  168. return;
  169. }
  170. }
  171. if (canMove)
  172. {
  173. canMove = false;
  174. isFloat = true;
  175. ChangeMat(0);
  176. curTime = 0;
  177. if (floatState == 0)
  178. {
  179. origPos = transform.position;
  180. origY = origPos.y;
  181. curHeight = origPos.y;
  182. }
  183. origPos.x = transform.position.x;
  184. ChangeState(CharacterState.Rise);
  185. floatState = 1;
  186. riseTime = Random.Range(minTime, maxTime);
  187. backSpeed = Random.Range(1, 4);
  188. if (gameObject.tag == "Enemy" || gameObject.tag == "Player")
  189. {
  190. backSpeed = -backSpeed;
  191. }
  192. rotateSpeed = Random.Range(minRotateSpeed, maxRotateSpeed);
  193. rotateDir = (1.5f - Random.Range(1, 3)) * 2;
  194. height = Random.Range(minHeight, maxHeight);
  195. }
  196. }
  197. private void RotateSelf()
  198. {
  199. transform.localEulerAngles += new Vector3(0, 0, 1) * rotateDir * rotateSpeed * Time.deltaTime;
  200. }
  201. public void CharacterFloat()
  202. {
  203. if (floatState == 1)
  204. {
  205. RotateSelf();
  206. curTime += Time.deltaTime;
  207. aniCollider.Play("Rise", 0, 0);
  208. curHeight = Mathf.SmoothDamp(curHeight, height, ref rise, riseTime);
  209. transform.position = new Vector3(origPos.x, curHeight, origPos.z);
  210. if (curHeight >= height - 0.02f)
  211. {
  212. floatState = 2;
  213. pastTime = curTime;
  214. height = transform.position.y;
  215. ChangeState(CharacterState.Float);
  216. }
  217. }
  218. else if (floatState == 2)
  219. {
  220. RotateSelf();
  221. curTime += Time.deltaTime;
  222. transform.position = new Vector3(origPos.x + backSpeed * (curTime - pastTime), height, origPos.z);
  223. if (curTime >= floatTime)
  224. {
  225. transform.localEulerAngles = new Vector3(0, 0, 0);
  226. floatState = 3;
  227. origPos.x = transform.position.x;
  228. ChangeState(CharacterState.Fall);
  229. }
  230. }
  231. else if (floatState == 3)
  232. {
  233. aniCollider.Play("Fall", 0, 0);
  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. beRepelValue -= repelValue;
  404. if (changeHurt && state == CharacterState.Weak)
  405. {
  406. if (!canNotAddForce)
  407. rb.AddForce(force * weakHitRate);
  408. }
  409. else
  410. {
  411. if (changeHurt && beRepelValue <= 0)
  412. {
  413. if (!canNotAddForce)
  414. rb.AddForce(force);
  415. ChangeState(CharacterState.Weak);
  416. }
  417. }
  418. if (gameObject.layer == 6) //屏幕红闪+抖动
  419. {
  420. if (ss == null)
  421. {
  422. ss = Camera.main.GetComponentInParent<ScreenShake>();
  423. }
  424. ss.enabled = true;
  425. if (isSustainedInjury || damage >= heavyDamage)
  426. {
  427. ss.HeavyShakeShine();
  428. }
  429. }
  430. }
  431. //受到持续伤害
  432. public void SustainedInjury()
  433. {
  434. sustainedInjuryTime += Time.deltaTime;
  435. if(sustainedInjuryTime >= sustainedInjury_IntervalTime)
  436. {
  437. sustainedInjuryTime = 0;
  438. BeHit(sustainedInjury_damage, Vector3.zero,false,0);
  439. }
  440. }
  441. }