using Sirenix.OdinInspector; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class UnTalkAnim : MonoBehaviour { #region Define public delegate void OnPlayAnimFinishedHandler(); public delegate void OnLinePlayedHandler(int line); [System.Serializable] public struct TalkerInfo { public string Name; public Sprite Icon; } [System.Serializable] public struct TalkerUIInfo { public Image HeadIcon; public TMPro.TMP_Text NameText; } [System.Serializable] public struct PlayTalkAnimLine { public TalkerInfo Talker; public List Lines; public List NodeItems; public bool IsRouteChoose; public bool ChoseMode; //public List ChoseItemLines; } [System.Serializable] public struct PlayTalksAnimInfo { public List Lines; public bool NoOpening; public bool NoEnding; public OnPlayAnimFinishedHandler OnPlayAnimFinished; public OnLinePlayedHandler OnLinePlayed; } #endregion [SerializeField] private float m_showTextInterval; [SerializeField] private float m_fadeSpeed; [SerializeField] private CanvasGroup m_panelGroup; [SerializeField] private TalkerUIInfo m_talkerUI; [SerializeField] private TMPro.TMP_Text m_speechText; [SerializeField] private Text m_typeText; [SerializeField] private GameObject m_rewardPanel; [SerializeField] private GameObject m_routePanel; #region TalkMode [SerializeField] private bool m_talkModeConfirmed; [SerializeField] private GameObject m_choseModePanel; [SerializeField] private GameObject m_talkModePanel; [SerializeField] private GameObject m_talkModeFinishedGO; private PlayTalkAnimLine? m_currentPlayInfo; private int m_currentTalkModeLineIndex; private int m_showTextCount = 0; private string TalkModeCurrentLine { get { return m_currentPlayInfo.Value.Lines[m_currentTalkModeLineIndex]; } } private bool IsTalkModeLineFinished { get { return m_showTextCount >= TalkModeCurrentLine.Length; } } private void SetSpeechText(string text) { m_speechText.text = text; } #endregion #region Chose Mode private bool m_inputComfirmed; private int m_choseIndex; [SerializeField] private GameObject m_choseModeItemPrefab; [SerializeField] private Transform m_choseItemParent; private List m_choseModeItems = new List(); public int ChoseIndex { get { return m_choseIndex; } } private void OnButtonChosed(int btnIndex) { m_choseIndex = btnIndex; m_inputComfirmed = true; } #endregion private void SetAnimFadeOpacity(float opacity) { m_panelGroup.alpha = opacity; } private void RefreshTalkerUIs(PlayTalkAnimLine playInfo) { m_talkerUI.HeadIcon.sprite = playInfo.Talker.Icon; m_talkerUI.NameText.text = playInfo.Talker.Name; } public IEnumerator PlayTalkAnim_Start(PlayTalkAnimLine playInfo) { SetSpeechText(""); RefreshTalkerUIs(playInfo); float startValue = 0; float endValue = 1; float curValue = startValue; while (curValue < endValue) { curValue += Time.deltaTime * m_fadeSpeed; SetAnimFadeOpacity(curValue); yield return null; } } public IEnumerator PlayTalkAnim_End(PlayTalkAnimLine playInfo) { float startValue = 1; float endValue = 0; float curValue = startValue; while (curValue > endValue) { curValue -= Time.deltaTime * m_fadeSpeed; SetAnimFadeOpacity(curValue); yield return null; } } public void SetTalkText(PlayTalkAnimLine playInfo) { m_currentPlayInfo = playInfo; m_choseModePanel.SetActive(false); m_talkModePanel.SetActive(true); m_talkModeFinishedGO.SetActive(false); m_typeText.text = playInfo.IsRouteChoose ? "Choose a path" : "Choose a reward"; m_rewardPanel.SetActive(!playInfo.IsRouteChoose); m_routePanel.SetActive(playInfo.IsRouteChoose); if (playInfo.ChoseMode) { m_inputComfirmed = false; foreach (var item in m_choseModeItems) { Destroy(item); } m_choseModeItems.Clear(); int count = playInfo.NodeItems.Count; for (int i = 0; i < count; i++) { string item = playInfo.NodeItems[i].Desc; GameObject newGO = Instantiate(m_choseModeItemPrefab, m_choseItemParent); m_choseModeItems.Add(newGO); UnTalkChoseButton btnScript = newGO.GetComponent(); btnScript.ButtonIndex = i; btnScript.SetNodeItem(playInfo.NodeItems[i]); btnScript.OnChosen.AddListener(delegate () { OnButtonChosed(btnScript.ButtonIndex); }); } } } public IEnumerator PlayTalkAnim_Text(PlayTalkAnimLine playInfo) { m_currentPlayInfo = playInfo; RefreshTalkerUIs(playInfo); if (playInfo.ChoseMode) { m_choseModePanel.SetActive(true); m_talkModePanel.SetActive(false); while (true) { if (!m_inputComfirmed) { yield return null; continue; } m_inputComfirmed = false; break; } } else { m_currentTalkModeLineIndex = 0; m_choseModePanel.SetActive(false); m_talkModePanel.SetActive(true); SetSpeechText(""); while (m_currentTalkModeLineIndex < playInfo.Lines.Count) { m_talkModeFinishedGO.SetActive(false); m_talkModeConfirmed = false; m_showTextCount = 0; int totalCount = TalkModeCurrentLine.Length; while (m_showTextCount <= totalCount) { yield return new WaitForSeconds(m_showTextInterval); int showCount = m_showTextCount <= totalCount ? m_showTextCount : totalCount; SetSpeechText(TalkModeCurrentLine.Substring(0, showCount)); m_showTextCount++; } m_talkModeFinishedGO.SetActive(true); while (!m_talkModeConfirmed) { yield return null; } m_talkModeConfirmed = false; m_currentTalkModeLineIndex++; } } m_currentPlayInfo = null; } public void JumpTextAnim() { m_showTextCount = 1000000; //print($"iii {m_currentTalkModeLineIndex}"); } public void FinishTalkMode() { if (m_currentPlayInfo == null) { return; } if (!IsTalkModeLineFinished) { JumpTextAnim(); return; } m_talkModeConfirmed = true; } public IEnumerator PlayTalksAnim(PlayTalksAnimInfo playInfo) { if (playInfo.Lines == null || playInfo.Lines.Count == 0) { yield break; } if (!playInfo.NoOpening) { yield return PlayTalkAnim_Start(playInfo.Lines.First()); } for (int i = 0; i < playInfo.Lines.Count; i++) { playInfo.OnLinePlayed?.Invoke(i); yield return PlayTalkAnim_Text(playInfo.Lines[i]); } if (!playInfo.NoEnding) { yield return PlayTalkAnim_End(playInfo.Lines.Last()); } playInfo.OnPlayAnimFinished?.Invoke(); } [Button] public void TestPlayTalks(PlayTalksAnimInfo playInfo) { StartCoroutine(PlayTalksAnim(playInfo)); } private void Update() { if (m_currentPlayInfo != null && !m_currentPlayInfo.Value.ChoseMode) { if (Input.anyKeyDown) { FinishTalkMode(); } } } }