LoginSignup
1
1

More than 1 year has passed since last update.

UniTaskで簡単なProcessをサクッと実行して結果を文字列で得る

Last updated at Posted at 2021-12-09

概要

  • 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をつけてしまうと検索性が著しく落ちるので別の名前をつけたほうがいいです

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1