Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 2ba1c94b88
commit ee9aee0a1b
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
using System;
using System.Globalization;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace LeTai.Asset.TranslucentImage.Editor
{
public class EditorProperty
{
public readonly SerializedProperty serializedProperty;
readonly SerializedObject serializedObject;
readonly MethodInfo propertySetter;
readonly SerializedProperty dirtyFlag;
public EditorProperty(SerializedObject obj, string name)
{
var propertyName = char.ToLowerInvariant(name[0]) + name.Substring(1);
serializedObject = obj;
serializedProperty = serializedObject.FindProperty(propertyName);
propertySetter = serializedObject.targetObject.GetType().GetProperty(name).SetMethod;
dirtyFlag = serializedObject.FindProperty("modifiedFromInspector");
}
public void Draw(params GUILayoutOption[] options)
{
using (var scope = new EditorGUI.ChangeCheckScope())
{
EditorGUILayout.PropertyField(serializedProperty, options);
if (!scope.changed)
return;
if (dirtyFlag != null)
dirtyFlag.boolValue = true;
serializedObject.ApplyModifiedProperties();
foreach (var target in serializedObject.targetObjects)
{
switch (serializedProperty.propertyType)
{
case SerializedPropertyType.ObjectReference:
propertySetter.Invoke(target, new object[] { serializedProperty.objectReferenceValue });
break;
case SerializedPropertyType.Float:
propertySetter.Invoke(target, new object[] { serializedProperty.floatValue });
break;
case SerializedPropertyType.Integer:
propertySetter.Invoke(target, new object[] { serializedProperty.intValue });
break;
case SerializedPropertyType.Rect:
propertySetter.Invoke(target, new object[] { serializedProperty.rectValue });
break;
case SerializedPropertyType.Enum:
propertySetter.Invoke(target, new object[] { serializedProperty.enumValueIndex });
break;
case SerializedPropertyType.Boolean:
propertySetter.Invoke(target, new object[] { serializedProperty.boolValue });
break;
case SerializedPropertyType.Color:
propertySetter.Invoke(target, new object[] { serializedProperty.colorValue });
break;
case SerializedPropertyType.Generic:
// Not needed for now
break;
default: throw new NotImplementedException($"Type {serializedProperty.propertyType} is not implemented");
}
}
serializedObject.Update();
}
}
}
}

View File

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

View File

@@ -0,0 +1,24 @@
{
"name": "LeTai.TranslucentImage.Editor",
"rootNamespace": "",
"references": [
"LeTai.TranslucentImage"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.render-pipelines.universal",
"expression": "12",
"define": "URP12_OR_NEWER"
}
],
"noEngineReferences": false
}

View File

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

View File

