Unity简单实用的文本对话插件,可以做任务说明框
程序员文章站
2022-06-15 14:49:25
...
实现需求:类似对话,
开始对话,
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
下一篇: Qt平移动画