I need to make a progress bar in EditorWindow. To do this, I perform the function of calculations in threads: Thread thread = new Thread (_worker.Work); thread.Start (); The class itself emitting calculations looks like this for me (Worker.cs):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Threading;
public class Worker
{
private bool _cancelled = false;
public void Cancel() {
_cancelled = true;
}
public void Work() {
for (int i = 0;i<=100;i++) {
if(_cancelled)
break;
Thread.Sleep(50);
Debug.Log("i="+i);
ProcessChanged(i);
}
WorkCompleted(_cancelled);
}
public event Action<int> ProcessChanged;
public event Action<bool> WorkCompleted;
}
The PlacementObjects: EditorWindow (PlacementObjects.cs) class looks like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using System.IO;
using System.Linq;
using System;
using System.Text.RegularExpressions;
using UnityEditor.IMGUI.Controls;
using UnityEngine.Profiling;
using Newtonsoft.Json;
using System.Threading;
public class PlacementObjects : EditorWindow
{
private Worker _worker;
bool pressedbool = false;
float scaleSlider = 0;
float scaleMinSlider = 0;
float scaleMaxSlider = 100;
[MenuItem("Window/PlacementObjects")]
static void Init()
{
_windowPlacementObj = (PlacementObjects)EditorWindow.GetWindow(typeof(PlacementObjects));
_windowPlacementObj.titleContent = new GUIContent("Работа с объектами и terrain");
}
...
void OnGUI()
{
DrawFooter();
}
void DrawFooter()
{
GUILayout.BeginArea(FooterSection);
GUILayout.BeginVertical();
if (!pressedbool)
{
GUILayout.Label("Выберите json");
GUILayout.BeginHorizontal();
stringTextFieldURLjsonfile = GUILayout.TextField(stringTextFieldURLjsonfile);
if (GUILayout.Button("Обзор...", GUILayout.Width(100)))
{
stringTextFieldURLjsonfile = EditorUtility.OpenFilePanel("Выбрать json", "", "json");
}
GUILayout.EndHorizontal();
if (GUILayout.Button("Старт"))
{
_worker = new Worker();
_worker.ProcessChanged += worker_ProcessChanged;
_worker.WorkCompleted += _worker_WorkCompleted;
pressedbool = true;
// ProcessJSONPlaceONmap();
Thread thread = new Thread(_worker.Work);
thread.Start();
}
} else {
if (GUILayout.Button("Стоп"))
{
pressedbool = false;
}
scaleSlider = EditorGUI.IntSlider(new Rect(3, 20, position.width - 6, 15), scaleSlider+"%", Mathf.RoundToInt(scaleSlider), scaleMinSlider, scaleMaxSlider);
EditorGUI.ProgressBar(new Rect(3, 45, position.width - 6, 20), scaleSlider / scaleMaxSlider, scaleSlider+"%");
Repaint();
}
GUILayout.EndVertical();
GUILayout.EndArea();
}
private void _worker_WorkCompleted(bool cancelled)
{
Action action = () =>
{
string messeg = cancelled ? "Процесс отменён" : "Процесс завершён!";
Debug.Log("messeg=" + messeg);
pressedbool = true;
};
// if (InvokeRequired)
// Invoke(action);
// else
// action();
}
private void worker_ProcessChanged(int progress)
{
Action action = () => {scaleSlider=progress;};
// if (InvokeRequired)
// Invoke(action);
// else
// action();
action();
}
}
This code does not update the progress bar.
Found an example of Asynchronous tasks / methods But here it is not clear how to call StartCoroutine (LoadingRoutine ()) from EditorWindow.