@@ -0,0 +1,175 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace LeTai.Asset.TranslucentImage.Editor
{
public class MenuIntegration : MonoBehaviour
{
[MenuItem("GameObject/UI/Translucent Image", false, 3)]
static void CreateTranslucentImage(MenuCommand menuCommand)
{
// Create a custom game object
GameObject go = new GameObject("Translucent Image");
go.AddComponent<TranslucentImage>();
PlaceUIElementRoot(go, menuCommand);
}
[MenuItem("CONTEXT/Image/Convert to Translucent Image", false, 3)]
static void ConvertToTranslucentImage(MenuCommand menuCommand)
{
var image = (Image) menuCommand.context;
var go = image.gameObject;
Undo.DestroyObjectImmediate(image);
var ti = Undo.AddComponent<TranslucentImage>(go);
ti.sprite = image.sprite;
var color = image.color;
ti.color = new Color(color.r, color.g, color.b,
1); // sprite blending should be used instead of alpha most of the time
ti.raycastTarget = image.raycastTarget;
ti.type = image.type;
ti.useSpriteMesh = image.useSpriteMesh;
ti.preserveAspect = image.preserveAspect;
ti.fillCenter = image.fillCenter;
ti.fillMethod = image.fillMethod;
ti.fillOrigin = image.fillOrigin;
ti.fillAmount = image.fillAmount;
ti.fillClockwise = image.fillClockwise;
}
#region PlaceUIElementRoot
static void PlaceUIElementRoot(GameObject element, MenuCommand menuCommand)
{
GameObject parent = menuCommand.context as GameObject;
if (parent == null || parent.GetComponentInParent<Canvas>() == null)
{
parent = GetOrCreateCanvasGameObject();
}
string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent.transform, element.name);
element.name = uniqueName;
Undo.RegisterCreatedObjectUndo(element, "Create " + element.name);
Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name);
GameObjectUtility.SetParentAndAlign(element, parent);
if (parent != menuCommand.context) // not a context click, so center in sceneview
SetPositionVisibleinSceneView(
parent.GetComponent<RectTransform>(),
element.GetComponent<RectTransform>());
Selection.activeGameObject = element;
}
// Helper function that returns a Canvas GameObject; preferably a parent of the selection, or other existing Canvas.
public static GameObject GetOrCreateCanvasGameObject()
{
GameObject selectedGo = Selection.activeGameObject;
// Try to find a gameobject that is the selected GO or one if its parents.
Canvas canvas = (selectedGo != null) ? selectedGo.GetComponentInParent<Canvas>() : null;
if (canvas != null && canvas.gameObject.activeInHierarchy)
return canvas.gameObject;
// No canvas in selection or its parents? Then use just any canvas..
canvas = Shims.FindObjectOfType<Canvas>();
if (canvas != null && canvas.gameObject.activeInHierarchy)
return canvas.gameObject;
// No canvas in the scene at all? Then create a new one.
return CreateNewUI();
}
public static GameObject CreateNewUI()
{
// Root for the UI
var root = new GameObject("Canvas") {layer = LayerMask.NameToLayer("UI")};
Canvas canvas = root.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
root.AddComponent<CanvasScaler>();
root.AddComponent<GraphicRaycaster>();
Undo.RegisterCreatedObjectUndo(root, "Create " + root.name);
// if there is no event system add one...
CreateEventSystem(false);
return root;
}
static void CreateEventSystem(bool select, GameObject parent = null)
{
var esys = Shims.FindObjectOfType<EventSystem>();
if (esys == null)
{
var eventSystem = new GameObject("EventSystem");
GameObjectUtility.SetParentAndAlign(eventSystem, parent);
esys = eventSystem.AddComponent<EventSystem>();
eventSystem.AddComponent<StandaloneInputModule>();
Undo.RegisterCreatedObjectUndo(eventSystem, "Create " + eventSystem.name);
}
if (select && esys != null)
{
Selection.activeGameObject = esys.gameObject;
}
}
static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform)
{
// Find the best scene view
SceneView sceneView = SceneView.lastActiveSceneView;
if (sceneView == null && SceneView.sceneViews.Count > 0)
sceneView = SceneView.sceneViews[0] as SceneView;
// Couldn't find a SceneView. Don't set position.
if (sceneView == null || sceneView.camera == null)
return;
// Create world space Plane from canvas position.
Vector2 localPlanePosition;
Camera camera = sceneView.camera;
Vector3 position = Vector3.zero;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvasRTransform,
new Vector2(camera.pixelWidth / 2, camera.pixelHeight / 2),
camera,
out localPlanePosition))
{
// Adjust for canvas pivot
localPlanePosition.x = localPlanePosition.x + canvasRTransform.sizeDelta.x * canvasRTransform.pivot.x;
localPlanePosition.y = localPlanePosition.y + canvasRTransform.sizeDelta.y * canvasRTransform.pivot.y;
localPlanePosition.x = Mathf.Clamp(localPlanePosition.x, 0, canvasRTransform.sizeDelta.x);
localPlanePosition.y = Mathf.Clamp(localPlanePosition.y, 0, canvasRTransform.sizeDelta.y);
// Adjust for anchoring
position.x = localPlanePosition.x - canvasRTransform.sizeDelta.x * itemTransform.anchorMin.x;
position.y = localPlanePosition.y - canvasRTransform.sizeDelta.y * itemTransform.anchorMin.y;
Vector3 minLocalPosition;
minLocalPosition.x = canvasRTransform.sizeDelta.x * (0 - canvasRTransform.pivot.x) +
itemTransform.sizeDelta.x * itemTransform.pivot.x;
minLocalPosition.y = canvasRTransform.sizeDelta.y * (0 - canvasRTransform.pivot.y) +
itemTransform.sizeDelta.y * itemTransform.pivot.y;
Vector3 maxLocalPosition;
maxLocalPosition.x = canvasRTransform.sizeDelta.x * (1 - canvasRTransform.pivot.x) -
itemTransform.sizeDelta.x * itemTransform.pivot.x;
maxLocalPosition.y = canvasRTransform.sizeDelta.y * (1 - canvasRTransform.pivot.y) -
itemTransform.sizeDelta.y * itemTransform.pivot.y;
position.x = Mathf.Clamp(position.x, minLocalPosition.x, maxLocalPosition.x);
position.y = Mathf.Clamp(position.y, minLocalPosition.y, maxLocalPosition.y);
}
itemTransform.anchoredPosition = position;
itemTransform.localRotation = Quaternion.identity;
itemTransform.localScale = Vector3.one;
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 99feb6419b119464aa5a3ad6549ea73c
timeCreated: 1539852386
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: c2fc80b7e20a4104db1297bcddfd83b5
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 4bc9a290ca74e434499699e3db41c3f9
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 0764cd30e065b7340891d9f7f680a12f
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,111 @@
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
namespace LeTai.Asset.TranslucentImage.Editor
{
[CustomEditor(typeof(ScalableBlurConfig))]
[CanEditMultipleObjects]
public class ScalableBlurConfigEditor : UnityEditor.Editor
{
readonly AnimBool useAdvancedControl = new AnimBool(false);
int tab, previousTab;
EditorProperty radius;
EditorProperty iteration;
EditorProperty strength;
public void Awake()
{
LoadTabSelection();
useAdvancedControl.value = tab > 0;
}
public void OnEnable()
{
radius = new EditorProperty(serializedObject, nameof(ScalableBlurConfig.Radius));
iteration = new EditorProperty(serializedObject, nameof(ScalableBlurConfig.Iteration));
strength = new EditorProperty(serializedObject, nameof(ScalableBlurConfig.Strength));
// Without this editor will not Repaint automatically when animating
useAdvancedControl.valueChanged.AddListener(Repaint);
}
public override void OnInspectorGUI()
{
Draw();
}
public void Draw()
{
using (new EditorGUILayout.VerticalScope())
{
DrawTabBar();
using (var changes = new EditorGUI.ChangeCheckScope())
{
serializedObject.Update();
DrawTabsContent();
if (changes.changed) serializedObject.ApplyModifiedProperties();
}
}
}
void DrawTabBar()
{
using (var h = new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
tab = GUILayout.Toolbar(
tab,
new[] { "Simple", "Advanced" },
GUILayout.MinWidth(0),
GUILayout.MaxWidth(EditorGUIUtility.pixelsPerPoint * 192)
);
GUILayout.FlexibleSpace();
}
if (tab != previousTab)
{
GUI.FocusControl(""); // Defocus
SaveTabSelection();
previousTab = tab;
}
useAdvancedControl.target = tab == 1;
}
void DrawTabsContent()
{
if (EditorGUILayout.BeginFadeGroup(1 - useAdvancedControl.faded))
{
// EditorProperty dooesn't invoke getter. Not needed anywhere else.
_ = ((ScalableBlurConfig)target).Strength;
strength.Draw();
}
EditorGUILayout.EndFadeGroup();
if (EditorGUILayout.BeginFadeGroup(useAdvancedControl.faded))
{
radius.Draw();
iteration.Draw();
}
EditorGUILayout.EndFadeGroup();
}
//Persist selected tab between sessions and instances
void SaveTabSelection()
{
EditorPrefs.SetInt("LETAI_TRANSLUCENTIMAGE_TIS_TAB", tab);
}
void LoadTabSelection()
{
if (EditorPrefs.HasKey("LETAI_TRANSLUCENTIMAGE_TIS_TAB"))
tab = EditorPrefs.GetInt("LETAI_TRANSLUCENTIMAGE_TIS_TAB");
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 771a13bc1eb042bc9d4ad186dd99dda5
timeCreated: 1560160054

View File

@@ -0,0 +1,55 @@
using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
namespace LeTai.Asset.TranslucentImage.Editor
{
class ScenceGizmoAutoDisable : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
if (!importedAssets.Any(p => p.Contains("TranslucentImage")))
return;
var structAnnotation = Type.GetType("UnityEditor.Annotation, UnityEditor");
if (structAnnotation == null) return;
var fieldClassId = structAnnotation.GetField("classID");
var fieldScriptClass = structAnnotation.GetField("scriptClass");
var fieldFlags = structAnnotation.GetField("flags");
var fieldIconEnabled = structAnnotation.GetField("iconEnabled");
Type classAnnotationUtility = Type.GetType("UnityEditor.AnnotationUtility, UnityEditor");
if (classAnnotationUtility == null) return;
var methodGetAnnotations = classAnnotationUtility.GetMethod("GetAnnotations", BindingFlags.NonPublic | BindingFlags.Static);
if (methodGetAnnotations == null) return;
var methodSetIconEnabled = classAnnotationUtility.GetMethod("SetIconEnabled", BindingFlags.NonPublic | BindingFlags.Static);
if (methodSetIconEnabled == null) return;
Array annotations = (Array)methodGetAnnotations.Invoke(null, null);
foreach (var a in annotations)
{
string scriptClass = (string)fieldScriptClass.GetValue(a);
// built in types
if (string.IsNullOrEmpty(scriptClass)) continue;
int classId = (int)fieldClassId.GetValue(a);
int flags = (int)fieldFlags.GetValue(a);
int iconEnabled = (int)fieldIconEnabled.GetValue(a);
const int maskHasIcon = 1;
bool hasIconFlag = (flags & maskHasIcon) == maskHasIcon;
if (hasIconFlag
&& iconEnabled != 0
&& scriptClass.Contains("TranslucentImage"))
{
methodSetIconEnabled.Invoke(null, new object[] { classId, scriptClass, 0 });
}
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d3c5df780c45454e820502d48a07db97
timeCreated: 1575814101

View File

@@ -0,0 +1,151 @@
using System.Linq;
using UnityEditor;
using UnityEditor.UI;
using UnityEngine;
using Debug = System.Diagnostics.Debug;
namespace LeTai.Asset.TranslucentImage.Editor
{
[CustomEditor(typeof(TranslucentImage))]
[CanEditMultipleObjects]
public class TranslucentImageEditor : ImageEditor
{
SerializedProperty spriteBlending;
SerializedProperty source;
SerializedProperty vibrancy;
SerializedProperty brightness;
SerializedProperty flatten;
bool materialUsedInDifferentSource;
bool usingIncorrectShader;
Shader correctShader;
protected override void OnEnable()
{
base.OnEnable();
source = serializedObject.FindProperty("source");
spriteBlending = serializedObject.FindProperty("m_spriteBlending");
vibrancy = serializedObject.FindProperty("vibrancy");
brightness = serializedObject.FindProperty("brightness");
flatten = serializedObject.FindProperty("flatten");
correctShader = Shader.Find("UI/TranslucentImage");
var self = serializedObject.targetObject as TranslucentImage;
if (self)
{
CheckMaterialUsedInDifferentSource(self);
CheckCorrectShader(self);
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
var ti = serializedObject.targetObject as TranslucentImage;
Debug.Assert(ti != null, "Translucent Image Editor serializedObject target is null");
var oldSource = ti.source;
var oldMaterial = ti.material;
base.OnInspectorGUI();
if (usingIncorrectShader)
{
EditorGUILayout.HelpBox("Material should use shader UI/Translucent Image",
MessageType.Error);
}
serializedObject.Update();
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.PropertyField(source);
if (source.objectReferenceValue == null)
{
var existingSources = Shims.FindObjectsOfType<TranslucentImageSource>();
if (existingSources.Length > 0)
{
using (new EditorGUI.IndentLevelScope())
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.PrefixLabel("From current Scene");
using (new EditorGUILayout.VerticalScope())
foreach (var s in existingSources)
{
if (GUILayout.Button(s.gameObject.name))
source.objectReferenceValue = s;
}
}
EditorGUILayout.Space();
}
else
{
EditorGUILayout.HelpBox("No Translucent Image Source(s) found in current scene", MessageType.Warning);
}
}
if (materialUsedInDifferentSource)
{
EditorGUILayout.HelpBox("Translucent Images with different Sources" +
" should also use different Materials",
MessageType.Error);
}
EditorGUILayout.PropertyField(spriteBlending);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Shared settings", EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.PropertyField(vibrancy);
EditorGUILayout.PropertyField(brightness);
EditorGUILayout.PropertyField(flatten);
serializedObject.ApplyModifiedProperties();
if (ti.source != oldSource)
OnSourceChanged(ti);
if (ti.material != oldMaterial)
OnMaterialChanged(ti);
}
void OnSourceChanged(TranslucentImage self)
{
CheckMaterialUsedInDifferentSource(self);
}
void OnMaterialChanged(TranslucentImage self)
{
CheckMaterialUsedInDifferentSource(self);
CheckCorrectShader(self);
}
private void CheckCorrectShader(TranslucentImage self)
{
usingIncorrectShader = self.material.shader != correctShader;
}
private void CheckMaterialUsedInDifferentSource(TranslucentImage self)
{
if (!self.source)
{
materialUsedInDifferentSource = false;
return;
}
var diffSource = Shims.FindObjectsOfType<TranslucentImage>()
.Where(ti => ti.source != self.source)
.ToList();
if (!diffSource.Any())
{
materialUsedInDifferentSource = false;
return;
}
var sameMat = diffSource.GroupBy(ti => ti.material).ToList();
materialUsedInDifferentSource = sameMat.All(group => group.Key == self.material);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9a6952d1e37a4f0458848a0e61378de5
timeCreated: 1539852386
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,83 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace LeTai.Asset.TranslucentImage.Editor
{
[CustomEditor(typeof(TranslucentImageSource))]
[CanEditMultipleObjects]
public class TranslucentImageSourceEditor : UnityEditor.Editor
{
UnityEditor.Editor configEditor;
EditorProperty blurConfig;
EditorProperty downsample;
EditorProperty blurRegion;
EditorProperty maxUpdateRate;
EditorProperty backgroundFill;
EditorProperty preview;
ScalableBlurConfigEditor ConfigEditor
{
get
{
if (configEditor == null)
{
var config = ((TranslucentImageSource)target).BlurConfig;
if (config != null)
configEditor = CreateEditor(config);
}
return (ScalableBlurConfigEditor)configEditor;
}
}
void OnEnable()
{
blurConfig = new EditorProperty(serializedObject, nameof(TranslucentImageSource.BlurConfig));
downsample = new EditorProperty(serializedObject, nameof(TranslucentImageSource.Downsample));
blurRegion = new EditorProperty(serializedObject, nameof(TranslucentImageSource.BlurRegion));
maxUpdateRate = new EditorProperty(serializedObject, nameof(TranslucentImageSource.MaxUpdateRate));
backgroundFill = new EditorProperty(serializedObject, nameof(TranslucentImageSource.BackgroundFill));
preview = new EditorProperty(serializedObject, nameof(TranslucentImageSource.Preview));
}
public override void OnInspectorGUI()
{
EditorGUILayout.Space();
blurConfig.Draw();
var curConfig = (ScalableBlurConfig)blurConfig.serializedProperty.objectReferenceValue;
if (!curConfig)
{
EditorGUILayout.HelpBox("Missing Blur Config", MessageType.Warning);
if (GUILayout.Button("New Blur Config File"))
{
ScalableBlurConfig newConfig = CreateInstance<ScalableBlurConfig>();
var path = AssetDatabase.GenerateUniqueAssetPath(
$"Assets/{SceneManager.GetActiveScene().name} {serializedObject.targetObject.name} Blur Config.asset");
AssetDatabase.CreateAsset(newConfig, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorGUIUtility.PingObject(newConfig);
blurConfig.serializedProperty.objectReferenceValue = newConfig;
}
}
else
{
ConfigEditor.Draw();
}
EditorGUILayout.Space();
downsample.Draw();
blurRegion.Draw();
maxUpdateRate.Draw();
backgroundFill.Draw();
preview.Draw();
if (GUI.changed) serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ec905d5b1e2c40f40b5cdd580f727f3e
timeCreated: 1539852387
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
#if UNITY_2019
using System.IO;
using UnityEditor;
using UnityEngine;
namespace LeTai.Asset.TranslucentImage.Editor
{
public class Unity2019ShaderCompilerBugWorkaround : ScriptableObject
{
[MenuItem("Tools/Translucent Image/Fix Shader Compile Errors")]
static void ReImport()
{
var guids = AssetDatabase.FindAssets("l:TranslucentImageEditorResources lib");
var path = AssetDatabase.GUIDToAssetPath(guids[0]);
var text = File.ReadAllText(path);
File.WriteAllText(path, text + "//DELETE ME: Workaround shader not compiling in Unity 2019");
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
File.WriteAllText(path, text);
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
}
}
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cb015e0abde84fd19af30c2bb2847361
timeCreated: 1624351629