HudComponent3D.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. public class HudComponent3D
  5. {
  6. public const string HUD_HERO_PREFAB = "Battle/Blood_Bar_Hero";
  7. private const int DEPTH = 30;
  8. private GameObject mHud;
  9. private Sprite3D mBloodBg;
  10. private Sprite3D mBloodImage;
  11. private Sprite3D mSpImage;
  12. private Sprite3D mSpBg;
  13. private Sprite3D mSingImage;
  14. private Sprite3D mCastingImage;
  15. private Sprite3D mBossShockImage;
  16. private Vector3 m_bloodPos;
  17. private bool m_bloodDirty = false;
  18. private bool m_hudLogicVisible = false;
  19. private bool m_updateSing = false;
  20. private bool m_showShock = false;
  21. private float m_beginShowShockTime = 0;
  22. private Fighter mFighter = null;
  23. public void Born(Fighter owner)
  24. {
  25. mFighter = owner;
  26. mHud = null;
  27. mBloodBg = null;
  28. mBloodImage = null;
  29. mSpImage = null;
  30. m_bloodPos = Vector3.zero;
  31. //EventMgr.AddEventListener<Fighter>(ECoreEventType.EID_FIGHTER_LIFE_CHANGED, OnLifeChanged);
  32. //EventMgr.AddEventListener<Fighter>(ECoreEventType.EID_FIGHTER_ENERGY_CHAGNED, OnSpChanged);
  33. //EventMgr.AddEventListener<Fighter>(ECoreEventType.EID_SKILL_BEGIN_SING, OnBeginSing);
  34. //EventMgr.AddEventListener<Fighter>(ECoreEventType.EID_SKILL_FRESH_SING, OnUpdateSing);
  35. //EventMgr.AddEventListener<Fighter>(ECoreEventType.EID_SKILL_END_SING, OnEndSing);
  36. //EventMgr.AddEventListener<Fighter>(ECoreEventType.EID_BOSS_SPAWNED, OnBossSpawned);
  37. //EventMgr.AddEventListener<Fighter>(ECoreEventType.EID_SHOW_SKILL_REPEATCASTING, OnShowRepeatCasting);
  38. }
  39. public void Dispose()
  40. {
  41. if (mHud != null)
  42. {
  43. ResourceMgr.Instance.RecycleGO(Constants.UI3DPath, HUD_HERO_PREFAB, mHud);
  44. }
  45. mHud = null;
  46. mBloodBg = null;
  47. mBloodImage = null;
  48. mSpImage = null;
  49. mSingImage = null;
  50. mCastingImage = null;
  51. mBossShockImage = null;
  52. m_bloodPos = Vector3.zero;
  53. }
  54. public void Destroy()
  55. {
  56. //EventMgr.RemoveEventListener<Fighter>(ECoreEventType.EID_FIGHTER_LIFE_CHANGED, OnLifeChanged);
  57. //EventMgr.RemoveEventListener<Fighter>(ECoreEventType.EID_FIGHTER_ENERGY_CHAGNED, OnSpChanged);
  58. //EventMgr.RemoveEventListener<Fighter>(ECoreEventType.EID_SKILL_BEGIN_SING, OnBeginSing);
  59. //EventMgr.RemoveEventListener<Fighter>(ECoreEventType.EID_SKILL_FRESH_SING, OnUpdateSing);
  60. //EventMgr.RemoveEventListener<Fighter>(ECoreEventType.EID_SKILL_END_SING, OnEndSing);
  61. //EventMgr.RemoveEventListener<Fighter>(ECoreEventType.EID_BOSS_SPAWNED, OnBossSpawned);
  62. //EventMgr.RemoveEventListener<Fighter>(ECoreEventType.EID_SHOW_SKILL_REPEATCASTING, OnShowRepeatCasting);
  63. Dispose();
  64. }
  65. public void Prepare()
  66. {
  67. InitHudUI();
  68. }
  69. public void Fight()
  70. {
  71. #if UNITY_EDITOR
  72. if (mHud)
  73. {
  74. mHud.name = mFighter.Ctrl.name +"_hud";
  75. }
  76. #endif
  77. ResetHudUI();
  78. }
  79. public void Deactive()
  80. {
  81. setHudLogicVisible(false);
  82. }
  83. public void OnActorDead()
  84. {
  85. if (mFighter == null) return;
  86. setHudLogicVisible(false);
  87. }
  88. public void OnActorRevive()
  89. {
  90. if (mFighter == null) return;
  91. setHudLogicVisible(false);
  92. }
  93. public void LateUpdate()
  94. {
  95. if (mHud == null) return;
  96. if(mFighter == null)
  97. {
  98. ResourceMgr.Instance.RecycleGO(Constants.UI3DPath,HUD_HERO_PREFAB, mHud);
  99. mHud = null;
  100. return;
  101. }
  102. // 这几种情况不需要更新下面的东西,太费了
  103. if (!mFighter.IsVisible)
  104. {
  105. return;
  106. }
  107. if (!BattleCamera.Instance.BattleCameraEnabled) return;
  108. Vector3 curUIPointPos = mFighter.Ctrl.GetUIPointPos();
  109. // 血条可见性需要修改
  110. if (m_bloodDirty)
  111. {
  112. m_bloodDirty = false;
  113. bool result = m_hudLogicVisible && mFighter.IsVisible;
  114. mHud.SetActive(result);
  115. }
  116. // Update Hud
  117. if (mHud.activeSelf)
  118. {
  119. Vector3 hudPosition = curUIPointPos + mFighter.Actor.AvatarData.bloodBarPos;
  120. Vector3 curBloodPos = Camera.main.WorldToScreenPoint(hudPosition);
  121. bool isNeedUpdateUIHud = (m_bloodPos != curBloodPos);
  122. m_bloodPos = curBloodPos;
  123. if (isNeedUpdateUIHud)
  124. {
  125. UpdateUIHud(ref curBloodPos);
  126. }
  127. }
  128. if(m_showShock )
  129. {
  130. float showShockedTime = Time.realtimeSinceStartup - m_beginShowShockTime;
  131. if (showShockedTime >= 2)
  132. {
  133. mBossShockImage.gameObject.SetActive(false);
  134. m_showShock = false;
  135. }
  136. }
  137. if(curentCastingFrame > 0 && mCastingImage!=null)
  138. {
  139. mCastingImage.fillAmount = curentCastingFrame * 1.0f / totalCastingFrame;
  140. curentCastingFrame--;
  141. }
  142. }
  143. int totalCastingFrame = 0;
  144. int curentCastingFrame = 0;
  145. private void OnShowRepeatCasting(CoreEvent<Fighter> ce)
  146. {
  147. if (ce.Data != mFighter) return;
  148. if(mCastingImage!=null)
  149. {
  150. bool vis = (bool)ce.Param2;
  151. totalCastingFrame = (int)ce.Param;
  152. curentCastingFrame = totalCastingFrame;
  153. mCastingImage.gameObject.SetActive(vis);
  154. mCastingImage.fillAmount = 1;
  155. setHudLogicVisible((mFighter.Life < mFighter.MaxLife) || vis);
  156. }
  157. }
  158. private void OnBeginSing(CoreEvent<Fighter> ce)
  159. {
  160. Fighter fighter = ce.Data;
  161. if (fighter != mFighter) return;
  162. curentCastingFrame = 0;
  163. totalCastingFrame = 0;
  164. mSingImage.gameObject.SetActive(true);
  165. mSpImage.gameObject.SetActive(false);
  166. setHudLogicVisible(true);
  167. }
  168. private void OnUpdateSing(CoreEvent<Fighter> ce)
  169. {
  170. if (ce.Data != mFighter) return;
  171. if (mSingImage != null)
  172. {
  173. int leftTime = (int)ce.Param2;
  174. int totalTime = (int)ce.Param;
  175. mSingImage.fillAmount = ((totalTime - leftTime) * 1.0f) / totalTime;
  176. }
  177. }
  178. private void OnEndSing(CoreEvent<Fighter> ce)
  179. {
  180. if (mSingImage == null) return;
  181. Fighter fighter = ce.Data;
  182. if (fighter != mFighter) return;
  183. mSingImage.gameObject.SetActive(false);
  184. mSpImage.gameObject.SetActive(true);
  185. setHudLogicVisible(mFighter.Life < mFighter.MaxLife);
  186. }
  187. private void OnBossSpawned(CoreEvent<Fighter> ce)
  188. {
  189. Fighter fighter = ce.Data;
  190. if (fighter != mFighter) return;
  191. mBloodBg.gameObject.SetActive(false);
  192. mBloodImage.gameObject.SetActive(false);
  193. mSpImage.gameObject.SetActive(false);
  194. mSpBg.gameObject.SetActive(false);
  195. mSingImage.gameObject.SetActive(false);
  196. mCastingImage.gameObject.SetActive(false);
  197. mBossShockImage.gameObject.SetActive(true);
  198. m_showShock = true;
  199. m_beginShowShockTime = Time.realtimeSinceStartup;
  200. setHudLogicVisible(true);
  201. }
  202. private void OnLifeChanged(CoreEvent<Fighter> ev)
  203. {
  204. Fighter fighter = ev.Data;
  205. if (fighter != mFighter) return;
  206. if (mFighter.Life < mFighter.MaxLife)
  207. setHudLogicVisible(true);
  208. UpdateBloodBar(mFighter.Life, mFighter.MaxLife);
  209. }
  210. ///-------------------------------------------------
  211. /// 更新血条值
  212. ///-------------------------------------------------
  213. private void UpdateBloodBar(long curValue, long maxValue)
  214. {
  215. if (mHud != null && maxValue != 0)
  216. {
  217. if ((curValue == 0 || curValue >= maxValue) && mFighter.IsDisposed)
  218. {
  219. setHudLogicVisible(false);
  220. }
  221. else
  222. {
  223. setHudLogicVisible(true);
  224. if (mBloodImage != null)
  225. {
  226. float lastVal = mBloodImage.fillAmount;
  227. mBloodImage.fillAmount = ((float)curValue / (float)maxValue);
  228. if (mFighter.Actor.IsNpc)
  229. {
  230. if (lastVal>0.5f && mBloodImage.fillAmount < 0.5f)
  231. {
  232. mBloodImage.spriteName = "Bar_HP_yellow";
  233. }
  234. }
  235. else
  236. {
  237. if(lastVal > 0.2f && mBloodImage.fillAmount < 0.2f)
  238. {
  239. mBloodImage.spriteName = "Bar_HP_red";
  240. }
  241. }
  242. }
  243. }
  244. }
  245. }
  246. private void OnSpChanged(CoreEvent<Fighter> ce)
  247. {
  248. Fighter fighter = ce.Data;
  249. if (fighter != mFighter) return;
  250. if (mSpImage != null )
  251. {
  252. mSpImage.fillAmount = ((float)mFighter.Sp / mFighter.MaxSp);
  253. if (mFighter.IsPlayer)
  254. {
  255. mSpImage.gameObject.SetActive(true);
  256. mSpBg.gameObject.SetActive(true);
  257. }
  258. }
  259. if(fighter == BattleMgr.Instance.Battle.FighterMgr.self)
  260. setHudLogicVisible(true);
  261. }
  262. private void setHudLogicVisible(bool isVisible)
  263. {
  264. m_hudLogicVisible = isVisible;
  265. refreshHudVisible();
  266. }
  267. private void refreshHudVisible()
  268. {
  269. if (mHud)
  270. {
  271. bool result = m_hudLogicVisible && mFighter.IsVisible;
  272. if (result != mHud.activeSelf)
  273. {
  274. m_bloodDirty = true;
  275. }
  276. }
  277. }
  278. ///-------------------------------------------------
  279. /// 初始化Hud UI
  280. ///-------------------------------------------------
  281. private void InitHudUI()
  282. {
  283. if (mFighter == null)
  284. return;
  285. if (mHud == null)
  286. {
  287. mHud = ResourceMgr.Instance.GetGoFromPool(Constants.UI3DPath, HUD_HERO_PREFAB);
  288. DebugHelper.Assert(mHud != null, "wtf?");
  289. if (mHud == null)
  290. {
  291. return;
  292. }
  293. Transform hudPanel = GetHudPanel();
  294. if (hudPanel != null)
  295. {
  296. mHud.transform.SetParent(hudPanel, true);
  297. mHud.transform.localScale = Vector3.one;
  298. mHud.transform.localRotation = Quaternion.identity;
  299. }
  300. mBloodBg = mHud.transform.Find("bloodBg").GetComponent<Sprite3D>();
  301. mBloodImage = mHud.transform.Find("bloodImg").GetComponent<Sprite3D>();
  302. DebugHelper.Assert(mBloodImage != null);
  303. if (mBloodImage != null)
  304. {
  305. mBloodImage.spriteName = mFighter.IsTeamMember ? "Bar_HP" : "Bar_HP_pink";
  306. if (mFighter.Life > 0)
  307. {
  308. mBloodImage.fillAmount = ((float)mFighter.Life / (float)mFighter.MaxLife);
  309. }
  310. else
  311. {
  312. mBloodImage.fillAmount = 0;
  313. }
  314. }
  315. GameObject energyFore = mHud.transform.getGameObject("spImg");
  316. if (energyFore != null)
  317. {
  318. mSpImage = energyFore.GetComponent<Sprite3D>();
  319. }
  320. mSpBg = mHud.transform.getGameObject("spBg").GetComponent<Sprite3D>();
  321. DebugHelper.Assert(mSpImage != null);
  322. if (mSpImage != null)
  323. {
  324. if (mFighter.Sp > 0)
  325. {
  326. mSpImage.fillAmount = ((float)mFighter.Sp / mFighter.MaxSp);
  327. }
  328. else
  329. {
  330. energyFore.SetActive(false);
  331. mSpBg.gameObject.SetActive(false);
  332. }
  333. }
  334. mSingImage = mHud.transform.getGameObject("singImg").GetComponent<Sprite3D>();
  335. mSingImage.spriteName = "Bar_SP_green";
  336. mSingImage.gameObject.SetActive(false);
  337. mBossShockImage = mHud.transform.getGameObject("shock").GetComponent<Sprite3D>();
  338. mBossShockImage.gameObject.SetActive(false);
  339. mCastingImage = mHud.transform.getGameObject("singImg").GetComponent<Sprite3D>();
  340. }
  341. setHudLogicVisible(false);
  342. }
  343. private void ResetHudUI()
  344. {
  345. if (mHud == null || mFighter == null)
  346. {
  347. return;
  348. }
  349. mBloodImage.spriteName = mFighter.IsTeamMember ? "Bar_HP" : "Bar_HP_pink";
  350. if (mFighter.Life > 0)
  351. {
  352. mBloodImage.fillAmount = ((float)mFighter.Life / (float)mFighter.MaxLife);
  353. }
  354. else
  355. {
  356. mBloodImage.fillAmount = 0;
  357. }
  358. mSpImage.gameObject.SetActive(mFighter.IsPlayer);
  359. mSpBg.gameObject.SetActive(mFighter.IsPlayer);
  360. mBloodImage.gameObject.SetActive(true);
  361. mBloodBg.gameObject.SetActive(false);
  362. //添加到对应的Panel
  363. Transform hudPanel = GetHudPanel();
  364. if (hudPanel != null)
  365. {
  366. mHud.transform.SetParent(hudPanel, true);
  367. mHud.transform.localScale = Vector3.one;
  368. mHud.transform.localRotation = Quaternion.identity;
  369. }
  370. //Camera_UI3D.GetInstance().GetCurrentCanvas().RefreshLayout();
  371. setHudLogicVisible(false);
  372. m_bloodDirty = true;
  373. }
  374. ///-------------------------------------------------
  375. /// 更新UI Hud
  376. ///-------------------------------------------------
  377. private void UpdateUIHud(ref Vector3 bloodPosition)
  378. {
  379. if (mHud != null)
  380. {
  381. bloodPosition.Set(bloodPosition.x, bloodPosition.y, bloodPosition.z);
  382. var UI3D_Came = Camera_UI3D.GetInstance().GetCurrentCamera();
  383. if (UI3D_Came == null)
  384. {
  385. return;
  386. }
  387. mHud.transform.position = UI3D_Came.ScreenToWorldPoint(bloodPosition);
  388. }
  389. }
  390. //--------------------------------------------------
  391. /// 返回HudPanel控件
  392. //--------------------------------------------------
  393. private Transform GetHudPanel()
  394. {
  395. string UNKNOWN_PANEL = "Unknown_Panel";
  396. if (null == BattleCamera.Instance.RealCamera)
  397. {
  398. return null;
  399. }
  400. var UI3D_Came = Camera_UI3D.GetInstance().GetCurrentCamera();
  401. if (UI3D_Came == null)
  402. {
  403. return null; //有可能该局已经结束了,此时还在loading协程
  404. }
  405. Transform root = UI3D_Came.transform.Find("Hud");
  406. if (root == null)
  407. {
  408. GameObject hud = new GameObject("Hud");
  409. root = hud.transform;
  410. root.parent = UI3D_Came.transform;
  411. root.localPosition = Vector3.zero;
  412. root.localRotation = Quaternion.identity;
  413. root.localScale = Vector3.one;
  414. string[] objNames = new string[5] { "Panel_MonsterHud", "Panel_HeroHud", "FloatTexts", "SkillNames", UNKNOWN_PANEL };
  415. for (int i = 0; i < objNames.Length; ++i)
  416. {
  417. GameObject childGO = new GameObject(objNames[i]);
  418. Transform childTrans = childGO.transform;
  419. childTrans = childGO.transform;
  420. childTrans.SetParent(root);
  421. childTrans.localPosition = Vector3.zero;
  422. childTrans.localRotation = Quaternion.identity;
  423. childTrans.localScale = Vector3.one;
  424. }
  425. }
  426. string childName = "";
  427. if (mFighter.IsNpc)
  428. {
  429. childName = "Panel_MonsterHud";
  430. }
  431. else if (mFighter.IsPlayer)
  432. {
  433. childName = "Panel_HeroHud";
  434. }
  435. if (string.IsNullOrEmpty(childName))
  436. {
  437. childName = UNKNOWN_PANEL;
  438. }
  439. Transform child = root.Find(childName);
  440. if (child == null)
  441. {
  442. DebugHelper.LogError("WTF????");
  443. }
  444. return child;
  445. }
  446. }