using FairyGUI; using UnityEngine; using UI.Main; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; 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 GameObject _scenePrefab; private GameObject _npcHead; private GoWrapper _npcWrapper; private GTextField _wordTextField; //剧情完成回调 private OnCompleteStoryDialogCall _onCompleteStoryDialogCall; private object _onCompleteStoryDialogCallParam; //回顾 private ArrayList _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 string _currentWords; public override void Dispose() { base.Dispose(); if (_scenePrefab != null) { GameObject.Destroy(_scenePrefab); _scenePrefab = null; } _wordTextField = null; _arrow = null; _isShowLetters = false; SceneController.DestroyObjectFromView(_npcHead); Timers.inst.Remove(UpdateLetters); } protected override void Init() { base.Init(); packageName = UI_StoryDialogUI.PACKAGE_NAME; _ui = UI_StoryDialogUI.Create(); viewCom = _ui.target; isfullScreen = true; _scenePrefab = GFGAsset.Load(ResPathUtil.GetPrefabPath("SceneStoryDialog")); } protected override void OnInit() { base.OnInit(); _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 = GameObject.Instantiate(_scenePrefab); } _speedAutoPlay = 1; _autoPlay = false; UpdateSpeedUpBtn(); _dialogListLookBack = new ArrayList(); object[] datas = viewData as object[]; string stroyStartID = (string)datas[0]; bool skipable = (bool)datas[1]; _onCompleteStoryDialogCall = (OnCompleteStoryDialogCall)datas[2]; if (datas.Length > 3) { _onCompleteStoryDialogCallParam = datas[3]; } if(LauncherConfig.netType == LauncherConfig.EnumNetType.LOCAL) { //临时设置都可以跳过对话 skipable = true; } _ui.m_btnSkip.enabled = skipable; ShowNextStep(stroyStartID); _ui.m_c1.selectedIndex = 0; _ui.m_btnAutoPlay.selected = false; if (stroyStartID == MainStoryDataManager.priorId) { _ui.m_c1.selectedIndex = 1; _ui.m_btnAutoPlay.selected = true; OnClickBtnAutoPlay(); } } protected override void OnHide() { base.OnHide(); Timers.inst.Remove(UpdateLetters); Timers.inst.Remove(UpdateShake); Timers.inst.Remove(OnScreenEffectComplete); Timers.inst.Remove(ShowNextWords); ScreenBlackController.Instance.HideBlack(); StopAutoPlay(); if (_sceneObject != null) { GameObject.Destroy(_sceneObject); _sceneObject = null; } MusicManager.Instance.Play(ResPathUtil.GetMusicPath(ConstMusicName.DEFAULT)); _onCompleteStoryDialogCall = null; _onCompleteStoryDialogCallParam = null; } private void OnClickBtnBack() { Over(false); } private void OnClickBtnNext() { // StopAutoPlay(); ShowNextWords(); } private void OnClickBtnLookBack() { ViewManager.Show(ViewName.STORY_LOOK_BACK_VIEW, _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"; } 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; } UpdateSpeedUpBtn(); } private void OnClickBtnAutoPlay() { _autoPlay = _ui.m_btnAutoPlay.selected; if (_autoPlay) { ShowNextWords(); } } private void InitStepListById(string dialogID) { var temp = StoryDialogCfgArray.Instance.GetCfgs(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); 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; Timers.inst.Add(delay, 1, OnScreenEffectComplete); } else { OnScreenEffectComplete(); } } private void OnScreenEffectComplete(object param = null) { if (_nextStepId == "0") { Over(); } else { ShowNextStep(_nextStepId); } } private void InitStepContent(StoryDialogCfg storyDialogCfg) { _currentStepCfg = storyDialogCfg; UpdateMusic(storyDialogCfg.musicRes); UpdateBg(storyDialogCfg.bgRes); UpdatePic(storyDialogCfg.picRes); PlayEffect(storyDialogCfg.effectInfoArr); PlayShake(storyDialogCfg.shakeInfoArr); string content = storyDialogCfg.content; content = storyDialogCfg.content.Replace("self", RoleDataManager.roleName); if (content.IndexOf("//") >= 0) { showList(content); } else { ShowDialog(storyDialogCfg); } } private void showList(string content) { StopAutoPlay(); _ui.m_btnAutoPlay.enabled = false; _wordTextField = null; _ui.m_dialogText.target.visible = false; _ui.m_dialogName.target.visible = false; _ui.m_dialogHead.target.visible = false; _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.m_list.numItems = list.Length; } private void ShowDialog(StoryDialogCfg storyDialogCfg) { _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; if (roleName == "self") { roleName = RoleDataManager.roleName; } //回顾 if (roleName != null) { _dialogListLookBack.Add("[color=#FDA2B1]" + roleName + "[/color]"); } if (!string.IsNullOrEmpty(headAniRes)) { _ui.m_dialogText.target.visible = false; _ui.m_dialogName.target.visible = false; _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; string resPath = ResPathUtil.GetViewEffectPath("ui_nzbq", headAniRes); SceneController.AddObjectToView(_npcHead, _npcWrapper, _ui.m_dialogHead.m_comphead.m_holder, resPath, out _npcHead, out _npcWrapper); _npcHead.transform.localScale = new Vector3(-100, 100, 100); _wordTextField = _ui.m_dialogHead.m_txtContent; _arrow = _ui.m_dialogHead.m_iconNext; } else if (!string.IsNullOrEmpty(headRes)) { _ui.m_dialogText.target.visible = false; _ui.m_dialogName.target.visible = false; _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; } else if (!string.IsNullOrEmpty(roleName)) { _ui.m_dialogText.target.visible = false; _ui.m_dialogName.target.visible = true; _ui.m_dialogHead.target.visible = false; _ui.m_dialogName.m_txtName.text = roleName; _wordTextField = _ui.m_dialogName.m_txtContent; _arrow = _ui.m_dialogName.m_iconNext; } else { _ui.m_dialogText.target.visible = true; _ui.m_dialogName.target.visible = false; _ui.m_dialogHead.target.visible = false; _wordTextField = _ui.m_dialogText.m_txtContent; _arrow = _ui.m_dialogText.m_iconNext; } _wordList = Regex.Split(words, "&&"); _wordIndex = 0; ShowNextDialog(); } private void ShowNextDialog() { if (_wordList != null && _wordList.Length > _wordIndex) { string itemInfo = _wordList[_wordIndex]; string[] itemInfoList = Regex.Split(itemInfo, "="); _currentWords = itemInfoList[0]; StartShowLetters(); if (itemInfoList.Length > 1) { _wordTextField.data = itemInfoList[1]; } else { _wordTextField.data = null; } } else { OnStepComplete(); } } private void ShowCurrentWords() { _arrow.target.visible = true; Timers.inst.Remove(UpdateLetters); _wordTextField.text = _currentWords; _dialogListLookBack.Add(_currentWords); _isShowLetters = false; _wordIndex++; if (_autoPlay) { Timers.inst.Add(GameConst.NEXT_WORDS_INTERVAL_MAX / _speedAutoPlay, 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 void StartShowLetters() { _isShowLetters = true; _arrow.target.visible = false; _wordTextField.verticalAlign = VertAlignType.Top; _wordTextField.text = ""; ArrayList letters = StoryUtil.GetLettersList(_currentWords); Timers.inst.Add(GameConst.LETTERS_INTERVAL_MAX / _speedAutoPlay, 0, UpdateLetters, letters); } private void UpdateLetters(object param) { ArrayList letters = (ArrayList)param; if (letters == null || letters.Count <= 0) { ShowCurrentWords(); } else { string letter = (string)letters[0]; letters.RemoveAt(0); _wordTextField.text = _wordTextField.text + letter; } } private void UpdateBg(string value) { if (value.Length > 0) { SceneController.UpdateDialogBg(value, _sceneObject); } } private void UpdatePic(string value) { if (value.Length > 0) { SceneController.UpdateDialogPic(value, _sceneObject); } } private void UpdateMusic(string value) { if (value.Length > 0) { if (value == "0") { MusicManager.Instance.Stop(); } else { MusicManager.Instance.Play(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 = ""; } } private void StopAutoPlay() { _autoPlay = false; _ui.m_btnAutoPlay.selected = false; Timers.inst.Remove(ShowNextWords); } } }