개요
- 간혹 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 등의 전처리는 다음과 같은 의미를 지닌다.
코드
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();
}
}