Unity 简单RPG对话系统——龙之谷2的NPC对话系统

Unity 简单RPG对话系统——龙之谷2的NPC对话系统

龙之谷2手游正式上线后不久,试玩了十几分钟(包括捏脸的5分钟),之后就再也没有打开过了。
本文章将对龙之谷2的NPC对话系统进行高仿,同时考虑到 策划可能不断修改对话内容 工具的重复利用,将部分通过编辑器模式来进行制作。

写在前边:

1.参考文章

知乎: Yumir——用128行代码实现一个文字冒险游戏
站内: 虚拟喵——Unity 编辑器扩展总结 五:数组或list集合的显示方式

2.素材使用
unity AssetStore——Unity-Chan! Model

3.根据如下游戏内截图,拆分实现步骤

龙之谷NPC对话系统gif
对话系统

正式开始

一、新建Unity工程,并设置UIPanel

  1. 这里为了 偷懒 方便演示,使用Unity娘到场景中,并复制出两个作为NPC,每个人物模型的Perfab作为空物体**Handle的子物体

图1

  1. NPC1Handle和NPC2Handle分别创建子物体SphereCollider,调整至合适大小,勾选Is Trigger,并重命名为DialogTrigger,Tag选择为NPCDialog,作为主角经过时触发对话界面的触发器

图2

  1. 新建Canvas–>Panel,重命名为DialogPanel,根据个人感觉调整DialogPanel的显示区域
  2. Canvas目录下新建一个空物体,添加GridLayoutGroup组件,用作问答类对话加载答案选项,这里重命名为AnswerGrid
  3. 新建一个空物体,用来挂载接下来的对话系统控制组件,这里重命名为DialogSystem

整体的层级图如下:

层级图

二、调整项目内Player的控制

根据自己的项目情况,让场景内放置好的人物能够实现简单的移动,这里以我下载好的Unity娘为例

  • MainCamera代码:ThirdPersonCamera.cs,找到FixedUpdate ()部分,取消鼠标控制摄像机(因为后边希望通过鼠标左键控制对话进度,当然有需要的同学可以分开写鼠标操作)

FixedUpdate ()

  • Player组件中,去除用不到的组件,并新建一个DialogTriggerEvent.cs,用于控制Player和NPC相遇弹出对话框,具体代码内容稍后再写

DialogTriggerEvent.cs

三、逻辑代码拆分

构思图

四、对话系统控制组件和他的自定义Inspector显示

1.为场景中的对话系统控制器挂载代码(DialogSystemController.cs),控制NPC图片和姓名的显示

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

public class DialogSystemController : MonoBehaviour
{
   
    [SerializeField]
    public List<NPCItem> npcItemArray = new List<NPCItem>();

    public static DialogSystemController Instance;

    void Awake()
    {
   
        Instance = this;
    }
}

[System.Serializable]
public class NPCItem
{
   
    [SerializeField]
    public string ID;
    [SerializeField]
    public Sprite icon;
    [SerializeField]
    public string name;
}

2.Assets目录下,新建Editor文件夹,新建DialogSystemEditor,依赖于DialogSystemController.cs,自定义Inspector面板显示内容

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;

[CustomEditor(typeof(DialogSystemController))]
public class DialogSystemEditor : Editor
{
   
    private ReorderableList _npcItemArray;

    private void OnEnable()
    {
   
        _npcItemArray = new ReorderableList(serializedObject, serializedObject.FindProperty("npcItemArray")
            , true, true, true, true);

        //自定义列表名称
        _npcItemArray.drawHeaderCallback = (Rect rect) =>
        {
   
            GUI.Label(rect, "NPC Array");
        };

        //定义元素的高度
        _npcItemArray.elementHeight = 88;

        //自定义绘制列表元素
        _npcItemArray.drawElementCallback = (Rect rect, int index, bool selected, bool focused) =>
        {
   
            //根据index获取对应元素 
            SerializedProperty item = _npcItemArray.serializedProperty.GetArrayElementAtIndex(index);
            rect.height -= 4;
            rect.y += 2;
            EditorGUI.PropertyField(rect, item, new GUIContent("Index " + index));
        };

        //当删除元素时候的回调函数,实现删除元素时,有提示框跳出
        _npcItemArray.onRemoveCallback = (ReorderableList list) =>
        {
   
            if (EditorUtility.DisplayDialog("Warnning", "Do you want to remove this element?", "Remove", "Cancel"))
            {
   
                ReorderableList.defaultBehaviours.DoRemoveButton(list);
            }
        }
  • 1
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值