うにてぃブログ

UnityやUnreal Engineの記事を書いていきます

【Unity】UnityEditor でプログレスバーを表示する

Unity でプログレスバーを操作するものは以下のものがある

  • EditorUtility.DisplayProgressBar
  • EditorUtility.DisplayCancelableProgressBar
  • EditorUtility.ClearProgressBar

表示に使うのは DisplayProgressBarDisplayCancelableProgressBar

EditorUtility.DisplayProgressBar

f:id:hacchi_man:20200115135040p:plain

using System;
using UnityEditor;
using UnityEngine;

public class ProgressShowWindow : EditorWindow 
{
    [MenuItem("Tools/ProgressShow")]
    private static void ShowWindow()
    {
        GetWindow<ProgressShowWindow>().Show();
    }

    private int _count;
    private const int MAX = 1000;
    
    private void OnGUI()
    {
        if (GUILayout.Button("ShowProgress"))
        {
            _count = 0;
            EditorApplication.update += ShowProgress;
            EditorUtility.ClearProgressBar();
        }
    }

    private void ShowProgress()
    {
        _count++;
        if (_count >= MAX)
        {
            EditorUtility.ClearProgressBar();
            EditorApplication.update -= ShowProgress;
            return;
        }

        EditorUtility.DisplayProgressBar("Title", $"progress {_count} / {MAX}", _count / (float) MAX);
    }
}

EditorUtility.DisplayCancelableProgressBar

DisplayCancelableProgressBar の場合は 途中で処理を止めれるように☓ボタンが表示される

上記とほとんど処理は変わらないので 変更のある ShowProgress のみ貼り付けておく

f:id:hacchi_man:20200115140439p:plain

   private void ShowProgress()
    {
        _count++;
        if (_count >= MAX)
        {
            EditorUtility.ClearProgressBar();
            EditorApplication.update -= ShowProgress;
            return;
        }

        if (EditorUtility.DisplayCancelableProgressBar("Title", $"progress {_count} / {MAX}", _count / (float) MAX))
        {
            _count = MAX;
        }
    }

ProgressBar の 注意点

例えば 1000 ループする場合 ShowProgress の内部でプログレスバーを表示する処理を除いた場合 2.0055450 秒だった
が処理の途中で EditorUtility.DisplayProgressBar を呼んだ場合 16.6299620 秒もかかってしまう
プログレスを表示した状態で アクティブなアプリがUnity以外になった場合は 97.3534140 秒

つまり 1回プログレスバーを表示するだけで .014629962 秒 も時間がかかってしまう
そのためプログレスの最大値が多い場合は 100回に1回表示するなど、表示回数を制限する必要があります

   private void ShowProgress()
    {
        _count++;
        if (_count >= MAX)
        {
            Debug.Log(DateTime.Now - _beginTime);
            EditorUtility.ClearProgressBar();
            EditorApplication.update -= ShowProgress;
            return;
        }

        if (_count % 100 == 0)
        {
            EditorUtility.DisplayProgressBar("Title", $"progress {_count} / {MAX}", _count / (float) MAX);
        }
    }

参考サイト

EditorUtility-DisplayProgressBar - Unity スクリプトリファレンス
EditorUtility-ClearProgressBar - Unity スクリプトリファレンス
EditorUtility-DisplayCancelableProgressBar - Unity スクリプトリファレンス