【Unity编辑器扩展】C#监听文件改变,自动刷新配置表

游戏中使用Excel文件配置游戏数据,打包时需要将Excel文件转成txt以供游戏解析使用,尽管提供了一键转换的菜单,还是经常忘记,造成不必要的麻烦。

如果用程序监听数据表文件的改动,当文件被修改后自动更新数据表,这样开发工作流就更完善了。

监听文件改变的API:

var watcher = new FileSystemWatcher(ConstEditor.DataTableExcelPath, "*.xlsx");
        watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
        watcher.EnableRaisingEvents = true;
        fileChangedCb = new FileSystemEventHandler(OnDataTableChanged);
        fileRenameCb = new RenamedEventHandler(OnDataTableChanged);
        watcher.Changed += fileChangedCb;
        watcher.Deleted += fileChangedCb;
        watcher.Renamed += fileRenameCb;

这样会出现一个问题,经常会出现文件改变回调函数不会触发的情况。因为当编辑Excel文件时,Unity编辑器窗口处于非激活状态,在回调中更新表的逻辑就没有被执行。

可以用EditorApplication.update,当文件修改后记录修改状态,然后在update中刷新表数据:

#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System;

public static partial class DataTableUpdater
{
    static FileSystemWatcher watcher;
    static FileSystemEventHandler fileChangedCb;
    static RenamedEventHandler fileRenameCb;

    static FileSystemEventArgs curChangeEventArgs;

    static bool isInitialized = false;
    [InitializeOnLoadMethod]
    private static void Init()
    {
        if (isInitialized) return;
        EditorApplication.update += OnUpdate;
        curChangeEventArgs = null;
        watcher = new FileSystemWatcher(ConstEditor.DataTableExcelPath, "*.xlsx");
        watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
        watcher.EnableRaisingEvents = true;
        fileChangedCb = new FileSystemEventHandler(OnDataTableChanged);
        fileRenameCb = new RenamedEventHandler(OnDataTableChanged);
        watcher.Changed += fileChangedCb;
        watcher.Deleted += fileChangedCb;
        watcher.Renamed += fileRenameCb;
        isInitialized = true;
    }

    private static void OnUpdate()
    {
        if (curChangeEventArgs != null)
        {
            var fileName = Path.GetFileNameWithoutExtension(curChangeEventArgs.Name);
            if (ArrayUtility.Contains(PreloadProcedure.dataTables, fileName))
            {
                MyGameTools.RefreshAllDataTable(new string[] { fileName });
                Debug.LogFormat("Auto Refresh DataTable:{0}", curChangeEventArgs.FullPath);
            }
            else if (ArrayUtility.Contains(PreloadProcedure.configs, fileName))
            {
                MyGameTools.RefreshAllConfig(PreloadProcedure.configs);
                Debug.LogFormat("Auto Refresh Config:{0}", curChangeEventArgs.FullPath);
            }
            curChangeEventArgs = null;
        }
    }

    private static void OnDataTableChanged(object sender, FileSystemEventArgs e)
    {
        curChangeEventArgs = e;
    }
}
#endif

猜你喜欢

转载自blog.csdn.net/final5788/article/details/126724013
今日推荐