This commit is contained in:
DESKTOP-5RP3AKU\Jisol
2024-10-14 03:07:34 +08:00
parent edafe4a058
commit d56c133a75
5989 changed files with 8767 additions and 441137 deletions

View File

@@ -0,0 +1,115 @@
// -----------------------------------------------
// Copyright © Sirius. All rights reserved.
// CreateTime: 2021/12/30 18:0:55
// -----------------------------------------------
/******************************************************************************
* DESCRIPTION: 清理材质未使用的纹理贴图的引用
*
* Copyright (c) 2020, 谭伟俊 (TanWeijun)
* All rights reserved
*
* COMPANY:
* CREATED: 2020.03.01, 15:20, CST
*******************************************************************************/
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
namespace Game
{
public class CleanMaterial
{
[MenuItem("Assets/Tools/Clean Material")]
public static void Clean()
{
Material[] materials = Selection.GetFiltered<Material>(SelectionMode.Assets | SelectionMode.DeepAssets);
foreach (var material in materials)
{
CleanOneMaterial(material);
}
Debug.Log("清理材质全部完成");
}
private static bool CleanOneMaterial(Material _material)
{
// 收集材质使用到的所有纹理贴图
HashSet<string> textureGUIDs = CollectTextureGUIDs(_material);
string materialPathName = Path.GetFullPath(AssetDatabase.GetAssetPath(_material));
StringBuilder strBuilder = new StringBuilder();
using (StreamReader reader = new StreamReader(materialPathName))
{
Regex regex = new Regex(@"\s+guid:\s+(\w+),");
string line = reader.ReadLine();
while (null != line)
{
if (line.Contains("m_Texture:"))
{
// 包含纹理贴图引用的行使用正则表达式获取纹理贴图的guid
Match match = regex.Match(line);
if (match.Success)
{
string textureGUID = match.Groups[1].Value;
if (textureGUIDs.Contains(textureGUID))
{
strBuilder.AppendLine(line);
}
else
{
// 材质没有用到纹理贴图guid赋值为0来清除引用关系
strBuilder.AppendLine(line.Substring(0, line.IndexOf("fileID:") + 7) + " 0}");
}
}
else
{
strBuilder.AppendLine(line);
}
}
else
{
strBuilder.AppendLine(line);
}
line = reader.ReadLine();
}
}
using (StreamWriter writer = new StreamWriter(materialPathName))
{
writer.Write(strBuilder.ToString());
}
Debug.Log($"清理材质--{materialPathName}");
return true;
}
private static HashSet<string> CollectTextureGUIDs(Material _material)
{
HashSet<string> textureGUIDs = new HashSet<string>();
for (int i = 0; i < ShaderUtil.GetPropertyCount(_material.shader); ++i)
{
if (ShaderUtil.ShaderPropertyType.TexEnv == ShaderUtil.GetPropertyType(_material.shader, i))
{
Texture texture = _material.GetTexture(ShaderUtil.GetPropertyName(_material.shader, i));
if (null == texture)
{
continue;
}
string textureGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(texture));
if (!textureGUIDs.Contains(textureGUID))
{
textureGUIDs.Add(textureGUID);
}
}
}
return textureGUIDs;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 706f69076a7589b4397cd353fa8eae8a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,126 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
public class DependAnalysis : EditorWindow
{
private static Object[] targetObjects;
private bool[] foldoutArr;
private Object[][] beDependArr;
private static int targetCount;
private Vector2 scrollPos;
string[] withoutExtensions = new string[] { ".prefab", ".unity", ".mat", ".asset", ".controller" };
[MenuItem("Assets/Tools/查找被引用", false, 19)]
static void FindReferences()
{
targetObjects = Selection.GetFiltered<Object>(SelectionMode.Assets);
targetCount = targetObjects == null ? 0 : targetObjects.Length;
if (targetCount == 0) return;
DependAnalysis window = GetWindow<DependAnalysis>("依赖分析");
window.Init();
window.Show();
}
void Init()
{
beDependArr = new Object[targetCount][];
foldoutArr = new bool[targetCount];
EditorStyles.foldout.richText = true;
for (int i = 0; i < targetCount; i++) beDependArr[i] = GetBeDepend(targetObjects[i]);
}
private void OnGUI()
{
if (beDependArr.Length != targetCount) return;
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
Object[] objArr;
int count;
string objName;
for (int i = 0; i < targetCount; i++)
{
objArr = beDependArr[i];
count = objArr == null ? 0 : objArr.Length;
objName = Path.GetFileName(AssetDatabase.GetAssetPath(targetObjects[i]));
string info = count == 0
? $"<color=yellow>{objName}【{count}】</color>"
: $"{objName}【{count}】";
foldoutArr[i] = EditorGUILayout.Foldout(foldoutArr[i], info);
if (foldoutArr[i])
{
if (count > 0)
{
foreach (var obj in objArr)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(15);
EditorGUILayout.ObjectField(obj, typeof(Object),true);
EditorGUILayout.EndHorizontal();
}
}
else
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(15);
EditorGUILayout.LabelField("【Null】");
EditorGUILayout.EndHorizontal();
}
}
}
EditorGUILayout.EndScrollView();
}
/// <summary>
/// 查找所有引用目标资源的物体
/// </summary>
/// <param name="target">目标资源</param>
/// <returns></returns>
private Object[] GetBeDepend(Object target)
{
if (target == null) return null;
string path = AssetDatabase.GetAssetPath(target);
if (string.IsNullOrEmpty(path)) return null;
string guid = AssetDatabase.AssetPathToGUID(path);
string[] files = Directory.GetFiles(Application.dataPath, "*",
SearchOption.AllDirectories).Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower()))
.ToArray();
List<Object> objects = new List<Object>();
foreach (var file in files)
{
string assetPath = file.Replace(Application.dataPath, "");
assetPath = "Assets" + assetPath;
string readText = File.ReadAllText(file);
if (!readText.StartsWith("%YAML"))
{
var depends = AssetDatabase.GetDependencies(assetPath, false);
if (depends != null)
{
foreach (var dep in depends)
{
if (dep == path)
{
objects.Add(AssetDatabase.LoadAssetAtPath<Object>(assetPath));
break;
}
}
}
}
else if (Regex.IsMatch(readText, guid)) objects.Add(AssetDatabase.LoadAssetAtPath<Object>(assetPath));
}
return objects.ToArray();
}
private void OnDestroy()
{
targetObjects = null;
beDependArr = null;
foldoutArr = null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c15d3a97f5b069f469dd60573a7fd842
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 92cecf72550b15c48b34487614f5fc16
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,121 @@
using System.IO;
using HybridCLR.Editor;
using HybridCLR.Editor.Commands;
using UnityEditor;
using UnityEngine;
namespace SHFrame.Editor
{
public static class BuildAssetsCommand
{
public static string HybridCLRBuildCacheDir => Application.dataPath + "/HybridCLRBuildCache";
public static string AssetBundleOutputDir => $"{HybridCLRBuildCacheDir}/AssetBundleOutput";
public static string DllBytesDir => $"{Application.dataPath}/HotAssets/HotDlls";
public static string GetAssetBundleOutputDirByTarget(BuildTarget target)
{
return $"{AssetBundleOutputDir}/{target}";
}
public static string ToRelativeAssetPath(string s)
{
return s.Substring(s.IndexOf("Assets/"));
}
[MenuItem("HybridCLR/Build/泛型补充dll与热更新dll导出")]
public static void BuildAndCopyABAOTHotUpdateDlls()
{
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
CompileDllCommand.CompileDll(target);
CopyABAOTHotUpdateDlls(target);
}
public static void CopyABAOTHotUpdateDlls(BuildTarget target)
{
CopyAssetBundlesToStreamingAssets(target);
ClearEmptyFolder(DllBytesDir);
CopyAOTAssembliesToStreamingAssets();
CopyHotUpdateAssembliesToStreamingAssets();
AssetDatabase.Refresh();
}
public static void CopyAOTAssembliesToStreamingAssets()
{
var target = EditorUserBuildSettings.activeBuildTarget;
string aotAssembliesSrcDir = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
//string aotAssembliesDstDir = "D:\\User\\Dou\\Unitys\\2023fars\\Assets\\HotAsset\\HotDlls";
string aotAssembliesDstDir = Application.streamingAssetsPath;
foreach (var dll in SettingsUtil.AOTAssemblyNames)
{
string srcDllPath = $"{aotAssembliesSrcDir}/{dll}.dll";
if (!File.Exists(srcDllPath))
{
Debug.LogError($"ab中添加AOT补充元数据dll:{srcDllPath} 时发生错误,文件不存在。裁剪后的AOT dll在BuildPlayer时才能生成因此需要你先构建一次游戏App后再打包。");
continue;
}
string dllBytesPath = $"{DllBytesDir}/{dll}.dll.bytes";
File.Copy(srcDllPath, dllBytesPath, true);
Debug.Log($"[CopyAOTAssembliesToStreamingAssets] copy AOT dll {srcDllPath} -> {dllBytesPath}");
}
}
public static void CopyHotUpdateAssembliesToStreamingAssets()
{
var target = EditorUserBuildSettings.activeBuildTarget;
string hotfixDllSrcDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
//string hotfixAssembliesDstDir = "D:\\User\\Dou\\Unitys\\2023fars\\Assets\\HotAsset\\HotDlls";
string hotfixAssembliesDstDir = Application.streamingAssetsPath;
foreach (var dll in SettingsUtil.HotUpdateAssemblyFilesExcludePreserved)
{
string dllPath = $"{hotfixDllSrcDir}/{dll}";
string dllBytesPath = $"{DllBytesDir}/{dll}.bytes";
File.Copy(dllPath, dllBytesPath, true);
Debug.Log($"[CopyHotUpdateAssembliesToStreamingAssets] copy hotfix dll {dllPath} -> {dllBytesPath}");
}
}
public static void CopyAssetBundlesToStreamingAssets(BuildTarget target)
{
string streamingAssetPathDst = Application.streamingAssetsPath;
Directory.CreateDirectory(streamingAssetPathDst);
string outputDir = GetAssetBundleOutputDirByTarget(target);
var abs = new string[] { "prefabs" };
foreach (var ab in abs)
{
string srcAb = ToRelativeAssetPath($"{outputDir}/{ab}");
string dstAb = ToRelativeAssetPath($"{streamingAssetPathDst}/{ab}");
Debug.Log($"[CopyAssetBundlesToStreamingAssets] copy assetbundle {srcAb} -> {dstAb}");
AssetDatabase.CopyAsset(srcAb, dstAb);
}
}
private static void ClearEmptyFolder(string folderPath)
{
DirectoryInfo dir = new DirectoryInfo(folderPath);
DirectoryInfo[] subDirs = dir.GetDirectories("*.*", SearchOption.AllDirectories);
foreach (DirectoryInfo subDir in subDirs)
{
FileSystemInfo[] subFiles = subDir.GetFileSystemInfos();
if (subFiles.Length == 0)
{
File.Delete(subDir.FullName + ".meta");
subDir.Delete();
}
}
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
File.Delete(file.FullName);
}
AssetDatabase.Refresh();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a8357532218e6f49a9bb9401382d6d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using System.IO;
using HybridCLR.Editor;
using HybridCLR.Editor.Commands;
using HybridCLR.Editor.Installer;
using UnityEditor;
using UnityEngine;
namespace SHFrame.Editor
{
public class BuildPlayerCommand
{
public static void CopyAssets(string outputDir)
{
Directory.CreateDirectory(outputDir);
foreach (var srcFile in Directory.GetFiles(Application.streamingAssetsPath))
{
string dstFile = $"{outputDir}/{Path.GetFileName(srcFile)}";
File.Copy(srcFile, dstFile, true);
}
}
public static void InstallFromRepo()
{
var ic = new InstallerController();
ic.InstallDefaultHybridCLR();
}
public static void InstallBuildWin64()
{
InstallFromRepo();
Build_Win64(true);
}
[MenuItem("HybridCLR/Build/Win64")]
public static void Build_Win64()
{
Build_Win64(false);
}
public static void Build_Win64(bool existWhenCompleted)
{
BuildTarget target = BuildTarget.StandaloneWindows64;
BuildTarget activeTarget = EditorUserBuildSettings.activeBuildTarget;
if (activeTarget != BuildTarget.StandaloneWindows64 && activeTarget != BuildTarget.StandaloneWindows)
{
Debug.LogError("请先切到Win平台再打包");
return;
}
// Get filename.
string outputPath = $"{SettingsUtil.ProjectDir}/Release-Win64";
var buildOptions = BuildOptions.CompressWithLz4;
string location = $"{outputPath}/HybridCLRTrial.exe";
PrebuildCommand.GenerateAll();
Debug.Log("====> Build App");
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions()
{
scenes = new string[] { "Assets/Scenes/main.unity" },
locationPathName = location,
options = buildOptions,
target = target,
targetGroup = BuildTargetGroup.Standalone,
};
var report = BuildPipeline.BuildPlayer(buildPlayerOptions);
if (report.summary.result != UnityEditor.Build.Reporting.BuildResult.Succeeded)
{
Debug.LogError("打包失败");
if (existWhenCompleted)
{
EditorApplication.Exit(1);
}
return;
}
Debug.Log("====> 复制热更新资源和代码");
BuildAssetsCommand.BuildAndCopyABAOTHotUpdateDlls();
BashUtil.CopyDir(Application.streamingAssetsPath, $"{outputPath}/HybridCLRTrial_Data/StreamingAssets", true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7796c8df856ac4a4a9d644329c1f0958
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
{
"name": "SHFrame.Editor",
"rootNamespace": "",
"references": [
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:4d1926c9df5b052469a1c63448b7609a",
"GUID:2373f786d14518f44b0f475db77ba4de",
"GUID:ac484fe5e443f4146a129450c27f000f"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b7d50a21d47842f4b81d103bfc07e719
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
using System.IO;
using UnityEditor;
using UnityEngine;
public class AutoSetTextureUISprite : AssetPostprocessor
{
void OnPreprocessTexture()
{
//自动设置类型
if (assetPath.Contains("FGui"))
{
//fgui的图片资源需要设置为Sprite和不生成Mip Maps
TextureImporter textureImporter = (TextureImporter)assetImporter;
textureImporter.textureType = TextureImporterType.Default;
textureImporter.textureShape = TextureImporterShape.Texture2D;
textureImporter.mipmapEnabled = false;
textureImporter.filterMode = FilterMode.Bilinear;
}
}
// private void OnPostprocessMaterial(Material material)
// {
// if (assetPath.Contains("FairyRes"))
// {
// material.SetInt("_StraightAlphaInput", 1);
// AssetDatabase.SaveAssets();
// }
// }
// [MenuItem("Tools/ConvertGammaToLinearTex")]
public static void ConvertGammaToLinearTex()
{
var assetGUIDs = Selection.assetGUIDs;
foreach (var assetGUID in assetGUIDs)
{
var assetPath = AssetDatabase.GUIDToAssetPath(assetGUID);
Debug.Log(assetPath);
if (!assetPath.Contains(".png")) continue;
Texture2D srcTex = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
if (srcTex != null)
{
Texture2D temp = new Texture2D(srcTex.width, srcTex.height, TextureFormat.RGBA32, true);
Color[] pixels = srcTex.GetPixels();
for (int j = 0; j < pixels.Length; j++)
{
Color pixel = pixels[j];
pixel.r = Mathf.Pow(pixel.r, 2.2f);
pixel.g = Mathf.Pow(pixel.g, 2.2f);
pixel.b = Mathf.Pow(pixel.b, 2.2f);
pixels[j] = pixel;
}
temp.SetPixels(pixels);
temp.Apply();
var bytes = temp.EncodeToPNG();
File.WriteAllBytes(assetPath, bytes);
}
}
return;
// List<string> selectedAsset = FindSelectionObject("*. png");
// int count = selectedAsset.Count;
// for (int i = 0; i < count; i++)
// {
// Texture2D srcTex = AssetDatabase.LoadAssetAtPath<Texture2D>(selectedAsset[i]);
// if (srcTex != null)
// {
// Texture2D temp = new Texture2D(srcTex.width, srcTex.height, TextureFormat.RGBA32, true);
// Color[] pixels = srcTex.GetPixels();
// for (int j = 0; j < pixels.Length; j++)
// {
// Color pixel = pixels[i];
// pixel.r = Mathf.Pow(pixel.r, 2.2f);
// pixel.g = Mathf.Pow(pixel.g, 2.2f);
// pixel.b = Mathf.Pow(pixel.b, 2.2f);
// pixels[i] = pixel;
// }
//
// temp.SetPixels(pixels);
// temp.Apply();
// var bytes = temp.EncodeToPNG();
// File.WriteAllBytes(selectedAsset[i], bytes);
// }
// }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 74bbc7b5200382a44b37699f1687e3c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 80372f1a333653748a8443a51f860e63
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9855eda2b13a0084ab0def6f7ca74141
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,91 @@
using UnityEditor;
using UnityEngine;
using UnityToolbarExtender;
namespace SHFrame
{
[InitializeOnLoad]
public class EditorResourceMode
{
static class ToolbarStyles
{
public static readonly GUIStyle ToolBarExtenderBtnStyle;
public static readonly GUIStyle ToolBarTextStyle;
public static readonly GUIStyle ToolBarButtonGuiStyle;
static ToolbarStyles()
{
ToolBarExtenderBtnStyle = new GUIStyle("Command")
{
fontSize = 12,
alignment = TextAnchor.MiddleCenter,
imagePosition = ImagePosition.ImageAbove,
fontStyle = FontStyle.Normal,
fixedWidth = 60
};
ToolBarTextStyle = new GUIStyle(ButtonStyleName)
{
padding = new RectOffset(2, 8, 2, 2),
alignment = TextAnchor.MiddleCenter,
fontStyle = FontStyle.Bold
};
ToolBarButtonGuiStyle = new GUIStyle(ButtonStyleName)
{
padding = new RectOffset(2, 8, 2, 2),
alignment = TextAnchor.MiddleCenter,
fontStyle = FontStyle.Bold
};
}
}
static EditorResourceMode()
{
ToolbarExtender.RightToolbarGUI.Add(OnToolbarGUI);
_resourceModeIndex = EditorPrefs.GetInt("EditorResourceMode", 0);
}
private const string ButtonStyleName = "Tab middle";
static GUIStyle _buttonGuiStyle;
private static readonly string[] _resourceModeNames =
{ "EditorMode (编辑器下的模拟模式)",
"OfflinePlayMode (单机模式)",
"HostPlayMode (联机运行模式)",
"WebPlayMode (WebGL运行模式)"
};
private static int _resourceModeIndex = 0;
public static int ResourceModeIndex => _resourceModeIndex;
static void OnToolbarGUI()
{
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
// GUILayout.Label("资源加载模式:",ToolbarStyles.ToolBarTextStyle);
GUILayout.Space(10);
GUILayout.FlexibleSpace();
// 资源模式
int selectedIndex = EditorGUILayout.Popup("", _resourceModeIndex, _resourceModeNames, ToolbarStyles.ToolBarButtonGuiStyle);
// ReSharper disable once RedundantCheckBeforeAssignment
if (selectedIndex != _resourceModeIndex)
{
Debug.Log($"更改编辑器资源运行模式 : {_resourceModeNames[selectedIndex]}");
_resourceModeIndex = selectedIndex;
EditorPrefs.SetInt("EditorResourceMode", selectedIndex);
}
GUILayout.FlexibleSpace();
GUILayout.Space(400);
}
EditorGUI.EndDisabledGroup();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce74293562bfebc45856ef1b22eb41b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,91 @@
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityToolbarExtender;
namespace SHFrame
{
[InitializeOnLoad]
public class SceneSwitchLeftButton
{
private static readonly string SceneMain = "Boot";
static SceneSwitchLeftButton()
{
ToolbarExtender.LeftToolbarGUI.Add(OnToolbarGUI);
}
static readonly string ButtonStyleName = "Tab middle";
static GUIStyle _buttonGuiStyle;
static void OnToolbarGUI()
{
_buttonGuiStyle ??= new GUIStyle(ButtonStyleName)
{
padding = new RectOffset(2, 8, 2, 2),
alignment = TextAnchor.MiddleCenter,
fontStyle = FontStyle.Bold,
};
GUILayout.FlexibleSpace();
if (GUILayout.Button(
new GUIContent("Launcher", EditorGUIUtility.FindTexture("PlayButton"), $"Start Scene Launcher"),
_buttonGuiStyle))
{
if (EditorApplication.isPlaying)
{
EditorApplication.isPlaying = false;
}
else
{
SceneHelper.StartScene(SceneMain);
}
}
}
}
static class SceneHelper
{
static string _sceneToOpen;
public static void StartScene(string sceneName)
{
if (EditorApplication.isPlaying)
{
EditorApplication.isPlaying = false;
}
_sceneToOpen = sceneName;
EditorApplication.update += OnUpdate;
}
static void OnUpdate()
{
if (_sceneToOpen == null ||
EditorApplication.isPlaying || EditorApplication.isPaused ||
EditorApplication.isCompiling || EditorApplication.isPlayingOrWillChangePlaymode)
{
return;
}
EditorApplication.update -= OnUpdate;
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
{
string[] guids = AssetDatabase.FindAssets("t:scene " + _sceneToOpen, null);
if (guids.Length == 0)
{
Debug.LogWarning("Couldn't find scene file");
}
else
{
string scenePath = AssetDatabase.GUIDToAssetPath(guids[0]);
EditorSceneManager.OpenScene(scenePath);
EditorApplication.isPlaying = true;
}
}
_sceneToOpen = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f015ac6f30edc48409abd5eaeb7de23b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,110 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.UIElements;
#else
using UnityEngine.Experimental.UIElements;
#endif
namespace UnityToolbarExtender
{
public static class ToolbarCallback
{
static Type m_toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
static Type m_guiViewType = typeof(Editor).Assembly.GetType("UnityEditor.GUIView");
#if UNITY_2020_1_OR_NEWER
static Type m_iWindowBackendType = typeof(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();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a4fbfa229ee894b478fb21c046afa6d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace UnityToolbarExtender
{
[InitializeOnLoad]
public static class ToolbarExtender
{
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 ToolbarExtender()
{
Type toolbarType = typeof(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();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8e582c227e3bb4498b2703b86ca00d7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 548460d28fdf29144a5f942b778caa3c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
namespace UnityWebSocket.Editor
{
public static class Settings
{
public const string GITHUB = "https://github.com/psygames/UnityWebSocket";
public const string QQ_GROUP = "1126457634";
public const string QQ_GROUP_LINK = "https://qm.qq.com/cgi-bin/qm/qr?k=KcexYJ9aYwogFXbj2aN0XHH5b2G7ICmd";
public const string EMAIL = "799329256@qq.com";
public const string AUHTOR = "psygames";
public const string VERSION = "2.7.0";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a8d0ca4e93274b74b864a13d989326c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,228 @@
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
namespace UnityWebSocket.Editor
{
internal class SettingsWindow : EditorWindow
{
static SettingsWindow window = null;
[MenuItem("Tools/UnityWebSocket", priority = 100)]
internal static void Open()
{
if (window != null)
{
window.Close();
}
window = GetWindow<SettingsWindow>(true, "UnityWebSocket");
window.minSize = window.maxSize = new Vector2(600, 310);
window.Show();
window.BeginCheck();
}
private void OnGUI()
{
DrawLogo();
DrawVersion();
DrawSeparator(80);
DrawSeparator(186);
DrawHelper();
DrawFooter();
}
Texture2D logoTex = null;
private void DrawLogo()
{
if (logoTex == null)
{
logoTex = new Texture2D(66, 66);
logoTex.LoadImage(Convert.FromBase64String(LOGO_BASE64.VALUE));
for (int i = 0; i < 66; i++) for (int j = 0; j < 15; j++) logoTex.SetPixel(i, j, Color.clear);
logoTex.Apply();
}
var logoPos = new Rect(10, 10, 66, 66);
GUI.DrawTexture(logoPos, logoTex);
var title = "<color=#3A9AD8><b>UnityWebSocket</b></color>";
var titlePos = new Rect(80, 20, 500, 50);
GUI.Label(titlePos, title, TextStyle(24));
}
private void DrawSeparator(int y)
{
EditorGUI.DrawRect(new Rect(10, y, 580, 1), Color.white * 0.5f);
}
private GUIStyle TextStyle(int fontSize = 10, TextAnchor alignment = TextAnchor.UpperLeft, float alpha = 0.85f)
{
var style = new GUIStyle();
style.fontSize = fontSize;
style.normal.textColor = (EditorGUIUtility.isProSkin ? Color.white : Color.black) * alpha;
style.alignment = alignment;
style.richText = true;
return style;
}
private void DrawVersion()
{
GUI.Label(new Rect(440, 10, 150, 10), "Current Version: " + Settings.VERSION, TextStyle(alignment: TextAnchor.MiddleLeft));
if (string.IsNullOrEmpty(latestVersion))
{
GUI.Label(new Rect(440, 30, 150, 10), "Checking for Updates...", TextStyle(alignment: TextAnchor.MiddleLeft));
}
else if (latestVersion == "unknown")
{
}
else
{
GUI.Label(new Rect(440, 30, 150, 10), "Latest Version: " + latestVersion, TextStyle(alignment: TextAnchor.MiddleLeft));
if (Settings.VERSION == latestVersion)
{
if (GUI.Button(new Rect(440, 50, 150, 18), "Check Update"))
{
latestVersion = "";
changeLog = "";
BeginCheck();
}
}
else
{
if (GUI.Button(new Rect(440, 50, 150, 18), "Update to | " + latestVersion))
{
ShowUpdateDialog();
}
}
}
}
private void ShowUpdateDialog()
{
var isOK = EditorUtility.DisplayDialog("UnityWebSocket",
"Update UnityWebSocket now?\n" + changeLog,
"Update Now", "Cancel");
if (isOK)
{
UpdateVersion();
}
}
private void UpdateVersion()
{
Application.OpenURL(Settings.GITHUB + "/releases");
}
private void DrawHelper()
{
GUI.Label(new Rect(330, 200, 100, 18), "GitHub:", TextStyle(10, TextAnchor.MiddleRight));
if (GUI.Button(new Rect(440, 200, 150, 18), "UnityWebSocket"))
{
Application.OpenURL(Settings.GITHUB);
}
GUI.Label(new Rect(330, 225, 100, 18), "Report:", TextStyle(10, TextAnchor.MiddleRight));
if (GUI.Button(new Rect(440, 225, 150, 18), "Report an Issue"))
{
Application.OpenURL(Settings.GITHUB + "/issues/new");
}
GUI.Label(new Rect(330, 250, 100, 18), "Email:", TextStyle(10, TextAnchor.MiddleRight));
if (GUI.Button(new Rect(440, 250, 150, 18), Settings.EMAIL))
{
var uri = new Uri(string.Format("mailto:{0}?subject={1}", Settings.EMAIL, "UnityWebSocket Feedback"));
Application.OpenURL(uri.AbsoluteUri);
}
GUI.Label(new Rect(330, 275, 100, 18), "QQ群:", TextStyle(10, TextAnchor.MiddleRight));
if (GUI.Button(new Rect(440, 275, 150, 18), Settings.QQ_GROUP))
{
Application.OpenURL(Settings.QQ_GROUP_LINK);
}
}
private void DrawFooter()
{
EditorGUI.DropShadowLabel(new Rect(10, 230, 400, 20), "Developed by " + Settings.AUHTOR);
EditorGUI.DropShadowLabel(new Rect(10, 250, 400, 20), "All rights reserved");
}
UnityWebRequest req;
string changeLog = "";
string latestVersion = "";
void BeginCheck()
{
EditorApplication.update -= VersionCheckUpdate;
EditorApplication.update += VersionCheckUpdate;
req = UnityWebRequest.Get(Settings.GITHUB + "/releases/latest");
req.SendWebRequest();
}
private void VersionCheckUpdate()
{
#if UNITY_2020_3_OR_NEWER
if (req == null
|| req.result == UnityWebRequest.Result.ConnectionError
|| req.result == UnityWebRequest.Result.DataProcessingError
|| req.result == UnityWebRequest.Result.ProtocolError)
#elif UNITY_2018_1_OR_NEWER
if (req == null || req.isNetworkError || req.isHttpError)
#else
if (req == null || req.isError)
#endif
{
EditorApplication.update -= VersionCheckUpdate;
latestVersion = "unknown";
return;
}
if (req.isDone)
{
EditorApplication.update -= VersionCheckUpdate;
latestVersion = req.url.Substring(req.url.LastIndexOf("/") + 1).TrimStart('v');
if (Settings.VERSION != latestVersion)
{
var text = req.downloadHandler.text;
var st = text.IndexOf("content=\"" + latestVersion);
st = st > 0 ? text.IndexOf("\n", st) : -1;
var end = st > 0 ? text.IndexOf("\" />", st) : -1;
if (st > 0 && end > st)
{
changeLog = text.Substring(st + 1, end - st - 1).Trim();
changeLog = changeLog.Replace("\r", "");
changeLog = changeLog.Replace("\n", "\n- ");
changeLog = "\nCHANGE LOG: \n- " + changeLog + "\n";
}
}
Repaint();
}
}
}
internal static class LOGO_BASE64
{
internal const string VALUE = "iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAMAAADUivDaAAAAq1BMVEUAAABKmtcvjtYzl" +
"9szmNszl9syl9k0mNs0mNwzmNs0mNszl9szl9s0mNs0mNwzmNw0mNwyltk0mNw0mNwzl9s0mNsymNs0mNszmNwzmNwzm" +
"NszmNs0mNwzl9w0mNwzmNw0mNs0mNs0mNwzl9wzmNs0mNwzmNs0mNwzl90zmNszmNszl9szmNsxmNszmNszmNw0mNwzm" +
"Nw0mNs2neM4pe41mt43ouo2oOY5qfM+UHlaAAAAMnRSTlMAAwXN3sgI+/069MSCK6M/MA74h9qfFHB8STWMJ9OSdmNcI" +
"8qya1IeF+/U0EIa57mqmFTYJe4AAAN3SURBVFjD7ZbpkppAFEa/bgVBREF2kEVGFNeZsM77P1kadURnJkr8k1Qlx1Khu" +
"/pw7+2lwH/+YcgfMBBLG7VocwDamzH+wJBB8Qhjve2f0TdrGwjei6o4Ub/nM/APw5Z7vvSB/qrCrqbD6fBEVtigeMxks" +
"fX9zWbj+z1jhqgSBplQ50eGo4614WXlRAzgrRhmtSfvxAn7pB0N5ObaKKZZuU5/d37IBcBgUQwqDuf7Z2gUmVAl4NGNr" +
"/UeHxV5n39ulbaKLI86h6HilmM5M1aN126lpNhtl59yeTsp8nUMvpNC1J3bh5FtfVRk+bJrJunn5d4U4piJ/Vw9eXgsj" +
"4ZpZaCjg9waZkIpnBWLJ44OwoNu60F2UnSaEkKv4XnAlCpm6B4F/aKMDiyGi2L8SEEAVdxNLuzmgV7nFwObEe2xQVuX+" +
"RV1lWetga3w+cN1sXgvm4cJH8OEgZC1DPKhfF/BIymmQrMjq/x65FUeEkDup8GxoexZmznHCvANtXU/CAq13yimhQGtm" +
"H4VCPnBBL1fTKo3CqEcvq7Lb/OwHxWTYlyw+JmjKoVvDLVOQB4pVsM8K8smgvLCxZDlIijwyOEc+nr/msMwK0+GQWGBd" +
"tmhjv8icTds1s2ammaFh04QLLe69NK7guP6mTDMaw3o6nAX/Z7EXUskPSvWEWg4srVlp5NTDXv9Lce9HGN5eeG4nj5Yz" +
"ACteU2wQLo4MBtJfd1nw5nG1/s9zwUQ6pykL1TQjqdeuvQW0naz2XKLYL4Cwzr4vj+OQdD96CSp7Lrynp4aeFF0xdm5q" +
"6OFtFfPv7URxpWJNjd/N+3+I9+1klMav12Qtgbt9R2JaIopjkzaPtOFq4KxUpqfUMSFnQrySWjLoQzRZS4HMH84ME1ej" +
"S1YJpQZ3B+sR1uCQJSBdGdCk1eAEgORR88KK05W8dh2MA+A/SKCYu3mCJ0Ek7HBx4HHeuwYy5G3x8hSMTJcOMFbinCsn" +
"hO1V1aszGULvA0g4UFsb4VA0hAFcyo6cgLsAoT7uUtGAH5wQKQle0wuLyxLTaNyJEYwxw4wSljLK1TP8CAaOyhBMMEsj" +
"OBoXgo7VGElFkSWL+vef1RF2YNXeRWYzQBTpkhC8KaZHhuIogArkQLKClBZjU26B2IZgGz+cpZkHl8g3fYUaW/YP2kb2" +
"M/V97JY/vZN859n+QmO7XtC9Bf2jAAAAABJRU5ErkJggg==";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7c42d421cc4c34f3eae1fbd67f0dced0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: