Unity项目中文字的统一管理

简介: 一款游戏在研发初期就需要考虑多语言的问题,否则后期在进行多国语言版本时就面临着巨大的成本。鉴于之前页游的经验,其它同事设计出读取Excel的方式来管理所有的文字。但是我在使用中发现很致使的一个问题,当多人编辑一个Excel时,冲突了就很麻烦,解决起来的成本还蛮高的。

一款游戏在研发初期就需要考虑多语言的问题,否则后期在进行多国语言版本时就面临着巨大的成本。鉴于之前页游的经验,其它同事设计出读取Excel的方式来管理所有的文字。但是我在使用中发现很致使的一个问题,当多人编辑一个Excel时,冲突了就很麻烦,解决起来的成本还蛮高的。

 

之后我想了一些办法,例如搭建一个web站点,将所有的字符串 Key、Value保存到数据库中,避免冲突,方便去查询。但感觉还是太过麻烦,成本略高。然后就想到一个办法,既然读取一个Excel容易冲突,那我就弄多个文件,一个人编辑一个Excel,这样总不会冲突了吧。然后添加 Key 的时候,先查找 Key是否存在,如果存在就提醒添加者。

 

这样问题就变成从读取单个文件变成遍历一个文件夹下的文件。因为Excel在打开时,会生成一个临时文件并被占用,所以不可以对它进行操作(如复制)。

using System;
using UnityEditor;
using UnityEditor.UI;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using OfficeOpenXml;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace xxxx
{
    [InitializeOnLoad]
    public class StringsWatcher
    {
        static string stringsPath;
        static DateTime lastModifyTime;
        static string stringsFolderPath;

        static StringsWatcher()
        {
            stringsFolderPath = Path.GetDirectoryName(Application.dataPath);
            stringsFolderPath = Path.Combine(stringsFolderPath, "strings");

            // 创建Strings文件夹
            if (!Directory.Exists(stringsFolderPath))
            {
                Directory.CreateDirectory(stringsFolderPath);
            }

            // stringsPath = Path.GetFullPath(Path.Combine(rootPath, "Strings.xlsx"));

            EditorApplication.update += Update;
        }

        static void Update()
        {
            if (EditorApplication.isPlaying || EditorApplication.isCompiling) return;

            //if (!File.Exists(stringsPath)) return;
            if (!Directory.Exists(stringsFolderPath)) return;

            DateTime time = Directory.GetLastWriteTime(stringsFolderPath);

            if (lastModifyTime == time) return;

            lastModifyTime = time;

            Debug.Log("Reloading " + stringsFolderPath + ", Time : " + time.ToString());

            DateTime startTime = DateTime.Now;

            // ExcelPackage package = new ExcelPackage(new FileInfo(tempFile));

            List<string> keys = new List<string>();
            List<string> values = new List<string>();

            // 遍历 strings 目录下的excel文件
            DirectoryInfo folder = new DirectoryInfo(stringsFolderPath);
            foreach (FileInfo fileItem in folder.GetFiles())
            {
                string strFileType = fileItem.Extension;

                // 如果是 excel 文件且不是临时文件, 临时文件以~$开关,读取临时文件会报错误:Invaliddataexception the file is not an valid package file
                if (new Regex(@"^[^~]+\.xlsx$").IsMatch(fileItem.Name.ToLower()))
                {
                    string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                    File.Copy(fileItem.FullName, tempFile);

                    //Debug.Log(fileItem.Name + ", " + tempFile);

                    ExcelPackage package = new ExcelPackage(new FileInfo(tempFile));
                    ExcelWorksheet sheet = package.Workbook.Worksheets[1];

                    int rows = sheet.Dimension.Rows;
                    for (int row = 2; row <= rows; row++)
                    {
                        object keyObj = sheet.Cells[row, 1].Value;
                        object valueObj = sheet.Cells[row, 2].Value;

                        // Valid key and value is null or not.
                        if (keyObj == null)
                        {
                            Debug.LogError("Find Key is null. fileName : " + fileItem.Name + ", rowIndex : " + row);
                            return;
                        }

                        if (valueObj == null)
                        {
                            Debug.LogError("Find Key is null. fileName : " + fileItem.Name + ", rowIndex : " + row);
                            return;
                        }

                        // Find key is Exist or not                        
                        if (keys.Find(x => x == keyObj.ToString()) != null)
                        {
                            Debug.LogError("Find Report Key. fileName : " + fileItem.Name + ", rowIndex : " + row);
                            return;
                        }
                        
                        string key = keyObj.ToString();
                        string value = valueObj.ToString();

                        keys.Add(key);
                        values.Add(value);
                    }

                    // 每删除一个文件大约多0.1秒
                    File.Delete(tempFile);
                }
                
                // 更新内存的数据,重新保存assets
                AssetDatabase.SaveAssets();
            }

            DateTime endTime = DateTime.Now;
            Debug.Log("Rebuild string.assets time : " + (endTime - startTime).TotalSeconds + "s");
        }
    }
}

 

如果你读取Excel时遇到了 Invaliddataexception the file is not an valid package file ,上面的代码或许对你有所帮助。

 

除了文字外,游戏项目中还需要管理的就是带有文字的UI图片,这个也需要提前进行约定,制定相关的规范。

目录
相关文章
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版3(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版3(附带项目源码)
54 2
|
1月前
|
存储 设计模式 监控
运用Unity Profiler定位内存泄漏并实施对象池管理优化内存使用
【7月更文第10天】在Unity游戏开发中,内存管理是至关重要的一个环节。内存泄漏不仅会导致游戏运行缓慢、卡顿,严重时甚至会引发崩溃。Unity Profiler作为一个强大的性能分析工具,能够帮助开发者深入理解应用程序的内存使用情况,从而定位并解决内存泄漏问题。同时,通过实施对象池管理策略,可以显著优化内存使用,提高游戏性能。本文将结合代码示例,详细介绍如何利用Unity Profiler定位内存泄漏,并实施对象池来优化内存使用。
56 0
|
2月前
|
图形学
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
73 0
|
6天前
|
API 开发工具 vr&ar
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
|
6天前
|
前端开发 图形学
小功能⭐️3DCanvas交互方法、Unity自动调整文本框大小、改变文字大小和颜色
小功能⭐️3DCanvas交互方法、Unity自动调整文本框大小、改变文字大小和颜色
|
2月前
|
图形学
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(上)
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)
105 2
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版2(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版2(附带项目源码)
34 1
|
2月前
|
图形学
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(下)
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(下)
41 0
|
2月前
|
存储 JSON 关系型数据库
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版13(完结,附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版13(完结,附带项目源码)
47 0
|
2月前
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版12(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版12(附带项目源码)
36 0