實現需求:類似對話,
開始對話,
1.播放問題文字,打字機動畫播放文字,鼠標點擊播完所有文字,
2.再次點擊,播放回答文字。
3.再次播放問題文字。
4.如果第2步沒有對應文字,則跳到第1步,第1步沒有對應文字則跳到第2步。
引用了DoTween插件和特性拓展插件NaughtyAttributes。
https://github.com/dbrizov/NaughtyAttributes
末尾有百度雲鏈接
核心代碼
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using NaughtyAttributes;
using UnityEngine.Events;
using UnityEditor;
/// <summary>
/// 對話,需引用dotween
/// 設置好,使用play即可
/// </summary>
public enum DialogueType
{
speek,
answer
}
public class DialogueCrt : MonoBehaviour
{
private DialData dataFlag = new DialData();
public bool showList = true;
[ShowIf("showList")]
[ReorderableList]
public List<DialogueData> dialogueList;
private GameObject speakPrefab;
private GameObject answerPrefab;
private List<GameObject> speakList = new List<GameObject>();
private List<GameObject> answerList = new List<GameObject>();
private GameObject mNowObj;
private int index = 0;
private UnityAction mAction;
private bool isEnd = false;
private bool isKeyDown =false;
public bool isUseJson = false;
[ShowIf("isUseJson")]
public TextAsset json;
[Button]
private void Json2List()
{
if (json == null || !isUseJson)
throw new System.Exception("json未添加,或者沒勾選isUseJson,請勾選isUseJson並添加json");
else
{
Undo.RegisterFullObjectHierarchyUndo(gameObject, "json");
dataFlag = JsonUtility.FromJson<DialData>(json.text);
dialogueList = dataFlag.dialogueList;
showList = true;
Debug.Log("成功將json添加到list");
}
}
/// <summary>
/// 播放dialogue
/// </summary>
public void Play()
{
Debug.Log("play");
Remove();
isEnd = false;
gameObject.SetActive(true);
if (speakList.Count > 0)
{
ShowObjText(speakList[index], DialogueType.speek);
}
}
/// <summary>
/// 播放dialogue,並添加結束事件
/// </summary>
/// <param name="action">結束調用事件</param>
public void Play(UnityAction action)
{
Debug.Log("playAction");
Remove();
isEnd = false;
gameObject.SetActive(true);
if (speakList.Count > 0)
{
ShowObjText(speakList[index], DialogueType.speek);
}
mAction = action;
}
/// <summary>
/// 結束dialogue
/// </summary>
public void Close()
{
DiaEnd();
}
private void Init()
{
speakPrefab = Resources.Load<GameObject>("Speak");
answerPrefab = Resources.Load<GameObject>("Answer");
foreach (DialogueData d in dialogueList)
{
if (true)
{
GameObject obj = Instantiate(speakPrefab, transform);
speakList.Add(obj);
}
if (true)
{
GameObject obj = Instantiate(answerPrefab, transform);
answerList.Add(obj);
}
}
Remove();
}
private void Remove()
{
EndObjText(mNowObj);
index = 0;
for (int i = 0; i < speakList.Count; i++)
{
speakList[i].SetActive(false);
}
for (int i = 0; i < answerList.Count; i++)
{
answerList[i].SetActive(false);
}
}
void Awake()
{
Init();
gameObject.SetActive(false);
}
void Update()
{
if (isEnd)
return;
if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
{
if(!isTweenEnd)
EndObjText(mNowObj);
else
Next();
}
}
private void DiaEnd()
{
Debug.Log("完成");
isEnd = true;
gameObject.SetActive(false);
if (mAction != null)
mAction.Invoke();
}
private void Next()
{
if (mNowObj == speakList[index])
{
ShowObjText(answerList[index], DialogueType.answer);
}
else if (mNowObj == answerList[index])
{
index++;
if (index >= dialogueList.Count)
{
DiaEnd();
return;
}
ShowObjText(speakList[index], DialogueType.speek);
}
}
private bool isTweenEnd = false;
private void ShowObjText(GameObject obj, DialogueType type)
{
mNowObj = obj;
string str = null;
if (!obj.activeSelf)
{
switch (type)
{
case DialogueType.speek:
str = dialogueList[index].speakStr;
break;
case DialogueType.answer:
str = dialogueList[index].answerStr;
break;
}
obj.GetComponentInChildren<Text>().ShowText(str,()=> { isTweenEnd = true; });
if (str == null || str == "")
{
EndObjText(mNowObj);
Next();
return;
}
isTweenEnd = false;
obj.SetActive(true);
}
}
private void EndObjText(GameObject obj)
{
if (obj != null)
{
obj.GetComponentInChildren<Text>().EndTextAnim();
isTweenEnd = true;
}
}
}
[System.Serializable]
public class DialData
{
public List<DialogueData> dialogueList;
}
[System.Serializable]
public class DialogueData
{
public string speakStr;
public string answerStr;
}
DoTween動畫代碼
using UnityEngine.UI;
using DG.Tweening;
using UnityEngine.Events;
using UnityEngine;
public static class TextDT
{
public static void ShowText(this Text _text, string _str,TweenCallback cb, float _time = 0.4f)
{
_text.text = "";
_text.DOText(_str, _time * _str.Length).OnComplete(cb);
}
public static void EndTextAnim(this Text _text)
{
_text.DOGoto(1000f, false);
}
}
使用2018.4.2製作
百度雲盤:鏈接:https://pan.baidu.com/s/1jkk2Ru_FdnRJ_OZkf8frtw 密碼:rg1w
如果文章對你有幫助,不妨關注我一下,點個贊。
我會一直分享Unity開發中解決的坑,分享學到的技術,也會分享讀書心得和理財心得,謝謝大家。