개요

  • 간혹 Editor에서는 파일 변경을 감지할 필요가 있다. 
  • .meta 파일이 변경된 경우를 감지하기 위해 제작해보았다.
    • git에서는 .meta를 ignore 시켜놓고, 파일이 변경되면 FileSystemWatcher를 사용해서 변경 파일 목록을 제작한 뒤
    • push때 githook을 이용해서 meta를 자동 commit할 심산으로
  • meta파일까지 git에 업로드하면 file change가 엄청나서 PR이 힘들어 만들어 보았는데, 아무도 githook을 안써서 폐기 했다.
  • FileSystemWatcher는 .Net4.6 이상 환경에서만 동작하지 주의 하자
    • .Net 4.6은 Unity 2017.x 이상 부터 사용 가능
    • Unity 버전이 2017.x 이상인 경우에도 .Net 버전이 3.x로 설정되어 있어 동작하지 않는 경우가 있다.
    • ScriptRuntimeVersion.Lastest로 현재 .Net 버전 검사가 가능하니 추가해서 사용해도 될 것 같다.
  • 참고로 UNITY_2017_1_OR_NEWER 등의 전처리는 다음과 같은 의미를 지닌다.
    • 2017.x 버전 이상

코드

using System.IO;
using UnityEditor;
using UnityEngine;

public class FileBasketFileWatcher : Editor
{
    private static bool triggerRecompile = false;
    private static double nextTick;

    private static FileSystemWatcher sWatcher;

    [InitializeOnLoadMethod]
    static void UpdateWatchers()
    {
        RegisterWatcher(".meta");
        EditorApplication.update += OnEditorApplicationUpdate;
    }

    private static void RegisterWatcher(string extenstion)
    {
#if UNITY_2017_1_OR_NEWER
        if (PlayerSettings.scriptingRuntimeVersion != ScriptingRuntimeVersion.Latest)
        {
            Debug.LogWarning("FileSystemWatcher required .Net 4.6 or higher");
            return;
        }

        sWatcher = new FileSystemWatcher(Application.dataPath, "*" + extenstion);

        sWatcher.NotifyFilter = NotifyFilters.CreationTime |
            NotifyFilters.Attributes |
            NotifyFilters.DirectoryName |
            NotifyFilters.FileName |
            NotifyFilters.LastAccess |
            NotifyFilters.LastWrite |
            NotifyFilters.Security |
            NotifyFilters.Size;

        sWatcher.IncludeSubdirectories = true;

        sWatcher.Changed += OnChanged;
        sWatcher.Created += OnCreated;
        sWatcher.Deleted += OnDeleted;
        //sWatcher.Renamed += OnRenamed;

        sWatcher.EnableRaisingEvents = true;
#else
        Debug.LogWarning("FileSystemWatcher required .Net 4.6 or higher");
#endif
    }

    private static void OnChanged(object source, FileSystemEventArgs e)
    {
        triggerRecompile = true;
    }

    private static void OnCreated(object source, FileSystemEventArgs e)
    {
        triggerRecompile = true;
    }

    private static void OnDeleted(object source, FileSystemEventArgs e)
    {
        triggerRecompile = true;
    }

    private static void OnRenamed(object source, RenamedEventArgs e)
    {
        triggerRecompile = true;
    }

    private static void OnEditorApplicationUpdate()
    {
        if (EditorApplication.timeSinceStartup > nextTick)
        {
            // note that this is called very often (100/sec)
            if (triggerRecompile)
            {
                _triggerRecompile = false;
                UpdateBasket();
            }

            nextTick = EditorApplication.timeSinceStartup + 1;
        }
    }

    private static void UpdateBasket()
    {
        FileBasketEditor.UpdateBasket();
    }
}

+ Recent posts