using FairyGUI; using UnityEngine; using UI.Main; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using System; namespace GFGGame { public delegate void OnCompleteStoryDialogCall(bool isSkip, object param); public class StoryDialogView : BaseView { private UI_StoryDialogUI _ui; private UI_CompArrow _arrow; private GameObject _sceneObject; private EffectUI _effectUI1; private DressUpObjUI _dressUpObjUI; private GTextField _wordTextField; //剧情完成回调 private OnCompleteStoryDialogCall _onCompleteStoryDialogCall; private object _onCompleteStoryDialogCallParam; //回顾 private List _dialogListLookBack; //自动播放 private int _speedAutoPlay = 1; private bool _autoPlay = false; //剧情状态 private List _stepListToRead; private StoryDialogCfg _currentStepCfg; private string _nextStepId; private string[] _wordList; private int _wordIndex = 0; private bool _isShowLetters; private bool _canClickBtnNext; private string _currentWords; private string _storyStartID; private string lastTextFieldType; // 上一段文本框的类型 private bool IsTeaParty; //是否是茶话会里的对话 TypingFadeEffectPro _typingEffect; //屏幕效果中 private Action _onScreenEffectComplete; public override void Dispose() { if (_sceneObject != null) { PrefabManager.Instance.Restore(_sceneObject); _sceneObject = null; } _dressUpObjUI?.Dispose(); _dressUpObjUI = null; _wordTextField = null; _arrow = null; _isShowLetters = false; EffectUIPool.Recycle(_effectUI1); _effectUI1 = null; _onScreenEffectComplete = null; _typingEffect = null; if (_ui != null) { _ui.Dispose(); _ui = null; } base.Dispose(); } protected override void OnInit() { base.OnInit(); packageName = UI_StoryDialogUI.PACKAGE_NAME; _ui = UI_StoryDialogUI.Create(); viewCom = _ui.target; isfullScreen = true; isReturnView = true; _ui.m_dialogText.target.visible = false; _ui.m_dialogName.target.visible = false; _ui.m_dialogHead.target.visible = false; _ui.m_list.visible = false; _ui.m_btnNext.width = GRoot.inst.width; _ui.m_btnNext.height = GRoot.inst.height; _ui.m_btnNext.AddRelation(GRoot.inst, RelationType.Size); _ui.m_btnBack.onClick.Add(OnClickBtnBack); _ui.m_btnNext.onClick.Add(OnClickBtnNext); _ui.m_btnLookBack.onClick.Add(OnClickBtnLookBack); _ui.m_btnSkip.onClick.Add(OnBtnSkip); _ui.m_list.onClickItem.Add(OnClickListItem); _ui.m_btnSpeedUp.onClick.Add(OnClickBtnSpeedUp); _ui.m_btnAutoPlay.onClick.Add(OnClickBtnAutoPlay); } protected override void OnShown() { base.OnShown(); if (_sceneObject == null) { _sceneObject = PrefabManager.Instance.InstantiateSync(ResPathUtil.GetPrefabPath("SceneStoryDialog")); } if (_dressUpObjUI == null) { _dressUpObjUI = new DressUpObjUI(); } _speedAutoPlay = FightDataManager.Instance.dialogSpeed; lastTextFieldType = ""; UpdateSpeedUpBtn(); _dialogListLookBack = new List(); object[] datas = viewData as object[]; _storyStartID = (string)datas[0]; bool skipable = (bool)datas[1]; _onCompleteStoryDialogCall = (OnCompleteStoryDialogCall)datas[2]; if (datas.Length > 3) { _onCompleteStoryDialogCallParam = datas[3]; } IsTeaParty = (bool)datas[4]; _autoPlay = IsTeaParty; if (LauncherConfig.netType == LauncherConfig.EnumNetType.TEMP && !InstanceZonesDataManager.CheckLevelPass(MainStoryDataManager.currentLevelCfgId)) { // 临时设置都可以跳过对话 skipable = false; } else { skipable = true; } _ui.m_btnSkip.visible = skipable; ShowNextStep(_storyStartID); _ui.m_c1.selectedIndex = 0; _ui.m_btnAutoPlay.selected = false; if (_storyStartID == MainStoryDataManager.priorId) { _ui.m_c1.selectedIndex = 1; OnClickBtnAutoPlay(); _speedAutoPlay = 1; FightDataManager.Instance.dialogSpeed = _speedAutoPlay; } if (IsTeaParty) { _ui.m_c1.selectedIndex = 2; } _ui.m_btnBack.visible = InstanceZonesDataManager.CheckLevelPass(100001001); } protected override void OnHide() { base.OnHide(); Timers.inst.Remove(UpdateShake); Timers.inst.Remove(OnScreenEffectComplete); Timers.inst.Remove(ShowNextWords); ScreenBlackController.Instance.HideBlack(); StopAutoPlay(); if (_sceneObject != null) { PrefabManager.Instance.Restore(_sceneObject); _sceneObject = null; } _dressUpObjUI.dressUpObj.TakeOffAll(); MusicManager.Instance.PlayCroutine(ResPathUtil.GetMusicPath(ConstMusicName.DEFAULT)); _onCompleteStoryDialogCall = null; _onCompleteStoryDialogCallParam = null; StoryDialogDataManager.Instance.Clear(); } private void OnClickBtnBack() { //Hide(); //ViewManager.Show(MainStoryDataManager.currentChapterCfgId, ViewManager.GetGoBackDatas(typeof(StoryChapterView).FullName), true); Over(false); } private void OnClickBtnNext() { if (!_canClickBtnNext || IsTeaParty) { return; } StopAutoPlay(); if (_onScreenEffectComplete != null) { Timers.inst.Remove(OnScreenEffectComplete); _onScreenEffectComplete.Invoke(null); } else { ShowNextWords(); } } private void OnClickBtnLookBack() { StopAutoPlay(); if (_ui.m_btnSkip.enabled) { ViewManager.Show(_storyStartID); } else { ViewManager.Show(_dialogListLookBack); } } private void OnBtnSkip() { Over(true); } private void OnClickListItem(EventContext context) { UI_ListDialogItem dialogItem = UI_ListDialogItem.Proxy(context.data as GObject); _dialogListLookBack.Add(dialogItem.m_txtContent.text); string stepID = (string)dialogItem.target.data; if (stepID == null) { stepID = "0"; } UI_ListDialogItem.ProxyEnd(); OnStepComplete(stepID); } private void OnClickBtnSpeedUp() { //如果没有自动播放先开始自动播放 if (!_autoPlay) { _ui.m_btnAutoPlay.selected = true; OnClickBtnAutoPlay(); } _speedAutoPlay = _speedAutoPlay * 2; if (_speedAutoPlay > GameConst.MAX_SPEED_AUTO_PLAY) { _speedAutoPlay = 1; } FightDataManager.Instance.dialogSpeed = _speedAutoPlay; UpdateSpeedUpBtn(); } private void OnClickBtnAutoPlay() { _autoPlay = _ui.m_btnAutoPlay.selected; if (_autoPlay) { ShowNextWords(); } } private void InitStepListById(string dialogID) { var temp = StoryDialogCfgArray.Instance.GetCfgsByid(dialogID); _stepListToRead = new List(temp); } private void ShowNextStep(string nextStepId) { if (nextStepId != null) { InitStepListById(nextStepId); } if (_stepListToRead != null && _stepListToRead.Count > 0) { StoryDialogCfg storyDialogCfg = (StoryDialogCfg)_stepListToRead[0]; _stepListToRead.RemoveAt(0); Timers.inst.StartCoroutine(InitStepContent(storyDialogCfg)); } else { Over(); } } private void OnStepComplete(string nextStepId = null) { _nextStepId = nextStepId; _ui.m_dialogText.target.visible = false; _ui.m_dialogName.target.visible = false; _ui.m_dialogHead.target.visible = false; float delay = 0; //屏幕效果 if (_currentStepCfg != null) { if (_currentStepCfg.blackScreenDur > 0) { delay = _currentStepCfg.blackScreenDur; ScreenBlackController.Instance.ShowBlack(delay, this.viewCom, 0); } else if (_currentStepCfg.blankScreenDur > 0) { delay = _currentStepCfg.blankScreenDur; UpdatePic("0"); } } if (delay > 0) { //转换成秒 delay = delay / 1000f; _onScreenEffectComplete = OnScreenEffectComplete; Timers.inst.Add(delay, 1, OnScreenEffectComplete); StoryDialogDataManager.Instance.dialogShowDelay = 0.6f; } else { OnScreenEffectComplete(); } } private void OnScreenEffectComplete(object param = null) { _onScreenEffectComplete = null; if (_nextStepId == "0") { Over(); } else { ShowNextStep(_nextStepId); } } private IEnumerator InitStepContent(StoryDialogCfg storyDialogCfg) { _canClickBtnNext = false; StoryDialogDataManager.Instance.waitPicFade = false; HideAllDialogUI(); // Init resource _currentStepCfg = storyDialogCfg; UpdateMusic(storyDialogCfg.musicRes); UpdateBg(storyDialogCfg.bgRes); UpdatePic(storyDialogCfg.picRes); UpdateRoleObj(storyDialogCfg.name); PlayEffect(storyDialogCfg.effectInfoArr); PlayShake(storyDialogCfg.shakeInfoArr); string content = storyDialogCfg.content; content = storyDialogCfg.content.Replace("self", RoleDataManager.roleName); while (StoryDialogDataManager.Instance.waitBgChange) { yield return new WaitForEndOfFrame(); } if(StoryDialogDataManager.Instance.dialogShowDelay > 0) { yield return new WaitForSeconds(StoryDialogDataManager.Instance.dialogShowDelay); StoryDialogDataManager.Instance.dialogShowDelay = 0f; } _canClickBtnNext = true; if (content.IndexOf("//") >= 0) { showList(content); } else { Timers.inst.StartCoroutine(ShowDialog(storyDialogCfg)); } } private void showList(string content) { StopAutoPlay(); _ui.m_btnAutoPlay.enabled = false; _wordTextField = null; _ui.m_list.visible = true; _ui.m_list.RemoveChildrenToPool(); string[] list = Regex.Split(content, "//"); _ui.m_list.itemRenderer = (int index, GObject item) => { string itemInfo = list[index]; string[] itemInfoList = Regex.Split(itemInfo, "="); UI_ListDialogItem dialogItem = UI_ListDialogItem.Proxy(item); dialogItem.m_txtContent.text = itemInfoList[0]; dialogItem.target.data = itemInfoList.Length > 1 ? itemInfoList[1] : null; UI_ListDialogItem.ProxyEnd(); }; _ui.m_list.numItems = list.Length; } private void HideAllDialogUI() { _ui.m_dialogText.target.visible = false; _ui.m_dialogName.target.visible = false; _ui.m_dialogHead.target.visible = false; _ui.m_list.visible = false; } private IEnumerator ShowDialog(StoryDialogCfg storyDialogCfg) { if (storyDialogCfg.showChangeName == 1 && StorageDataManager.Instance.GetStorageValue(ConstStorageId.CHANGE_NAME) == 0) { GameController.ShowCreateRole(); StoryDialogDataManager.Instance.waiting = true; while (StoryDialogDataManager.Instance.waiting) { yield return new WaitForEndOfFrame(); } if (_autoPlay) { _ui.m_btnAutoPlay.selected = false; OnClickBtnAutoPlay(); } } _ui.m_loaMask.url = ResPathUtil.GetBgImgPath(storyDialogCfg.maskRes); _ui.m_btnAutoPlay.enabled = true; _ui.m_list.visible = false; var content = storyDialogCfg.content.Replace("self", RoleDataManager.roleName); string words = content; string roleName = storyDialogCfg.name; string headRes = storyDialogCfg.head; string headAniRes = storyDialogCfg.headAni; VoiceManager.Instance.StopVoice(); // 如果配置了语音,读取语音 VoiceManager.Instance.LoadRes(ResPathUtil.GetCardSoundPath("111111111")); if (roleName == "self") { roleName = RoleDataManager.roleName; } //回顾 if (roleName != null) { _dialogListLookBack.Add("[color=#FDA2B1]" + roleName + "[/color]"); } if (!string.IsNullOrEmpty(headAniRes) || storyDialogCfg.suitId > 0) { //显示对话框半身像 _ui.m_dialogHead.target.visible = true; _ui.m_dialogHead.m_txtName.text = roleName; _ui.m_dialogHead.m_comphead.m_head.visible = false; _ui.m_dialogHead.m_comphead.m_holder.visible = true; var headAniCfg = HeadAniCfgArray.Instance.GetCfg(headAniRes); if (headAniCfg != null && !string.IsNullOrEmpty(headAniCfg.headAni)) { //独立动画 _ui.m_dialogHead.m_compDressUp.target.visible = false; _ui.m_dialogHead.m_comphead.target.visible = true; _effectUI1 = EffectUIPool.CreateEffectUI(_ui.m_dialogHead.m_comphead.m_holder, "ui_nzbq", headAniCfg.headAni); } else { //换装 _ui.m_dialogHead.m_compDressUp.target.visible = true; _ui.m_dialogHead.m_comphead.target.visible = false; _dressUpObjUI.ResetSceneObj(80, true, false, null, false); if (storyDialogCfg.suitId > 0) { _dressUpObjUI.dressUpObj.PutOnSuitCfg(storyDialogCfg.suitId, false, new int[] { ConstDressUpItemType.SHOU_CHI_WU }, false, false); } else { _dressUpObjUI.dressUpObj.PutOnDressUpData(CustomSuitDataManager.GetCurrentSuitData().dressUpData, new int[] { ConstDressUpItemType.SHOU_CHI_WU }); if (_dressUpObjUI.dressUpObj.actionId > 0) { _dressUpObjUI.dressUpObj.CancelAction(true); } } if (headAniCfg != null && headAniCfg.faceId > 0) { //表情 _dressUpObjUI.dressUpObj.AddOrRemove(headAniCfg.faceId, true); _dressUpObjUI.UpdateWrapper(_ui.m_dialogHead.m_compDressUp.m_holder); } } _wordTextField = _ui.m_dialogHead.m_txtContent; _arrow = _ui.m_dialogHead.m_iconNext; lastTextFieldType = "head"; } else if (!string.IsNullOrEmpty(headRes)) { _ui.m_dialogHead.target.visible = true; _ui.m_dialogHead.m_txtName.text = roleName; _ui.m_dialogHead.m_comphead.m_head.visible = true; _ui.m_dialogHead.m_comphead.m_holder.visible = false; _ui.m_dialogHead.m_comphead.m_head.url = ResPathUtil.GetNpcHeadPath(headRes); _wordTextField = _ui.m_dialogHead.m_txtContent; _arrow = _ui.m_dialogHead.m_iconNext; lastTextFieldType = "head"; } else if (!string.IsNullOrEmpty(roleName)) { _ui.m_dialogName.target.visible = true; if (IsTeaParty) { var roleContainerList = LeagueDataManager.Instance.RoleContainerList; var teapartyRoleCfg = TeapartyRoleCfgArray.Instance.GetCfgsByid(LeagueDataManager.Instance.TeaPartyId); int roleIndex = Convert.ToInt32(roleName); _ui.m_dialogName.m_txtName.text = teapartyRoleCfg[roleIndex - 1].name; _ui.m_dialogName.m_bgType.selectedIndex = 1; _ui.m_dialogName.m_showArrow.selectedIndex = 1; if (roleIndex <= roleContainerList.Count && roleContainerList[roleIndex - 1].MaxScoreRoleName != null && roleContainerList[roleIndex - 1].MaxScoreRoleName != "" && _ui.m_dialogName.m_txtName.text != "") { _ui.m_comPlayName.visible = true; _ui.m_txtPlayName.text = roleContainerList[roleIndex - 1].MaxScoreRoleName; if (_ui.m_txtPlayName.text == RoleDataManager.roleName) _ui.m_dialogName.m_bgType.selectedIndex = 0; } else _ui.m_comPlayName.visible = false; } else { _ui.m_dialogName.m_bgType.selectedIndex = 0; _ui.m_dialogName.m_showArrow.selectedIndex = 0; _ui.m_dialogName.m_txtName.text = roleName; } _wordTextField = _ui.m_dialogName.m_txtContent; _arrow = _ui.m_dialogName.m_iconNext; if (!lastTextFieldType.Equals("name")) { lastTextFieldType = "name"; StoryDialogDataManager.Instance.waiting = true; _ui.m_t0.Play(()=> { StoryDialogDataManager.Instance.waiting = false; }); } } else { if (IsTeaParty) _ui.m_dialogText.m_showArrow.selectedIndex = 1; else _ui.m_dialogText.m_showArrow.selectedIndex = 0; _ui.m_dialogText.target.visible = true; _wordTextField = _ui.m_dialogText.m_txtContent; _arrow = _ui.m_dialogText.m_iconNext; lastTextFieldType = "text"; _ui.m_comPlayName.visible = false; } _wordList = Regex.Split(words, "&&"); _wordIndex = 0; _typingEffect = new TypingFadeEffectPro(_wordTextField); _typingEffect.typeFinishedAction = ShowCurrentWords; ShowNextDialog(); } private void ShowNextDialog() { if (_wordList != null && _wordList.Length > _wordIndex) { string itemInfo = _wordList[_wordIndex]; string[] itemInfoList = Regex.Split(itemInfo, "="); _currentWords = itemInfoList[0]; if (itemInfoList.Length > 1) { _wordTextField.data = itemInfoList[1]; } else { _wordTextField.data = null; } Timers.inst.StartCoroutine(StartShowLetters()); } else { OnStepComplete(); } } private void ShowCurrentWords() { _arrow.target.visible = true; //Timers.inst.Remove(UpdateLetters); StopTyping(); _typingEffect?.Cancel(); _wordTextField.text = _currentWords; _dialogListLookBack.Add(_currentWords); _isShowLetters = false; _wordIndex++; if (_autoPlay) { int interval = (int)Mathf.Max(VoiceManager.Instance.GetClipLength(), GameConst.NEXT_WORDS_INTERVAL_MAX / _speedAutoPlay); Timers.inst.Add(interval, 1, ShowNextWords); } } private void ShowNextWords(object param = null) { if (_wordTextField != null) { if (_isShowLetters) { ShowCurrentWords(); } else { string stepID = (string)_wordTextField.data; if (stepID != null) { OnStepComplete(stepID); } else { ShowNextDialog(); } } } } private IEnumerator StartShowLetters() { _isShowLetters = true; _arrow.target.visible = false; _wordTextField.verticalAlign = VertAlignType.Top; _wordTextField.text = ""; ArrayList letters = StoryUtil.GetLettersList(_currentWords); _canClickBtnNext = false; while (StoryDialogDataManager.Instance.waitPicFade || StoryDialogDataManager.Instance.waiting) { yield return new WaitForEndOfFrame(); } _canClickBtnNext = true; _wordTextField.text = _currentWords; StartTyping(); } /// /// 开启打字机显示 /// private void StartTyping() { _typingEffect.SetSpeed(_speedAutoPlay); _typingEffect.Start(); // 如果配置了语音,则播放语音 VoiceManager.Instance.PlayVoice(); } private void StopTyping() { _typingEffect.Cancel(); } private void UpdateBg(string value) { if (value.Length > 0) { SceneController.UpdateDialogBg(value, _sceneObject); } } private void UpdatePic(string value) { if(value.Length > 0 && !IsTeaParty) { SceneController.UpdateDialogPic(value, _sceneObject); } } private void UpdateRoleObj(string value) { if (IsTeaParty) { var roleContainerList = LeagueDataManager.Instance.RoleContainerList; MyDressUpHelper.dressUpObj.setSceneObj(_sceneObject, false, false); for (int i = 0; i < roleContainerList.Count; i++) { if (value == (i + 1).ToString() && roleContainerList[i].EquipIds.Count > 0) { MyDressUpHelper.dressUpObj.PutOnItemList(roleContainerList[i].EquipIds); return; } } MyDressUpHelper.dressUpObj.PutOnDefaultDressUpData(IsTeaParty); } } private void UpdateMusic(string value) { if (value.Length > 0) { if (value == "0") { MusicManager.Instance.Stop(); } else { MusicManager.Instance.PlayCroutine(ResPathUtil.GetMusicPath(value, "mp3")); } } } private void PlayEffect(string[] infos) { } private void PlayShake(int[] shakeInfoArr) { if (shakeInfoArr != null && shakeInfoArr.Length > 0) { Vector3 position = _sceneObject.transform.position; position.x = (float)shakeInfoArr[0] / GameConst.PIXELS_PER_UNITY_UNIT; position.y = (float)shakeInfoArr[1] / GameConst.PIXELS_PER_UNITY_UNIT; _sceneObject.transform.position = position; float attenuationX = (float)shakeInfoArr[2] / GameConst.PIXELS_PER_UNITY_UNIT; float attenuationY = (float)shakeInfoArr[3] / GameConst.PIXELS_PER_UNITY_UNIT; float interval = (float)shakeInfoArr[4] / 1000; float duration = (float)shakeInfoArr[5] / 1000; int repeat = Mathf.RoundToInt(duration / interval); Timers.inst.Add(interval, 0, UpdateShake, new float[] { attenuationX, attenuationY }); } } private void UpdateShake(object param) { float[] attenuations = param as float[]; float attenuationX = attenuations[0]; float attenuationY = attenuations[1]; Vector3 position = _sceneObject.transform.position; bool done = false; bool doneX = false; float absX = Mathf.Abs(position.x); if (absX > attenuationX) { int dir = (int)(position.x / absX); position.x = Mathf.Abs(position.x) - attenuationX; position.x *= -1 * dir; } else { doneX = true; position.x = 0; } bool doneY = false; float absY = Mathf.Abs(position.y); if (absY > attenuationY) { int dir = (int)(position.y / absY); position.y = Mathf.Abs(position.y) - attenuationY; position.y *= -1 * dir; } else { doneY = true; position.y = 0; } done = doneX && doneY; _sceneObject.transform.position = position; if (done) { Timers.inst.Remove(UpdateShake); } } private void Over(bool isSkip = false) { if (_onCompleteStoryDialogCall != null) { _onCompleteStoryDialogCall(isSkip, _onCompleteStoryDialogCallParam); } } private void UpdateSpeedUpBtn() { if (_speedAutoPlay > 1) { _ui.m_btnSpeedUp.text = "x" + _speedAutoPlay; } else { _ui.m_btnSpeedUp.text = ""; } _typingEffect?.SetSpeed(_speedAutoPlay); } private void StopAutoPlay() { _autoPlay = false; _ui.m_btnAutoPlay.selected = false; Timers.inst.Remove(ShowNextWords); } } }