Unity辅助工具_头部与svn

发布于:2025-03-12 ⋅ 阅读:(20) ⋅ 点赞:(0)

在这里插入图片描述

Unity调用者按钮增加PlaySideButton

using QQu;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class PlaySideButton
{
    static PlaySideButton()
    {
        UnityEditorToolbar.RightToolbarGUI.Add(OnRightToolbarGUI);
        UnityEditorToolbar.LeftToolbarGUI.Add(OnLeftToolbarGUI);
    }
    private static bool mIsOpenPreview = false;
    private static void OnRightToolbarGUI()
    {
        if (GUILayout.Button("GM | 格子坐标 | 格子使用", GUILayout.MaxWidth(150), GUILayout.Height(21)))
        {
            if (Event.current.button == 0)
            {
                AudioController.GetInstance().PlayClickSound();
                UIMgr.Ins.Show<QQu.UI.GMView>().Task();
            }
            else if (Event.current.button == 2)
            {
                BuildingGridTileMgr.Ins.SetTestShowCell();
            }
            else if (Event.current.button == 1)
            {
                if(mIsOpenPreview==false)
                    SceneMapManager.Ins.PreviewCell(PreviewCellTypeEnum.CanBuilding);
                else
                    SceneMapManager.Ins.ClosePreviewCell();

                mIsOpenPreview = !mIsOpenPreview;
            }
        }
    }

    private static void OnLeftToolbarGUI()
    {
        GUILayout.FlexibleSpace(); //从右开始排
        if (GUILayout.Button("更新 | 日志 | 提交", GUILayout.MaxWidth(110), GUILayout.Height(21)))
        {
            if (Application.isPlaying)
            {
                Debug.LogError("你游戏正在运行中");
                return;
            }

            string[] strCMD = { "update", "commit", "log" }; //更新   查看日志  提交

            string path = Application.dataPath.Replace("Assets", "");
            SVNHelper.StartSvnProc(strCMD[Event.current.button], path);
        }
    }
}

unity头部扩展基类ToolbarCallback

using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif
//https://github.com/marijnz/unity-toolbar-extender

