[Unity] 实现ScriptableObject数据同步Excel表格(对话系统数据管理,C# ExcelNPOI)

这篇具有很好参考价值的文章主要介绍了[Unity] 实现ScriptableObject数据同步Excel表格(对话系统数据管理,C# ExcelNPOI)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

        在制作游戏中需要管理各种各样的项目资源,其中游戏中的剧情文字也是一种需要管理的资源。自己刚开始接触游戏开发的时候,第一次看MStudio里面的对话系统教学,只讲了怎么写脚本同步UI的设置,并没有讲有什么方式去管理这些对话数据,视频里拿的是txt来演示存储对话数据,导致我制作的第一个游戏也是那txt来写的,一个对话就是一个txt,管理起来肯定是不方便的。

        如何存储文字数据呢?当然我们可以专门写一个系统去对接数据库,而对话系统的网络上也有很多插件,其中就有很多节点化,可分支的对话系统,但是系统太过庞大,如果只是对一个小项目显得的有点用牛刀杀鸡的感觉了。

        这里我们可以想到拿ScriptableObject管理数据,ScriptableObject是一种很方便存储不可变数据的数据结构。但是ScriptableObject是面向Unity的,有时候只是比赛的小组队的情况下,并不方便策划进编辑器里数据(策划不会用unity?/版本同步?)

        这时候就可以使用Excel表格了,让策划在表格中编写完数据后我们就可以一键导入成ScriptableObject,有需要再编辑是也可以导出到excel中发回给策划,或者策划直接进编辑器修改scrpitableObject也是可以的。这可以比较轻松的实现数据管理,excel也很方便策划的理解和使用,在比赛的一些中小项目中还是很实用的。

效果展示:

unity npoi,Unity,Unity框架开发,Unity工具,unity,游戏引擎,c#,excel,游戏

 功能实现:

        本文章使用了C# ExcelNPOI,这是一个开源的C#读写Excel、WORD等微软OLE2组件文档的项目,可以自行去网上下载,或者在本文结尾也会放出github网址,直接在里面下载即可。

        (这东西其实就是两个DLL,放入Plugins文件夹中里即可生效)

unity npoi,Unity,Unity框架开发,Unity工具,unity,游戏引擎,c#,excel,游戏

         这里拿我的项目中的对话系统举例,首先假设我们已经在unity中实现了一个对话系统,并使用了ScriptableObject进行数据管理,其中对话数据的代码如下:

[CreateAssetMenu(fileName = "DialogueSo")]
    public class DialogueData : ScriptableObject
    {
        public List<Sentence> data = new List<Sentence>();

        [System.Serializable]
        public class Sentence
        {
            public string character;
            [TextArea]
            public string content;
        }
    }

          这里的一个对话数据由一个句子的List构成,句子有角色名和对话内容组成,组成都为string,我们excel里也可以定义约束一下格式,在第一列中为该ScriptableObject的name,意味着一个新的对话数据开始,第二列为该角色名,第三列为具体的对话内容,其中第二第三列是不能为空的,第一列为空待变该对话仍在上一个定义的对话中,有内容代表新起了一段新对话。

        Excel里如下:

unity npoi,Unity,Unity框架开发,Unity工具,unity,游戏引擎,c#,excel,游戏

        对于的ScriptableObject如下:

unity npoi,Unity,Unity框架开发,Unity工具,unity,游戏引擎,c#,excel,游戏

         这里只是简单展示,当然也可以使用其他的规范,或者在第四第五行再添加一些额外的数据也是可以的(比如表示对话关联的其他事件,对话分支什么的)。确定了规范,就可以实现与Excel的同步了。

        在开始将同步前,先简单介绍一下一些NPOI的基本用法。

        首先需要将NPOI两个DLL放入Unity的Plugins文件夹,这个文件夹会被当做插件载入项目,就可以直接使用对应的命名空间了。

unity npoi,Unity,Unity框架开发,Unity工具,unity,游戏引擎,c#,excel,游戏

        在使用前,需要引入对应的两个命名空间,一般为NPOI.HSSF.UserModel和NPOI.SS.UserModel。需要注意NPOI的API只能在编辑器中使用,游戏最后打包是无法将逻辑带出去的(打包时会提示编译错误),所以需要加上#if UNITY_EDITOR的宏定义,或者将使用Excel的代码放入Unity的Editor文件夹。

#if UNITY_EDITOR
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
#endif

unity npoi,Unity,Unity框架开发,Unity工具,unity,游戏引擎,c#,excel,游戏

         从逻辑上讲,放入Editor文件夹更方便,因为数据同步本身就是在Unity编辑器中完成的。

        接着就是API的使用了,这里介绍一下本文章中使用的。更多详细的API可自行上网查找。

//创建一个excel文件实例,fs这里指为文件路径
var wk = new HSSFWorkbook(fs);
//将表格内容写入回路径
wk.Write(fs);
//获取excel中第index个sheet
var sheet = wk.GetSheetAt(0);
//在excel中创建一个新的sheet
var sheet = wk.CreateSheet();
//sheet的行数
sheet.LastRowNum

//读取第i行的内容,下标从0开始
var row = sheet.GetRow(i)
//读取该行中的第i个元素(可以用toString转换为字符串内容),下标从0开始
row.GetCell(i)
//创建行和行中元素
var row = sheet.CreateRow(i);
var cell = row.CreateCell(0);
cell.SetCellValue(string);

        然后我们就可以开始编写Excel脚本逻辑了。首先我们需要两个string,去表示ScriptableObject的保存文件夹路径和excel的文件路径。注意这里一个是文件夹的路径,一个是文件路径。

[FolderPath]
public string saveScriptableObjectPath; //对话数据文件夹存储路径
[FilePath]
public string excelPath;                //excel表格文件路径

       unity npoi,Unity,Unity框架开发,Unity工具,unity,游戏引擎,c#,excel,游戏

        Excel 同步分为写出加载两种操作,一种是将所有的ScriptableObject写到Excel,另一种是Excel的数据载入进Unity,写出机制逻辑比较简单,就是先读取所有对话文件,然后对着行列一个个写入即可,代码如下。

public void WriteExcel()
{
    //空值判断
    if (string.IsNullOrEmpty(excelPath))
        return;
    if (!excelPath.Contains(".xlsx"))
    {
        Debug.Log("路径不是excel文件");
        return;
    }
    //打开文件流
    FileStream fs = File.Exists(excelPath) ? File.Open(excelPath, FileMode.Open) : File.Create(excelPath);
    //新建excel和sheet
    var wk = new HSSFWorkbook();
    var sheet = wk.CreateSheet();

    int i = 1; //省略掉第0行

    //遍历所有对话文件
    foreach (var dialogue in dialogueData.datas)
    {
        var row = sheet.CreateRow(i);
        var cell = row.CreateCell(0);
        //讲ScriptableObject的name写在第一列
        cell.SetCellValue(dialogue.ID.name);
        //遍历句子内容
        for (int j = 0; j < dialogue.ID.data.Count; j++)  
        {
            if (j != 0)
                row = sheet.CreateRow(i);
            //将名字写在第二列
            row.CreateCell(1).SetCellValue(dialogue.ID.data[j].character.ToString());
            //将对话内容写在第三列
            row.CreateCell(2).SetCellValue(dialogue.ID.data[j].content);
            i++;
        }
    }


    wk.Write(fs);
    fs.Close();
    fs.Dispose();
    Debug.Log("写入成功");
}

        加载机制同理,这里有一点不用的是,加载需要动Unity中的ScriptableObject的数据,所以只有新的ID数据(name)时需要创建ScriptableObject的实例并保存,如果已经存在的ID就不用删除再创建新的文件了,否者会导致资源的meta文件被刷新,原本游戏逻辑中已经引用了这个ScriptableObject数据的地方就会丢失(当然你要使用string做数据索引这点就不用担心了)

        最后不要忘记使用AssetDatabase.SaveAssets();AssetDatabase.Refresh();刷新一下unity资源列表。


public void ReadExcel()
{
    //空值判断
    if (string.IsNullOrEmpty(excelPath))
        return;
    if (!excelPath.Contains(".xlsx"))
    {
        Debug.Log("路径不是excel文件");
        return;
    }
    //打开文件流
    FileStream fs = File.Open(excelPath, FileMode.Open);
    //打开excel和sheet
    var wk = new HSSFWorkbook(fs);
    var sheet = wk.GetSheetAt(0);
    //这是ScriptableObject的实例
    DialogueData so = null;
    //开始遍历sheet每一行的数据,注意这里i=1跳过了第一行
    for (int i = 1; i < sheet.LastRowNum; i++)
    {
        Debug.Log("读取EXCEL 行数:" + i);
        var row = sheet.GetRow(i);
        //如果当前行第一列元素不为空,证明需要保存当前so,然后创建新的so
        if (row.GetCell(0) != null && !string.IsNullOrEmpty(row.GetCell(0).ToString()))
        {
            //只有第一次so为null
            if (so) //保存路径
            {
                //是否原来已经创建了ScriptableObject资源
                if (File.Exists(saveScriptableObjectPath + "/" + so.name + ".asset"))
                {
                    dialogueData.datas.Find(x => { return x.ID.name == so.name; }).ID.data = so.data;
                }
                else
                    AssetDatabase.CreateAsset(so, saveScriptableObjectPath + "/" + so.name + ".asset");
            }
            //创建实例,开始新的对话数据记录
            so = ScriptableObject.CreateInstance<DialogueData>();
            so.name = row.GetCell(0).ToString();
        }
        //加载excel第二第三列的数据
        if (so != null)
        {
            var se = new DialogueData.Sentence();
            se.character = row.GetCell(1).ToString();
            se.content = row.GetCell(2).ToString();
            so.data.Add(se);
        }
    }
    //退出循环时记得还有一个so的数据
    if (so)
    {
        if (File.Exists(saveScriptableObjectPath + "/" + so.name + ".asset"))
        {
            File.Delete(saveScriptableObjectPath + "/" + so.name + ".meta");
            File.Delete(saveScriptableObjectPath + "/" + so.name + ".asset");
        }
        AssetDatabase.CreateAsset(so, saveScriptableObjectPath + "/" + so.name + ".asset");
    }

    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();
}

        unity npoi,Unity,Unity框架开发,Unity工具,unity,游戏引擎,c#,excel,游戏

        本文完结!最后本文章出现的代码和NPOI需要用到的两个DLL已放在github上,欢迎下载和讨论

         GitHub - sugarzo/Unity_ExcelFrame: 使用NPOI实现在unity中的ScriptableObject和Excel表格数据同步文章来源地址https://www.toymoban.com/news/detail-695364.html

到了这里,关于[Unity] 实现ScriptableObject数据同步Excel表格(对话系统数据管理,C# ExcelNPOI)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue 实现前端处理 “数组数据“ 转excel格式文件,并导出excel表格

    一、安装插件 XLSX 二、页面引入        希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~

    2024年01月18日
    浏览(43)
  • 如何使用Vue实现Excel表格数据的导入,在前端实现Excel表格文件的上传和解析,并使用Table组件将解析出来的数据展示在前端页面上

    随着互联网的发展和社会的进步,各个行业的数据量越来越大,对于数据的处理变得越来越重要。其中,Excel表格是一种重要的数据处理工具。在前后端项目中,实现Excel表格的导入和导出功能也愈加常见。这篇文章将介绍如何使用Vue实现Excel表格数据的导入。 在开始介绍实现

    2024年02月11日
    浏览(34)
  • SpringBoot整合Easyexcel实现将数据导出为Excel表格的功能

    本文主要介绍基于SpringBoot +MyBatis-Plus+Easyexcel+Vue实现缺陷跟踪系统中导出缺陷数据的功能,实现效果如下图: EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。 本文

    2024年02月14日
    浏览(35)
  • JS实现把表格数据导出,并生成为excel下载到本地

    最近开发页面用到了导出功能,之前也没有做导出为excel功能的经验,经过各方面查询尝试之后,终于成功实现,所以来总结一下 首先,你需要下载xlsx.js插件,并在HTML头部文件中需要引入,我是直接用命令行下载的:npm install xlsx --save 前端写一个按钮绑定函数: js部分实现函

    2024年02月06日
    浏览(30)
  • Excel表格和Unity

    下载EPPlus.dll 链接:https://pan.baidu.com/s/1l0FYTf8nATrPdEt6fXJ6Kg?pwd=1111 提取码:1111 将dll文件拖拽到 Assets/Plugins Assets 下新建文件夹 Editor ,右键Editor点击 Show in Explorer ,新建 Excel 表格文件(后缀.xlsx),表格文件放在Assete/Editor中。 引入命名空间 :using OfficeOpenXml ; using System.IO; Exce

    2024年02月08日
    浏览(23)
  • Excel与Unity工作流(二):基础对话框架

    本文将演示在unity中实现类似galgame的对话效果,并且通过Excel进行文本、图片、选项、赋值、音乐的配置 (该图主要是展示版面和大致目标效果,与本文关系不大) (来源:《无期迷途》) 每点击一次鼠标,就出现下一个对话/或者出现选项; 如果出现选项,点击选项,会有不同

    2024年04月14日
    浏览(36)
  • Springboot基于easyexcel实现一个excel文件包含多个sheet表格的数据导出

    EasyExcel 是一款基于Java的开源Excel操作工具,它提供了简单且强大的 API,使开发人员可以轻松地读写、操作和生成Excel文件。 EasyExcel 支持 Excel 文件的导入和导出,可以处理大量数据,具有高性能和低内存占用。它可以读取 Excel 文件中的数据,并将数据转换为 Java 对象,也可

    2024年02月03日
    浏览(45)
  • 【MySQL × SpringBoot 突发奇想】全面实现流程 · 数据库导出Excel表格文件的接口

    在上一篇博客,【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口_s:103的博客-CSDN博客 我们学习了如何导入表格,现在我们反过来,看看如何导出表格~ 网络资料: View Object(视图对象)是一种在软件开发中常见的设计模式,它用于在用户界面

    2024年02月08日
    浏览(37)
  • 【Unity】用Excel库读取Excel表格(.xlsx或者.xls)

    首先需要下载解析的库  EPPlus,  Excel,  ICSharpCode.SharpZipLib    下载链接: https://download.csdn.net/download/weixin_46472622/87238048 使用方法 我的Excel 表格是这样的,每一列有一个 我用一个结构体对象来表示 读取的方法  全部代码,以及调用: 如果是打包PC端的exe,需要将编辑

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包