Unity游戏开发:对话系统的实现

在解谜类游戏中,与npc的对话是一个基础且常用的功能。通常来说,在与npc的对话中玩家可以获取一些有价值的信息并对之后的游戏有一定的导向作用。此外,在玩家获取对应物品前后,与npc的对话内容也会发生相应改变。因此,我们需要将对话系统进行封装,以便于在不同的npc身上进行使用,同时要预留接口,后期可以增加或修改对话内容。
这里我们以Cotton Puzzle为例,将对话系统拆分为数据、逻辑和UI三部分来实现。在游戏中,获取物品前后与老太太的对话显示如下:
获取船票前
获取船票后

一、数据

首先,添加数据创建目录

//DialogData.cs
[CreateAssetMenu(fileName = "DailogData", menuName = "Dialog/DailogData")]

创建列表用于存储对话内容

//DialogData.cs
public class DialogData : ScriptableObject
{
    public List<string> dialogList;
}

之后,单机右键依次选择Create -> Dialog -> DialogData创建一个空的数据集
创建数据
在所创建的数据集中输入对话内容,如下:
Empty
Finish

二、逻辑

利用栈来存储对话数据,每次在需要进行对话时首先将当前状态设置为isTalking并禁用场景切换的操作,之后每一次点击老奶奶便从栈中弹出一条对话内容进行显示。在完成对话之后将isTalking设置为false并重新将数据压入栈中。

1.定义数据存储和状态变量

//DialogController.cs
    public DialogData dialogEmpty;
    public DialogData dialogFinish;

    private Stack<string> dialogEmptyStack = new Stack<string>();
    private Stack<string> dialogFinishStack = new Stack<string>();

    public bool isTalking;

2.在游戏一开始时将数据压入栈中

//DialogController.cs
    private void Awake()
    {
        FillDialogStack();
    }

    public void FillDialogStack()
    {
        for(int i=dialogEmpty.dialogList.Count-1;i>=0;i--)
        {
            dialogEmptyStack.Push(dialogEmpty.dialogList[i]);
        }
        for (int i = dialogFinish.dialogList.Count - 1; i >= 0; i--)
        {
            dialogFinishStack.Push(dialogFinish.dialogList[i]);
        }
    }

3.定义协程,根据不同状态显示不同对话内容

    public void ShowDialogEmpty()
    {
        if (!isTalking)
            StartCoroutine(DialogRoutine(dialogEmptyStack));
    }

    public void ShowDialogFinish()
    {
        if (!isTalking)
            StartCoroutine(DialogRoutine(dialogFinishStack));
    }
    
    private IEnumerator DialogRoutine(Stack<string> data)
    {
        isTalking = true;
        //Debug.Log("DialogRoutine协程开始");
        if (data.TryPop(out string result))
        {
            //Debug.Log("开始对话");
            EventHandler.CallShowDialogEvent(result);
            yield return null;
            EventHandler.CallGameStateChangedEvent(GameState.Pause);//暂停游戏
        }
        else
        {
            EventHandler.CallShowDialogEvent(string.Empty);
            FillDialogStack();
            EventHandler.CallGameStateChangedEvent(GameState.GamePlay);//暂停游戏
        }
        isTalking = false;
    }

三、UI

在DialogUI 中注册ShowDialogEvent ,当对话未完成时(即dialog 不为空)将panel设置为active,当对话结束以后便关闭panel。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DialogUI : MonoBehaviour
{
    public GameObject panel;
    public Text dialogText;

    private void OnEnable()
    {
        EventHandler.ShowDialogEvent += ShowDialog;
    }

    private void OnDisable()
    {
        EventHandler.ShowDialogEvent -= ShowDialog;
    }


    private void ShowDialog(string dialog)
    {
        if (dialog != string.Empty)
            panel.SetActive(true);
        else
            panel.SetActive(false);
        dialogText.text = dialog;
    }    
}

  • 13
    点赞
  • 132
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Unity对话系统是一个轻量级的对话系统和界面,设计用于绑定到任何UI系统。它需要Unity 5.0.0或更高版本。 在Unity实现对话系统的一种方法是使用VIDE Dialogues (Pro) 2.1。你需要在脚本中引入命名空间using UnityEngine.UI;,并创建相应的游戏对象和文本组件来显示对话内容。你可以使用[TextArea(1,3)]特性来在Inspector窗口中将文字区域显示为三行。对话内容可以存储在一个字符串数组中,并通过索引进行访问。你还可以将对话信息存储在ScriptableObject(SO)中,使用[CreateAssetMenu(fileName ="New Dialogue",menuName ="Dialogue/Dialogue Data")]特性来创建对话数据的菜单选项。对话数据可以存储在一个包含对话片段的列表中。 总之,Unity对话系统是一个可以绑定到任何UI系统的轻量级对话系统,可以通过使用VIDE Dialogues来实现,并且还可以使用ScriptableObject来存储对话数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Unity对话系统源码](https://download.csdn.net/download/nippyli/10143335)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [UNITY 对话系统](https://blog.csdn.net/qq_45783556/article/details/116171371)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Unity3D RPG实现 3 —— 对话、任务系统](https://blog.csdn.net/weixin_43757333/article/details/123287146)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值