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

如果文章對你有幫助,不妨關注我一下,點個贊。
我會一直分享Unity開發中解決的坑,分享學到的技術,也會分享讀書心得和理財心得,謝謝大家。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章