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

相关推荐
大眼睛姑娘1 小时前
Unity3d场景童话梦幻卡通Q版城镇建筑植物山石3D模型游戏美术素材
unity·游戏美术
鹿野素材屋6 小时前
Unity Dots下的动画合批工具:GPU ECS Animation Baker
unity·游戏引擎
小春熙子13 小时前
Unity图形学之着色器之间传递参数
unity·游戏引擎·技术美术·着色器
虾球xz14 小时前
游戏引擎学习第15天
学习·游戏引擎
Java Fans18 小时前
在Unity中实现电梯升降功能的完整指南
unity·游戏引擎
GrimRaider1 天前
[Unity]TileMap开发,TileMap地图缝隙问题
unity·游戏引擎·tilemap
无敌最俊朗@1 天前
unity3d——基础篇小项目(开始界面)
unity·游戏引擎
suzh1qian1 天前
Unity类银河战士恶魔城学习总结(P133 Merge skill tree with Parry skill把技能树和格挡技能相组合)
学习·unity·c#·游戏引擎
泠曦れいひ1 天前
Unity的反射机制及游戏场景
游戏·unity·游戏引擎
tealcwu1 天前
【Unity踩坑】在Mac上安装Cocoapods失败
unity·ios·游戏引擎