Before 优化 机场
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
|
||||
namespace Kamgam.UIToolkitBlurredBackground
|
||||
{
|
||||
public static class EditorPlayState
|
||||
{
|
||||
public enum PlayState
|
||||
{
|
||||
NotListening = 0,
|
||||
Editing = 1,
|
||||
FromEditToPlay = 2,
|
||||
Playing = 3,
|
||||
FromPlayToEdit = 4
|
||||
}
|
||||
|
||||
static string _editorPlayStateKey;
|
||||
static string EditorPlayStateKey
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_editorPlayStateKey))
|
||||
{
|
||||
_editorPlayStateKey = typeof(EditorPlayState).FullName + ".State";
|
||||
}
|
||||
|
||||
return _editorPlayStateKey;
|
||||
}
|
||||
}
|
||||
|
||||
static PlayState _state = PlayState.NotListening;
|
||||
public static PlayState State
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_state == PlayState.NotListening)
|
||||
StartListening();
|
||||
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
[DidReloadScripts]
|
||||
[InitializeOnLoadMethod]
|
||||
public static void StartListening()
|
||||
{
|
||||
if (_state != PlayState.NotListening)
|
||||
return;
|
||||
|
||||
EditorApplication.playModeStateChanged -= onPlayModeChanged;
|
||||
EditorApplication.playModeStateChanged += onPlayModeChanged;
|
||||
|
||||
int state = SessionState.GetInt(EditorPlayStateKey, -1);
|
||||
if (state >= 0)
|
||||
{
|
||||
_state = (PlayState)state;
|
||||
}
|
||||
else
|
||||
{
|
||||
_state = EditorApplication.isPlayingOrWillChangePlaymode ? PlayState.Playing : PlayState.Editing;
|
||||
}
|
||||
}
|
||||
|
||||
private static void onPlayModeChanged(PlayModeStateChange change)
|
||||
{
|
||||
if (change == PlayModeStateChange.EnteredPlayMode)
|
||||
{
|
||||
_state = PlayState.Playing;
|
||||
}
|
||||
if (change == PlayModeStateChange.ExitingPlayMode)
|
||||
{
|
||||
_state = PlayState.FromPlayToEdit;
|
||||
}
|
||||
if (change == PlayModeStateChange.EnteredEditMode)
|
||||
{
|
||||
_state = PlayState.Editing;
|
||||
}
|
||||
if (change == PlayModeStateChange.ExitingEditMode)
|
||||
{
|
||||
_state = PlayState.FromEditToPlay;
|
||||
}
|
||||
|
||||
SessionState.SetInt(EditorPlayStateKey, (int)_state);
|
||||
}
|
||||
|
||||
public static void StopListening()
|
||||
{
|
||||
_state = PlayState.NotListening;
|
||||
SessionState.EraseInt(EditorPlayStateKey);
|
||||
|
||||
EditorApplication.playModeStateChanged -= onPlayModeChanged;
|
||||
}
|
||||
|
||||
public static bool IsInBetween
|
||||
{
|
||||
get => _state == PlayState.FromEditToPlay || _state == PlayState.FromPlayToEdit;
|
||||
}
|
||||
|
||||
public static bool IsEditing
|
||||
{
|
||||
get => _state == PlayState.Editing;
|
||||
}
|
||||
|
||||
public static bool IsPlaying
|
||||
{
|
||||
get => _state == PlayState.Playing;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b74da72089888e458571f6b6303e93d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 343da767e1329d94783b9866b9bf7764
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,363 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Kamgam.UIToolkitBlurredBackground
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows you to register a callback before compilation
|
||||
/// which is then executed automatically after compilation.<br />
|
||||
/// <br />
|
||||
/// Methods registered are usually executed in FIFO order. Though there
|
||||
/// is no guarantee that this will always be the case.
|
||||
/// <example>
|
||||
/// CrossCompileCallbacks.RegisterCallback(testCallbackA); // It can find the type automatically.
|
||||
/// CrossCompileCallbacks.RegisterCallback(typeof(YourClass), "testCallbackA");
|
||||
/// </example>
|
||||
/// </summary>
|
||||
public static class CrossCompileCallbacks
|
||||
{
|
||||
/// <summary>
|
||||
/// If set to true then the callbacks will not be called immediately but
|
||||
/// within the next editor update cycle.<br />
|
||||
/// Use this to avoid "Calling ... from assembly reloading callbacks are not supported." errors.
|
||||
/// </summary>
|
||||
public static bool DelayExecutionAfterCompilation
|
||||
{
|
||||
get => SessionState.GetBool(typeName() + ".DelayExecution", false);
|
||||
set => SessionState.SetBool(typeName() + ".DelayExecution", value);
|
||||
}
|
||||
|
||||
static string typeName() => typeof(CrossCompileCallbacks).FullName;
|
||||
|
||||
const string _maxIndexKey = ".MaxIndex";
|
||||
static string maxIndexKey() => typeName() + _maxIndexKey;
|
||||
|
||||
const string _lastReleasedIndexKey = ".LastReleasedIndex";
|
||||
static string lastReleasedIndexKey() => typeName() + _lastReleasedIndexKey;
|
||||
|
||||
const string _indexTypeKey = ".Index[{0}].Type";
|
||||
static string indexTypeKey(int index) => string.Format(typeName() + _indexTypeKey, index);
|
||||
|
||||
const string _indexMethodKey = ".Index[{0}].Method";
|
||||
static string indexMethodKey(int index) => string.Format(typeName() + _indexMethodKey, index);
|
||||
|
||||
|
||||
static int getMaxIndex()
|
||||
{
|
||||
return SessionState.GetInt(maxIndexKey(), -1);
|
||||
}
|
||||
|
||||
static int getNextIndex()
|
||||
{
|
||||
int maxIndex;
|
||||
|
||||
// Try to reuse an old index (update max index if necessary)
|
||||
int reusableIndex = SessionState.GetInt(lastReleasedIndexKey(), -1);
|
||||
if (reusableIndex >= 0)
|
||||
{
|
||||
SessionState.SetInt(lastReleasedIndexKey(), -1);
|
||||
|
||||
maxIndex = getMaxIndex();
|
||||
if(maxIndex < reusableIndex)
|
||||
SessionState.SetInt(maxIndexKey(), reusableIndex);
|
||||
|
||||
return reusableIndex;
|
||||
}
|
||||
|
||||
// New index needed (increase max index).
|
||||
maxIndex = SessionState.GetInt(maxIndexKey(), -1);
|
||||
maxIndex++;
|
||||
SessionState.SetInt(maxIndexKey(), maxIndex);
|
||||
|
||||
return maxIndex;
|
||||
}
|
||||
|
||||
public static void ReleaseIndex(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
SessionState.SetInt(lastReleasedIndexKey(), index);
|
||||
SessionState.EraseString(indexTypeKey(index));
|
||||
SessionState.EraseString(indexMethodKey(index));
|
||||
|
||||
// Decrease or erase max index if needed.
|
||||
int maxIndex = getMaxIndex();
|
||||
if(index == maxIndex)
|
||||
{
|
||||
maxIndex--;
|
||||
if(maxIndex < 0)
|
||||
SessionState.EraseInt(maxIndexKey());
|
||||
else
|
||||
SessionState.SetInt(maxIndexKey(), maxIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseAllOnType(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
return;
|
||||
|
||||
int maxIndex = getMaxIndex();
|
||||
for (int i = maxIndex; i >= 0; i--)
|
||||
{
|
||||
string typeName;
|
||||
GetCallbackInfo(i, out typeName, out _);
|
||||
|
||||
if(typeName == type.FullName)
|
||||
{
|
||||
ReleaseIndex(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a callback and returns an index >= 0 on success and -1 on failure.
|
||||
/// </summary>
|
||||
/// <param name="callback">A static method without any parameters.</param>
|
||||
/// <returns></returns>
|
||||
public static int RegisterCallback(System.Action callback)
|
||||
{
|
||||
if (callback == null)
|
||||
return -1;
|
||||
|
||||
var methodInfo = callback.GetMethodInfo();
|
||||
if (methodInfo == null)
|
||||
return -1;
|
||||
|
||||
if (!methodInfo.IsStatic)
|
||||
{
|
||||
Debug.Log("Method needs to be static.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return RegisterCallback(methodInfo.DeclaringType, methodInfo.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a callback and returns an index >= 0 on success and -1 on failure.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="staticMethodName">A static method without any parameters.</param>
|
||||
/// <returns></returns>
|
||||
public static int RegisterCallback(Type type, string staticMethodName)
|
||||
{
|
||||
if (type == null || string.IsNullOrEmpty(staticMethodName))
|
||||
{
|
||||
Debug.Assert(type != null);
|
||||
Debug.Assert(staticMethodName != null);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check if methods has any parameters (that's not supported)
|
||||
try
|
||||
{
|
||||
var flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
|
||||
var methodInfo = type.GetMethod(staticMethodName, flags);
|
||||
if (methodInfo == null)
|
||||
{
|
||||
Debug.LogError("No static method '" + staticMethodName + "' found in '" + type.FullName + "'.");
|
||||
return -1;
|
||||
}
|
||||
if (methodInfo.GetParameters().Length > 0)
|
||||
{
|
||||
Debug.Assert(methodInfo.GetParameters().Length == 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError($"CrossCompileCallbacks: Error while checking '{staticMethodName}' method parameters. Error:\n" + e.Message);
|
||||
}
|
||||
|
||||
int index = getNextIndex();
|
||||
SessionState.SetString(indexTypeKey(index), type.FullName);
|
||||
SessionState.SetString(indexMethodKey(index), staticMethodName);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
public static void GetCallbackInfo(int index, out string typeName, out string methodName)
|
||||
{
|
||||
typeName = SessionState.GetString(indexTypeKey(index), null);
|
||||
methodName = SessionState.GetString(indexMethodKey(index), null);
|
||||
}
|
||||
|
||||
[DidReloadScripts(-1)]
|
||||
static void onAfterCompilation()
|
||||
{
|
||||
if (DelayExecutionAfterCompilation)
|
||||
{
|
||||
EditorApplication.delayCall -= delayedExecuteRegisteredCallbacks;
|
||||
EditorApplication.delayCall += delayedExecuteRegisteredCallbacks;
|
||||
}
|
||||
else
|
||||
{
|
||||
executeRegisteredCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
static void delayedExecuteRegisteredCallbacks()
|
||||
{
|
||||
EditorApplication.delayCall -= delayedExecuteRegisteredCallbacks;
|
||||
executeRegisteredCallbacks();
|
||||
}
|
||||
|
||||
static void executeRegisteredCallbacks()
|
||||
{
|
||||
int maxIndex = getMaxIndex();
|
||||
for (int i = maxIndex; i >= 0; i--)
|
||||
{
|
||||
string typeName;
|
||||
string methodName;
|
||||
GetCallbackInfo(i, out typeName, out methodName);
|
||||
|
||||
try
|
||||
{
|
||||
ReleaseIndex(i);
|
||||
|
||||
if (string.IsNullOrEmpty(typeName) || string.IsNullOrEmpty(methodName))
|
||||
continue;
|
||||
|
||||
var methodInfo = findStaticMethod(typeName, methodName);
|
||||
methodInfo.Invoke(null, null);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
string errorMsg = e.Message;
|
||||
if(errorMsg.Contains("invocation") && e.InnerException != null)
|
||||
{
|
||||
errorMsg += "\n" + e.InnerException.Message;
|
||||
}
|
||||
Debug.LogError($"CrossCompileCallbacks: Calling '{typeName}.{methodName}' failed. Error:\n" + errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MethodInfo findStaticMethod(string fullTypeName, string methodName)
|
||||
{
|
||||
var type = findType(fullTypeName);
|
||||
if (type == null)
|
||||
return null;
|
||||
|
||||
var flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
|
||||
var methodInfo = type.GetMethod(methodName, flags);
|
||||
|
||||
return methodInfo;
|
||||
}
|
||||
|
||||
static Type findType(string fullTypeName)
|
||||
{
|
||||
Debug.Assert(fullTypeName != null);
|
||||
|
||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
Type t = assembly.GetType(fullTypeName, throwOnError: false);
|
||||
if (t != null)
|
||||
return t;
|
||||
}
|
||||
|
||||
throw new ArgumentException("Type " + fullTypeName + " doesn't exist in the current app domain.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Utility method to store a static parameterless Action
|
||||
/// in the SessionState for retrieval at a later time.
|
||||
/// </summary>
|
||||
/// <param name="sessionStorageKey"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <returns></returns>
|
||||
public static bool StoreAction(string sessionStorageKey, System.Action action)
|
||||
{
|
||||
if (action == null)
|
||||
return false;
|
||||
|
||||
var methodInfo = action.GetMethodInfo();
|
||||
if (methodInfo == null)
|
||||
return false;
|
||||
|
||||
if (!methodInfo.IsStatic)
|
||||
{
|
||||
Debug.Log("Method '"+ methodInfo.Name + "'needs to be static.");
|
||||
return false;
|
||||
}
|
||||
|
||||
SessionState.SetString(sessionStorageKey + ".Type", methodInfo.DeclaringType.FullName);
|
||||
SessionState.SetString(sessionStorageKey + ".Method", methodInfo.Name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the Action from the SessionState.
|
||||
/// </summary>
|
||||
/// <param name="sessionStorageKey"></param>
|
||||
/// <returns></returns>
|
||||
public static System.Action GetStoredAction(string sessionStorageKey)
|
||||
{
|
||||
var typeName = SessionState.GetString(sessionStorageKey + ".Type", null);
|
||||
var methodName = SessionState.GetString(sessionStorageKey + ".Method", null);
|
||||
|
||||
if (string.IsNullOrEmpty(typeName) || string.IsNullOrEmpty(methodName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var type = findType(typeName);
|
||||
if (type == null)
|
||||
return null;
|
||||
|
||||
var methodInfo = findStaticMethod(typeName, methodName);
|
||||
if (methodInfo == null)
|
||||
return null;
|
||||
|
||||
return (Action) Delegate.CreateDelegate(typeof(Action), methodInfo);
|
||||
}
|
||||
|
||||
public static void ClearStoredAction(string sessionStorageKey)
|
||||
{
|
||||
SessionState.EraseString(sessionStorageKey + ".Type");
|
||||
SessionState.EraseString(sessionStorageKey + ".Method");
|
||||
}
|
||||
|
||||
// Testing
|
||||
/*
|
||||
[DidReloadScripts]
|
||||
static void StartTest()
|
||||
{
|
||||
Debug.Log("CrossCompileCallbacks: Starting test.");
|
||||
RegisterCallback(testCallbackA);
|
||||
RegisterCallback(typeof(CrossCompileCallbacks), "testCallbackB");
|
||||
|
||||
var action = GetStoredAction("storedActionA");
|
||||
ClearStoredAction("storedActionA");
|
||||
if (action != null)
|
||||
action.Invoke();
|
||||
StoreAction("storedActionA", storedActionA);
|
||||
}
|
||||
|
||||
static void testCallbackA()
|
||||
{
|
||||
Debug.Log("Test callback A executed.");
|
||||
}
|
||||
|
||||
static void testCallbackB()
|
||||
{
|
||||
Debug.Log("Test callback B executed.");
|
||||
}
|
||||
|
||||
static void storedActionA()
|
||||
{
|
||||
Debug.Log("Stored action A executed.");
|
||||
}
|
||||
//*/
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa14d306c727c71409d46d6aa8335138
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.SceneManagement;
|
||||
#endif
|
||||
namespace Kamgam.UIToolkitBlurredBackground
|
||||
{
|
||||
public class Installer
|
||||
#if UNITY_EDITOR
|
||||
: IActiveBuildTargetChanged
|
||||
#endif
|
||||
{
|
||||
public const string AssetName = "UI Toolkit Blurred Background";
|
||||
public const string Version = "1.2.3";
|
||||
public const string Define = "KAMGAM_UI_TOOLKIT_BLURRED_BACKGROUND";
|
||||
public const string ManualUrl = "https://kamgam.com/unity/UIToolkitBlurredBackgroundManual.pdf";
|
||||
public const string AssetLink = "https://assetstore.unity.com/packages/slug/254328";
|
||||
|
||||
public static string _assetRootPathDefault = "Assets/Kamgam/UIToolkitBlurredBackground/";
|
||||
public static string AssetRootPath
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (System.IO.File.Exists(_assetRootPathDefault))
|
||||
{
|
||||
return _assetRootPathDefault;
|
||||
}
|
||||
|
||||
// The the tool was moved then search for the installer script and derive the root
|
||||
// path from there. Used Assets/ as ultimate fallback.
|
||||
string finalPath = "Assets/";
|
||||
string assetRootPathRelative = _assetRootPathDefault.Replace("Assets/", "");
|
||||
var installerGUIDS = AssetDatabase.FindAssets("t:Script Installer");
|
||||
foreach (var guid in installerGUIDS)
|
||||
{
|
||||
var path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (path.Contains(assetRootPathRelative))
|
||||
{
|
||||
int index = path.IndexOf(assetRootPathRelative);
|
||||
return path.Substring(0, index) + assetRootPathRelative;
|
||||
}
|
||||
}
|
||||
|
||||
return finalPath;
|
||||
#else
|
||||
return _assetRootPathDefault;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
public static string ExamplePath = AssetRootPath + "Examples/UIToolkitBlurredBackgroundDemo.unity";
|
||||
|
||||
public static Version GetVersion() => new Version(Version);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.Callbacks.DidReloadScripts(998001)]
|
||||
public static void InstallIfNeeded()
|
||||
{
|
||||
bool versionChanged = VersionHelper.UpgradeVersion(GetVersion, out Version oldVersion, out Version newVersion);
|
||||
if (versionChanged)
|
||||
{
|
||||
if (versionChanged)
|
||||
{
|
||||
Debug.Log(AssetName + " version changed from " + oldVersion + " to " + newVersion);
|
||||
|
||||
if (AddDefineSymbol())
|
||||
{
|
||||
CrossCompileCallbacks.RegisterCallback(onPostImport);
|
||||
}
|
||||
else
|
||||
{
|
||||
onPostImport();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
|
||||
{
|
||||
Logger.LogMessage($"Build target changed from {previousTarget} to {newTarget}. Refreshing define symbols.");
|
||||
AddDefineSymbol();
|
||||
}
|
||||
|
||||
[MenuItem("Tools/" + AssetName + "/Debug/Add Defines", priority = 501)]
|
||||
private static void AddDefineSymbolMenu()
|
||||
{
|
||||
AddDefineSymbol();
|
||||
}
|
||||
|
||||
private static bool AddDefineSymbol()
|
||||
{
|
||||
bool didChange = false;
|
||||
|
||||
foreach (BuildTargetGroup targetGroup in System.Enum.GetValues(typeof(BuildTargetGroup)))
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (targetGroup == BuildTargetGroup.Unknown || targetGroup == BuildTargetGroup.GameCoreScarlett)
|
||||
continue;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
try
|
||||
{
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
string currentDefineSymbols = PlayerSettings.GetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(targetGroup));
|
||||
#else
|
||||
string currentDefineSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup);
|
||||
#endif
|
||||
|
||||
if (currentDefineSymbols.Contains(Define))
|
||||
continue;
|
||||
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
PlayerSettings.SetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(targetGroup), currentDefineSymbols + ";" + Define);
|
||||
#else
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup, currentDefineSymbols + ";" + Define);
|
||||
#endif
|
||||
// Logger.LogMessage($"{Define} symbol has been added for {targetGroup}.");
|
||||
|
||||
didChange = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// There are many obsolete defines in the enum, skip them silently.
|
||||
}
|
||||
}
|
||||
|
||||
return didChange;
|
||||
}
|
||||
|
||||
[MenuItem("Tools/" + AssetName + "/Debug/Remove Defines", priority = 502)]
|
||||
private static void RemoveDefineSymbol()
|
||||
{
|
||||
foreach (BuildTargetGroup targetGroup in System.Enum.GetValues(typeof(BuildTargetGroup)))
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (targetGroup == BuildTargetGroup.Unknown || targetGroup == BuildTargetGroup.GameCoreScarlett)
|
||||
continue;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
try
|
||||
{
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
string currentDefineSymbols = PlayerSettings.GetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(targetGroup));
|
||||
#else
|
||||
string currentDefineSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup);
|
||||
#endif
|
||||
|
||||
if (currentDefineSymbols.Contains(Define))
|
||||
{
|
||||
currentDefineSymbols = currentDefineSymbols.Replace(";" + Define, "");
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
PlayerSettings.SetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(targetGroup), currentDefineSymbols);
|
||||
#else
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup, currentDefineSymbols);
|
||||
#endif
|
||||
Logger.LogMessage($"{Define} symbol has been removed for {targetGroup}.");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// There are many obsolete defines in the enum, skip them silently.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void onPostImport()
|
||||
{
|
||||
// Import packages and then show welcome screen.
|
||||
PackageImporter.ImportDelayed(showWelcomeMessage);
|
||||
}
|
||||
|
||||
static void showWelcomeMessage()
|
||||
{
|
||||
bool openExample = EditorUtility.DisplayDialog(
|
||||
AssetName,
|
||||
"Thank you for choosing " + AssetName + ".\n\n" +
|
||||
"Please start by reading the manual.\n\n" +
|
||||
"You'll find the asset options under Tools > UGUI Blurred Background > ...\n\n" +
|
||||
"It would be great if you could find the time to leave a review.\n\n" +
|
||||
"I have prepared some examples for you.",
|
||||
"Open Example", "Open manual (web)"
|
||||
);
|
||||
|
||||
if (openExample)
|
||||
OpenExample();
|
||||
else
|
||||
OpenManual();
|
||||
|
||||
UIToolkitBlurredBackgroundSettings.GetOrCreateSettings().AddShaderBeforeBuild = true;
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("Tools/" + AssetName + "/Manual", priority = 101)]
|
||||
public static void OpenManual()
|
||||
{
|
||||
Application.OpenURL(ManualUrl);
|
||||
}
|
||||
|
||||
[MenuItem("Tools/" + AssetName + "/Open Example Scene", priority = 103)]
|
||||
public static void OpenExample()
|
||||
{
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
var scene = AssetDatabase.LoadAssetAtPath<SceneAsset>(ExamplePath);
|
||||
EditorGUIUtility.PingObject(scene);
|
||||
EditorSceneManager.OpenScene(ExamplePath);
|
||||
};
|
||||
}
|
||||
|
||||
[MenuItem("Tools/" + AssetName + "/Please leave a review :-)", priority = 510)]
|
||||
public static void LeaveReview()
|
||||
{
|
||||
Application.OpenURL(AssetLink + "?aid=1100lqC54&pubref=asset");
|
||||
}
|
||||
|
||||
[MenuItem("Tools/" + AssetName + "/More Asset by KAMGAM", priority = 511)]
|
||||
public static void MoreAssets()
|
||||
{
|
||||
Application.OpenURL("https://assetstore.unity.com/publishers/37829?aid=1100lqC54&pubref=asset");
|
||||
}
|
||||
|
||||
[MenuItem("Tools/" + AssetName + "/Version " + Version, priority = 512)]
|
||||
public static void LogVersion()
|
||||
{
|
||||
Debug.Log(AssetName + " v" + Version);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0c8e1d2030d4f249a58791bb732838b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,78 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Kamgam.UIToolkitBlurredBackground
|
||||
{
|
||||
public class Logger
|
||||
{
|
||||
public delegate void LogCallback(string msg, LogLevel logLevel);
|
||||
|
||||
public const string Prefix = "UITK Blurred BG: ";
|
||||
public static LogLevel CurrentLogLevel = LogLevel.Warning;
|
||||
|
||||
/// <summary>
|
||||
/// Optional: leave as is or set to NULL to not use it.<br />
|
||||
/// Set this to a function which returns the log level (from settings for example).<br />
|
||||
/// This will be called before every log.
|
||||
/// <example>
|
||||
/// [RuntimeInitializeOnLoadMethod]
|
||||
/// private static void HookUpToLogger()
|
||||
/// {
|
||||
/// Logger.OnGetLogLevel = () => GetOrCreateSettings().LogLevel;
|
||||
/// }
|
||||
/// </example>
|
||||
/// </summary>
|
||||
public static System.Func<LogLevel> OnGetLogLevel = null;
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
Log = 0,
|
||||
Warning = 1,
|
||||
Error = 2,
|
||||
Message = 3,
|
||||
NoLogs = 99
|
||||
}
|
||||
|
||||
public static bool IsLogLevelVisible(LogLevel logLevel)
|
||||
{
|
||||
return (int)logLevel >= (int)CurrentLogLevel;
|
||||
}
|
||||
|
||||
public static void UpdateCurrentLogLevel()
|
||||
{
|
||||
if (OnGetLogLevel != null)
|
||||
{
|
||||
CurrentLogLevel = OnGetLogLevel();
|
||||
}
|
||||
}
|
||||
|
||||
const string changeHint = "\nYou can change the verbosity of logs in the Settings under Tools > UI Toolkit Blurred Background > Settings : LogLevel";
|
||||
|
||||
public static void Log(string message)
|
||||
{
|
||||
UpdateCurrentLogLevel();
|
||||
if(IsLogLevelVisible(LogLevel.Log))
|
||||
Debug.Log(Prefix + message + changeHint);
|
||||
}
|
||||
|
||||
public static void LogWarning(string message)
|
||||
{
|
||||
UpdateCurrentLogLevel();
|
||||
if (IsLogLevelVisible(LogLevel.Warning))
|
||||
Debug.LogWarning(Prefix + message + changeHint);
|
||||
}
|
||||
|
||||
public static void LogError(string message)
|
||||
{
|
||||
UpdateCurrentLogLevel();
|
||||
if (IsLogLevelVisible(LogLevel.Error))
|
||||
Debug.LogError(Prefix + message + changeHint);
|
||||
}
|
||||
|
||||
public static void LogMessage(string message)
|
||||
{
|
||||
UpdateCurrentLogLevel();
|
||||
if (IsLogLevelVisible(LogLevel.Message))
|
||||
Debug.Log(Prefix + message + changeHint);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e0bd73b28c8cc543bdc4b01080f358a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,268 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Kamgam.UIToolkitBlurredBackground
|
||||
{
|
||||
public static class PackageImporter
|
||||
{
|
||||
public enum RenderPiplelineType
|
||||
{
|
||||
URP = 0, HDRP = 1, BuiltIn = 2
|
||||
}
|
||||
|
||||
public enum PackageType
|
||||
{
|
||||
// match them 1:1 to RenderPiplelineType
|
||||
URP = 0, HDRP = 1, BuiltIn = 2
|
||||
}
|
||||
|
||||
private class Package
|
||||
{
|
||||
public PackageType PackageType;
|
||||
public string PackagePath;
|
||||
|
||||
public Package(PackageType packageType, string packagePath)
|
||||
{
|
||||
PackageType = packageType;
|
||||
PackagePath = packagePath;
|
||||
}
|
||||
}
|
||||
|
||||
static List<Package> Packages = new List<Package>()
|
||||
{
|
||||
new Package( PackageType.URP, "Assets/Kamgam/UIToolkitBlurredBackground/Packages/UITKBlurredBackgroundURP.unitypackage" ),
|
||||
new Package( PackageType.HDRP, "Assets/Kamgam/UIToolkitBlurredBackground/Packages/UITKBlurredBackgroundHDRP.unitypackage" )
|
||||
};
|
||||
|
||||
static Package getPackageFor(RenderPiplelineType renderPipeline)
|
||||
{
|
||||
foreach (var pkg in Packages)
|
||||
{
|
||||
if ((int)pkg.PackageType == (int)renderPipeline)
|
||||
return pkg;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Package getPackageFor(PackageType packageType)
|
||||
{
|
||||
foreach (var pkg in Packages)
|
||||
{
|
||||
if (pkg.PackageType == packageType)
|
||||
return pkg;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static System.Action _onComplete;
|
||||
|
||||
#region Start Import Delayed
|
||||
static double startPackageImportAt;
|
||||
|
||||
public static void ImportDelayed(System.Action onComplete)
|
||||
{
|
||||
// Some assets may not be loaded at this time. Thus we wait for them to be imported.
|
||||
_onComplete = onComplete;
|
||||
EditorApplication.update -= onEditorUpdate;
|
||||
EditorApplication.update += onEditorUpdate;
|
||||
startPackageImportAt = EditorApplication.timeSinceStartup + 3; // wait N seconds
|
||||
}
|
||||
|
||||
static void onEditorUpdate()
|
||||
{
|
||||
// wait for the time to reach startPackageImportAt
|
||||
if (startPackageImportAt - EditorApplication.timeSinceStartup < 0)
|
||||
{
|
||||
EditorApplication.update -= onEditorUpdate;
|
||||
ImportFixes();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
static int _crossCompileCallbackID = -1;
|
||||
|
||||
const string PackagesToImportKey = "Kamgam.SettingsGenerator.PackagesToImport";
|
||||
|
||||
[MenuItem("Tools/UI Toolkit Blurred Background/Debug/Import packages", priority = 500)]
|
||||
public static void ImportFixes()
|
||||
{
|
||||
// Don't import during play mode.
|
||||
if (EditorApplication.isPlaying)
|
||||
return;
|
||||
|
||||
Debug.Log("PackageImporter: Importing..");
|
||||
|
||||
var packagesToImport = initializePackagesToImport();
|
||||
startImportingNextPackage(packagesToImport);
|
||||
}
|
||||
|
||||
static List<PackageType> initializePackagesToImport()
|
||||
{
|
||||
var packages = new List<PackageType>();
|
||||
|
||||
// render pipeline packages
|
||||
var createdForRenderPipleline = RenderPiplelineType.BuiltIn;
|
||||
var currentRenderPipline = GetCurrentRenderPiplelineType();
|
||||
var package = getPackageFor(currentRenderPipline);
|
||||
if (package == null)
|
||||
{
|
||||
Debug.Log("PackageImporter: Render Pipline seems okay, no import needed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("PackageImporter: Scheduling upgrade from '" + createdForRenderPipleline.ToString() + "' to '" + currentRenderPipline.ToString() + "'.");
|
||||
packages.Add((PackageType)currentRenderPipline);
|
||||
}
|
||||
|
||||
setPackagesToImportList(packages);
|
||||
|
||||
if (packages.Count == 0)
|
||||
{
|
||||
onPackageImportDone(_onComplete);
|
||||
}
|
||||
|
||||
return packages;
|
||||
}
|
||||
|
||||
static void startImportingNextPackage(List<PackageType> packagesToImport)
|
||||
{
|
||||
if (packagesToImport.Count > 0)
|
||||
{
|
||||
var package = getPackageFor(packagesToImport[0]);
|
||||
removePackageToImportList(package.PackageType);
|
||||
startImportingPackage(package);
|
||||
}
|
||||
}
|
||||
|
||||
static void startImportingPackage(Package package)
|
||||
{
|
||||
// AssetDatabase.importPackageCompleted callbacks are lost after a recompile.
|
||||
// Therefore, if the package includes any scripts then these will not be called.
|
||||
// See: https://forum.unity.com/threads/assetdatabase-importpackage-callbacks-dont-work.544031/#post-3716791
|
||||
|
||||
// We use CrossCompileCallbacks to register a callback for after compilation.
|
||||
_crossCompileCallbackID = CrossCompileCallbacks.RegisterCallback(onPackageImportedAfterRecompile);
|
||||
// We also have to store the external callback (if there is one)
|
||||
CrossCompileCallbacks.StoreAction(typeof(PackageImporter).FullName + ".importedCallack", _onComplete);
|
||||
// Delay to avoid "Calling ... from assembly reloading callbacks are not supported." errors.
|
||||
CrossCompileCallbacks.DelayExecutionAfterCompilation = true;
|
||||
|
||||
// If the package does not contain any scripts the we can still use the normal callbacks.
|
||||
AssetDatabase.importPackageCompleted -= onPackageImported;
|
||||
AssetDatabase.importPackageCompleted += onPackageImported;
|
||||
|
||||
// import package
|
||||
Debug.Log("PackageImporter: Importing '" + package.PackagePath + "'.");
|
||||
AssetDatabase.ImportPackage(package.PackagePath, interactive: false);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
static void setPackagesToImportList(List<PackageType> packages)
|
||||
{
|
||||
var packagesAsInts = packages.Select(p => (int)p).ToArray();
|
||||
SessionState.SetIntArray(PackagesToImportKey, packagesAsInts);
|
||||
}
|
||||
|
||||
static List<PackageType> getPackagesToImportList()
|
||||
{
|
||||
var packagesAsInts = SessionState.GetIntArray(PackagesToImportKey, new int[] { });
|
||||
var packages = packagesAsInts.Select(p => (PackageType)p).ToList();
|
||||
return packages;
|
||||
}
|
||||
|
||||
static void removePackageToImportList(PackageType package)
|
||||
{
|
||||
var packages = getPackagesToImportList();
|
||||
packages.Remove(package);
|
||||
setPackagesToImportList(packages);
|
||||
}
|
||||
|
||||
// This is only execute if the package did not contain any script files.
|
||||
static void onPackageImported(string packageName)
|
||||
{
|
||||
Debug.Log("PackageImporter: Package '" + packageName + "' imported.");
|
||||
|
||||
// There was no recompile. Thus we clear the registered callback.
|
||||
CrossCompileCallbacks.ReleaseIndex(_crossCompileCallbackID);
|
||||
|
||||
// Check if it is one of our packages.
|
||||
// Abort if not.
|
||||
bool isFixerPackage = false;
|
||||
foreach (var pkg in Packages)
|
||||
{
|
||||
if (pkg.PackagePath.Contains(packageName))
|
||||
isFixerPackage = true;
|
||||
}
|
||||
if (!isFixerPackage)
|
||||
return;
|
||||
|
||||
AssetDatabase.importPackageCompleted -= onPackageImported;
|
||||
|
||||
onPackageImportDone(_onComplete);
|
||||
_onComplete = null;
|
||||
}
|
||||
|
||||
static void onPackageImportedAfterRecompile()
|
||||
{
|
||||
Debug.Log("PackageImporter: Recompile detected. Assuming package import is done.");
|
||||
|
||||
// The registered callback is already cleared by now.
|
||||
// Now we let's retrieve that stored extenal callback and hand it over.
|
||||
var onComplete = CrossCompileCallbacks.GetStoredAction(typeof(PackageImporter).FullName + ".importedCallack");
|
||||
onPackageImportDone(onComplete);
|
||||
}
|
||||
|
||||
static void onPackageImportDone(System.Action onComplete)
|
||||
{
|
||||
// Check for more packages to import
|
||||
Debug.Log("PackageImporter: package imported. Looking for next package.");
|
||||
|
||||
var packagesToImport = getPackagesToImportList();
|
||||
|
||||
if (packagesToImport.Count > 0)
|
||||
{
|
||||
// Make sure the onComplete callback is retained across multiple package loads.
|
||||
_onComplete = onComplete;
|
||||
|
||||
// Start importing
|
||||
startImportingNextPackage(packagesToImport);
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetDatabase.SaveAssets();
|
||||
onComplete?.Invoke();
|
||||
|
||||
Debug.Log("PackageImporter: Done (no more packages to import).");
|
||||
}
|
||||
}
|
||||
|
||||
public static RenderPiplelineType GetCurrentRenderPiplelineType()
|
||||
{
|
||||
var currentRP = GraphicsSettings.currentRenderPipeline;
|
||||
|
||||
// null if built-in
|
||||
if (currentRP != null)
|
||||
{
|
||||
if (currentRP.GetType().Name.Contains("Universal"))
|
||||
{
|
||||
return RenderPiplelineType.URP;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RenderPiplelineType.HDRP;
|
||||
}
|
||||
}
|
||||
|
||||
return RenderPiplelineType.BuiltIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f365eb8588ba4cf41bfbc9d123cf0739
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,80 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Kamgam.UIToolkitBlurredBackground
|
||||
{
|
||||
/// <summary>
|
||||
/// Since we do not add any objects directly referencing the materials/shaders we
|
||||
/// need to make sure the shaders are added to builds so they can be found at runtime.
|
||||
/// </summary>
|
||||
public static class SetupShaders
|
||||
{
|
||||
public class SetupShadersOnBuild : IPreprocessBuildWithReport
|
||||
{
|
||||
public int callbackOrder => int.MinValue + 10;
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
if (UIToolkitBlurredBackgroundSettings.GetOrCreateSettings().AddShaderBeforeBuild)
|
||||
SetupShaders.AddShaders();
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Tools/UI Toolkit Blurred Background/Debug/Add shaders to always included shader", priority = 401)]
|
||||
public static void AddShaders()
|
||||
{
|
||||
#if !KAMGAM_RENDER_PIPELINE_URP && !KAMGAM_RENDER_PIPELINE_HDRP
|
||||
// BuiltIn
|
||||
AddShaders(BlurredBackgroundBufferBuiltIn.ShaderName);
|
||||
#elif KAMGAM_RENDER_PIPELINE_URP
|
||||
// URP
|
||||
AddShaders(BlurredBackgroundPassURP.ShaderName);
|
||||
#else
|
||||
// HDRP
|
||||
AddShaders(BlurredBackgroundPassHDRP.ShaderName);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void AddShaders(string shaderName)
|
||||
{
|
||||
// Thanks to: https://forum.unity.com/threads/modify-always-included-shaders-with-pre-processor.509479/#post-3509413
|
||||
|
||||
var shader = Shader.Find(shaderName);
|
||||
if (shader == null)
|
||||
return;
|
||||
|
||||
var graphicsSettingsObj = AssetDatabase.LoadAssetAtPath<GraphicsSettings>("ProjectSettings/GraphicsSettings.asset");
|
||||
var serializedObject = new SerializedObject(graphicsSettingsObj);
|
||||
var arrayProp = serializedObject.FindProperty("m_AlwaysIncludedShaders");
|
||||
bool hasShader = false;
|
||||
for (int i = 0; i < arrayProp.arraySize; ++i)
|
||||
{
|
||||
var arrayElem = arrayProp.GetArrayElementAtIndex(i);
|
||||
if (shader == arrayElem.objectReferenceValue)
|
||||
{
|
||||
hasShader = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasShader)
|
||||
{
|
||||
int arrayIndex = arrayProp.arraySize;
|
||||
arrayProp.InsertArrayElementAtIndex(arrayIndex);
|
||||
var arrayElem = arrayProp.GetArrayElementAtIndex(arrayIndex);
|
||||
arrayElem.objectReferenceValue = shader;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
Debug.Log("Added the '"+ shaderName + "' shader to always included shaders (see Project Settings > Graphics). UI Toolkit Blurred Background requires it to render the blur. Hope that's okay.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd28bf476ff557e4ba94bcad28feaf45
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 254328
|
||||
packageName: UI Toolkit Blurred Background - Fast translucent background image
|
||||
packageVersion: 1.0.4
|
||||
assetPath: Assets/Kamgam/UIToolkitBlurredBackground/Runtime/Editor/Settings/SetupShaders.cs
|
||||
uploadId: 644498
|
@@ -0,0 +1,206 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.Compilation;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Kamgam.UIToolkitBlurredBackground
|
||||
{
|
||||
// Create a new type of Settings Asset.
|
||||
public class UIToolkitBlurredBackgroundSettings : ScriptableObject
|
||||
{
|
||||
public enum ShaderVariant { Performance, Gaussian };
|
||||
|
||||
public const string Version = "1.2.0";
|
||||
public const string SettingsFilePath = "Assets/UIToolkitBlurredBackgroundSettings.asset";
|
||||
|
||||
[SerializeField, Tooltip(_logLevelTooltip)]
|
||||
public Logger.LogLevel LogLevel;
|
||||
public const string _logLevelTooltip = "Any log above this log level will not be shown. To turn off all logs choose 'NoLogs'";
|
||||
|
||||
public const string _addShaderBeforeBuildTooltip = "Should the blur shader be added to the list of always included shaders before a build is started?\n\n" +
|
||||
"Disable only if you do not use any blurred images in your project but you still want to keep the asset around.";
|
||||
[Tooltip(_addShaderBeforeBuildTooltip)]
|
||||
public bool AddShaderBeforeBuild = true;
|
||||
|
||||
[RuntimeInitializeOnLoadMethod]
|
||||
static void bindLoggerLevelToSetting()
|
||||
{
|
||||
// Notice: This does not yet create a setting instance!
|
||||
Logger.OnGetLogLevel = () => GetOrCreateSettings().LogLevel;
|
||||
}
|
||||
|
||||
static UIToolkitBlurredBackgroundSettings cachedSettings;
|
||||
|
||||
public static UIToolkitBlurredBackgroundSettings GetOrCreateSettings()
|
||||
{
|
||||
if (cachedSettings == null)
|
||||
{
|
||||
string typeName = typeof(UIToolkitBlurredBackgroundSettings).Name;
|
||||
|
||||
cachedSettings = AssetDatabase.LoadAssetAtPath<UIToolkitBlurredBackgroundSettings>(SettingsFilePath);
|
||||
|
||||
// Still not found? Then search for it.
|
||||
if (cachedSettings == null)
|
||||
{
|
||||
string[] results = AssetDatabase.FindAssets("t:" + typeName);
|
||||
if (results.Length > 0)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(results[0]);
|
||||
cachedSettings = AssetDatabase.LoadAssetAtPath<UIToolkitBlurredBackgroundSettings>(path);
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedSettings != null)
|
||||
{
|
||||
SessionState.EraseBool(typeName + "WaitingForReload");
|
||||
}
|
||||
|
||||
// Still not found? Then create settings.
|
||||
if (cachedSettings == null)
|
||||
{
|
||||
// Are the settings waiting for a recompile to finish? If yes then return null;
|
||||
// This is important if an external script tries to access the settings before they
|
||||
// are deserialized after a re-compile.
|
||||
bool isWaitingForReloadAfterCompilation = SessionState.GetBool(typeName + "WaitingForReload", false);
|
||||
if (isWaitingForReloadAfterCompilation)
|
||||
{
|
||||
Debug.LogWarning(typeName + " is waiting for assembly reload.");
|
||||
return null;
|
||||
}
|
||||
|
||||
cachedSettings = ScriptableObject.CreateInstance<UIToolkitBlurredBackgroundSettings>();
|
||||
cachedSettings.LogLevel = Logger.LogLevel.Warning;
|
||||
cachedSettings.AddShaderBeforeBuild = true;
|
||||
|
||||
AssetDatabase.CreateAsset(cachedSettings, SettingsFilePath);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
Logger.OnGetLogLevel = () => cachedSettings.LogLevel;
|
||||
}
|
||||
}
|
||||
|
||||
return cachedSettings;
|
||||
}
|
||||
|
||||
internal static SerializedObject GetSerializedSettings()
|
||||
{
|
||||
return new SerializedObject(GetOrCreateSettings());
|
||||
}
|
||||
|
||||
[MenuItem("Tools/UI Toolkit Blurred Background/Settings", priority = 101)]
|
||||
public static void OpenSettings()
|
||||
{
|
||||
var settings = UIToolkitBlurredBackgroundSettings.GetOrCreateSettings();
|
||||
if (settings != null)
|
||||
{
|
||||
Selection.activeObject = settings;
|
||||
EditorGUIUtility.PingObject(settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", "UI Toolkit Blurred Background Settings could not be found or created.", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
EditorUtility.SetDirty(this);
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
AssetDatabase.SaveAssetIfDirty(this);
|
||||
#else
|
||||
AssetDatabase.SaveAssets();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(UIToolkitBlurredBackgroundSettings))]
|
||||
public class UIToolkitBlurredBackgroundSettingsEditor : Editor
|
||||
{
|
||||
public UIToolkitBlurredBackgroundSettings settings;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
settings = target as UIToolkitBlurredBackgroundSettings;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Version: " + UIToolkitBlurredBackgroundSettings.Version);
|
||||
base.OnInspectorGUI();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static class UIToolkitBlurredBackgroundSettingsProvider
|
||||
{
|
||||
[SettingsProvider]
|
||||
public static UnityEditor.SettingsProvider CreateUIToolkitBlurredBackgroundSettingsProvider()
|
||||
{
|
||||
var provider = new UnityEditor.SettingsProvider("Project/UI Toolkit Blurred Background", SettingsScope.Project)
|
||||
{
|
||||
label = "UI Toolkit Blurred Background",
|
||||
guiHandler = (searchContext) =>
|
||||
{
|
||||
var settings = UIToolkitBlurredBackgroundSettings.GetSerializedSettings();
|
||||
|
||||
var style = new GUIStyle(GUI.skin.label);
|
||||
style.wordWrap = true;
|
||||
|
||||
EditorGUILayout.LabelField("Version: " + UIToolkitBlurredBackgroundSettings.Version);
|
||||
if (drawButton(" Open Manual ", icon: "_Help"))
|
||||
{
|
||||
Installer.OpenManual();
|
||||
}
|
||||
|
||||
var settingsObj = settings.targetObject as UIToolkitBlurredBackgroundSettings;
|
||||
|
||||
drawField("LogLevel", "Log Level", UIToolkitBlurredBackgroundSettings._logLevelTooltip, settings, style);
|
||||
drawField("AddShaderBeforeBuild", "Add Shader Before Build", UIToolkitBlurredBackgroundSettings._addShaderBeforeBuildTooltip, settings, style);
|
||||
|
||||
settings.ApplyModifiedProperties();
|
||||
},
|
||||
|
||||
// Populate the search keywords to enable smart search filtering and label highlighting.
|
||||
keywords = new System.Collections.Generic.HashSet<string>(new[] { "shader", "triplanar", "rendering" })
|
||||
};
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
static void drawField(string propertyName, string label, string tooltip, SerializedObject settings, GUIStyle style)
|
||||
{
|
||||
EditorGUILayout.PropertyField(settings.FindProperty(propertyName), new GUIContent(label));
|
||||
if (!string.IsNullOrEmpty(tooltip))
|
||||
{
|
||||
GUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
GUILayout.Label(tooltip, style);
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
GUILayout.Space(10);
|
||||
}
|
||||
|
||||
static bool drawButton(string text, string tooltip = null, string icon = null, params GUILayoutOption[] options)
|
||||
{
|
||||
GUIContent content;
|
||||
|
||||
// icon
|
||||
if (!string.IsNullOrEmpty(icon))
|
||||
content = EditorGUIUtility.IconContent(icon);
|
||||
else
|
||||
content = new GUIContent();
|
||||
|
||||
// text
|
||||
content.text = text;
|
||||
|
||||
// tooltip
|
||||
if (!string.IsNullOrEmpty(tooltip))
|
||||
content.tooltip = tooltip;
|
||||
|
||||
return GUILayout.Button(content, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9535b8a7472136f4f82f99c6192cc973
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,173 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Kamgam.UIToolkitBlurredBackground
|
||||
{
|
||||
public static class VersionHelper
|
||||
{
|
||||
public static string VersionFileName = "." + typeof(VersionHelper).FullName + ".txt";
|
||||
public static Version DefaultVersion = new Version(0, 0, 0, 1);
|
||||
|
||||
public delegate bool UpgradeVersionDelegate(Version oldVersion, Version newVersion);
|
||||
|
||||
public static Version Parse(string version)
|
||||
{
|
||||
if (string.IsNullOrEmpty(version))
|
||||
return DefaultVersion;
|
||||
|
||||
if (Version.TryParse(version, out var versionObj))
|
||||
return versionObj;
|
||||
else
|
||||
return VersionHelper.DefaultVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns false if upgrading was not necessary, True otherwise.
|
||||
/// </summary>
|
||||
/// <param name="getVersionFunc">Change this to return the version of the software.<br />
|
||||
/// This is a separate method because your version may be stored in another class or a file.<br />
|
||||
/// The return value if this is compared against the install version marker.</param>
|
||||
/// <param name="upgradeVersionFunc">Use this to execute some custom code before upgrading
|
||||
/// the installed version info. If this returns false then the installed version will NOT be changed.</param>
|
||||
/// <returns></returns>
|
||||
public static bool UpgradeVersion(Func<Version> getVersionFunc, UpgradeVersionDelegate upgradeVersionFunc = null)
|
||||
{
|
||||
return UpgradeVersion(getVersionFunc, out _, out _, upgradeVersionFunc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns false if upgrading was not necessary, True otherwise.<br />
|
||||
/// Upgrades the version number only if the version info file path is valid. Otherwise it will abort.
|
||||
/// </summary>
|
||||
/// <param name="getVersionFunc">Change this to return the version of the software.<br />
|
||||
/// This is a separate method because your version may be stored in another class or a file.<br />
|
||||
/// The return value if this is compared against the install version marker.</param>
|
||||
/// <param name="oldVersion"></param>
|
||||
/// <param name="newVersion"></param>
|
||||
/// <param name="upgradeVersionFunc">Use this to execute some custom code before upgrading
|
||||
/// the installed version info. If this returns false then the installed version will NOT be changed.</param>
|
||||
/// <returns>Returns false if upgrading was not necessary (or impossible). Returns true if an upgrade is needed (and possible).</returns>
|
||||
public static bool UpgradeVersion(Func<Version> getVersionFunc, out Version oldVersion, out Version newVersion, UpgradeVersionDelegate upgradeVersionFunc = null)
|
||||
{
|
||||
oldVersion = GetInstalledVersion();
|
||||
newVersion = getVersionFunc();
|
||||
|
||||
// Abort upgrades if version info can not be retrieved.
|
||||
if (!VersionInfoPathIsValid())
|
||||
{
|
||||
// We abort if the dir is not found because we assume the
|
||||
// user has moved the asset and thus any upgrade attempts
|
||||
// will probably fail anyways.
|
||||
Logger.LogWarning(
|
||||
"Could not find version info directory: '" + getVersionFileDir() + "'. Aborting upgrade. Did you move the asset?\n" +
|
||||
"If you want auto-upgrades to work again then please restore the asset to the original directory (" + Installer.AssetRootPath + ").");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Notice: this also cover downgrades.
|
||||
if (oldVersion != newVersion)
|
||||
{
|
||||
if (upgradeVersionFunc != null)
|
||||
{
|
||||
bool upgradeSucceeded = upgradeVersionFunc(oldVersion, newVersion);
|
||||
if (upgradeSucceeded)
|
||||
SetInstalledVersion(newVersion);
|
||||
return upgradeSucceeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetInstalledVersion(newVersion);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool VersionInfoPathIsValid()
|
||||
{
|
||||
return System.IO.Directory.Exists(getVersionFileDir());
|
||||
}
|
||||
|
||||
public static void SetInstalledVersion(Version version)
|
||||
{
|
||||
if (version == null)
|
||||
return;
|
||||
|
||||
if (!VersionInfoPathIsValid())
|
||||
return;
|
||||
|
||||
string versionString = version.ToString();
|
||||
string filePath = getVersionFilePath();
|
||||
string tmpPath = filePath + ".tmp";
|
||||
|
||||
if (File.Exists(tmpPath))
|
||||
{
|
||||
File.Delete(tmpPath);
|
||||
}
|
||||
|
||||
File.WriteAllText(tmpPath, versionString);
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
File.Delete(filePath);
|
||||
}
|
||||
|
||||
File.Move(tmpPath, filePath);
|
||||
}
|
||||
|
||||
public static Version GetInstalledVersion()
|
||||
{
|
||||
string filePath = getVersionFilePath();
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return DefaultVersion;
|
||||
}
|
||||
|
||||
string version = File.ReadAllText(filePath);
|
||||
return Parse(version);
|
||||
}
|
||||
|
||||
static string getVersionFilePath()
|
||||
{
|
||||
string dir = getVersionFileDir();
|
||||
return dir + VersionFileName;
|
||||
}
|
||||
|
||||
static string getVersionFileDir()
|
||||
{
|
||||
string dir = Installer.AssetRootPath.Trim();
|
||||
|
||||
// fix empty dir path
|
||||
if (string.IsNullOrEmpty(dir))
|
||||
{
|
||||
dir = "Assets/";
|
||||
}
|
||||
|
||||
// Fix missing ending slash
|
||||
if (!dir.EndsWith("/") && !dir.EndsWith("\\"))
|
||||
{
|
||||
dir = dir + "/";
|
||||
}
|
||||
|
||||
return getBasePath() + dir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the path to project root (the parent dir of Assets).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
static string getBasePath()
|
||||
{
|
||||
// Unity Editor: <path to project folder>/Assets
|
||||
// See: https://docs.unity3d.com/ScriptReference/Application-dataPath.html
|
||||
string basePath = Application.dataPath.Replace("/Assets", "/");
|
||||
basePath = basePath.Replace("\\Assets", "\\");
|
||||
return basePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f7fae563c3916c40a7026d274ee36e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user