obsidian/笔记文件/2.笔记/Unity编辑器工具Task异步进度条.md
2025-03-26 00:02:56 +08:00

7.7 KiB
Raw Blame History

#unity/代码缓存

模拟进度条效果

ProgressBarExampleWindow

using UnityEditor;
using UnityEngine;
using System.Threading.Tasks;

public class ProgressBarExampleWindow : EditorWindow
{
    private float progress = 0f;
    private string statusMessage = "Ready";
    private bool isProcessing = false;

    [MenuItem("Tools/Async Progress Bar Example")]
    public static void ShowWindow()
    {
        GetWindow<ProgressBarExampleWindow>("Async Progress Bar");
    }

    private void OnGUI()
    {
        GUILayout.Label("Simulate an Async Task with Progress", EditorStyles.boldLabel);

        if (GUILayout.Button("Start Task") && !isProcessing)
        {
            StartAsyncTask();
        }

        // 显示进度条
        EditorGUI.ProgressBar(new Rect(3, 50, position.width - 6, 20), progress, statusMessage);
        GUILayout.Space(30);

        Repaint(); // 刷新窗口
    }

    private async void StartAsyncTask()
    {
        isProcessing = true;
        statusMessage = "Processing...";
        progress = 0f;

        // 模拟异步任务
        await Task.Run(async () =>
        {
            for (int i = 0; i <= 100; i++)
            {
                await Task.Delay(50); // 模拟工作负载
                progress = i / 100f; // 更新进度
                statusMessage = "Progress: " + (int)(progress * 100) + "%";
            }
        });

        statusMessage = "Task Complete!";
        isProcessing = false;
    }
}

拉取git仓库

GitCloneProgressWindow

using UnityEditor;
using UnityEngine;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

public class GitCloneProgressWindow : EditorWindow
{
    private float progress = 0f;
    private string statusMessage = "Ready";
    private bool isCloning = false;

    [MenuItem("Tools/Git Clone with Progress")]
    public static void ShowWindow()
    {
        GetWindow<GitCloneProgressWindow>("Git Clone Progress");
    }

    private void OnGUI()
    {
        GUILayout.Label("Clone Repository to C:\\git_backup", EditorStyles.boldLabel);

        if (GUILayout.Button("Start Cloning") && !isCloning)
        {
            StartCloneProcess();
        }

        // 显示进度条
        EditorGUI.ProgressBar(new Rect(3, 50, position.width - 6, 20), progress, statusMessage);
        GUILayout.Space(30);

        Repaint(); // 刷新窗口以实时更新进度
    }

    private async void StartCloneProcess()
    {
        isCloning = true;
        statusMessage = "Starting clone process...";
        progress = 0f;

        await Task.Run(() => CloneRepository());

        // 完成后重置状态
        isCloning = false;
        statusMessage = "Clone complete!";
        progress = 1f;
    }

    private void CloneRepository()
    {
        string commands = "cd C:\\ && mkdir git_backup && cd git_backup && git clone https://192.168.0.223:8843/igengine/gamecenter_data.git";

        Process process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.Arguments = "/c " + commands;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = true;
        process.EnableRaisingEvents = true;

        // 注册输出处理器以解析进度
        process.OutputDataReceived += (sender, args) => ParseGitOutput(args.Data);
        process.ErrorDataReceived += (sender, args) => ParseGitOutput(args.Data);

        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        process.WaitForExit();
    }

    private void ParseGitOutput(string data)
    {
        if (string.IsNullOrEmpty(data)) return;

        UnityEngine.Debug.Log(data); // 打印输出到控制台以供调试

        // 解析 Receiving objects 进度
        var receivingMatch = Regex.Match(data, @"Updating files:\s+(\d+)%");
        if (receivingMatch.Success)
        {
            progress = int.Parse(receivingMatch.Groups[1].Value) / 100f;
            statusMessage = "Updating files... " + receivingMatch.Groups[1].Value + "%";
            return;
        }

        // 检查是否完成克隆
        if (data.Contains("Checking out files"))
        {
            progress = 1f;
            statusMessage = "Clone complete!";
        }
    }
}

其余情况参考有可能log是包含Resolving deltasReceiving objects

GitCloneProgressWindow

using UnityEditor;
using UnityEngine;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

public class GitCloneProgressWindow : EditorWindow
{
    private float progress = 0f;
    private string statusMessage = "Ready";
    private bool isCloning = false;

    [MenuItem("Tools/Git Clone with Progress")]
    public static void ShowWindow()
    {
        GetWindow<GitCloneProgressWindow>("Git Clone Progress");
    }

    private void OnGUI()
    {
        GUILayout.Label("Clone Repository to C:\\git_backup", EditorStyles.boldLabel);

        if (GUILayout.Button("Start Cloning") && !isCloning)
        {
            StartCloneProcess();
        }

        // 显示进度条
        EditorGUI.ProgressBar(new Rect(3, 50, position.width - 6, 20), progress, statusMessage);
        GUILayout.Space(30);

        Repaint(); // 刷新窗口以实时更新进度
    }

    private async void StartCloneProcess()
    {
        isCloning = true;
        statusMessage = "Starting clone process...";
        progress = 0f;

        await Task.Run(() => CloneRepository());

        // 完成后重置状态
        isCloning = false;
        statusMessage = "Clone complete!";
        progress = 1f;
    }

    private void CloneRepository()
    {
        string commands = "cd C:\\ && mkdir git_backup && cd git_backup && git clone https://192.168.0.223:8843/igengine/cgbu_sdk.git";

        Process process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.Arguments = "/c " + commands;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = true;
        process.EnableRaisingEvents = true;

        // 注册输出处理器以解析进度
        process.OutputDataReceived += (sender, args) => ParseGitOutput(args.Data);
        process.ErrorDataReceived += (sender, args) => ParseGitOutput(args.Data);

        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        process.WaitForExit();
    }

    private void ParseGitOutput(string data)
    {
        if (string.IsNullOrEmpty(data)) return;

        UnityEngine.Debug.Log(data); // 打印输出到控制台以供调试

        // 解析 Receiving objects 进度
        var receivingMatch = Regex.Match(data, @"Receiving objects:\s+(\d+)%");
        if (receivingMatch.Success)
        {
            progress = int.Parse(receivingMatch.Groups[1].Value) / 100f;
            statusMessage = "Receiving objects... " + receivingMatch.Groups[1].Value + "%";
            return;
        }

        // 解析 Resolving deltas 进度
        var resolvingMatch = Regex.Match(data, @"Resolving deltas:\s+(\d+)%");
        if (resolvingMatch.Success)
        {
            progress = 0.7f + int.Parse(resolvingMatch.Groups[1].Value) / 100f * 0.2f;
            statusMessage = "Resolving deltas... " + resolvingMatch.Groups[1].Value + "%";
            return;
        }

        // 检查是否完成克隆
        if (data.Contains("Checking out files"))
        {
            progress = 1f;
            statusMessage = "Clone complete!";
        }
    }
}