public static class ToolbarCallback
{
    static Type m_toolbarType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.Toolbar");
    static Type m_guiViewType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.GUIView");
#if UNITY_2020_1_OR_NEWER
    static Type m_iWindowBackendType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.IWindowBackend");
    static PropertyInfo m_windowBackend = m_guiViewType.GetProperty("windowBackend",
        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    static PropertyInfo m_viewVisualTree = m_iWindowBackendType.GetProperty("visualTree",
        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
#else
        static PropertyInfo m_viewVisualTree = m_guiViewType.GetProperty("visualTree",
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
#endif
    static FieldInfo m_imguiContainerOnGui = typeof(IMGUIContainer).GetField("m_OnGUIHandler",
        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    static ScriptableObject m_currentToolbar;

    /// <summary>
    /// Callback for toolbar OnGUI method.
    /// </summary>
    public static Action OnToolbarGUI;
    public static Action OnToolbarGUILeft;
    public static Action OnToolbarGUIRight;

    static ToolbarCallback()
    {
        EditorApplication.update -= OnUpdate;
        EditorApplication.update += OnUpdate;
    }

    static void OnUpdate()
    {
        // Relying on the fact that toolbar is ScriptableObject and gets deleted when layout changes
        if (m_currentToolbar == null)
        {
            // Find toolbar
            var toolbars = Resources.FindObjectsOfTypeAll(m_toolbarType);
            m_currentToolbar = toolbars.Length > 0 ? (ScriptableObject)toolbars[0] : null;
            if (m_currentToolbar != null)
            {
#if UNITY_2021_1_OR_NEWER
                var root = m_currentToolbar.GetType().GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
                var rawRoot = root.GetValue(m_currentToolbar);
                var mRoot = rawRoot as VisualElement;
                RegisterCallback("ToolbarZoneLeftAlign", OnToolbarGUILeft);
                RegisterCallback("ToolbarZoneRightAlign", OnToolbarGUIRight);

                void RegisterCallback(string root, Action cb)
                {
                    var toolbarZone = mRoot.Q(root);

                    var parent = new VisualElement()
                    {
                        style = {
                                flexGrow = 1,
                                flexDirection = FlexDirection.Row,
                            }
                    };
                    var container = new IMGUIContainer();
                    container.style.flexGrow = 1;
                    container.onGUIHandler += () =>
                    {
                        cb?.Invoke();
                    };
                    parent.Add(container);
                    toolbarZone.Add(parent);
                }
#else
#if UNITY_2020_1_OR_NEWER
var windowBackend = m_windowBackend.GetValue(m_currentToolbar);
 
// Get it's visual tree
var visualTree = (VisualElement) m_viewVisualTree.GetValue(windowBackend, null);
#else
                    // Get it's visual tree
                    var visualTree = (VisualElement)m_viewVisualTree.GetValue(m_currentToolbar, null);
#endif

                    // Get first child which 'happens' to be toolbar IMGUIContainer
                    var container = (IMGUIContainer)visualTree[0];

                    // (Re)attach handler
                    var handler = (Action)m_imguiContainerOnGui.GetValue(container);
                    handler -= OnGUI;
                    handler += OnGUI;
                    m_imguiContainerOnGui.SetValue(container, handler);

#endif
            }
        }
    }

    static void OnGUI()
    {
        var handler = OnToolbarGUI;
        if (handler != null) handler();
    }
}

[InitializeOnLoad]
public static class UnityEditorToolbar
{
    static int m_toolCount;
    static GUIStyle m_commandStyle = null;

    public static readonly List<Action> LeftToolbarGUI = new List<Action>();
    public static readonly List<Action> RightToolbarGUI = new List<Action>();

    static UnityEditorToolbar()
    {
        Type toolbarType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.Toolbar");

#if UNITY_2019_1_OR_NEWER
        string fieldName = "k_ToolCount";
#else
string fieldName = "s_ShownToolIcons";
#endif

        FieldInfo toolIcons = toolbarType.GetField(fieldName,
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

#if UNITY_2019_3_OR_NEWER
        m_toolCount = toolIcons != null ? ((int)toolIcons.GetValue(null)) : 8;
#elif UNITY_2019_1_OR_NEWER
m_toolCount = toolIcons != null ? ((int) toolIcons.GetValue(null)) : 7;
#elif UNITY_2018_1_OR_NEWER
m_toolCount = toolIcons != null ? ((Array) toolIcons.GetValue(null)).Length : 6;
#else
m_toolCount = toolIcons != null ? ((Array) toolIcons.GetValue(null)).Length : 5;
#endif

        ToolbarCallback.OnToolbarGUI = OnGUI;
        ToolbarCallback.OnToolbarGUILeft = GUILeft;
        ToolbarCallback.OnToolbarGUIRight = GUIRight;
    }

#if UNITY_2019_3_OR_NEWER
    public const float space = 8;
#else
public const float space = 10;
#endif
    public const float largeSpace = 20;
    public const float buttonWidth = 32;
    public const float dropdownWidth = 80;
#if UNITY_2019_1_OR_NEWER
    public const float playPauseStopWidth = 140;
#else
public const float playPauseStopWidth = 100;
#endif

    static void OnGUI()
    {
        // Create two containers, left and right
        // Screen is whole toolbar

        if (m_commandStyle == null)
        {
            m_commandStyle = new GUIStyle("CommandLeft");
        }

        var screenWidth = EditorGUIUtility.currentViewWidth;

        // Following calculations match code reflected from Toolbar.OldOnGUI()
        float playButtonsPosition = Mathf.RoundToInt((screenWidth - playPauseStopWidth) / 2);

        Rect leftRect = new Rect(0, 0, screenWidth, Screen.height);
        leftRect.xMin += space; // Spacing left
        leftRect.xMin += buttonWidth * m_toolCount; // Tool buttons
#if UNITY_2019_3_OR_NEWER
        leftRect.xMin += space; // Spacing between tools and pivot
#else
leftRect.xMin += largeSpace; // Spacing between tools and pivot
#endif
        leftRect.xMin += 64 * 2; // Pivot buttons
        leftRect.xMax = playButtonsPosition;

        Rect rightRect = new Rect(0, 0, screenWidth, Screen.height);
        rightRect.xMin = playButtonsPosition;
        rightRect.xMin += m_commandStyle.fixedWidth * 3; // Play buttons
        rightRect.xMax = screenWidth;
        rightRect.xMax -= space; // Spacing right
        rightRect.xMax -= dropdownWidth; // Layout
        rightRect.xMax -= space; // Spacing between layout and layers
        rightRect.xMax -= dropdownWidth; // Layers
#if UNITY_2019_3_OR_NEWER
        rightRect.xMax -= space; // Spacing between layers and account
#else
rightRect.xMax -= largeSpace; // Spacing between layers and account
#endif
        rightRect.xMax -= dropdownWidth; // Account
        rightRect.xMax -= space; // Spacing between account and cloud
        rightRect.xMax -= buttonWidth; // Cloud
        rightRect.xMax -= space; // Spacing between cloud and collab
        rightRect.xMax -= 78; // Colab

        // Add spacing around existing controls
        leftRect.xMin += space;
        leftRect.xMax -= space;
        rightRect.xMin += space;
        rightRect.xMax -= space;

        // Add top and bottom margins
#if UNITY_2019_3_OR_NEWER
        leftRect.y = 4;
        leftRect.height = 22;
        rightRect.y = 4;
        rightRect.height = 22;
#else
leftRect.y = 5;
leftRect.height = 24;
rightRect.y = 5;
rightRect.height = 24;
#endif

        if (leftRect.width > 0)
        {
            GUILayout.BeginArea(leftRect);
            GUILayout.BeginHorizontal();
            foreach (var handler in LeftToolbarGUI)
            {
                handler();
            }

            GUILayout.EndHorizontal();
            GUILayout.EndArea();
        }

        if (rightRect.width > 0)
        {
            GUILayout.BeginArea(rightRect);
            GUILayout.BeginHorizontal();
            foreach (var handler in RightToolbarGUI)
            {
                handler();
            }

            GUILayout.EndHorizontal();
            GUILayout.EndArea();
        }
    }

    public static void GUILeft()
    {
        GUILayout.BeginHorizontal();
        foreach (var handler in LeftToolbarGUI)
        {
            handler();
        }
        GUILayout.EndHorizontal();
    }

    public static void GUIRight()
    {
        GUILayout.BeginHorizontal();
        foreach (var handler in RightToolbarGUI)
        {
            handler();
        }
        GUILayout.EndHorizontal();
    }
}

在这里插入图片描述

svn工具辅助类 SVNHelper

using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using UnityEditor;
using UnityEngine;
public static class SVNHelper
{
    //Log
    [MenuItem("Assets/SVN/日志",false,1)]
    private static void RightClickLog()
    {
        var path = MySelectActiveObj();
        if (string.IsNullOrEmpty(path) == false)
        {
            StartSvnProc("log", path);
        }
    }
    //更新
    [MenuItem("Assets/SVN/更新", false, 1)]
    private static void RightClickUpdate()
    {
        var path = MySelectActiveObj();
        if (string.IsNullOrEmpty(path) == false)
        {
            StartSvnProc("update", path);
        }
    }
    //提交
    [MenuItem("Assets/SVN/提交", false, 1)]
    private static void RightClickCommit()
    {
        var path= MySelectActiveObj();
        if (string.IsNullOrEmpty(path)==false)
        {
            StartSvnProc("commit", path);
        }
    }
    // 获取选中的对象
    private static string MySelectActiveObj()
    {       
        var selectedObjects = Selection.objects;
        if (selectedObjects.Length > 0)
        {
            foreach (var obj in selectedObjects)
            {
                // 检查选定对象是否是文件夹
                string path = AssetDatabase.GetAssetPath(obj);
                if (AssetDatabase.IsValidFolder(path))
                {
                    string target = Application.dataPath.Replace("Assets", "")+path;
                    return target;
                }
            }
        }
        return null;
    }
    public static int StartSvnProc(string cmd, string path, string url = "", bool closeOnEnd = false,
        string logMsg = "")
    {
        ProcessStartInfo startInfo = new ProcessStartInfo();
#if UNITY_EDITOR_WIN
        var tortoiseProcPath = GetTortoiseProcSvnPath();
        if (string.IsNullOrEmpty(tortoiseProcPath))
        {
            UnityEngine.Debug.LogError("TortoiseProc未找到");
            return 0;
        }
        startInfo.FileName = tortoiseProcPath;

        if (cmd.Equals("commit") && !string.IsNullOrEmpty(logMsg))
        {
            if (string.IsNullOrEmpty(url))
                startInfo.Arguments =
                    $"/command:{cmd} /path:\"{path}\" /logmsg:{logMsg} /closeonend:{(closeOnEnd ? 2 : 0)}";
            else
                startInfo.Arguments =
                    $"/command:{cmd} /path:\"{path}\" /url:\"{url}\" /logmsg:{logMsg} /closeonend:{(closeOnEnd ? 2 : 0)}";
        }
        else
        {
            if (string.IsNullOrEmpty(url))
                startInfo.Arguments = $"/command:{cmd} /path:\"{path}\" /closeonend:{(closeOnEnd ? 2 : 0)}";
            else
                startInfo.Arguments =
                    $"/command:{cmd} /path:\"{path}\" /url:\"{url}\" /closeonend:{(closeOnEnd ? 2 : 0)}";
        }

        startInfo.RedirectStandardOutput = true;
        startInfo.UseShellExecute = false;

#elif UNITY_EDITOR_OSX
        startInfo.CreateNoWindow = true;
        startInfo.ErrorDialog = true;
        startInfo.UseShellExecute = false;
        startInfo.FileName = "/usr/local/bin/svn";
        startInfo.Arguments = $"{cmd} {url} {path}";
        startInfo.RedirectStandardOutput = true;
        UnityEngine.Debug.Log("start process = " + startInfo.Arguments);
#endif
        Process svnUpProcess = new Process();
        svnUpProcess.StartInfo = startInfo;
        svnUpProcess.Start();
        svnUpProcess.WaitForExit();
        string output = svnUpProcess.StandardOutput.ReadToEnd();
        UnityEngine.Debug.Log("process output = " + output);

        var exitCode = svnUpProcess.ExitCode;
        svnUpProcess.Close();
        AssetDatabase.Refresh();
        return exitCode;
    }
    private static string GetTortoiseProcSvnPath()
    {
        try
        {
            RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
            var path = key.OpenSubKey("SOFTWARE").OpenSubKey("TortoiseSVN").GetValue("ProcPath").ToString();
            return path;
        }
        catch (Exception)
        {
            string[] vols = { "C", "D", "E", "F", "G", "H" };
            string[] dirs =
            {
                @"Program Files",
                @"Program Files (x86)",
            };

            foreach (var vol in vols)
                foreach (var dir in dirs)
                {
                    string file = $"{vol}:\\{dir}\\TortoiseSVN\\bin\\TortoiseProc.exe";
                    if (File.Exists(file))
                        return file;
                }

            return null;
        }
    }
}

git工具辅助类 GitHelper

using Microsoft.Win32;
using System;
using System.Diagnostics;
using UnityEditor;
public class GitHelper
{
    public static bool StartGitProc(string cmd, string path, string outPath = "")
    {
        string gitProcPath = GetTortoiseGitProcPath();
        if (string.IsNullOrEmpty(gitProcPath))
        {
            UnityEngine.Debug.LogError("TortoiseGitProc未找到");
            return false;
        }

        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.FileName = gitProcPath;
        startInfo.Arguments = $"/command:{cmd} /path:\"{path}\"/closeonend:2";

        Process gitProcess = new Process();
        gitProcess.StartInfo = startInfo;
        gitProcess.Start();
        gitProcess.WaitForExit();

        if (gitProcess.ExitCode > 0)
        {
            EditorUtility.DisplayDialog("提示", $"git {cmd} exit with code:{gitProcess.ExitCode}", "确定");

            return false;
        }

        return true;
    }
    public static string GetTortoiseGitProcPath()
    {
        try
        {
            RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);
            var path = key.OpenSubKey("SOFTWARE").OpenSubKey("TortoiseGit").GetValue("ProcPath").ToString();
            return path;
        }
        catch (Exception)
        {
            return null;
        }
    }
}