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

相关推荐
xcLeigh18 小时前
Unity基础:Instantiate实例化——在运行时动态创建游戏物体
游戏·unity·游戏引擎·教程·instantiate
流浪打工人2 天前
Unity3d TimeLine中audio track的使用
unity
淡海水2 天前
02-07-原理篇-GC暂停时间的本质
开发语言·unity·c#·gc·暂停时间
WarPigs2 天前
UI路径配置SO>字典json工作流
ui·unity
淡海水2 天前
02-06-原理篇-增量式GC与并发GC
算法·unity·c#·并发·gc·增量
阿松爱学习2 天前
【Unity开发】Aspose.PDF的使用
unity·pdf·c#
淡海水2 天前
02-04-原理篇-GC Roots与对象图遍历
算法·unity·c#·图·gc·遍历·roots
辻弋2017 天前
五年前的旅行视频糊成马赛克?Video2X用Real-ESRGAN逐帧重建细节,但只支持Windows、集显用户建议直接放弃
服务器·数据库·windows·游戏引擎·电脑
Martina_03217 天前
AI生成3D场景导入 Unity/Unreal 后,NPC 总串层?用6步检查导航高度与跨层连接
人工智能·游戏·数学建模·3d·unity·自然语言处理·aigc
小贺儿开发7 天前
Unity 局域网遥控幻灯片展示工具 3.0
科技·http·unity·工具·ppt·通信·网页