【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。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

相关推荐
Artistation Game19 小时前
九、怪物行为逻辑
游戏·unity·游戏引擎
百里香酚兰19 小时前
【AI学习笔记】基于Unity+DeepSeek开发的一些BUG记录&解决方案
人工智能·学习·unity·大模型·deepseek
妙为19 小时前
unreal engine5制作动作类游戏时,我们使用刀剑等武器攻击怪物或敌方单位时,发现攻击特效、伤害等没有触发
游戏·游戏引擎·虚幻·碰撞预设
dangoxiba1 天前
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十三集:制作小骑士的接触地刺复活机制以及完善地图的可交互对象
游戏·unity·visualstudio·c#·游戏引擎
先生沉默先2 天前
使用Materialize制作unity的贴图,Materialize的简单教程,Materialize学习日志
学习·unity·贴图
十画_8242 天前
Visual Studio 小技巧记录
unity·visual studio
red_redemption2 天前
cpp,git,unity学习
git·unity·游戏引擎
tealcwu2 天前
【Unity踩坑】Unity更新Google Play结算库
unity·游戏引擎
先生沉默先2 天前
unity 默认渲染管线材质球的材质通道,材质球的材质通道
unity·游戏引擎·材质
白鹭float.2 天前
【Unity AI】基于 WebSocket 和 讯飞星火大模型
人工智能·websocket·unity