欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity简单实用的文本对话插件,可以做任务说明框

程序员文章站 2022-06-15 14:49:25
...

实现需求:类似对话,
开始对话,
1.播放问题文字,打字机动画播放文字,鼠标点击播完所有文字,
2.再次点击,播放回答文字。
3.再次播放问题文字。
4.如果第2步没有对应文字,则跳到第1步,第1步没有对应文字则跳到第2步。

引用了DoTween插件和特性拓展插件NaughtyAttributes。
https://github.com/dbrizov/NaughtyAttributes
末尾有百度云链接
Unity简单实用的文本对话插件,可以做任务说明框
Unity简单实用的文本对话插件,可以做任务说明框

核心代码

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功能代码