【unity实战】教你轻松构建对话系统

先来看最终效果

前言

欢迎来到我们的Unity实战教程系列。在这一篇中,我们将深入探讨如何在Unity中构建一个对话系统。

对话系统是许多游戏中不可或缺的一部分,特别是在角色扮演游戏(RPG)、冒险游戏和视觉小说等类型中。它们为玩家提供了丰富的背景故事,帮助塑造角色性格,甚至决定游戏的发展方向和结局。然而,构建一个既能满足游戏需求又易于管理和扩展的对话系统却是一项挑战。

本教程将指导你如何在Unity中从零开始构建一个灵活且可自定义的对话系统。我们将首先讨论对话系统的基本组成部分,包括对话节点、角色类型和对话内容。然后,我们将逐步引导你创建ScriptableObject以存储对话数据,以及如何使用MonoBehaviour处理对话逻辑。我们还将介绍如何在Unity编辑器中设置对话数据,并模拟实际的对话场景。

无论你是Unity新手,还是有一定经验的开发者,只要你对构建对话系统感兴趣,都可以从本教程中受益。希望你能跟随我们的步骤,动手实践,并最终在你自己的游戏项目中构建出精彩的对话系统。

让我们开始吧!

开始

新建对话结点脚本DialogNode

csharp 复制代码
// CharacterType 是一个枚举,它定义了两种类型的角色:NPC 和玩家。
public enum CharacterType
{
    Npc,     // NPC 角色类型
    Player   // 玩家角色类型
}

// DialogNode 是一个可序列化的类,代表了一个对话节点。
[Serializable]
public class DialogNode
{
    public CharacterType type; // 表示对话的角色类型。
    public string charecterName; // 表示角色的名字。
    
    [TextArea]
    public string dialog; // 表示对话的内容。
}

新增对话脚本Dialogue

csharp 复制代码
// Dialogue 是一个继承自 ScriptableObject 的类,它表示一段对话。
[CreateAssetMenu(fileName = "对话")]
public class Dialogue : ScriptableObject 
{
    // 它包含了这段对话中的所有对话节点。
    public DialogNode[] dialogNodes;
}

新增对话系统脚本DialogueSystem

csharp 复制代码
public class DialogueSystem : MonoBehaviour
{
    [Header("对话")]
    [SerializeField] private Dialogue dialogue;
    [Header("对话框")]
    [SerializeField] private GameObject dialogBox;
    [Header("对话文本")]
    [SerializeField] private TextMeshProUGUI dialog;
    [Header("角色名称")]
    [SerializeField] private TextMeshProUGUI charecterName;
    [Header("角色类型")]
    [SerializeField] private CharacterType type;

    // 用于追踪当前正在播放的对话节点的索引。
    private int index;

    // 表示玩家是否在交互范围内。
    private bool isInTurn;

    // 如果玩家按下 E 键并且在交互范围内,则开始播放对话。
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.E) && isInTurn)
            Play();
    }

    // 当玩家进入交互范围时,设置 isInTurn 为 true。
    private void OnTriggerEnter2D(Collider2D other) => isInTurn = true;

    // 当玩家离开交互范围时,设置 isInTurn 为 false。
    private void OnTriggerExit2D(Collider2D other) => isInTurn = false;

    // Play 函数用于开始播放对话。
    private void Play()
    {
        // 激活对话框。
        dialogBox.SetActive(true);

        // 获取当前对话节点,并更新索引值。
        DialogNode node = dialogue.dialogNodes[Mathf.Clamp(index++, 0, dialogue.dialogNodes.Length - 1)];

        // 设置对话文本和角色名称。
        dialog.text = node.dialog;
        charecterName.text = node.charecterName;

        // 如果已经播放完所有对话节点,则关闭对话框。
        if (index - 1 == dialogue.dialogNodes.Length)
            dialogBox.SetActive(false);
    }
}

新增对话表,配置我们的对话信息

在角色挂载我们的对话系统脚本DialogueSystem并配置参数

运行效果

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。点赞越多,更新越快哦!当然,如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

相关推荐
极客柒27 分钟前
Unity 大地图高性能砍树顶点动画Shader
unity·游戏引擎
avi91114 小时前
UnityProfiler游戏优化-举一个简单的Editor调试
游戏·unity·游戏引擎·aigc·vibe coding·editor扩展
学嵌入式的小杨同学4 小时前
C 语言实战:动态规划求解最长公共子串(连续),附完整实现与优化
数据结构·c++·算法·unity·游戏引擎·代理模式
学嵌入式的小杨同学7 小时前
顺序表(SqList)完整解析与实现(数据结构专栏版)
c++·算法·unity·游戏引擎·代理模式
程序猿多布7 小时前
HybridCLR热更打包后AOT泛型函数实例化缺失处理
unity·hybridclr·aot generic
平行云8 小时前
实时云渲染支持数字孪生智能工厂:迈向“零原型”制造
人工智能·unity·ue5·云计算·webrtc·制造·实时云渲染
dzj20218 小时前
Unity中使用LLMUnity遇到的问题(一)
unity·llm·llmunity
Howrun7779 小时前
虚幻引擎 C++ 制作“射击FPS游戏“
游戏·游戏引擎·虚幻
DowneyJoy9 小时前
【Unity通用工具类】列表扩展方法ListExtensions
unity·c#·交互
极客柒9 小时前
Unity 大地图 高性能路径引导Shader
unity·游戏引擎