zoukankan      html  css  js  c++  java
  • Unity项目中文字的统一管理

    一款游戏在研发初期就需要考虑多语言的问题,否则后期在进行多国语言版本时就面临着巨大的成本。鉴于之前页游的经验,其它同事设计出读取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图片,这个也需要提前进行约定,制定相关的规范。

  • 相关阅读:
    python3下搜狗AI API实现
    辽宁移动宽带体验及魔百盒M101s-2刷机
    年会抽奖系统-支持作弊,指定中奖
    论python3下“多态”与“继承”中坑
    fiddler抓手机报文的配置指南
    微软BI套件
    IntelliJ IDEA 2018 Community(社区版)创建J2EE项目+Tomcat9部署
    Spring.net的Demo项目,了解什么是控制反转
    manjaro安装virtualbox教程
    Debian9 安装后的配置笔记
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/7772084.html
Copyright © 2011-2022 走看看