概要
- macOS BigSur 11.4
- Unity 2021.1.28f1
- UniTask 2.2.4
Unityでもコマンド実行した結果を使いたいな〜ってときに使えるやつです
使用クラス
具体例: Gitのコミットハッシュを取得してTextに表示する
特に解説することはなかったので早速コードをドン
CommitHashLabel.cs
public class CommitHashLabel : MonoBehaviour
{
[SerializeField] private Text text;
private void Start() => InitCommitHashAsync().Forget();
private async UniTaskVoid InitCommitHashAsync()
{
try
{
var hash = await GetCommitHashAsync();
text.text = hash;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private async UniTask<string> GetCommitHashAsync()
{
var processStartInfo = new ProcessStartInfo
{
FileName = "git",
Arguments = "rev-parse --short HEAD",
CreateNoWindow = false,
StandardOutputEncoding = Encoding.UTF8,
RedirectStandardOutput = true,
UseShellExecute = false
};
var process = Process.Start(processStartInfo);
if (process == null)
{
throw new ArgumentException("Process cannot start.");
}
await UniTask.SwitchToThreadPool();
process.WaitForExit();
await UniTask.SwitchToMainThread();
return (await process.StandardOutput.ReadToEndAsync().AsUniTask()).Trim();
}
}
これで実行時に勝手にコミットハッシュを表示してくれます
Start
に書いていますがAwake
でやっても大丈夫だと思います
Editor上でしか動作しないので使用の際には注意!
補足
ProcessStartInfo
ProcessStartInfo.WorkingDirectory
実行場所の指定
指定がないとEnvironment.CurrentDirectory
が指定されます
Unityのプロジェクトをgitで管理しているのであれば指定がなくても問題なく使用できると思います
Process
Process.WaitForExit
これをメインスレッドで実行してしまうと処理が止まってしまうのでスレッドプールに移動してから呼ぶことで非同期っぽくしています
Unityで.NET6が使えるようになったら WaitForExitAsyncとかいうゴキゲンなメソッドも使えるようになるみたいです
汎用的に使えるようにする
ProcessStartInfoの作成とProcessの実行を行うクラスを作成します
UniTaskProcessExecutor.cs
public class UniTaskProcessExecutor
{
private readonly ProcessStartInfo processStartInfo;
public UniTaskProcessExecutor(string filename, string arguments)
{
processStartInfo = new ProcessStartInfo
{
FileName = filename,
Arguments = arguments,
CreateNoWindow = false,
StandardOutputEncoding = Encoding.UTF8,
RedirectStandardOutput = true,
UseShellExecute = false
};
}
public async UniTask<string> ExecuteAsync()
{
var process = Process.Start(processStartInfo);
if (process == null)
{
throw new ArgumentException("Process cannot start.");
}
await UniTask.SwitchToThreadPool();
process.WaitForExit();
await UniTask.SwitchToMainThread();
return (await process.StandardOutput.ReadToEndAsync().AsUniTask()).Trim();
}
}
CommitHashLabel.cs
public class CommitHashLabel : MonoBehaviour
{
[SerializeField] private Text text;
private void Start() => InitCommitHashAsync().Forget();
private async UniTaskVoid InitCommitHashAsync()
{
try
{
var process = new UniTaskProcessExecutor("git", "rev-parse --short HEAD");
var hash = await process.ExecuteAsync();
text.text = hash;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
クラス名にUniTaskをつけてしまうと検索性が著しく落ちるので別の名前をつけたほうがいいです