From 2c784ff34305b9daa3ccbf04fd235d7792e405e6 Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Sun, 31 Aug 2025 19:42:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=B8=8A=E7=9A=84=E6=BC=8F=E6=B4=9E=E4=B8=8E?= =?UTF-8?q?=E9=A2=84=E5=88=B6=E4=BD=93=E4=B8=8A=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WindowsPlugins/Hierarchy Variant.prefab | 12 + Convention/[Runtime]/Config.cs | 17 +- Convention/[Runtime]/Math.cs | 584 ++++++++++++++++++ Convention/[Runtime]/Math.cs.meta | 11 + .../Variant/HierarchyWindow/HierarchyItem.cs | 10 +- .../UIComponent/Variant/PropertiesWindow.cs | 15 +- 6 files changed, 638 insertions(+), 11 deletions(-) create mode 100644 Convention/[Runtime]/Math.cs create mode 100644 Convention/[Runtime]/Math.cs.meta diff --git a/Convention/Resources/WindowsPlugins/Hierarchy Variant.prefab b/Convention/Resources/WindowsPlugins/Hierarchy Variant.prefab index 04dfaf9..a1708d3 100644 --- a/Convention/Resources/WindowsPlugins/Hierarchy Variant.prefab +++ b/Convention/Resources/WindowsPlugins/Hierarchy Variant.prefab @@ -327,6 +327,18 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: + - target: {fileID: 860861549860063477, guid: 14851ab435cb18448974bf76e92d8952, type: 3} + propertyPath: m_AllContextPlane.Array.size + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 860861549860063477, guid: 14851ab435cb18448974bf76e92d8952, type: 3} + propertyPath: m_AllContextPlane.Array.data[0].root + value: + objectReference: {fileID: 8975345697986449064} + - target: {fileID: 860861549860063477, guid: 14851ab435cb18448974bf76e92d8952, type: 3} + propertyPath: m_AllContextPlane.Array.data[0].plane + value: + objectReference: {fileID: 8975345697986449064} - target: {fileID: 2372686227554923148, guid: 14851ab435cb18448974bf76e92d8952, type: 3} propertyPath: m_AnchorMax.y value: 0 diff --git a/Convention/[Runtime]/Config.cs b/Convention/[Runtime]/Config.cs index 9b122d7..ac1e454 100644 --- a/Convention/[Runtime]/Config.cs +++ b/Convention/[Runtime]/Config.cs @@ -435,6 +435,21 @@ namespace Convention throw new InvalidCastException($"\"{str}\" is cannt convert to type<{type}>"); } + + public static object ConventValue([In] Type type, [In] string str) + { + var parse_method = type.GetMethod("Parse"); + if (parse_method != null && + (parse_method.ReturnType.IsSubclassOf(type) || parse_method.ReturnType == type) && + parse_method.GetParameters().Length == 1 && + parse_method.GetParameters()[0].ParameterType == typeof(string)) + { + return parse_method.Invoke(null, new object[] { str }); + } + + throw new InvalidCastException($"\"{str}\" is cannt convert to type<{type}>"); + } + public static string Combine([In] params object[] args) { if (args.Length == 0) @@ -1463,7 +1478,7 @@ namespace Convention } public static void AdjustSizeToContainsChilds([In] RectTransform rectTransform, Vector2 min, Vector2 max, RectTransform.Axis? axis) { - if (IsDisableAdjustSizeToContainsChilds2DeferUpdates) + if (IsDisableAdjustSizeToContainsChilds2DeferUpdates) return; LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform); diff --git a/Convention/[Runtime]/Math.cs b/Convention/[Runtime]/Math.cs new file mode 100644 index 0000000..1a5939c --- /dev/null +++ b/Convention/[Runtime]/Math.cs @@ -0,0 +1,584 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +#if UNITY_URP +using static Unity.Mathematics.math; +#endif +using static Convention.MathExtension; + +namespace Convention +{ + public static partial class MathExtension + { + #region EaseCurve + + public static AnimationCurve MakeAnimationCurve(EaseCurveType type, float start, float end, float startValue, float endValue, int keyCount) + { + var curve = new AnimationCurve(); + curve.keys = new Keyframe[keyCount]; + for (int i = 0; i < keyCount; i++) + { + float t = i / (float)(keyCount - 1); + curve.keys[i] = new Keyframe( + Mathf.Lerp(start, end, t), + Mathf.Lerp(startValue, endValue, Evaluate(t, type)) + ); + } + return curve; + } + public enum EaseCurveType + { + Linear = 0, + InQuad = 1, + OutQuad = 2, + InOutQuad = 3, + InCubic = 4, + OutCubic = 5, + InOutCubic = 6, + InQuart = 7, + OutQuart = 8, + InOutQuart = 9, + InQuint = 10, + OutQuint = 11, + InOutQuint = 12, + InSine = 13, + OutSine = 14, + InOutSine = 15, + InExpo = 16, + OutExpo = 17, + InOutExpo = 18, + InCirc = 19, + OutCirc = 20, + InOutCirc = 21, + InBounce = 22, + OutBounce = 23, + InOutBounce = 24, + InElastic = 25, + OutElastic = 26, + InOutElastic = 27, + InBack = 28, + OutBack = 29, + InOutBack = 30, + Custom = 31 + } + + public static float Evaluate(float t, EaseCurveType curveType) + { + float from = 0; + float to = 1; + + return curveType switch + { + EaseCurveType.Linear => Linear(from, to, t), + EaseCurveType.InQuad => InQuad(from, to, t), + EaseCurveType.OutQuad => OutQuad(from, to, t), + EaseCurveType.InOutQuad => InOutQuad(from, to, t), + EaseCurveType.InCubic => InCubic(from, to, t), + EaseCurveType.OutCubic => OutCubic(from, to, t), + EaseCurveType.InOutCubic => InOutCubic(from, to, t), + EaseCurveType.InQuart => InQuart(from, to, t), + EaseCurveType.OutQuart => OutQuart(from, to, t), + EaseCurveType.InOutQuart => InOutQuart(from, to, t), + EaseCurveType.InQuint => InQuint(from, to, t), + EaseCurveType.OutQuint => OutQuint(from, to, t), + EaseCurveType.InOutQuint => InOutQuint(from, to, t), + EaseCurveType.InSine => InSine(from, to, t), + EaseCurveType.OutSine => OutSine(from, to, t), + EaseCurveType.InOutSine => InOutSine(from, to, t), + EaseCurveType.InExpo => InExpo(from, to, t), + EaseCurveType.OutExpo => OutExpo(from, to, t), + EaseCurveType.InOutExpo => InOutExpo(from, to, t), + EaseCurveType.InCirc => InCirc(from, to, t), + EaseCurveType.OutCirc => OutCirc(from, to, t), + EaseCurveType.InOutCirc => InOutCirc(from, to, t), + EaseCurveType.InBounce => InBounce(from, to, t), + EaseCurveType.OutBounce => OutBounce(from, to, t), + EaseCurveType.InOutBounce => InOutBounce(from, to, t), + EaseCurveType.InElastic => InElastic(from, to, t), + EaseCurveType.OutElastic => OutElastic(from, to, t), + EaseCurveType.InOutElastic => InOutElastic(from, to, t), + EaseCurveType.InBack => InBack(from, to, t), + EaseCurveType.OutBack => OutBack(from, to, t), + EaseCurveType.InOutBack => InOutBack(from, to, t), + _ => throw new NotImplementedException() + }; + } + + public static float Linear(float from, float to, float t) + { + float c = to - from; + t /= 1f; + return c * t / 1f + from; + } + + public static float InQuad(float from, float to, float t) + { + float c = to - from; + t /= 1f; + return c * t * t + from; + } + + public static float OutQuad(float from, float to, float t) + { + float c = to - from; + t /= 1f; + return -c * t * (t - 2f) + from; + } + + public static float InOutQuad(float from, float to, float t) + { + float c = to - from; + t /= 0.5f; + if (t < 1) return c / 2f * t * t + from; + t--; + return -c / 2f * (t * (t - 2) - 1) + from; + } + + public static float InCubic(float from, float to, float t) + { + float c = to - from; + t /= 1f; + return c * t * t * t + from; + } + + public static float OutCubic(float from, float to, float t) + { + float c = to - from; + t /= 1f; + t--; + return c * (t * t * t + 1) + from; + } + + public static float InOutCubic(float from, float to, float t) + { + float c = to - from; + t /= 0.5f; + if (t < 1) return c / 2f * t * t * t + from; + t -= 2; + return c / 2f * (t * t * t + 2) + from; + } + + public static float InQuart(float from, float to, float t) + { + float c = to - from; + t /= 1f; + return c * t * t * t * t + from; + } + + public static float OutQuart(float from, float to, float t) + { + float c = to - from; + t /= 1f; + t--; + return -c * (t * t * t * t - 1) + from; + } + + public static float InOutQuart(float from, float to, float t) + { + float c = to - from; + t /= 0.5f; + if (t < 1) return c / 2f * t * t * t * t + from; + t -= 2; + return -c / 2f * (t * t * t * t - 2) + from; + } + + public static float InQuint(float from, float to, float t) + { + float c = to - from; + t /= 1f; + return c * t * t * t * t * t + from; + } + + public static float OutQuint(float from, float to, float t) + { + float c = to - from; + t /= 1f; + t--; + return c * (t * t * t * t * t + 1) + from; + } + + public static float InOutQuint(float from, float to, float t) + { + float c = to - from; + t /= 0.5f; + if (t < 1) return c / 2f * t * t * t * t * t + from; + t -= 2; + return c / 2f * (t * t * t * t * t + 2) + from; + } + + public static float InSine(float from, float to, float t) + { + float c = to - from; + return -c * Mathf.Cos(t / 1f * (Mathf.PI / 2f)) + c + from; + } + + public static float OutSine(float from, float to, float t) + { + float c = to - from; + return c * Mathf.Sin(t / 1f * (Mathf.PI / 2f)) + from; + } + + public static float InOutSine(float from, float to, float t) + { + float c = to - from; + return -c / 2f * (Mathf.Cos(Mathf.PI * t / 1f) - 1) + from; + } + + public static float InExpo(float from, float to, float t) + { + float c = to - from; + return c * Mathf.Pow(2, 10 * (t / 1f - 1)) + from; + } + + public static float OutExpo(float from, float to, float t) + { + float c = to - from; + return c * (-Mathf.Pow(2, -10 * t / 1f) + 1) + from; + } + + public static float InOutExpo(float from, float to, float t) + { + float c = to - from; + t /= 0.5f; + if (t < 1f) return c / 2f * Mathf.Pow(2, 10 * (t - 1)) + from; + t--; + return c / 2f * (-Mathf.Pow(2, -10 * t) + 2) + from; + } + + public static float InCirc(float from, float to, float t) + { + float c = to - from; + t /= 1f; + return -c * (Mathf.Sqrt(1 - t * t) - 1) + from; + } + + public static float OutCirc(float from, float to, float t) + { + float c = to - from; + t /= 1f; + t--; + return c * Mathf.Sqrt(1 - t * t) + from; + } + + public static float InOutCirc(float from, float to, float t) + { + float c = to - from; + t /= 0.5f; + if (t < 1) return -c / 2f * (Mathf.Sqrt(1 - t * t) - 1) + from; + t -= 2; + return c / 2f * (Mathf.Sqrt(1 - t * t) + 1) + from; + } + + public static float InBounce(float from, float to, float t) + { + float c = to - from; + return c - OutBounce(0f, c, 1f - t) + from; //does this work? + } + + public static float OutBounce(float from, float to, float t) + { + float c = to - from; + + if ((t /= 1f) < (1 / 2.75f)) + { + return c * (7.5625f * t * t) + from; + } + else if (t < (2 / 2.75f)) + { + return c * (7.5625f * (t -= (1.5f / 2.75f)) * t + .75f) + from; + } + else if (t < (2.5 / 2.75)) + { + return c * (7.5625f * (t -= (2.25f / 2.75f)) * t + .9375f) + from; + } + else + { + return c * (7.5625f * (t -= (2.625f / 2.75f)) * t + .984375f) + from; + } + } + + public static float InOutBounce(float from, float to, float t) + { + float c = to - from; + if (t < 0.5f) return InBounce(0, c, t * 2f) * 0.5f + from; + return OutBounce(0, c, t * 2 - 1) * 0.5f + c * 0.5f + from; + + } + + public static float InElastic(float from, float to, float t) + { + float c = to - from; + if (t == 0) return from; + if ((t /= 1f) == 1) return from + c; + float p = 0.3f; + float s = p / 4f; + return -(c * Mathf.Pow(2, 10 * (t -= 1)) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p)) + from; + } + + public static float OutElastic(float from, float to, float t) + { + float c = to - from; + if (t == 0) return from; + if ((t /= 1f) == 1) return from + c; + float p = 0.3f; + float s = p / 4f; + return (c * Mathf.Pow(2, -10 * t) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p) + c + from); + } + + public static float InOutElastic(float from, float to, float t) + { + float c = to - from; + if (t == 0) return from; + if ((t /= 0.5f) == 2) return from + c; + float p = 0.3f * 1.5f; + float s = p / 4f; + if (t < 1) + return -0.5f * (c * Mathf.Pow(2, 10 * (t -= 1f)) * Mathf.Sin((t - 2) * (2 * Mathf.PI) / p)) + from; + return c * Mathf.Pow(2, -10 * (t -= 1)) * Mathf.Sin((t - s) * (2f * Mathf.PI) / p) * 0.5f + c + from; + } + + public static float InBack(float from, float to, float t) + { + float c = to - from; + float s = 1.70158f; + t /= 0.5f; + return c * t * t * ((s + 1) * t - s) + from; + } + + public static float OutBack(float from, float to, float t) + { + float c = to - from; + float s = 1.70158f; + t = t / 1f - 1f; + return c * (t * t * ((s + 1) * t + s) + 1) + from; + } + + public static float InOutBack(float from, float to, float t) + { + float c = to - from; + float s = 1.70158f; + t /= 0.5f; + if (t < 1) return c / 2f * (t * t * (((s *= (1.525f)) + 1) * t - s)) + from; + t -= 2; + return c / 2f * (t * t * (((s *= (1.525f)) + 1) * t + s) + 2) + from; + } + + #endregion + + #region DataFilter + + public interface IBaseFilter<_Type> + { + _Type[][] Filtrate(_Type[][] source, int width, int length); + void FiltrateSource(_Type[][] source, int width, int length); + } + + public interface ITreeFilter<_Type, _NextFilter> : IBaseFilter<_Type> where _NextFilter : IBaseFilter<_Type> + { + _Type[][] Filtrate(_Type[][] source, int width, int length, _NextFilter next); + } + + public abstract class AbstractFilter : IBaseFilter + { + protected abstract void DoFiltrate(float[][] source, float[][] result, int width, int length); + + public float[][] Filtrate(float[][] source, int width, int length) + { + float[][] result = new float[width][]; + for (int i = 0; i < width; i++) + { + result[i] = new float[length]; + } + DoFiltrate(source, result, width, length); + return result; + } + + public void FiltrateSource(float[][] source, int width, int length) + { + DoFiltrate(source, source, width, length); + } + } + + public abstract class AbstractColorFilter : IBaseFilter + { + protected abstract void DoFiltrate(Color[][] source, Color[][] result, int width, int length); + + public Color[][] Filtrate(Color[][] source, int width, int length) + { + Color[][] result = new Color[width][]; + for (int i = 0; i < width; i++) + { + result[i] = new Color[length]; + } + DoFiltrate(source, result, width, length); + return result; + } + + public void FiltrateSource(Color[][] source, int width, int length) + { + DoFiltrate(source, source, width, length); + } + } + + [Serializable] + public class TemplateLimitFilter : AbstractFilter + { + public float min; + public float max; + public float maxEnhance; + public float maxWeakened; + public int bufferSize; + + private float[][] buffer; + private int header = 0; + + public TemplateLimitFilter(float min, float max, float maxEnhance, float maxWeakened, int bufferSize) + { + this.min = min; + this.max = max; + this.maxEnhance = maxEnhance; + this.maxWeakened = maxWeakened; + this.bufferSize = bufferSize; + } + + protected override void DoFiltrate(float[][] source, float[][] result, int width, int length) + { + InitBuffer(source, result, width, length); + for (int i = 0; i < width; i++) + { + ReadLine(source, result, i, width, length); + BuildLine(source, result, i, width, length); + } + ClearBuffer(); + } + + protected virtual void InitBuffer(float[][] source, float[][] result, int width, int length) + { + buffer ??= new float[bufferSize][]; + for (int i = 0; i < buffer.Length; i++) + { + buffer[i] = new float[length]; + if (i < width) + for (int j = 0; j < length; j++) + { + buffer[i][j] = source[i][j]; + } + } + } + + protected virtual void ClearBuffer() + { + for (int i = 0; i < buffer.Length; i++) + { + buffer[i] = null; + } + } + + protected virtual void ReadLine(float[][] source, float[][] result, int offset, int width, int length) + { + //Move data to buffer + for (int i = 0, e = length; i < e; i++) + { + buffer[header][i] = source[offset][i]; + } + //Push buffer header + header = (header + 1) % bufferSize; + } + + protected virtual void BuildLine(float[][] source, float[][] result, int offset, int width, int length) + { + int tempHeader = header; + float[] line = new float[length]; + do + { + //Mark data + for (int i = 0; i < length; i++) + { + float value = buffer[tempHeader][i]; + int j = (tempHeader - 1) % bufferSize; + if (j < 0) + j = bufferSize + j; + float lastValue = buffer[j][i]; + line[i] = Mathf.Clamp(Mathf.Clamp(value, lastValue - maxWeakened, lastValue + maxEnhance), min, max); + } + //Push buffer header + tempHeader = (tempHeader + 1) % bufferSize; + } + while (tempHeader != header); + for (int i = 0; i < length; i++) + { + result[offset][i] = line[i]; + } + } + } + + [Serializable] + public class TemplateColorLimitFilter : AbstractColorFilter + { + public Color min; + public Color max; + public Color maxEnhance; + public Color maxWeakened; + + public TemplateColorLimitFilter(Color min, Color max, Color maxEnhance, Color maxWeakened) + { + this.min = min; + this.max = max; + this.maxEnhance = maxEnhance; + this.maxWeakened = maxWeakened; + } + + protected override void DoFiltrate(Color[][] source, Color[][] result, int width, int length) + { + for (int i = 1; i < width; i++) + { + BuildLine(source, result, i, width, length); + } + } + + protected virtual void BuildLine(Color[][] source, Color[][] result, int offset, int width, int length) + { + Color[] line = new Color[length]; + //Mark data + for (int i = 0; i < length; i++) + { + int j = (offset - 1) % source.Length; + Color value = source[j][i]; + Color lastValue = source[offset][i]; + line[i] = new(BuildColorR(value, lastValue), + BuildColorG(value, lastValue), + BuildColorB(value, lastValue), + BuildColorA(value, lastValue)); + } + for (int i = 0; i < length; i++) + { + result[offset][i] = line[i]; + } + } + + protected float BuildColorA(Color value, Color lastValue) + { + return Mathf.Clamp(Mathf.Clamp(value.a, lastValue.a - maxWeakened.a, lastValue.a + maxEnhance.a), min.a, max.a); + } + + protected float BuildColorR(Color value, Color lastValue) + { + return Mathf.Clamp(Mathf.Clamp(value.r, lastValue.r - maxWeakened.r, lastValue.r + maxEnhance.r), min.r, max.r); + } + + protected float BuildColorG(Color value, Color lastValue) + { + return Mathf.Clamp(Mathf.Clamp(value.g, lastValue.g - maxWeakened.g, lastValue.g + maxEnhance.g), min.g, max.g); + } + + protected float BuildColorB(Color value, Color lastValue) + { + return Mathf.Clamp(Mathf.Clamp(value.b, lastValue.b - maxWeakened.b, lastValue.b + maxEnhance.b), min.b, max.b); + } + } + + #endregion + } +} + diff --git a/Convention/[Runtime]/Math.cs.meta b/Convention/[Runtime]/Math.cs.meta new file mode 100644 index 0000000..0ac21c7 --- /dev/null +++ b/Convention/[Runtime]/Math.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53c6be54f26ac234d9734eee0cd11766 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Convention/[Visual]/UIComponent/Variant/HierarchyWindow/HierarchyItem.cs b/Convention/[Visual]/UIComponent/Variant/HierarchyWindow/HierarchyItem.cs index a87a58e..885f4b3 100644 --- a/Convention/[Visual]/UIComponent/Variant/HierarchyWindow/HierarchyItem.cs +++ b/Convention/[Visual]/UIComponent/Variant/HierarchyWindow/HierarchyItem.cs @@ -43,7 +43,7 @@ namespace Convention.WindowsUI.Variant } private void OnDestroy() { - if (InspectorWindow.instance.GetTarget() == target) + if (InspectorWindow.instance != null && InspectorWindow.instance.GetTarget() == target) { InspectorWindow.instance.ClearWindow(); } @@ -64,11 +64,13 @@ namespace Convention.WindowsUI.Variant [Content] public void OnFocusHierarchyItem() { - if (target == null) + if (target != null) { - throw new InvalidOperationException("target is null"); + if (InspectorWindow.instance != null) + { + InspectorWindow.instance.SetTarget(target, this); + } } - InspectorWindow.instance.SetTarget(target, this); if (!IsEnableFocusWindow) return; if (FocusWindowIndictaor.instance != null) diff --git a/Convention/[Visual]/UIComponent/Variant/PropertiesWindow.cs b/Convention/[Visual]/UIComponent/Variant/PropertiesWindow.cs index 4c22a0d..0101d5c 100644 --- a/Convention/[Visual]/UIComponent/Variant/PropertiesWindow.cs +++ b/Convention/[Visual]/UIComponent/Variant/PropertiesWindow.cs @@ -313,8 +313,12 @@ namespace Convention.WindowsUI.Variant } static IEnumerator Adjuster2(RectTransform rectTransform, ItemEntry parentEntry) { + if (rectTransform == null) + yield break; LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform); yield return null; + if (rectTransform == null) + yield break; RectTransformExtension.AdjustSizeToContainsChilds(rectTransform); yield return null; parentEntry.ForceRebuildLayoutImmediate(); @@ -364,6 +368,8 @@ namespace Convention.WindowsUI.Variant ForceRebuildLayoutImmediate(); } + public bool IsRemovingChilds { get; private set; } = false; + public void Release() { if ((parentWindow == null && parentEntry == null) || childs == null || rootWindow == null) @@ -376,21 +382,18 @@ namespace Convention.WindowsUI.Variant ref_value.gameObject.SetActive(false); Destroy(ref_value.gameObject); } + IsRemovingChilds = true; foreach (var item in childs) { item.Release(); } + IsRemovingChilds = false; if (parentWindow != null) parentWindow.m_Entrys.Remove(this); - else + else if (GetParent().IsRemovingChilds == false) parentEntry.childs.Remove(this); ref_value = null; } - - ~ItemEntry() - { - Release(); - } } public interface IItemEntry {