Как сделать progress bar в EditorWindow с Threading в Unity?

198
06 октября 2021, 19:40

Мне надо сделать progress bar в EditorWindow. Для этого я выполняю функцию расчётов в потоках: Thread thread = new Thread(_worker.Work); thread.Start(); Сам класс эмитирующий расчёты у меня выглядит так (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;
}

Класс PlacementObjects : EditorWindow(PlacementObjects.cs) выглядит так :

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 = EditorGUILayout.Slider(scaleSlider, scaleMinSlider, scaleMaxSlider);
                GUILayout.Label(scaleSlider.ToString());
            }
        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();
}
}

Чем заменить (System.Windows.Forms):

if (InvokeRequired)
    Invoke(action);
else
    action();

в Unity ?

Сейчас мой код отрабатывает не корректно. Не каждую итерацию обновляется значение в progress bar

Добавил Repaint(); прогресс бар(EditorGUI.ProgressBar) не обновляется . В слайдере значения стали обновляться:

                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("Старт"))
                    {
                        _FillForest = new UnityEditor.Experimental.TerrainAPI.FillForest();
                        _FillForest.ProcessChanged += worker_ProcessChanged;
                        _FillForest.WorkCompleted += _worker_WorkCompleted;
                        pressedbool = true;
                        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();
                }
READ ALSO
Расшифровка ID в Access

Расшифровка ID в Access

имеется БД в которой находятся таблицы "Сотрудники" и "Отделы", в таблице "Сотрудники" в поле "Отдел" имеется ID отдела тип данных(Числовой), а в таблице...

258
Как отправить файл в ASP.NET Core MVC через модель?

Как отправить файл в ASP.NET Core MVC через модель?

У меня появилась необходимость загружать файл вместе с дополнительными даннымиОбычно я отправлял данные в контроллер так:

145
WPF effect - проблемы с перерисовкой окна

WPF effect - проблемы с перерисовкой окна

В проекте использую C# и WPF, NetFramework 4

173