From 6d70945827f8f01b13a17920d4fe0b016574fc73 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Tue, 9 Sep 2025 18:57:04 +0000 Subject: [PATCH 01/26] Mirror com.unity.ugui package (Unity 6000.3.0b2) --- .../HorizontalOrVerticalLayoutGroupEditor.cs | 14 +++-- .../AssertionFailureOnOutputVertexCount.cs | 2 +- ...ValidPositionsWhenCameraOrthoSizeIsZero.cs | 2 +- .../UGUI/Canvas/CanvasUseReflectionProbes.cs | 39 -------------- .../Canvas/CanvasUseReflectionProbes.cs.meta | 2 - ...vasWidthAssertionErrorWithRectTransform.cs | 2 +- .../Editor/UGUI/Canvas/RootCanvasTests.cs | 52 +------------------ ...ilerAddMarkerWithNullObjectDoesNotCrash.cs | 2 +- .../ChangingHierarchyOfCanvasRenderer.cs | 2 +- .../UGUI/CanvasRenderer/ParentCanvasIsSane.cs | 2 +- .../Dropdown/DropdownOptionsListDrawer.cs | 4 +- .../EventTriggerRemoveDuringExecution.cs | 2 +- .../UGUI/EventSystem/InputModuleTests.cs | 4 +- .../InterceptedEventsPreviewTests.cs | 2 +- .../InputField/CharacterLimitValidation.cs | 2 +- .../UGUI/InputField/ContentValidation.cs | 2 +- .../UGUI/RectMask2D/RectMask2DCulling.cs | 2 +- .../UGUI/RectMask2D/RectTransformPosition.cs | 2 +- .../UGUI/Slider/SliderRectReferences.cs | 2 +- .../Tests/Editor/UGUI/TestBehaviourBase.cs | 2 +- .../Editor/UGUI/Text/FontCreatedByScript.cs | 2 +- .../UI/PropertyDrawers/PropertyDrawerTests.cs | 2 +- .../UGUI/UnityEvent/UnityEventInvoke.cs | 2 +- .../Tests/Editor/UGUI/WrapperWindowFixture.cs | 4 +- .../Tests/Runtime/UGUI/Button/ButtonTests.cs | 2 +- .../Canvas/BridgeScriptForRetainingObjects.cs | 2 +- .../UGUI/Canvas/CanvasGroupInheritedAlpha.cs | 2 +- .../CanvasResizeCorrectlyForRenderTexture.cs | 2 +- ...asScalerWithChildTextObjectDoesNotCrash.cs | 2 +- .../CanvasSizeCorrectInAwakeAndStart.cs | 2 +- .../CanvasSizeCorrectInAwakeAndStartScript.cs | 2 +- .../Canvas/CheckMeshColorsAndColors32Match.cs | 2 +- .../CoroutineWorksIfUIObjectIsAttached.cs | 6 +-- .../Tests/Runtime/UGUI/Canvas/NestedCanvas.cs | 2 +- .../NestedCanvasMaintainsCorrectSize.cs | 2 +- ...NoActiveCameraInSceneDoesNotCrashEditor.cs | 2 +- .../RectMask2DReparentedToDifferentCanvas.cs | 2 +- ...NestedCanvasCullsUsingCorrectCanvasRect.cs | 2 +- .../Canvas/RectTransformValidAfterEnable.cs | 2 +- .../RectangleContainsScreenPointTest.cs | 2 +- .../UGUI/Canvas/SiblingOrderChangesLayout.cs | 2 +- .../CanvasRenderer/CanvasRendererTests.cs | 2 +- .../Runtime/UGUI/Dropdown/DropdownTests.cs | 2 +- .../UGUI/EventSystem/GraphicRaycasterTests.cs | 2 +- .../GraphicRaycasterWorldSpaceCanvasTests.cs | 2 +- .../UGUI/EventSystem/InputModuleTests.cs | 2 +- .../InputModuleTests/DragCallbackCheck.cs | 2 +- .../InputModuleTests/FakeBaseInput.cs | 2 +- .../InputModuleTests/MouseUpdate.cs | 2 +- .../PointerClickCallbackCheck.cs | 2 +- .../PointerEnterCallbackCheck.cs | 2 +- .../PointerExitCallbackCheck.cs | 2 +- .../EventSystem/Physics2DRaycasterTests.cs | 2 +- .../UGUI/EventSystem/PhysicsRaycasterTests.cs | 2 +- .../UGUI/EventSystem/RaycastSortingTests.cs | 2 +- .../Tests/Runtime/UGUI/Graphic/ImageTests.cs | 2 +- .../Runtime/UGUI/Graphic/RawImageTest.cs | 2 +- .../Runtime/UGUI/Graphic/RawImageTestHook.cs | 2 +- .../UGUI/Graphic/ToggleTestImageHook.cs | 2 +- .../UGUI/Image/ImageFilledGenerateWork.cs | 2 +- .../Tests/Runtime/UGUI/Image/ImageTests.cs | 2 +- .../Tests/Runtime/UGUI/Image/TestableImage.cs | 2 +- .../UGUI/InputField/DesktopInputFieldTests.cs | 2 +- .../UGUI/InputField/FakeInputModule.cs | 2 +- .../UGUI/InputField/GenericInputFieldTests.cs | 2 +- .../UGUI/InputField/InputFieldTests.cs | 2 +- .../UGUI/InputField/TouchInputFieldTests.cs | 2 +- .../UGUI/Layout/HorizonalLayoutGroupTests.cs | 2 +- .../Runtime/UGUI/Layout/LayoutGroupScaling.cs | 2 +- .../UGUI/Layout/VerticalLayoutGroupTests.cs | 2 +- .../LayoutGroup/LayoutGroupArrangement.cs | 2 +- .../UGUI/MaskClipping/RectMask2DClipping.cs | 2 +- ...SceneWithNestedLayoutElementsLoadScript.cs | 2 +- .../SceneWithNestedLayoutElementsLoads.cs | 2 +- .../Runtime/UGUI/ScrollBar/ScrollBarClamp.cs | 2 +- .../Runtime/UGUI/ScrollBar/ScrollBarTests.cs | 2 +- .../UGUI/ScrollRect/ScrollRectClamp.cs | 2 +- .../UGUI/ScrollRect/ScrollRectScale.cs | 2 +- .../UGUI/ScrollRect/ScrollRectStableLayout.cs | 2 +- .../UGUI/ScrollRect/ScrollRectTests.cs | 2 +- .../Tests/Runtime/UGUI/Slider/SliderTests.cs | 2 +- .../TextEditor/TextEditorBackspaceDelete.cs | 2 +- .../UGUI/TextEditor/TextEditorTests.cs | 2 +- .../Runtime/UGUI/Util/ConcreteGraphic.cs | 2 +- .../Tests/Runtime/UGUI/Util/ImageHook.cs | 2 +- .../UGUI/Util/UIBehaviourExtensions.cs | 10 ++-- 86 files changed, 98 insertions(+), 191 deletions(-) delete mode 100644 com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasUseReflectionProbes.cs delete mode 100644 com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasUseReflectionProbes.cs.meta diff --git a/com.unity.ugui/Editor/UGUI/UI/HorizontalOrVerticalLayoutGroupEditor.cs b/com.unity.ugui/Editor/UGUI/UI/HorizontalOrVerticalLayoutGroupEditor.cs index 40b2a6b..0ec8a22 100644 --- a/com.unity.ugui/Editor/UGUI/UI/HorizontalOrVerticalLayoutGroupEditor.cs +++ b/com.unity.ugui/Editor/UGUI/UI/HorizontalOrVerticalLayoutGroupEditor.cs @@ -41,17 +41,15 @@ protected virtual void OnEnable() public override void OnInspectorGUI() { serializedObject.Update(); - EditorGUIUtility.labelWidth = 130; EditorGUILayout.PropertyField(m_Padding, true); EditorGUILayout.PropertyField(m_Spacing, true); EditorGUILayout.PropertyField(m_ChildAlignment, true); EditorGUILayout.PropertyField(m_ReverseArrangement, true); - EditorGUIUtility.labelWidth = 0; Rect rect = EditorGUILayout.GetControlRect(); rect = EditorGUI.PrefixLabel(rect, -1, EditorGUIUtility.TrTextContent("Control Child Size")); - rect.width = Mathf.Max(60, (rect.width - 4) / 3); - EditorGUIUtility.labelWidth = 60; + rect.width = Mathf.Max(50, (rect.width - 4) / 3); + EditorGUIUtility.labelWidth = 50; ToggleLeft(rect, m_ChildControlWidth, EditorGUIUtility.TrTextContent("Width")); rect.x += rect.width + 2; ToggleLeft(rect, m_ChildControlHeight, EditorGUIUtility.TrTextContent("Height")); @@ -59,8 +57,8 @@ public override void OnInspectorGUI() rect = EditorGUILayout.GetControlRect(); rect = EditorGUI.PrefixLabel(rect, -1, EditorGUIUtility.TrTextContent("Use Child Scale")); - rect.width = Mathf.Max(60, (rect.width - 4) / 3); - EditorGUIUtility.labelWidth = 60; + rect.width = Mathf.Max(50, (rect.width - 4) / 3); + EditorGUIUtility.labelWidth = 50; ToggleLeft(rect, m_ChildScaleWidth, EditorGUIUtility.TrTextContent("Width")); rect.x += rect.width + 2; ToggleLeft(rect, m_ChildScaleHeight, EditorGUIUtility.TrTextContent("Height")); @@ -68,8 +66,8 @@ public override void OnInspectorGUI() rect = EditorGUILayout.GetControlRect(); rect = EditorGUI.PrefixLabel(rect, -1, EditorGUIUtility.TrTextContent("Child Force Expand")); - rect.width = Mathf.Max(60, (rect.width - 4) / 3); - EditorGUIUtility.labelWidth = 60; + rect.width = Mathf.Max(50, (rect.width - 4) / 3); + EditorGUIUtility.labelWidth = 50; ToggleLeft(rect, m_ChildForceExpandWidth, EditorGUIUtility.TrTextContent("Width")); rect.x += rect.width + 2; ToggleLeft(rect, m_ChildForceExpandHeight, EditorGUIUtility.TrTextContent("Height")); diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/AssertionFailureOnOutputVertexCount.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/AssertionFailureOnOutputVertexCount.cs index c90e366..225cd45 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/AssertionFailureOnOutputVertexCount.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/AssertionFailureOnOutputVertexCount.cs @@ -5,7 +5,7 @@ using UnityEditor.SceneManagement; using UnityEditor; -internal class AssertionFailureOnOutputVertexCount +public class AssertionFailureOnOutputVertexCount { const string scenePath = "Assets/AssertionFailureOnOutputVertexCountTestScene.unity"; [Test] diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero.cs index c5c09d8..01cbf1e 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero.cs @@ -4,7 +4,7 @@ using UnityEngine.TestTools; using UnityEngine.UI; -internal class CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero +public class CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero { GameObject image; GameObject canvas; diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasUseReflectionProbes.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasUseReflectionProbes.cs deleted file mode 100644 index 3b8e904..0000000 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasUseReflectionProbes.cs +++ /dev/null @@ -1,39 +0,0 @@ -using NUnit.Framework; -using UnityEngine; - -[Category("Canvas")] -internal class CanvasUseReflectionProbes : TestBehaviourBase -{ - [Test] - public void OnlyWorldSpaceCanvasCanUseReflectionProbes() - { - m_TestObject.useReflectionProbes = true; - - m_TestObject.renderMode = RenderMode.ScreenSpaceOverlay; - Assert.False(m_TestObject.useReflectionProbes); - - m_TestObject.renderMode = RenderMode.ScreenSpaceCamera; - Assert.False(m_TestObject.useReflectionProbes); - - m_TestObject.renderMode = RenderMode.WorldSpace; - Assert.True(m_TestObject.useReflectionProbes); - } - - [Test] - public void ProvidesNormals() - { - var dummyChannels = AdditionalCanvasShaderChannels.TexCoord1 | AdditionalCanvasShaderChannels.Tangent; - - m_TestObject.renderMode = RenderMode.WorldSpace; - m_TestObject.additionalShaderChannels = dummyChannels; - - m_TestObject.useReflectionProbes = false; - Assert.AreEqual(m_TestObject.additionalShaderChannels, dummyChannels); - - m_TestObject.useReflectionProbes = true; - Assert.AreEqual(m_TestObject.additionalShaderChannels, dummyChannels | AdditionalCanvasShaderChannels.Normal); - - m_TestObject.useReflectionProbes = false; - Assert.AreEqual(m_TestObject.additionalShaderChannels, dummyChannels); - } -} diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasUseReflectionProbes.cs.meta b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasUseReflectionProbes.cs.meta deleted file mode 100644 index 9408581..0000000 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasUseReflectionProbes.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 3cbc4280d63720c448a3c6fee4b1ec88 \ No newline at end of file diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasWidthAssertionErrorWithRectTransform.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasWidthAssertionErrorWithRectTransform.cs index bccca46..5adf200 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasWidthAssertionErrorWithRectTransform.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasWidthAssertionErrorWithRectTransform.cs @@ -5,7 +5,7 @@ [TestFixture] [Category("RegressionTest")] [Description("CoveredBugID = 913932")] -internal class CanvasWidthAssertionErrorWithRectTransform +public class CanvasWidthAssertionErrorWithRectTransform { GameObject m_CanvasMaster; GameObject m_CanvasChild; diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/RootCanvasTests.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/RootCanvasTests.cs index 3306e25..8263845 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/RootCanvasTests.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/RootCanvasTests.cs @@ -3,7 +3,7 @@ using UnityEngine.UI; [Category("Canvas")] -internal class RootCanvasTests : TestBehaviourBase +public class RootCanvasTests : TestBehaviourBase { // A simple nested canvas hierarchy // m_TestObject @@ -78,54 +78,4 @@ public void ChildOfDisabledCanvasCantReceiveClicks() Assert.IsTrue(raycasts.Count == 0); } - - [Test] - public void ChildrenInheritRootCanvasReflectionProbeProperties() - { - m_TestObject.useReflectionProbes = true; - m_TestObject.renderMode = RenderMode.WorldSpace; - - // rootCanvasChild inherits properties from root - Assert.AreEqual( - rootCanvasChild.useReflectionProbes, - m_TestObject.useReflectionProbes); - Assert.AreEqual( - rootCanvasChild.additionalShaderChannels & AdditionalCanvasShaderChannels.Normal, - m_TestObject.additionalShaderChannels & AdditionalCanvasShaderChannels.Normal); - - // baseCanvas inherits properties from root - Assert.AreEqual( - baseCanvas.useReflectionProbes, - m_TestObject.useReflectionProbes); - Assert.AreEqual( - baseCanvas.additionalShaderChannels & AdditionalCanvasShaderChannels.Normal, - m_TestObject.additionalShaderChannels & AdditionalCanvasShaderChannels.Normal); - } - - [Test] - public void CannotOverrideRootCanvasReflectionProbeProperties() - { - m_TestObject.useReflectionProbes = true; - m_TestObject.renderMode = RenderMode.WorldSpace; - - rootCanvasChild.useReflectionProbes = false; - rootCanvasChild.renderMode = RenderMode.ScreenSpaceOverlay; - rootCanvasChild.additionalShaderChannels = AdditionalCanvasShaderChannels.None; - - // rootCanvasChild inherits properties from root - Assert.AreEqual( - rootCanvasChild.useReflectionProbes, - m_TestObject.useReflectionProbes); - Assert.AreEqual( - rootCanvasChild.additionalShaderChannels & AdditionalCanvasShaderChannels.Normal, - m_TestObject.additionalShaderChannels & AdditionalCanvasShaderChannels.Normal); - - // baseCanvas inherits properties from root - Assert.AreEqual( - baseCanvas.useReflectionProbes, - m_TestObject.useReflectionProbes); - Assert.AreEqual( - baseCanvas.additionalShaderChannels & AdditionalCanvasShaderChannels.Normal, - m_TestObject.additionalShaderChannels & AdditionalCanvasShaderChannels.Normal); - } } diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/UISystemProfilerAddMarkerWithNullObjectDoesNotCrash.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/UISystemProfilerAddMarkerWithNullObjectDoesNotCrash.cs index 4bd803f..137bce2 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/UISystemProfilerAddMarkerWithNullObjectDoesNotCrash.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/UISystemProfilerAddMarkerWithNullObjectDoesNotCrash.cs @@ -3,7 +3,7 @@ namespace Tests { - internal class UISystemProfilerAddMarkerWithNullObjectDoesNotCrash + public class UISystemProfilerAddMarkerWithNullObjectDoesNotCrash { [Test] public void AddMarkerShouldNotCrashWithNullObject() diff --git a/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ChangingHierarchyOfCanvasRenderer.cs b/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ChangingHierarchyOfCanvasRenderer.cs index 942fd45..057b7c2 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ChangingHierarchyOfCanvasRenderer.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ChangingHierarchyOfCanvasRenderer.cs @@ -4,7 +4,7 @@ using System.Collections; using UnityEditor.SceneManagement; -internal class ChangingHierarchyOfCanvasRenderer +public class ChangingHierarchyOfCanvasRenderer { [Test] public void ChangingHierarchyOfCanvasRenderer_DoesntCrash() diff --git a/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ParentCanvasIsSane.cs b/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ParentCanvasIsSane.cs index 5048478..87e49dc 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ParentCanvasIsSane.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ParentCanvasIsSane.cs @@ -4,7 +4,7 @@ using System.Collections; using UnityEngine.UI; -internal class ParentCanvasIsSane +public class ParentCanvasIsSane { GameObject rootCanvas; GameObject rootObject; diff --git a/com.unity.ugui/Tests/Editor/UGUI/Dropdown/DropdownOptionsListDrawer.cs b/com.unity.ugui/Tests/Editor/UGUI/Dropdown/DropdownOptionsListDrawer.cs index be43b8e..326911a 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Dropdown/DropdownOptionsListDrawer.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Dropdown/DropdownOptionsListDrawer.cs @@ -5,9 +5,9 @@ using UnityEditor; using NUnit.Framework; -internal class DropdownOptionsListDrawer : WrapperWindowFixture +public class DropdownOptionsListDrawer : WrapperWindowFixture { - internal class Fixture : MonoBehaviour + public class Fixture : MonoBehaviour { public Dropdown.OptionDataList options = new Dropdown.OptionDataList(); } diff --git a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/EventTriggerRemoveDuringExecution.cs b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/EventTriggerRemoveDuringExecution.cs index 1c55f28..9bd73e3 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/EventTriggerRemoveDuringExecution.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/EventTriggerRemoveDuringExecution.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.EventSystems; -internal class EventTriggerRemoveDuringExecution +public class EventTriggerRemoveDuringExecution { [Test] [Description("ArgumentOutOfRange Exception is thrown when removing handler in callback in EventTrigger (case 1401557)")] diff --git a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InputModuleTests.cs b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InputModuleTests.cs index 2ba9ed8..5a13be7 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InputModuleTests.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InputModuleTests.cs @@ -4,7 +4,7 @@ using UnityEngine.EventSystems; [TestFixture] -internal class InputModuleTests +public class InputModuleTests { private EventSystem m_EventSystem; @@ -40,7 +40,7 @@ public void InputModuleComponentFactory_AddComponent_CanBeOverriden() Assert.IsInstanceOf(inputModule); } - internal class TestInputModule : BaseInputModule + public class TestInputModule : BaseInputModule { public override void Process() { } } diff --git a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InterceptedEventsPreviewTests.cs b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InterceptedEventsPreviewTests.cs index a5d7eb1..60780dc 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InterceptedEventsPreviewTests.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InterceptedEventsPreviewTests.cs @@ -5,7 +5,7 @@ using UnityEditor; using NUnit.Framework; -internal class InterceptedEventsPreviewTests +public class InterceptedEventsPreviewTests { [Test] public void InterceptedEventsPreviewCacheUsingTypeCacheReturnsSameTypes() diff --git a/com.unity.ugui/Tests/Editor/UGUI/InputField/CharacterLimitValidation.cs b/com.unity.ugui/Tests/Editor/UGUI/InputField/CharacterLimitValidation.cs index 32dd638..ea5fbc7 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/InputField/CharacterLimitValidation.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/InputField/CharacterLimitValidation.cs @@ -2,7 +2,7 @@ namespace Core.InputField { - internal class CharacterLimitValidation : TestBehaviourBase + public class CharacterLimitValidation : TestBehaviourBase { [Test] public void LimitCanNotBeNegative() diff --git a/com.unity.ugui/Tests/Editor/UGUI/InputField/ContentValidation.cs b/com.unity.ugui/Tests/Editor/UGUI/InputField/ContentValidation.cs index 0ec6d01..9c1a993 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/InputField/ContentValidation.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/InputField/ContentValidation.cs @@ -3,7 +3,7 @@ namespace Core.InputField { - internal class ContentValidation : TestBehaviourBase + public class ContentValidation : TestBehaviourBase { [Test] [TestCase(ContentType.Alphanumeric, "0", "0")] diff --git a/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectMask2DCulling.cs b/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectMask2DCulling.cs index 1b7054a..22ba1ed 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectMask2DCulling.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectMask2DCulling.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.UI; -internal class RectMask2DCulling : TestBehaviourBase +public class RectMask2DCulling : TestBehaviourBase { [Test] public void CullFlagNotResetWhenReparented740604() diff --git a/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectTransformPosition.cs b/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectTransformPosition.cs index 1f058e3..bdce6da 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectTransformPosition.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectTransformPosition.cs @@ -1,7 +1,7 @@ using UnityEngine; using NUnit.Framework; -internal class RectTransformPosition +public class RectTransformPosition { [Test] public void SettingPositionBeforeGameObjectIsActivatedWorks_953409() diff --git a/com.unity.ugui/Tests/Editor/UGUI/Slider/SliderRectReferences.cs b/com.unity.ugui/Tests/Editor/UGUI/Slider/SliderRectReferences.cs index 6469968..06746c0 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Slider/SliderRectReferences.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Slider/SliderRectReferences.cs @@ -3,7 +3,7 @@ using UnityEngine; [Category("Slider")] -internal class SliderRectRefernces : Behaviour +public class SliderRectRefernces : Behaviour { private Slider slider; private GameObject emptyGO; diff --git a/com.unity.ugui/Tests/Editor/UGUI/TestBehaviourBase.cs b/com.unity.ugui/Tests/Editor/UGUI/TestBehaviourBase.cs index 49a3196..2e2e527 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/TestBehaviourBase.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/TestBehaviourBase.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using UnityEngine; -internal class TestBehaviourBase where T : Behaviour +public class TestBehaviourBase where T : Behaviour { protected T m_TestObject; diff --git a/com.unity.ugui/Tests/Editor/UGUI/Text/FontCreatedByScript.cs b/com.unity.ugui/Tests/Editor/UGUI/Text/FontCreatedByScript.cs index 9dabf16..8425a09 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Text/FontCreatedByScript.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Text/FontCreatedByScript.cs @@ -3,7 +3,7 @@ using UnityEngine; [Category("Text")] -internal class FontCreatedByScript +public class FontCreatedByScript { static Font CreateDefaultFontWithOneCharacter(int character) { diff --git a/com.unity.ugui/Tests/Editor/UGUI/UI/PropertyDrawers/PropertyDrawerTests.cs b/com.unity.ugui/Tests/Editor/UGUI/UI/PropertyDrawers/PropertyDrawerTests.cs index 543a1c3..5f87c3c 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/UI/PropertyDrawers/PropertyDrawerTests.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/UI/PropertyDrawers/PropertyDrawerTests.cs @@ -11,7 +11,7 @@ using UnityEngine.Search; [Timeout(360000)] -internal class PropertyDrawerTests +public class PropertyDrawerTests { class PropertyDrawerTestsWindow : EditorWindow { diff --git a/com.unity.ugui/Tests/Editor/UGUI/UnityEvent/UnityEventInvoke.cs b/com.unity.ugui/Tests/Editor/UGUI/UnityEvent/UnityEventInvoke.cs index 3107cf2..5e5c412 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/UnityEvent/UnityEventInvoke.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/UnityEvent/UnityEventInvoke.cs @@ -3,7 +3,7 @@ using UnityEngine; using UnityEngine.Events; -internal class UnityEventInvoke +public class UnityEventInvoke { class SimpleCounter : MonoBehaviour { diff --git a/com.unity.ugui/Tests/Editor/UGUI/WrapperWindowFixture.cs b/com.unity.ugui/Tests/Editor/UGUI/WrapperWindowFixture.cs index e8ac2f8..8e24611 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/WrapperWindowFixture.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/WrapperWindowFixture.cs @@ -4,11 +4,11 @@ using UnityEditor; using UnityEngine; -internal class WrapperWindowFixture +public class WrapperWindowFixture { private static WrapperWindow s_MostRecentWrapperWindow; - internal class WrapperWindow : EditorWindow + public class WrapperWindow : EditorWindow { // Return true to end the test public Func onGUIDelegate; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Button/ButtonTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Button/ButtonTests.cs index 89f3836..cac2e8d 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Button/ButtonTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Button/ButtonTests.cs @@ -7,7 +7,7 @@ using UnityEngine.UI; using UnityEngine; -internal class ButtonTests : IPrebuildSetup +public class ButtonTests : IPrebuildSetup { GameObject m_PrefabRoot; const string kPrefabPath = "Assets/Resources/ButtonPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/BridgeScriptForRetainingObjects.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/BridgeScriptForRetainingObjects.cs index a50f3a7..4bdc710 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/BridgeScriptForRetainingObjects.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/BridgeScriptForRetainingObjects.cs @@ -1,6 +1,6 @@ using UnityEngine; -internal class BridgeScriptForRetainingObjects : MonoBehaviour +public class BridgeScriptForRetainingObjects : MonoBehaviour { public const string bridgeObjectName = "BridgeGameObject"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasGroupInheritedAlpha.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasGroupInheritedAlpha.cs index 9c9290d..f57adcd 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasGroupInheritedAlpha.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasGroupInheritedAlpha.cs @@ -5,7 +5,7 @@ using UnityEngine.UI; [TestFixture] -internal class CanvasGroupTests +public class CanvasGroupTests { GameObject m_CanvasObject; CanvasGroup m_CanvasGroup; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasResizeCorrectlyForRenderTexture.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasResizeCorrectlyForRenderTexture.cs index c3f8100..f3e63dd 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasResizeCorrectlyForRenderTexture.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasResizeCorrectlyForRenderTexture.cs @@ -7,7 +7,7 @@ using UnityEditor; [TestFixture] -internal class CanvasResizeCorrectlyForRenderTexture +public class CanvasResizeCorrectlyForRenderTexture { Canvas m_Canvas; Camera m_Camera; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasScalerWithChildTextObjectDoesNotCrash.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasScalerWithChildTextObjectDoesNotCrash.cs index 06cfe00..4b33d82 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasScalerWithChildTextObjectDoesNotCrash.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasScalerWithChildTextObjectDoesNotCrash.cs @@ -7,7 +7,7 @@ [TestFixture] [Category("RegressionTest")] [Description("CoveredBugID = 734299")] -internal class CanvasScalerWithChildTextObjectDoesNotCrash +public class CanvasScalerWithChildTextObjectDoesNotCrash { GameObject m_CanvasObject; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStart.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStart.cs index e344048..35f6124 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStart.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStart.cs @@ -7,7 +7,7 @@ using UnityEditor; [TestFixture] -internal class CanvasSizeCorrectInAwakeAndStart : IPrebuildSetup +public class CanvasSizeCorrectInAwakeAndStart : IPrebuildSetup { const string k_SceneName = "CanvasSizeCorrectInAwakeAndStartScene"; GameObject m_CanvasGameObject; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStartScript.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStartScript.cs index 22c040c..5ba6be7 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStartScript.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStartScript.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.TestTools.Utils; -internal class CanvasSizeCorrectInAwakeAndStartScript : MonoBehaviour +public class CanvasSizeCorrectInAwakeAndStartScript : MonoBehaviour { public bool isStartCalled { get; private set; } public bool isAwakeCalled { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CheckMeshColorsAndColors32Match.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CheckMeshColorsAndColors32Match.cs index 940b843..5eabee8 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CheckMeshColorsAndColors32Match.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CheckMeshColorsAndColors32Match.cs @@ -6,7 +6,7 @@ using UnityEngine.TestTools.Utils; [TestFixture] -internal class CheckMeshColorsAndColors32Match +public class CheckMeshColorsAndColors32Match { GameObject m_CanvasGO; GameObject m_ColorMeshGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CoroutineWorksIfUIObjectIsAttached.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CoroutineWorksIfUIObjectIsAttached.cs index 12137d6..9756040 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CoroutineWorksIfUIObjectIsAttached.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CoroutineWorksIfUIObjectIsAttached.cs @@ -8,7 +8,7 @@ [UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })] [Category("RegressionTest")] [Description("CoveredBugID = 904415")] -internal class CoroutineWorksIfUIObjectIsAttached +public class CoroutineWorksIfUIObjectIsAttached { GameObject m_CanvasMaster; GameObject m_ImageObject; @@ -48,7 +48,7 @@ public void TearDown() } } -internal class BugObject : MonoBehaviour +public class BugObject : MonoBehaviour { void Awake() { @@ -58,7 +58,7 @@ void Awake() } } -internal class CoroutineObject : MonoBehaviour +public class CoroutineObject : MonoBehaviour { public int coroutineCount { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvas.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvas.cs index f29e55f..6cd804a 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvas.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvas.cs @@ -6,7 +6,7 @@ using System.Collections; using UnityEditor; -internal class NestedCanvas : IPrebuildSetup +public class NestedCanvas : IPrebuildSetup { Object m_GO1; Object m_GO2; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvasMaintainsCorrectSize.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvasMaintainsCorrectSize.cs index d749b22..ace6c11 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvasMaintainsCorrectSize.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvasMaintainsCorrectSize.cs @@ -2,7 +2,7 @@ using UnityEngine.TestTools; using NUnit.Framework; -internal class NestedCanvasMaintainsCorrectSize : IPrebuildSetup +public class NestedCanvasMaintainsCorrectSize : IPrebuildSetup { BridgeScriptForRetainingObjects m_BridgeComponent; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs index 4c1df05..9312f4f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs @@ -11,7 +11,7 @@ [UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })] [Category("RegressionTest")] [Description("CoveredBugID = 883807, CoveredBugDescription = \"Object::GetInstanceID crash when trying to switch canvas\"")] -internal class NoActiveCameraInSceneDoesNotCrashEditor : IPrebuildSetup +public class NoActiveCameraInSceneDoesNotCrashEditor : IPrebuildSetup { Scene m_InitScene; const string k_SceneName = "NoActiveCameraInSceneDoesNotCrashEditorScene"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DReparentedToDifferentCanvas.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DReparentedToDifferentCanvas.cs index a896c9e..23fa93e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DReparentedToDifferentCanvas.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DReparentedToDifferentCanvas.cs @@ -6,7 +6,7 @@ namespace Graphics { [Category("RegressionTest")] [Description("CoveredBugID = 1395695, CoveredBugDescription = \"RectMask2D hides all content when parented from other display to first dislpay in the Game view window\"")] - internal class RectMask2DReparentedToDifferentCanvas + public class RectMask2DReparentedToDifferentCanvas { GameObject m_GameObjectA; GameObject m_GameObjectB; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect.cs index 8fc1743..0bd75bf 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect.cs @@ -10,7 +10,7 @@ namespace Graphics [Category("RegressionTest")] [Description( "CoveredBugID = 782957, CoveredBugDescription = \"Some element from scroll view are invisible when they're masked with RectMask2D and sub-canvases\"")] - internal class RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect + public class RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect { GameObject m_RootCanvasGO; GameObject m_MaskGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectTransformValidAfterEnable.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectTransformValidAfterEnable.cs index 199f4f2..4c4eb04 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectTransformValidAfterEnable.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectTransformValidAfterEnable.cs @@ -8,7 +8,7 @@ using UnityEditor; [TestFixture] -internal class RectTransformValidAfterEnable : IPrebuildSetup +public class RectTransformValidAfterEnable : IPrebuildSetup { const string kSceneName = "DisabledCanvasScene"; const string kGameObjectName = "DisabledCanvas"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectangleContainsScreenPointTest.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectangleContainsScreenPointTest.cs index f939738..31b1745 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectangleContainsScreenPointTest.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectangleContainsScreenPointTest.cs @@ -3,7 +3,7 @@ using UnityEngine; using System.Linq; -internal class RectangleContainsScreenPointTest : MonoBehaviour +public class RectangleContainsScreenPointTest : MonoBehaviour { RectTransform m_RectTransform; Camera m_MainCamera; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/SiblingOrderChangesLayout.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/SiblingOrderChangesLayout.cs index 5e449c6..1599eb1 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/SiblingOrderChangesLayout.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/SiblingOrderChangesLayout.cs @@ -7,7 +7,7 @@ [TestFixture] [Category("RegressionTest")] [Description("Case 723062")] -internal class SiblingOrderChangesLayout +public class SiblingOrderChangesLayout { GameObject m_CanvasGO; GameObject m_ParentGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs index 324d2fe..6712b3c 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs @@ -1,7 +1,7 @@ using UnityEngine; using NUnit.Framework; -internal class CanvasRendererTests +public class CanvasRendererTests { private const int Width = 32; private const int Height = 32; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Dropdown/DropdownTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Dropdown/DropdownTests.cs index 7154ab5..86ea34d 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Dropdown/DropdownTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Dropdown/DropdownTests.cs @@ -7,7 +7,7 @@ using UnityEditor; using System.Collections.Generic; -internal class DropdownTests : IPrebuildSetup +public class DropdownTests : IPrebuildSetup { GameObject m_PrefabRoot; GameObject m_CameraGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterTests.cs index d077c90..8608b98 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterTests.cs @@ -7,7 +7,7 @@ using UnityEngine.UI; using UnityEngine.TestTools.Utils; -internal class GraphicRaycasterTests +public class GraphicRaycasterTests { Camera m_Camera; EventSystem m_EventSystem; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterWorldSpaceCanvasTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterWorldSpaceCanvasTests.cs index c60c4c4..ac9bc7e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterWorldSpaceCanvasTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterWorldSpaceCanvasTests.cs @@ -7,7 +7,7 @@ using UnityEngine.UI; using UnityEngine.TestTools.Utils; -internal class GraphicRaycasterWorldSpaceCanvasTests +public class GraphicRaycasterWorldSpaceCanvasTests { Camera m_Camera; EventSystem m_EventSystem; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests.cs index 236af33..ad9143f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests.cs @@ -6,7 +6,7 @@ using UnityEngine.UI; [UnityPlatform()] -internal class InputModuleTests +public class InputModuleTests { EventSystem m_EventSystem; FakeBaseInput m_FakeBaseInput; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/DragCallbackCheck.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/DragCallbackCheck.cs index a8d9ea0..647acbf 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/DragCallbackCheck.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/DragCallbackCheck.cs @@ -1,7 +1,7 @@ using UnityEngine; using UnityEngine.EventSystems; -internal class DragCallbackCheck : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerDownHandler +public class DragCallbackCheck : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerDownHandler { private bool loggedOnDrag = false; public bool onBeginDragCalled = false; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/FakeBaseInput.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/FakeBaseInput.cs index fea4dc3..0e7853e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/FakeBaseInput.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/FakeBaseInput.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.EventSystems; -internal class FakeBaseInput : BaseInput +public class FakeBaseInput : BaseInput { [NonSerialized] public String CompositionString = ""; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/MouseUpdate.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/MouseUpdate.cs index fe77e9d..ec6e4d9 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/MouseUpdate.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/MouseUpdate.cs @@ -1,6 +1,6 @@ using UnityEngine; -internal class MouseUpdate : MonoBehaviour +public class MouseUpdate : MonoBehaviour { FakeBaseInput m_FakeBaseInput; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerClickCallbackCheck.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerClickCallbackCheck.cs index 7777fd8..0e325d2 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerClickCallbackCheck.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerClickCallbackCheck.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; -internal class PointerClickCallbackCheck : MonoBehaviour, IPointerDownHandler +public class PointerClickCallbackCheck : MonoBehaviour, IPointerDownHandler { public bool pointerDown = false; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerEnterCallbackCheck.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerEnterCallbackCheck.cs index 5000026..a1be530 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerEnterCallbackCheck.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerEnterCallbackCheck.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; -internal class PointerEnterCallbackCheck : MonoBehaviour, IPointerEnterHandler +public class PointerEnterCallbackCheck : MonoBehaviour, IPointerEnterHandler { public PointerEventData pointerData { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerExitCallbackCheck.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerExitCallbackCheck.cs index 593b43f..28d0d78 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerExitCallbackCheck.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerExitCallbackCheck.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; -internal class PointerExitCallbackCheck : MonoBehaviour, IPointerExitHandler +public class PointerExitCallbackCheck : MonoBehaviour, IPointerExitHandler { public PointerEventData pointerData { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/Physics2DRaycasterTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/Physics2DRaycasterTests.cs index d216d74..dc2d6e6 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/Physics2DRaycasterTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/Physics2DRaycasterTests.cs @@ -4,7 +4,7 @@ using UnityEngine.EventSystems; using UnityEngine.Rendering; -internal class Physics2DRaycasterTests +public class Physics2DRaycasterTests { GameObject m_CamGO; SpriteRenderer m_RedSprite; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/PhysicsRaycasterTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/PhysicsRaycasterTests.cs index 0b8867f..6e80d60 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/PhysicsRaycasterTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/PhysicsRaycasterTests.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using UnityEngine.EventSystems; -internal class PhysicsRaycasterTests +public class PhysicsRaycasterTests { GameObject m_CamGO; GameObject m_Collider; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/RaycastSortingTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/RaycastSortingTests.cs index 0a993d7..6c54d47 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/RaycastSortingTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/RaycastSortingTests.cs @@ -8,7 +8,7 @@ using UnityEngine.TestTools; using UnityEngine.UI; -internal class RaycastSortingTests : IPrebuildSetup +public class RaycastSortingTests : IPrebuildSetup { // Test to check that a a raycast over two canvases will not use hierarchal depth to compare two results // from different canvases (case 912396 - Raycast hits ignores 2nd Canvas which is drawn in front) diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs index 5e9dc76..24d4170 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs @@ -6,7 +6,7 @@ namespace UnityEngine.UI.Tests { [TestFixture] - internal class ImageTests + class ImageTests { Image m_Image; private Sprite m_Sprite; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTest.cs b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTest.cs index 8e49523..6fa3bb7 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTest.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTest.cs @@ -8,7 +8,7 @@ namespace Graphics { - internal class RawImageTest : IPrebuildSetup + public class RawImageTest : IPrebuildSetup { private const int Width = 32; private const int Height = 32; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTestHook.cs b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTestHook.cs index 5f0e56b..fc1e3b4 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTestHook.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTestHook.cs @@ -3,7 +3,7 @@ using UnityEngine; using UnityEngine.UI; -internal class RawImageTestHook : RawImage +public class RawImageTestHook : RawImage { public bool isGeometryUpdated; public bool isCacheUsed; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ToggleTestImageHook.cs b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ToggleTestImageHook.cs index 5d197cd..a964b2a 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ToggleTestImageHook.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ToggleTestImageHook.cs @@ -3,7 +3,7 @@ using UnityEngine; using UnityEngine.UI; -internal class ToggleTestImageHook : Image +public class ToggleTestImageHook : Image { public float durationTween; public override void CrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha, bool useRGB) diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageFilledGenerateWork.cs b/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageFilledGenerateWork.cs index d87b442..ee534df 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageFilledGenerateWork.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageFilledGenerateWork.cs @@ -6,7 +6,7 @@ [TestFixture] [Category("RegressionTest")] -internal class ImageFilledGenerateWork +public class ImageFilledGenerateWork { GameObject m_CanvasGO; GameObject m_ImageGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs index 487cfd3..9615dcc 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs @@ -5,7 +5,7 @@ using UnityEngine.UI; using System.Reflection; -internal class ImageTests +public class ImageTests { private const int Width = 32; private const int Height = 32; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs b/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs index d05a626..acaff3c 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs @@ -2,7 +2,7 @@ using UnityEngine.UI; using System.Reflection; -internal class TestableImage : Image +public class TestableImage : Image { public bool isOnPopulateMeshCalled = false; public bool isGeometryUpdated = false; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/DesktopInputFieldTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/DesktopInputFieldTests.cs index 1c49b13..50e815e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/DesktopInputFieldTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/DesktopInputFieldTests.cs @@ -12,7 +12,7 @@ namespace InputfieldTests { - internal class DesktopInputFieldTests : BaseInputFieldTests, IPrebuildSetup + public class DesktopInputFieldTests : BaseInputFieldTests, IPrebuildSetup { protected const string kPrefabPath = "Assets/Resources/DesktopInputFieldPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/FakeInputModule.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/FakeInputModule.cs index 6cb6d70..782047f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/FakeInputModule.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/FakeInputModule.cs @@ -2,7 +2,7 @@ namespace InputfieldTests { - internal class FakeInputModule : BaseInputModule + public class FakeInputModule : BaseInputModule { public override void Process() { diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs index 554fb9f..1320a54 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs @@ -12,7 +12,7 @@ namespace InputfieldTests { - internal class GenericInputFieldTests : BaseInputFieldTests, IPrebuildSetup + public class GenericInputFieldTests : BaseInputFieldTests, IPrebuildSetup { protected const string kPrefabPath = "Assets/Resources/GenericInputFieldPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/InputFieldTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/InputFieldTests.cs index 5094c6e..c421b08 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/InputFieldTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/InputFieldTests.cs @@ -12,7 +12,7 @@ namespace InputfieldTests { - internal class BaseInputFieldTests + public class BaseInputFieldTests { protected GameObject m_PrefabRoot; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/TouchInputFieldTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/TouchInputFieldTests.cs index 67caea3..50b57cf 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/TouchInputFieldTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/TouchInputFieldTests.cs @@ -12,7 +12,7 @@ namespace InputfieldTests { - internal class TouchInputFieldTests : BaseInputFieldTests, IPrebuildSetup + public class TouchInputFieldTests : BaseInputFieldTests, IPrebuildSetup { protected const string kPrefabPath = "Assets/Resources/TouchInputFieldPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Layout/HorizonalLayoutGroupTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Layout/HorizonalLayoutGroupTests.cs index 140dee6..7b36364 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Layout/HorizonalLayoutGroupTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Layout/HorizonalLayoutGroupTests.cs @@ -8,7 +8,7 @@ namespace LayoutTests { - internal class HorizontalLayoutGroupTests : IPrebuildSetup + public class HorizontalLayoutGroupTests : IPrebuildSetup { GameObject m_PrefabRoot; const string kPrefabPath = "Assets/Resources/HorizontalLayoutGroupPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupScaling.cs b/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupScaling.cs index 4b3b58e..53b4fa4 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupScaling.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupScaling.cs @@ -9,7 +9,7 @@ // test for case 879374 - Checks that layout group children scale properly when scaleWidth / scaleHeight are toggled namespace LayoutTests { - internal class LayoutGroupScaling : IPrebuildSetup + public class LayoutGroupScaling : IPrebuildSetup { GameObject m_PrefabRoot; GameObject m_CameraGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Layout/VerticalLayoutGroupTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Layout/VerticalLayoutGroupTests.cs index cd82f37..dce7c2f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Layout/VerticalLayoutGroupTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Layout/VerticalLayoutGroupTests.cs @@ -10,7 +10,7 @@ namespace LayoutTests { - internal class VerticalLayoutGroupTests : IPrebuildSetup + public class VerticalLayoutGroupTests : IPrebuildSetup { GameObject m_PrefabRoot; const string kPrefabPath = "Assets/Resources/VerticalLayoutGroupPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/LayoutGroup/LayoutGroupArrangement.cs b/com.unity.ugui/Tests/Runtime/UGUI/LayoutGroup/LayoutGroupArrangement.cs index 1cf7415..b45de20 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/LayoutGroup/LayoutGroupArrangement.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/LayoutGroup/LayoutGroupArrangement.cs @@ -6,7 +6,7 @@ using UnityEngine.UI; [TestFixture] -internal class LayoutGroupArrangement +public class LayoutGroupArrangement { const float k_LayoutDefaultSize = 100f; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/MaskClipping/RectMask2DClipping.cs b/com.unity.ugui/Tests/Runtime/UGUI/MaskClipping/RectMask2DClipping.cs index c86443a..d107c33 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/MaskClipping/RectMask2DClipping.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/MaskClipping/RectMask2DClipping.cs @@ -12,7 +12,7 @@ This test checks that a maskableGraphic within a RectMask2D will be properly cli */ namespace UnityEngine.UI.Tests { - internal class RectMask2DClipping : IPrebuildSetup + public class RectMask2DClipping : IPrebuildSetup { GameObject m_PrefabRoot; GameObject m_CameraGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoadScript.cs b/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoadScript.cs index eda1dd9..3945e54 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoadScript.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoadScript.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.TestTools.Utils; -internal class SceneWithNestedLayoutElementsLoadScript : MonoBehaviour +public class SceneWithNestedLayoutElementsLoadScript : MonoBehaviour { public bool isStartCalled { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoads.cs b/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoads.cs index 6c6b9d9..e561cfa 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoads.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoads.cs @@ -9,7 +9,7 @@ [TestFixture] [Category("RegressionTest")] -internal class SceneWithNestedLayoutElementsLoad : IPrebuildSetup +public class SceneWithNestedLayoutElementsLoad : IPrebuildSetup { Scene m_InitScene; const string aspectRatioFitterSceneName = "AspectRatioFitter"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarClamp.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarClamp.cs index aeaa923..dba9a70 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarClamp.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarClamp.cs @@ -9,7 +9,7 @@ using UnityEngine.EventSystems; using UnityEditor; -internal class ScrollBarClamp : IPrebuildSetup +public class ScrollBarClamp : IPrebuildSetup { // This test tests that setting scrollBar.value will not be clamped (case 802330 - Scrollbar stops velocity of 'Scroll Rect' unexpectedly) GameObject m_PrefabRoot; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarTests.cs index c620f6e..98ba89b 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarTests.cs @@ -7,7 +7,7 @@ using UnityEngine.TestTools; using UnityEngine.UI; -internal class ScrollBarTests : IPrebuildSetup +public class ScrollBarTests : IPrebuildSetup { GameObject m_PrefabRoot; const string kPrefabPath = "Assets/Resources/ScrollBarPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectClamp.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectClamp.cs index 4041c28..2c48ef5 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectClamp.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectClamp.cs @@ -4,7 +4,7 @@ using NUnit.Framework; using System.Collections; -internal class ScrollRectClamp +public class ScrollRectClamp { // Prefab has the following hierarchy: // - PrefabRoot diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectScale.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectScale.cs index 20b7209..d127066 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectScale.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectScale.cs @@ -6,7 +6,7 @@ using UnityEngine.UI; using UnityEditor; -internal class ScrollRectScale : IPrebuildSetup +public class ScrollRectScale : IPrebuildSetup { const string kPrefabPath = "Assets/Resources/ScrollRectScalePrefab.prefab"; public void Setup() diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectStableLayout.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectStableLayout.cs index 67e0b03..a0d2270 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectStableLayout.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectStableLayout.cs @@ -11,7 +11,7 @@ Test for case (1010178-Clamped ScrollRect with scalling cause a large spike in performance) */ -internal class ScrollRectStableLayout : IPrebuildSetup +public class ScrollRectStableLayout : IPrebuildSetup { GameObject m_PrefabRoot; GameObject m_CameraGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectTests.cs index 2ca0d6a..aff635c 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectTests.cs @@ -10,7 +10,7 @@ using UnityEngine.TestTools; using System.Runtime.CompilerServices; -internal class ScrollRectTests : IPrebuildSetup +public class ScrollRectTests : IPrebuildSetup { const int ScrollSensitivity = 3; GameObject m_PrefabRoot; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Slider/SliderTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Slider/SliderTests.cs index e71a983..95f0b10 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Slider/SliderTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Slider/SliderTests.cs @@ -3,7 +3,7 @@ using UnityEngine; [Category("Slider")] -internal class SliderTests +public class SliderTests { private Slider slider; private GameObject emptyGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorBackspaceDelete.cs b/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorBackspaceDelete.cs index 6b9b37e..6b3a50f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorBackspaceDelete.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorBackspaceDelete.cs @@ -4,7 +4,7 @@ using UnityEngine; using UnityEngine.TestTools; -internal class TextEditorBackspaceDelete +public class TextEditorBackspaceDelete { private const string kFailedToRemoveCharacterMessage = "Backspace or Delete Failed To Remove The Expected Character"; private const string kFailedToChangeCursor = "Backspace or Delete Failed To Move The Cursor To The Expected Index"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorTests.cs index 94031c5..aaa8088 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorTests.cs @@ -3,7 +3,7 @@ using NUnit.Framework; using UnityEngine; -internal class TextEditorTests +public class TextEditorTests { TextEditor m_TextEditor; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Util/ConcreteGraphic.cs b/com.unity.ugui/Tests/Runtime/UGUI/Util/ConcreteGraphic.cs index 8616aff..ac095d6 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Util/ConcreteGraphic.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Util/ConcreteGraphic.cs @@ -3,7 +3,7 @@ namespace UnityEngine.UI.Tests { // Make a non-abstract Graphic. - internal class ConcreteGraphic : Graphic + public class ConcreteGraphic : Graphic { public override string ToString() { diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Util/ImageHook.cs b/com.unity.ugui/Tests/Runtime/UGUI/Util/ImageHook.cs index e03a68e..ff580cc 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Util/ImageHook.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Util/ImageHook.cs @@ -6,7 +6,7 @@ namespace UnityEngine.UI.Tests { // Hook into the graphic callback so we can do our check. - internal class ImageHook : Image + public class ImageHook : Image { public bool isGeometryUpdated; public bool isLayoutRebuild; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Util/UIBehaviourExtensions.cs b/com.unity.ugui/Tests/Runtime/UGUI/Util/UIBehaviourExtensions.cs index 1af4c7f..722aba6 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Util/UIBehaviourExtensions.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Util/UIBehaviourExtensions.cs @@ -7,7 +7,7 @@ namespace UnityEngine.UI.Tests { - internal static class UIBehaviourExtensions + public static class UIBehaviourExtensions { private static object InvokeMethodAndRethrow(Type type, Object obj, string methodName, params object[] args) { @@ -90,7 +90,7 @@ public static void InvokeOnDidApplyAnimationProperties(this UIBehaviour behaviou } } - internal static class SelectableExtensions + public static class SelectableExtensions { public static void InvokeOnPointerDown(this Selectable selectable, PointerEventData data) { @@ -123,7 +123,7 @@ public static void InvokeOnSelect(this Selectable selectable, string triggerName } } - internal static class GraphicExtension + public static class GraphicExtension { public static void InvokeOnPopulateMesh(this Graphic graphic, VertexHelper vh) { @@ -131,7 +131,7 @@ public static void InvokeOnPopulateMesh(this Graphic graphic, VertexHelper vh) } } - internal static class GraphicRaycasterExtension + public static class GraphicRaycasterExtension { public static void InvokeRaycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, List results) { @@ -139,7 +139,7 @@ public static void InvokeRaycast(Canvas canvas, Camera eventCamera, Vector2 poin } } - internal static class ToggleGroupExtension + public static class ToggleGroupExtension { public static void InvokeValidateToggleIsInGroup(this ToggleGroup tgroup, Toggle toggle) { From d78187f00c32867602d0b2da56471c648b0da0a9 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 13 Sep 2025 05:55:23 +0000 Subject: [PATCH 02/26] Mirror com.unity.ugui package (Unity 6000.3.0b3) --- com.unity.ugui/Runtime/TMP/TMP_Text.cs | 46 +++++++----- com.unity.ugui/Runtime/TMP/TextMeshPro.cs | 59 ++++++++------- com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs | 59 ++++++++------- .../InputModules/StandaloneInputModule.cs | 45 ++++++++--- .../UGUI/UI/Core/Layout/LayoutGroup.cs | 10 +++ .../AssertionFailureOnOutputVertexCount.cs | 2 +- ...ValidPositionsWhenCameraOrthoSizeIsZero.cs | 2 +- ...vasWidthAssertionErrorWithRectTransform.cs | 2 +- .../Editor/UGUI/Canvas/RootCanvasTests.cs | 2 +- ...ilerAddMarkerWithNullObjectDoesNotCrash.cs | 2 +- .../ChangingHierarchyOfCanvasRenderer.cs | 2 +- .../UGUI/CanvasRenderer/ParentCanvasIsSane.cs | 2 +- .../Dropdown/DropdownOptionsListDrawer.cs | 4 +- .../EventTriggerRemoveDuringExecution.cs | 2 +- .../UGUI/EventSystem/InputModuleTests.cs | 4 +- .../InterceptedEventsPreviewTests.cs | 2 +- .../InputField/CharacterLimitValidation.cs | 2 +- .../UGUI/InputField/ContentValidation.cs | 2 +- .../UGUI/RectMask2D/RectMask2DCulling.cs | 2 +- .../UGUI/RectMask2D/RectTransformPosition.cs | 2 +- .../UGUI/Slider/SliderRectReferences.cs | 2 +- .../Tests/Editor/UGUI/TestBehaviourBase.cs | 2 +- .../Editor/UGUI/Text/FontCreatedByScript.cs | 2 +- .../UI/PropertyDrawers/PropertyDrawerTests.cs | 2 +- .../UGUI/UnityEvent/UnityEventInvoke.cs | 2 +- .../Tests/Editor/UGUI/WrapperWindowFixture.cs | 4 +- .../Tests/Runtime/UGUI/Button/ButtonTests.cs | 2 +- .../Canvas/BridgeScriptForRetainingObjects.cs | 2 +- .../UGUI/Canvas/CanvasGroupInheritedAlpha.cs | 2 +- .../CanvasResizeCorrectlyForRenderTexture.cs | 2 +- ...asScalerWithChildTextObjectDoesNotCrash.cs | 2 +- .../CanvasSizeCorrectInAwakeAndStart.cs | 2 +- .../CanvasSizeCorrectInAwakeAndStartScript.cs | 2 +- .../Canvas/CheckMeshColorsAndColors32Match.cs | 2 +- .../CoroutineWorksIfUIObjectIsAttached.cs | 6 +- .../Tests/Runtime/UGUI/Canvas/NestedCanvas.cs | 2 +- .../NestedCanvasMaintainsCorrectSize.cs | 2 +- ...NoActiveCameraInSceneDoesNotCrashEditor.cs | 2 +- .../RectMask2DReparentedToDifferentCanvas.cs | 2 +- ...NestedCanvasCullsUsingCorrectCanvasRect.cs | 2 +- .../Canvas/RectTransformValidAfterEnable.cs | 2 +- .../RectangleContainsScreenPointTest.cs | 2 +- .../UGUI/Canvas/SiblingOrderChangesLayout.cs | 2 +- .../CanvasRenderer/CanvasRendererTests.cs | 2 +- .../Runtime/UGUI/Dropdown/DropdownTests.cs | 2 +- .../UGUI/EventSystem/GraphicRaycasterTests.cs | 2 +- .../GraphicRaycasterWorldSpaceCanvasTests.cs | 2 +- .../UGUI/EventSystem/InputModuleTests.cs | 58 +++++++++++++- .../InputModuleTests/DragCallbackCheck.cs | 15 +++- .../InputModuleTests/FakeBaseInput.cs | 2 +- .../InputModuleTests/MouseUpdate.cs | 2 +- .../PointerClickCallbackCheck.cs | 2 +- .../PointerEnterCallbackCheck.cs | 2 +- .../PointerExitCallbackCheck.cs | 2 +- .../EventSystem/Physics2DRaycasterTests.cs | 2 +- .../UGUI/EventSystem/PhysicsRaycasterTests.cs | 2 +- .../UGUI/EventSystem/RaycastSortingTests.cs | 2 +- .../Tests/Runtime/UGUI/Graphic/ImageTests.cs | 2 +- .../Runtime/UGUI/Graphic/RawImageTest.cs | 2 +- .../Runtime/UGUI/Graphic/RawImageTestHook.cs | 2 +- .../UGUI/Graphic/ToggleTestImageHook.cs | 2 +- .../UGUI/Image/ImageFilledGenerateWork.cs | 2 +- .../Tests/Runtime/UGUI/Image/ImageTests.cs | 2 +- .../Tests/Runtime/UGUI/Image/TestableImage.cs | 2 +- .../UGUI/InputField/DesktopInputFieldTests.cs | 2 +- .../UGUI/InputField/FakeInputModule.cs | 2 +- .../UGUI/InputField/GenericInputFieldTests.cs | 2 +- .../UGUI/InputField/InputFieldTests.cs | 2 +- .../UGUI/InputField/TouchInputFieldTests.cs | 2 +- .../UGUI/Layout/HorizonalLayoutGroupTests.cs | 2 +- .../Runtime/UGUI/Layout/LayoutGroupScaling.cs | 2 +- .../Runtime/UGUI/Layout/LayoutGroupTests.cs | 75 +++++++++++++++++++ .../UGUI/Layout/LayoutGroupTests.cs.meta | 2 + .../UGUI/Layout/VerticalLayoutGroupTests.cs | 2 +- .../LayoutGroup/LayoutGroupArrangement.cs | 2 +- .../UGUI/MaskClipping/RectMask2DClipping.cs | 2 +- ...SceneWithNestedLayoutElementsLoadScript.cs | 2 +- .../SceneWithNestedLayoutElementsLoads.cs | 2 +- .../Runtime/UGUI/ScrollBar/ScrollBarClamp.cs | 2 +- .../Runtime/UGUI/ScrollBar/ScrollBarTests.cs | 2 +- .../UGUI/ScrollRect/ScrollRectClamp.cs | 2 +- .../UGUI/ScrollRect/ScrollRectScale.cs | 2 +- .../UGUI/ScrollRect/ScrollRectStableLayout.cs | 2 +- .../UGUI/ScrollRect/ScrollRectTests.cs | 2 +- .../Tests/Runtime/UGUI/Slider/SliderTests.cs | 2 +- .../TextEditor/TextEditorBackspaceDelete.cs | 2 +- .../UGUI/TextEditor/TextEditorTests.cs | 2 +- .../Runtime/UGUI/Util/ConcreteGraphic.cs | 2 +- .../Tests/Runtime/UGUI/Util/ImageHook.cs | 2 +- .../UGUI/Util/UIBehaviourExtensions.cs | 10 +-- 90 files changed, 372 insertions(+), 177 deletions(-) create mode 100644 com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupTests.cs create mode 100644 com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupTests.cs.meta diff --git a/com.unity.ugui/Runtime/TMP/TMP_Text.cs b/com.unity.ugui/Runtime/TMP/TMP_Text.cs index 2d1be86..528102d 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_Text.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_Text.cs @@ -3885,9 +3885,10 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m // Calculate the scale of the font based on selected font size and sampling point size. // baseScale is calculated using the font asset assigned to the text object. - float baseScale = (fontSize / m_fontAsset.faceInfo.pointSize * m_fontAsset.faceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); + float orthographicMultiplier = m_isOrthographic ? 1 : 0.1f; + float baseScale = fontSize / m_fontAsset.faceInfo.pointSize * m_fontAsset.faceInfo.scale * orthographicMultiplier; float currentElementScale = baseScale; - float currentEmScale = fontSize * 0.01f * (m_isOrthographic ? 1 : 0.1f); + float currentEmScale = fontSize * 0.01f * orthographicMultiplier; m_fontScaleMultiplier = 1; m_currentFontSize = fontSize; @@ -4094,36 +4095,41 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m float baselineOffset = 0; float elementAscentLine = 0; float elementDescentLine = 0; + + FaceInfo fontFace = m_currentFontAsset.faceInfo; + if (m_textElementType == TMP_TextElementType.Sprite) { // If a sprite is used as a fallback then get a reference to it and set the color to white. TMP_SpriteCharacter sprite = (TMP_SpriteCharacter)m_textInfo.characterInfo[m_characterCount].textElement; + if (sprite == null) continue; + m_currentSpriteAsset = sprite.textAsset as TMP_SpriteAsset; m_spriteIndex = (int)sprite.glyphIndex; - if (sprite == null) continue; - // Sprites are assigned in the E000 Private Area + sprite Index if (charCode == 60) - charCode = 57344 + (uint)m_spriteIndex; + charCode = 0xE000 + (uint)m_spriteIndex; + + FaceInfo spriteFace = m_currentSpriteAsset.faceInfo; - // The sprite scale calculations are based on the font asset assigned to the text object. - if (m_currentSpriteAsset.faceInfo.pointSize > 0) + // Use sprite asset's own metrics when available. Otherwise, scale sprite based on current font asset face metrics. + if (spriteFace.pointSize > 0) { - float spriteScale = (m_currentFontSize / m_currentSpriteAsset.faceInfo.pointSize * m_currentSpriteAsset.faceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); + float spriteScale = m_currentFontSize / spriteFace.pointSize * spriteFace.scale * orthographicMultiplier; currentElementScale = sprite.scale * sprite.glyph.scale * spriteScale; - elementAscentLine = m_currentSpriteAsset.faceInfo.ascentLine; + elementAscentLine = spriteFace.ascentLine; //baselineOffset = m_currentSpriteAsset.faceInfo.baseline * m_fontScale * m_fontScaleMultiplier * m_currentSpriteAsset.faceInfo.scale; - elementDescentLine = m_currentSpriteAsset.faceInfo.descentLine; + elementDescentLine = spriteFace.descentLine; } else { - float spriteScale = (m_currentFontSize / m_currentFontAsset.faceInfo.pointSize * m_currentFontAsset.faceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); - currentElementScale = m_currentFontAsset.faceInfo.ascentLine / sprite.glyph.metrics.height * sprite.scale * sprite.glyph.scale * spriteScale; - float scaleDelta = spriteScale / currentElementScale; - elementAscentLine = m_currentFontAsset.faceInfo.ascentLine * scaleDelta; + float spriteScale = m_currentFontSize / fontFace.pointSize * fontFace.scale * orthographicMultiplier; + currentElementScale = fontFace.ascentLine / sprite.glyph.metrics.height * sprite.scale * sprite.glyph.scale * spriteScale; + float scaleDelta = currentElementScale != 0 ? spriteScale / currentElementScale : 0; + elementAscentLine = fontFace.ascentLine * scaleDelta; //baselineOffset = m_currentFontAsset.faceInfo.baseline * m_fontScale * m_fontScaleMultiplier * m_currentFontAsset.faceInfo.scale; - elementDescentLine = m_currentFontAsset.faceInfo.descentLine * scaleDelta; + elementDescentLine = fontFace.descentLine * scaleDelta; } m_cached_TextElement = sprite; @@ -4142,9 +4148,9 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m float adjustedScale; if (isInjectedCharacter && m_TextProcessingArray[i].unicode == 0x0A && m_characterCount != m_firstCharacterOfLine) - adjustedScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize * smallCapsMultiplier / m_currentFontAsset.m_FaceInfo.pointSize * m_currentFontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + adjustedScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize * smallCapsMultiplier / fontFace.pointSize * fontFace.scale * orthographicMultiplier; else - adjustedScale = m_currentFontSize * smallCapsMultiplier / m_currentFontAsset.m_FaceInfo.pointSize * m_currentFontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + adjustedScale = m_currentFontSize * smallCapsMultiplier / fontFace.pointSize * fontFace.scale * orthographicMultiplier; // Special handling for injected Ellipsis if (isInjectedCharacter && charCode == 0x2026) @@ -4154,11 +4160,11 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m } else { - elementAscentLine = m_currentFontAsset.m_FaceInfo.ascentLine; - elementDescentLine = m_currentFontAsset.m_FaceInfo.descentLine; + elementAscentLine = fontFace.ascentLine; + elementDescentLine = fontFace.descentLine; } - currentElementScale = adjustedScale * m_fontScaleMultiplier * m_cached_TextElement.scale; + currentElementScale = adjustedScale * m_fontScaleMultiplier * m_cached_TextElement.scale * m_cached_TextElement.m_Glyph.scale; m_internalCharacterInfo[m_characterCount].elementType = TMP_TextElementType.Character; } diff --git a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs index dec8b7e..42b8219 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs @@ -2211,9 +2211,10 @@ protected virtual void GenerateTextMesh() // Calculate the scale of the font based on selected font size and sampling point size. // baseScale is calculated using the font asset assigned to the text object. - float baseScale = (m_fontSize / m_fontAsset.m_FaceInfo.pointSize * m_fontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); + float orthographicMultiplier = m_isOrthographic ? 1 : 0.1f; + float baseScale = m_fontSize / m_fontAsset.m_FaceInfo.pointSize * m_fontAsset.m_FaceInfo.scale * orthographicMultiplier; float currentElementScale = baseScale; - float currentEmScale = m_fontSize * 0.01f * (m_isOrthographic ? 1 : 0.1f); + float currentEmScale = m_fontSize * 0.01f * orthographicMultiplier; m_fontScaleMultiplier = 1; m_currentFontSize = m_fontSize; @@ -2509,44 +2510,48 @@ protected virtual void GenerateTextMesh() float baselineOffset = 0; float elementAscentLine = 0; float elementDescentLine = 0; + + FaceInfo fontFace = m_currentFontAsset.m_FaceInfo; + if (m_textElementType == TMP_TextElementType.Sprite) { // If a sprite is used as a fallback then get a reference to it and set the color to white. TMP_SpriteCharacter sprite = (TMP_SpriteCharacter)textInfo.characterInfo[m_characterCount].textElement; - m_currentSpriteAsset = sprite.textAsset as TMP_SpriteAsset; - m_spriteIndex = (int)sprite.glyphIndex; - if (sprite == null) { k_CharacterLookupMarker.End(); continue; } + m_currentSpriteAsset = sprite.textAsset as TMP_SpriteAsset; + m_spriteIndex = (int)sprite.glyphIndex; + // Sprites are assigned in the E000 Private Area + sprite Index if (charCode == '<') - charCode = 57344 + (uint)m_spriteIndex; + charCode = 0xE000 + (uint)m_spriteIndex; else m_spriteColor = s_colorWhite; - float fontScale = (m_currentFontSize / m_currentFontAsset.faceInfo.pointSize * m_currentFontAsset.faceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); + float fontScale = m_currentFontSize / fontFace.pointSize * fontFace.scale * orthographicMultiplier; + FaceInfo spriteFace = m_currentSpriteAsset.m_FaceInfo; - // The sprite scale calculations are based on the font asset assigned to the text object. - if (m_currentSpriteAsset.m_FaceInfo.pointSize > 0) + // Use sprite asset's own metrics when available. Otherwise, scale sprite based on current font asset face metrics. + if (spriteFace.pointSize > 0) { - float spriteScale = m_currentFontSize / m_currentSpriteAsset.m_FaceInfo.pointSize * m_currentSpriteAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + float spriteScale = m_currentFontSize / spriteFace.pointSize * spriteFace.scale * orthographicMultiplier; currentElementScale = sprite.m_Scale * sprite.m_Glyph.scale * spriteScale; - elementAscentLine = m_currentSpriteAsset.m_FaceInfo.ascentLine; - baselineOffset = m_currentSpriteAsset.m_FaceInfo.baseline * fontScale * m_fontScaleMultiplier * m_currentSpriteAsset.m_FaceInfo.scale; - elementDescentLine = m_currentSpriteAsset.m_FaceInfo.descentLine; + elementAscentLine = spriteFace.ascentLine; + baselineOffset = spriteFace.baseline * fontScale * m_fontScaleMultiplier * spriteFace.scale; + elementDescentLine = spriteFace.descentLine; } else { - float spriteScale = m_currentFontSize / m_currentFontAsset.m_FaceInfo.pointSize * m_currentFontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); - currentElementScale = m_currentFontAsset.m_FaceInfo.ascentLine / sprite.m_Glyph.metrics.height * sprite.m_Scale * sprite.m_Glyph.scale * spriteScale; - float scaleDelta = spriteScale / currentElementScale; - elementAscentLine = m_currentFontAsset.m_FaceInfo.ascentLine * scaleDelta; - baselineOffset = m_currentFontAsset.m_FaceInfo.baseline * fontScale * m_fontScaleMultiplier * m_currentFontAsset.m_FaceInfo.scale; - elementDescentLine = m_currentFontAsset.m_FaceInfo.descentLine * scaleDelta; + float spriteScale = m_currentFontSize / fontFace.pointSize * fontFace.scale * orthographicMultiplier; + currentElementScale = fontFace.ascentLine / sprite.m_Glyph.metrics.height * sprite.m_Scale * sprite.m_Glyph.scale * spriteScale; + float scaleDelta = currentElementScale != 0 ? spriteScale / currentElementScale : 0; + elementAscentLine = fontFace.ascentLine * scaleDelta; + baselineOffset = fontFace.baseline * fontScale * m_fontScaleMultiplier * fontFace.scale; + elementDescentLine = fontFace.descentLine * scaleDelta; } m_cached_TextElement = sprite; @@ -2576,9 +2581,9 @@ protected virtual void GenerateTextMesh() // Special handling if replaced character was a line feed where in this case we have to use the scale of the previous character. float adjustedScale; if (isInjectedCharacter && m_TextProcessingArray[i].unicode == 0x0A && m_characterCount != m_firstCharacterOfLine) - adjustedScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize * smallCapsMultiplier / m_currentFontAsset.m_FaceInfo.pointSize * m_currentFontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + adjustedScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize * smallCapsMultiplier / fontFace.pointSize * fontFace.scale * orthographicMultiplier; else - adjustedScale = m_currentFontSize * smallCapsMultiplier / m_currentFontAsset.m_FaceInfo.pointSize * m_currentFontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + adjustedScale = m_currentFontSize * smallCapsMultiplier / fontFace.pointSize * fontFace.scale * orthographicMultiplier; // Special handling for injected Ellipsis if (isInjectedCharacter && charCode == 0x2026) @@ -2588,12 +2593,12 @@ protected virtual void GenerateTextMesh() } else { - elementAscentLine = m_currentFontAsset.m_FaceInfo.ascentLine; - elementDescentLine = m_currentFontAsset.m_FaceInfo.descentLine; + elementAscentLine = fontFace.ascentLine; + elementDescentLine = fontFace.descentLine; } currentElementScale = adjustedScale * m_fontScaleMultiplier * m_cached_TextElement.m_Scale * m_cached_TextElement.m_Glyph.scale; - baselineOffset = m_currentFontAsset.m_FaceInfo.baseline * adjustedScale * m_fontScaleMultiplier * m_currentFontAsset.m_FaceInfo.scale; + baselineOffset = fontFace.baseline * adjustedScale * m_fontScaleMultiplier * fontFace.scale; m_textInfo.characterInfo[m_characterCount].elementType = TMP_TextElementType.Character; m_textInfo.characterInfo[m_characterCount].scale = currentElementScale; @@ -3763,7 +3768,7 @@ protected virtual void GenerateTextMesh() #region Track Potential Insertion Location for Ellipsis if (m_overflowMode == TextOverflowModes.Ellipsis && (isInjectedCharacter == false || charCode == 0x2D)) { - float fontScale = m_currentFontSize / m_Ellipsis.fontAsset.m_FaceInfo.pointSize * m_Ellipsis.fontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + float fontScale = m_currentFontSize / m_Ellipsis.fontAsset.m_FaceInfo.pointSize * m_Ellipsis.fontAsset.m_FaceInfo.scale * orthographicMultiplier; float scale = fontScale * m_fontScaleMultiplier * m_Ellipsis.character.m_Scale * m_Ellipsis.character.m_Glyph.scale; float marginLeft = m_marginLeft; float marginRight = m_marginRight; @@ -3771,7 +3776,7 @@ protected virtual void GenerateTextMesh() // Use the scale and margins of the previous character if Line Feed (LF) is not the first character of a line. if (charCode == 0x0A && m_characterCount != m_firstCharacterOfLine) { - fontScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize / m_Ellipsis.fontAsset.m_FaceInfo.pointSize * m_Ellipsis.fontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + fontScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize / m_Ellipsis.fontAsset.m_FaceInfo.pointSize * m_Ellipsis.fontAsset.m_FaceInfo.scale * orthographicMultiplier; scale = fontScale * m_fontScaleMultiplier * m_Ellipsis.character.m_Scale * m_Ellipsis.character.m_Glyph.scale; marginLeft = m_textInfo.lineInfo[m_lineNumber].marginLeft; marginRight = m_textInfo.lineInfo[m_lineNumber].marginRight; @@ -4328,7 +4333,7 @@ protected virtual void GenerateTextMesh() { float gap = !m_isRightToLeft ? lineInfo.width - lineInfo.maxAdvance : lineInfo.width + lineInfo.maxAdvance; int visibleCount = lineInfo.visibleCharacterCount - 1 + lineInfo.controlCharacterCount; - int spaces = lineInfo.spaceCount - lineInfo.controlCharacterCount; + int spaces = lineInfo.visibleSpaceCount - lineInfo.controlCharacterCount; if (isFirstSeperator) { spaces -= 1; visibleCount += 1; } diff --git a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index 74e4b75..cc9520e 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -2559,9 +2559,10 @@ protected virtual void GenerateTextMesh() // Calculate the scale of the font based on selected font size and sampling point size. // baseScale is calculated using the font asset assigned to the text object. - float baseScale = (m_fontSize / m_fontAsset.m_FaceInfo.pointSize * m_fontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); + float orthographicMultiplier = m_isOrthographic ? 1 : 0.1f; + float baseScale = m_fontSize / m_fontAsset.m_FaceInfo.pointSize * m_fontAsset.m_FaceInfo.scale * orthographicMultiplier; float currentElementScale = baseScale; - float currentEmScale = m_fontSize * 0.01f * (m_isOrthographic ? 1 : 0.1f); + float currentEmScale = m_fontSize * 0.01f * orthographicMultiplier; m_fontScaleMultiplier = 1; m_currentFontSize = m_fontSize; @@ -2857,44 +2858,48 @@ protected virtual void GenerateTextMesh() float baselineOffset = 0; float elementAscentLine = 0; float elementDescentLine = 0; + + FaceInfo fontFace = m_currentFontAsset.m_FaceInfo; + if (m_textElementType == TMP_TextElementType.Sprite) { // If a sprite is used as a fallback then get a reference to it and set the color to white. TMP_SpriteCharacter sprite = (TMP_SpriteCharacter)textInfo.characterInfo[m_characterCount].textElement; - m_currentSpriteAsset = sprite.textAsset as TMP_SpriteAsset; - m_spriteIndex = (int)sprite.glyphIndex; - if (sprite == null) { k_CharacterLookupMarker.End(); continue; } + m_currentSpriteAsset = sprite.textAsset as TMP_SpriteAsset; + m_spriteIndex = (int)sprite.glyphIndex; + // Sprites are assigned in the E000 Private Area + sprite Index if (charCode == '<') - charCode = 57344 + (uint)m_spriteIndex; + charCode = 0xE000 + (uint)m_spriteIndex; else m_spriteColor = s_colorWhite; - float fontScale = (m_currentFontSize / m_currentFontAsset.faceInfo.pointSize * m_currentFontAsset.faceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); + float fontScale = m_currentFontSize / fontFace.pointSize * fontFace.scale * orthographicMultiplier; + FaceInfo spriteFace = m_currentSpriteAsset.m_FaceInfo; - // The sprite scale calculations are based on the font asset assigned to the text object. - if (m_currentSpriteAsset.m_FaceInfo.pointSize > 0) + // Use sprite asset's own metrics when available. Otherwise, scale sprite based on current font asset face metrics. + if (spriteFace.pointSize > 0) { - float spriteScale = m_currentFontSize / m_currentSpriteAsset.m_FaceInfo.pointSize * m_currentSpriteAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + float spriteScale = m_currentFontSize / spriteFace.pointSize * spriteFace.scale * orthographicMultiplier; currentElementScale = sprite.m_Scale * sprite.m_Glyph.scale * spriteScale; - elementAscentLine = m_currentSpriteAsset.m_FaceInfo.ascentLine; - baselineOffset = m_currentSpriteAsset.m_FaceInfo.baseline * fontScale * m_fontScaleMultiplier * m_currentSpriteAsset.m_FaceInfo.scale; - elementDescentLine = m_currentSpriteAsset.m_FaceInfo.descentLine; + elementAscentLine = spriteFace.ascentLine; + baselineOffset = spriteFace.baseline * fontScale * m_fontScaleMultiplier * spriteFace.scale; + elementDescentLine = spriteFace.descentLine; } else { - float spriteScale = m_currentFontSize / m_currentFontAsset.m_FaceInfo.pointSize * m_currentFontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); - currentElementScale = m_currentFontAsset.m_FaceInfo.ascentLine / sprite.m_Glyph.metrics.height * sprite.m_Scale * sprite.m_Glyph.scale * spriteScale; - float scaleDelta = spriteScale / currentElementScale; - elementAscentLine = m_currentFontAsset.m_FaceInfo.ascentLine * scaleDelta; - baselineOffset = m_currentFontAsset.m_FaceInfo.baseline * fontScale * m_fontScaleMultiplier * m_currentFontAsset.m_FaceInfo.scale; - elementDescentLine = m_currentFontAsset.m_FaceInfo.descentLine * scaleDelta; + float spriteScale = m_currentFontSize / fontFace.pointSize * fontFace.scale * orthographicMultiplier; + currentElementScale = fontFace.ascentLine / sprite.m_Glyph.metrics.height * sprite.m_Scale * sprite.m_Glyph.scale * spriteScale; + float scaleDelta = currentElementScale != 0 ? spriteScale / currentElementScale : 0; + elementAscentLine = fontFace.ascentLine * scaleDelta; + baselineOffset = fontFace.baseline * fontScale * m_fontScaleMultiplier * fontFace.scale; + elementDescentLine = fontFace.descentLine * scaleDelta; } m_cached_TextElement = sprite; @@ -2924,9 +2929,9 @@ protected virtual void GenerateTextMesh() // Special handling if replaced character was a line feed where in this case we have to use the scale of the previous character. float adjustedScale; if (isInjectedCharacter && m_TextProcessingArray[i].unicode == 0x0A && m_characterCount != m_firstCharacterOfLine) - adjustedScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize * smallCapsMultiplier / m_currentFontAsset.m_FaceInfo.pointSize * m_currentFontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + adjustedScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize * smallCapsMultiplier / fontFace.pointSize * fontFace.scale * orthographicMultiplier; else - adjustedScale = m_currentFontSize * smallCapsMultiplier / m_currentFontAsset.m_FaceInfo.pointSize * m_currentFontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + adjustedScale = m_currentFontSize * smallCapsMultiplier / fontFace.pointSize * fontFace.scale * orthographicMultiplier; // Special handling for injected Ellipsis if (isInjectedCharacter && charCode == 0x2026) @@ -2936,12 +2941,12 @@ protected virtual void GenerateTextMesh() } else { - elementAscentLine = m_currentFontAsset.m_FaceInfo.ascentLine; - elementDescentLine = m_currentFontAsset.m_FaceInfo.descentLine; + elementAscentLine = fontFace.ascentLine; + elementDescentLine = fontFace.descentLine; } currentElementScale = adjustedScale * m_fontScaleMultiplier * m_cached_TextElement.m_Scale * m_cached_TextElement.m_Glyph.scale; - baselineOffset = m_currentFontAsset.m_FaceInfo.baseline * adjustedScale * m_fontScaleMultiplier * m_currentFontAsset.m_FaceInfo.scale; + baselineOffset = fontFace.baseline * adjustedScale * m_fontScaleMultiplier * fontFace.scale; m_textInfo.characterInfo[m_characterCount].elementType = TMP_TextElementType.Character; m_textInfo.characterInfo[m_characterCount].scale = currentElementScale; @@ -2987,7 +2992,7 @@ protected virtual void GenerateTextMesh() GlyphPairAdjustmentRecord adjustmentPair; uint baseGlyphIndex = m_cached_TextElement.m_GlyphIndex; - if (m_characterCount < totalCharacterCount - 1 && textInfo.characterInfo[m_characterCount + 1].elementType == TMP_TextElementType.Character) + if (m_characterCount < totalCharacterCount - 1 && m_textInfo.characterInfo[m_characterCount + 1].elementType == TMP_TextElementType.Character) { uint nextGlyphIndex = m_textInfo.characterInfo[m_characterCount + 1].textElement.m_GlyphIndex; uint key = nextGlyphIndex << 16 | baseGlyphIndex; @@ -4111,7 +4116,7 @@ protected virtual void GenerateTextMesh() #region Track Potential Insertion Location for Ellipsis if (m_overflowMode == TextOverflowModes.Ellipsis && (isInjectedCharacter == false || charCode == 0x2D)) { - float fontScale = m_currentFontSize / m_Ellipsis.fontAsset.m_FaceInfo.pointSize * m_Ellipsis.fontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + float fontScale = m_currentFontSize / m_Ellipsis.fontAsset.m_FaceInfo.pointSize * m_Ellipsis.fontAsset.m_FaceInfo.scale * orthographicMultiplier; float scale = fontScale * m_fontScaleMultiplier * m_Ellipsis.character.m_Scale * m_Ellipsis.character.m_Glyph.scale; float marginLeft = m_marginLeft; float marginRight = m_marginRight; @@ -4119,7 +4124,7 @@ protected virtual void GenerateTextMesh() // Use the scale and margins of the previous character if Line Feed (LF) is not the first character of a line. if (charCode == 0x0A && m_characterCount != m_firstCharacterOfLine) { - fontScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize / m_Ellipsis.fontAsset.m_FaceInfo.pointSize * m_Ellipsis.fontAsset.m_FaceInfo.scale * (m_isOrthographic ? 1 : 0.1f); + fontScale = m_textInfo.characterInfo[m_characterCount - 1].pointSize / m_Ellipsis.fontAsset.m_FaceInfo.pointSize * m_Ellipsis.fontAsset.m_FaceInfo.scale * orthographicMultiplier; scale = fontScale * m_fontScaleMultiplier * m_Ellipsis.character.m_Scale * m_Ellipsis.character.m_Glyph.scale; marginLeft = m_textInfo.lineInfo[m_lineNumber].marginLeft; marginRight = m_textInfo.lineInfo[m_lineNumber].marginRight; diff --git a/com.unity.ugui/Runtime/UGUI/EventSystem/InputModules/StandaloneInputModule.cs b/com.unity.ugui/Runtime/UGUI/EventSystem/InputModules/StandaloneInputModule.cs index 1fae484..b60c92f 100644 --- a/com.unity.ugui/Runtime/UGUI/EventSystem/InputModules/StandaloneInputModule.cs +++ b/com.unity.ugui/Runtime/UGUI/EventSystem/InputModules/StandaloneInputModule.cs @@ -1,5 +1,6 @@ using System; -using UnityEngine; +using System.Collections.Generic; +using UnityEngine.Pool; using UnityEngine.Serialization; namespace UnityEngine.EventSystems @@ -22,7 +23,7 @@ public class StandaloneInputModule : PointerInputModule private GameObject m_CurrentFocusedGameObject; - private PointerEventData m_InputPointerEvent; + private readonly Dictionary m_InputPointerEvents = new(); private const float doubleClickTime = 0.3f; @@ -166,18 +167,40 @@ public override void UpdateModule() { if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus()) { - if (m_InputPointerEvent != null && m_InputPointerEvent.pointerDrag != null && m_InputPointerEvent.dragging) + ReleasePointerDrags(); + return; + } + + m_LastMousePosition = m_MousePosition; + m_MousePosition = input.mousePosition; + } + + private void ReleasePointerDrags() + { + using (ListPool.Get(out var pointerIds)) + { + // Copy all current pointer IDs into a temporary list so we can iterate over them safely. + // We cannot iterate m_InputPointerEvents directly because ReleaseMouse() modifies + // m_InputPointerEvents, which would invalidate any active enumeration. + foreach (var key in m_InputPointerEvents.Keys) { - ReleaseMouse(m_InputPointerEvent, m_InputPointerEvent.pointerCurrentRaycast.gameObject); + pointerIds.Add(key); } - m_InputPointerEvent = null; + // Release drag events for all pointers + foreach (var pointerId in pointerIds) + { + if (!m_InputPointerEvents.TryGetValue(pointerId, out var inputPointerEvent)) + continue; - return; + if (inputPointerEvent != null && inputPointerEvent.pointerDrag != null && inputPointerEvent.dragging) + { + ReleaseMouse(inputPointerEvent, inputPointerEvent.pointerCurrentRaycast.gameObject); + } + } } - m_LastMousePosition = m_MousePosition; - m_MousePosition = input.mousePosition; + m_InputPointerEvents.Clear(); } private void ReleaseMouse(PointerEventData pointerEvent, GameObject currentOverGo) @@ -217,7 +240,7 @@ private void ReleaseMouse(PointerEventData pointerEvent, GameObject currentOverG HandlePointerExitAndEnter(pointerEvent, currentOverGo); } - m_InputPointerEvent = pointerEvent; + m_InputPointerEvents[pointerEvent.pointerId] = pointerEvent; } public override bool ShouldActivateModule() @@ -436,7 +459,7 @@ protected void ProcessTouchPress(PointerEventData pointerEvent, bool pressed, bo pointerEvent.pointerEnter = null; } - m_InputPointerEvent = pointerEvent; + m_InputPointerEvents[pointerEvent.pointerId] = pointerEvent; } /// @@ -645,7 +668,7 @@ protected void ProcessMousePress(MouseButtonEventData data) if (pointerEvent.pointerDrag != null) ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag); - m_InputPointerEvent = pointerEvent; + m_InputPointerEvents[pointerEvent.pointerId] = pointerEvent; } // PointerUp notification diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutGroup.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutGroup.cs index d5480b9..ded5d81 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutGroup.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutGroup.cs @@ -134,6 +134,7 @@ protected LayoutGroup() protected override void OnEnable() { base.OnEnable(); + rectTransform.sendChildDimensionsChange = true; SetDirty(); } @@ -141,6 +142,7 @@ protected override void OnDisable() { m_Tracker.Clear(); LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + rectTransform.sendChildDimensionsChange = false; base.OnDisable(); } @@ -337,6 +339,14 @@ protected virtual void OnTransformChildrenChanged() SetDirty(); } + /// + /// Callback sent from native code whenever the RectTransform dimensions of a direct child are changed. + /// + protected virtual void OnChildRectTransformDimensionsChange() + { + SetDirty(); + } + /// /// Helper method used to set a given property if it has changed. /// diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/AssertionFailureOnOutputVertexCount.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/AssertionFailureOnOutputVertexCount.cs index 225cd45..c90e366 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/AssertionFailureOnOutputVertexCount.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/AssertionFailureOnOutputVertexCount.cs @@ -5,7 +5,7 @@ using UnityEditor.SceneManagement; using UnityEditor; -public class AssertionFailureOnOutputVertexCount +internal class AssertionFailureOnOutputVertexCount { const string scenePath = "Assets/AssertionFailureOnOutputVertexCountTestScene.unity"; [Test] diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero.cs index 01cbf1e..c5c09d8 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero.cs @@ -4,7 +4,7 @@ using UnityEngine.TestTools; using UnityEngine.UI; -public class CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero +internal class CanvasElementsMaintainValidPositionsWhenCameraOrthoSizeIsZero { GameObject image; GameObject canvas; diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasWidthAssertionErrorWithRectTransform.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasWidthAssertionErrorWithRectTransform.cs index 5adf200..bccca46 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasWidthAssertionErrorWithRectTransform.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/CanvasWidthAssertionErrorWithRectTransform.cs @@ -5,7 +5,7 @@ [TestFixture] [Category("RegressionTest")] [Description("CoveredBugID = 913932")] -public class CanvasWidthAssertionErrorWithRectTransform +internal class CanvasWidthAssertionErrorWithRectTransform { GameObject m_CanvasMaster; GameObject m_CanvasChild; diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/RootCanvasTests.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/RootCanvasTests.cs index 8263845..a650761 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/RootCanvasTests.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/RootCanvasTests.cs @@ -3,7 +3,7 @@ using UnityEngine.UI; [Category("Canvas")] -public class RootCanvasTests : TestBehaviourBase +internal class RootCanvasTests : TestBehaviourBase { // A simple nested canvas hierarchy // m_TestObject diff --git a/com.unity.ugui/Tests/Editor/UGUI/Canvas/UISystemProfilerAddMarkerWithNullObjectDoesNotCrash.cs b/com.unity.ugui/Tests/Editor/UGUI/Canvas/UISystemProfilerAddMarkerWithNullObjectDoesNotCrash.cs index 137bce2..4bd803f 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Canvas/UISystemProfilerAddMarkerWithNullObjectDoesNotCrash.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Canvas/UISystemProfilerAddMarkerWithNullObjectDoesNotCrash.cs @@ -3,7 +3,7 @@ namespace Tests { - public class UISystemProfilerAddMarkerWithNullObjectDoesNotCrash + internal class UISystemProfilerAddMarkerWithNullObjectDoesNotCrash { [Test] public void AddMarkerShouldNotCrashWithNullObject() diff --git a/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ChangingHierarchyOfCanvasRenderer.cs b/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ChangingHierarchyOfCanvasRenderer.cs index 057b7c2..942fd45 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ChangingHierarchyOfCanvasRenderer.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ChangingHierarchyOfCanvasRenderer.cs @@ -4,7 +4,7 @@ using System.Collections; using UnityEditor.SceneManagement; -public class ChangingHierarchyOfCanvasRenderer +internal class ChangingHierarchyOfCanvasRenderer { [Test] public void ChangingHierarchyOfCanvasRenderer_DoesntCrash() diff --git a/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ParentCanvasIsSane.cs b/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ParentCanvasIsSane.cs index 87e49dc..5048478 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ParentCanvasIsSane.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/CanvasRenderer/ParentCanvasIsSane.cs @@ -4,7 +4,7 @@ using System.Collections; using UnityEngine.UI; -public class ParentCanvasIsSane +internal class ParentCanvasIsSane { GameObject rootCanvas; GameObject rootObject; diff --git a/com.unity.ugui/Tests/Editor/UGUI/Dropdown/DropdownOptionsListDrawer.cs b/com.unity.ugui/Tests/Editor/UGUI/Dropdown/DropdownOptionsListDrawer.cs index 326911a..be43b8e 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Dropdown/DropdownOptionsListDrawer.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Dropdown/DropdownOptionsListDrawer.cs @@ -5,9 +5,9 @@ using UnityEditor; using NUnit.Framework; -public class DropdownOptionsListDrawer : WrapperWindowFixture +internal class DropdownOptionsListDrawer : WrapperWindowFixture { - public class Fixture : MonoBehaviour + internal class Fixture : MonoBehaviour { public Dropdown.OptionDataList options = new Dropdown.OptionDataList(); } diff --git a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/EventTriggerRemoveDuringExecution.cs b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/EventTriggerRemoveDuringExecution.cs index 9bd73e3..1c55f28 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/EventTriggerRemoveDuringExecution.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/EventTriggerRemoveDuringExecution.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.EventSystems; -public class EventTriggerRemoveDuringExecution +internal class EventTriggerRemoveDuringExecution { [Test] [Description("ArgumentOutOfRange Exception is thrown when removing handler in callback in EventTrigger (case 1401557)")] diff --git a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InputModuleTests.cs b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InputModuleTests.cs index 5a13be7..2ba9ed8 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InputModuleTests.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InputModuleTests.cs @@ -4,7 +4,7 @@ using UnityEngine.EventSystems; [TestFixture] -public class InputModuleTests +internal class InputModuleTests { private EventSystem m_EventSystem; @@ -40,7 +40,7 @@ public void InputModuleComponentFactory_AddComponent_CanBeOverriden() Assert.IsInstanceOf(inputModule); } - public class TestInputModule : BaseInputModule + internal class TestInputModule : BaseInputModule { public override void Process() { } } diff --git a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InterceptedEventsPreviewTests.cs b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InterceptedEventsPreviewTests.cs index 60780dc..a5d7eb1 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InterceptedEventsPreviewTests.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/EventSystem/InterceptedEventsPreviewTests.cs @@ -5,7 +5,7 @@ using UnityEditor; using NUnit.Framework; -public class InterceptedEventsPreviewTests +internal class InterceptedEventsPreviewTests { [Test] public void InterceptedEventsPreviewCacheUsingTypeCacheReturnsSameTypes() diff --git a/com.unity.ugui/Tests/Editor/UGUI/InputField/CharacterLimitValidation.cs b/com.unity.ugui/Tests/Editor/UGUI/InputField/CharacterLimitValidation.cs index ea5fbc7..32dd638 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/InputField/CharacterLimitValidation.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/InputField/CharacterLimitValidation.cs @@ -2,7 +2,7 @@ namespace Core.InputField { - public class CharacterLimitValidation : TestBehaviourBase + internal class CharacterLimitValidation : TestBehaviourBase { [Test] public void LimitCanNotBeNegative() diff --git a/com.unity.ugui/Tests/Editor/UGUI/InputField/ContentValidation.cs b/com.unity.ugui/Tests/Editor/UGUI/InputField/ContentValidation.cs index 9c1a993..0ec6d01 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/InputField/ContentValidation.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/InputField/ContentValidation.cs @@ -3,7 +3,7 @@ namespace Core.InputField { - public class ContentValidation : TestBehaviourBase + internal class ContentValidation : TestBehaviourBase { [Test] [TestCase(ContentType.Alphanumeric, "0", "0")] diff --git a/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectMask2DCulling.cs b/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectMask2DCulling.cs index 22ba1ed..1b7054a 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectMask2DCulling.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectMask2DCulling.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.UI; -public class RectMask2DCulling : TestBehaviourBase +internal class RectMask2DCulling : TestBehaviourBase { [Test] public void CullFlagNotResetWhenReparented740604() diff --git a/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectTransformPosition.cs b/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectTransformPosition.cs index bdce6da..1f058e3 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectTransformPosition.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/RectMask2D/RectTransformPosition.cs @@ -1,7 +1,7 @@ using UnityEngine; using NUnit.Framework; -public class RectTransformPosition +internal class RectTransformPosition { [Test] public void SettingPositionBeforeGameObjectIsActivatedWorks_953409() diff --git a/com.unity.ugui/Tests/Editor/UGUI/Slider/SliderRectReferences.cs b/com.unity.ugui/Tests/Editor/UGUI/Slider/SliderRectReferences.cs index 06746c0..6469968 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Slider/SliderRectReferences.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Slider/SliderRectReferences.cs @@ -3,7 +3,7 @@ using UnityEngine; [Category("Slider")] -public class SliderRectRefernces : Behaviour +internal class SliderRectRefernces : Behaviour { private Slider slider; private GameObject emptyGO; diff --git a/com.unity.ugui/Tests/Editor/UGUI/TestBehaviourBase.cs b/com.unity.ugui/Tests/Editor/UGUI/TestBehaviourBase.cs index 2e2e527..49a3196 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/TestBehaviourBase.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/TestBehaviourBase.cs @@ -1,7 +1,7 @@ using NUnit.Framework; using UnityEngine; -public class TestBehaviourBase where T : Behaviour +internal class TestBehaviourBase where T : Behaviour { protected T m_TestObject; diff --git a/com.unity.ugui/Tests/Editor/UGUI/Text/FontCreatedByScript.cs b/com.unity.ugui/Tests/Editor/UGUI/Text/FontCreatedByScript.cs index 8425a09..9dabf16 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/Text/FontCreatedByScript.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/Text/FontCreatedByScript.cs @@ -3,7 +3,7 @@ using UnityEngine; [Category("Text")] -public class FontCreatedByScript +internal class FontCreatedByScript { static Font CreateDefaultFontWithOneCharacter(int character) { diff --git a/com.unity.ugui/Tests/Editor/UGUI/UI/PropertyDrawers/PropertyDrawerTests.cs b/com.unity.ugui/Tests/Editor/UGUI/UI/PropertyDrawers/PropertyDrawerTests.cs index 5f87c3c..543a1c3 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/UI/PropertyDrawers/PropertyDrawerTests.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/UI/PropertyDrawers/PropertyDrawerTests.cs @@ -11,7 +11,7 @@ using UnityEngine.Search; [Timeout(360000)] -public class PropertyDrawerTests +internal class PropertyDrawerTests { class PropertyDrawerTestsWindow : EditorWindow { diff --git a/com.unity.ugui/Tests/Editor/UGUI/UnityEvent/UnityEventInvoke.cs b/com.unity.ugui/Tests/Editor/UGUI/UnityEvent/UnityEventInvoke.cs index 5e5c412..3107cf2 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/UnityEvent/UnityEventInvoke.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/UnityEvent/UnityEventInvoke.cs @@ -3,7 +3,7 @@ using UnityEngine; using UnityEngine.Events; -public class UnityEventInvoke +internal class UnityEventInvoke { class SimpleCounter : MonoBehaviour { diff --git a/com.unity.ugui/Tests/Editor/UGUI/WrapperWindowFixture.cs b/com.unity.ugui/Tests/Editor/UGUI/WrapperWindowFixture.cs index 8e24611..e8ac2f8 100644 --- a/com.unity.ugui/Tests/Editor/UGUI/WrapperWindowFixture.cs +++ b/com.unity.ugui/Tests/Editor/UGUI/WrapperWindowFixture.cs @@ -4,11 +4,11 @@ using UnityEditor; using UnityEngine; -public class WrapperWindowFixture +internal class WrapperWindowFixture { private static WrapperWindow s_MostRecentWrapperWindow; - public class WrapperWindow : EditorWindow + internal class WrapperWindow : EditorWindow { // Return true to end the test public Func onGUIDelegate; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Button/ButtonTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Button/ButtonTests.cs index cac2e8d..89f3836 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Button/ButtonTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Button/ButtonTests.cs @@ -7,7 +7,7 @@ using UnityEngine.UI; using UnityEngine; -public class ButtonTests : IPrebuildSetup +internal class ButtonTests : IPrebuildSetup { GameObject m_PrefabRoot; const string kPrefabPath = "Assets/Resources/ButtonPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/BridgeScriptForRetainingObjects.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/BridgeScriptForRetainingObjects.cs index 4bdc710..a50f3a7 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/BridgeScriptForRetainingObjects.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/BridgeScriptForRetainingObjects.cs @@ -1,6 +1,6 @@ using UnityEngine; -public class BridgeScriptForRetainingObjects : MonoBehaviour +internal class BridgeScriptForRetainingObjects : MonoBehaviour { public const string bridgeObjectName = "BridgeGameObject"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasGroupInheritedAlpha.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasGroupInheritedAlpha.cs index f57adcd..9c9290d 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasGroupInheritedAlpha.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasGroupInheritedAlpha.cs @@ -5,7 +5,7 @@ using UnityEngine.UI; [TestFixture] -public class CanvasGroupTests +internal class CanvasGroupTests { GameObject m_CanvasObject; CanvasGroup m_CanvasGroup; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasResizeCorrectlyForRenderTexture.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasResizeCorrectlyForRenderTexture.cs index f3e63dd..c3f8100 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasResizeCorrectlyForRenderTexture.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasResizeCorrectlyForRenderTexture.cs @@ -7,7 +7,7 @@ using UnityEditor; [TestFixture] -public class CanvasResizeCorrectlyForRenderTexture +internal class CanvasResizeCorrectlyForRenderTexture { Canvas m_Canvas; Camera m_Camera; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasScalerWithChildTextObjectDoesNotCrash.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasScalerWithChildTextObjectDoesNotCrash.cs index 4b33d82..06cfe00 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasScalerWithChildTextObjectDoesNotCrash.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasScalerWithChildTextObjectDoesNotCrash.cs @@ -7,7 +7,7 @@ [TestFixture] [Category("RegressionTest")] [Description("CoveredBugID = 734299")] -public class CanvasScalerWithChildTextObjectDoesNotCrash +internal class CanvasScalerWithChildTextObjectDoesNotCrash { GameObject m_CanvasObject; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStart.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStart.cs index 35f6124..e344048 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStart.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStart.cs @@ -7,7 +7,7 @@ using UnityEditor; [TestFixture] -public class CanvasSizeCorrectInAwakeAndStart : IPrebuildSetup +internal class CanvasSizeCorrectInAwakeAndStart : IPrebuildSetup { const string k_SceneName = "CanvasSizeCorrectInAwakeAndStartScene"; GameObject m_CanvasGameObject; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStartScript.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStartScript.cs index 5ba6be7..22c040c 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStartScript.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CanvasSizeCorrectInAwakeAndStartScript.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.TestTools.Utils; -public class CanvasSizeCorrectInAwakeAndStartScript : MonoBehaviour +internal class CanvasSizeCorrectInAwakeAndStartScript : MonoBehaviour { public bool isStartCalled { get; private set; } public bool isAwakeCalled { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CheckMeshColorsAndColors32Match.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CheckMeshColorsAndColors32Match.cs index 5eabee8..940b843 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CheckMeshColorsAndColors32Match.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CheckMeshColorsAndColors32Match.cs @@ -6,7 +6,7 @@ using UnityEngine.TestTools.Utils; [TestFixture] -public class CheckMeshColorsAndColors32Match +internal class CheckMeshColorsAndColors32Match { GameObject m_CanvasGO; GameObject m_ColorMeshGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CoroutineWorksIfUIObjectIsAttached.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CoroutineWorksIfUIObjectIsAttached.cs index 9756040..12137d6 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CoroutineWorksIfUIObjectIsAttached.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/CoroutineWorksIfUIObjectIsAttached.cs @@ -8,7 +8,7 @@ [UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })] [Category("RegressionTest")] [Description("CoveredBugID = 904415")] -public class CoroutineWorksIfUIObjectIsAttached +internal class CoroutineWorksIfUIObjectIsAttached { GameObject m_CanvasMaster; GameObject m_ImageObject; @@ -48,7 +48,7 @@ public void TearDown() } } -public class BugObject : MonoBehaviour +internal class BugObject : MonoBehaviour { void Awake() { @@ -58,7 +58,7 @@ void Awake() } } -public class CoroutineObject : MonoBehaviour +internal class CoroutineObject : MonoBehaviour { public int coroutineCount { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvas.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvas.cs index 6cd804a..f29e55f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvas.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvas.cs @@ -6,7 +6,7 @@ using System.Collections; using UnityEditor; -public class NestedCanvas : IPrebuildSetup +internal class NestedCanvas : IPrebuildSetup { Object m_GO1; Object m_GO2; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvasMaintainsCorrectSize.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvasMaintainsCorrectSize.cs index ace6c11..d749b22 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvasMaintainsCorrectSize.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NestedCanvasMaintainsCorrectSize.cs @@ -2,7 +2,7 @@ using UnityEngine.TestTools; using NUnit.Framework; -public class NestedCanvasMaintainsCorrectSize : IPrebuildSetup +internal class NestedCanvasMaintainsCorrectSize : IPrebuildSetup { BridgeScriptForRetainingObjects m_BridgeComponent; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs index 9312f4f..4c1df05 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs @@ -11,7 +11,7 @@ [UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })] [Category("RegressionTest")] [Description("CoveredBugID = 883807, CoveredBugDescription = \"Object::GetInstanceID crash when trying to switch canvas\"")] -public class NoActiveCameraInSceneDoesNotCrashEditor : IPrebuildSetup +internal class NoActiveCameraInSceneDoesNotCrashEditor : IPrebuildSetup { Scene m_InitScene; const string k_SceneName = "NoActiveCameraInSceneDoesNotCrashEditorScene"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DReparentedToDifferentCanvas.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DReparentedToDifferentCanvas.cs index 23fa93e..a896c9e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DReparentedToDifferentCanvas.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DReparentedToDifferentCanvas.cs @@ -6,7 +6,7 @@ namespace Graphics { [Category("RegressionTest")] [Description("CoveredBugID = 1395695, CoveredBugDescription = \"RectMask2D hides all content when parented from other display to first dislpay in the Game view window\"")] - public class RectMask2DReparentedToDifferentCanvas + internal class RectMask2DReparentedToDifferentCanvas { GameObject m_GameObjectA; GameObject m_GameObjectB; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect.cs index 0bd75bf..8fc1743 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect.cs @@ -10,7 +10,7 @@ namespace Graphics [Category("RegressionTest")] [Description( "CoveredBugID = 782957, CoveredBugDescription = \"Some element from scroll view are invisible when they're masked with RectMask2D and sub-canvases\"")] - public class RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect + internal class RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect { GameObject m_RootCanvasGO; GameObject m_MaskGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectTransformValidAfterEnable.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectTransformValidAfterEnable.cs index 4c4eb04..199f4f2 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectTransformValidAfterEnable.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectTransformValidAfterEnable.cs @@ -8,7 +8,7 @@ using UnityEditor; [TestFixture] -public class RectTransformValidAfterEnable : IPrebuildSetup +internal class RectTransformValidAfterEnable : IPrebuildSetup { const string kSceneName = "DisabledCanvasScene"; const string kGameObjectName = "DisabledCanvas"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectangleContainsScreenPointTest.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectangleContainsScreenPointTest.cs index 31b1745..f939738 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectangleContainsScreenPointTest.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/RectangleContainsScreenPointTest.cs @@ -3,7 +3,7 @@ using UnityEngine; using System.Linq; -public class RectangleContainsScreenPointTest : MonoBehaviour +internal class RectangleContainsScreenPointTest : MonoBehaviour { RectTransform m_RectTransform; Camera m_MainCamera; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/SiblingOrderChangesLayout.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/SiblingOrderChangesLayout.cs index 1599eb1..5e449c6 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/SiblingOrderChangesLayout.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/SiblingOrderChangesLayout.cs @@ -7,7 +7,7 @@ [TestFixture] [Category("RegressionTest")] [Description("Case 723062")] -public class SiblingOrderChangesLayout +internal class SiblingOrderChangesLayout { GameObject m_CanvasGO; GameObject m_ParentGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs index 6712b3c..324d2fe 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs @@ -1,7 +1,7 @@ using UnityEngine; using NUnit.Framework; -public class CanvasRendererTests +internal class CanvasRendererTests { private const int Width = 32; private const int Height = 32; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Dropdown/DropdownTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Dropdown/DropdownTests.cs index 86ea34d..7154ab5 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Dropdown/DropdownTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Dropdown/DropdownTests.cs @@ -7,7 +7,7 @@ using UnityEditor; using System.Collections.Generic; -public class DropdownTests : IPrebuildSetup +internal class DropdownTests : IPrebuildSetup { GameObject m_PrefabRoot; GameObject m_CameraGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterTests.cs index 8608b98..d077c90 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterTests.cs @@ -7,7 +7,7 @@ using UnityEngine.UI; using UnityEngine.TestTools.Utils; -public class GraphicRaycasterTests +internal class GraphicRaycasterTests { Camera m_Camera; EventSystem m_EventSystem; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterWorldSpaceCanvasTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterWorldSpaceCanvasTests.cs index ac9bc7e..c60c4c4 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterWorldSpaceCanvasTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterWorldSpaceCanvasTests.cs @@ -7,7 +7,7 @@ using UnityEngine.UI; using UnityEngine.TestTools.Utils; -public class GraphicRaycasterWorldSpaceCanvasTests +internal class GraphicRaycasterWorldSpaceCanvasTests { Camera m_Camera; EventSystem m_EventSystem; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests.cs index ad9143f..6f9ce06 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Reflection; using NUnit.Framework; using UnityEngine; using UnityEngine.EventSystems; @@ -6,7 +7,7 @@ using UnityEngine.UI; [UnityPlatform()] -public class InputModuleTests +internal class InputModuleTests { EventSystem m_EventSystem; FakeBaseInput m_FakeBaseInput; @@ -251,6 +252,61 @@ public IEnumerator PointerExitChildShouldFullyExit() Assert.IsTrue(callbackCheck.pointerData.fullyExited == true); } + [UnityTest] + public IEnumerator AllDragsAreReleasedOnLoseFocus() + { + // When the application loses focus, OnEndDrag and OnDrop should be called for all pointers + // involved in an active drag. + + var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2); + + // Add scripts to Image which implement OnBeginDrag, OnDrag & OnEndDrag callbacks + var callbackCheckLmb = m_Image.gameObject.AddComponent(); + callbackCheckLmb.pointerId = -1; + var callbackCheckRmb = m_Image.gameObject.AddComponent(); + callbackCheckRmb.pointerId = -2; + + // Setting required to fake mouse presence + m_FakeBaseInput.MousePresent = true; + + // Press both mouse buttons + m_FakeBaseInput.MouseButtonDown[0] = true; + m_FakeBaseInput.MouseButtonDown[1] = true; + m_FakeBaseInput.MousePosition = screenMiddle; + + yield return null; + + // Reset mouse down events and move pointer somewhere else -> initiates drag + m_FakeBaseInput.MouseButtonDown[0] = false; + m_FakeBaseInput.MouseButtonDown[1] = false; + m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150); + + yield return null; + + // We should be mid-drag for both mouse buttons now + Assert.IsTrue(callbackCheckLmb.onBeginDragCalled, "OnBeginDrag not called for LMB"); + Assert.IsTrue(callbackCheckRmb.onBeginDragCalled, "OnBeginDrag not called for RMB"); + Assert.IsTrue(callbackCheckLmb.onDragCalled, "OnDrag not called for LMB"); + Assert.IsTrue(callbackCheckRmb.onDragCalled, "OnDrag not called for RMB"); + Assert.IsFalse(callbackCheckLmb.onEndDragCalled, "OnEndDrag called prematurely for LMB"); + Assert.IsFalse(callbackCheckRmb.onEndDragCalled, "OnEndDrag called prematurely for RMB"); + Assert.IsFalse(callbackCheckLmb.onDropCalled, "OnDrop called prematurely for LMB"); + Assert.IsFalse(callbackCheckRmb.onDropCalled, "OnDrop called prematurely for RMB"); + + // Fake the application losing focus + typeof(EventSystem) + .GetMethod("OnApplicationFocus", BindingFlags.Instance | BindingFlags.NonPublic) + .Invoke(m_EventSystem, new object[] { false }); + + yield return null; + + // Losing focus should have released the drags for both mouse buttons + Assert.IsTrue(callbackCheckLmb.onEndDragCalled, "OnEndDrag not called for LMB"); + Assert.IsTrue(callbackCheckRmb.onEndDragCalled, "OnEndDrag not called for RMB"); + Assert.IsTrue(callbackCheckLmb.onDropCalled, "OnDrop not called for LMB"); + Assert.IsTrue(callbackCheckRmb.onDropCalled, "OnDrop not called for RMB"); + } + [TearDown] public void TearDown() { diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/DragCallbackCheck.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/DragCallbackCheck.cs index 647acbf..f0ed27b 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/DragCallbackCheck.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/DragCallbackCheck.cs @@ -1,21 +1,28 @@ using UnityEngine; using UnityEngine.EventSystems; -public class DragCallbackCheck : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerDownHandler +internal class DragCallbackCheck : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerDownHandler { private bool loggedOnDrag = false; public bool onBeginDragCalled = false; public bool onDragCalled = false; public bool onEndDragCalled = false; public bool onDropCalled = false; + public int? pointerId = null; public void OnBeginDrag(PointerEventData eventData) { + if (pointerId.HasValue && eventData.pointerId != pointerId) + return; + onBeginDragCalled = true; } public void OnDrag(PointerEventData eventData) { + if (pointerId.HasValue && eventData.pointerId != pointerId) + return; + if (loggedOnDrag) return; @@ -25,11 +32,17 @@ public void OnDrag(PointerEventData eventData) public void OnEndDrag(PointerEventData eventData) { + if (pointerId.HasValue && eventData.pointerId != pointerId) + return; + onEndDragCalled = true; } public void OnDrop(PointerEventData eventData) { + if (pointerId.HasValue && eventData.pointerId != pointerId) + return; + onDropCalled = true; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/FakeBaseInput.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/FakeBaseInput.cs index 0e7853e..fea4dc3 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/FakeBaseInput.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/FakeBaseInput.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.EventSystems; -public class FakeBaseInput : BaseInput +internal class FakeBaseInput : BaseInput { [NonSerialized] public String CompositionString = ""; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/MouseUpdate.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/MouseUpdate.cs index ec6e4d9..fe77e9d 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/MouseUpdate.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/MouseUpdate.cs @@ -1,6 +1,6 @@ using UnityEngine; -public class MouseUpdate : MonoBehaviour +internal class MouseUpdate : MonoBehaviour { FakeBaseInput m_FakeBaseInput; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerClickCallbackCheck.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerClickCallbackCheck.cs index 0e325d2..7777fd8 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerClickCallbackCheck.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerClickCallbackCheck.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; -public class PointerClickCallbackCheck : MonoBehaviour, IPointerDownHandler +internal class PointerClickCallbackCheck : MonoBehaviour, IPointerDownHandler { public bool pointerDown = false; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerEnterCallbackCheck.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerEnterCallbackCheck.cs index a1be530..5000026 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerEnterCallbackCheck.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerEnterCallbackCheck.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; -public class PointerEnterCallbackCheck : MonoBehaviour, IPointerEnterHandler +internal class PointerEnterCallbackCheck : MonoBehaviour, IPointerEnterHandler { public PointerEventData pointerData { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerExitCallbackCheck.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerExitCallbackCheck.cs index 28d0d78..593b43f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerExitCallbackCheck.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/InputModuleTests/PointerExitCallbackCheck.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; -public class PointerExitCallbackCheck : MonoBehaviour, IPointerExitHandler +internal class PointerExitCallbackCheck : MonoBehaviour, IPointerExitHandler { public PointerEventData pointerData { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/Physics2DRaycasterTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/Physics2DRaycasterTests.cs index dc2d6e6..d216d74 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/Physics2DRaycasterTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/Physics2DRaycasterTests.cs @@ -4,7 +4,7 @@ using UnityEngine.EventSystems; using UnityEngine.Rendering; -public class Physics2DRaycasterTests +internal class Physics2DRaycasterTests { GameObject m_CamGO; SpriteRenderer m_RedSprite; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/PhysicsRaycasterTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/PhysicsRaycasterTests.cs index 6e80d60..0b8867f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/PhysicsRaycasterTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/PhysicsRaycasterTests.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using UnityEngine.EventSystems; -public class PhysicsRaycasterTests +internal class PhysicsRaycasterTests { GameObject m_CamGO; GameObject m_Collider; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/RaycastSortingTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/RaycastSortingTests.cs index 6c54d47..0a993d7 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/RaycastSortingTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/RaycastSortingTests.cs @@ -8,7 +8,7 @@ using UnityEngine.TestTools; using UnityEngine.UI; -public class RaycastSortingTests : IPrebuildSetup +internal class RaycastSortingTests : IPrebuildSetup { // Test to check that a a raycast over two canvases will not use hierarchal depth to compare two results // from different canvases (case 912396 - Raycast hits ignores 2nd Canvas which is drawn in front) diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs index 24d4170..5e9dc76 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ImageTests.cs @@ -6,7 +6,7 @@ namespace UnityEngine.UI.Tests { [TestFixture] - class ImageTests + internal class ImageTests { Image m_Image; private Sprite m_Sprite; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTest.cs b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTest.cs index 6fa3bb7..8e49523 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTest.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTest.cs @@ -8,7 +8,7 @@ namespace Graphics { - public class RawImageTest : IPrebuildSetup + internal class RawImageTest : IPrebuildSetup { private const int Width = 32; private const int Height = 32; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTestHook.cs b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTestHook.cs index fc1e3b4..5f0e56b 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTestHook.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/RawImageTestHook.cs @@ -3,7 +3,7 @@ using UnityEngine; using UnityEngine.UI; -public class RawImageTestHook : RawImage +internal class RawImageTestHook : RawImage { public bool isGeometryUpdated; public bool isCacheUsed; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ToggleTestImageHook.cs b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ToggleTestImageHook.cs index a964b2a..5d197cd 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ToggleTestImageHook.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Graphic/ToggleTestImageHook.cs @@ -3,7 +3,7 @@ using UnityEngine; using UnityEngine.UI; -public class ToggleTestImageHook : Image +internal class ToggleTestImageHook : Image { public float durationTween; public override void CrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha, bool useRGB) diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageFilledGenerateWork.cs b/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageFilledGenerateWork.cs index ee534df..d87b442 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageFilledGenerateWork.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageFilledGenerateWork.cs @@ -6,7 +6,7 @@ [TestFixture] [Category("RegressionTest")] -public class ImageFilledGenerateWork +internal class ImageFilledGenerateWork { GameObject m_CanvasGO; GameObject m_ImageGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs index 9615dcc..487cfd3 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs @@ -5,7 +5,7 @@ using UnityEngine.UI; using System.Reflection; -public class ImageTests +internal class ImageTests { private const int Width = 32; private const int Height = 32; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs b/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs index acaff3c..d05a626 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs @@ -2,7 +2,7 @@ using UnityEngine.UI; using System.Reflection; -public class TestableImage : Image +internal class TestableImage : Image { public bool isOnPopulateMeshCalled = false; public bool isGeometryUpdated = false; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/DesktopInputFieldTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/DesktopInputFieldTests.cs index 50e815e..1c49b13 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/DesktopInputFieldTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/DesktopInputFieldTests.cs @@ -12,7 +12,7 @@ namespace InputfieldTests { - public class DesktopInputFieldTests : BaseInputFieldTests, IPrebuildSetup + internal class DesktopInputFieldTests : BaseInputFieldTests, IPrebuildSetup { protected const string kPrefabPath = "Assets/Resources/DesktopInputFieldPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/FakeInputModule.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/FakeInputModule.cs index 782047f..6cb6d70 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/FakeInputModule.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/FakeInputModule.cs @@ -2,7 +2,7 @@ namespace InputfieldTests { - public class FakeInputModule : BaseInputModule + internal class FakeInputModule : BaseInputModule { public override void Process() { diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs index 1320a54..554fb9f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs @@ -12,7 +12,7 @@ namespace InputfieldTests { - public class GenericInputFieldTests : BaseInputFieldTests, IPrebuildSetup + internal class GenericInputFieldTests : BaseInputFieldTests, IPrebuildSetup { protected const string kPrefabPath = "Assets/Resources/GenericInputFieldPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/InputFieldTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/InputFieldTests.cs index c421b08..5094c6e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/InputFieldTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/InputFieldTests.cs @@ -12,7 +12,7 @@ namespace InputfieldTests { - public class BaseInputFieldTests + internal class BaseInputFieldTests { protected GameObject m_PrefabRoot; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/InputField/TouchInputFieldTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/InputField/TouchInputFieldTests.cs index 50b57cf..67caea3 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/InputField/TouchInputFieldTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/InputField/TouchInputFieldTests.cs @@ -12,7 +12,7 @@ namespace InputfieldTests { - public class TouchInputFieldTests : BaseInputFieldTests, IPrebuildSetup + internal class TouchInputFieldTests : BaseInputFieldTests, IPrebuildSetup { protected const string kPrefabPath = "Assets/Resources/TouchInputFieldPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Layout/HorizonalLayoutGroupTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Layout/HorizonalLayoutGroupTests.cs index 7b36364..140dee6 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Layout/HorizonalLayoutGroupTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Layout/HorizonalLayoutGroupTests.cs @@ -8,7 +8,7 @@ namespace LayoutTests { - public class HorizontalLayoutGroupTests : IPrebuildSetup + internal class HorizontalLayoutGroupTests : IPrebuildSetup { GameObject m_PrefabRoot; const string kPrefabPath = "Assets/Resources/HorizontalLayoutGroupPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupScaling.cs b/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupScaling.cs index 53b4fa4..4b3b58e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupScaling.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupScaling.cs @@ -9,7 +9,7 @@ // test for case 879374 - Checks that layout group children scale properly when scaleWidth / scaleHeight are toggled namespace LayoutTests { - public class LayoutGroupScaling : IPrebuildSetup + internal class LayoutGroupScaling : IPrebuildSetup { GameObject m_PrefabRoot; GameObject m_CameraGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupTests.cs new file mode 100644 index 0000000..c84994b --- /dev/null +++ b/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupTests.cs @@ -0,0 +1,75 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using UnityEngine.UI; + +namespace LayoutTests +{ + [UnityPlatform()] + internal class LayoutGroupTests + { + Canvas m_Canvas; + + [SetUp] + public void TestSetup() + { + m_Canvas = new GameObject("Canvas").AddComponent(); + m_Canvas.renderMode = RenderMode.ScreenSpaceOverlay; + } + + [TearDown] + public void TearDown() + { + GameObject.DestroyImmediate(m_Canvas.gameObject); + } + + [UnityTest] + public IEnumerator EmptyRecttransformUpdatesLayoutGroup() + { + // Canvas + // ....LayoutGroup + // ........"pure" RectTransform <--- we modify the dimensions of this + // ........Image + + // Create VerticalLayoutGroup with spacing=10 + var layoutGroup = new GameObject("LayoutGroup").AddComponent(); + layoutGroup.pivot = new Vector2(0, 1); + layoutGroup.SetParent(m_Canvas.transform, false); + var verticalLayoutGroup = layoutGroup.gameObject.AddComponent(); + verticalLayoutGroup.childForceExpandWidth = false; + verticalLayoutGroup.childForceExpandHeight = false; + verticalLayoutGroup.childControlWidth = false; + verticalLayoutGroup.childControlHeight = false; + verticalLayoutGroup.spacing = 10; + + // Add an empty RectTransfrom with height=100 to the layout group + var emptyChild = new GameObject("EmptyRectTransform").AddComponent(); + emptyChild.pivot = new Vector2(0, 1); + emptyChild.SetParent(layoutGroup, false); + emptyChild.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 100f); + + // Add an image as a sibbling after the empty RectTransform + var image = new GameObject("Image").AddComponent(); + image.pivot = new Vector2(0, 1); + image.transform.SetParent(layoutGroup, false); + image.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 100f); + image.gameObject.AddComponent(); + + yield return null; + + // Verify the test setup + Assert.AreEqual(0f, emptyChild.anchoredPosition.y); + Assert.AreEqual(-110f, image.anchoredPosition.y); // -10 for spacing + + // Expand the empty child + emptyChild.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 200f); + + yield return null; + + // Expanding the empty child should have triggered the layout group to rebuild and push the image down + Assert.AreEqual(0f, emptyChild.anchoredPosition.y); + Assert.AreEqual(-210f, image.anchoredPosition.y); + } + } +} diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupTests.cs.meta b/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupTests.cs.meta new file mode 100644 index 0000000..3e1a408 --- /dev/null +++ b/com.unity.ugui/Tests/Runtime/UGUI/Layout/LayoutGroupTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 30f2a9fda7b63b041a70443bae3e7c01 \ No newline at end of file diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Layout/VerticalLayoutGroupTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Layout/VerticalLayoutGroupTests.cs index dce7c2f..cd82f37 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Layout/VerticalLayoutGroupTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Layout/VerticalLayoutGroupTests.cs @@ -10,7 +10,7 @@ namespace LayoutTests { - public class VerticalLayoutGroupTests : IPrebuildSetup + internal class VerticalLayoutGroupTests : IPrebuildSetup { GameObject m_PrefabRoot; const string kPrefabPath = "Assets/Resources/VerticalLayoutGroupPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/LayoutGroup/LayoutGroupArrangement.cs b/com.unity.ugui/Tests/Runtime/UGUI/LayoutGroup/LayoutGroupArrangement.cs index b45de20..1cf7415 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/LayoutGroup/LayoutGroupArrangement.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/LayoutGroup/LayoutGroupArrangement.cs @@ -6,7 +6,7 @@ using UnityEngine.UI; [TestFixture] -public class LayoutGroupArrangement +internal class LayoutGroupArrangement { const float k_LayoutDefaultSize = 100f; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/MaskClipping/RectMask2DClipping.cs b/com.unity.ugui/Tests/Runtime/UGUI/MaskClipping/RectMask2DClipping.cs index d107c33..c86443a 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/MaskClipping/RectMask2DClipping.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/MaskClipping/RectMask2DClipping.cs @@ -12,7 +12,7 @@ This test checks that a maskableGraphic within a RectMask2D will be properly cli */ namespace UnityEngine.UI.Tests { - public class RectMask2DClipping : IPrebuildSetup + internal class RectMask2DClipping : IPrebuildSetup { GameObject m_PrefabRoot; GameObject m_CameraGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoadScript.cs b/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoadScript.cs index 3945e54..eda1dd9 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoadScript.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoadScript.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.TestTools.Utils; -public class SceneWithNestedLayoutElementsLoadScript : MonoBehaviour +internal class SceneWithNestedLayoutElementsLoadScript : MonoBehaviour { public bool isStartCalled { get; private set; } diff --git a/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoads.cs b/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoads.cs index e561cfa..6c6b9d9 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoads.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/NestedLayout/SceneWithNestedLayoutElementsLoads.cs @@ -9,7 +9,7 @@ [TestFixture] [Category("RegressionTest")] -public class SceneWithNestedLayoutElementsLoad : IPrebuildSetup +internal class SceneWithNestedLayoutElementsLoad : IPrebuildSetup { Scene m_InitScene; const string aspectRatioFitterSceneName = "AspectRatioFitter"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarClamp.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarClamp.cs index dba9a70..aeaa923 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarClamp.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarClamp.cs @@ -9,7 +9,7 @@ using UnityEngine.EventSystems; using UnityEditor; -public class ScrollBarClamp : IPrebuildSetup +internal class ScrollBarClamp : IPrebuildSetup { // This test tests that setting scrollBar.value will not be clamped (case 802330 - Scrollbar stops velocity of 'Scroll Rect' unexpectedly) GameObject m_PrefabRoot; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarTests.cs index 98ba89b..c620f6e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollBar/ScrollBarTests.cs @@ -7,7 +7,7 @@ using UnityEngine.TestTools; using UnityEngine.UI; -public class ScrollBarTests : IPrebuildSetup +internal class ScrollBarTests : IPrebuildSetup { GameObject m_PrefabRoot; const string kPrefabPath = "Assets/Resources/ScrollBarPrefab.prefab"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectClamp.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectClamp.cs index 2c48ef5..4041c28 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectClamp.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectClamp.cs @@ -4,7 +4,7 @@ using NUnit.Framework; using System.Collections; -public class ScrollRectClamp +internal class ScrollRectClamp { // Prefab has the following hierarchy: // - PrefabRoot diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectScale.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectScale.cs index d127066..20b7209 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectScale.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectScale.cs @@ -6,7 +6,7 @@ using UnityEngine.UI; using UnityEditor; -public class ScrollRectScale : IPrebuildSetup +internal class ScrollRectScale : IPrebuildSetup { const string kPrefabPath = "Assets/Resources/ScrollRectScalePrefab.prefab"; public void Setup() diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectStableLayout.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectStableLayout.cs index a0d2270..67e0b03 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectStableLayout.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectStableLayout.cs @@ -11,7 +11,7 @@ Test for case (1010178-Clamped ScrollRect with scalling cause a large spike in performance) */ -public class ScrollRectStableLayout : IPrebuildSetup +internal class ScrollRectStableLayout : IPrebuildSetup { GameObject m_PrefabRoot; GameObject m_CameraGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectTests.cs index aff635c..2ca0d6a 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/ScrollRect/ScrollRectTests.cs @@ -10,7 +10,7 @@ using UnityEngine.TestTools; using System.Runtime.CompilerServices; -public class ScrollRectTests : IPrebuildSetup +internal class ScrollRectTests : IPrebuildSetup { const int ScrollSensitivity = 3; GameObject m_PrefabRoot; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Slider/SliderTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/Slider/SliderTests.cs index 95f0b10..e71a983 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Slider/SliderTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Slider/SliderTests.cs @@ -3,7 +3,7 @@ using UnityEngine; [Category("Slider")] -public class SliderTests +internal class SliderTests { private Slider slider; private GameObject emptyGO; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorBackspaceDelete.cs b/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorBackspaceDelete.cs index 6b3a50f..6b9b37e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorBackspaceDelete.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorBackspaceDelete.cs @@ -4,7 +4,7 @@ using UnityEngine; using UnityEngine.TestTools; -public class TextEditorBackspaceDelete +internal class TextEditorBackspaceDelete { private const string kFailedToRemoveCharacterMessage = "Backspace or Delete Failed To Remove The Expected Character"; private const string kFailedToChangeCursor = "Backspace or Delete Failed To Move The Cursor To The Expected Index"; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorTests.cs index aaa8088..94031c5 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorTests.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/TextEditor/TextEditorTests.cs @@ -3,7 +3,7 @@ using NUnit.Framework; using UnityEngine; -public class TextEditorTests +internal class TextEditorTests { TextEditor m_TextEditor; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Util/ConcreteGraphic.cs b/com.unity.ugui/Tests/Runtime/UGUI/Util/ConcreteGraphic.cs index ac095d6..8616aff 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Util/ConcreteGraphic.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Util/ConcreteGraphic.cs @@ -3,7 +3,7 @@ namespace UnityEngine.UI.Tests { // Make a non-abstract Graphic. - public class ConcreteGraphic : Graphic + internal class ConcreteGraphic : Graphic { public override string ToString() { diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Util/ImageHook.cs b/com.unity.ugui/Tests/Runtime/UGUI/Util/ImageHook.cs index ff580cc..e03a68e 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Util/ImageHook.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Util/ImageHook.cs @@ -6,7 +6,7 @@ namespace UnityEngine.UI.Tests { // Hook into the graphic callback so we can do our check. - public class ImageHook : Image + internal class ImageHook : Image { public bool isGeometryUpdated; public bool isLayoutRebuild; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Util/UIBehaviourExtensions.cs b/com.unity.ugui/Tests/Runtime/UGUI/Util/UIBehaviourExtensions.cs index 722aba6..1af4c7f 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Util/UIBehaviourExtensions.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Util/UIBehaviourExtensions.cs @@ -7,7 +7,7 @@ namespace UnityEngine.UI.Tests { - public static class UIBehaviourExtensions + internal static class UIBehaviourExtensions { private static object InvokeMethodAndRethrow(Type type, Object obj, string methodName, params object[] args) { @@ -90,7 +90,7 @@ public static void InvokeOnDidApplyAnimationProperties(this UIBehaviour behaviou } } - public static class SelectableExtensions + internal static class SelectableExtensions { public static void InvokeOnPointerDown(this Selectable selectable, PointerEventData data) { @@ -123,7 +123,7 @@ public static void InvokeOnSelect(this Selectable selectable, string triggerName } } - public static class GraphicExtension + internal static class GraphicExtension { public static void InvokeOnPopulateMesh(this Graphic graphic, VertexHelper vh) { @@ -131,7 +131,7 @@ public static void InvokeOnPopulateMesh(this Graphic graphic, VertexHelper vh) } } - public static class GraphicRaycasterExtension + internal static class GraphicRaycasterExtension { public static void InvokeRaycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, List results) { @@ -139,7 +139,7 @@ public static void InvokeRaycast(Canvas canvas, Camera eventCamera, Vector2 poin } } - public static class ToggleGroupExtension + internal static class ToggleGroupExtension { public static void InvokeValidateToggleIsInGroup(this ToggleGroup tgroup, Toggle toggle) { From cd97d3485bd0b506484e0218f69213fc9fb68101 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 20 Sep 2025 06:18:48 +0000 Subject: [PATCH 03/26] Mirror com.unity.ugui package (Unity 6000.3.0b4) --- com.unity.ugui/Runtime/TMP/TextMeshPro.cs | 6 ++++-- com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs index 42b8219..67ffbf6 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs @@ -1831,9 +1831,11 @@ internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) } // Handle Multi Atlas Texture support - if (character != null && character.glyph.atlasIndex > 0) + int atlasIndex = m_textInfo.characterInfo[m_totalCharacterCount].alternativeGlyph != null ? m_textInfo.characterInfo[m_totalCharacterCount].alternativeGlyph.atlasIndex : character == null ? 0 : character.glyph.atlasIndex; + + if (character != null && atlasIndex > 0) { - m_currentMaterial = TMP_MaterialManager.GetFallbackMaterial(m_currentFontAsset, m_currentMaterial, character.glyph.atlasIndex); + m_currentMaterial = TMP_MaterialManager.GetFallbackMaterial(m_currentFontAsset, m_currentMaterial, atlasIndex); m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentMaterial, m_currentFontAsset, ref m_materialReferences, m_materialReferenceIndexLookup); diff --git a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index cc9520e..e223850 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -2143,9 +2143,11 @@ internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) } // Handle Multi Atlas Texture support - if (character != null && character.glyph.atlasIndex > 0) + int atlasIndex = m_textInfo.characterInfo[m_totalCharacterCount].alternativeGlyph != null ? m_textInfo.characterInfo[m_totalCharacterCount].alternativeGlyph.atlasIndex : character == null ? 0 : character.glyph.atlasIndex; + + if (character != null && atlasIndex > 0) { - m_currentMaterial = TMP_MaterialManager.GetFallbackMaterial(m_currentFontAsset, m_currentMaterial, character.glyph.atlasIndex); + m_currentMaterial = TMP_MaterialManager.GetFallbackMaterial(m_currentFontAsset, m_currentMaterial, atlasIndex); m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentMaterial, m_currentFontAsset, ref m_materialReferences, m_materialReferenceIndexLookup); From edb0fcd55cb64bb2d5724685121254f0062dd820 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 27 Sep 2025 06:39:07 +0000 Subject: [PATCH 04/26] Mirror com.unity.ugui package (Unity 6000.3.0b5) --- .../Editor/TMP/TMP_BaseEditorPanel.cs | 99 ++++++++++--------- com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs | 18 ++++ 2 files changed, 70 insertions(+), 47 deletions(-) diff --git a/com.unity.ugui/Editor/TMP/TMP_BaseEditorPanel.cs b/com.unity.ugui/Editor/TMP/TMP_BaseEditorPanel.cs index 5881c77..257ee2e 100644 --- a/com.unity.ugui/Editor/TMP/TMP_BaseEditorPanel.cs +++ b/com.unity.ugui/Editor/TMP/TMP_BaseEditorPanel.cs @@ -73,6 +73,7 @@ public abstract class TMP_BaseEditorPanel : Editor static readonly GUIContent k_TopLabel = new GUIContent("Top"); static readonly GUIContent k_RightLabel = new GUIContent("Right"); static readonly GUIContent k_BottomLabel = new GUIContent("Bottom"); + static readonly GUIContent[] k_MarginLabels = { k_LeftLabel, k_TopLabel, k_RightLabel, k_BottomLabel }; protected static readonly GUIContent k_ExtraSettingsLabel = new GUIContent("Extra Settings"); protected static string[] k_UiStateLabel = new string[] { "(Click to collapse) ", "(Click to expand) " }; @@ -80,6 +81,8 @@ public abstract class TMP_BaseEditorPanel : Editor static Dictionary k_AvailableStyles = new Dictionary(); protected Dictionary m_TextStyleIndexLookup = new Dictionary(); + const float kPaddingBetweenMarginFields = 5f; + protected struct Foldout { // Track Inspector foldout panel states, globally. @@ -1126,25 +1129,7 @@ void DrawWrappingOverflow() protected void DrawMargins() { - EditorGUI.BeginChangeCheck(); DrawMarginProperty(m_MarginProp, k_MarginsLabel); - if (EditorGUI.EndChangeCheck()) - { - // Value range check on margins to make sure they are not excessive. - Vector4 margins = m_MarginProp.vector4Value; - Rect textContainerSize = m_RectTransform.rect; - - margins.x = Mathf.Clamp(margins.x, -textContainerSize.width, textContainerSize.width); - margins.z = Mathf.Clamp(margins.z, -textContainerSize.width, textContainerSize.width); - - margins.y = Mathf.Clamp(margins.y, -textContainerSize.height, textContainerSize.height); - margins.w = Mathf.Clamp(margins.w, -textContainerSize.height, textContainerSize.height); - - m_MarginProp.vector4Value = margins; - - m_HavePropertiesChanged = true; - } - EditorGUILayout.Space(); } @@ -1410,49 +1395,70 @@ protected GUIContent[] GetStyleNames() // DRAW MARGIN PROPERTY protected void DrawMarginProperty(SerializedProperty property, GUIContent label) { - Rect rect = EditorGUILayout.GetControlRect(false, 2 * 18); - - EditorGUI.BeginProperty(rect, label, property); + Rect rect = EditorGUILayout.GetControlRect(false, 2 * EditorGUIUtility.singleLineHeight); + rect.y += 2; - Rect pos0 = new Rect(rect.x, rect.y + 2, rect.width - 15, 18); - - float width = rect.width + 3; + Rect pos0 = rect; pos0.width = EditorGUIUtility.labelWidth; - EditorGUI.PrefixLabel(pos0, label); - - Vector4 margins = property.vector4Value; - - float widthB = width - EditorGUIUtility.labelWidth; - float fieldWidth = widthB / 4; - pos0.width = Mathf.Max(fieldWidth - 5, 45f); - // Labels - pos0.x = EditorGUIUtility.labelWidth + 15; - margins.x = DrawMarginField(pos0, "Left", margins.x); + // BeginProperty ensures that the property works correctly with prefabs + EditorGUI.BeginProperty(pos0, label, property); - pos0.x += fieldWidth; - margins.y = DrawMarginField(pos0, "Top", margins.y); + int controlId = GUIUtility.GetControlID(FocusType.Keyboard, pos0); + pos0 = EditorGUI.PrefixLabel(pos0, controlId, label); - pos0.x += fieldWidth; - margins.z = DrawMarginField(pos0, "Right", margins.z); + float width = rect.xMax + kPaddingBetweenMarginFields - pos0.xMin; + float fieldWidth = width / 4f; + pos0.width = Mathf.Max(fieldWidth - kPaddingBetweenMarginFields, 45f); - pos0.x += fieldWidth; - margins.w = DrawMarginField(pos0, "Bottom", margins.w); - - property.vector4Value = margins; + // Draw each margin component by iterating the serialized sub-properties + var subProperty = property.Copy(); + for (int i = 0; i < 4; i++) + { + // The first Next() needs to enter the children + subProperty.Next(i == 0); + // The X (i==0) and Z (i==2) components are horizontal + var axis = i % 2 == 0 ? RectTransform.Axis.Horizontal : RectTransform.Axis.Vertical; + DrawMarginField(pos0, k_MarginLabels[i], subProperty, axis); + pos0.x += fieldWidth; + } EditorGUI.EndProperty(); } - float DrawMarginField(Rect position, string label, float value) + bool DrawMarginField(Rect position, GUIContent label, SerializedProperty prop, RectTransform.Axis axis) { + // BeginProperty ensures that each margin field works correctly with prefabs + EditorGUI.BeginProperty(position, label, prop); + int controlId = GUIUtility.GetControlID(FocusType.Keyboard, position); - EditorGUI.PrefixLabel(position, controlId, new GUIContent(label)); + position.yMax -= EditorGUIUtility.singleLineHeight; + EditorGUI.PrefixLabel(position, controlId, label); - Rect dragZone = new Rect(position.x, position.y, position.width, position.height); + Rect dragZone = position; position.y += EditorGUIUtility.singleLineHeight; - return EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor, position, dragZone, controlId, value, EditorGUI.kFloatFieldFormatString, EditorStyles.numberField, true); + EditorGUI.BeginChangeCheck(); + // Do not update the property value directly. Cache the new + // value and update the property if there was a change. + var newValue = EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor, position, dragZone, controlId, prop.floatValue, EditorGUI.kFloatFieldFormatString, EditorStyles.numberField, true); + bool hasChanged = EditorGUI.EndChangeCheck(); + if (hasChanged) + { + // Loop through all selected objects and calculate their minimum width/height. + float size = float.MaxValue; + foreach (TMP_Text target in serializedObject.targetObjects) + { + var rect = target.rectTransform.rect; + size = Mathf.Min(size, axis == RectTransform.Axis.Horizontal ? rect.width : rect.height); + } + // Clamp the new value to be within the size. + prop.floatValue = Mathf.Clamp(newValue, -size, size); + m_HavePropertiesChanged = true; + } + EditorGUI.EndProperty(); + + return hasChanged; } protected void DrawPropertySlider(GUIContent label, SerializedProperty property) @@ -1467,6 +1473,5 @@ protected void DrawPropertySlider(GUIContent label, SerializedProperty property) // Special Handling of Undo / Redo Events. protected abstract void OnUndoRedo(); - } } diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs index 27c44ec..abe5392 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs @@ -2,6 +2,10 @@ using UnityEngine.Events; using UnityEngine.EventSystems; +#if UNITY_EDITOR +using UnityEditor; +#endif + namespace UnityEngine.UI { [AddComponentMenu("UI/Slider", 34)] @@ -428,10 +432,17 @@ protected override void OnEnable() Set(m_Value, false); // Update rects since they need to be initialized correctly. UpdateVisuals(); +#if UNITY_EDITOR + Undo.undoRedoEvent -= OnUndoRedoEvent; + Undo.undoRedoEvent += OnUndoRedoEvent; +#endif } protected override void OnDisable() { +#if UNITY_EDITOR + Undo.undoRedoEvent -= OnUndoRedoEvent; +#endif m_Tracker.Clear(); base.OnDisable(); } @@ -553,6 +564,13 @@ protected override void OnRectTransformDimensionsChange() UpdateVisuals(); } +#if UNITY_EDITOR + void OnUndoRedoEvent(in UndoRedoInfo undo) + { + UpdateVisuals(); + } +#endif + enum Axis { Horizontal = 0, From 8b9214ff46d09237b7fbe237199d45118d31448d Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 4 Oct 2025 08:03:48 +0000 Subject: [PATCH 05/26] Mirror com.unity.ugui package (Unity 6000.3.0b5) --- .../Editor/TMP/TMP_FontAssetEditor.cs | 68 ++++++++++++------- .../Runtime/TMP/TMP_TextParsingUtilities.cs | 9 +++ com.unity.ugui/Runtime/TMP/TextMeshPro.cs | 52 ++++++++------ com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs | 51 ++++++++------ .../UGUI/UI/Core/Layout/LayoutGroup.cs | 3 +- .../Tests/Editor/TMP/FontEngineTests.cs | 3 +- .../Tests/Editor/TMP/TMP_ControlTests.cs | 2 +- .../Tests/Editor/TMP/TMP_EditorTests.cs | 3 +- .../Tests/Runtime/TMP/TMP_CanvasTests.cs | 3 +- .../Tests/Runtime/TMP/TMP_RuntimeTests.cs | 2 +- 10 files changed, 125 insertions(+), 71 deletions(-) diff --git a/com.unity.ugui/Editor/TMP/TMP_FontAssetEditor.cs b/com.unity.ugui/Editor/TMP/TMP_FontAssetEditor.cs index 4b670cf..62fdada 100644 --- a/com.unity.ugui/Editor/TMP/TMP_FontAssetEditor.cs +++ b/com.unity.ugui/Editor/TMP/TMP_FontAssetEditor.cs @@ -2599,6 +2599,22 @@ void CopyCharacterSerializedProperty(SerializedProperty source, ref SerializedPr } + static List ParseGlyphIndexList(string pattern) + { + var list = new List(); + if (string.IsNullOrWhiteSpace(pattern)) return list; + + var separators = new[] { ',', ';', '|', ' ', '\t' }; + var parts = pattern.Split(separators, StringSplitOptions.RemoveEmptyEntries); + foreach (var p in parts) + { + if (uint.TryParse(p.Trim(), out var id)) + list.Add(id); + } + return list; + } + + /// /// /// @@ -2666,38 +2682,44 @@ void SearchCharacterTable(string searchPattern, ref List searchResults) void SearchLigatureTable(string searchPattern, ref List searchResults) { if (searchResults == null) searchResults = new List(); - searchResults.Clear(); - // Lookup glyph index of potential characters contained in the search pattern. - uint firstGlyphIndex = 0; - TMP_Character firstCharacterSearch; + var requestedGlyphIndexes = ParseGlyphIndexList(searchPattern); + if (requestedGlyphIndexes.Count == 0) + return; - if (searchPattern.Length > 0 && m_fontAsset.characterLookupTable.TryGetValue(searchPattern[0], out firstCharacterSearch)) - firstGlyphIndex = firstCharacterSearch.glyphIndex; + int arraySize = m_LigatureSubstitutionRecords_prop.arraySize; - uint secondGlyphIndex = 0; - TMP_Character secondCharacterSearch; + for (int i = 0; i < arraySize; i++) + { + SerializedProperty record = m_LigatureSubstitutionRecords_prop.GetArrayElementAtIndex(i); - if (searchPattern.Length > 1 && m_fontAsset.characterLookupTable.TryGetValue(searchPattern[1], out secondCharacterSearch)) - secondGlyphIndex = secondCharacterSearch.glyphIndex; + // Build a set of all glyph IDs referenced by this ligature record. + var matches = new HashSet(); - int arraySize = m_MarkToBaseAdjustmentRecords_prop.arraySize; + SerializedProperty componentGlyphIDsProp = record.FindPropertyRelative("m_ComponentGlyphIDs"); + int componentCount = componentGlyphIDsProp.arraySize; + for (int j = 0; j < componentCount; j++) + { + uint componentGlyphID = (uint)componentGlyphIDsProp.GetArrayElementAtIndex(j).intValue; + matches.Add(componentGlyphID); + } - for (int i = 0; i < arraySize; i++) - { - SerializedProperty record = m_MarkToBaseAdjustmentRecords_prop.GetArrayElementAtIndex(i); + uint ligatureGlyphID = (uint)record.FindPropertyRelative("m_LigatureGlyphID").intValue; + matches.Add(ligatureGlyphID); - int baseGlyphIndex = record.FindPropertyRelative("m_BaseGlyphID").intValue; - int markGlyphIndex = record.FindPropertyRelative("m_MarkGlyphID").intValue; + // Require that all requested IDs are present somewhere in this record. + bool hasAll = true; + for (int n = 0; n < requestedGlyphIndexes.Count; n++) + { + if (!matches.Contains(requestedGlyphIndexes[n])) + { + hasAll = false; + break; + } + } - if (firstGlyphIndex == baseGlyphIndex && secondGlyphIndex == markGlyphIndex) - searchResults.Add(i); - else if (searchPattern.Length == 1 && (firstGlyphIndex == baseGlyphIndex || firstGlyphIndex == markGlyphIndex)) - searchResults.Add(i); - else if (baseGlyphIndex.ToString().Contains(searchPattern)) - searchResults.Add(i); - else if (markGlyphIndex.ToString().Contains(searchPattern)) + if (hasAll) searchResults.Add(i); } } diff --git a/com.unity.ugui/Runtime/TMP/TMP_TextParsingUtilities.cs b/com.unity.ugui/Runtime/TMP/TMP_TextParsingUtilities.cs index 3ff3754..fa8dee7 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_TextParsingUtilities.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_TextParsingUtilities.cs @@ -168,6 +168,15 @@ internal static bool IsBaseGlyph(uint c) ); } + + internal static bool IsIgnorableForLigature(uint cp) + { + // ZWJ + VS1..VS16 + (optional) Variation Selectors Supplement + return cp == 0x200D // ZWJ + || (cp >= 0xFE00 && cp <= 0xFE0F) // VS1..VS16 + || (cp >= 0xE0100 && cp <= 0xE01EF); // VS17..VS256 (supplement) + } + /// /// HashSet that contains all known Emojis as per Unicode Emoji 16.0 https://unicode.org/Public/draft/UCD/ucd/emoji/emoji-data.txt /// This HashSet is generated by using the following project https://drive.google.com/file/d/1iWEKEPvqkNoH_iPq3fhPZ5CTCyJETqMd and copy / pasting the resulting string. diff --git a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs index 67ffbf6..8f9c1c3 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs @@ -1431,7 +1431,6 @@ void SetPerspectiveCorrection() m_sharedMaterial.SetFloat(ShaderUtilities.ID_PerspectiveFilter, 0.875f); } - Dictionary materialIndexPairs = new Dictionary(); // This function parses through the Char[] to determine how many characters will be visible. It then makes sure the arrays are large enough for all those characters. internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) @@ -1741,46 +1740,59 @@ internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) { LigatureSubstitutionRecord record = records[j]; + uint[] componentGlyphIDs = record.componentGlyphIDs; int componentCount = record.componentGlyphIDs.Length; uint ligatureGlyphID = record.ligatureGlyphID; - // - for (int k = 1; k < componentCount; k++) + int idx = i + 1; // current input index + int componentIndex = 1; // next component index we still need to match in record.componentGlyphIDs + + // Try to match remaining components, skipping ignorable code points when they aren't the expected component. + while (ligatureGlyphID != 0 && componentIndex < componentCount) { - uint componentUnicode = (uint)textProcessingArray[i + k].unicode; + if (idx >= textProcessingArray.Length) { ligatureGlyphID = 0; break; } - // Special Handling for Zero Width Joiner (ZWJ) - //if (componentUnicode == 0x200D) - // continue; + uint codepoint = textProcessingArray[idx].unicode; + uint glyphIndex = m_currentFontAsset.GetGlyphIndex(codepoint); + uint expect = componentGlyphIDs[componentIndex]; - uint glyphIndex = m_currentFontAsset.GetGlyphIndex(componentUnicode); + // If codepoint is ignorable for ligature matching *and* it is not the expected component, skip it. + if (glyphIndex != expect && TMP_TextParsingUtilities.IsIgnorableForLigature(codepoint)) + { + idx++; + continue; + } - if (glyphIndex == record.componentGlyphIDs[k]) + // Otherwise, we require an exact glyph match for this component. + if (glyphIndex == expect) + { + componentIndex++; + idx++; continue; + } + // Mismatch. ligatureGlyphID = 0; break; } - if (ligatureGlyphID != 0) + // If we matched all components, perform the substitution. + if (ligatureGlyphID != 0 && componentIndex == componentCount) { + // idx now points one past the last code point we consume (including any skipped VS/ZWJ within the cluster). + int spanLen = idx - i; if (m_currentFontAsset.TryAddGlyphInternal(ligatureGlyphID, out Glyph glyph)) { m_textInfo.characterInfo[m_totalCharacterCount].alternativeGlyph = glyph; + textProcessingArray[i].length = spanLen; - // Update text processing array - for (int c = 0; c < componentCount; c++) + // Collapse the entire consumed span into the ligature. + for (int c = 1; c < spanLen; c++) { - if (c == 0) - { - textProcessingArray[i + c].length = componentCount; - continue; - } - - textProcessingArray[i + c].unicode = 0x1A; + textProcessingArray[i + c].unicode = 0x1A; // mark as consumed } - i += componentCount - 1; + i += spanLen - 1; // advance past the cluster break; } } diff --git a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index e223850..6754bbb 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -2053,46 +2053,59 @@ internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) { LigatureSubstitutionRecord record = records[j]; + uint[] componentGlyphIDs = record.componentGlyphIDs; int componentCount = record.componentGlyphIDs.Length; uint ligatureGlyphID = record.ligatureGlyphID; - // - for (int k = 1; k < componentCount; k++) + int idx = i + 1; // current input index + int componentIndex = 1; // next component index we still need to match in record.componentGlyphIDs + + // Try to match remaining components, skipping ignorable code points when they aren't the expected component. + while (ligatureGlyphID != 0 && componentIndex < componentCount) { - uint componentUnicode = (uint)textProcessingArray[i + k].unicode; + if (idx >= textProcessingArray.Length) { ligatureGlyphID = 0; break; } - // Special Handling for Zero Width Joiner (ZWJ) - //if (componentUnicode == 0x200D) - // continue; + uint codepoint = textProcessingArray[idx].unicode; + uint glyphIndex = m_currentFontAsset.GetGlyphIndex(codepoint); + uint expect = componentGlyphIDs[componentIndex]; - uint glyphIndex = m_currentFontAsset.GetGlyphIndex(componentUnicode); + // If codepoint is ignorable for ligature matching *and* it is not the expected component, skip it. + if (glyphIndex != expect && TMP_TextParsingUtilities.IsIgnorableForLigature(codepoint)) + { + idx++; + continue; + } - if (glyphIndex == record.componentGlyphIDs[k]) + // Otherwise, we require an exact glyph match for this component. + if (glyphIndex == expect) + { + componentIndex++; + idx++; continue; + } + // Mismatch. ligatureGlyphID = 0; break; } - if (ligatureGlyphID != 0) + // If we matched all components, perform the substitution. + if (ligatureGlyphID != 0 && componentIndex == componentCount) { + // idx now points one past the last code point we consume (including any skipped VS/ZWJ within the cluster). + int spanLen = idx - i; if (m_currentFontAsset.TryAddGlyphInternal(ligatureGlyphID, out Glyph glyph)) { m_textInfo.characterInfo[m_totalCharacterCount].alternativeGlyph = glyph; + textProcessingArray[i].length = spanLen; - // Update text processing array - for (int c = 0; c < componentCount; c++) + // Collapse the entire consumed span into the ligature. + for (int c = 1; c < spanLen; c++) { - if (c == 0) - { - textProcessingArray[i + c].length = componentCount; - continue; - } - - textProcessingArray[i + c].unicode = 0x1A; + textProcessingArray[i + c].unicode = 0x1A; // mark as consumed } - i += componentCount - 1; + i += spanLen - 1; // advance past the cluster break; } } diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutGroup.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutGroup.cs index ded5d81..6c14ff9 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutGroup.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutGroup.cs @@ -344,7 +344,8 @@ protected virtual void OnTransformChildrenChanged() /// protected virtual void OnChildRectTransformDimensionsChange() { - SetDirty(); + if (!CanvasUpdateRegistry.IsRebuildingLayout()) + SetDirty(); } /// diff --git a/com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs b/com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs index c3d0528..64a3fe1 100644 --- a/com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs +++ b/com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs @@ -3,11 +3,10 @@ using NUnit.Framework; using UnityEngine.TextCore.LowLevel; - namespace TMPro { [Category("Text Parsing & Layout")] - class FontEngineTests + internal class FontEngineTests { [OneTimeSetUp] public void Setup() diff --git a/com.unity.ugui/Tests/Editor/TMP/TMP_ControlTests.cs b/com.unity.ugui/Tests/Editor/TMP/TMP_ControlTests.cs index b216b6f..81feba1 100644 --- a/com.unity.ugui/Tests/Editor/TMP/TMP_ControlTests.cs +++ b/com.unity.ugui/Tests/Editor/TMP/TMP_ControlTests.cs @@ -5,7 +5,7 @@ namespace TMPro { - public class TMP_ControlTests + internal class TMP_ControlTests { Scene scene; [SetUp] diff --git a/com.unity.ugui/Tests/Editor/TMP/TMP_EditorTests.cs b/com.unity.ugui/Tests/Editor/TMP/TMP_EditorTests.cs index 132a62d..3982db8 100644 --- a/com.unity.ugui/Tests/Editor/TMP/TMP_EditorTests.cs +++ b/com.unity.ugui/Tests/Editor/TMP/TMP_EditorTests.cs @@ -3,11 +3,10 @@ using NUnit.Framework; using System.IO; - namespace TMPro { [Category("Text Parsing & Layout")] - class TMP_EditorTests + internal class TMP_EditorTests { private TextMeshPro m_TextComponent; diff --git a/com.unity.ugui/Tests/Runtime/TMP/TMP_CanvasTests.cs b/com.unity.ugui/Tests/Runtime/TMP/TMP_CanvasTests.cs index 3078d15..67e2c69 100644 --- a/com.unity.ugui/Tests/Runtime/TMP/TMP_CanvasTests.cs +++ b/com.unity.ugui/Tests/Runtime/TMP/TMP_CanvasTests.cs @@ -5,10 +5,9 @@ using UnityEngine.UI; using UnityEngine.EventSystems; - namespace TMPro { - public class TMP_CanvasTests + internal class TMP_CanvasTests { [OneTimeSetUp] public void Setup() diff --git a/com.unity.ugui/Tests/Runtime/TMP/TMP_RuntimeTests.cs b/com.unity.ugui/Tests/Runtime/TMP/TMP_RuntimeTests.cs index ac4ec00..73a5039 100644 --- a/com.unity.ugui/Tests/Runtime/TMP/TMP_RuntimeTests.cs +++ b/com.unity.ugui/Tests/Runtime/TMP/TMP_RuntimeTests.cs @@ -9,7 +9,7 @@ namespace TMPro { [Category("Text Parsing & Layout")] - class TMP_RuntimeTests + internal class TMP_RuntimeTests { private TextMeshPro m_TextComponent; From 94e5c79924f192f438247f9da847a4e0deaa1fe1 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 11 Oct 2025 05:55:41 +0000 Subject: [PATCH 06/26] Mirror com.unity.ugui package (Unity 6000.3.0b7) --- .../Runtime/TMP/TMP_TextParsingUtilities.cs | 79 +++++++++++++------ com.unity.ugui/Runtime/TMP/TextMeshPro.cs | 1 + com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs | 1 + .../Runtime/UGUI/UI/Core/RawImage.cs | 35 ++++---- 4 files changed, 75 insertions(+), 41 deletions(-) diff --git a/com.unity.ugui/Runtime/TMP/TMP_TextParsingUtilities.cs b/com.unity.ugui/Runtime/TMP/TMP_TextParsingUtilities.cs index fa8dee7..3bc5ad4 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_TextParsingUtilities.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_TextParsingUtilities.cs @@ -275,32 +275,59 @@ internal static bool IsHangul(uint c) internal static bool IsCJK(uint c) { - return c >= 0x3100 && c <= 0x312F || /* Bopomofo */ - c >= 0x31A0 && c <= 0x31BF || /* Bopomofo Extended */ - c >= 0x4E00 && c <= 0x9FFF || /* CJK Unified Ideographs (Han) */ - c >= 0x3400 && c <= 0x4DBF || /* CJK Extension A */ - c >= 0x20000 && c <= 0x2A6DF || /* CJK Extension B */ - c >= 0x2A700 && c <= 0x2B73F || /* CJK Extension C */ - c >= 0x2B740 && c <= 0x2B81F || /* CJK Extension D */ - c >= 0x2B820 && c <= 0x2CEAF || /* CJK Extension E */ - c >= 0x2CEB0 && c <= 0x2EBE0 || /* CJK Extension F */ - c >= 0x30000 && c <= 0x3134A || /* CJK Extension G */ - c >= 0xF900 && c <= 0xFAFF || /* CJK Compatibility Ideographs */ - c >= 0x2F800 && c <= 0x2FA1F || /* CJK Compatibility Ideographs Supplement */ - c >= 0x2F00 && c <= 0x2FDF || /* CJK Radicals / Kangxi Radicals */ - c >= 0x2E80 && c <= 0x2EFF || /* CJK Radicals Supplement */ - c >= 0x31C0 && c <= 0x31EF || /* CJK Strokes */ - c >= 0x2FF0 && c <= 0x2FFF || /* Ideographic Description Characters */ - c >= 0x3040 && c <= 0x309F || /* Hiragana */ - c >= 0x1B100 && c <= 0x1B12F || /* Kana Extended-A */ - c >= 0x1AFF0 && c <= 0x1AFFF || /* Kana Extended-B */ - c >= 0x1B000 && c <= 0x1B0FF || /* Kana Supplement */ - c >= 0x1B130 && c <= 0x1B16F || /* Small Kana Extension */ - c >= 0x3190 && c <= 0x319F || /* Kanbun */ - c >= 0x30A0 && c <= 0x30FF || /* Katakana */ - c >= 0x31F0 && c <= 0x31FF || /* Katakana Phonetic Extensions */ - c >= 0xFF65 && c <= 0xFF9F; /* Halfwidth Katakana */ + // Han Ideographs and Extensions (Unified CJK) + if ((c >= 0x4E00 && c <= 0x9FFF) || // CJK Unified Ideographs + (c >= 0x3400 && c <= 0x4DBF) || // CJK Extension A + (c >= 0x20000 && c <= 0x2A6DF) || // CJK Extension B + (c >= 0x2A700 && c <= 0x2B73F) || // CJK Extension C + (c >= 0x2B740 && c <= 0x2B81F) || // CJK Extension D + (c >= 0x2B820 && c <= 0x2CEAF) || // CJK Extension E + (c >= 0x2CEB0 && c <= 0x2EBE0) || // CJK Extension F + (c >= 0x30000 && c <= 0x3134A) || // CJK Extension G + (c >= 0x31350 && c <= 0x323AF)) // CJK Extension H + return true; + + // CJK Compatibility Ideographs + if ((c >= 0xF900 && c <= 0xFAFF) || // Compatibility Ideographs + (c >= 0x2F800 && c <= 0x2FA1F)) // Compatibility Ideographs Supplement + return true; + + // Japanese + if ((c >= 0x3040 && c <= 0x309F) || // Hiragana + (c >= 0x30A0 && c <= 0x30FF) || // Katakana + (c >= 0x31F0 && c <= 0x31FF) || // Katakana Phonetic Extensions + (c >= 0x1B000 && c <= 0x1B0FF) || // Kana Supplement + (c >= 0x1B100 && c <= 0x1B12F) || // Kana Extended-A + (c >= 0x1AFF0 && c <= 0x1AFFF) || // Kana Extended-B + (c >= 0x1B130 && c <= 0x1B16F)) // Small Kana Extension + return true; + + // Chinese phonetics (Zhuyin/Bopomofo) + if ((c >= 0x3100 && c <= 0x312F) || // Bopomofo + (c >= 0x31A0 && c <= 0x31BF)) // Bopomofo Extended + return true; + + // Radicals, Description Characters, Strokes + if ((c >= 0x2E80 && c <= 0x2EFF) || // CJK Radicals Supplement + (c >= 0x2F00 && c <= 0x2FDF) || // Kangxi Radicals + (c >= 0x2FF0 && c <= 0x2FFF) || // Ideographic Description Characters + (c >= 0x31C0 && c <= 0x31EF)) // CJK Strokes + return true; + + // Punctuation and Symbols + if ((c >= 0x3000 && c <= 0x303F) || // CJK Symbols and Punctuation + (c >= 0x3190 && c <= 0x319F) || // Kanbun + (c >= 0x16FE0 && c <= 0x16FFF)) // Ideographic Symbols and Punctuation + return true; + + // Compatibility Forms and Halfwidth / Fullwidth + if ((c >= 0xFE10 && c <= 0xFE1F) || // Vertical Forms + (c >= 0xFE30 && c <= 0xFE4F) || // CJK Compatibility Forms + (c >= 0xFE50 && c <= 0xFE6F) || // Small Form Variants + (c >= 0xFF65 && c <= 0xFF9F)) // Halfwidth Katakana (JP) + return true; + + return false; } - } } diff --git a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs index 8f9c1c3..b59b5c5 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs @@ -1452,6 +1452,7 @@ internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) m_currentFontAsset = m_fontAsset; m_currentMaterial = m_sharedMaterial; m_currentMaterialIndex = 0; + materialIndexPairs.Clear(); m_materialReferenceStack.SetDefault(new MaterialReference(m_currentMaterialIndex, m_currentFontAsset, null, m_currentMaterial, m_padding)); diff --git a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index 6754bbb..66ee704 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -1753,6 +1753,7 @@ internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) m_currentFontAsset = m_fontAsset; m_currentMaterial = m_sharedMaterial; m_currentMaterialIndex = 0; + materialIndexPairs.Clear(); m_materialReferenceStack.SetDefault(new MaterialReference(m_currentMaterialIndex, m_currentFontAsset, null, m_currentMaterial, m_padding)); diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/RawImage.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/RawImage.cs index fb33060..bd6fd67 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/RawImage.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/RawImage.cs @@ -1,5 +1,3 @@ -using System; -using System.Collections.Generic; using UnityEngine.Serialization; namespace UnityEngine.UI @@ -42,7 +40,13 @@ public override Texture mainTexture return s_WhiteTexture; } - return m_Texture; + // Patch fix for UUM-117371. + // If m_Texture is set as a non-matching type from native side this will ensure that dependent code will be able to null-check. + // Proposed fix involved safe-casting to Texture2D, but RawImage must support any Texture subclass. + // We can't safe-cast m_Texture to Texture directly, as the managed runtime assumes it's already a Texture and does nothing. + // Instead, cast to a System.Object and check that. + object objReference = m_Texture; + return objReference as Texture; } } @@ -138,20 +142,21 @@ protected override void OnPopulateMesh(VertexHelper vh) vh.Clear(); if (tex != null) { - var r = GetPixelAdjustedRect(); + Rect r = GetPixelAdjustedRect(); var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height); - var scaleX = tex.width * tex.texelSize.x; - var scaleY = tex.height * tex.texelSize.y; - { - var color32 = color; - vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(m_UVRect.xMin * scaleX, m_UVRect.yMin * scaleY)); - vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(m_UVRect.xMin * scaleX, m_UVRect.yMax * scaleY)); - vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(m_UVRect.xMax * scaleX, m_UVRect.yMax * scaleY)); - vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(m_UVRect.xMax * scaleX, m_UVRect.yMin * scaleY)); - vh.AddTriangle(0, 1, 2); - vh.AddTriangle(2, 3, 0); - } + Vector2 texTexelSize = tex.texelSize; + float scaleX = tex.width * texTexelSize.x; + float scaleY = tex.height * texTexelSize.y; + + Color32 color32 = color; + vh.AddVert(new Vector3(v.x, v.y), color32, new Vector4(m_UVRect.xMin * scaleX, m_UVRect.yMin * scaleY)); + vh.AddVert(new Vector3(v.x, v.w), color32, new Vector4(m_UVRect.xMin * scaleX, m_UVRect.yMax * scaleY)); + vh.AddVert(new Vector3(v.z, v.w), color32, new Vector4(m_UVRect.xMax * scaleX, m_UVRect.yMax * scaleY)); + vh.AddVert(new Vector3(v.z, v.y), color32, new Vector4(m_UVRect.xMax * scaleX, m_UVRect.yMin * scaleY)); + + vh.AddTriangle(0, 1, 2); + vh.AddTriangle(2, 3, 0); } } From 5f12e1b8962e345dc33c916013728adb203e1efe Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 18 Oct 2025 05:55:54 +0000 Subject: [PATCH 07/26] Mirror com.unity.ugui package (Unity 6000.3.0b8) --- com.unity.ugui/Runtime/TMP/TMP_Text.cs | 17 +++++++---------- com.unity.ugui/Runtime/TMP/TextMeshPro.cs | 13 +++++-------- com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs | 13 +++++-------- .../UIToolkitInteroperabilityBridge.cs | 16 ++++++++++++++-- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/com.unity.ugui/Runtime/TMP/TMP_Text.cs b/com.unity.ugui/Runtime/TMP/TMP_Text.cs index 528102d..39257ba 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_Text.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_Text.cs @@ -4511,7 +4511,6 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m float baselineAdjustmentDelta = m_maxLineAscender - m_startOfLineAscender; if (m_lineOffset > 0 && Math.Abs(baselineAdjustmentDelta) > 0.01f && m_IsDrivenLineSpacing == false && !m_isNewPage) { - //AdjustLineOffset(m_firstCharacterOfLine, m_characterCount, baselineAdjustmentDelta); m_ElementDescender -= baselineAdjustmentDelta; m_lineOffset += baselineAdjustmentDelta; } @@ -4576,9 +4575,9 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m if (m_lineOffset > 0 && !TMP_Math.Approximately(m_maxLineAscender, m_startOfLineAscender) && m_IsDrivenLineSpacing == false && !m_isNewPage) { float offsetDelta = m_maxLineAscender - m_startOfLineAscender; - //AdjustLineOffset(m_firstCharacterOfLine, m_characterCount, offsetDelta); m_ElementDescender -= offsetDelta; m_lineOffset += offsetDelta; + m_RenderedHeight += offsetDelta; m_startOfLineAscender += offsetDelta; internalWordWrapState.lineOffset = m_lineOffset; @@ -4651,6 +4650,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m m_lineNumber += 1; m_firstCharacterOfLine = m_characterCount + 1; + isFirstWordOfLine = true; float ascender = m_internalCharacterInfo[m_characterCount].adjustedAscender; @@ -4690,6 +4690,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m { bool shouldSaveHardLineBreak = false; bool shouldSaveSoftLineBreak = false; + uint nextChar = m_characterCount + 1 < totalCharacterCount ? m_textInfo.characterInfo[m_characterCount + 1].character : 0u; if ((isWhiteSpace || charCode == 0x200B || charCode == 0x2D || charCode == 0xAD) && (!m_isNonBreakingSpace || ignoreNonBreakingSpace) && charCode != 0xA0 && charCode != 0x2007 && charCode != 0x2011 && charCode != 0x202F && charCode != 0x2060) { @@ -4707,7 +4708,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m else if (m_isNonBreakingSpace == false && (TMP_TextParsingUtilities.IsHangul(charCode) && TMP_Settings.useModernHangulLineBreakingRules == false || TMP_TextParsingUtilities.IsCJK(charCode))) { bool isCurrentLeadingCharacter = TMP_Settings.linebreakingRules.leadingCharacters.Contains(charCode); - bool isNextFollowingCharacter = m_characterCount < totalCharacterCount - 1 && TMP_Settings.linebreakingRules.followingCharacters.Contains(m_internalCharacterInfo[m_characterCount + 1].character); + bool isNextFollowingCharacter = m_characterCount < totalCharacterCount - 1 && TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar); if (isCurrentLeadingCharacter == false) { @@ -4738,14 +4739,10 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m } } } - // Special handling for Latin characters followed by a CJK character. - else if (!m_isNonBreakingSpace && (m_characterCount + 1) < totalCharacterCount && TMP_TextParsingUtilities.IsCJK(m_textInfo.characterInfo[m_characterCount + 1].character)) + // Handling for Latin characters followed by a CJK character that is not a following character. + else if (m_isNonBreakingSpace == false && TMP_TextParsingUtilities.IsCJK(nextChar) && !TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar)) { - uint nextChar = m_textInfo.characterInfo[m_characterCount + 1].character; - bool prevIsLeading = TMP_Settings.linebreakingRules.leadingCharacters.Contains(charCode); - bool nextIsFollowing = TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar); - if (!prevIsLeading && !nextIsFollowing) - shouldSaveHardLineBreak = true; + shouldSaveHardLineBreak = true; } else if (isFirstWordOfLine) { diff --git a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs index b59b5c5..e8236eb 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs @@ -4062,6 +4062,7 @@ protected virtual void GenerateTextMesh() bool shouldSaveHardLineBreak = false; bool shouldSaveSoftLineBreak = false; + uint nextChar = m_characterCount + 1 < totalCharacterCount ? m_textInfo.characterInfo[m_characterCount + 1].character : 0u; if ((isWhiteSpace || charCode == 0x200B || charCode == 0x2D || charCode == 0xAD) && (!m_isNonBreakingSpace || ignoreNonBreakingSpace) && charCode != 0xA0 && charCode != 0x2007 && charCode != 0x2011 && charCode != 0x202F && charCode != 0x2060) { @@ -4079,7 +4080,7 @@ protected virtual void GenerateTextMesh() else if (m_isNonBreakingSpace == false && (TMP_TextParsingUtilities.IsHangul(charCode) && TMP_Settings.useModernHangulLineBreakingRules == false || TMP_TextParsingUtilities.IsCJK(charCode))) { bool isCurrentLeadingCharacter = TMP_Settings.linebreakingRules.leadingCharacters.Contains(charCode); - bool isNextFollowingCharacter = m_characterCount < totalCharacterCount - 1 && TMP_Settings.linebreakingRules.followingCharacters.Contains(m_textInfo.characterInfo[m_characterCount + 1].character); + bool isNextFollowingCharacter = m_characterCount < totalCharacterCount - 1 && TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar); if (isCurrentLeadingCharacter == false) { @@ -4110,14 +4111,10 @@ protected virtual void GenerateTextMesh() } } } - // Special handling for Latin characters followed by a CJK character. - else if (!m_isNonBreakingSpace && (m_characterCount + 1) < totalCharacterCount && TMP_TextParsingUtilities.IsCJK(m_textInfo.characterInfo[m_characterCount + 1].character)) + // Handling for Latin characters followed by a CJK character that is not a following character. + else if (m_isNonBreakingSpace == false && TMP_TextParsingUtilities.IsCJK(nextChar) && !TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar)) { - uint nextChar = m_textInfo.characterInfo[m_characterCount + 1].character; - bool prevIsLeading = TMP_Settings.linebreakingRules.leadingCharacters.Contains(charCode); - bool nextIsFollowing = TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar); - if (!prevIsLeading && !nextIsFollowing) - shouldSaveHardLineBreak = true; + shouldSaveHardLineBreak = true; } else if (isFirstWordOfLine) { diff --git a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index 66ee704..3a50383 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -4411,6 +4411,7 @@ protected virtual void GenerateTextMesh() bool shouldSaveHardLineBreak = false; bool shouldSaveSoftLineBreak = false; + uint nextChar = m_characterCount + 1 < totalCharacterCount ? m_textInfo.characterInfo[m_characterCount + 1].character : 0u; if ((isWhiteSpace || charCode == 0x200B || charCode == 0x2D || charCode == 0xAD) && (!m_isNonBreakingSpace || ignoreNonBreakingSpace) && charCode != 0xA0 && charCode != 0x2007 && charCode != 0x2011 && charCode != 0x202F && charCode != 0x2060) { @@ -4428,7 +4429,7 @@ protected virtual void GenerateTextMesh() else if (m_isNonBreakingSpace == false && (TMP_TextParsingUtilities.IsHangul(charCode) && TMP_Settings.useModernHangulLineBreakingRules == false || TMP_TextParsingUtilities.IsCJK(charCode))) { bool isCurrentLeadingCharacter = TMP_Settings.linebreakingRules.leadingCharacters.Contains(charCode); - bool isNextFollowingCharacter = m_characterCount < totalCharacterCount - 1 && TMP_Settings.linebreakingRules.followingCharacters.Contains(m_textInfo.characterInfo[m_characterCount + 1].character); + bool isNextFollowingCharacter = m_characterCount < totalCharacterCount - 1 && TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar); if (isCurrentLeadingCharacter == false) { @@ -4459,14 +4460,10 @@ protected virtual void GenerateTextMesh() } } } - // Special handling for Latin characters followed by a CJK character. - else if (!m_isNonBreakingSpace && (m_characterCount + 1) < totalCharacterCount && TMP_TextParsingUtilities.IsCJK(m_textInfo.characterInfo[m_characterCount + 1].character)) + // Handling for Latin characters followed by a CJK character that is not a following character. + else if (m_isNonBreakingSpace == false && TMP_TextParsingUtilities.IsCJK(nextChar) && !TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar)) { - uint nextChar = m_textInfo.characterInfo[m_characterCount + 1].character; - bool prevIsLeading = TMP_Settings.linebreakingRules.leadingCharacters.Contains(charCode); - bool nextIsFollowing = TMP_Settings.linebreakingRules.followingCharacters.Contains(nextChar); - if (!prevIsLeading && !nextIsFollowing) - shouldSaveHardLineBreak = true; + shouldSaveHardLineBreak = true; } else if (isFirstWordOfLine) { diff --git a/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/UIToolkitInteroperabilityBridge.cs b/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/UIToolkitInteroperabilityBridge.cs index ae3a2e7..f94e796 100644 --- a/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/UIToolkitInteroperabilityBridge.cs +++ b/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/UIToolkitInteroperabilityBridge.cs @@ -143,7 +143,7 @@ private void CreatePanelGameObject(BaseRuntimePanel panel) var go = new GameObject(panel.name, typeof(PanelEventHandler), typeof(PanelRaycaster)); go.transform.SetParent(m_EventSystem.transform); panel.selectableGameObject = go; - var destroyed = destroyedActions[panel] = () => UIRUtility.Destroy(go); + var destroyed = destroyedActions[panel] = () => DestroyPanelGameObject(panel); panel.destroyed += destroyed; } } @@ -339,18 +339,30 @@ private void UpdatePanelTracking() } } + private List m_PanelsToRemove = new(); private void UpdatePanelGameObjects() { if (!m_IsTrackingPanels) return; bool isWorldSpaceActive = false; - foreach (var panel in trackedPanels) { + if (panel.disposed) + { + m_PanelsToRemove.Add(panel); + continue; + } + UpdatePanelGameObject(panel); isWorldSpaceActive |= !panel.isFlat; } + foreach (var panel in m_PanelsToRemove) + { + trackedPanels.Remove(panel); + } + m_PanelsToRemove.Clear(); + if (isWorldSpaceActive && (m_HandlerTypes & EventHandlerTypes.WorldSpace) != 0) { CreateWorldSpacePanelGameObject(); From 24ed588f0baf85b431b5f4ee4c194095ab67e965 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 25 Oct 2025 05:55:49 +0000 Subject: [PATCH 08/26] Mirror com.unity.ugui package (Unity 6000.3.0b9) --- .../Editor/TMP/TMP_FontAssetEditor.cs | 2 +- .../UIElements/PanelEventHandler.cs | 4 ++++ .../UGUI/UI/Core/Layout/LayoutRebuilder.cs | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/com.unity.ugui/Editor/TMP/TMP_FontAssetEditor.cs b/com.unity.ugui/Editor/TMP/TMP_FontAssetEditor.cs index 62fdada..80aaee5 100644 --- a/com.unity.ugui/Editor/TMP/TMP_FontAssetEditor.cs +++ b/com.unity.ugui/Editor/TMP/TMP_FontAssetEditor.cs @@ -2445,7 +2445,7 @@ GlyphPairAdjustmentRecord GetGlyphPairAdjustmentRecord(SerializedProperty proper // TODO : Need to revise how Everything is handled in the event more enum values are added. int flagValue = property.FindPropertyRelative("m_FeatureLookupFlags").intValue; - //pairAdjustmentRecord.featureLookupFlags = flagValue == -1 ? FontFeatureLookupFlags.IgnoreLigatures | FontFeatureLookupFlags.IgnoreSpacingAdjustments : (FontFeatureLookupFlags) flagValue; + pairAdjustmentRecord.featureLookupFlags = (UnityEngine.TextCore.LowLevel.FontFeatureLookupFlags)flagValue; return pairAdjustmentRecord; } diff --git a/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelEventHandler.cs b/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelEventHandler.cs index bb6ce08..cbe2f98 100644 --- a/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelEventHandler.cs +++ b/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelEventHandler.cs @@ -151,6 +151,10 @@ public void OnPointerDown(PointerEventData eventData) if (!ReadPointerData(m_PointerEvent, eventData, PointerEventType.Down)) return; + // Allow KeyDown/KeyUp events to be processed before pointer events. + var target = currentFocusedElement ?? m_Panel.visualTree; + ProcessImguiEvents(target); + if (eventSystem != null) eventSystem.SetSelectedGameObject(selectableGameObject); diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutRebuilder.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutRebuilder.cs index 48db463..eef4283 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutRebuilder.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutRebuilder.cs @@ -195,6 +195,25 @@ public static void MarkLayoutForRebuild(RectTransform rect) parent = parent.parent as RectTransform; } +#if UNITY_EDITOR + //Child ILayoutGroup components from the root need to be marked for layout rebuild. + //UUM-100091: Ideally, we'd want a broader fix. This change narrowly addresses the bug. + using (ListPool.Get(out var layoutComps)) + { + layoutRoot.GetComponentsInChildren(layoutComps); + foreach (var layout in layoutComps) + { + if (layout is Behaviour behaviour && behaviour.isActiveAndEnabled) + { + if (ReferenceEquals(behaviour.gameObject, layoutRoot.gameObject)) + continue; + + MarkLayoutRootForRebuild(behaviour.transform as RectTransform); + } + } + } +#endif + // We know the layout root is valid if it's not the same as the rect, // since we checked that above. But if they're the same we still need to check. if (layoutRoot == rect && !ValidController(layoutRoot, comps)) From 62e1ab28b15d4c7ff832b36cf2618ff6ac988730 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 1 Nov 2025 06:12:02 +0000 Subject: [PATCH 09/26] Mirror com.unity.ugui package (Unity 6000.3.0b10) --- .../UGUI/UI/InterceptedEventsPreview.cs | 18 ---------- com.unity.ugui/Runtime/TMP/TextMeshPro.cs | 33 ++++++------------- com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs | 33 ++++++------------- 3 files changed, 20 insertions(+), 64 deletions(-) diff --git a/com.unity.ugui/Editor/UGUI/UI/InterceptedEventsPreview.cs b/com.unity.ugui/Editor/UGUI/UI/InterceptedEventsPreview.cs index 4ea4eef..9b92d9c 100644 --- a/com.unity.ugui/Editor/UGUI/UI/InterceptedEventsPreview.cs +++ b/com.unity.ugui/Editor/UGUI/UI/InterceptedEventsPreview.cs @@ -27,25 +27,7 @@ class Styles public Styles() { - Color fontColor = new Color(0.7f, 0.7f, 0.7f); labelStyle.padding.right += 20; - labelStyle.normal.textColor = fontColor; - labelStyle.active.textColor = fontColor; - labelStyle.focused.textColor = fontColor; - labelStyle.hover.textColor = fontColor; - labelStyle.onNormal.textColor = fontColor; - labelStyle.onActive.textColor = fontColor; - labelStyle.onFocused.textColor = fontColor; - labelStyle.onHover.textColor = fontColor; - - componentName.normal.textColor = fontColor; - componentName.active.textColor = fontColor; - componentName.focused.textColor = fontColor; - componentName.hover.textColor = fontColor; - componentName.onNormal.textColor = fontColor; - componentName.onActive.textColor = fontColor; - componentName.onFocused.textColor = fontColor; - componentName.onHover.textColor = fontColor; } } diff --git a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs index e8236eb..5904204 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs @@ -2806,39 +2806,26 @@ protected virtual void GenerateTextMesh() // Set Padding based on selected font style #region Handle Style Padding - float boldSpacingAdjustment; - float style_padding; - if (m_textElementType == TMP_TextElementType.Character && !isUsingAltTypeface && ((m_FontStyleInternal & FontStyles.Bold) == FontStyles.Bold)) // Checks for any combination of Bold Style. - { - if (m_currentMaterial != null && m_currentMaterial.HasProperty(ShaderUtilities.ID_GradientScale)) - { - float gradientScale = m_currentMaterial.GetFloat(ShaderUtilities.ID_GradientScale); - style_padding = m_currentFontAsset.boldStyle / 4.0f * gradientScale * m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A); - - // Clamp overall padding to Gradient Scale size. - if (style_padding + padding > gradientScale) - padding = gradientScale - style_padding; - } - else - style_padding = 0; + float boldSpacingAdjustment = 0; + float style_padding = 0; - boldSpacingAdjustment = m_currentFontAsset.boldSpacing; - } - else + if (m_textElementType == TMP_TextElementType.Character) { + bool isBold = !isUsingAltTypeface && (m_FontStyleInternal & FontStyles.Bold) == FontStyles.Bold; + boldSpacingAdjustment = isBold ? m_currentFontAsset.boldSpacing : 0; + if (m_currentMaterial != null && m_currentMaterial.HasProperty(ShaderUtilities.ID_GradientScale) && m_currentMaterial.HasProperty(ShaderUtilities.ID_ScaleRatio_A)) { float gradientScale = m_currentMaterial.GetFloat(ShaderUtilities.ID_GradientScale); - style_padding = m_currentFontAsset.normalStyle / 4.0f * gradientScale * m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A); + float scaleRatioA = m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A); + float styleModifier = isBold ? m_currentFontAsset.boldStyle : m_currentFontAsset.normalStyle; + + style_padding = styleModifier * 0.25f * gradientScale * scaleRatioA; // Clamp overall padding to Gradient Scale size. if (style_padding + padding > gradientScale) padding = gradientScale - style_padding; } - else - style_padding = 0; - - boldSpacingAdjustment = 0; } #endregion Handle Style Padding diff --git a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index 3a50383..1f86561 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -3155,39 +3155,26 @@ protected virtual void GenerateTextMesh() // Set Padding based on selected font style #region Handle Style Padding - float boldSpacingAdjustment; - float style_padding; - if (m_textElementType == TMP_TextElementType.Character && !isUsingAltTypeface && ((m_FontStyleInternal & FontStyles.Bold) == FontStyles.Bold)) // Checks for any combination of Bold Style. - { - if (m_currentMaterial != null && m_currentMaterial.HasProperty(ShaderUtilities.ID_GradientScale)) - { - float gradientScale = m_currentMaterial.GetFloat(ShaderUtilities.ID_GradientScale); - style_padding = m_currentFontAsset.boldStyle / 4.0f * gradientScale * m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A); - - // Clamp overall padding to Gradient Scale size. - if (style_padding + padding > gradientScale) - padding = gradientScale - style_padding; - } - else - style_padding = 0; + float boldSpacingAdjustment = 0; + float style_padding = 0; - boldSpacingAdjustment = m_currentFontAsset.boldSpacing; - } - else + if (m_textElementType == TMP_TextElementType.Character) { + bool isBold = !isUsingAltTypeface && (m_FontStyleInternal & FontStyles.Bold) == FontStyles.Bold; + boldSpacingAdjustment = isBold ? m_currentFontAsset.boldSpacing : 0; + if (m_currentMaterial != null && m_currentMaterial.HasProperty(ShaderUtilities.ID_GradientScale) && m_currentMaterial.HasProperty(ShaderUtilities.ID_ScaleRatio_A)) { float gradientScale = m_currentMaterial.GetFloat(ShaderUtilities.ID_GradientScale); - style_padding = m_currentFontAsset.normalStyle / 4.0f * gradientScale * m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A); + float scaleRatioA = m_currentMaterial.GetFloat(ShaderUtilities.ID_ScaleRatio_A); + float styleModifier = isBold ? m_currentFontAsset.boldStyle : m_currentFontAsset.normalStyle; + + style_padding = styleModifier * 0.25f * gradientScale * scaleRatioA; // Clamp overall padding to Gradient Scale size. if (style_padding + padding > gradientScale) padding = gradientScale - style_padding; } - else - style_padding = 0; - - boldSpacingAdjustment = 0; } #endregion Handle Style Padding From ac2cbeab0f6665640169452d44e98ddb6b404f1c Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 15 Nov 2025 05:55:34 +0000 Subject: [PATCH 10/26] Mirror com.unity.ugui package (Unity 6000.3.0f1) --- com.unity.ugui/Documentation~/ProfilerUI.md | 49 +++++----- .../images/ui-profiler-module.png | Bin 0 -> 333756 bytes .../Editor/TMP/TMP_BaseEditorPanel.cs | 17 ++-- .../Editor/TMP/TMP_EditorPanelUI.cs | 15 ++- com.unity.ugui/Runtime/TMP/TMP_InputField.cs | 4 +- com.unity.ugui/Runtime/TMP/TMP_SubMeshUI.cs | 9 +- com.unity.ugui/Runtime/TMP/TMP_Text.cs | 89 ++++++++++++------ com.unity.ugui/Runtime/TMP/TextMeshPro.cs | 31 +++--- com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs | 60 +++++++----- 9 files changed, 172 insertions(+), 102 deletions(-) create mode 100644 com.unity.ugui/Documentation~/images/ui-profiler-module.png diff --git a/com.unity.ugui/Documentation~/ProfilerUI.md b/com.unity.ugui/Documentation~/ProfilerUI.md index 0a987bb..b9fb649 100644 --- a/com.unity.ugui/Documentation~/ProfilerUI.md +++ b/com.unity.ugui/Documentation~/ProfilerUI.md @@ -2,40 +2,47 @@ uid: um-profiler-ui --- -# UI and UI Details Profiler +# UI and UI Details Profiler module reference -The UI and UI Details Profiler modules provide information on how much time and resources Unity spends laying out and rendering the user interface within your application. You can use this module to understand how Unity handles UI batching for your application, including why and how it batches objects. You can also use this module to find out which part of the UI is responsible for slow performance, or to preview the UI while you scrub the timeline. +>[!NOTE] +> The UI and UI Details Profiler module collects Editor-only data, and doesn't work in development builds. -To open the Profiler window, go to **Window > Analysis > Profiler**. For more information on how to use the Profiler window, refer to [The Profiler window](ProfilerWindow). +The UI and UI Details Profiler modules provide information on how much time and resources Unity spends laying out and rendering the user interface within your application. You can use this module to understand how Unity handles UI batching for your application, including why and how it batches objects. You can also use this module to find out which part of the UI has slow performance, or to preview the UI while you scrub the timeline. -![The UI and UI Details Profiler module](../uploads/Main/ui-profiler-module.png) +To open the Profiler window, go to **Window > Analysis > Profiler**. For more information on how to use the Profiler window, refer to [The Profiler window](xref:um-profiler-window). + +![The UI and UI Details Profiler module](images/ui-profiler-module.png) ## Chart categories -The UI and UI Details Profiler modules’ charts are divided into five categories. To change the order of the categories in the chart, you can drag and drop them in the chart’s legend. You can also click a category’s colored legend to toggle its display. +The UI and UI Details Profiler modules' charts contain the following categories. To change the order of the categories in the chart, you can drag and drop them in the chart's legend. You can also click a category's colored legend to toggle its display. + +### UI Profiler module +|**Chart**|**Description**| +|---|---| +|**Layout**|How much time Unity spent performing the layout pass for the UI. This includes calculations done by [`HorizontalLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.HorizontalLayoutGroup.html), [`VerticalLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.VerticalLayoutGroup.html), and [`GridLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.GridLayoutGroup.html).| +|**Render**|How much time the UI has spent doing its portion of rendering. This is either the time spent rendering directly to the graphics device or rendering to the main render queue.| -|**Chart**||**Description**| -|---|---|---| -|**UI Profiler module**||| -||Layout|How much time Unity has spent performing the layout pass for the UI. This includes calculations done by [HorizontalLayoutGroup](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.HorizontalLayoutGroup.html), [VerticalLayoutGroup](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.VerticalLayoutGroup.html), and [GridLayoutGroup](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.GridLayoutGroup.html).| -||Render|How much time the UI has spent doing its portion of rendering. This is either the cost of rendering directly to the graphics device or rendering to the main render queue.| -|**UI Details Profile module**||| -||Batches|Displays the total number of draw calls that are batched together. | -||Vertices|The total number of vertices that are used to render a section of UI. | -||Markers|Displays event markers. Unity records markers when the user interacts with the UI (for example, a button click, or a slider value change) and then draws them as vertical lines and labels on the chart.| +### UI Details Profile module + +|**Chart**|**Description**| +|---|---| +|**Batches**|Displays the total number of draw calls that are batched together. | +|**Vertices**|The total number of vertices that are used to render a section of UI. | +|**Markers**|Displays event markers. Unity records markers when the user interacts with the UI (for example, a button click, or a slider value change) and then draws them as vertical lines and labels on the chart.| ## Module details pane When you select the UI or the UI Details Profiler module, the module details pane at the bottom of the Profiler window displays more details on the UI in your application. You can use it to inspect the profiling information about the UI objects in your application. The pane is divided into the following columns: |**Column**|**Description**| |---|---| -|**Object**|A list of UI canvases your application used during the period profiled. Double click on a row to highlight the matching object in the Scene.| +|**Object**|A list of UI canvases your application used during the period profiled. Double click on a row to highlight the matching object in the scene.| |**Self Batch Count**|How many batches Unity generated for the canvas.| -|**Cumulative Batch Count**|How many batches Unity generated for the canvas and all of its nested canvases| +|**Cumulative Batch Count**|How many batches Unity generated for the canvas and all its nested canvases.| |**Self Vertex Count**|How many vertices this canvas is rendering.| -|**Cumulative Vertex Count**|How many vertices this canvas and nested canvases are rendering| -|**Batch Breaking Reason**|Why Unity split the batch. Sometimes Unity might not be able to batch objects together. Common reasons include:

**Not Coplanar With Canvas**, where the batching needs the object’s rect transform to be coplanar (unrotated) with the canvas.
**CanvasInjectionIndex**, where a CanvasGroup component is present and forces a new batch, such as when it displays the drop down list of a combo box on top of the rest.
**Different Material Instance, Rect clipping, Texture, or A8TextureUsage**, where Unity can only batch together objects with identical materials, masking, textures, and texture alpha channel usage.| -|**GameObject Count**|How many GameObjects are part of this batch| +|**Cumulative Vertex Count**|How many vertices this canvas and nested canvases are rendering.| +|**Batch Breaking Reason**|Why Unity split the batch. Sometimes Unity might not be able to batch objects together. Common reasons include:
  • **Not Coplanar With Canvas**: The batching needs the object's rect transform to be coplanar (unrotated) with the canvas.
  • **CanvasInjectionIndex**: A CanvasGroup component is present and forces a new batch, such as when it displays the drop down list of a combo box on top of the rest.
  • **Different Material Instance, Rect clipping, Texture, or A8TextureUsage**: Unity can only batch together objects with identical materials, masking, textures, and texture alpha channel usage.
| +|**GameObject Count**|How many GameObjects are part of this batch.| |**GameObjects**|The list of GameObjects in the batch.| When you select a UI object from the list, a preview of it appears on the right hand side of the pane. Above the preview there are the following options in the toolbar: @@ -46,6 +53,6 @@ When you select a UI object from the list, a preview of it appears on the right ## Additional resources -* [Profiler window introduction](ProfilerWindow) -* [Profiling your application](profiler-profiling-applications) +* [Profiler window introduction](xref:um-profiler-window) +* [Profiling your application](xref:um-profiler-profiling-applications) diff --git a/com.unity.ugui/Documentation~/images/ui-profiler-module.png b/com.unity.ugui/Documentation~/images/ui-profiler-module.png new file mode 100644 index 0000000000000000000000000000000000000000..62bc7f9e7cfe7a287662e4a454acdccb38b6f0d4 GIT binary patch literal 333756 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%0DPv) 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�#ASp{b^*jWNj5tp`#CHe<|uPBYoE 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 literal 0 HcmV?d00001 diff --git a/com.unity.ugui/Editor/TMP/TMP_BaseEditorPanel.cs b/com.unity.ugui/Editor/TMP/TMP_BaseEditorPanel.cs index 257ee2e..96646f3 100644 --- a/com.unity.ugui/Editor/TMP/TMP_BaseEditorPanel.cs +++ b/com.unity.ugui/Editor/TMP/TMP_BaseEditorPanel.cs @@ -41,6 +41,7 @@ public abstract class TMP_BaseEditorPanel : Editor static readonly GUIContent k_SpacingOptionsLabel = new GUIContent("Spacing Options (em)", "Spacing adjustments between different elements of the text. Values are in font units where a value of 1 equals 1/100em."); static readonly GUIContent k_CharacterSpacingLabel = new GUIContent("Character"); + static readonly GUIContent k_CharacterHorizontalScaleLabel = new GUIContent("Character Horizontal Scale", "The horizontal scale of the characters. Value = 1.0 is normal. Values > 1.0 or < 1.0 respectively increases or decreases the horizontal scale or width of the characters."); static readonly GUIContent k_WordSpacingLabel = new GUIContent("Word"); static readonly GUIContent k_LineSpacingLabel = new GUIContent("Line"); static readonly GUIContent k_ParagraphSpacingLabel = new GUIContent("Paragraph"); @@ -132,6 +133,7 @@ protected struct Foldout protected SerializedProperty m_CharWidthMaxAdjProp; protected SerializedProperty m_CharacterSpacingProp; + private protected SerializedProperty m_CharacterHorizontalScaleProp; protected SerializedProperty m_WordSpacingProp; protected SerializedProperty m_LineSpacingProp; protected SerializedProperty m_ParagraphSpacingProp; @@ -216,6 +218,7 @@ protected virtual void OnEnable() m_OverrideHtmlColorProp = serializedObject.FindProperty("m_overrideHtmlColors"); m_CharacterSpacingProp = serializedObject.FindProperty("m_characterSpacing"); + m_CharacterHorizontalScaleProp = serializedObject.FindProperty("m_characterHorizontalScale"); m_WordSpacingProp = serializedObject.FindProperty("m_wordSpacing"); m_LineSpacingProp = serializedObject.FindProperty("m_lineSpacing"); m_ParagraphSpacingProp = serializedObject.FindProperty("m_paragraphSpacing"); @@ -278,7 +281,7 @@ protected virtual void OnEnable() // Get Styles from Style Sheet if (TMP_Settings.instance != null) m_StyleNames = GetStyleNames(); - + // Get list of font features for the primary font asset assigned to the text component // FontEngine.LoadFontFace(m_TextComponent.font.SourceFont_EditorRef); // OTL_Table gposTable = UnityEngine.TextCore.LowLevel.FontEngine.GetOpenTypeLayoutTable(OTL_TableType.GPOS); @@ -998,6 +1001,8 @@ void DrawSpacing() EditorGUIUtility.labelWidth = currentLabelWidth; EditorGUI.indentLevel = oldIndent; + EditorGUILayout.PropertyField(m_CharacterHorizontalScaleProp, k_CharacterHorizontalScaleLabel, GUILayout.MaxWidth(EditorGUIUtility.labelWidth + 50f)); + if (EditorGUI.EndChangeCheck()) { m_HavePropertiesChanged = true; @@ -1251,7 +1256,7 @@ protected void DrawFontFeatures() for (int i = 0; i < featureCount; i++) { SerializedProperty activeFeatureProperty = m_FontFeaturesActiveProp.GetArrayElementAtIndex(i); - + for (int j = 0; j < k_FontFeatures.Length; j++) { if (activeFeatureProperty.intValue == k_FontFeatures[j].TagToInt()) @@ -1263,15 +1268,15 @@ protected void DrawFontFeatures() } EditorGUI.BeginChangeCheck(); - + int mask = EditorGUILayout.MaskField(k_FontFeaturesLabel, srcMask, k_FontFeatures); - + if (EditorGUI.EndChangeCheck()) { m_FontFeaturesActiveProp.ClearArray(); int writeIndex = 0; - + for (int i = 0; i < k_FontFeatures.Length; i++) { int bit = 0x1 << i; @@ -1286,7 +1291,7 @@ protected void DrawFontFeatures() } m_HavePropertiesChanged = true; - } + } } protected void DrawPadding() diff --git a/com.unity.ugui/Editor/TMP/TMP_EditorPanelUI.cs b/com.unity.ugui/Editor/TMP/TMP_EditorPanelUI.cs index 2b22a03..0d09d6b 100644 --- a/com.unity.ugui/Editor/TMP/TMP_EditorPanelUI.cs +++ b/com.unity.ugui/Editor/TMP/TMP_EditorPanelUI.cs @@ -51,7 +51,7 @@ protected override void DrawExtraSettings() DrawSpriteAsset(); DrawStyleSheet(); - + DrawFontFeatures(); DrawPadding(); @@ -83,12 +83,19 @@ protected void DrawMaskable() EditorGUILayout.PropertyField(m_MaskableProp, k_MaskableLabel); if (EditorGUI.EndChangeCheck()) { - m_TextComponent.maskable = m_MaskableProp.boolValue; + bool value = m_MaskableProp.boolValue; // Change needs to propagate to the child sub objects. MaskableGraphic[] maskableGraphics = m_TextComponent.GetComponentsInChildren(); - for (int i = 1; i < maskableGraphics.Length; i++) - maskableGraphics[i].maskable = m_MaskableProp.boolValue; + + foreach (var graphicComponent in maskableGraphics) + { + graphicComponent.maskable = value; + + // Force RectMask2D to re-evaluate clipping for this graphic + graphicComponent.RecalculateClipping(); + EditorUtility.SetDirty(graphicComponent); + } m_HavePropertiesChanged = true; } diff --git a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs index b25f891..5d30d04 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs @@ -1940,9 +1940,9 @@ IEnumerator MouseDragOutsideRect(PointerEventData eventData) if (multiLine) { if (localMousePos.y > rect.yMax) - MoveUp(true, true); + MoveUp(true, false); else if (localMousePos.y < rect.yMin) - MoveDown(true, true); + MoveDown(true, false); } else { diff --git a/com.unity.ugui/Runtime/TMP/TMP_SubMeshUI.cs b/com.unity.ugui/Runtime/TMP/TMP_SubMeshUI.cs index 9aa238b..610d891 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_SubMeshUI.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_SubMeshUI.cs @@ -238,14 +238,19 @@ public static TMP_SubMeshUI AddSubTextObject(TextMeshProUGUI textComponent, Mate subMesh.m_fontAsset = materialReference.fontAsset; subMesh.m_spriteAsset = materialReference.spriteAsset; subMesh.m_isDefaultMaterial = materialReference.isDefaultMaterial; - subMesh.maskable = textComponent.maskable; subMesh.SetSharedMaterial(materialReference.material); + // Only recalculate clipping if it is set to false on the parent text object + if (!textComponent.maskable) + { + subMesh.maskable = false; + subMesh.RecalculateClipping(); + } + return subMesh; } - ///

/// /// diff --git a/com.unity.ugui/Runtime/TMP/TMP_Text.cs b/com.unity.ugui/Runtime/TMP/TMP_Text.cs index 39257ba..0dce65d 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_Text.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_Text.cs @@ -663,6 +663,18 @@ public float characterSpacing protected float m_monoSpacing = 0; protected bool m_duoSpace; + /// + /// The horizontal scale of characters. + /// A value of 1.0 is normal. Value greater than 1.0 increases the width. Value less than 1.0 decreases the width. + /// + public float characterHorizontalScale + { + get { return m_characterHorizontalScale; } + set { if (m_characterHorizontalScale == value) return; m_havePropertiesChanged = true; m_characterHorizontalScale = value; SetVerticesDirty(); SetLayoutDirty(); } + } + [SerializeField] + private protected float m_characterHorizontalScale = 1.0f; + /// /// The amount of additional spacing between words. /// @@ -2018,6 +2030,17 @@ protected void ParseInputText() break; } + // Used to output the character sequence for debugging + /*for (int i = 0; i < m_TextProcessingArray.Length; i++) + { + uint c = m_TextProcessingArray[i].unicode; + + if (c == 0) + break; + + Debug.Log("Unicode: " + c.ToString("X8")); + }*/ + SetArraySizes(m_TextProcessingArray); k_ParseTextMarker.End(); @@ -3931,6 +3954,10 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m m_IsDrivenLineSpacing = false; m_LastBaseGlyphIndex = int.MinValue; + bool kerning = m_ActiveFontFeatures.Contains(OTL_FeatureTag.kern); + bool markToBase = m_ActiveFontFeatures.Contains(OTL_FeatureTag.mark); + bool markToMark = m_ActiveFontFeatures.Contains(OTL_FeatureTag.mkmk); + float marginWidth = marginSize.x; float marginHeight = marginSize.y; m_marginLeft = 0; @@ -3948,6 +3975,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m // Tracking of the highest Ascender m_maxCapHeight = 0; m_maxTextAscender = 0; + float maxTextDescender = 0; m_ElementDescender = 0; float maxVisibleDescender = 0; bool isMaxVisibleDescenderSet = false; @@ -4194,8 +4222,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m #region Handle Kerning GlyphValueRecord glyphAdjustments = new GlyphValueRecord(); float characterSpacingAdjustment = m_characterSpacing; - // Make sure the current character and the next are Characters (not Sprite). - if (m_enableKerning && m_textElementType == TMP_TextElementType.Character) + if (kerning && m_textElementType == TMP_TextElementType.Character) { GlyphPairAdjustmentRecord adjustmentPair; uint baseGlyphIndex = m_cached_TextElement.m_GlyphIndex; @@ -4231,7 +4258,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m // Handle Diacritical Marks #region Handle Diacritical Marks - bool isBaseGlyph = TMP_TextParsingUtilities.IsBaseGlyph((uint)charCode); + bool isBaseGlyph = TMP_TextParsingUtilities.IsBaseGlyph(charCode); if (isBaseGlyph) m_LastBaseGlyphIndex = m_characterCount; @@ -4239,7 +4266,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m if (m_characterCount > 0 && !isBaseGlyph) { // Check for potential Mark-to-Base lookup if previous glyph was a base glyph - if (m_LastBaseGlyphIndex != int.MinValue && m_LastBaseGlyphIndex == m_characterCount - 1) + if (markToBase && m_LastBaseGlyphIndex != int.MinValue && m_LastBaseGlyphIndex == m_characterCount - 1) { Glyph baseGlyph = m_textInfo.characterInfo[m_LastBaseGlyphIndex].textElement.glyph; uint baseGlyphIndex = baseGlyph.index; @@ -4262,31 +4289,34 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m bool wasLookupApplied = false; // Check for any potential Mark-to-Mark lookups - for (int characterLookupIndex = m_characterCount - 1; characterLookupIndex >= 0 && characterLookupIndex != m_LastBaseGlyphIndex; characterLookupIndex--) + if (markToMark) { - // Handle any potential Mark-to-Mark lookup - Glyph baseMarkGlyph = m_textInfo.characterInfo[characterLookupIndex].textElement.glyph; - uint baseGlyphIndex = baseMarkGlyph.index; - uint combiningMarkGlyphIndex = m_cached_TextElement.glyphIndex; - uint key = combiningMarkGlyphIndex << 16 | baseGlyphIndex; - - if (m_currentFontAsset.fontFeatureTable.m_MarkToMarkAdjustmentRecordLookup.TryGetValue(key, out MarkToMarkAdjustmentRecord glyphAdjustmentRecord)) + for (int characterLookupIndex = m_characterCount - 1; characterLookupIndex >= 0 && characterLookupIndex != m_LastBaseGlyphIndex; characterLookupIndex--) { - float baseMarkOrigin = (m_textInfo.characterInfo[characterLookupIndex].origin - m_xAdvance) / currentElementScale; - float currentBaseline = baselineOffset - m_lineOffset + m_baselineOffset; - float baseMarkBaseline = (m_internalCharacterInfo[characterLookupIndex].baseLine - currentBaseline) / currentElementScale; + // Handle any potential Mark-to-Mark lookup + Glyph baseMarkGlyph = m_textInfo.characterInfo[characterLookupIndex].textElement.glyph; + uint baseGlyphIndex = baseMarkGlyph.index; + uint combiningMarkGlyphIndex = m_cached_TextElement.glyphIndex; + uint key = combiningMarkGlyphIndex << 16 | baseGlyphIndex; - glyphAdjustments.xPlacement = baseMarkOrigin + glyphAdjustmentRecord.baseMarkGlyphAnchorPoint.xCoordinate - glyphAdjustmentRecord.combiningMarkPositionAdjustment.xPositionAdjustment; - glyphAdjustments.yPlacement = baseMarkBaseline + glyphAdjustmentRecord.baseMarkGlyphAnchorPoint.yCoordinate - glyphAdjustmentRecord.combiningMarkPositionAdjustment.yPositionAdjustment; + if (m_currentFontAsset.fontFeatureTable.m_MarkToMarkAdjustmentRecordLookup.TryGetValue(key, out MarkToMarkAdjustmentRecord glyphAdjustmentRecord)) + { + float baseMarkOrigin = (m_textInfo.characterInfo[characterLookupIndex].origin - m_xAdvance) / currentElementScale; + float currentBaseline = baselineOffset - m_lineOffset + m_baselineOffset; + float baseMarkBaseline = (m_internalCharacterInfo[characterLookupIndex].baseLine - currentBaseline) / currentElementScale; - characterSpacingAdjustment = 0; - wasLookupApplied = true; - break; + glyphAdjustments.xPlacement = baseMarkOrigin + glyphAdjustmentRecord.baseMarkGlyphAnchorPoint.xCoordinate - glyphAdjustmentRecord.combiningMarkPositionAdjustment.xPositionAdjustment; + glyphAdjustments.yPlacement = baseMarkBaseline + glyphAdjustmentRecord.baseMarkGlyphAnchorPoint.yCoordinate - glyphAdjustmentRecord.combiningMarkPositionAdjustment.yPositionAdjustment; + + characterSpacingAdjustment = 0; + wasLookupApplied = true; + break; + } } } // If no Mark-to-Mark lookups were applied, check for potential Mark-to-Base lookup. - if (m_LastBaseGlyphIndex != int.MinValue && !wasLookupApplied) + if (markToBase && m_LastBaseGlyphIndex != int.MinValue && !wasLookupApplied) { // Handle lookup for Mark-to-Base Glyph baseGlyph = m_textInfo.characterInfo[m_LastBaseGlyphIndex].textElement.glyph; @@ -4330,7 +4360,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m float monoAdvance = 0; if (m_monoSpacing != 0) { - monoAdvance = (m_monoSpacing / 2 - (m_cached_TextElement.glyph.metrics.width / 2 + m_cached_TextElement.glyph.metrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta); + monoAdvance = (m_monoSpacing / 2 - (m_cached_TextElement.glyph.metrics.width / 2 + m_cached_TextElement.glyph.metrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; m_xAdvance += monoAdvance; } #endregion @@ -4374,7 +4404,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m m_maxLineAscender = Mathf.Max(adjustedAscender, m_maxLineAscender); m_maxLineDescender = Mathf.Min(adjustedDescender, m_maxLineDescender); - } + } // Element Ascender and Descender in object space if (isFirstCharacterOfLine || isWhiteSpace == false) @@ -4404,6 +4434,9 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m } } + // Max text Ascender and Descender + maxTextDescender = Mathf.Min(maxTextDescender, m_ElementDescender); + // Page ascender if (m_lineOffset == 0) { @@ -4431,7 +4464,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m widthOfTextArea = m_width != -1 ? Mathf.Min(marginWidth + 0.0001f - m_marginLeft - m_marginRight, m_width) : marginWidth + 0.0001f - m_marginLeft - m_marginRight; // Calculate the line breaking width of the text. - textWidth = Mathf.Abs(m_xAdvance) + currentGlyphMetrics.horizontalAdvance * (1 - m_charWidthAdjDelta) * (charCode == 0xAD ? currentElementUnmodifiedScale : currentElementScale); + textWidth = Mathf.Abs(m_xAdvance) + currentGlyphMetrics.horizontalAdvance * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale * (charCode == 0xAD ? currentElementUnmodifiedScale : currentElementScale); int testedCharacterCount = m_characterCount; @@ -4564,7 +4597,7 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m // Compute Preferred Width & Height m_RenderedWidth = Mathf.Max(m_RenderedWidth, textWidth + m_marginLeft + m_marginRight); - m_RenderedHeight = Mathf.Max(m_RenderedHeight, m_maxTextAscender - m_ElementDescender); + m_RenderedHeight = Mathf.Max(m_RenderedHeight, m_maxTextAscender - maxTextDescender); } #endregion Handle Visible Characters @@ -4596,14 +4629,14 @@ protected virtual Vector2 CalculatePreferredValues(ref float fontSize, Vector2 m } else if (m_monoSpacing != 0) { - m_xAdvance += (m_monoSpacing - monoAdvance + ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale) + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += (m_monoSpacing - monoAdvance + ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale) + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; } else { - m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * m_FXScale.x + glyphAdjustments.xAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * m_FXScale.x + glyphAdjustments.xAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; @@ -5002,7 +5035,7 @@ internal void InsertNewLine(int i, float baseScale, float currentElementScale, f m_textInfo.lineInfo[m_lineNumber].width = width; float glyphAdjustment = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].adjustedHorizontalAdvance; - float maxAdvanceOffset = (glyphAdjustment * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + float maxAdvanceOffset = (glyphAdjustment * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; float adjustedHorizontalAdvance = m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance + (m_isRightToLeft ? maxAdvanceOffset : - maxAdvanceOffset); m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance = adjustedHorizontalAdvance; diff --git a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs index 5904204..1bafc9d 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshPro.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshPro.cs @@ -1780,7 +1780,10 @@ internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) // If we matched all components, perform the substitution. if (ligatureGlyphID != 0 && componentIndex == componentCount) { - // idx now points one past the last code point we consume (including any skipped VS/ZWJ within the cluster). + // Check for potential trailing variant selector that should also be consumed in the sequence. + if (idx < textProcessingArray.Length && TMP_TextParsingUtilities.IsIgnorableForLigature(textProcessingArray[idx].unicode)) + idx++; + int spanLen = idx - i; if (m_currentFontAsset.TryAddGlyphInternal(ligatureGlyphID, out Glyph glyph)) { @@ -2148,7 +2151,7 @@ void OnPreRenderObject() m_maxFontSize = m_fontSizeMax; m_minFontSize = m_fontSizeMin; m_lineSpacingDelta = 0; - m_charWidthAdjDelta = 0; + m_charWidthAdjDelta = 0.0f; m_isTextTruncated = false; @@ -2781,7 +2784,7 @@ protected virtual void GenerateTextMesh() #region Handle Right-to-Left if (m_isRightToLeft) { - m_xAdvance -= currentGlyphMetrics.horizontalAdvance * (1 - m_charWidthAdjDelta) * currentElementScale; + m_xAdvance -= currentGlyphMetrics.horizontalAdvance * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale * currentElementScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance -= m_wordSpacing * currentEmScale; @@ -2795,9 +2798,9 @@ protected virtual void GenerateTextMesh() if (m_monoSpacing != 0) { if (m_duoSpace && (charCode == '.' || charCode == ':' || charCode == ',')) - monoAdvance = (m_monoSpacing / 4 - (currentGlyphMetrics.width / 2 + currentGlyphMetrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta); + monoAdvance = (m_monoSpacing / 4 - (currentGlyphMetrics.width / 2 + currentGlyphMetrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; else - monoAdvance = (m_monoSpacing / 2 - (currentGlyphMetrics.width / 2 + currentGlyphMetrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta); + monoAdvance = (m_monoSpacing / 2 - (currentGlyphMetrics.width / 2 + currentGlyphMetrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; m_xAdvance += monoAdvance; } @@ -2834,7 +2837,7 @@ protected virtual void GenerateTextMesh() #region Calculate Vertices Position k_CalculateVerticesPositionMarker.Begin(); Vector3 top_left; - top_left.x = m_xAdvance + ((currentGlyphMetrics.horizontalBearingX * m_FXScale.x - padding - style_padding + glyphAdjustments.xPlacement) * currentElementScale * (1 - m_charWidthAdjDelta)); + top_left.x = m_xAdvance + (currentGlyphMetrics.horizontalBearingX * m_FXScale.x - padding - style_padding + glyphAdjustments.xPlacement) * currentElementScale * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; top_left.y = baselineOffset + (currentGlyphMetrics.horizontalBearingY + padding + glyphAdjustments.yPlacement) * currentElementScale - m_lineOffset + m_baselineOffset; top_left.z = 0; @@ -2844,7 +2847,7 @@ protected virtual void GenerateTextMesh() bottom_left.z = 0; Vector3 top_right; - top_right.x = bottom_left.x + ((currentGlyphMetrics.width * m_FXScale.x + padding * 2 + style_padding * 2) * currentElementScale * (1 - m_charWidthAdjDelta)); + top_right.x = bottom_left.x + (currentGlyphMetrics.width * m_FXScale.x + padding * 2 + style_padding * 2) * currentElementScale * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; top_right.y = top_left.y; top_right.z = 0; @@ -3031,7 +3034,7 @@ protected virtual void GenerateTextMesh() widthOfTextArea = m_width != -1 ? Mathf.Min(marginWidth + 0.0001f - marginLeft - marginRight, m_width) : marginWidth + 0.0001f - marginLeft - marginRight; // Calculate the line breaking width of the text. - float textWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? currentGlyphMetrics.horizontalAdvance : 0) * (1 - m_charWidthAdjDelta) * (charCode == 0xAD ? currentElementUnmodifiedScale : currentElementScale); + float textWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? currentGlyphMetrics.horizontalAdvance : 0) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale * (charCode == 0xAD ? currentElementUnmodifiedScale : currentElementScale); float textHeight = m_maxTextAscender - (m_maxLineDescender - m_lineOffset) + (m_lineOffset > 0 && m_IsDrivenLineSpacing == false ? m_maxLineAscender - m_startOfLineAscender : 0); int testedCharacterCount = m_characterCount; @@ -3785,7 +3788,7 @@ protected virtual void GenerateTextMesh() } float textHeight = m_maxTextAscender - (m_maxLineDescender - m_lineOffset) + (m_lineOffset > 0 && m_IsDrivenLineSpacing == false ? m_maxLineAscender - m_startOfLineAscender : 0); - float textWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? m_Ellipsis.character.m_Glyph.metrics.horizontalAdvance : 0) * (1 - m_charWidthAdjDelta) * scale; + float textWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? m_Ellipsis.character.m_Glyph.metrics.horizontalAdvance : 0) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale * scale; float widthOfTextAreaForEllipsis = m_width != -1 ? Mathf.Min(marginWidth + 0.0001f - marginLeft - marginRight, m_width) : marginWidth + 0.0001f - marginLeft - marginRight; if (textWidth < widthOfTextAreaForEllipsis * (isJustifiedOrFlush ? 1.05f : 1.0f) && textHeight < marginHeight + 0.0001f) @@ -3833,21 +3836,21 @@ protected virtual void GenerateTextMesh() else monoAdjustment = m_monoSpacing - monoAdvance; - m_xAdvance += (monoAdjustment + ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale) + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += (monoAdjustment + ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale) + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; } else if (m_isRightToLeft) { - m_xAdvance -= ((glyphAdjustments.xAdvance * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta)); + m_xAdvance -= (glyphAdjustments.xAdvance * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance -= m_wordSpacing * currentEmScale; } else { - m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * m_FXScale.x + glyphAdjustments.xAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * m_FXScale.x + glyphAdjustments.xAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; @@ -3952,7 +3955,7 @@ protected virtual void GenerateTextMesh() if (m_textInfo.lineInfo[m_lineNumber].characterCount == 1) m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification; - float maxAdvanceOffset = ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + float maxAdvanceOffset = ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].isVisible) m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance + (m_isRightToLeft ? maxAdvanceOffset : - maxAdvanceOffset); else @@ -4495,7 +4498,7 @@ protected virtual void GenerateTextMesh() // Pack UV's so that we can pass Xscale needed for Shader to maintain 1:1 ratio. #region Pack Scale into UV2 - xScale = characterInfos[i].scale * Mathf.Abs(lossyScale) * (1 - m_charWidthAdjDelta); + xScale = characterInfos[i].scale * Mathf.Abs(lossyScale) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (!characterInfos[i].isUsingAlternateTypeface && (characterInfos[i].style & FontStyles.Bold) == FontStyles.Bold) xScale *= -1; // Set SDF Scale diff --git a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index 1f86561..bc48176 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -2093,7 +2093,10 @@ internal override int SetArraySizes(TextProcessingElement[] textProcessingArray) // If we matched all components, perform the substitution. if (ligatureGlyphID != 0 && componentIndex == componentCount) { - // idx now points one past the last code point we consume (including any skipped VS/ZWJ within the cluster). + // Check for potential trailing variant selector that should also be consumed in the sequence. + if (idx < textProcessingArray.Length && TMP_TextParsingUtilities.IsIgnorableForLigature(textProcessingArray[idx].unicode)) + idx++; + int spanLen = idx - i; if (m_currentFontAsset.TryAddGlyphInternal(ligatureGlyphID, out Glyph glyph)) { @@ -3130,7 +3133,7 @@ protected virtual void GenerateTextMesh() #region Handle Right-to-Left if (m_isRightToLeft) { - m_xAdvance -= currentGlyphMetrics.horizontalAdvance * (1 - m_charWidthAdjDelta) * currentElementScale; + m_xAdvance -= currentGlyphMetrics.horizontalAdvance * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale * currentElementScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance -= m_wordSpacing * currentEmScale; @@ -3144,9 +3147,9 @@ protected virtual void GenerateTextMesh() if (m_monoSpacing != 0) { if (m_duoSpace && (charCode == '.' || charCode == ':' || charCode == ',')) - monoAdvance = (m_monoSpacing / 4 - (currentGlyphMetrics.width / 2 + currentGlyphMetrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta); + monoAdvance = (m_monoSpacing / 4 - (currentGlyphMetrics.width / 2 + currentGlyphMetrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; else - monoAdvance = (m_monoSpacing / 2 - (currentGlyphMetrics.width / 2 + currentGlyphMetrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta); + monoAdvance = (m_monoSpacing / 2 - (currentGlyphMetrics.width / 2 + currentGlyphMetrics.horizontalBearingX) * currentElementScale) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; m_xAdvance += monoAdvance; } @@ -3183,7 +3186,7 @@ protected virtual void GenerateTextMesh() #region Calculate Vertices Position k_CalculateVerticesPositionMarker.Begin(); Vector3 top_left; - top_left.x = m_xAdvance + ((currentGlyphMetrics.horizontalBearingX * m_FXScale.x - padding - style_padding + glyphAdjustments.xPlacement) * currentElementScale * (1 - m_charWidthAdjDelta)); + top_left.x = m_xAdvance + (currentGlyphMetrics.horizontalBearingX * m_FXScale.x - padding - style_padding + glyphAdjustments.xPlacement) * currentElementScale * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; top_left.y = baselineOffset + (currentGlyphMetrics.horizontalBearingY + padding + glyphAdjustments.yPlacement) * currentElementScale - m_lineOffset + m_baselineOffset; top_left.z = 0; @@ -3193,7 +3196,7 @@ protected virtual void GenerateTextMesh() bottom_left.z = 0; Vector3 top_right; - top_right.x = bottom_left.x + ((currentGlyphMetrics.width * m_FXScale.x + padding * 2 + style_padding * 2) * currentElementScale * (1 - m_charWidthAdjDelta)); + top_right.x = bottom_left.x + (currentGlyphMetrics.width * m_FXScale.x + padding * 2 + style_padding * 2) * currentElementScale * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; top_right.y = top_left.y; top_right.z = 0; @@ -3380,7 +3383,7 @@ protected virtual void GenerateTextMesh() widthOfTextArea = m_width != -1 ? Mathf.Min(marginWidth + 0.0001f - marginLeft - marginRight, m_width) : marginWidth + 0.0001f - marginLeft - marginRight; // Calculate the line breaking width of the text. - float textWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? currentGlyphMetrics.horizontalAdvance : 0) * (1 - m_charWidthAdjDelta) * (charCode == 0xAD ? currentElementUnmodifiedScale : currentElementScale); + float textWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? currentGlyphMetrics.horizontalAdvance : 0) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale * (charCode == 0xAD ? currentElementUnmodifiedScale : currentElementScale); float textHeight = m_maxTextAscender - (m_maxLineDescender - m_lineOffset) + (m_lineOffset > 0 && m_IsDrivenLineSpacing == false ? m_maxLineAscender - m_startOfLineAscender : 0); int testedCharacterCount = m_characterCount; @@ -4134,7 +4137,7 @@ protected virtual void GenerateTextMesh() } float textHeight = m_maxTextAscender - (m_maxLineDescender - m_lineOffset) + (m_lineOffset > 0 && m_IsDrivenLineSpacing == false ? m_maxLineAscender - m_startOfLineAscender : 0); - float textWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? m_Ellipsis.character.m_Glyph.metrics.horizontalAdvance : 0) * (1 - m_charWidthAdjDelta) * scale; + float textWidth = Mathf.Abs(m_xAdvance) + (!m_isRightToLeft ? m_Ellipsis.character.m_Glyph.metrics.horizontalAdvance : 0) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale * scale; float widthOfTextAreaForEllipsis = m_width != -1 ? Mathf.Min(marginWidth + 0.0001f - marginLeft - marginRight, m_width) : marginWidth + 0.0001f - marginLeft - marginRight; if (textWidth < widthOfTextAreaForEllipsis * (isJustifiedOrFlush ? 1.05f : 1.0f) && textHeight < marginHeight + 0.0001f) @@ -4182,21 +4185,21 @@ protected virtual void GenerateTextMesh() else monoAdjustment = m_monoSpacing - monoAdvance; - m_xAdvance += (monoAdjustment + ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale) + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += (monoAdjustment + ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment) * currentEmScale) + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; } else if (m_isRightToLeft) { - m_xAdvance -= ((glyphAdjustments.xAdvance * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta)); + m_xAdvance -= (glyphAdjustments.xAdvance * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance -= m_wordSpacing * currentEmScale; } else { - m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * m_FXScale.x + glyphAdjustments.xAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + m_xAdvance += ((currentGlyphMetrics.horizontalAdvance * m_FXScale.x + glyphAdjustments.xAdvance) * currentElementScale + (m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (isWhiteSpace || charCode == 0x200B) m_xAdvance += m_wordSpacing * currentEmScale; @@ -4301,7 +4304,7 @@ protected virtual void GenerateTextMesh() if (m_textInfo.lineInfo[m_lineNumber].characterCount == 1) m_textInfo.lineInfo[m_lineNumber].alignment = m_lineJustification; - float maxAdvanceOffset = ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta); + float maxAdvanceOffset = ((m_currentFontAsset.normalSpacingOffset + characterSpacingAdjustment + boldSpacingAdjustment) * currentEmScale + m_cSpacing) * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].isVisible) m_textInfo.lineInfo[m_lineNumber].maxAdvance = m_textInfo.characterInfo[m_lastVisibleCharacterOfLine].xAdvance + (m_isRightToLeft ? maxAdvanceOffset : - maxAdvanceOffset); else @@ -4848,7 +4851,7 @@ protected virtual void GenerateTextMesh() // Pack UV's so that we can pass Xscale needed for Shader to maintain 1:1 ratio. #region Pack Scale into UV2 - xScale = characterInfos[i].scale * (1 - m_charWidthAdjDelta); + xScale = characterInfos[i].scale * (1 - m_charWidthAdjDelta) * m_characterHorizontalScale; if (!characterInfos[i].isUsingAlternateTypeface && (characterInfos[i].style & FontStyles.Bold) == FontStyles.Bold) xScale *= -1; switch (canvasRenderMode) @@ -5411,31 +5414,38 @@ protected virtual void GenerateTextMesh() // Clear unused vertices m_textInfo.meshInfo[i].ClearUnusedVertices(); - if (m_subTextObjects[i] == null) continue; + TMP_SubMeshUI subTextObject = m_subTextObjects[i]; + + if (subTextObject == null) continue; // Sort the geometry of the sub-text objects if needed. if (m_geometrySortingOrder != VertexSortingOrder.Normal) m_textInfo.meshInfo[i].SortGeometry(VertexSortingOrder.Reverse); - //m_subTextObjects[i].mesh.MarkDynamic(); - m_subTextObjects[i].mesh.vertices = m_textInfo.meshInfo[i].vertices; - m_subTextObjects[i].mesh.SetUVs(0, m_textInfo.meshInfo[i].uvs0); - m_subTextObjects[i].mesh.uv2 = m_textInfo.meshInfo[i].uvs2; - //m_subTextObjects[i].mesh.uv4 = m_textInfo.meshInfo[i].uvs4; - m_subTextObjects[i].mesh.colors32 = m_textInfo.meshInfo[i].colors32; + subTextObject.mesh.vertices = m_textInfo.meshInfo[i].vertices; + subTextObject.mesh.SetUVs(0, m_textInfo.meshInfo[i].uvs0); + subTextObject.mesh.uv2 = m_textInfo.meshInfo[i].uvs2; + subTextObject.mesh.colors32 = m_textInfo.meshInfo[i].colors32; - m_subTextObjects[i].mesh.RecalculateBounds(); + subTextObject.mesh.RecalculateBounds(); - m_subTextObjects[i].canvasRenderer.SetMesh(m_subTextObjects[i].mesh); + subTextObject.canvasRenderer.SetMesh(subTextObject.mesh); // Set CanvasRenderer color to match the parent text object. - m_subTextObjects[i].canvasRenderer.SetColor(parentBaseColor); + subTextObject.canvasRenderer.SetColor(parentBaseColor); // Make sure Cull Transparent Mesh of the sub objects matches the parent - m_subTextObjects[i].canvasRenderer.cullTransparentMesh = isCullTransparentMeshEnabled; + subTextObject.canvasRenderer.cullTransparentMesh = isCullTransparentMeshEnabled; // Sync RaycastTarget property with parent text object - m_subTextObjects[i].raycastTarget = this.raycastTarget; + subTextObject.raycastTarget = this.raycastTarget; + + // Sync Maskable property with parent text object (if needed) + if (subTextObject.maskable != this.maskable) + { + subTextObject.maskable = this.maskable; + subTextObject.RecalculateClipping(); + } } } From 61c86f118588b578c26124b601dc3c1cd2931ae2 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 6 Dec 2025 05:56:10 +0000 Subject: [PATCH 11/26] Mirror com.unity.ugui package (Unity 6000.3.2f1) --- com.unity.ugui/Runtime/TMP/TMP_InputField.cs | 6 + .../Runtime/UGUI/UI/Core/Graphic.cs | 63 +++++--- com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs | 6 - .../GraphicRaycasterButtonTests.cs | 114 +++++++++++++++ .../GraphicRaycasterButtonTests.cs.meta | 2 + .../Tests/Runtime/UGUI/Graphic/ImageTests.cs | 137 ++++++++++++++---- 6 files changed, 277 insertions(+), 51 deletions(-) create mode 100644 com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterButtonTests.cs create mode 100644 com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterButtonTests.cs.meta diff --git a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs index 5d30d04..640fd63 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs @@ -4476,6 +4476,12 @@ public virtual void OnSubmit(BaseEventData eventData) m_ShouldActivateNextUpdate = true; SendOnSubmit(); +#if PLATFORM_TVOS + // When a keyboard is open in tvOS, the submit button is used for typing. + // Only actually close the keyboard on tvOS if "Done" was pressed in the soft keyboard. + if (m_SoftKeyboard != null && m_SoftKeyboard.status == TouchScreenKeyboard.Status.Visible) + return; +#endif DeactivateInputField(); eventData?.Use(); } diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Graphic.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Graphic.cs index 8a1fe9a..6bddd68 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Graphic.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Graphic.cs @@ -858,52 +858,81 @@ protected bool Raycast(Vector2 sp, Camera eventCamera, bool ignoreMasks) bool ignoreParentGroups = false; bool continueTraversal = true; + bool isParent = false; while (t != null) { + bool raycastValid = true; + bool hasMask = false; + bool maskableGraphicRaycastValid = true; + t.GetComponents(components); for (var i = 0; i < components.Count; i++) { - var canvas = components[i] as Canvas; + var component = components[i]; + var canvas = component as Canvas; if (canvas != null && canvas.overrideSorting) continueTraversal = false; - var filter = components[i] as ICanvasRaycastFilter; - + var filter = component as ICanvasRaycastFilter; // Image, Mask, RectMask2D, CanvasGroup if (filter == null) continue; - if (ignoreMasks && components[i] is Mask or RectMask2D) + if (ignoreMasks && component is Mask or RectMask2D) continue; - var raycastValid = true; - - var group = components[i] as CanvasGroup; - if (group != null) + if (component is CanvasGroup group) { if (!group.enabled) continue; - if (ignoreParentGroups == false && group.ignoreParentGroups) + if (ignoreParentGroups == false) { - ignoreParentGroups = true; + if (group.ignoreParentGroups) + ignoreParentGroups = true; + raycastValid = filter.IsRaycastLocationValid(sp, eventCamera); + if (!raycastValid) + break; } - else if (!ignoreParentGroups) - raycastValid = filter.IsRaycastLocationValid(sp, eventCamera); } else { + if (isParent && component is Graphic graphic && !graphic.raycastTarget) + continue; + + hasMask |= component is Mask; + raycastValid = filter.IsRaycastLocationValid(sp, eventCamera); - } - if (!raycastValid) - { - ListPool.Release(components); - return false; + // Try to early-out if the raycast is not valid + if (!raycastValid) + { + // Cache the raycast result for parent MaskableGraphics and continue processing components + // unless we already found a Mask and are not ignoring masks + if (isParent && component is MaskableGraphic) + { + maskableGraphicRaycastValid = raycastValid; + if (ignoreMasks || !hasMask) + { + raycastValid = true; + continue; + } + } + + break; + } } } + + if (!raycastValid || (hasMask && !maskableGraphicRaycastValid)) + { + ListPool.Release(components); + return false; + } + t = continueTraversal ? t.parent : null; + isParent = true; } ListPool.Release(components); return true; diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs index 3733bb8..1c05533 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs @@ -1925,12 +1925,6 @@ public virtual bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCame float x = local.x / activeSprite.texture.width; float y = local.y / activeSprite.texture.height; - // Locations outside the image are always considered valid. - // This guarantees that the behavior remains consistent with the case where alphaHitTestMinimumThreshold <= 0. - // Without this check, we would continue to sample a pixel outside the texture. - if (x < 0 || x > 1 || y < 0 || y > 1) - return true; - try { return activeSprite.texture.GetPixelBilinear(x, y).a >= alphaHitTestMinimumThreshold; diff --git a/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterButtonTests.cs b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterButtonTests.cs new file mode 100644 index 0000000..28e0727 --- /dev/null +++ b/com.unity.ugui/Tests/Runtime/UGUI/EventSystem/GraphicRaycasterButtonTests.cs @@ -0,0 +1,114 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.TestTools; +using UnityEngine.UI; + +internal class GraphicRaycasterButtonTests +{ + Camera m_Camera; + EventSystem m_EventSystem; + Canvas m_Canvas; + Button m_ParentButton; + Button m_ChildButton; + Sprite m_Sprite; + + const int TextureSize = 64; + readonly Texture2D texture = new Texture2D(TextureSize, TextureSize); + + [UnitySetUp] + public IEnumerator TestSetup() + { + m_Camera = new GameObject("Camera").AddComponent(); + m_Camera.transform.position = new Vector3(0, 0, -10); + + m_Canvas = new GameObject("Canvas").AddComponent(); + m_Canvas.renderMode = RenderMode.ScreenSpaceOverlay; + m_Canvas.gameObject.AddComponent(); + + m_EventSystem = new GameObject("Event System").AddComponent(); + + Color[] colors = new Color[TextureSize * TextureSize]; + for (int y = 24; y < 40; y++) + for (int x = 0; x < TextureSize; x++) + colors[y + TextureSize * x] = colors[x + TextureSize * y] = Color.red; + texture.SetPixels(colors); + texture.Apply(); + + m_Sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100); + + var parentImage = new GameObject("ParentButton", typeof(RectTransform)).AddComponent(); + parentImage.transform.SetParent(m_Canvas.transform); + parentImage.rectTransform.anchoredPosition = new Vector2(0, 0); + parentImage.sprite = m_Sprite; + parentImage.SetNativeSize(); + m_ParentButton = parentImage.gameObject.AddComponent
/// - [MenuItem("GameObject/UI/Text - TextMeshPro", false, 2001)] + [MenuItem("GameObject/UI (Canvas)/Text - TextMeshPro", false, 2001)] static void CreateTextMeshProGuiObjectPerform(MenuCommand menuCommand) { GameObject go = TMP_DefaultControls.CreateText(GetStandardResources()); @@ -117,7 +117,7 @@ static void CreateTextMeshProGuiObjectPerform(MenuCommand menuCommand) PlaceUIElementRoot(go, menuCommand); } - [MenuItem("GameObject/UI/Button - TextMeshPro", false, 2031)] + [MenuItem("GameObject/UI (Canvas)/Button - TextMeshPro", false, 2031)] public static void AddButton(MenuCommand menuCommand) { GameObject go = TMP_DefaultControls.CreateButton(GetStandardResources()); @@ -130,7 +130,7 @@ public static void AddButton(MenuCommand menuCommand) } - [MenuItem("GameObject/UI/Input Field - TextMeshPro", false, 2037)] + [MenuItem("GameObject/UI (Canvas)/Input Field - TextMeshPro", false, 2037)] static void AddTextMeshProInputField(MenuCommand menuCommand) { GameObject go = TMP_DefaultControls.CreateInputField(GetStandardResources()); @@ -138,7 +138,7 @@ static void AddTextMeshProInputField(MenuCommand menuCommand) } - [MenuItem("GameObject/UI/Dropdown - TextMeshPro", false, 2036)] + [MenuItem("GameObject/UI (Canvas)/Dropdown - TextMeshPro", false, 2036)] public static void AddDropdown(MenuCommand menuCommand) { GameObject go = TMP_DefaultControls.CreateDropdown(GetStandardResources()); diff --git a/com.unity.ugui/Editor/UGUI/UI/MenuOptions.cs b/com.unity.ugui/Editor/UGUI/UI/MenuOptions.cs index 491d1f2..e1285bf 100644 --- a/com.unity.ugui/Editor/UGUI/UI/MenuOptions.cs +++ b/com.unity.ugui/Editor/UGUI/UI/MenuOptions.cs @@ -202,7 +202,7 @@ private static void SetLayerRecursively(GameObject go, int layer) // Graphic elements - [MenuItem("GameObject/UI/Image", false, (int)MenuOptionsPriorityOrder.Image)] + [MenuItem("GameObject/UI (Canvas)/Image", false, (int)MenuOptionsPriorityOrder.Image)] static public void AddImage(MenuCommand menuCommand) { GameObject go; @@ -211,7 +211,7 @@ static public void AddImage(MenuCommand menuCommand) PlaceUIElementRoot(go, menuCommand); } - [MenuItem("GameObject/UI/Raw Image", false, (int)MenuOptionsPriorityOrder.RawImage)] + [MenuItem("GameObject/UI (Canvas)/Raw Image", false, (int)MenuOptionsPriorityOrder.RawImage)] static public void AddRawImage(MenuCommand menuCommand) { GameObject go; @@ -220,7 +220,7 @@ static public void AddRawImage(MenuCommand menuCommand) PlaceUIElementRoot(go, menuCommand); } - [MenuItem("GameObject/UI/Panel", false, (int)MenuOptionsPriorityOrder.Panel)] + [MenuItem("GameObject/UI (Canvas)/Panel", false, (int)MenuOptionsPriorityOrder.Panel)] static public void AddPanel(MenuCommand menuCommand) { GameObject go; @@ -238,7 +238,7 @@ static public void AddPanel(MenuCommand menuCommand) // Toggle is a control you just click on. - [MenuItem("GameObject/UI/Toggle", false, (int)MenuOptionsPriorityOrder.Toggle)] + [MenuItem("GameObject/UI (Canvas)/Toggle", false, (int)MenuOptionsPriorityOrder.Toggle)] static public void AddToggle(MenuCommand menuCommand) { GameObject go; @@ -249,7 +249,7 @@ static public void AddToggle(MenuCommand menuCommand) // Slider and Scrollbar modify a number - [MenuItem("GameObject/UI/Slider", false, (int)MenuOptionsPriorityOrder.Slider)] + [MenuItem("GameObject/UI (Canvas)/Slider", false, (int)MenuOptionsPriorityOrder.Slider)] static public void AddSlider(MenuCommand menuCommand) { GameObject go; @@ -258,7 +258,7 @@ static public void AddSlider(MenuCommand menuCommand) PlaceUIElementRoot(go, menuCommand); } - [MenuItem("GameObject/UI/Scrollbar", false, (int)MenuOptionsPriorityOrder.Scrollbar)] + [MenuItem("GameObject/UI (Canvas)/Scrollbar", false, (int)MenuOptionsPriorityOrder.Scrollbar)] static public void AddScrollbar(MenuCommand menuCommand) { GameObject go; @@ -267,7 +267,7 @@ static public void AddScrollbar(MenuCommand menuCommand) PlaceUIElementRoot(go, menuCommand); } - [MenuItem("GameObject/UI/Scroll View", false, (int)MenuOptionsPriorityOrder.ScrollView)] + [MenuItem("GameObject/UI (Canvas)/Scroll View", false, (int)MenuOptionsPriorityOrder.ScrollView)] static public void AddScrollView(MenuCommand menuCommand) { GameObject go; @@ -278,7 +278,7 @@ static public void AddScrollView(MenuCommand menuCommand) // Containers - [MenuItem("GameObject/UI/Canvas", false, (int)MenuOptionsPriorityOrder.Canvas)] + [MenuItem("GameObject/UI (Canvas)/Canvas", false, (int)MenuOptionsPriorityOrder.Canvas)] static public void AddCanvas(MenuCommand menuCommand) { var go = CreateNewUI(); @@ -296,7 +296,7 @@ static public void AddCanvas(MenuCommand menuCommand) // Legacy Elements - [MenuItem("GameObject/UI/Legacy/Text", false, (int)MenuOptionsPriorityOrder.Text)] + [MenuItem("GameObject/UI (Canvas)/Legacy/Text", false, (int)MenuOptionsPriorityOrder.Text)] static public void AddText(MenuCommand menuCommand) { GameObject go; @@ -305,7 +305,7 @@ static public void AddText(MenuCommand menuCommand) PlaceUIElementRoot(go, menuCommand); } - [MenuItem("GameObject/UI/Legacy/Button", false, (int)MenuOptionsPriorityOrder.Button)] + [MenuItem("GameObject/UI (Canvas)/Legacy/Button", false, (int)MenuOptionsPriorityOrder.Button)] static public void AddButton(MenuCommand menuCommand) { GameObject go; @@ -314,7 +314,7 @@ static public void AddButton(MenuCommand menuCommand) PlaceUIElementRoot(go, menuCommand); } - [MenuItem("GameObject/UI/Legacy/Dropdown", false, (int)MenuOptionsPriorityOrder.Dropdown)] + [MenuItem("GameObject/UI (Canvas)/Legacy/Dropdown", false, (int)MenuOptionsPriorityOrder.Dropdown)] static public void AddDropdown(MenuCommand menuCommand) { GameObject go; @@ -323,7 +323,7 @@ static public void AddDropdown(MenuCommand menuCommand) PlaceUIElementRoot(go, menuCommand); } - [MenuItem("GameObject/UI/Legacy/Input Field", false, (int)MenuOptionsPriorityOrder.InputField)] + [MenuItem("GameObject/UI (Canvas)/Legacy/Input Field", false, (int)MenuOptionsPriorityOrder.InputField)] public static void AddInputField(MenuCommand menuCommand) { GameObject go; @@ -363,7 +363,7 @@ static public GameObject CreateNewUI() return root; } - [MenuItem("GameObject/UI/Event System", false, (int)MenuOptionsPriorityOrder.EventSystem)] + [MenuItem("GameObject/UI (Canvas)/Event System", false, (int)MenuOptionsPriorityOrder.EventSystem)] public static void CreateEventSystem(MenuCommand menuCommand) { GameObject parent = menuCommand.context as GameObject; diff --git a/com.unity.ugui/LICENSE.md b/com.unity.ugui/LICENSE.md index 3af9c29..208a9f4 100644 --- a/com.unity.ugui/LICENSE.md +++ b/com.unity.ugui/LICENSE.md @@ -1,4 +1,4 @@ -Unity UI Copyright © 2015-2020 Unity Technologies ApS ("**_Unity_**") +uGUI Copyright © 2015-2020 Unity Technologies ApS ("**_Unity_**") Licensed under the Unity Companion License for Unity-dependent projects (see https://unity3d.com/legal/licenses/unity_companion_license). diff --git a/com.unity.ugui/README.md b/com.unity.ugui/README.md index 223c383..e365b68 100644 --- a/com.unity.ugui/README.md +++ b/com.unity.ugui/README.md @@ -1,5 +1,5 @@ -# Unity UI -The Unity UI package allows you to create in-game user interfaces fast and intuitively. +# uGUI (Unity UI) +The uGUI (Unity UI) package allows you to create in-game user interfaces fast and intuitively. ## Getting Started -The Unity UI user manual can be found [here](https://docs.unity3d.com/Manual/UISystem.html). +The uGUI (Unity UI) user manual can be found [here](https://docs.unity3d.com/Manual/UISystem.html). diff --git a/com.unity.ugui/Runtime/TMP/TMP_Dropdown.cs b/com.unity.ugui/Runtime/TMP/TMP_Dropdown.cs index deecaeb..c2b1ba2 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_Dropdown.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_Dropdown.cs @@ -9,7 +9,7 @@ namespace TMPro { - [AddComponentMenu("UI/Dropdown - TextMeshPro", 35)] + [AddComponentMenu("UI (Canvas)/Dropdown - TextMeshPro", 35)] [RequireComponent(typeof(RectTransform))] /// /// A standard dropdown that presents a list of options when clicked, of which one can be chosen. diff --git a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs index 640fd63..4afdedd 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs @@ -18,7 +18,7 @@ namespace TMPro /// /// Editable text input field. /// - [AddComponentMenu("UI/TextMeshPro - Input Field", 11)] + [AddComponentMenu("UI (Canvas)/TextMeshPro - Input Field", 11)] #if UNITY_2023_2_OR_NEWER [HelpURL("https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/TextMeshPro/index.html")] #else diff --git a/com.unity.ugui/Runtime/TMP/TMP_MaterialManager.cs b/com.unity.ugui/Runtime/TMP/TMP_MaterialManager.cs index 1d9e1ce..6b32140 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_MaterialManager.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_MaterialManager.cs @@ -266,7 +266,7 @@ public static void ClearMaterials() /// public static int GetStencilID(GameObject obj) { - // Implementation is almost copied from Unity UI + // Implementation is almost copied from uGUI (Unity UI) var count = 0; @@ -320,7 +320,7 @@ public static Material GetMaterialForRendering(MaskableGraphic graphic, Material private static Transform FindRootSortOverrideCanvas(Transform start) { - // Implementation is copied from Unity UI + // Implementation is copied from uGUI (Unity UI) var canvasList = TMP_ListPool.Get(); start.GetComponentsInParent(false, canvasList); diff --git a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index bc48176..92ce4c4 100644 --- a/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -19,7 +19,7 @@ namespace TMPro [DisallowMultipleComponent] [RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(CanvasRenderer))] - [AddComponentMenu("UI/TextMeshPro - Text (UI)", 11)] + [AddComponentMenu("UI (Canvas)/TextMeshPro - Text (UI)", 11)] [ExecuteAlways] #if UNITY_2023_2_OR_NEWER [HelpURL("https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/TextMeshPro/index.html")] diff --git a/com.unity.ugui/Runtime/UGUI/EventSystem/EventSystem.cs b/com.unity.ugui/Runtime/UGUI/EventSystem/EventSystem.cs index 32e5145..3d7eef8 100644 --- a/com.unity.ugui/Runtime/UGUI/EventSystem/EventSystem.cs +++ b/com.unity.ugui/Runtime/UGUI/EventSystem/EventSystem.cs @@ -363,7 +363,7 @@ private struct UIToolkitOverrideConfigOld /// /// Sets how UI Toolkit runtime panels receive events and handle selection - /// when interacting with other objects that use the EventSystem, such as components from the Unity UI package. + /// when interacting with other objects that use the EventSystem, such as components from the uGUI (Unity UI) package. /// /// /// This method is obsolete. Use the PanelInputConfiguration component instead. diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Button.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Button.cs index 2819d98..a3d4078 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Button.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Button.cs @@ -9,7 +9,7 @@ namespace UnityEngine.UI /// /// A standard button that sends an event when clicked. /// - [AddComponentMenu("UI/Button", 30)] + [AddComponentMenu("UI (Canvas)/Button", 30)] public class Button : Selectable, IPointerClickHandler, ISubmitHandler { [Serializable] diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Dropdown.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Dropdown.cs index a65b3d1..c4d6f85 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Dropdown.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Dropdown.cs @@ -8,7 +8,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Legacy/Dropdown", 102)] + [AddComponentMenu("UI (Canvas)/Legacy/Dropdown", 102)] [RequireComponent(typeof(RectTransform))] /// /// A standard dropdown that presents a list of options when clicked, of which one can be chosen. diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs index 1c05533..f0ec83c 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs @@ -12,7 +12,7 @@ namespace UnityEngine.UI /// [RequireComponent(typeof(CanvasRenderer))] - [AddComponentMenu("UI/Image", 11)] + [AddComponentMenu("UI (Canvas)/Image", 11)] /// /// Displays a Sprite inside the UI System. /// diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs index d5b1a02..8d5cef1 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs @@ -13,7 +13,7 @@ namespace UnityEngine.UI /// Turn a simple label into a interactable input field. /// - [AddComponentMenu("UI/Legacy/Input Field", 103)] + [AddComponentMenu("UI (Canvas)/Legacy/Input Field", 103)] public class InputField : Selectable, IUpdateSelectedHandler, diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutRebuilder.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutRebuilder.cs index eef4283..b003bcf 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutRebuilder.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Layout/LayoutRebuilder.cs @@ -198,17 +198,20 @@ public static void MarkLayoutForRebuild(RectTransform rect) #if UNITY_EDITOR //Child ILayoutGroup components from the root need to be marked for layout rebuild. //UUM-100091: Ideally, we'd want a broader fix. This change narrowly addresses the bug. - using (ListPool.Get(out var layoutComps)) + if (!UnityEditor.EditorApplication.isPlaying) { - layoutRoot.GetComponentsInChildren(layoutComps); - foreach (var layout in layoutComps) + using (ListPool.Get(out var layoutComps)) { - if (layout is Behaviour behaviour && behaviour.isActiveAndEnabled) + layoutRoot.GetComponentsInChildren(layoutComps); + foreach (var layout in layoutComps) { - if (ReferenceEquals(behaviour.gameObject, layoutRoot.gameObject)) - continue; + if (layout is Behaviour behaviour && behaviour.isActiveAndEnabled) + { + if (ReferenceEquals(behaviour.gameObject, layoutRoot.gameObject)) + continue; - MarkLayoutRootForRebuild(behaviour.transform as RectTransform); + MarkLayoutRootForRebuild(behaviour.transform as RectTransform); + } } } } diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Mask.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Mask.cs index 3619b5d..54836cb 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Mask.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Mask.cs @@ -6,7 +6,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Mask", 13)] + [AddComponentMenu("UI (Canvas)/Mask", 13)] [ExecuteAlways] [RequireComponent(typeof(RectTransform))] [DisallowMultipleComponent] diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/RawImage.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/RawImage.cs index bd6fd67..93effd2 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/RawImage.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/RawImage.cs @@ -12,7 +12,7 @@ namespace UnityEngine.UI /// [RequireComponent(typeof(CanvasRenderer))] - [AddComponentMenu("UI/Raw Image", 12)] + [AddComponentMenu("UI (Canvas)/Raw Image", 12)] public class RawImage : MaskableGraphic { [FormerlySerializedAs("m_Tex")] diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/RectMask2D.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/RectMask2D.cs index 443acdb..61fb85d 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/RectMask2D.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/RectMask2D.cs @@ -5,7 +5,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Rect Mask 2D", 14)] + [AddComponentMenu("UI (Canvas)/Rect Mask 2D", 14)] [ExecuteAlways] [DisallowMultipleComponent] [RequireComponent(typeof(RectTransform))] diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs index ab676fb..a475d17 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs @@ -4,7 +4,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Scroll Rect", 37)] + [AddComponentMenu("UI (Canvas)/Scroll Rect", 37)] [SelectionBase] [ExecuteAlways] [DisallowMultipleComponent] diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Scrollbar.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Scrollbar.cs index 7af5bbe..e269b79 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Scrollbar.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Scrollbar.cs @@ -5,7 +5,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Scrollbar", 36)] + [AddComponentMenu("UI (Canvas)/Scrollbar", 36)] [ExecuteAlways] [RequireComponent(typeof(RectTransform))] /// diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Selectable.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Selectable.cs index 47ebf53..803c7ca 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Selectable.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Selectable.cs @@ -5,7 +5,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Selectable", 35)] + [AddComponentMenu("UI (Canvas)/Selectable", 35)] [ExecuteAlways] [SelectionBase] [DisallowMultipleComponent] diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs index abe5392..4539059 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Slider.cs @@ -8,7 +8,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Slider", 34)] + [AddComponentMenu("UI (Canvas)/Slider", 34)] [ExecuteAlways] [RequireComponent(typeof(RectTransform))] /// diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Text.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Text.cs index 1ac9e11..27738ea 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Text.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Text.cs @@ -4,7 +4,7 @@ namespace UnityEngine.UI { [RequireComponent(typeof(CanvasRenderer))] - [AddComponentMenu("UI/Legacy/Text", 100)] + [AddComponentMenu("UI (Canvas)/Legacy/Text", 100)] /// /// The default Graphic to draw font data to screen. /// diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs index 7ac0b54..eecd9ce 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs @@ -12,7 +12,7 @@ namespace UnityEngine.UI /// The toggle component is a Selectable that controls a child graphic which displays the on / off state. /// When a toggle event occurs a callback is sent to any registered listeners of UI.Toggle._onValueChanged. /// - [AddComponentMenu("UI/Toggle", 30)] + [AddComponentMenu("UI (Canvas)/Toggle", 30)] [RequireComponent(typeof(RectTransform))] public class Toggle : Selectable, IPointerClickHandler, ISubmitHandler, ICanvasElement { @@ -283,6 +283,11 @@ void Set(bool value, bool sendCallback = true) UISystemProfilerApi.AddMarker("Toggle.value", this); onValueChanged.Invoke(m_IsOn); } + +#if PACKAGE_POLYSPATIAL + // When the isOn value is changed, call MarkDirty() so that ObjectDispatcher picks it up. + MarkDirty(); +#endif } /// diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/ToggleGroup.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/ToggleGroup.cs index 559f391..cac1b7c 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/ToggleGroup.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/ToggleGroup.cs @@ -5,7 +5,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Toggle Group", 31)] + [AddComponentMenu("UI (Canvas)/Toggle Group", 31)] [DisallowMultipleComponent] /// /// A component that represents a group of UI.Toggles. diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/Outline.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/Outline.cs index 02da103..f265b94 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/Outline.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/Outline.cs @@ -2,7 +2,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Effects/Outline", 81)] + [AddComponentMenu("UI (Canvas)/Effects/Outline", 81)] /// /// Adds an outline to a graphic using IVertexModifier. /// diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/PositionAsUV1.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/PositionAsUV1.cs index 4d872a5..ad513dd 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/PositionAsUV1.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/PositionAsUV1.cs @@ -2,7 +2,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Effects/Position As UV1", 82)] + [AddComponentMenu("UI (Canvas)/Effects/Position As UV1", 82)] /// /// An IVertexModifier which sets the raw vertex position into UV1 of the generated verts. /// diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/Shadow.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/Shadow.cs index 3ac029e..230a6e9 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/Shadow.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/VertexModifiers/Shadow.cs @@ -4,7 +4,7 @@ namespace UnityEngine.UI { - [AddComponentMenu("UI/Effects/Shadow", 80)] + [AddComponentMenu("UI (Canvas)/Effects/Shadow", 80)] /// /// Adds an outline to a graphic using IVertexModifier. /// diff --git a/com.unity.ugui/Tests/Editor/TMP/TMP_ControlTests.cs b/com.unity.ugui/Tests/Editor/TMP/TMP_ControlTests.cs index 81feba1..8ac07fb 100644 --- a/com.unity.ugui/Tests/Editor/TMP/TMP_ControlTests.cs +++ b/com.unity.ugui/Tests/Editor/TMP/TMP_ControlTests.cs @@ -15,10 +15,10 @@ public void Setup() scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene); } - [TestCase("GameObject/UI/Dropdown - TextMeshPro")] - [TestCase("GameObject/UI/Button - TextMeshPro")] - [TestCase("GameObject/UI/Input Field - TextMeshPro")] - [TestCase("GameObject/UI/Text - TextMeshPro")] + [TestCase("GameObject/UI (Canvas)/Dropdown - TextMeshPro")] + [TestCase("GameObject/UI (Canvas)/Button - TextMeshPro")] + [TestCase("GameObject/UI (Canvas)/Input Field - TextMeshPro")] + [TestCase("GameObject/UI (Canvas)/Text - TextMeshPro")] public void TMPControlCreationAndUndoTest(string menuItem) { Assert.AreEqual(0, scene.rootCount); diff --git a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs index 4c1df05..51567f9 100644 --- a/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs +++ b/com.unity.ugui/Tests/Runtime/UGUI/Canvas/NoActiveCameraInSceneDoesNotCrashEditor.cs @@ -21,7 +21,7 @@ public void Setup() #if UNITY_EDITOR Action codeToExecute = delegate() { - UnityEditor.EditorApplication.ExecuteMenuItem("GameObject/UI/Legacy/Button"); + UnityEditor.EditorApplication.ExecuteMenuItem("GameObject/UI (Canvas)/Legacy/Button"); }; CreateSceneUtility.CreateScene(k_SceneName, codeToExecute); diff --git a/com.unity.ugui/package.json b/com.unity.ugui/package.json index bb98db4..c0944d3 100644 --- a/com.unity.ugui/package.json +++ b/com.unity.ugui/package.json @@ -1,6 +1,6 @@ { "name": "com.unity.ugui", - "displayName": "Unity UI", + "displayName": "uGUI", "version": "2.0.0", "unity": "2019.2", "keywords": [ @@ -14,7 +14,7 @@ "TMP", "SDF" ], - "description": "Unity UI is a set of tools for developing user interfaces for games and applications. It is a GameObject-based UI system that uses Components and the Game View to arrange, position, and style user interfaces. ​ You cannot use Unity UI to create or change user interfaces in the Unity Editor.", + "description": "uGUI (Unity UI) is a set of tools for developing user interfaces for games and applications. It is a GameObject-based UI system that uses Components and the Game View to arrange, position, and style user interfaces. ​ You cannot use Unity UI to create or change user interfaces in the Unity Editor.", "dependencies": { "com.unity.modules.ui": "1.0.0", "com.unity.modules.imgui":"1.0.0" From 87fd4453a1a37e21dbeff800b16784975eedc3e8 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 17 Jan 2026 05:57:17 +0000 Subject: [PATCH 14/26] Mirror com.unity.ugui package (Unity 6000.3.6f1) --- com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs index a475d17..2c61d97 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/ScrollRect.cs @@ -1051,8 +1051,8 @@ public float verticalNormalizedPosition } } - private void SetHorizontalNormalizedPosition(float value) { SetNormalizedPosition(value, 0); } - private void SetVerticalNormalizedPosition(float value) { SetNormalizedPosition(value, 1); } + private void SetHorizontalNormalizedPosition(float value) { if(horizontalNormalizedPosition != value) SetNormalizedPosition(value, 0); } + private void SetVerticalNormalizedPosition(float value) { if(verticalNormalizedPosition != value) SetNormalizedPosition(value, 1); } /// /// >Set the horizontal or vertical scroll position as a value between 0 and 1, with 0 being at the left or at the bottom. From 2bebd161062b4fda4720d4f04fe306d76941846f Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 24 Jan 2026 05:57:54 +0000 Subject: [PATCH 15/26] Mirror com.unity.ugui package (Unity 6000.3.7f1) --- com.unity.ugui/Documentation~/ProfilerUI.md | 28 ++++++++++----------- com.unity.ugui/Documentation~/index.md | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/com.unity.ugui/Documentation~/ProfilerUI.md b/com.unity.ugui/Documentation~/ProfilerUI.md index b9fb649..d8fe514 100644 --- a/com.unity.ugui/Documentation~/ProfilerUI.md +++ b/com.unity.ugui/Documentation~/ProfilerUI.md @@ -2,28 +2,28 @@ uid: um-profiler-ui --- -# UI and UI Details Profiler module reference +# UI (Canvas) and UI Details (Canvas) Profiler module reference >[!NOTE] -> The UI and UI Details Profiler module collects Editor-only data, and doesn't work in development builds. +> The UI (Canvas) and UI Details (Canvas) Profiler module collects Editor-only data, and doesn't work in development builds. -The UI and UI Details Profiler modules provide information on how much time and resources Unity spends laying out and rendering the user interface within your application. You can use this module to understand how Unity handles UI batching for your application, including why and how it batches objects. You can also use this module to find out which part of the UI has slow performance, or to preview the UI while you scrub the timeline. +The UI (Canvas) and UI Details (Canvas) Profiler modules provide information on how much time and resources uGUI (Unity UI) spends laying out and rendering the user interface within your application. You can use this module to understand how uGUI handles UI batching for your application, including why and how it batches objects. You can also use this module to find out which part of the uGUI's UI has slow performance, or to preview the UI while you scrub the timeline. To open the Profiler window, go to **Window > Analysis > Profiler**. For more information on how to use the Profiler window, refer to [The Profiler window](xref:um-profiler-window). -![The UI and UI Details Profiler module](images/ui-profiler-module.png) +![The UI (Canvas) and UI Details (Canvas) Profiler module](images/ui-profiler-module.png) ## Chart categories -The UI and UI Details Profiler modules' charts contain the following categories. To change the order of the categories in the chart, you can drag and drop them in the chart's legend. You can also click a category's colored legend to toggle its display. +The UI (Canvas) and UI Details (Canvas) Profiler modules' charts contain the following categories. To change the order of the categories in the chart, you can drag and drop them in the chart's legend. You can also click a category's colored legend to toggle its display. -### UI Profiler module +### UI (Canvas) Profiler module |**Chart**|**Description**| |---|---| -|**Layout**|How much time Unity spent performing the layout pass for the UI. This includes calculations done by [`HorizontalLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.HorizontalLayoutGroup.html), [`VerticalLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.VerticalLayoutGroup.html), and [`GridLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.GridLayoutGroup.html).| -|**Render**|How much time the UI has spent doing its portion of rendering. This is either the time spent rendering directly to the graphics device or rendering to the main render queue.| +|**Layout**|How much time uGUI spent performing the layout pass for the UI. This includes calculations done by [`HorizontalLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.HorizontalLayoutGroup.html), [`VerticalLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.VerticalLayoutGroup.html), and [`GridLayoutGroup`](https://docs.unity3d.com/Packages/com.unity.ugui@latest/index.html?subfolder=/api/UnityEngine.UI.GridLayoutGroup.html).| +|**Render**|How much time uGUI has spent doing its portion of rendering. This is either the time spent rendering directly to the graphics device or rendering to the main render queue.| -### UI Details Profile module +### UI Details (Canvas) Profile module |**Chart**|**Description**| |---|---| @@ -32,20 +32,20 @@ The UI and UI Details Profiler modules' charts contain the following categories. |**Markers**|Displays event markers. Unity records markers when the user interacts with the UI (for example, a button click, or a slider value change) and then draws them as vertical lines and labels on the chart.| ## Module details pane -When you select the UI or the UI Details Profiler module, the module details pane at the bottom of the Profiler window displays more details on the UI in your application. You can use it to inspect the profiling information about the UI objects in your application. The pane is divided into the following columns: +When you select the UI (Canvas) or the UI Details (Canvas) Profiler module, the module details pane at the bottom of the Profiler window displays more details on the uGUI's UI in your application. You can use it to inspect the profiling information about the UI objects in your application. The pane is divided into the following columns: |**Column**|**Description**| |---|---| |**Object**|A list of UI canvases your application used during the period profiled. Double click on a row to highlight the matching object in the scene.| -|**Self Batch Count**|How many batches Unity generated for the canvas.| -|**Cumulative Batch Count**|How many batches Unity generated for the canvas and all its nested canvases.| +|**Self Batch Count**|How many batches uGUI generated for the canvas.| +|**Cumulative Batch Count**|How many batches uGUI generated for the canvas and all its nested canvases.| |**Self Vertex Count**|How many vertices this canvas is rendering.| |**Cumulative Vertex Count**|How many vertices this canvas and nested canvases are rendering.| -|**Batch Breaking Reason**|Why Unity split the batch. Sometimes Unity might not be able to batch objects together. Common reasons include:
  • **Not Coplanar With Canvas**: The batching needs the object's rect transform to be coplanar (unrotated) with the canvas.
  • **CanvasInjectionIndex**: A CanvasGroup component is present and forces a new batch, such as when it displays the drop down list of a combo box on top of the rest.
  • **Different Material Instance, Rect clipping, Texture, or A8TextureUsage**: Unity can only batch together objects with identical materials, masking, textures, and texture alpha channel usage.
| +|**Batch Breaking Reason**|Why uGUI split the batch. Sometimes uGUI might not be able to batch objects together. Common reasons include:
  • **Not Coplanar With Canvas**: The batching needs the object's rect transform to be coplanar (unrotated) with the canvas.
  • **CanvasInjectionIndex**: A CanvasGroup component is present and forces a new batch, such as when it displays the drop down list of a combo box on top of the rest.
  • **Different Material Instance, Rect clipping, Texture, or A8TextureUsage**: Unity can only batch together objects with identical materials, masking, textures, and texture alpha channel usage.
| |**GameObject Count**|How many GameObjects are part of this batch.| |**GameObjects**|The list of GameObjects in the batch.| -When you select a UI object from the list, a preview of it appears on the right hand side of the pane. Above the preview there are the following options in the toolbar: +When you select a uGUI's UI object from the list, a preview of it appears on the right hand side of the pane. Above the preview there are the following options in the toolbar: * **Detach:** Select this button to open the UI canvas in a separate window. To reattach the window, close it. * **Preview background:** Use the dropdown to change the color of the preview background. You can choose from **Checkerboard**, **Black**, or **White**. This is useful if your UI has a particularly light or dark color scheme. diff --git a/com.unity.ugui/Documentation~/index.md b/com.unity.ugui/Documentation~/index.md index 0762c82..81679e3 100644 --- a/com.unity.ugui/Documentation~/index.md +++ b/com.unity.ugui/Documentation~/index.md @@ -14,7 +14,7 @@ Unity UI (uGUI) is a GameObject-based UI system that you can use to develop user | [Events](EventSystem.md) | The Event System sends events to objects in the application based on input. | | [Reference](UIReference.md) | Comprehensive guide to understanding of uGUI features. | | [UI How Tos](UIHowTos.md) | Solutions to common UI tasks. | -| [UI and UI Details Profiler](ProfilerUI.md) | Use the UI and UI Details Profiler modules to understand how Unity handles UI batching for your application. | +| [UI (Canvas) and UI Details (Canvas) Profiler](ProfilerUI.md) | Use the UI (Canvas) and UI Details (Canvas) Profiler modules to understand how uGUI handles UI batching for your application. | > [!NOTE] > You can't use uGUI to create or change user interfaces of the Unity Editor. From 46d6570d96fc521fe84004f8bc3f1e52e3275a41 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 31 Jan 2026 06:00:39 +0000 Subject: [PATCH 16/26] Mirror com.unity.ugui package (Unity 6000.3.8f1) --- com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs index 8d5cef1..b303d8d 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs @@ -1483,6 +1483,10 @@ protected virtual void LateUpdate() m_WasCanceled = true; else if (m_Keyboard.status == TouchScreenKeyboard.Status.Done) SendOnSubmit(); + +#if UNITY_ANDROID || UNITY_IOS + DeactivateInputField(); +#endif } return; From 667391773a4d98d77aeeffd679f3f85d50a368ef Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 21 Feb 2026 06:17:19 +0000 Subject: [PATCH 17/26] Mirror com.unity.ugui package (Unity 6000.3.11f1) --- com.unity.ugui/Runtime/TMP/TMP_Text.cs | 120 +++++++++--------- .../Runtime/TMP/TMPro_MeshUtilities.cs | 10 +- 2 files changed, 69 insertions(+), 61 deletions(-) diff --git a/com.unity.ugui/Runtime/TMP/TMP_Text.cs b/com.unity.ugui/Runtime/TMP/TMP_Text.cs index 0dce65d..f85671b 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_Text.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_Text.cs @@ -2197,6 +2197,7 @@ void PopulateTextProcessingArray() InsertOpeningStyleTag(m_TextStyle, ref m_TextProcessingArray, ref writeIndex); tag_NoParsing = false; + bool wasAnchorElementStyleApplied = false; int readIndex = 0; for (; readIndex < srcLength; readIndex++) @@ -2337,8 +2338,12 @@ void PopulateTextProcessingArray() continue; case MarkupTag.A: // Additional check - if (m_TextBackingArray.Count > readIndex + 4 && m_TextBackingArray[readIndex + 3] == 'h' && m_TextBackingArray[readIndex + 4] == 'r') + if (m_TextBackingArray.Count > readIndex + 4 && m_TextBackingArray[readIndex + 3] == 'h' && + m_TextBackingArray[readIndex + 4] == 'r') + { InsertOpeningTextStyle(GetStyle((int)MarkupTag.A), ref m_TextProcessingArray, ref writeIndex); + wasAnchorElementStyleApplied = true; + } break; case MarkupTag.STYLE: if (tag_NoParsing) break; @@ -2358,7 +2363,11 @@ void PopulateTextProcessingArray() } break; case MarkupTag.SLASH_A: - InsertClosingTextStyle(GetStyle((int)MarkupTag.A), ref m_TextProcessingArray, ref writeIndex); + if (wasAnchorElementStyleApplied) + { + InsertClosingTextStyle(GetStyle((int)MarkupTag.A), ref m_TextProcessingArray, ref writeIndex); + wasAnchorElementStyleApplied = false; + } break; case MarkupTag.SLASH_STYLE: if (tag_NoParsing) break; @@ -6793,13 +6802,6 @@ protected float ConvertToFloat(char[] chars, int startIndex, int length, out int return value; } - void ClearMarkupTagAttributes() - { - int length = m_xmlAttribute.Length; - for (int i = 0; i < length; i++) - m_xmlAttribute[i] = new RichTextTagAttribute(); - } - /// /// Function to identify and validate the rich tag. Returns the position of the > if the tag was valid. /// @@ -6812,11 +6814,16 @@ internal bool ValidateHtmlTag(TextProcessingElement[] chars, int startIndex, out int tagCharCount = 0; byte attributeFlag = 0; - int attributeIndex = 0; - ClearMarkupTagAttributes(); + // Reset the first element of the array + m_xmlAttribute[0] = RichTextTagAttribute.Default; + TagValueType tagValueType = TagValueType.None; TagUnitType tagUnitType = TagUnitType.Pixels; + // Cache reference to markupAttribute + int attributeIndex = 0; + ref RichTextTagAttribute markupAttribute = ref m_xmlAttribute[attributeIndex]; + endIndex = startIndex; bool isTagSet = false; bool isValidHtmlTag = false; @@ -6844,30 +6851,30 @@ internal bool ValidateHtmlTag(TextProcessingElement[] chars, int startIndex, out if (unicode == '+' || unicode == '-' || unicode == '.' || (unicode >= '0' && unicode <= '9')) { tagUnitType = TagUnitType.Pixels; - tagValueType = m_xmlAttribute[attributeIndex].valueType = TagValueType.NumericalValue; - m_xmlAttribute[attributeIndex].valueStartIndex = tagCharCount - 1; - m_xmlAttribute[attributeIndex].valueLength += 1; + tagValueType = markupAttribute.valueType = TagValueType.NumericalValue; + markupAttribute.valueStartIndex = tagCharCount - 1; + markupAttribute.valueLength += 1; } else if (unicode == '#') { tagUnitType = TagUnitType.Pixels; - tagValueType = m_xmlAttribute[attributeIndex].valueType = TagValueType.ColorValue; - m_xmlAttribute[attributeIndex].valueStartIndex = tagCharCount - 1; - m_xmlAttribute[attributeIndex].valueLength += 1; + tagValueType = markupAttribute.valueType = TagValueType.ColorValue; + markupAttribute.valueStartIndex = tagCharCount - 1; + markupAttribute.valueLength += 1; } else if (unicode == '"') { tagUnitType = TagUnitType.Pixels; - tagValueType = m_xmlAttribute[attributeIndex].valueType = TagValueType.StringValue; - m_xmlAttribute[attributeIndex].valueStartIndex = tagCharCount; + tagValueType = markupAttribute.valueType = TagValueType.StringValue; + markupAttribute.valueStartIndex = tagCharCount; } else { tagUnitType = TagUnitType.Pixels; - tagValueType = m_xmlAttribute[attributeIndex].valueType = TagValueType.StringValue; - m_xmlAttribute[attributeIndex].valueStartIndex = tagCharCount - 1; - m_xmlAttribute[attributeIndex].valueHashCode = (m_xmlAttribute[attributeIndex].valueHashCode << 5) + m_xmlAttribute[attributeIndex].valueHashCode ^ TMP_TextUtilities.ToUpperFast((char)unicode); - m_xmlAttribute[attributeIndex].valueLength += 1; + tagValueType = markupAttribute.valueType = TagValueType.StringValue; + markupAttribute.valueStartIndex = tagCharCount - 1; + markupAttribute.valueHashCode = (markupAttribute.valueHashCode << 5) + markupAttribute.valueHashCode ^ TMP_TextUtilities.ToUpperFast((char)unicode); + markupAttribute.valueLength += 1; } } else @@ -6883,48 +6890,40 @@ internal bool ValidateHtmlTag(TextProcessingElement[] chars, int startIndex, out switch (unicode) { case 'e': - m_xmlAttribute[attributeIndex].unitType = tagUnitType = TagUnitType.FontUnits; + markupAttribute.unitType = tagUnitType = TagUnitType.FontUnits; break; case '%': - m_xmlAttribute[attributeIndex].unitType = tagUnitType = TagUnitType.Percentage; + markupAttribute.unitType = tagUnitType = TagUnitType.Percentage; break; default: - m_xmlAttribute[attributeIndex].unitType = tagUnitType = TagUnitType.Pixels; + markupAttribute.unitType = tagUnitType = TagUnitType.Pixels; break; } attributeIndex += 1; - m_xmlAttribute[attributeIndex].nameHashCode = 0; - m_xmlAttribute[attributeIndex].valueHashCode = 0; - m_xmlAttribute[attributeIndex].valueType = TagValueType.None; - m_xmlAttribute[attributeIndex].unitType = TagUnitType.Pixels; - m_xmlAttribute[attributeIndex].valueStartIndex = 0; - m_xmlAttribute[attributeIndex].valueLength = 0; - + markupAttribute = ref m_xmlAttribute[attributeIndex]; + markupAttribute = RichTextTagAttribute.Default; } else { - m_xmlAttribute[attributeIndex].valueLength += 1; + markupAttribute.valueLength += 1; } } else if (tagValueType == TagValueType.ColorValue) { if (unicode != ' ') { - m_xmlAttribute[attributeIndex].valueLength += 1; + markupAttribute.valueLength += 1; } else { attributeFlag = 2; tagValueType = TagValueType.None; tagUnitType = TagUnitType.Pixels; + attributeIndex += 1; - m_xmlAttribute[attributeIndex].nameHashCode = 0; - m_xmlAttribute[attributeIndex].valueType = TagValueType.None; - m_xmlAttribute[attributeIndex].unitType = TagUnitType.Pixels; - m_xmlAttribute[attributeIndex].valueHashCode = 0; - m_xmlAttribute[attributeIndex].valueStartIndex = 0; - m_xmlAttribute[attributeIndex].valueLength = 0; + markupAttribute = ref m_xmlAttribute[attributeIndex]; + markupAttribute = RichTextTagAttribute.Default; } } else if (tagValueType == TagValueType.StringValue) @@ -6932,28 +6931,24 @@ internal bool ValidateHtmlTag(TextProcessingElement[] chars, int startIndex, out // Compute HashCode value for the named tag. if (unicode != '"') { - m_xmlAttribute[attributeIndex].valueHashCode = (m_xmlAttribute[attributeIndex].valueHashCode << 5) + m_xmlAttribute[attributeIndex].valueHashCode ^ TMP_TextUtilities.ToUpperFast((char)unicode); - m_xmlAttribute[attributeIndex].valueLength += 1; + markupAttribute.valueHashCode = (markupAttribute.valueHashCode << 5) + markupAttribute.valueHashCode ^ TMP_TextUtilities.ToUpperFast((char)unicode); + markupAttribute.valueLength += 1; } else { attributeFlag = 2; tagValueType = TagValueType.None; tagUnitType = TagUnitType.Pixels; + attributeIndex += 1; - m_xmlAttribute[attributeIndex].nameHashCode = 0; - m_xmlAttribute[attributeIndex].valueType = TagValueType.None; - m_xmlAttribute[attributeIndex].unitType = TagUnitType.Pixels; - m_xmlAttribute[attributeIndex].valueHashCode = 0; - m_xmlAttribute[attributeIndex].valueStartIndex = 0; - m_xmlAttribute[attributeIndex].valueLength = 0; + markupAttribute = ref m_xmlAttribute[attributeIndex]; + markupAttribute = RichTextTagAttribute.Default; } } } } - - if (unicode == '=') // '=' + if (attributeFlag == 0 && unicode == '=') // '=' attributeFlag = 1; // Compute HashCode for the name of the attribute @@ -6966,23 +6961,25 @@ internal bool ValidateHtmlTag(TextProcessingElement[] chars, int startIndex, out tagValueType = TagValueType.None; tagUnitType = TagUnitType.Pixels; + attributeIndex += 1; - m_xmlAttribute[attributeIndex].nameHashCode = 0; - m_xmlAttribute[attributeIndex].valueType = TagValueType.None; - m_xmlAttribute[attributeIndex].unitType = TagUnitType.Pixels; - m_xmlAttribute[attributeIndex].valueHashCode = 0; - m_xmlAttribute[attributeIndex].valueStartIndex = 0; - m_xmlAttribute[attributeIndex].valueLength = 0; + markupAttribute = ref m_xmlAttribute[attributeIndex]; + markupAttribute = RichTextTagAttribute.Default; } if (attributeFlag == 0) - m_xmlAttribute[attributeIndex].nameHashCode = (m_xmlAttribute[attributeIndex].nameHashCode << 5) + m_xmlAttribute[attributeIndex].nameHashCode ^ TMP_TextUtilities.ToUpperFast((char)unicode); + markupAttribute.nameHashCode = (markupAttribute.nameHashCode << 5) + markupAttribute.nameHashCode ^ TMP_TextUtilities.ToUpperFast((char)unicode); if (attributeFlag == 2 && unicode == ' ') attributeFlag = 0; } + // Terminate markupAttribute array + int terminalIndex = attributeIndex + 1; + if (terminalIndex < m_xmlAttribute.Length) + m_xmlAttribute[terminalIndex] = RichTextTagAttribute.Default; + if (!isValidHtmlTag) { return false; @@ -7590,9 +7587,12 @@ internal bool ValidateHtmlTag(TextProcessingElement[] chars, int startIndex, out { int index = m_textInfo.linkCount; - m_textInfo.linkInfo[index].linkTextLength = m_characterCount - m_textInfo.linkInfo[index].linkTextfirstCharacterIndex; + if (index < m_textInfo.linkInfo.Length) + { + m_textInfo.linkInfo[index].linkTextLength = m_characterCount - m_textInfo.linkInfo[index].linkTextfirstCharacterIndex; - m_textInfo.linkCount += 1; + m_textInfo.linkCount += 1; + } } return true; case MarkupTag.LINK: diff --git a/com.unity.ugui/Runtime/TMP/TMPro_MeshUtilities.cs b/com.unity.ugui/Runtime/TMP/TMPro_MeshUtilities.cs index 51e4265..188d004 100644 --- a/com.unity.ugui/Runtime/TMP/TMPro_MeshUtilities.cs +++ b/com.unity.ugui/Runtime/TMP/TMPro_MeshUtilities.cs @@ -449,7 +449,7 @@ internal struct TagAttribute public int hashCode; } - internal struct RichTextTagAttribute + struct RichTextTagAttribute { public int nameHashCode; public int valueHashCode; @@ -457,6 +457,14 @@ internal struct RichTextTagAttribute public int valueStartIndex; public int valueLength; public TagUnitType unitType; + + public static RichTextTagAttribute Default => k_Default; + + static readonly RichTextTagAttribute k_Default = new () + { + valueType = TagValueType.None, + unitType = TagUnitType.Pixels + }; } } From 1c8d37648677aff82422ba569d4782a04bd0c73b Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 28 Feb 2026 06:00:44 +0000 Subject: [PATCH 18/26] Mirror com.unity.ugui package (Unity 6000.3.11f1) --- com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs | 2 +- .../Runtime/UGUI/UI/Core/ToggleGroup.cs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs index eecd9ce..cce8675 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/Toggle.cs @@ -199,7 +199,7 @@ private void SetToggleGroup(ToggleGroup newGroup, bool setMemberValue) } /// - /// Whether the toggle is currently active. + /// Whether the toggle is currently on. /// /// /// diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/ToggleGroup.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/ToggleGroup.cs index cac1b7c..973bd0d 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/ToggleGroup.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/ToggleGroup.cs @@ -11,7 +11,7 @@ namespace UnityEngine.UI /// A component that represents a group of UI.Toggles. ///
/// - /// When using a group reference the group from a UI.Toggle. Only one member of a group can be active at a time. + /// When using a group reference from a `UI.Toggle`. Only one member of a group can be on at a time. /// public class ToggleGroup : UIBehaviour { @@ -33,7 +33,7 @@ protected ToggleGroup() /// /// Because all the Toggles have registered themselves in the OnEnabled, Start should check to - /// make sure at least one Toggle is active in groups that do not AllowSwitchOff + /// make sure at least one Toggle is on in groups that do not AllowSwitchOff /// protected override void Start() { @@ -54,7 +54,7 @@ private void ValidateToggleIsInGroup(Toggle toggle) } /// - /// Notify the group that the given toggle is enabled. + /// Notify the group that the given toggle is on. /// /// The toggle that got triggered on. /// If other toggles should send onValueChanged. @@ -133,11 +133,11 @@ public bool AnyTogglesOn() } /// - /// Returns the toggles in this group that are active. + /// Returns the toggles in this group that are on. /// - /// The active toggles in the group. + /// The toggles in the group that are on. /// - /// Toggles belonging to this group but are not active either because their GameObject is inactive or because the Toggle component is disabled, are not returned as part of the list. + /// This only checks the on or off state, not the GameObject's active state. /// public IEnumerable ActiveToggles() { @@ -145,11 +145,11 @@ public IEnumerable ActiveToggles() } /// - /// Returns the toggle that is the first in the list of active toggles. + /// Returns the first toggle that is on. /// - /// The first active toggle from m_Toggles + /// The first toggle that is on, or `null` if none are on. /// - /// Get the active toggle for this group. As the group + /// This only checks the on or off state, not the GameObject's active state. /// public Toggle GetFirstActiveToggle() { From 8778e5aa192de0c8f3cf3f02128af785d32cbbba Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 7 Mar 2026 06:43:15 +0000 Subject: [PATCH 19/26] Mirror com.unity.ugui package (Unity 6000.3.12f1) --- com.unity.ugui/Runtime/TMP/TMP_InputField.cs | 4 ++++ .../Runtime/UGUI/UI/Core/FontUpdateTracker.cs | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs index 4afdedd..7032c68 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs @@ -1764,6 +1764,10 @@ protected virtual void LateUpdate() OnSubmit(null); break; } + +#if UNITY_ANDROID || UNITY_IOS + DeactivateInputField(); +#endif } return; diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/FontUpdateTracker.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/FontUpdateTracker.cs index 8dfaea3..d50cf0f 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/FontUpdateTracker.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/FontUpdateTracker.cs @@ -45,8 +45,16 @@ private static void RebuildForFont(Font f) if (texts == null) return; - foreach (var text in texts) + // Iterate a list copy since the set can be modified within the scope of this loop + var textsCopy = new List(texts); + foreach (var text in textsCopy) + { + if (!text) + { + continue; + } text.FontTextureChanged(); + } } /// From ddb508dea64bcde61940b4c1a3c0355e640654e2 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 14 Mar 2026 07:11:54 +0000 Subject: [PATCH 20/26] Mirror com.unity.ugui package (Unity 6000.3.12f1) --- com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs b/com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs index 64a3fe1..eb6b066 100644 --- a/com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs +++ b/com.unity.ugui/Tests/Editor/TMP/FontEngineTests.cs @@ -6,6 +6,7 @@ namespace TMPro { [Category("Text Parsing & Layout")] + [Ignore("Unstable tests, see: https://jira.unity3d.com/browse/UUM-133195")] internal class FontEngineTests { [OneTimeSetUp] From 4ac1376e66b8f3870b8b75d29495748849637eb0 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 25 Apr 2026 05:59:42 +0000 Subject: [PATCH 21/26] Mirror com.unity.ugui package (Unity 6000.3.15f1) --- com.unity.ugui/Runtime/TMP/TMP_InputField.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs index 7032c68..b6865cd 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs @@ -1811,6 +1811,9 @@ protected virtual void LateUpdate() return; } + if (!m_AllowInput) + return; + // In the case of a Custom Validator, the user is expected to modify the m_Text where as such we do not append c. // However we will append c if the user did not modify the m_Text (UUM-42147) if (c != 0 && (characterValidation != CharacterValidation.CustomValidator || !hasValidateUpdatedText)) From 98b6d4980eba9dbb9aade9a5d753111d3c3c1a18 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 2 May 2026 05:57:53 +0000 Subject: [PATCH 22/26] Mirror com.unity.ugui package (Unity 6000.3.16f1) --- com.unity.ugui/Runtime/TMP/TMP_InputField.cs | 10 ++++++++++ com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs index b6865cd..e88ee2b 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs @@ -4466,6 +4466,16 @@ public void DeactivateInputField(bool clearSelection = false) public override void OnDeselect(BaseEventData eventData) { + // Commit any pending IME composition string before deactivating. + // When focus is changed programmatically, OnUpdateSelected is not called, + // so the composition is never processed. DeactivateInputField resets the + // IME mode and discards the composition, causing the last composed character + // (e.g., the final Hangul syllable) to be lost. + if (compositionLength > 0) + { + Append(compositionString); + } + DeactivateInputField(); base.OnDeselect(eventData); diff --git a/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs b/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs index b303d8d..fb9f046 100644 --- a/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs +++ b/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs @@ -3277,6 +3277,11 @@ public void DeactivateInputField() /// The data sent by the EventSystem public override void OnDeselect(BaseEventData eventData) { + if (compositionString.Length > 0) + { + Append(compositionString); + } + DeactivateInputField(); base.OnDeselect(eventData); } From 15e8132ca52e5a936fff0638ad49f28715b03d79 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 16 May 2026 06:00:11 +0000 Subject: [PATCH 23/26] Mirror com.unity.ugui package (Unity 6000.3.17f1) --- .../Documentation~/TextMeshPro/TMPObjects.md | 4 +++ com.unity.ugui/Documentation~/UICanvas.md | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/com.unity.ugui/Documentation~/TextMeshPro/TMPObjects.md b/com.unity.ugui/Documentation~/TextMeshPro/TMPObjects.md index 3cfcaa1..e9ce683 100644 --- a/com.unity.ugui/Documentation~/TextMeshPro/TMPObjects.md +++ b/com.unity.ugui/Documentation~/TextMeshPro/TMPObjects.md @@ -17,6 +17,10 @@ TextMesh Pro UI text objects use [Unity's UI system](https://docs.unity3d.com/Ma 1. In the **TextMesh Pro (UGUI)** Inspector, enter your text. 1. Adjust the [UI text properties](TMPObjectUIText.md) as needed. +**Additional Shader Channels** + +**TextMesh Pro (UGUI)** automatically enables **TexCoord1**, **Normal**, and **Tangent** in the **[Additional Shader Channels](../UICanvas.md#additional-shader-channels)** of its parent [Canvas](../UICanvas.md). This is required by TMP’s shaders and occurs during text mesh generation. If you inspect the Canvas and notice these channels are set, this is expected behavior. Be aware that any custom UI shaders on the same Canvas will also receive these additional vertex attributes. + ### Other TextMesh Pro UI GameObjects In addition to the UI text GameObject, you can create TextMesh Pro **Dropdown** and **Input Field** components from the **GameObject > UI** menu. diff --git a/com.unity.ugui/Documentation~/UICanvas.md b/com.unity.ugui/Documentation~/UICanvas.md index 95b9054..ef1e3fd 100644 --- a/com.unity.ugui/Documentation~/UICanvas.md +++ b/com.unity.ugui/Documentation~/UICanvas.md @@ -32,3 +32,39 @@ This is similar to **Screen Space - Overlay**, but in this render mode the Canva In this render mode, the Canvas will behave as any other object in the scene. The size of the Canvas can be set manually using its Rect Transform, and UI elements will render in front of or behind other objects in the scene based on 3D placement. This is useful for UIs that are meant to be a part of the world. This is also known as a "diegetic interface". ![UI in world space canvas](images/GUI_Canvas_Worldspace.png) + +## Additional shader channels + +When the Canvas generates mesh geometry for rendering, it always includes **Position**, **Color**, and **UV0** vertex attributes. For **Screen Space - Camera** and **World Space** render modes, **Normal** and **Tangent** are also included by default to support lighting. + +The **Additional Shader Channels** property lets you include extra vertex attributes beyond these defaults. This is useful when your UI shaders sample additional UV sets, or when you need per-vertex normal and tangent data in overlay canvases. + +The available channels are: + +| Channel | Description | +|---------|-------------| +| **None** | No additional attributes. Only the defaults are included. | +| **TexCoord1** | Adds a second UV set (UV1) to each vertex. | +| **TexCoord2** | Adds a third UV set (UV2) to each vertex. | +| **TexCoord3** | Adds a fourth UV set (UV3) to each vertex. | +| **Normal** | Adds a per-vertex normal (Vector3). Required for lighting effects on UI geometry.| +| **Tangent** | Adds a per-vertex tangent (Vector4). Required for normal-mapped shaders.| + +> [!NOTE] +> **Screen Space - Overlay** canvases are not affected by standard scene lighting, so **Normal** and **Tangent** have no visible effect in typical cases. However, specialized shaders, such as those used by TextMeshPro, can still use this data. + +### Reflection probes + +When **Use Reflection Probes** is enabled on the Canvas, the **Normal** channel is automatically included in the mesh regardless of the Additional Shader Channels setting. + +## Vertex color always in gamma color space + +In a linear color space project, Unity normally converts UI vertex colors from gamma to linear space during mesh generation, before the colors reach the shader. This conversion loses detail, particularly for darker colors, where gamma encoding provides the most precision. + +**Vertex Color Always in Gamma Color Space** defers that conversion to the shader instead. When enabled, vertex colors are written to the mesh in gamma space and the UI shader performs the gamma-to-linear conversion in floating-point, preserving more precision throughout. This improves the accuracy of dark-color tones and subtle gradients in linear color space workflows. + +The precision gain is only relevant when the project's color space is set to **Linear** in ***Project Settings** > **Player**. In gamma color space projects, the setting has no effect. + +### Custom UI shader + +Built-in UI shaders already include the gamma-to-linear conversion that this feature relies on. If you use a custom UI shader, you must handle this conversion manually when the setting is enabled. Otherwise, vertex colors can appear too bright. From 69ef7f0da92df43b3663e83122188ecf49898ceb Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 23 May 2026 06:01:13 +0000 Subject: [PATCH 24/26] Mirror com.unity.ugui package (Unity 6000.3.17f1) --- .../Editor/UGUI/UnityEditor.UI.asmdef | 54 +++++++++---------- com.unity.ugui/Runtime/TMP/TMP_InputField.cs | 6 +-- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/com.unity.ugui/Editor/UGUI/UnityEditor.UI.asmdef b/com.unity.ugui/Editor/UGUI/UnityEditor.UI.asmdef index 982ca23..1c34715 100644 --- a/com.unity.ugui/Editor/UGUI/UnityEditor.UI.asmdef +++ b/com.unity.ugui/Editor/UGUI/UnityEditor.UI.asmdef @@ -1,28 +1,28 @@ -{ - "name": "UnityEditor.UI", - - "references": [ - "UnityEngine.UI" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "versionDefines": [ - { - "name": "com.unity.modules.physics", - "expression": "1.0.0", - "define": "PACKAGE_PHYSICS" - }, - { - "name": "com.unity.modules.physics2d", - "expression": "1.0.0", - "define": "PACKAGE_PHYSICS2D" - }, - { - "name": "com.unity.modules.animation", - "expression": "1.0.0", - "define": "PACKAGE_ANIMATION" - } - ] +{ + "name": "UnityEditor.UI", + + "references": [ + "UnityEngine.UI" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "versionDefines": [ + { + "name": "com.unity.modules.physics", + "expression": "1.0.0", + "define": "PACKAGE_PHYSICS" + }, + { + "name": "com.unity.modules.physics2d", + "expression": "1.0.0", + "define": "PACKAGE_PHYSICS2D" + }, + { + "name": "com.unity.modules.animation", + "expression": "1.0.0", + "define": "PACKAGE_ANIMATION" + } + ] } \ No newline at end of file diff --git a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs index e88ee2b..e78ac11 100644 --- a/com.unity.ugui/Runtime/TMP/TMP_InputField.cs +++ b/com.unity.ugui/Runtime/TMP/TMP_InputField.cs @@ -2533,7 +2533,7 @@ private void MoveRight(bool shift, bool ctrl) } else { - // Special handling for + // Special handling for \r\n: if we are on the \r character, we want to move to the end of the \r\n pair, not just after the \r character. if (m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal].character == '\r' && m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal + 1].character == '\n') position = m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal + 1].index + m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal + 1].stringLength; else @@ -2610,8 +2610,8 @@ private void MoveLeft(bool shift, bool ctrl) ? m_TextComponent.textInfo.characterInfo[0].index : m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal - 1].index; - // Special handling for - if (position > 0 && m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal - 1].character == '\n' && m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal - 2].character == '\r') + // Special handling for \r\n: if we are on the \n character, we want to move to the start of the \r\n pair, not just before the \n character. + if (position > 0 && caretSelectPositionInternal > 1 && m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal - 1].character == '\n' && m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal - 2].character == '\r') position = m_TextComponent.textInfo.characterInfo[caretSelectPositionInternal - 2].index; } } From 1b357307893c60897b0688f835dc0cd2f5794ab0 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 30 May 2026 06:01:12 +0000 Subject: [PATCH 25/26] Mirror com.unity.ugui package (Unity 6000.3.18f1) --- .../Editor/TMP/HDRP/TMP_BaseHDRPLitShaderGUI.cs | 3 ++- .../Editor/TMP/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs | 9 +++++---- com.unity.ugui/Editor/TMP/TMP_BaseShaderGUI.cs | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/com.unity.ugui/Editor/TMP/HDRP/TMP_BaseHDRPLitShaderGUI.cs b/com.unity.ugui/Editor/TMP/HDRP/TMP_BaseHDRPLitShaderGUI.cs index b4e8e08..fe2a54d 100644 --- a/com.unity.ugui/Editor/TMP/HDRP/TMP_BaseHDRPLitShaderGUI.cs +++ b/com.unity.ugui/Editor/TMP/HDRP/TMP_BaseHDRPLitShaderGUI.cs @@ -435,7 +435,8 @@ protected void DoColor(string name, string label) { MaterialProperty property = BeginProperty(name); s_TempLabel.text = label; - Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, true); + bool isHDR = ((property.propertyFlags & UnityEngine.Rendering.ShaderPropertyFlags.HDR) != 0); + Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, isHDR); if (EndProperty()) { property.colorValue = value; diff --git a/com.unity.ugui/Editor/TMP/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs b/com.unity.ugui/Editor/TMP/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs index f165824..cb14c9f 100644 --- a/com.unity.ugui/Editor/TMP/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs +++ b/com.unity.ugui/Editor/TMP/HDRP/TMP_BaseHDRPUnlitShaderGUI.cs @@ -7,11 +7,11 @@ namespace TMPro.EditorUtilities { /// Base class for TextMesh Pro shader GUIs. - #if HDRP_11_OR_NEWER +#if HDRP_11_OR_NEWER internal abstract class TMP_BaseHDRPUnlitShaderGUI : UnlitShaderGraphGUI - #else +#else internal abstract class TMP_BaseHDRPUnlitShaderGUI : HDUnlitGUI - #endif +#endif { /// Representation of a #pragma shader_feature. /// It is assumed that the first feature option is for no keyword (underscores). @@ -439,7 +439,8 @@ protected void DoColor(string name, string label) { MaterialProperty property = BeginProperty(name); s_TempLabel.text = label; - Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, true); + bool isHDR = ((property.propertyFlags & UnityEngine.Rendering.ShaderPropertyFlags.HDR) != 0); + Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, isHDR); if (EndProperty()) { property.colorValue = value; diff --git a/com.unity.ugui/Editor/TMP/TMP_BaseShaderGUI.cs b/com.unity.ugui/Editor/TMP/TMP_BaseShaderGUI.cs index bc0db5d..fb3b5f1 100644 --- a/com.unity.ugui/Editor/TMP/TMP_BaseShaderGUI.cs +++ b/com.unity.ugui/Editor/TMP/TMP_BaseShaderGUI.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEditor; +using UnityEngine.Rendering; namespace TMPro.EditorUtilities { @@ -438,7 +439,8 @@ protected void DoColor(string name, string label) { MaterialProperty property = BeginProperty(name); s_TempLabel.text = label; - Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, true); + bool isHDR = ((property.propertyFlags & ShaderPropertyFlags.HDR) != 0); + Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, isHDR); if (EndProperty()) { property.colorValue = value; From dd21e59c094d9ee93935a21d3258f3fa92253442 Mon Sep 17 00:00:00 2001 From: Unity CI Bot Date: Sat, 6 Jun 2026 05:57:50 +0000 Subject: [PATCH 26/26] Mirror com.unity.ugui package (Unity 6000.3.18f1) --- com.unity.ugui/Editor/UGUI/UI/RawImageEditor.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/com.unity.ugui/Editor/UGUI/UI/RawImageEditor.cs b/com.unity.ugui/Editor/UGUI/UI/RawImageEditor.cs index e5ba9f0..8b44952 100644 --- a/com.unity.ugui/Editor/UGUI/UI/RawImageEditor.cs +++ b/com.unity.ugui/Editor/UGUI/UI/RawImageEditor.cs @@ -75,6 +75,17 @@ public override bool HasPreviewGUI() return outer.width > 0 && outer.height > 0; } + /// + /// Repaint this element constantly if it's a RenderTexture. + /// + /// True if the rawImage is not null and is RenderTexture; otherwise, false. + + public override bool RequiresConstantRepaint() + { + RawImage rawImage = target as RawImage; + return rawImage != null && rawImage.mainTexture is RenderTexture; + } + /// /// Draw the Image preview. ///