StoryDialogView.cs 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. using FairyGUI;
  2. using UnityEngine;
  3. using UI.Main;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Text.RegularExpressions;
  7. using System;
  8. using YooAsset;
  9. using GFGGame.Launcher;
  10. using UnityEngine.UI;
  11. namespace GFGGame
  12. {
  13. public delegate void OnCompleteStoryDialogCall(bool isSkip, object param);
  14. public class StoryDialogView : BaseView
  15. {
  16. private UI_StoryDialogUI _ui;
  17. private UI_CompArrow _arrow;
  18. private GameObject _sceneObject;
  19. private GameObject _animObject;
  20. private EffectUI _effectUI1;
  21. private DressUpObj _dressUpObj;
  22. private GameObject _dressUpSceneObj;
  23. private GameObject _selfHeadImgObj;
  24. private GTextField _wordTextField;
  25. //剧情完成回调
  26. private OnCompleteStoryDialogCall _onCompleteStoryDialogCall;
  27. private object _onCompleteStoryDialogCallParam;
  28. //回顾
  29. private List<string> _dialogListLookBack;
  30. //自动播放
  31. private int _speedAutoPlay = 1;
  32. private bool _autoPlay = false;
  33. //剧情状态
  34. private List<StoryDialogCfg> _stepListToRead;
  35. private StoryDialogCfg _currentStepCfg;
  36. private string _nextStepId;
  37. private string[] _wordList;
  38. private int _wordIndex = 0;
  39. private bool _isShowLetters;
  40. private bool _canClickBtnNext;
  41. private string _currentWords;
  42. private string _storyStartID;
  43. private string lastTextFieldType; // 上一段文本框的类型
  44. private bool IsTeaParty; //是否是茶话会里的对话
  45. TypingFadeEffectPro _typingEffect;
  46. //屏幕效果中
  47. private Action<object> _onScreenEffectComplete;
  48. public override void Dispose()
  49. {
  50. if (_sceneObject != null)
  51. {
  52. PrefabManager.Instance.Restore(_sceneObject);
  53. _sceneObject = null;
  54. }
  55. if(_animObject != null)
  56. {
  57. PrefabManager.Instance.Restore(_animObject);
  58. _animObject = null;
  59. }
  60. _wordTextField = null;
  61. _arrow = null;
  62. _isShowLetters = false;
  63. EffectUIPool.Recycle(_effectUI1);
  64. _effectUI1 = null;
  65. _onScreenEffectComplete = null;
  66. _typingEffect = null;
  67. if (_ui != null)
  68. {
  69. _ui.Dispose();
  70. _ui = null;
  71. }
  72. base.Dispose();
  73. }
  74. protected override void OnInit()
  75. {
  76. base.OnInit();
  77. packageName = UI_StoryDialogUI.PACKAGE_NAME;
  78. _ui = UI_StoryDialogUI.Create();
  79. viewCom = _ui.target;
  80. isfullScreen = true;
  81. isReturnView = true;
  82. _ui.m_dialogText.target.visible = false;
  83. _ui.m_dialogName.target.visible = false;
  84. _ui.m_dialogHead.target.visible = false;
  85. _ui.m_list.visible = false;
  86. _ui.m_btnNext.width = GRoot.inst.width;
  87. _ui.m_btnNext.height = GRoot.inst.height;
  88. _ui.m_mask1.height = (GRoot.inst.height - 1920) / 2;
  89. _ui.m_mask2.height = (GRoot.inst.height - 1920) / 2;
  90. _ui.m_mask1.y = 0;
  91. _ui.m_mask2.y = GRoot.inst.height - _ui.m_mask2.height;
  92. _ui.m_btnNext.AddRelation(GRoot.inst, RelationType.Size);
  93. _ui.m_btnBack.onClick.Add(OnClickBtnBack);
  94. _ui.m_btnNext.onClick.Add(OnClickBtnNext);
  95. _ui.m_btnLookBack.onClick.Add(OnClickBtnLookBack);
  96. _ui.m_btnSkip.onClick.Add(OnBtnSkip);
  97. _ui.m_list.onClickItem.Add(OnClickListItem);
  98. _ui.m_btnSpeedUp.onClick.Add(OnClickBtnSpeedUp);
  99. _ui.m_btnAutoPlay.onClick.Add(OnClickBtnAutoPlay);
  100. }
  101. protected override void OnShown()
  102. {
  103. base.OnShown();
  104. // 初始化
  105. MusicManager.Instance.Stop();
  106. MusicManager.Instance.SetVolume(0);
  107. _ui.m_hideAnimMask.Play();
  108. if (_sceneObject == null)
  109. {
  110. _sceneObject = PrefabManager.Instance.InstantiateSync(ResPathUtil.GetPrefabPath("SceneStoryDialog"));
  111. }
  112. if (_dressUpObj == null)
  113. {
  114. _dressUpObj = new DressUpObj();
  115. }
  116. CreateHeadImg();
  117. _speedAutoPlay = FightDataManager.Instance.dialogSpeed;
  118. lastTextFieldType = "";
  119. UpdateSpeedUpBtn();
  120. _dialogListLookBack = new List<string>();
  121. object[] datas = viewData as object[];
  122. _storyStartID = (string)datas[0];
  123. bool skipable = (bool)datas[1];
  124. _onCompleteStoryDialogCall = (OnCompleteStoryDialogCall)datas[2];
  125. if (datas.Length > 3)
  126. {
  127. _onCompleteStoryDialogCallParam = datas[3];
  128. }
  129. IsTeaParty = (bool)datas[4];
  130. _autoPlay = _lastStartAutoPlay;
  131. _ui.m_btnAutoPlay.selected = _autoPlay;
  132. if (LauncherConfig.netType == LauncherConfig.EnumNetType.TEMP && !InstanceZonesDataManager.CheckLevelPass(MainStoryDataManager.currentLevelCfgId))
  133. {
  134. // 临时设置都可以跳过对话
  135. skipable = false;
  136. }
  137. else
  138. {
  139. skipable = true;
  140. }
  141. _ui.m_btnSkip.visible = skipable;
  142. _ui.m_c1.selectedIndex = 0;
  143. if (_storyStartID == MainStoryDataManager.priorId)
  144. {
  145. _ui.m_c1.selectedIndex = 1;
  146. OnClickBtnAutoPlay();
  147. _speedAutoPlay = 1;
  148. FightDataManager.Instance.dialogSpeed = _speedAutoPlay;
  149. }
  150. if (IsTeaParty)
  151. {
  152. _ui.m_c1.selectedIndex = 2;
  153. _speedAutoPlay = 1;
  154. }
  155. _ui.m_btnBack.visible = InstanceZonesDataManager.CheckLevelPass(100001001);
  156. StoryDialogDataManager.Instance.Clear();
  157. InitStepListById(_storyStartID);
  158. // 检查资源的初始化
  159. Timers.inst.StartCoroutine(CheckResLoad());
  160. }
  161. private bool _lastStartAutoPlay = false;
  162. protected override void OnHide()
  163. {
  164. base.OnHide();
  165. Timers.inst.Remove(UpdateShake);
  166. Timers.inst.Remove(OnScreenEffectComplete);
  167. ScreenBlackController.Instance.HideBlack();
  168. _lastStartAutoPlay = _autoPlay;
  169. StopAutoPlay();
  170. VoiceManager.Instance.StopVoice();
  171. if (_sceneObject != null)
  172. {
  173. PrefabManager.Instance.Restore(_sceneObject);
  174. _sceneObject = null;
  175. }
  176. if (_animObject != null)
  177. {
  178. PrefabManager.Instance.Restore(_animObject);
  179. _animObject = null;
  180. }
  181. _dressUpObj.TakeOffAll();
  182. MusicManager.Instance.PlayCroutine(ResPathUtil.GetMusicPath(ConstMusicName.DEFAULT));
  183. _onCompleteStoryDialogCall = null;
  184. _onCompleteStoryDialogCallParam = null;
  185. StoryDialogDataManager.Instance.Clear();
  186. GuideController.TryCompleteGuide(ConstGuideId.ENTER_CHAPTER_5, 3);
  187. DestroyHeadImg();
  188. }
  189. protected override void TryCompleteGuide()
  190. {
  191. base.TryCompleteGuide();
  192. GuideController.TryCompleteGuide(ConstGuideId.ENTER_CHAPTER_5, 3);
  193. }
  194. private void OnClickBtnBack()
  195. {
  196. Over(false);
  197. }
  198. private void OnClickBtnNext()
  199. {
  200. if (!_canClickBtnNext || IsTeaParty)
  201. {
  202. return;
  203. }
  204. StopAutoPlay();
  205. if (_onScreenEffectComplete != null)
  206. {
  207. Timers.inst.Remove(OnScreenEffectComplete);
  208. _onScreenEffectComplete.Invoke(null);
  209. }
  210. else
  211. {
  212. ShowNextWords();
  213. }
  214. }
  215. private void OnClickBtnLookBack()
  216. {
  217. StopAutoPlay();
  218. if (_ui.m_btnSkip.visible)
  219. {
  220. ViewManager.Show<StoryLookBackView>(_storyStartID);
  221. }
  222. else
  223. {
  224. ViewManager.Show<StoryLookBackView>(_dialogListLookBack);
  225. }
  226. }
  227. private void OnBtnSkip()
  228. {
  229. Over(true);
  230. }
  231. private void OnClickListItem(EventContext context)
  232. {
  233. UI_ListDialogItem dialogItem = UI_ListDialogItem.Proxy(context.data as GObject);
  234. _dialogListLookBack.Add(dialogItem.m_txtContent.text);
  235. string stepID = (string)dialogItem.target.data;
  236. if (stepID == null)
  237. {
  238. stepID = "0";
  239. }
  240. UI_ListDialogItem.ProxyEnd();
  241. OnStepComplete(stepID);
  242. }
  243. private void OnClickBtnSpeedUp()
  244. {
  245. //如果没有自动播放先开始自动播放
  246. if (!_autoPlay)
  247. {
  248. _ui.m_btnAutoPlay.selected = true;
  249. OnClickBtnAutoPlay();
  250. }
  251. _speedAutoPlay = _speedAutoPlay * 2;
  252. if (_speedAutoPlay > GameConst.MAX_SPEED_AUTO_PLAY)
  253. {
  254. _speedAutoPlay = 1;
  255. }
  256. FightDataManager.Instance.dialogSpeed = _speedAutoPlay;
  257. UpdateSpeedUpBtn();
  258. //if (_speedAutoPlay > 1)
  259. //{
  260. // VoiceManager.Instance.StopVoice();
  261. //}
  262. }
  263. private void OnClickBtnAutoPlay()
  264. {
  265. _autoPlay = _ui.m_btnAutoPlay.selected;
  266. if (_autoPlay)
  267. {
  268. ShowNextWords();
  269. }
  270. }
  271. private void InitStepListById(string dialogID)
  272. {
  273. var temp = StoryDialogCfgArray.Instance.GetCfgsByid(dialogID);
  274. _stepListToRead = new List<StoryDialogCfg>(temp);
  275. }
  276. private void ShowNextStep(string nextStepId)
  277. {
  278. if (nextStepId != null)
  279. {
  280. InitStepListById(nextStepId);
  281. }
  282. if (_stepListToRead != null && _stepListToRead.Count > 0)
  283. {
  284. StoryDialogCfg storyDialogCfg = (StoryDialogCfg)_stepListToRead[0];
  285. _stepListToRead.RemoveAt(0);
  286. Timers.inst.StartCoroutine(InitStepContent(storyDialogCfg));
  287. }
  288. else
  289. {
  290. Over();
  291. }
  292. }
  293. private void OnStepComplete(string nextStepId = null)
  294. {
  295. _nextStepId = nextStepId;
  296. _ui.m_dialogText.target.visible = false;
  297. _ui.m_dialogName.target.visible = false;
  298. _ui.m_dialogHead.target.visible = false;
  299. float delay = 0;
  300. //屏幕效果
  301. if (_currentStepCfg != null)
  302. {
  303. if (_currentStepCfg.blackScreenDur > 0)
  304. {
  305. delay = _currentStepCfg.blackScreenDur;
  306. ScreenBlackController.Instance.ShowBlack(delay, this.viewCom, 0);
  307. }
  308. else if (_currentStepCfg.blankScreenDur > 0)
  309. {
  310. delay = _currentStepCfg.blankScreenDur;
  311. UpdatePic("0");
  312. UpdateAnim("0");
  313. }
  314. }
  315. if (delay > 0)
  316. {
  317. //转换成秒
  318. delay = delay / 1000f;
  319. _onScreenEffectComplete = OnScreenEffectComplete;
  320. Timers.inst.Add(delay, 1, OnScreenEffectComplete);
  321. StoryDialogDataManager.Instance.dialogShowDelay = 0.6f;
  322. }
  323. else
  324. {
  325. OnScreenEffectComplete();
  326. }
  327. }
  328. private void OnScreenEffectComplete(object param = null)
  329. {
  330. _onScreenEffectComplete = null;
  331. if (_nextStepId == "0")
  332. {
  333. Over();
  334. }
  335. else
  336. {
  337. ShowNextStep(_nextStepId);
  338. }
  339. }
  340. private IEnumerator InitStepContent(StoryDialogCfg storyDialogCfg)
  341. {
  342. _canClickBtnNext = false;
  343. StoryDialogDataManager.Instance.waitPicFade = false;
  344. _ui.m_hide.Play(); // 隐藏遮罩
  345. HideAllDialogUI();
  346. // Init resource
  347. _currentStepCfg = storyDialogCfg;
  348. UpdateMusic(storyDialogCfg.musicRes);
  349. UpdateBg(storyDialogCfg.bgRes);
  350. UpdatePic(storyDialogCfg.picRes);
  351. UpdateAnim(storyDialogCfg.aniRes);
  352. UpdateRoleObj(storyDialogCfg.name);
  353. PlayEffect(storyDialogCfg.effectInfoArr);
  354. PlayShake(storyDialogCfg.shakeInfoArr);
  355. string content = storyDialogCfg.content;
  356. content = storyDialogCfg.content.Replace("self", RoleDataManager.roleName);
  357. while (StoryDialogDataManager.Instance.waitBgChange)
  358. {
  359. //Debug.Log("等待背景转换");
  360. yield return new WaitForEndOfFrame();
  361. }
  362. if(StoryDialogDataManager.Instance.dialogShowDelay > 0)
  363. {
  364. yield return new WaitForSeconds(StoryDialogDataManager.Instance.dialogShowDelay);
  365. StoryDialogDataManager.Instance.dialogShowDelay = 0f;
  366. }
  367. _canClickBtnNext = true;
  368. if (content.IndexOf("//") >= 0)
  369. {
  370. ShowList(content);
  371. }
  372. else
  373. {
  374. Timers.inst.StartCoroutine(ShowDialog(storyDialogCfg));
  375. }
  376. }
  377. private void ShowList(string content)
  378. {
  379. StopAutoPlay();
  380. _ui.m_btnAutoPlay.enabled = false;
  381. _wordTextField = null;
  382. _ui.m_list.visible = true;
  383. _ui.m_list.RemoveChildrenToPool();
  384. string[] list = Regex.Split(content, "//");
  385. _ui.m_list.itemRenderer = (int index, GObject item) =>
  386. {
  387. string itemInfo = list[index];
  388. string[] itemInfoList = Regex.Split(itemInfo, "=");
  389. UI_ListDialogItem dialogItem = UI_ListDialogItem.Proxy(item);
  390. dialogItem.m_txtContent.text = itemInfoList[0];
  391. dialogItem.target.data = itemInfoList.Length > 1 ? itemInfoList[1] : null;
  392. UI_ListDialogItem.ProxyEnd();
  393. };
  394. _ui.m_list.numItems = list.Length;
  395. }
  396. private void HideAllDialogUI()
  397. {
  398. _ui.m_dialogText.target.visible = false;
  399. _ui.m_dialogName.target.visible = false;
  400. _ui.m_dialogHead.target.visible = false;
  401. _ui.m_list.visible = false;
  402. }
  403. /// <summary>
  404. /// 初始化对话框/语音/CG等
  405. /// </summary>
  406. /// <param name="storyDialogCfg"></param>
  407. /// <returns></returns>
  408. private IEnumerator ShowDialog(StoryDialogCfg storyDialogCfg)
  409. {
  410. if (storyDialogCfg.showChangeName == 1 && StorageDataManager.Instance.GetStorageValue(ConstStorageId.CHANGE_NAME) == 0)
  411. {
  412. GameController.ShowCreateRole();
  413. StoryDialogDataManager.Instance.waiting = true;
  414. while (StoryDialogDataManager.Instance.waiting)
  415. {
  416. yield return new WaitForEndOfFrame();
  417. }
  418. //if (_autoPlay)
  419. //{
  420. // _ui.m_btnAutoPlay.selected = false;
  421. // OnClickBtnAutoPlay();
  422. //}
  423. }
  424. _ui.m_loaMask.url = ResPathUtil.GetBgImgPath(storyDialogCfg.maskRes);
  425. _ui.m_btnAutoPlay.enabled = true;
  426. _ui.m_list.visible = false;
  427. var content = storyDialogCfg.content.Replace("self", RoleDataManager.roleName);
  428. string words = content;
  429. string roleName = storyDialogCfg.name;
  430. string headRes = storyDialogCfg.head;
  431. string headAniRes = storyDialogCfg.headAni;
  432. string[] effectInfo = storyDialogCfg.effectInfoArr;
  433. VoiceManager.Instance.StopVoice();
  434. // 如果没开倍速才加载语音
  435. if(_speedAutoPlay == 1 || !_autoPlay)
  436. {
  437. // 如果配置了语音,读取语音
  438. VoiceManager.Instance.LoadRes(ResPathUtil.GetVoicePath(storyDialogCfg.voiceRes));
  439. }
  440. _wordList = Regex.Split(words, "&&");
  441. // 有对话
  442. if (_wordList.Length > 0 && !_wordList[0].Equals(""))
  443. {
  444. if (roleName == "self")
  445. {
  446. roleName = RoleDataManager.roleName;
  447. }
  448. //回顾
  449. if (roleName != null)
  450. {
  451. _dialogListLookBack.Add("[color=#FDA2B1]" + roleName + "[/color]");
  452. }
  453. if (!string.IsNullOrEmpty(headAniRes) || storyDialogCfg.suitId > 0)
  454. {
  455. //显示对话框半身像
  456. _ui.m_dialogHead.target.visible = true;
  457. _ui.m_dialogHead.m_txtName.text = roleName;
  458. _ui.m_dialogHead.m_comphead.m_head.visible = false;
  459. _ui.m_dialogHead.m_comphead.m_holder.visible = true;
  460. var headAniCfg = HeadAniCfgArray.Instance.GetCfg(headAniRes);
  461. if (headAniCfg != null && !string.IsNullOrEmpty(headAniCfg.headAni))
  462. {
  463. //独立动画
  464. _ui.m_dialogHead.m_compDressUp.target.visible = false;
  465. _ui.m_dialogHead.m_comphead.target.visible = true;
  466. _effectUI1 = EffectUIPool.CreateEffectUI(_ui.m_dialogHead.m_comphead.m_holder, "ui_nzbq", headAniCfg.headAni);
  467. }
  468. else
  469. {
  470. //换装
  471. _ui.m_dialogHead.m_compDressUp.target.visible = true;
  472. _ui.m_dialogHead.m_comphead.target.visible = false;
  473. //_dressUpObjUI.ResetSceneObj(80, true, false, sceneObject.transform.Find("Scene").gameObject, false);
  474. _dressUpObj.setSceneObj(_dressUpSceneObj, false, false, null, false, ChangeHeadImgLayer);
  475. if (storyDialogCfg.suitId > 0)
  476. {
  477. _dressUpObj.PutOnSuitCfg(storyDialogCfg.suitId, false, new int[] { ConstDressUpItemType.SHOU_CHI_WU }, false, false);
  478. }
  479. else
  480. {
  481. _dressUpObj.PutOnDressUpData(CustomSuitDataManager.GetCurrentSuitData().dressUpData, new int[] { ConstDressUpItemType.SHOU_CHI_WU });
  482. if (_dressUpObj.actionId > 0)
  483. {
  484. _dressUpObj.CancelAction(true, new int[] { ConstDressUpItemType.SHOU_CHI_WU });
  485. }
  486. }
  487. if (headAniCfg != null && headAniCfg.faceId > 0)
  488. {
  489. //表情
  490. _dressUpObj.AddOrRemove(headAniCfg.faceId, true);
  491. //_dressUpObjUI.UpdateWrapper(_ui.m_dialogHead.m_compDressUp.m_holder);
  492. }
  493. }
  494. _wordTextField = _ui.m_dialogHead.m_txtContent;
  495. _arrow = _ui.m_dialogHead.m_iconNext;
  496. lastTextFieldType = "head";
  497. }
  498. else if (!string.IsNullOrEmpty(headRes))
  499. {
  500. _ui.m_dialogHead.target.visible = true;
  501. _ui.m_dialogHead.m_txtName.text = roleName;
  502. _ui.m_dialogHead.m_comphead.m_head.visible = true;
  503. _ui.m_dialogHead.m_comphead.m_holder.visible = false;
  504. _ui.m_dialogHead.m_comphead.m_head.url = ResPathUtil.GetNpcHeadPath(headRes);
  505. _wordTextField = _ui.m_dialogHead.m_txtContent;
  506. _arrow = _ui.m_dialogHead.m_iconNext;
  507. lastTextFieldType = "head";
  508. }
  509. else if (!string.IsNullOrEmpty(roleName))
  510. {
  511. _ui.m_dialogName.target.visible = true;
  512. if (IsTeaParty)
  513. {
  514. var roleContainerList = LeagueDataManager.Instance.RoleContainerList;
  515. var teapartyRoleCfg = TeapartyRoleCfgArray.Instance.GetCfgsByid(LeagueDataManager.Instance.TeaPartyId);
  516. int roleIndex = Convert.ToInt32(roleName);
  517. _ui.m_dialogName.m_txtName.text = teapartyRoleCfg[roleIndex - 1].name;
  518. _ui.m_dialogName.m_bgType.selectedIndex = 1;
  519. _ui.m_dialogName.m_showArrow.selectedIndex = 1;
  520. if (roleIndex <= roleContainerList.Count && roleContainerList[roleIndex - 1].MaxScoreRoleName != null && roleContainerList[roleIndex - 1].MaxScoreRoleName != "" && _ui.m_dialogName.m_txtName.text != "")
  521. {
  522. _ui.m_comPlayName.visible = true;
  523. _ui.m_txtPlayName.text = roleContainerList[roleIndex - 1].MaxScoreRoleName;
  524. if (_ui.m_txtPlayName.text == RoleDataManager.roleName)
  525. _ui.m_dialogName.m_bgType.selectedIndex = 0;
  526. }
  527. else
  528. _ui.m_comPlayName.visible = false;
  529. }
  530. else
  531. {
  532. _ui.m_dialogName.m_bgType.selectedIndex = 0;
  533. _ui.m_dialogName.m_showArrow.selectedIndex = 0;
  534. _ui.m_dialogName.m_txtName.text = roleName;
  535. }
  536. _wordTextField = _ui.m_dialogName.m_txtContent;
  537. _arrow = _ui.m_dialogName.m_iconNext;
  538. if (!lastTextFieldType.Equals("name"))
  539. {
  540. lastTextFieldType = "name";
  541. StoryDialogDataManager.Instance.waiting = true;
  542. _ui.m_t0.Play(() =>
  543. {
  544. StoryDialogDataManager.Instance.waiting = false;
  545. });
  546. }
  547. }
  548. else
  549. {
  550. if (IsTeaParty)
  551. _ui.m_dialogText.m_showArrow.selectedIndex = 1;
  552. else
  553. _ui.m_dialogText.m_showArrow.selectedIndex = 0;
  554. _ui.m_dialogText.target.visible = true;
  555. _wordTextField = _ui.m_dialogText.m_txtContent;
  556. _arrow = _ui.m_dialogText.m_iconNext;
  557. lastTextFieldType = "text";
  558. _ui.m_comPlayName.visible = false;
  559. }
  560. _wordIndex = 0;
  561. _typingEffect = new TypingFadeEffectPro(_wordTextField);
  562. _typingEffect.typeFinishedAction = ShowCurrentWords;
  563. ShowNextDialog();
  564. }
  565. else
  566. {
  567. OnStepComplete();
  568. //if (effectInfo.Length > 0)
  569. //{
  570. // // 等待CG播放完毕直接进入下一段
  571. // Timers.inst.StartCoroutine(WaitCGAnimFinish(effectInfo[0], int.Parse(effectInfo[1])));
  572. //}
  573. //// 播放效果等
  574. //else
  575. //{
  576. // OnStepComplete();
  577. //}
  578. }
  579. }
  580. private void ShowNextDialog()
  581. {
  582. if (_wordList != null && _wordList.Length > _wordIndex)
  583. {
  584. string itemInfo = _wordList[_wordIndex];
  585. string[] itemInfoList = Regex.Split(itemInfo, "=");
  586. _currentWords = itemInfoList[0];
  587. if (itemInfoList.Length > 1)
  588. {
  589. _wordTextField.data = itemInfoList[1];
  590. }
  591. else
  592. {
  593. _wordTextField.data = null;
  594. }
  595. Timers.inst.StartCoroutine(StartShowLetters());
  596. }
  597. else
  598. {
  599. OnStepComplete();
  600. }
  601. }
  602. private void ShowCurrentWords()
  603. {
  604. //_arrow.target.visible = true;
  605. //Timers.inst.Remove(UpdateLetters);
  606. StopTyping();
  607. _typingEffect?.Cancel();
  608. _wordTextField.text = _currentWords;
  609. _dialogListLookBack.Add(_currentWords);
  610. _isShowLetters = false;
  611. _wordIndex++;
  612. if (_autoPlay)
  613. {
  614. float interval = Mathf.Max(VoiceManager.Instance.GetClipRemainingLength(), GameConst.NEXT_WORDS_INTERVAL_MAX / _speedAutoPlay);
  615. Timers.inst.Add(interval, 1, ShowNextWords);
  616. }
  617. }
  618. private void ShowNextWords(object param = null)
  619. {
  620. if (_wordTextField != null)
  621. {
  622. if (_isShowLetters)
  623. {
  624. ShowCurrentWords();
  625. }
  626. else
  627. {
  628. string stepID = (string)_wordTextField.data;
  629. if (stepID != null)
  630. {
  631. OnStepComplete(stepID);
  632. }
  633. else
  634. {
  635. ShowNextDialog();
  636. }
  637. }
  638. }
  639. }
  640. private IEnumerator StartShowLetters()
  641. {
  642. _isShowLetters = true;
  643. _arrow.target.visible = false;
  644. _wordTextField.verticalAlign = VertAlignType.Top;
  645. _wordTextField.text = "";
  646. _canClickBtnNext = false;
  647. while (StoryDialogDataManager.Instance.waitPicFade || StoryDialogDataManager.Instance.waiting)
  648. {
  649. //Debug.Log("等待立绘/动画结束");
  650. yield return new WaitForEndOfFrame();
  651. }
  652. _canClickBtnNext = true;
  653. _wordTextField.text = _currentWords;
  654. StartTyping();
  655. }
  656. /// <summary>
  657. /// 开启打字机显示
  658. /// </summary>
  659. private void StartTyping()
  660. {
  661. _typingEffect.SetSpeed(_speedAutoPlay);
  662. _typingEffect.Start();
  663. // 如果配置了语音,则播放语音
  664. VoiceManager.Instance.PlayVoice();
  665. }
  666. private void StopTyping()
  667. {
  668. _typingEffect.Cancel();
  669. }
  670. private void UpdateBg(string value)
  671. {
  672. if (value.Length > 0)
  673. {
  674. SceneController.UpdateDialogBg(value, _sceneObject);
  675. }
  676. }
  677. private void UpdatePic(string value)
  678. {
  679. if(value.Length > 0 && !IsTeaParty)
  680. {
  681. SceneController.UpdateDialogPic(value, _sceneObject);
  682. }
  683. }
  684. private void UpdateAnim(string value)
  685. {
  686. if (value.Length > 0 && !IsTeaParty)
  687. {
  688. if (value == "0")
  689. {
  690. //SceneController.ControlBgVisible(_sceneObject, true);
  691. _ui.m_hideAnimMask.Play();
  692. SceneController.UpdateDialogAnim(value, ref _animObject);
  693. }
  694. // 播放动画
  695. else
  696. {
  697. StoryDialogDataManager.Instance.waiting = true;
  698. _ui.m_showMask.Play(() =>
  699. {
  700. _ui.m_hideMask.Play();
  701. _ui.m_showAnimMask.Play();
  702. //SceneController.ControlBgVisible(_sceneObject, false);
  703. SceneController.UpdateDialogAnim(value, ref _animObject);
  704. });
  705. }
  706. }
  707. }
  708. private void UpdateRoleObj(string value)
  709. {
  710. if (IsTeaParty)
  711. {
  712. var roleContainerList = LeagueDataManager.Instance.RoleContainerList;
  713. MyDressUpHelper.dressUpObj.setSceneObj(_sceneObject, false, false);
  714. for (int i = 0; i < roleContainerList.Count; i++)
  715. {
  716. if (value == (i + 1).ToString() && roleContainerList[i].EquipIds.Count > 0)
  717. {
  718. MyDressUpHelper.dressUpObj.PutOnItemList(roleContainerList[i].EquipIds);
  719. return;
  720. }
  721. }
  722. MyDressUpHelper.dressUpObj.PutOnDefaultDressUpData(IsTeaParty);
  723. }
  724. }
  725. private void UpdateMusic(string value)
  726. {
  727. if (value.Length > 0)
  728. {
  729. if (value == "0")
  730. {
  731. MusicManager.Instance.Stop();
  732. }
  733. else
  734. {
  735. MusicManager.Instance.PlayCroutine(ResPathUtil.GetMusicPath(value, "mp3"), false, 0.1f);
  736. }
  737. }
  738. }
  739. private void PlayEffect(string[] infos)
  740. {
  741. }
  742. private void PlayShake(int[] shakeInfoArr)
  743. {
  744. if (shakeInfoArr != null && shakeInfoArr.Length > 0)
  745. {
  746. Vector3 position = _sceneObject.transform.position;
  747. position.x = (float)shakeInfoArr[0] / GameConst.PIXELS_PER_UNITY_UNIT;
  748. position.y = (float)shakeInfoArr[1] / GameConst.PIXELS_PER_UNITY_UNIT;
  749. _sceneObject.transform.position = position;
  750. float attenuationX = (float)shakeInfoArr[2] / GameConst.PIXELS_PER_UNITY_UNIT;
  751. float attenuationY = (float)shakeInfoArr[3] / GameConst.PIXELS_PER_UNITY_UNIT;
  752. float interval = (float)shakeInfoArr[4] / 1000;
  753. float duration = (float)shakeInfoArr[5] / 1000;
  754. int repeat = Mathf.RoundToInt(duration / interval);
  755. Timers.inst.Add(interval, 0, UpdateShake, new float[] { attenuationX, attenuationY });
  756. }
  757. }
  758. private void UpdateShake(object param)
  759. {
  760. float[] attenuations = param as float[];
  761. float attenuationX = attenuations[0];
  762. float attenuationY = attenuations[1];
  763. Vector3 position = _sceneObject.transform.position;
  764. bool done = false;
  765. bool doneX = false;
  766. float absX = Mathf.Abs(position.x);
  767. if (absX > attenuationX)
  768. {
  769. int dir = (int)(position.x / absX);
  770. position.x = Mathf.Abs(position.x) - attenuationX;
  771. position.x *= -1 * dir;
  772. }
  773. else
  774. {
  775. doneX = true;
  776. position.x = 0;
  777. }
  778. bool doneY = false;
  779. float absY = Mathf.Abs(position.y);
  780. if (absY > attenuationY)
  781. {
  782. int dir = (int)(position.y / absY);
  783. position.y = Mathf.Abs(position.y) - attenuationY;
  784. position.y *= -1 * dir;
  785. }
  786. else
  787. {
  788. doneY = true;
  789. position.y = 0;
  790. }
  791. done = doneX && doneY;
  792. _sceneObject.transform.position = position;
  793. if (done)
  794. {
  795. Timers.inst.Remove(UpdateShake);
  796. }
  797. }
  798. private void Over(bool isSkip = true)
  799. {
  800. if (_onCompleteStoryDialogCall != null)
  801. {
  802. _onCompleteStoryDialogCall(isSkip, _onCompleteStoryDialogCallParam);
  803. }
  804. this.Hide();
  805. }
  806. private void UpdateSpeedUpBtn()
  807. {
  808. if (_speedAutoPlay > 1)
  809. {
  810. _ui.m_btnSpeedUp.text = "x" + _speedAutoPlay;
  811. }
  812. else
  813. {
  814. _ui.m_btnSpeedUp.text = "";
  815. }
  816. _typingEffect?.SetSpeed(_speedAutoPlay);
  817. }
  818. private void StopAutoPlay()
  819. {
  820. _autoPlay = false;
  821. _ui.m_btnAutoPlay.selected = false;
  822. Timers.inst.Remove(ShowNextWords);
  823. }
  824. private IEnumerator WaitCGAnimFinish(string resName, int times = 1)
  825. {
  826. GameObject cg = PrefabManager.Instance.InstantiateSync("test");
  827. Animator animator = cg.GetComponentInChildren<Animator>();
  828. AnimatorStateInfo info = animator.GetCurrentAnimatorStateInfo(0);
  829. yield return new WaitForSeconds(info.length * times);
  830. //while (info.normalizedTime < 0.95)
  831. //{
  832. // info = animator.GetCurrentAnimatorStateInfo(0);
  833. // yield return new WaitForSeconds(0.1f);
  834. //}
  835. PrefabManager.Instance.Restore(cg);
  836. OnStepComplete();
  837. }
  838. /// <summary>
  839. /// 检查资源加载是否完成
  840. /// </summary>
  841. private IEnumerator CheckResLoad()
  842. {
  843. List<string> resList = new List<string>();
  844. for (int i = 0; i < _stepListToRead.Count; i++)
  845. {
  846. StoryDialogCfg cfg = _stepListToRead[i];
  847. if (cfg.bgRes.Length > 0 && cfg.bgRes != "0")
  848. {
  849. string bgRes = ResPathUtil.GetSceneBgPath(cfg.bgRes);
  850. if (!resList.Contains(bgRes))
  851. {
  852. resList.Add(bgRes);
  853. }
  854. }
  855. if (cfg.aniRes.Length > 0 && cfg.aniRes != "0")
  856. {
  857. string res = cfg.aniRes.Split('/')[1];
  858. string aniRes = ResPathUtil.GetStoryDialogCGPath(cfg.aniRes, res);
  859. if (!resList.Contains(aniRes))
  860. {
  861. resList.Add(aniRes);
  862. }
  863. }
  864. }
  865. ResourceDownloaderOperation downloaderOperation = YooAssets.CreateBundleDownloader(resList.ToArray(), 3, 3);
  866. if (downloaderOperation.TotalDownloadCount == 0)
  867. {
  868. ShowNextStep(_storyStartID);
  869. yield break;
  870. }
  871. // 开始加载资源
  872. ViewManager.Show<LoadingView>();
  873. LoadingView.Instance.SetDesc("正在加载剧情资源...");
  874. downloaderOperation.OnDownloadErrorCallback =
  875. (fileName, error) =>
  876. {
  877. Debug.LogError($"加载{fileName}失败 {error}");
  878. };
  879. downloaderOperation.OnDownloadProgressCallback =
  880. (totalDownloadCount, currentDownloadCount, totalDownloadSizeBytes, currentDownloadSizeBytes) =>
  881. {
  882. string currentSizeMB = (currentDownloadSizeBytes / 1048576f).ToString("f1");
  883. string totalSizeMB = (totalDownloadSizeBytes / 1048576f).ToString("f1");
  884. var progress = (float)currentDownloadSizeBytes / totalDownloadSizeBytes;
  885. //LauncherView.Instance.SetDesc($"正在下载资源,{currentDownloadCount}/{totalDownloadCount}", $"{currentSizeMB}MB/{totalSizeMB}MB", true);
  886. LoadingView.Instance.SetProgress((int)(progress * 100));
  887. };
  888. downloaderOperation.BeginDownload();
  889. yield return downloaderOperation;
  890. // 检测下载结果
  891. if (downloaderOperation.Status != EOperationStatus.Succeed)
  892. {
  893. Alert.Show("下载失败!请检查网络状态后重试。")
  894. .SetLeftButton(true, "返回", (data) =>
  895. {
  896. ViewManager.Hide<LoadingView>();
  897. Hide();
  898. });
  899. yield break;
  900. }
  901. // 加载完成
  902. LoadingView.Instance.SetProgress(100, () =>
  903. {
  904. ViewManager.Hide<LoadingView>();
  905. ShowNextStep(_storyStartID);
  906. }
  907. );
  908. }
  909. private RenderTexture renderTexure;
  910. private void CreateHeadImg()
  911. {
  912. // 创建render texture
  913. renderTexure = new RenderTexture(550, 760, 24);
  914. // 换装父节点 + 相机
  915. _dressUpSceneObj = PrefabManager.Instance.InstantiateSync(ResPathUtil.GetPrefabPath("StoryDialogSelfImg/StoryDialogDressUpObj"));
  916. Camera camera = _dressUpSceneObj.transform.Find("Camera").GetComponent<Camera>();
  917. camera.targetTexture = renderTexure;
  918. // 创建RawImg
  919. _selfHeadImgObj = PrefabManager.Instance.InstantiateSync(ResPathUtil.GetPrefabPath("StoryDialogSelfImg/Canvas"));
  920. RawImage rawImage = _selfHeadImgObj.transform.Find("mask/RawImage").GetComponent<RawImage>();
  921. rawImage.texture = renderTexure;
  922. // 将RawImg放在FGUI上
  923. GoWrapper goWrapper = new GoWrapper(_selfHeadImgObj);
  924. _ui.m_dialogHead.m_compDressUp.m_holder.SetNativeObject(goWrapper);
  925. // FGUI会自动修改Canvas的参数,需要调整一下位置
  926. RectTransform canvas = _selfHeadImgObj.transform.GetComponent<RectTransform>();
  927. canvas.pivot = Vector2.one * 0.5f;
  928. canvas.anchoredPosition = Vector2.zero;
  929. }
  930. private void DestroyHeadImg()
  931. {
  932. // 清空render Texture
  933. Camera camera = _dressUpSceneObj.transform.Find("Camera").GetComponent<Camera>();
  934. camera.targetTexture = null;
  935. RawImage rawImage = _selfHeadImgObj.transform.Find("mask/RawImage").GetComponent<RawImage>();
  936. rawImage.texture = null;
  937. renderTexure.Release();
  938. renderTexure = null;
  939. // 回收人物
  940. _dressUpObj?.Dispose();
  941. _dressUpObj = null;
  942. // 回收RawImage
  943. if (_selfHeadImgObj != null)
  944. {
  945. PrefabManager.Instance.Restore(_selfHeadImgObj);
  946. _selfHeadImgObj = null;
  947. }
  948. // 回收相机预制
  949. if (_dressUpSceneObj != null)
  950. {
  951. PrefabManager.Instance.Restore(_dressUpSceneObj);
  952. _dressUpSceneObj = null;
  953. }
  954. }
  955. /// <summary>
  956. /// 修改主角头像组件层级
  957. /// </summary>
  958. private void ChangeHeadImgLayer()
  959. {
  960. Transform parent = _dressUpSceneObj.transform.Find("Role");
  961. ChangeLayer(parent, parent.gameObject.layer);
  962. }
  963. private void ChangeLayer(Transform transform, int layer)
  964. {
  965. if (transform.childCount > 0)
  966. {
  967. for (int i = 0; i < transform.childCount; i++)
  968. {
  969. ChangeLayer(transform.GetChild(i), layer);
  970. }
  971. transform.gameObject.layer = layer;
  972. }
  973. else
  974. {
  975. transform.gameObject.layer = layer;
  976. }
  977. }
  978. }
  979. }