• C# Unity游戏开发——Excel中的数据是如何到游戏中的 (一)


    引言

    现在做游戏开发的没有几个不用Excel的,用的最多的就是策划。尤其是数值策划,Excel为用户提供强大的工具,各种快捷键,各种插件,各种函数。但是作为程序来说其实关注的不是Excel而是它最终形成的数据,而在程序中数据其实就是二进制,比如说一个int型就是4个byte,一个字母占2个byte。但是游戏中不可能把excel文件放进去(因为Excel本身就会占一部分额外的空间),也不可能把处理Excel的类库打包到程序,所以现在大多是对Excel进行读取然后将数据进行序列化并写入文件再打包,程序运行的时候直接读取数据文件在进行反序列化。

    这样做有几个好处:1.节省了空间。2.把和游戏无关的操作放在了游戏之外。3.游戏开发过程中用起来也比较方便,因为反序列换后的数据就是自己定义的某个类型的一个变量。3.减少了前后端通讯传输的数据量。4.方便对数据进行加密。

    其实这个过程的核心部分都是一次性的操作,只要实现一遍以后就可以重复使用。

    流程


    实现的流程大致可以分为三个部分:1.读取Excel文件。2.将读取的数据进行序列化并写入文件。3.反序列化。#4.加密

    读取Excel

    本来读取Excel是一件非常简单的事情,但是开始做才发现,对于C#来说Excel操作的类库很多,所以用哪个类库就成了一个问题,其实这些操作都是在游戏之外进行的类库的性能可以忽略,但是一般人肯定都喜欢用性能好一点的。

    另外一个问题就相对比较重要了,很多Excel类库都是基于windows开发环境的,而且还需要安装office,换到其他平台就不支持,而且Unity是换平台游戏引擎,所以基于这几点,我最后选择了一个跨平台操作Excel的开源类库ExcelReader

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using Excel;
    using System.Data;
    
    public class ExportExcel {
    
        [MenuItem("Frame/ExportExcel")]
        public static void ExportExcelToBinary()
        {
    
            Dictionary<string, List<List<Property>>> DataMap = new Dictionary<string, List<List<Property>>>();
            List<List<Property>> classes;
            List<Property> properties;
    
            FileInfo info;
            FileStream stream;
            IExcelDataReader excelReader;
            DataSet result;
    
            string[] files = Directory.GetFiles(Application.dataPath + "/EasyUI/ExcelFiles", "*.xlsx", SearchOption.TopDirectoryOnly);
    
            int row = 0, col = 0;
    
            try
            {
                foreach (string path in files)
                {
                    info = new FileInfo(path);
                    stream = info.Open(FileMode.Open, FileAccess.Read);
                    excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
                    result = excelReader.AsDataSet();
    
                    classes = new List<List<Property>>();
    
                    int rowCount = result.Tables[0].Rows.Count;
                    int colCount = result.Tables[0].Columns.Count;
    
                    for (row = 1; row < rowCount; row++)
                    {
                        properties = new List<Property>();
    
                        for (col = 0; col < colCount; col++)
                        {
                            //string name = result.Tables[0].Rows[0][j].ToString();
                            //string value = result.Tables[0].Rows[i][j].ToString();
                            //string type = result.Tables[1].Rows[1][col].ToString();
                            //Debug.Log(result.Tables[0].Rows[0][col].ToString()+":"+result.Tables[0].Rows[row][col].ToString());
                            properties.Add(
                                new Property(
                                    result.Tables[0].Rows[0][col].ToString(),
                                    result.Tables[0].Rows[row][col].ToString(),
                                    result.Tables[1].Rows[1][col].ToString()
                                ));
                            Debug.Log(result.Tables[1].Rows[1][col].ToString());
                        }
    
                        classes.Add(properties);
                    }
    
                    DataMap.Add(info.Name, classes);
                    excelReader.Close();
                    stream.Close();
                }
            }
            catch(IndexOutOfRangeException exp)
            {
                Debug.LogError("数组下标超出范围!");
            }
    
        }
    }

    先把数据读到这里面Dictionary<string, List<List<Property>>> DataMap;后面会讲怎么利用meta data来做映射,怎么序列化。

    还有就是Excel文件是有格式要求的哦,文件名就是类名,第一个sheet是数据从第二行开始读。第二个sheet的第一行是字段名称,第二行是字段类型,第三行的第一列是预留的类名。如下图

    还有一个Property类是为了以后映射和序列化使用的

    using System;
    public class Property {
    
        public string name;
    
        public string value;
    
        public string type;
        public Property(string name,string value,string type)
        {
            this.name = name;
            this.value = value;
            this.type = type;
        }
        public Type GetType()
        {
            return null;
            //todo..
        }
    }
    View Code

    看了很多帖子,比较有用的先给大家贴出来。http://www.mamicode.com/info-detail-494944.html , http://www.xuanyusong.com/archives/2429/ , http://www.cnblogs.com/shanyou/archive/2009/11/21/1607548.html

    ,加密:http://wenku.baidu.com/view/031ede00964bcf84b9d57b6e.html

     本文固定链接:http://www.cnblogs.com/fly-100/p/4538975.html

  • 相关阅读:
    Redis 分区
    Redis 管道技术
    8完善博客 8-1 博客主页面开发
    7章 Admin
    6章 Models
    开发第一个Template
    云服务器装teamviewer
    Centos搭建图形界面VNC
    创建应用,并了解应用目录下各文件的作用,同时创建第一个文件响应
    setings.py配置文件详解
  • 原文地址:https://www.cnblogs.com/fly-100/p/4538975.html
Copyright © 2020-2023  润新知