Unity辅助工具_头部与svn

news/2025/3/14 6:01:47/

在这里插入图片描述

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);elseSceneMapManager.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-extenderpublic 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_NEWERstatic 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);
#elsestatic PropertyInfo m_viewVisualTree = m_guiViewType.GetProperty("visualTree",BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
#endifstatic 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 changesif (m_currentToolbar == null){// Find toolbarvar toolbars = Resources.FindObjectsOfTypeAll(m_toolbarType);m_currentToolbar = toolbars.Length > 0 ? (ScriptableObject)toolbars[0] : null;if (m_currentToolbar != null){
#if UNITY_2021_1_OR_NEWERvar 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 treevar visualTree = (VisualElement)m_viewVisualTree.GetValue(m_currentToolbar, null);
#endif// Get first child which 'happens' to be toolbar IMGUIContainervar container = (IMGUIContainer)visualTree[0];// (Re)attach handlervar 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_NEWERstring fieldName = "k_ToolCount";
#else
string fieldName = "s_ShownToolIcons";
#endifFieldInfo toolIcons = toolbarType.GetField(fieldName,BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);#if UNITY_2019_3_OR_NEWERm_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;
#endifToolbarCallback.OnToolbarGUI = OnGUI;ToolbarCallback.OnToolbarGUILeft = GUILeft;ToolbarCallback.OnToolbarGUIRight = GUIRight;}#if UNITY_2019_3_OR_NEWERpublic const float space = 8;
#else
public const float space = 10;
#endifpublic const float largeSpace = 20;public const float buttonWidth = 32;public const float dropdownWidth = 80;
#if UNITY_2019_1_OR_NEWERpublic const float playPauseStopWidth = 140;
#else
public const float playPauseStopWidth = 100;
#endifstatic void OnGUI(){// Create two containers, left and right// Screen is whole toolbarif (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 leftleftRect.xMin += buttonWidth * m_toolCount; // Tool buttons
#if UNITY_2019_3_OR_NEWERleftRect.xMin += space; // Spacing between tools and pivot
#else
leftRect.xMin += largeSpace; // Spacing between tools and pivot
#endifleftRect.xMin += 64 * 2; // Pivot buttonsleftRect.xMax = playButtonsPosition;Rect rightRect = new Rect(0, 0, screenWidth, Screen.height);rightRect.xMin = playButtonsPosition;rightRect.xMin += m_commandStyle.fixedWidth * 3; // Play buttonsrightRect.xMax = screenWidth;rightRect.xMax -= space; // Spacing rightrightRect.xMax -= dropdownWidth; // LayoutrightRect.xMax -= space; // Spacing between layout and layersrightRect.xMax -= dropdownWidth; // Layers
#if UNITY_2019_3_OR_NEWERrightRect.xMax -= space; // Spacing between layers and account
#else
rightRect.xMax -= largeSpace; // Spacing between layers and account
#endifrightRect.xMax -= dropdownWidth; // AccountrightRect.xMax -= space; // Spacing between account and cloudrightRect.xMax -= buttonWidth; // CloudrightRect.xMax -= space; // Spacing between cloud and collabrightRect.xMax -= 78; // Colab// Add spacing around existing controlsleftRect.xMin += space;leftRect.xMax -= space;rightRect.xMin += space;rightRect.xMax -= space;// Add top and bottom margins
#if UNITY_2019_3_OR_NEWERleftRect.y = 4;leftRect.height = 22;rightRect.y = 4;rightRect.height = 22;
#else
leftRect.y = 5;
leftRect.height = 24;
rightRect.y = 5;
rightRect.height = 24;
#endifif (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_WINvar 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)}";elsestartInfo.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)}";elsestartInfo.Arguments =$"/command:{cmd} /path:\"{path}\" /url:\"{url}\" /closeonend:{(closeOnEnd ? 2 : 0)}";}startInfo.RedirectStandardOutput = true;startInfo.UseShellExecute = false;#elif UNITY_EDITOR_OSXstartInfo.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);
#endifProcess 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;}}
}

http://www.ppmy.cn/news/1578677.html

相关文章

从零开始 | C语言基础刷题DAY1

❤个人主页&#xff1a;折枝寄北的博客 DAY1[2025.3.11] 1. 求两个数的较大值2.从键盘输入的两个数的大小关系3.一个整数的奇偶性&#xff0c;请判断4. 考试分数是否通过5.考试成绩是否完美&#xff0c;请判断 1. 求两个数的较大值 题目&#xff1a; 写一个函数求两个整数的较…

react脚手架(creat-react-app)

安装 react脚手架 React官方提供的脚手架工程Create React App&#xff1a;https://github.com/facebook/create-react-app npm install create-react-app -g 全局安装 create-react-app my-react (my-react为项目名称&#xff0c;可以自定义) cd my-react 启动项目&#xff1a…

ArcGIS Pro中字段的新建方法与应用

一、引言 在地理信息系统&#xff08;GIS&#xff09;的数据管理和分析过程中&#xff0c;字段操作起着至关重要的作用。 无论是进行地图制作、空间分析还是数据统计&#xff0c;字段都是承载属性信息的基本单元。 ArcGIS Pro作为一款功能强大的GIS软件&#xff0c;为用户提…

Linux:基本指令与内涵理解

1.文件操作指令 1.1 ls ls指令用于查看指定层级文件夹下的文件或文件夹 基本格式&#xff1a;ls (选项) (查看层级&#xff09; 其中选项处不写就默认是显示文件名&#xff0c;查看层级默认是当前层级 选项1&#xff1a; -l 作用&#xff1a;将查找文件的详细信息显示出来 我们…

设计模式之工厂模式:原理、实现与应用

引言 工厂模式&#xff08;Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种创建对象的方式&#xff0c;而无需指定具体的类。工厂模式通过将对象的创建过程封装起来&#xff0c;使得代码更加灵活、可扩展。本文将深入探讨工厂模式的原理、实现方式以…

el-input输入框敏感词关键词高亮标红

在textarea中输入文本关键字标红&#xff0c;在原有的方案上做了改动&#xff0c;使用了el-input是为了添加一些按键功能 &#xff0c;原有方案支持input 和 textarea两种类型&#xff0c;有用请采纳。 若依 ruoyi-vue SpringBoot highlight-textarea 输入框敏感词关键词高亮标…

nextjs15简要介绍以及配置eslint和prettier

目录 一、Next.js 何时使用服务器端渲染&#xff08;SSR&#xff09;&#xff1f;何时使用静态生成&#xff08;SSG&#xff09;&#xff1f; 1、服务器端渲染&#xff08;SSR - getServerSideProps&#xff09; 2、 静态生成&#xff08;SSG - getStaticProps&#xff09; …

常用开源MQ组件对比

文章目录 前言一、常用MQ1.RabbitMQ2.Kafka3.RocketMQ4.ActiveMQ5.Pulsar 二、如何选择总结 前言 常用的开源mq组件有RabbitMQ、Kafka、RocketMQ、ActiveMQ、Pulsar。 一、常用MQ 1.RabbitMQ 特点&#xff1a; 基于 Erlang&#xff0c;支持 AMQP 协议&#xff0c;提供 丰富的…