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

实现需求:类似对话,
开始对话,
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

发布了7 篇原创文章 · 获赞 1 · 访问量 191

猜你喜欢

转载自blog.csdn.net/boyZhenGui/article/details/103989608