Chocolade19721309

Untitled

May 15th, 2024
18
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 448.23 KB | None | 0 0
  1. [
  2. {
  3. "Name": "Main Camera",
  4. "Components": [
  5. {
  6. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  7. "Local Position": "(0.00, 1.00, -10.00)",
  8. "Local Scale": "(1.00, 1.00, 1.00)",
  9. "Constrain Proportions Scale": "False"
  10. },
  11. {
  12. "Clear Flags": "Skybox",
  13. "Back Ground Color": "RGBA(1.000, 1.000, 1.000, 0.000)",
  14. "Projection Matrix Mode": "1",
  15. "Gate Fit Mode": "2",
  16. "FOV Axis Mode": "0",
  17. "Iso": "200",
  18. "Shutter Speed": "0.005",
  19. "Aperture": "16",
  20. "Focus Distance": "10",
  21. "Focal Length": "50",
  22. "Blade Count": "5",
  23. "Curvature": "(2.00, 11.00)",
  24. "Barrel Clipping": "0.25",
  25. "Anamorphism": "0",
  26. "Sensor Size": "(36.00, 24.00)",
  27. "Lens Shift": "(0.00, 0.00)",
  28. "Normalized View Port Rect": "(x:0.00, y:0.00, width:1.00, height:1.00)",
  29. "Near clip plane": "0.3",
  30. "Far clip plane": "1000",
  31. "Field of view": "60",
  32. "Orthographic": "False",
  33. "Orthographic size": "5",
  34. "Depth": "-1",
  35. "Culling Mask": "Invalid layer",
  36. "Rendering Path": "Use Graphics Settings",
  37. "Target Texture": "None",
  38. "Target Display": "0",
  39. "Target Eye": "3",
  40. "HDR": "True",
  41. "Allow MSAA": "True",
  42. "Allow Dynamic Resolution": "False",
  43. "Force Into RT": "False",
  44. "Occlusion Culling": "True",
  45. "Stereo Convergence": "10",
  46. "Stereo Separation": "0.022"
  47. }
  48. ],
  49. "Children": []
  50. },
  51. {
  52. "Name": "Directional Light",
  53. "Components": [
  54. {
  55. "Local Rotation": "(0.40822, -0.23457, 0.10938, 0.87543)",
  56. "Local Position": "(0.00, 3.00, 0.00)",
  57. "Local Scale": "(1.00, 1.00, 1.00)",
  58. "Constrain Proportions Scale": "False"
  59. },
  60. {
  61. "Type": "Directional",
  62. "Shape": "Cone",
  63. "Color": "RGBA(1.000, 0.957, 0.839, 1.000)",
  64. "Intensity": "1",
  65. "Range": "10",
  66. "Spot Angle": "30",
  67. "Inner Spot Angle": "21.80208",
  68. "Cookie Size": "10",
  69. "Shadows": "<Unsupported Type>",
  70. "Cookie": "None",
  71. "Draw Halo": "False",
  72. "Baking Output": "<Unsupported Type>",
  73. "Flare": "None",
  74. "Render Mode": "Auto",
  75. "Culling Mask": "Invalid layer",
  76. "Rendering Layer Mask": "1",
  77. "Lightmapping": "Mixed",
  78. "Light Shadow Caster Mode": "0",
  79. "Area Size": "(1.00, 1.00)",
  80. "Bounce Intensity": "1",
  81. "Color Temperature": "6570",
  82. "Use Color Temperature": "False",
  83. "Bounding Sphere Override": "(0.00, 0.00, 0.00, 0.00)",
  84. "Use Bounding Sphere Override": "False",
  85. "Use View Frustum For Shadow Caster Cull": "True",
  86. "Shadow Radius": "0",
  87. "Shadow Angle": "0"
  88. }
  89. ],
  90. "Children": []
  91. },
  92. {
  93. "Name": "Canvas",
  94. "Components": [
  95. {
  96. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  97. "Local Position": "(453.00, 209.50, 0.00)",
  98. "Local Scale": "(0.47, 0.47, 0.47)",
  99. "Constrain Proportions Scale": "False",
  100. "Anchor Min": "(0.00, 0.00)",
  101. "Anchor Max": "(0.00, 0.00)",
  102. "Anchored Position": "(453.00, 209.50)",
  103. "Size Delta": "(1920.00, 887.95)",
  104. "Pivot": "(0.50, 0.50)"
  105. },
  106. {
  107. "Render Mode": "Screen Space - Overlay",
  108. "Camera": "None",
  109. "Plane Distance": "100",
  110. "Pixel Perfect": "False",
  111. "Receives Events": "True",
  112. "Override Sorting": "False",
  113. "Override Pixel Perfect": "False",
  114. "Sorting Bucket Normalized Size": "0",
  115. "Vertex Color Always Gamma Space": "True",
  116. "Additional Shader Channels Flag": "Error: Index was outside the bounds of the array.",
  117. "Update Rect Transform For Standalone": "Enabled"
  118. },
  119. {
  120. "Name": "CanvasScaler",
  121. "Content": "using System;\nusing UnityEngine.Events;\nusing UnityEngine.EventSystems;\n\nnamespace UnityEngine.UI\n{\n [RequireComponent(typeof(Canvas))]\n [ExecuteAlways]\n [AddComponentMenu(\"Layout/Canvas Scaler\", 101)]\n [DisallowMultipleComponent]\n /// <summary>\n /// The Canvas Scaler component is used for controlling the overall scale and pixel density of UI elements in the Canvas. This scaling affects everything under the Canvas, including font sizes and image borders.\n /// </summary>\n /// <remarks>\n /// For a Canvas set to 'Screen Space - Overlay' or 'Screen Space - Camera', the Canvas Scaler UI Scale Mode can be set to Constant Pixel Size, Scale With Screen Size, or Constant Physical Size.\n ///\n /// Using the Constant Pixel Size mode, positions and sizes of UI elements are specified in pixels on the screen. This is also the default functionality of the Canvas when no Canvas Scaler is attached. However, With the Scale Factor setting in the Canvas Scaler, a constant scaling can be applied to all UI elements in the Canvas.\n ///\n /// Using the Scale With Screen Size mode, positions and sizes can be specified according to the pixels of a specified reference resolution. If the current screen resolution is larger than the reference resolution, the Canvas will keep having only the resolution of the reference resolution, but will scale up in order to fit the screen. If the current screen resolution is smaller than the reference resolution, the Canvas will similarly be scaled down to fit. If the current screen resolution has a different aspect ratio than the reference resolution, scaling each axis individually to fit the screen would result in non-uniform scaling, which is generally undesirable. Instead of this, the ReferenceResolution component will make the Canvas resolution deviate from the reference resolution in order to respect the aspect ratio of the screen. It is possible to control how this deviation should behave using the ::ref::screenMatchMode setting.\n ///\n /// Using the Constant Physical Size mode, positions and sizes of UI elements are specified in physical units, such as millimeters, points, or picas. This mode relies on the device reporting its screen DPI correctly. You can specify a fallback DPI to use for devices that do not report a DPI.\n ///\n /// For a Canvas set to 'World Space' the Canvas Scaler can be used to control the pixel density of UI elements in the Canvas.\n /// </remarks>\n public class CanvasScaler : UIBehaviour\n {\n /// <summary>\n /// Determines how UI elements in the Canvas are scaled.\n /// </summary>\n public enum ScaleMode\n {\n /// <summary>\n /// Using the Constant Pixel Size mode, positions and sizes of UI elements are specified in pixels on the screen.\n /// </summary>\n ConstantPixelSize,\n /// <summary>\n /// Using the Scale With Screen Size mode, positions and sizes can be specified according to the pixels of a specified reference resolution.\n /// If the current screen resolution is larger than the reference resolution, the Canvas will keep having only the resolution of the reference resolution, but will scale up in order to fit the screen. If the current screen resolution is smaller than the reference resolution, the Canvas will similarly be scaled down to fit.\n /// </summary>\n ScaleWithScreenSize,\n /// <summary>\n /// Using the Constant Physical Size mode, positions and sizes of UI elements are specified in physical units, such as millimeters, points, or picas.\n /// </summary>\n ConstantPhysicalSize\n }\n\n [Tooltip(\"Determines how UI elements in the Canvas are scaled.\")]\n [SerializeField] private ScaleMode m_UiScaleMode = ScaleMode.ConstantPixelSize;\n\n ///<summary>\n ///Determines how UI elements in the Canvas are scaled.\n ///</summary>\n public ScaleMode uiScaleMode { get { return m_UiScaleMode; } set { m_UiScaleMode = value; } }\n\n [Tooltip(\"If a sprite has this 'Pixels Per Unit' setting, then one pixel in the sprite will cover one unit in the UI.\")]\n [SerializeField] protected float m_ReferencePixelsPerUnit = 100;\n\n /// <summary>\n /// If a sprite has this 'Pixels Per Unit' setting, then one pixel in the sprite will cover one unit in the UI.\n /// </summary>\n public float referencePixelsPerUnit { get { return m_ReferencePixelsPerUnit; } set { m_ReferencePixelsPerUnit = value; } }\n\n\n // Constant Pixel Size settings\n\n [Tooltip(\"Scales all UI elements in the Canvas by this factor.\")]\n [SerializeField] protected float m_ScaleFactor = 1;\n\n /// <summary>\n /// Scales all UI elements in the Canvas by this factor.\n /// </summary>\n\n /// <summary>\n /// Scales all UI elements in the Canvas by this factor.\n /// </summary>\n public float scaleFactor { get { return m_ScaleFactor; } set { m_ScaleFactor = Mathf.Max(0.01f, value); } }\n\n /// Scale the canvas area with the width as reference, the height as reference, or something in between.\n /// <summary>\n /// Scale the canvas area with the width as reference, the height as reference, or something in between.\n /// </summary>\n public enum ScreenMatchMode\n {\n /// <summary>\n /// Scale the canvas area with the width as reference, the height as reference, or something in between.\n /// </summary>\n MatchWidthOrHeight = 0,\n /// <summary>\n /// Expand the canvas area either horizontally or vertically, so the size of the canvas will never be smaller than the reference.\n /// </summary>\n Expand = 1,\n /// <summary>\n /// Crop the canvas area either horizontally or vertically, so the size of the canvas will never be larger than the reference.\n /// </summary>\n Shrink = 2\n }\n\n [Tooltip(\"The resolution the UI layout is designed for. If the screen resolution is larger, the UI will be scaled up, and if it's smaller, the UI will be scaled down. This is done in accordance with the Screen Match Mode.\")]\n [SerializeField] protected Vector2 m_ReferenceResolution = new Vector2(800, 600);\n\n /// <summary>\n /// The resolution the UI layout is designed for.\n /// </summary>\n /// <remarks>\n /// If the screen resolution is larger, the UI will be scaled up, and if it's smaller, the UI will be scaled down. This is done in accordance with the Screen Match Mode.\n /// </remarks>\n public Vector2 referenceResolution\n {\n get\n {\n return m_ReferenceResolution;\n }\n set\n {\n m_ReferenceResolution = value;\n\n const float k_MinimumResolution = 0.00001f;\n\n if (m_ReferenceResolution.x > -k_MinimumResolution && m_ReferenceResolution.x < k_MinimumResolution) m_ReferenceResolution.x = k_MinimumResolution * Mathf.Sign(m_ReferenceResolution.x);\n if (m_ReferenceResolution.y > -k_MinimumResolution && m_ReferenceResolution.y < k_MinimumResolution) m_ReferenceResolution.y = k_MinimumResolution * Mathf.Sign(m_ReferenceResolution.y);\n }\n }\n\n [Tooltip(\"A mode used to scale the canvas area if the aspect ratio of the current resolution doesn't fit the reference resolution.\")]\n [SerializeField] protected ScreenMatchMode m_ScreenMatchMode = ScreenMatchMode.MatchWidthOrHeight;\n /// <summary>\n /// A mode used to scale the canvas area if the aspect ratio of the current resolution doesn't fit the reference resolution.\n /// </summary>\n public ScreenMatchMode screenMatchMode { get { return m_ScreenMatchMode; } set { m_ScreenMatchMode = value; } }\n\n [Tooltip(\"Determines if the scaling is using the width or height as reference, or a mix in between.\")]\n [Range(0, 1)]\n [SerializeField] protected float m_MatchWidthOrHeight = 0;\n\n /// <summary>\n /// Setting to scale the Canvas to match the width or height of the reference resolution, or a combination.\n /// </summary>\n /// <remarks>\n /// If the setting is set to 0, the Canvas is scaled according to the difference between the current screen resolution width and the reference resolution width. If the setting is set to 1, the Canvas is scaled according to the difference between the current screen resolution height and the reference resolution height.\n ///\n /// For values in between 0 and 1, the scaling is based on a combination of the relative width and height.\n ///\n /// Consider an example where the reference resolution of 640x480, and the current screen resolution is a landscape mode of 480x640.\n ///\n /// If the scaleWidthOrHeight setting is set to 0, the Canvas is scaled by 0.75 because the current resolution width of 480 is 0.75 times the reference resolution width of 640. The Canvas resolution gets a resolution of 640x853.33. This resolution has the same width as the reference resolution width, but has the aspect ratio of the current screen resolution. Note that the Canvas resolution of 640x853.33 is the current screen resolution divided by the scale factor of 0.75.\n ///\n /// If the scaleWidthOrHeight setting is set to 1, the Canvas is scaled by 1.33 because the current resolution height of 640 is 1.33 times the reference resolution height of 480. The Canvas resolution gets a resolution of 360x480. This resolution has the same height as the reference resolution width, but has the aspect ratio of the current screen resolution. Note that the Canvas resolution of 360x480 is the current screen resolution divided by the scale factor of 1.33.\n ///\n /// If the scaleWidthOrHeight setting is set to 0.5, we find the horizontal scaling needed (0.75) and the vertical scaling needed (1.33) and find the average. However, we do the average in logarithmic space. A regular average of 0.75 and 1.33 would produce a result of 1.04. However, since multiplying by 1.33 is the same as diving by 0.75, the two scale factor really corresponds to multiplying by 0.75 versus dividing by 0.75, and the average of those two things should even out and produce a neutral result. The average in logarithmic space of 0.75 and 1.33 is exactly 1.0, which is what we want. The Canvas resolution hence ends up being 480x640 which is the current resolution divided by the scale factor of 1.0.\n ///\n /// The logic works the same for all values. The average between the horizontal and vertical scale factor is a weighted average based on the matchWidthOrHeight value.\n /// </remarks>\n public float matchWidthOrHeight { get { return m_MatchWidthOrHeight; } set { m_MatchWidthOrHeight = value; } }\n\n // The log base doesn't have any influence on the results whatsoever, as long as the same base is used everywhere.\n private const float kLogBase = 2;\n\n /// <summary>\n /// The possible physical unit types\n /// </summary>\n public enum Unit\n {\n /// <summary>\n /// Use centimeters.\n /// A centimeter is 1/100 of a meter\n /// </summary>\n Centimeters,\n /// <summary>\n /// Use millimeters.\n /// A millimeter is 1/10 of a centimeter, and 1/1000 of a meter.\n /// </summary>\n Millimeters,\n /// <summary>\n /// Use inches.\n /// </summary>\n Inches,\n /// <summary>\n /// Use points.\n /// One point is 1/12 of a pica, and 1/72 of an inch.\n /// </summary>\n Points,\n /// <summary>\n /// Use picas.\n /// One pica is 1/6 of an inch.\n /// </summary>\n Picas\n }\n\n [Tooltip(\"The physical unit to specify positions and sizes in.\")]\n [SerializeField] protected Unit m_PhysicalUnit = Unit.Points;\n\n /// <summary>\n /// The physical unit to specify positions and sizes in.\n /// </summary>\n public Unit physicalUnit { get { return m_PhysicalUnit; } set { m_PhysicalUnit = value; } }\n\n [Tooltip(\"The DPI to assume if the screen DPI is not known.\")]\n [SerializeField] protected float m_FallbackScreenDPI = 96;\n\n /// <summary>\n /// The DPI to assume if the screen DPI is not known.\n /// </summary>\n public float fallbackScreenDPI { get { return m_FallbackScreenDPI; } set { m_FallbackScreenDPI = value; } }\n\n [Tooltip(\"The pixels per inch to use for sprites that have a 'Pixels Per Unit' setting that matches the 'Reference Pixels Per Unit' setting.\")]\n [SerializeField] protected float m_DefaultSpriteDPI = 96;\n\n /// <summary>\n /// The pixels per inch to use for sprites that have a 'Pixels Per Unit' setting that matches the 'Reference Pixels Per Unit' setting.\n /// </summary>\n public float defaultSpriteDPI { get { return m_DefaultSpriteDPI; } set { m_DefaultSpriteDPI = Mathf.Max(1, value); } }\n\n\n // World Canvas settings\n\n [Tooltip(\"The amount of pixels per unit to use for dynamically created bitmaps in the UI, such as Text.\")]\n [SerializeField] protected float m_DynamicPixelsPerUnit = 1;\n\n /// <summary>\n /// The amount of pixels per unit to use for dynamically created bitmaps in the UI, such as Text.\n /// </summary>\n public float dynamicPixelsPerUnit { get { return m_DynamicPixelsPerUnit; } set { m_DynamicPixelsPerUnit = value; } }\n\n\n // General variables\n\n private Canvas m_Canvas;\n [System.NonSerialized]\n private float m_PrevScaleFactor = 1;\n [System.NonSerialized]\n private float m_PrevReferencePixelsPerUnit = 100;\n\n [SerializeField] protected bool m_PresetInfoIsWorld = false;\n\n protected CanvasScaler() {}\n\n protected override void OnEnable()\n {\n base.OnEnable();\n m_Canvas = GetComponent<Canvas>();\n Handle();\n Canvas.preWillRenderCanvases += Canvas_preWillRenderCanvases;\n }\n\n private void Canvas_preWillRenderCanvases()\n {\n Handle();\n }\n\n protected override void OnDisable()\n {\n SetScaleFactor(1);\n SetReferencePixelsPerUnit(100);\n Canvas.preWillRenderCanvases -= Canvas_preWillRenderCanvases;\n base.OnDisable();\n }\n\n ///<summary>\n ///Method that handles calculations of canvas scaling.\n ///</summary>\n protected virtual void Handle()\n {\n if (m_Canvas == null || !m_Canvas.isRootCanvas)\n return;\n\n if (m_Canvas.renderMode == RenderMode.WorldSpace)\n {\n HandleWorldCanvas();\n return;\n }\n\n switch (m_UiScaleMode)\n {\n case ScaleMode.ConstantPixelSize: HandleConstantPixelSize(); break;\n case ScaleMode.ScaleWithScreenSize: HandleScaleWithScreenSize(); break;\n case ScaleMode.ConstantPhysicalSize: HandleConstantPhysicalSize(); break;\n }\n }\n\n /// <summary>\n /// Handles canvas scaling for world canvas.\n /// </summary>\n protected virtual void HandleWorldCanvas()\n {\n SetScaleFactor(m_DynamicPixelsPerUnit);\n SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit);\n }\n\n /// <summary>\n /// Handles canvas scaling for a constant pixel size.\n /// </summary>\n protected virtual void HandleConstantPixelSize()\n {\n SetScaleFactor(m_ScaleFactor);\n SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit);\n }\n\n /// <summary>\n /// Handles canvas scaling that scales with the screen size.\n /// </summary>\n protected virtual void HandleScaleWithScreenSize()\n {\n Vector2 screenSize = m_Canvas.renderingDisplaySize;\n\n // Multiple display support only when not the main display. For display 0 the reported\n // resolution is always the desktops resolution since its part of the display API,\n // so we use the standard none multiple display method. (case 741751)\n int displayIndex = m_Canvas.targetDisplay;\n if (displayIndex > 0 && displayIndex < Display.displays.Length)\n {\n Display disp = Display.displays[displayIndex];\n screenSize = new Vector2(disp.renderingWidth, disp.renderingHeight);\n }\n\n\n float scaleFactor = 0;\n switch (m_ScreenMatchMode)\n {\n case ScreenMatchMode.MatchWidthOrHeight:\n {\n // We take the log of the relative width and height before taking the average.\n // Then we transform it back in the original space.\n // the reason to transform in and out of logarithmic space is to have better behavior.\n // If one axis has twice resolution and the other has half, it should even out if widthOrHeight value is at 0.5.\n // In normal space the average would be (0.5 + 2) / 2 = 1.25\n // In logarithmic space the average is (-1 + 1) / 2 = 0\n float logWidth = Mathf.Log(screenSize.x / m_ReferenceResolution.x, kLogBase);\n float logHeight = Mathf.Log(screenSize.y / m_ReferenceResolution.y, kLogBase);\n float logWeightedAverage = Mathf.Lerp(logWidth, logHeight, m_MatchWidthOrHeight);\n scaleFactor = Mathf.Pow(kLogBase, logWeightedAverage);\n break;\n }\n case ScreenMatchMode.Expand:\n {\n scaleFactor = Mathf.Min(screenSize.x / m_ReferenceResolution.x, screenSize.y / m_ReferenceResolution.y);\n break;\n }\n case ScreenMatchMode.Shrink:\n {\n scaleFactor = Mathf.Max(screenSize.x / m_ReferenceResolution.x, screenSize.y / m_ReferenceResolution.y);\n break;\n }\n }\n\n SetScaleFactor(scaleFactor);\n SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit);\n }\n\n ///<summary>\n ///Handles canvas scaling for a constant physical size.\n ///</summary>\n protected virtual void HandleConstantPhysicalSize()\n {\n float currentDpi = Screen.dpi;\n float dpi = (currentDpi == 0 ? m_FallbackScreenDPI : currentDpi);\n float targetDPI = 1;\n switch (m_PhysicalUnit)\n {\n case Unit.Centimeters: targetDPI = 2.54f; break;\n case Unit.Millimeters: targetDPI = 25.4f; break;\n case Unit.Inches: targetDPI = 1; break;\n case Unit.Points: targetDPI = 72; break;\n case Unit.Picas: targetDPI = 6; break;\n }\n\n SetScaleFactor(dpi / targetDPI);\n SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit * targetDPI / m_DefaultSpriteDPI);\n }\n\n /// <summary>\n /// Sets the scale factor on the canvas.\n /// </summary>\n /// <param name=\"scaleFactor\">The scale factor to use.</param>\n protected void SetScaleFactor(float scaleFactor)\n {\n if (scaleFactor == m_PrevScaleFactor)\n return;\n\n m_Canvas.scaleFactor = scaleFactor;\n m_PrevScaleFactor = scaleFactor;\n }\n\n /// <summary>\n /// Sets the referencePixelsPerUnit on the Canvas.\n /// </summary>\n /// <param name=\"referencePixelsPerUnit\">The new reference pixels per Unity value</param>\n protected void SetReferencePixelsPerUnit(float referencePixelsPerUnit)\n {\n if (referencePixelsPerUnit == m_PrevReferencePixelsPerUnit)\n return;\n\n m_Canvas.referencePixelsPerUnit = referencePixelsPerUnit;\n m_PrevReferencePixelsPerUnit = referencePixelsPerUnit;\n }\n\n#if UNITY_EDITOR\n protected override void OnValidate()\n {\n m_ScaleFactor = Mathf.Max(0.01f, m_ScaleFactor);\n m_DefaultSpriteDPI = Mathf.Max(1, m_DefaultSpriteDPI);\n }\n\n#endif\n }\n}\n"
  122. },
  123. {
  124. "Script": "CanvasScaler",
  125. "Ui Scale Mode": "ScaleWithScreenSize",
  126. "Reference Pixels Per Unit": "100",
  127. "Scale Factor": "1",
  128. "Reference Resolution": "(1920.00, 1080.00)",
  129. "Screen Match Mode": "MatchWidthOrHeight",
  130. "Match Width Or Height": "0",
  131. "Physical Unit": "Points",
  132. "Fallback Screen DPI": "96",
  133. "Default Sprite DPI": "96",
  134. "Dynamic Pixels Per Unit": "1",
  135. "Preset Info Is World": "False"
  136. },
  137. {
  138. "Name": "GraphicRaycaster",
  139. "Content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing UnityEngine.EventSystems;\nusing UnityEngine.Serialization;\n\nnamespace UnityEngine.UI\n{\n [AddComponentMenu(\"Event/Graphic Raycaster\")]\n [RequireComponent(typeof(Canvas))]\n /// <summary>\n /// A derived BaseRaycaster to raycast against Graphic elements.\n /// </summary>\n public class GraphicRaycaster : BaseRaycaster\n {\n protected const int kNoEventMaskSet = -1;\n\n /// <summary>\n /// Type of raycasters to check against to check for canvas blocking elements.\n /// </summary>\n public enum BlockingObjects\n {\n /// <summary>\n /// Perform no raycasts.\n /// </summary>\n None = 0,\n /// <summary>\n /// Perform a 2D raycast check to check for blocking 2D elements\n /// </summary>\n TwoD = 1,\n /// <summary>\n /// Perform a 3D raycast check to check for blocking 3D elements\n /// </summary>\n ThreeD = 2,\n /// <summary>\n /// Perform a 2D and a 3D raycasts to check for blocking 2D and 3D elements.\n /// </summary>\n All = 3,\n }\n\n /// <summary>\n /// Priority of the raycaster based upon sort order.\n /// </summary>\n /// <returns>\n /// The sortOrder priority.\n /// </returns>\n public override int sortOrderPriority\n {\n get\n {\n // We need to return the sorting order here as distance will all be 0 for overlay.\n if (canvas.renderMode == RenderMode.ScreenSpaceOverlay)\n return canvas.sortingOrder;\n\n return base.sortOrderPriority;\n }\n }\n\n /// <summary>\n /// Priority of the raycaster based upon render order.\n /// </summary>\n /// <returns>\n /// The renderOrder priority.\n /// </returns>\n public override int renderOrderPriority\n {\n get\n {\n // We need to return the sorting order here as distance will all be 0 for overlay.\n if (canvas.renderMode == RenderMode.ScreenSpaceOverlay)\n return canvas.rootCanvas.renderOrder;\n\n return base.renderOrderPriority;\n }\n }\n\n [FormerlySerializedAs(\"ignoreReversedGraphics\")]\n [SerializeField]\n private bool m_IgnoreReversedGraphics = true;\n [FormerlySerializedAs(\"blockingObjects\")]\n [SerializeField]\n private BlockingObjects m_BlockingObjects = BlockingObjects.None;\n\n /// <summary>\n /// Whether Graphics facing away from the raycaster are checked for raycasts.\n /// </summary>\n public bool ignoreReversedGraphics { get {return m_IgnoreReversedGraphics; } set { m_IgnoreReversedGraphics = value; } }\n\n /// <summary>\n /// The type of objects that are checked to determine if they block graphic raycasts.\n /// </summary>\n public BlockingObjects blockingObjects { get {return m_BlockingObjects; } set { m_BlockingObjects = value; } }\n\n [SerializeField]\n protected LayerMask m_BlockingMask = kNoEventMaskSet;\n\n /// <summary>\n /// The type of objects specified through LayerMask that are checked to determine if they block graphic raycasts.\n /// </summary>\n public LayerMask blockingMask { get { return m_BlockingMask; } set { m_BlockingMask = value; } }\n\n private Canvas m_Canvas;\n\n protected GraphicRaycaster()\n {}\n\n private Canvas canvas\n {\n get\n {\n if (m_Canvas != null)\n return m_Canvas;\n\n m_Canvas = GetComponent<Canvas>();\n return m_Canvas;\n }\n }\n\n [NonSerialized] private List<Graphic> m_RaycastResults = new List<Graphic>();\n\n /// <summary>\n /// Perform the raycast against the list of graphics associated with the Canvas.\n /// </summary>\n /// <param name=\"eventData\">Current event data</param>\n /// <param name=\"resultAppendList\">List of hit objects to append new results to.</param>\n public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList)\n {\n if (canvas == null)\n return;\n\n var canvasGraphics = GraphicRegistry.GetRaycastableGraphicsForCanvas(canvas);\n if (canvasGraphics == null || canvasGraphics.Count == 0)\n return;\n\n int displayIndex;\n var currentEventCamera = eventCamera; // Property can call Camera.main, so cache the reference\n\n if (canvas.renderMode == RenderMode.ScreenSpaceOverlay || currentEventCamera == null)\n displayIndex = canvas.targetDisplay;\n else\n displayIndex = currentEventCamera.targetDisplay;\n\n Vector3 eventPosition = MultipleDisplayUtilities.GetRelativeMousePositionForRaycast(eventData);\n\n // Discard events that are not part of this display so the user does not interact with multiple displays at once.\n if ((int) eventPosition.z != displayIndex)\n return;\n\n // Convert to view space\n Vector2 pos;\n if (currentEventCamera == null)\n {\n // Multiple display support only when not the main display. For display 0 the reported\n // resolution is always the desktops resolution since its part of the display API,\n // so we use the standard none multiple display method. (case 741751)\n float w = Screen.width;\n float h = Screen.height;\n if (displayIndex > 0 && displayIndex < Display.displays.Length)\n {\n w = Display.displays[displayIndex].systemWidth;\n h = Display.displays[displayIndex].systemHeight;\n }\n pos = new Vector2(eventPosition.x / w, eventPosition.y / h);\n }\n else\n pos = currentEventCamera.ScreenToViewportPoint(eventPosition);\n\n // If it's outside the camera's viewport, do nothing\n if (pos.x < 0f || pos.x > 1f || pos.y < 0f || pos.y > 1f)\n return;\n\n float hitDistance = float.MaxValue;\n\n Ray ray = new Ray();\n\n if (currentEventCamera != null)\n ray = currentEventCamera.ScreenPointToRay(eventPosition);\n\n if (canvas.renderMode != RenderMode.ScreenSpaceOverlay && blockingObjects != BlockingObjects.None)\n {\n float distanceToClipPlane = 100.0f;\n\n if (currentEventCamera != null)\n {\n float projectionDirection = ray.direction.z;\n distanceToClipPlane = Mathf.Approximately(0.0f, projectionDirection)\n ? Mathf.Infinity\n : Mathf.Abs((currentEventCamera.farClipPlane - currentEventCamera.nearClipPlane) / projectionDirection);\n }\n#if PACKAGE_PHYSICS\n if (blockingObjects == BlockingObjects.ThreeD || blockingObjects == BlockingObjects.All)\n {\n if (ReflectionMethodsCache.Singleton.raycast3D != null)\n {\n RaycastHit hit;\n if (ReflectionMethodsCache.Singleton.raycast3D(ray, out hit, distanceToClipPlane, (int)m_BlockingMask))\n {\n hitDistance = hit.distance;\n }\n }\n }\n#endif\n#if PACKAGE_PHYSICS2D\n if (blockingObjects == BlockingObjects.TwoD || blockingObjects == BlockingObjects.All)\n {\n if (ReflectionMethodsCache.Singleton.raycast2D != null)\n {\n var hits = ReflectionMethodsCache.Singleton.getRayIntersectionAll(ray, distanceToClipPlane, (int)m_BlockingMask);\n if (hits.Length > 0)\n hitDistance = hits[0].distance;\n }\n }\n#endif\n }\n\n m_RaycastResults.Clear();\n\n Raycast(canvas, currentEventCamera, eventPosition, canvasGraphics, m_RaycastResults);\n\n int totalCount = m_RaycastResults.Count;\n for (var index = 0; index < totalCount; index++)\n {\n var go = m_RaycastResults[index].gameObject;\n bool appendGraphic = true;\n\n if (ignoreReversedGraphics)\n {\n if (currentEventCamera == null)\n {\n // If we dont have a camera we know that we should always be facing forward\n var dir = go.transform.rotation * Vector3.forward;\n appendGraphic = Vector3.Dot(Vector3.forward, dir) > 0;\n }\n else\n {\n // If we have a camera compare the direction against the cameras forward.\n var cameraForward = currentEventCamera.transform.rotation * Vector3.forward * currentEventCamera.nearClipPlane;\n appendGraphic = Vector3.Dot(go.transform.position - currentEventCamera.transform.position - cameraForward, go.transform.forward) >= 0;\n }\n }\n\n if (appendGraphic)\n {\n float distance = 0;\n Transform trans = go.transform;\n Vector3 transForward = trans.forward;\n\n if (currentEventCamera == null || canvas.renderMode == RenderMode.ScreenSpaceOverlay)\n distance = 0;\n else\n {\n // http://geomalgorithms.com/a06-_intersect-2.html\n distance = (Vector3.Dot(transForward, trans.position - ray.origin) / Vector3.Dot(transForward, ray.direction));\n\n // Check to see if the go is behind the camera.\n if (distance < 0)\n continue;\n }\n\n if (distance >= hitDistance)\n continue;\n\n var castResult = new RaycastResult\n {\n gameObject = go,\n module = this,\n distance = distance,\n screenPosition = eventPosition,\n displayIndex = displayIndex,\n index = resultAppendList.Count,\n depth = m_RaycastResults[index].depth,\n sortingLayer = canvas.sortingLayerID,\n sortingOrder = canvas.sortingOrder,\n worldPosition = ray.origin + ray.direction * distance,\n worldNormal = -transForward\n };\n resultAppendList.Add(castResult);\n }\n }\n }\n\n /// <summary>\n /// The camera that will generate rays for this raycaster.\n /// </summary>\n /// <returns>\n /// - Null if Camera mode is ScreenSpaceOverlay or ScreenSpaceCamera and has no camera.\n /// - canvas.worldCanvas if not null\n /// - Camera.main.\n /// </returns>\n public override Camera eventCamera\n {\n get\n {\n var canvas = this.canvas;\n var renderMode = canvas.renderMode;\n if (renderMode == RenderMode.ScreenSpaceOverlay\n || (renderMode == RenderMode.ScreenSpaceCamera && canvas.worldCamera == null))\n return null;\n\n return canvas.worldCamera ?? Camera.main;\n }\n }\n\n /// <summary>\n /// Perform a raycast into the screen and collect all graphics underneath it.\n /// </summary>\n [NonSerialized] static readonly List<Graphic> s_SortedGraphics = new List<Graphic>();\n private static void Raycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, IList<Graphic> foundGraphics, List<Graphic> results)\n {\n // Necessary for the event system\n int totalCount = foundGraphics.Count;\n for (int i = 0; i < totalCount; ++i)\n {\n Graphic graphic = foundGraphics[i];\n\n // -1 means it hasn't been processed by the canvas, which means it isn't actually drawn\n if (!graphic.raycastTarget || graphic.canvasRenderer.cull || graphic.depth == -1)\n continue;\n\n if (!RectTransformUtility.RectangleContainsScreenPoint(graphic.rectTransform, pointerPosition, eventCamera, graphic.raycastPadding))\n continue;\n\n if (eventCamera != null && eventCamera.WorldToScreenPoint(graphic.rectTransform.position).z > eventCamera.farClipPlane)\n continue;\n\n if (graphic.Raycast(pointerPosition, eventCamera))\n {\n s_SortedGraphics.Add(graphic);\n }\n }\n\n s_SortedGraphics.Sort((g1, g2) => g2.depth.CompareTo(g1.depth));\n totalCount = s_SortedGraphics.Count;\n for (int i = 0; i < totalCount; ++i)\n results.Add(s_SortedGraphics[i]);\n\n s_SortedGraphics.Clear();\n }\n }\n}\n"
  140. },
  141. {
  142. "Script": "GraphicRaycaster",
  143. "Ignore Reversed Graphics": "True",
  144. "Blocking Objects": "None",
  145. "Blocking Mask": "Invalid layer"
  146. }
  147. ],
  148. "Children": [
  149. {
  150. "Name": "Panel",
  151. "Components": [
  152. {
  153. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  154. "Local Position": "(0.00, 0.00, 0.00)",
  155. "Local Scale": "(1.00, 1.20, 1.00)",
  156. "Constrain Proportions Scale": "False",
  157. "Anchor Min": "(0.00, 0.50)",
  158. "Anchor Max": "(1.00, 0.50)",
  159. "Anchored Position": "(0.00, 0.00)",
  160. "Size Delta": "(0.00, 300.00)",
  161. "Pivot": "(0.50, 0.50)"
  162. },
  163. {
  164. "Cull Transparent Mesh": "True"
  165. },
  166. {
  167. "Name": "Image",
  168. "Content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n#if UNITY_EDITOR\nusing UnityEditor;\n#endif\nusing UnityEngine.Experimental.Rendering;\nusing UnityEngine.Serialization;\nusing UnityEngine.U2D;\n\nnamespace UnityEngine.UI\n{\n /// <summary>\n /// Image is a textured element in the UI hierarchy.\n /// </summary>\n\n [RequireComponent(typeof(CanvasRenderer))]\n [AddComponentMenu(\"UI/Image\", 11)]\n /// <summary>\n /// Displays a Sprite inside the UI System.\n /// </summary>\n public class Image : MaskableGraphic, ISerializationCallbackReceiver, ILayoutElement, ICanvasRaycastFilter\n {\n /// <summary>\n /// Image fill type controls how to display the image.\n /// </summary>\n public enum Type\n {\n /// <summary>\n /// Displays the full Image\n /// </summary>\n /// <remarks>\n /// This setting shows the entire image stretched across the Image's RectTransform\n /// </remarks>\n Simple,\n\n /// <summary>\n /// Displays the Image as a 9-sliced graphic.\n /// </summary>\n /// <remarks>\n /// A 9-sliced image displays a central area stretched across the image surrounded by a border comprising of 4 corners and 4 stretched edges.\n ///\n /// This has the effect of creating a resizable skinned rectangular element suitable for dialog boxes, windows, and general UI elements.\n ///\n /// Note: For this method to work properly the Sprite assigned to Image.sprite needs to have Sprite.border defined.\n /// </remarks>\n Sliced,\n\n /// <summary>\n /// Displays a sliced Sprite with its resizable sections tiled instead of stretched.\n /// </summary>\n /// <remarks>\n /// A Tiled image behaves similarly to a UI.Image.Type.Sliced|Sliced image, except that the resizable sections of the image are repeated instead of being stretched. This can be useful for detailed UI graphics that do not look good when stretched.\n ///\n /// It uses the Sprite.border value to determine how each part (border and center) should be tiled.\n ///\n /// The Image sections will repeat the corresponding section in the Sprite until the whole section is filled. The corner sections will be unaffected and will draw in the same way as a Sliced Image. The edges will repeat along their lengths. The center section will repeat across the whole central part of the Image.\n ///\n /// The Image section will repeat the corresponding section in the Sprite until the whole section is filled.\n ///\n /// Be aware that if you are tiling a Sprite with borders or a packed sprite, a mesh will be generated to create the tiles. The size of the mesh will be limited to 16250 quads; if your tiling would require more tiles, the size of the tiles will be enlarged to ensure that the number of generated quads stays below this limit.\n ///\n /// For optimum efficiency, use a Sprite with no borders and with no packing, and make sure the Sprite.texture wrap mode is set to TextureWrapMode.Repeat.These settings will prevent the generation of additional geometry.If this is not possible, limit the number of tiles in your Image.\n /// </remarks>\n Tiled,\n\n /// <summary>\n /// Displays only a portion of the Image.\n /// </summary>\n /// <remarks>\n /// A Filled Image will display a section of the Sprite, with the rest of the RectTransform left transparent. The Image.fillAmount determines how much of the Image to show, and Image.fillMethod controls the shape in which the Image will be cut.\n ///\n /// This can be used for example to display circular or linear status information such as timers, health bars, and loading bars.\n /// </remarks>\n Filled\n }\n\n /// <summary>\n /// The possible fill method types for a Filled Image.\n /// </summary>\n public enum FillMethod\n {\n /// <summary>\n /// The Image will be filled Horizontally.\n /// </summary>\n /// <remarks>\n /// The Image will be Cropped at either left or right size depending on Image.fillOriging at the Image.fillAmount\n /// </remarks>\n Horizontal,\n\n /// <summary>\n /// The Image will be filled Vertically.\n /// </summary>\n /// <remarks>\n /// The Image will be Cropped at either top or Bottom size depending on Image.fillOrigin at the Image.fillAmount\n /// </remarks>\n Vertical,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center in one of the corners.\n /// </summary>\n /// <remarks>\n /// For this method the Image.fillAmount represents an angle between 0 and 90 degrees. The Image will be cut by a line passing at the Image.fillOrigin at the specified angle.\n /// </remarks>\n Radial90,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center in one of the edges.\n /// </summary>\n /// <remarks>\n /// For this method the Image.fillAmount represents an angle between 0 and 180 degrees. The Image will be cut by a line passing at the Image.fillOrigin at the specified angle.\n /// </remarks>\n Radial180,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center at the center.\n /// </summary>\n /// <remarks>\n /// or this method the Image.fillAmount represents an angle between 0 and 360 degrees. The Arc defined by the center of the Image, the Image.fillOrigin and the angle will be cut from the Image.\n /// </remarks>\n Radial360,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Horizontal.\n /// </summary>\n public enum OriginHorizontal\n {\n /// <summary>\n /// >Origin at the Left side.\n /// </summary>\n Left,\n\n /// <summary>\n /// >Origin at the Right side.\n /// </summary>\n Right,\n }\n\n\n /// <summary>\n /// Origin for the Image.FillMethod.Vertical.\n /// </summary>\n public enum OriginVertical\n {\n /// <summary>\n /// >Origin at the Bottom Edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// >Origin at the Top Edge.\n /// </summary>\n Top,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Radial90.\n /// </summary>\n public enum Origin90\n {\n /// <summary>\n /// Radial starting at the Bottom Left corner.\n /// </summary>\n BottomLeft,\n\n /// <summary>\n /// Radial starting at the Top Left corner.\n /// </summary>\n TopLeft,\n\n /// <summary>\n /// Radial starting at the Top Right corner.\n /// </summary>\n TopRight,\n\n /// <summary>\n /// Radial starting at the Bottom Right corner.\n /// </summary>\n BottomRight,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Radial180.\n /// </summary>\n public enum Origin180\n {\n /// <summary>\n /// Center of the radial at the center of the Bottom edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// Center of the radial at the center of the Left edge.\n /// </summary>\n Left,\n\n /// <summary>\n /// Center of the radial at the center of the Top edge.\n /// </summary>\n Top,\n\n /// <summary>\n /// Center of the radial at the center of the Right edge.\n /// </summary>\n Right,\n }\n\n /// <summary>\n /// One of the points of the Arc for the Image.FillMethod.Radial360.\n /// </summary>\n public enum Origin360\n {\n /// <summary>\n /// Arc starting at the center of the Bottom edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// Arc starting at the center of the Right edge.\n /// </summary>\n Right,\n\n /// <summary>\n /// Arc starting at the center of the Top edge.\n /// </summary>\n Top,\n\n /// <summary>\n /// Arc starting at the center of the Left edge.\n /// </summary>\n Left,\n }\n\n static protected Material s_ETC1DefaultUI = null;\n\n [FormerlySerializedAs(\"m_Frame\")]\n [SerializeField]\n private Sprite m_Sprite;\n\n /// <summary>\n /// The sprite that is used to render this image.\n /// </summary>\n /// <remarks>\n /// This returns the source Sprite of an Image. This Sprite can also be viewed and changed in the Inspector as part of an Image component. This can also be used to change the Sprite using a script.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// //Attach this script to an Image GameObject and set its Source Image to the Sprite you would like.\n /// //Press the space key to change the Sprite. Remember to assign a second Sprite in this script's section of the Inspector.\n ///\n /// using UnityEngine;\n /// using UnityEngine.UI;\n ///\n /// public class Example : MonoBehaviour\n /// {\n /// Image m_Image;\n /// //Set this in the Inspector\n /// public Sprite m_Sprite;\n ///\n /// void Start()\n /// {\n /// //Fetch the Image from the GameObject\n /// m_Image = GetComponent<Image>();\n /// }\n ///\n /// void Update()\n /// {\n /// //Press space to change the Sprite of the Image\n /// if (Input.GetKey(KeyCode.Space))\n /// {\n /// m_Image.sprite = m_Sprite;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n\n public Sprite sprite\n {\n get { return m_Sprite; }\n set\n {\n if (m_Sprite != null)\n {\n if (m_Sprite != value)\n {\n m_SkipLayoutUpdate = m_Sprite.rect.size.Equals(value ? value.rect.size : Vector2.zero);\n m_SkipMaterialUpdate = m_Sprite.texture == (value ? value.texture : null);\n m_Sprite = value;\n\n ResetAlphaHitThresholdIfNeeded();\n SetAllDirty();\n TrackSprite();\n }\n }\n else if (value != null)\n {\n m_SkipLayoutUpdate = value.rect.size == Vector2.zero;\n m_SkipMaterialUpdate = value.texture == null;\n m_Sprite = value;\n\n ResetAlphaHitThresholdIfNeeded();\n SetAllDirty();\n TrackSprite();\n }\n\n void ResetAlphaHitThresholdIfNeeded()\n {\n if (!SpriteSupportsAlphaHitTest() && m_AlphaHitTestMinimumThreshold > 0)\n {\n Debug.LogWarning(\"Sprite was changed for one not readable or with Crunch Compression. Resetting the AlphaHitThreshold to 0.\", this);\n m_AlphaHitTestMinimumThreshold = 0;\n }\n }\n\n bool SpriteSupportsAlphaHitTest()\n {\n return m_Sprite != null && m_Sprite.texture != null && !GraphicsFormatUtility.IsCrunchFormat(m_Sprite.texture.format) && m_Sprite.texture.isReadable;\n }\n }\n }\n\n\n /// <summary>\n /// Disable all automatic sprite optimizations.\n /// </summary>\n /// <remarks>\n /// When a new Sprite is assigned update optimizations are automatically applied.\n /// </remarks>\n\n public void DisableSpriteOptimizations()\n {\n m_SkipLayoutUpdate = false;\n m_SkipMaterialUpdate = false;\n }\n\n [NonSerialized]\n private Sprite m_OverrideSprite;\n\n /// <summary>\n /// Set an override sprite to be used for rendering.\n /// </summary>\n /// <remarks>\n /// The UI.Image-overrideSprite|overrideSprite variable allows a sprite to have the\n /// sprite changed.This change happens immediately.When the changed\n /// sprite is no longer needed the sprite can be reverted back to the\n /// original version.This happens when the overrideSprite\n /// is set to /null/.\n /// </remarks>\n /// <example>\n /// Note: The script example below has two buttons. The button textures are loaded from the\n /// /Resources/ folder. (They are not used in the shown example). Two sprites are added to\n /// the example code. /Example1/ and /Example2/ are functions called by the button OnClick\n /// functions. Example1 calls overrideSprite and Example2 sets overrideSprite to null.\n /// <code>\n /// <![CDATA[\n /// using System.Collections;\n /// using System.Collections.Generic;\n /// using UnityEngine;\n /// using UnityEngine.UI;\n ///\n /// public class ExampleClass : MonoBehaviour\n /// {\n /// private Sprite sprite1;\n /// private Sprite sprite2;\n /// private Image i;\n ///\n /// public void Start()\n /// {\n /// i = GetComponent<Image>();\n /// sprite1 = Resources.Load<Sprite>(\"texture1\");\n /// sprite2 = Resources.Load<Sprite>(\"texture2\");\n ///\n /// i.sprite = sprite1;\n /// }\n ///\n /// // Called by a Button OnClick() with ExampleClass.Example1\n /// // Uses overrideSprite to make this change temporary\n /// public void Example1()\n /// {\n /// i.overrideSprite = sprite2;\n /// }\n ///\n /// // Called by a Button OnClick() with ExampleClass.Example2\n /// // Removes the overrideSprite which causes the original sprite to be used again.\n /// public void Example2()\n /// {\n /// i.overrideSprite = null;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public Sprite overrideSprite\n {\n get { return activeSprite; }\n set\n {\n if (SetPropertyUtility.SetClass(ref m_OverrideSprite, value))\n {\n SetAllDirty();\n TrackSprite();\n }\n }\n }\n\n private Sprite activeSprite { get { return m_OverrideSprite != null ? m_OverrideSprite : sprite; } }\n\n /// How the Image is drawn.\n [SerializeField] private Type m_Type = Type.Simple;\n\n /// <summary>\n /// How to display the image.\n /// </summary>\n /// <remarks>\n /// Unity can interpret an Image in various different ways depending on the intended purpose. This can be used to display:\n /// - Whole images stretched to fit the RectTransform of the Image.\n /// - A 9-sliced image useful for various decorated UI boxes and other rectangular elements.\n /// - A tiled image with sections of the sprite repeated.\n /// - As a partial image, useful for wipes, fades, timers, status bars etc.\n /// </remarks>\n public Type type { get { return m_Type; } set { if (SetPropertyUtility.SetStruct(ref m_Type, value)) SetVerticesDirty(); } }\n\n [SerializeField] private bool m_PreserveAspect = false;\n\n /// <summary>\n /// Whether this image should preserve its Sprite aspect ratio.\n /// </summary>\n public bool preserveAspect { get { return m_PreserveAspect; } set { if (SetPropertyUtility.SetStruct(ref m_PreserveAspect, value)) SetVerticesDirty(); } }\n\n [SerializeField] private bool m_FillCenter = true;\n\n /// <summary>\n /// Whether or not to render the center of a Tiled or Sliced image.\n /// </summary>\n /// <remarks>\n /// This will only have any effect if the Image.sprite has borders.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI;\n ///\n /// public class FillCenterScript : MonoBehaviour\n /// {\n /// public Image xmasCalenderDoor;\n ///\n /// // removes the center of the image to reveal the image behind it\n /// void OpenCalendarDoor()\n /// {\n /// xmasCalenderDoor.fillCenter = false;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public bool fillCenter { get { return m_FillCenter; } set { if (SetPropertyUtility.SetStruct(ref m_FillCenter, value)) SetVerticesDirty(); } }\n\n /// Filling method for filled sprites.\n [SerializeField] private FillMethod m_FillMethod = FillMethod.Radial360;\n public FillMethod fillMethod { get { return m_FillMethod; } set { if (SetPropertyUtility.SetStruct(ref m_FillMethod, value)) { SetVerticesDirty(); m_FillOrigin = 0; } } }\n\n /// Amount of the Image shown. 0-1 range with 0 being nothing shown, and 1 being the full Image.\n [Range(0, 1)]\n [SerializeField]\n private float m_FillAmount = 1.0f;\n\n /// <summary>\n /// Amount of the Image shown when the Image.type is set to Image.Type.Filled.\n /// </summary>\n /// <remarks>\n /// 0-1 range with 0 being nothing shown, and 1 being the full Image.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class Cooldown : MonoBehaviour\n /// {\n /// public Image cooldown;\n /// public bool coolingDown;\n /// public float waitTime = 30.0f;\n ///\n /// // Update is called once per frame\n /// void Update()\n /// {\n /// if (coolingDown == true)\n /// {\n /// //Reduce fill amount over 30 seconds\n /// cooldown.fillAmount -= 1.0f / waitTime * Time.deltaTime;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public float fillAmount { get { return m_FillAmount; } set { if (SetPropertyUtility.SetStruct(ref m_FillAmount, Mathf.Clamp01(value))) SetVerticesDirty(); } }\n\n /// Whether the Image should be filled clockwise (true) or counter-clockwise (false).\n [SerializeField] private bool m_FillClockwise = true;\n\n /// <summary>\n /// Whether the Image should be filled clockwise (true) or counter-clockwise (false).\n /// </summary>\n /// <remarks>\n /// This will only have any effect if the Image.type is set to Image.Type.Filled and Image.fillMethod is set to any of the Radial methods.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class FillClockwiseScript : MonoBehaviour\n /// {\n /// public Image healthCircle;\n ///\n /// // This method sets the direction of the health circle.\n /// // Clockwise for the Player, Counter Clockwise for the opponent.\n /// void SetHealthDirection(GameObject target)\n /// {\n /// if (target.tag == \"Player\")\n /// {\n /// healthCircle.fillClockwise = true;\n /// }\n /// else if (target.tag == \"Opponent\")\n /// {\n /// healthCircle.fillClockwise = false;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public bool fillClockwise { get { return m_FillClockwise; } set { if (SetPropertyUtility.SetStruct(ref m_FillClockwise, value)) SetVerticesDirty(); } }\n\n /// Controls the origin point of the Fill process. Value means different things with each fill method.\n [SerializeField] private int m_FillOrigin;\n\n /// <summary>\n /// Controls the origin point of the Fill process. Value means different things with each fill method.\n /// </summary>\n /// <remarks>\n /// You should cast to the appropriate origin type: Image.OriginHorizontal, Image.OriginVertical, Image.Origin90, Image.Origin180 or Image.Origin360 depending on the Image.Fillmethod.\n /// Note: This will only have any effect if the Image.type is set to Image.Type.Filled.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using UnityEngine.UI;\n /// using System.Collections;\n ///\n /// [RequireComponent(typeof(Image))]\n /// public class ImageOriginCycle : MonoBehaviour\n /// {\n /// void OnEnable()\n /// {\n /// Image image = GetComponent<Image>();\n /// string fillOriginName = \"\";\n ///\n /// switch ((Image.FillMethod)image.fillMethod)\n /// {\n /// case Image.FillMethod.Horizontal:\n /// fillOriginName = ((Image.OriginHorizontal)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Vertical:\n /// fillOriginName = ((Image.OriginVertical)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial90:\n ///\n /// fillOriginName = ((Image.Origin90)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial180:\n ///\n /// fillOriginName = ((Image.Origin180)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial360:\n /// fillOriginName = ((Image.Origin360)image.fillOrigin).ToString();\n /// break;\n /// }\n /// Debug.Log(string.Format(\"{0} is using {1} fill method with the origin on {2}\", name, image.fillMethod, fillOriginName));\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public int fillOrigin { get { return m_FillOrigin; } set { if (SetPropertyUtility.SetStruct(ref m_FillOrigin, value)) SetVerticesDirty(); } }\n\n // Not serialized until we support read-enabled sprites better.\n private float m_AlphaHitTestMinimumThreshold = 0;\n\n // Whether this is being tracked for Atlas Binding.\n private bool m_Tracked = false;\n\n [Obsolete(\"eventAlphaThreshold has been deprecated. Use eventMinimumAlphaThreshold instead (UnityUpgradable) -> alphaHitTestMinimumThreshold\")]\n\n /// <summary>\n /// Obsolete. You should use UI.Image.alphaHitTestMinimumThreshold instead.\n /// The alpha threshold specifies the minimum alpha a pixel must have for the event to considered a \"hit\" on the Image.\n /// </summary>\n public float eventAlphaThreshold { get { return 1 - alphaHitTestMinimumThreshold; } set { alphaHitTestMinimumThreshold = 1 - value; } }\n\n /// <summary>\n /// The alpha threshold specifies the minimum alpha a pixel must have for the event to considered a \"hit\" on the Image.\n /// </summary>\n /// <remarks>\n /// Alpha values less than the threshold will cause raycast events to pass through the Image. An value of 1 would cause only fully opaque pixels to register raycast events on the Image. The alpha tested is retrieved from the image sprite only, while the alpha of the Image [[UI.Graphic.color]] is disregarded.\n ///\n /// alphaHitTestMinimumThreshold defaults to 0; all raycast events inside the Image rectangle are considered a hit. In order for greater than 0 to values to work, the sprite used by the Image must have readable pixels. This can be achieved by enabling Read/Write enabled in the advanced Texture Import Settings for the sprite and disabling atlassing for the sprite.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class ExampleClass : MonoBehaviour\n /// {\n /// public Image theButton;\n ///\n /// // Use this for initialization\n /// void Start()\n /// {\n /// theButton.alphaHitTestMinimumThreshold = 0.5f;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public float alphaHitTestMinimumThreshold { get { return m_AlphaHitTestMinimumThreshold; }\n set\n {\n if (sprite != null && (GraphicsFormatUtility.IsCrunchFormat(sprite.texture.format) || !sprite.texture.isReadable))\n throw new InvalidOperationException(\"alphaHitTestMinimumThreshold should not be modified on a texture not readeable or not using Crunch Compression.\");\n\n m_AlphaHitTestMinimumThreshold = value;\n }\n }\n\n /// Controls whether or not to use the generated mesh from the sprite importer.\n [SerializeField] private bool m_UseSpriteMesh;\n\n /// <summary>\n /// Allows you to specify whether the UI Image should be displayed using the mesh generated by the TextureImporter, or by a simple quad mesh.\n /// </summary>\n /// <remarks>\n /// When this property is set to false, the UI Image uses a simple quad. When set to true, the UI Image uses the sprite mesh generated by the [[TextureImporter]]. You should set this to true if you want to use a tightly fitted sprite mesh based on the alpha values in your image.\n /// Note: If the texture importer's SpriteMeshType property is set to SpriteMeshType.FullRect, it will only generate a quad, and not a tightly fitted sprite mesh, which means this UI image will be drawn using a quad regardless of the value of this property. Therefore, when enabling this property to use a tightly fitted sprite mesh, you must also ensure the texture importer's SpriteMeshType property is set to Tight.\n /// </remarks>\n public bool useSpriteMesh { get { return m_UseSpriteMesh; } set { if (SetPropertyUtility.SetStruct(ref m_UseSpriteMesh, value)) SetVerticesDirty(); } }\n\n\n protected Image()\n {\n useLegacyMeshGeneration = false;\n }\n\n /// <summary>\n /// Cache of the default Canvas Ericsson Texture Compression 1 (ETC1) and alpha Material.\n /// </summary>\n /// <remarks>\n /// Stores the ETC1 supported Canvas Material that is returned from GetETC1SupportedCanvasMaterial().\n /// Note: Always specify the UI/DefaultETC1 Shader in the Always Included Shader list, to use the ETC1 and alpha Material.\n /// </remarks>\n static public Material defaultETC1GraphicMaterial\n {\n get\n {\n if (s_ETC1DefaultUI == null)\n s_ETC1DefaultUI = Canvas.GetETC1SupportedCanvasMaterial();\n return s_ETC1DefaultUI;\n }\n }\n\n /// <summary>\n /// Image's texture comes from the UnityEngine.Image.\n /// </summary>\n public override Texture mainTexture\n {\n get\n {\n if (activeSprite == null)\n {\n if (material != null && material.mainTexture != null)\n {\n return material.mainTexture;\n }\n return s_WhiteTexture;\n }\n\n return activeSprite.texture;\n }\n }\n\n /// <summary>\n /// Whether the Sprite of the image has a border to work with.\n /// </summary>\n\n public bool hasBorder\n {\n get\n {\n if (activeSprite != null)\n {\n Vector4 v = activeSprite.border;\n return v.sqrMagnitude > 0f;\n }\n return false;\n }\n }\n\n\n [SerializeField]\n private float m_PixelsPerUnitMultiplier = 1.0f;\n\n /// <summary>\n /// Pixel per unit modifier to change how sliced sprites are generated.\n /// </summary>\n public float pixelsPerUnitMultiplier\n {\n get { return m_PixelsPerUnitMultiplier; }\n set\n {\n m_PixelsPerUnitMultiplier = Mathf.Max(0.01f, value);\n SetVerticesDirty();\n }\n }\n\n // case 1066689 cache referencePixelsPerUnit when canvas parent is disabled;\n private float m_CachedReferencePixelsPerUnit = 100;\n\n public float pixelsPerUnit\n {\n get\n {\n float spritePixelsPerUnit = 100;\n if (activeSprite)\n spritePixelsPerUnit = activeSprite.pixelsPerUnit;\n\n if (canvas)\n m_CachedReferencePixelsPerUnit = canvas.referencePixelsPerUnit;\n\n return spritePixelsPerUnit / m_CachedReferencePixelsPerUnit;\n }\n }\n\n protected float multipliedPixelsPerUnit\n {\n get { return pixelsPerUnit * m_PixelsPerUnitMultiplier; }\n }\n\n /// <summary>\n /// The specified Material used by this Image. The default Material is used instead if one wasn't specified.\n /// </summary>\n public override Material material\n {\n get\n {\n if (m_Material != null)\n return m_Material;\n\n //Edit and Runtime should use Split Alpha Shader if EditorSettings.spritePackerMode = Sprite Atlas V2\n#if UNITY_EDITOR\n if ((Application.isPlaying || EditorSettings.spritePackerMode == SpritePackerMode.SpriteAtlasV2) &&\n activeSprite && activeSprite.associatedAlphaSplitTexture != null)\n {\n return defaultETC1GraphicMaterial;\n }\n#else\n\n if (activeSprite && activeSprite.associatedAlphaSplitTexture != null)\n return defaultETC1GraphicMaterial;\n#endif\n\n return defaultMaterial;\n }\n\n set\n {\n base.material = value;\n }\n }\n\n /// <summary>\n /// See ISerializationCallbackReceiver.\n /// </summary>\n public virtual void OnBeforeSerialize() {}\n\n /// <summary>\n /// See ISerializationCallbackReceiver.\n /// </summary>\n public virtual void OnAfterDeserialize()\n {\n if (m_FillOrigin < 0)\n m_FillOrigin = 0;\n else if (m_FillMethod == FillMethod.Horizontal && m_FillOrigin > 1)\n m_FillOrigin = 0;\n else if (m_FillMethod == FillMethod.Vertical && m_FillOrigin > 1)\n m_FillOrigin = 0;\n else if (m_FillOrigin > 3)\n m_FillOrigin = 0;\n\n m_FillAmount = Mathf.Clamp(m_FillAmount, 0f, 1f);\n }\n\n private void PreserveSpriteAspectRatio(ref Rect rect, Vector2 spriteSize)\n {\n var spriteRatio = spriteSize.x / spriteSize.y;\n var rectRatio = rect.width / rect.height;\n\n if (spriteRatio > rectRatio)\n {\n var oldHeight = rect.height;\n rect.height = rect.width * (1.0f / spriteRatio);\n rect.y += (oldHeight - rect.height) * rectTransform.pivot.y;\n }\n else\n {\n var oldWidth = rect.width;\n rect.width = rect.height * spriteRatio;\n rect.x += (oldWidth - rect.width) * rectTransform.pivot.x;\n }\n }\n\n /// Image's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top.\n private Vector4 GetDrawingDimensions(bool shouldPreserveAspect)\n {\n var padding = activeSprite == null ? Vector4.zero : Sprites.DataUtility.GetPadding(activeSprite);\n var size = activeSprite == null ? Vector2.zero : new Vector2(activeSprite.rect.width, activeSprite.rect.height);\n\n Rect r = GetPixelAdjustedRect();\n // Debug.Log(string.Format(\"r:{2}, size:{0}, padding:{1}\", size, padding, r));\n\n int spriteW = Mathf.RoundToInt(size.x);\n int spriteH = Mathf.RoundToInt(size.y);\n\n var v = new Vector4(\n padding.x / spriteW,\n padding.y / spriteH,\n (spriteW - padding.z) / spriteW,\n (spriteH - padding.w) / spriteH);\n\n if (shouldPreserveAspect && size.sqrMagnitude > 0.0f)\n {\n PreserveSpriteAspectRatio(ref r, size);\n }\n\n v = new Vector4(\n r.x + r.width * v.x,\n r.y + r.height * v.y,\n r.x + r.width * v.z,\n r.y + r.height * v.w\n );\n\n return v;\n }\n\n /// <summary>\n /// Adjusts the image size to make it pixel-perfect.\n /// </summary>\n /// <remarks>\n /// This means setting the Images RectTransform.sizeDelta to be equal to the Sprite dimensions.\n /// </remarks>\n public override void SetNativeSize()\n {\n if (activeSprite != null)\n {\n float w = activeSprite.rect.width / pixelsPerUnit;\n float h = activeSprite.rect.height / pixelsPerUnit;\n rectTransform.anchorMax = rectTransform.anchorMin;\n rectTransform.sizeDelta = new Vector2(w, h);\n SetAllDirty();\n }\n }\n\n /// <summary>\n /// Update the UI renderer mesh.\n /// </summary>\n protected override void OnPopulateMesh(VertexHelper toFill)\n {\n if (activeSprite == null)\n {\n base.OnPopulateMesh(toFill);\n return;\n }\n\n switch (type)\n {\n case Type.Simple:\n if (!useSpriteMesh)\n GenerateSimpleSprite(toFill, m_PreserveAspect);\n else\n GenerateSprite(toFill, m_PreserveAspect);\n break;\n case Type.Sliced:\n GenerateSlicedSprite(toFill);\n break;\n case Type.Tiled:\n GenerateTiledSprite(toFill);\n break;\n case Type.Filled:\n GenerateFilledSprite(toFill, m_PreserveAspect);\n break;\n }\n }\n\n private void TrackSprite()\n {\n if (activeSprite != null && activeSprite.texture == null)\n {\n TrackImage(this);\n m_Tracked = true;\n }\n }\n\n protected override void OnEnable()\n {\n base.OnEnable();\n TrackSprite();\n }\n\n protected override void OnDisable()\n {\n base.OnDisable();\n\n if (m_Tracked)\n UnTrackImage(this);\n }\n\n /// <summary>\n /// Update the renderer's material.\n /// </summary>\n\n protected override void UpdateMaterial()\n {\n base.UpdateMaterial();\n\n // check if this sprite has an associated alpha texture (generated when splitting RGBA = RGB + A as two textures without alpha)\n\n if (activeSprite == null)\n {\n canvasRenderer.SetAlphaTexture(null);\n return;\n }\n\n Texture2D alphaTex = activeSprite.associatedAlphaSplitTexture;\n\n if (alphaTex != null)\n {\n canvasRenderer.SetAlphaTexture(alphaTex);\n }\n }\n\n protected override void OnCanvasHierarchyChanged()\n {\n base.OnCanvasHierarchyChanged();\n if (canvas == null)\n {\n m_CachedReferencePixelsPerUnit = 100;\n }\n else if (canvas.referencePixelsPerUnit != m_CachedReferencePixelsPerUnit)\n {\n m_CachedReferencePixelsPerUnit = canvas.referencePixelsPerUnit;\n if (type == Type.Sliced || type == Type.Tiled)\n {\n SetVerticesDirty();\n SetLayoutDirty();\n }\n }\n }\n\n /// <summary>\n /// Generate vertices for a simple Image.\n /// </summary>\n void GenerateSimpleSprite(VertexHelper vh, bool lPreserveAspect)\n {\n Vector4 v = GetDrawingDimensions(lPreserveAspect);\n var uv = (activeSprite != null) ? Sprites.DataUtility.GetOuterUV(activeSprite) : Vector4.zero;\n\n var color32 = color;\n vh.Clear();\n vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));\n vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));\n vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));\n vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));\n\n vh.AddTriangle(0, 1, 2);\n vh.AddTriangle(2, 3, 0);\n }\n\n private void GenerateSprite(VertexHelper vh, bool lPreserveAspect)\n {\n var spriteSize = new Vector2(activeSprite.rect.width, activeSprite.rect.height);\n\n // Covert sprite pivot into normalized space.\n var spritePivot = activeSprite.pivot / spriteSize;\n var rectPivot = rectTransform.pivot;\n Rect r = GetPixelAdjustedRect();\n\n if (lPreserveAspect & spriteSize.sqrMagnitude > 0.0f)\n {\n PreserveSpriteAspectRatio(ref r, spriteSize);\n }\n\n var drawingSize = new Vector2(r.width, r.height);\n var spriteBoundSize = activeSprite.bounds.size;\n\n // Calculate the drawing offset based on the difference between the two pivots.\n var drawOffset = (rectPivot - spritePivot) * drawingSize;\n\n var color32 = color;\n vh.Clear();\n\n Vector2[] vertices = activeSprite.vertices;\n Vector2[] uvs = activeSprite.uv;\n for (int i = 0; i < vertices.Length; ++i)\n {\n vh.AddVert(new Vector3((vertices[i].x / spriteBoundSize.x) * drawingSize.x - drawOffset.x, (vertices[i].y / spriteBoundSize.y) * drawingSize.y - drawOffset.y), color32, new Vector2(uvs[i].x, uvs[i].y));\n }\n\n UInt16[] triangles = activeSprite.triangles;\n for (int i = 0; i < triangles.Length; i += 3)\n {\n vh.AddTriangle(triangles[i + 0], triangles[i + 1], triangles[i + 2]);\n }\n }\n\n static readonly Vector2[] s_VertScratch = new Vector2[4];\n static readonly Vector2[] s_UVScratch = new Vector2[4];\n\n /// <summary>\n /// Generate vertices for a 9-sliced Image.\n /// </summary>\n private void GenerateSlicedSprite(VertexHelper toFill)\n {\n if (!hasBorder)\n {\n GenerateSimpleSprite(toFill, false);\n return;\n }\n\n Vector4 outer, inner, padding, border;\n\n if (activeSprite != null)\n {\n outer = Sprites.DataUtility.GetOuterUV(activeSprite);\n inner = Sprites.DataUtility.GetInnerUV(activeSprite);\n padding = Sprites.DataUtility.GetPadding(activeSprite);\n border = activeSprite.border;\n }\n else\n {\n outer = Vector4.zero;\n inner = Vector4.zero;\n padding = Vector4.zero;\n border = Vector4.zero;\n }\n\n Rect rect = GetPixelAdjustedRect();\n\n Vector4 adjustedBorders = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);\n padding = padding / multipliedPixelsPerUnit;\n\n s_VertScratch[0] = new Vector2(padding.x, padding.y);\n s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);\n\n s_VertScratch[1].x = adjustedBorders.x;\n s_VertScratch[1].y = adjustedBorders.y;\n\n s_VertScratch[2].x = rect.width - adjustedBorders.z;\n s_VertScratch[2].y = rect.height - adjustedBorders.w;\n\n for (int i = 0; i < 4; ++i)\n {\n s_VertScratch[i].x += rect.x;\n s_VertScratch[i].y += rect.y;\n }\n\n s_UVScratch[0] = new Vector2(outer.x, outer.y);\n s_UVScratch[1] = new Vector2(inner.x, inner.y);\n s_UVScratch[2] = new Vector2(inner.z, inner.w);\n s_UVScratch[3] = new Vector2(outer.z, outer.w);\n\n toFill.Clear();\n\n for (int x = 0; x < 3; ++x)\n {\n int x2 = x + 1;\n\n for (int y = 0; y < 3; ++y)\n {\n if (!m_FillCenter && x == 1 && y == 1)\n continue;\n\n int y2 = y + 1;\n\n\n AddQuad(toFill,\n new Vector2(s_VertScratch[x].x, s_VertScratch[y].y),\n new Vector2(s_VertScratch[x2].x, s_VertScratch[y2].y),\n color,\n new Vector2(s_UVScratch[x].x, s_UVScratch[y].y),\n new Vector2(s_UVScratch[x2].x, s_UVScratch[y2].y));\n }\n }\n }\n\n /// <summary>\n /// Generate vertices for a tiled Image.\n /// </summary>\n\n void GenerateTiledSprite(VertexHelper toFill)\n {\n Vector4 outer, inner, border;\n Vector2 spriteSize;\n\n if (activeSprite != null)\n {\n outer = Sprites.DataUtility.GetOuterUV(activeSprite);\n inner = Sprites.DataUtility.GetInnerUV(activeSprite);\n border = activeSprite.border;\n spriteSize = activeSprite.rect.size;\n }\n else\n {\n outer = Vector4.zero;\n inner = Vector4.zero;\n border = Vector4.zero;\n spriteSize = Vector2.one * 100;\n }\n\n Rect rect = GetPixelAdjustedRect();\n float tileWidth = (spriteSize.x - border.x - border.z) / multipliedPixelsPerUnit;\n float tileHeight = (spriteSize.y - border.y - border.w) / multipliedPixelsPerUnit;\n\n border = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);\n\n var uvMin = new Vector2(inner.x, inner.y);\n var uvMax = new Vector2(inner.z, inner.w);\n\n // Min to max max range for tiled region in coordinates relative to lower left corner.\n float xMin = border.x;\n float xMax = rect.width - border.z;\n float yMin = border.y;\n float yMax = rect.height - border.w;\n\n toFill.Clear();\n var clipped = uvMax;\n\n // if either width is zero we cant tile so just assume it was the full width.\n if (tileWidth <= 0)\n tileWidth = xMax - xMin;\n\n if (tileHeight <= 0)\n tileHeight = yMax - yMin;\n\n if (activeSprite != null && (hasBorder || activeSprite.packed || activeSprite.texture != null && activeSprite.texture.wrapMode != TextureWrapMode.Repeat))\n {\n // Sprite has border, or is not in repeat mode, or cannot be repeated because of packing.\n // We cannot use texture tiling so we will generate a mesh of quads to tile the texture.\n\n // Evaluate how many vertices we will generate. Limit this number to something sane,\n // especially since meshes can not have more than 65000 vertices.\n\n long nTilesW = 0;\n long nTilesH = 0;\n if (m_FillCenter)\n {\n nTilesW = (long)Math.Ceiling((xMax - xMin) / tileWidth);\n nTilesH = (long)Math.Ceiling((yMax - yMin) / tileHeight);\n\n double nVertices = 0;\n if (hasBorder)\n {\n nVertices = (nTilesW + 2.0) * (nTilesH + 2.0) * 4.0; // 4 vertices per tile\n }\n else\n {\n nVertices = nTilesW * nTilesH * 4.0; // 4 vertices per tile\n }\n\n if (nVertices > 65000.0)\n {\n Debug.LogError(\"Too many sprite tiles on Image \\\"\" + name + \"\\\". The tile size will be increased. To remove the limit on the number of tiles, set the Wrap mode to Repeat in the Image Import Settings\", this);\n\n double maxTiles = 65000.0 / 4.0; // Max number of vertices is 65000; 4 vertices per tile.\n double imageRatio;\n if (hasBorder)\n {\n imageRatio = (nTilesW + 2.0) / (nTilesH + 2.0);\n }\n else\n {\n imageRatio = (double)nTilesW / nTilesH;\n }\n\n double targetTilesW = Math.Sqrt(maxTiles / imageRatio);\n double targetTilesH = targetTilesW * imageRatio;\n if (hasBorder)\n {\n targetTilesW -= 2;\n targetTilesH -= 2;\n }\n\n nTilesW = (long)Math.Floor(targetTilesW);\n nTilesH = (long)Math.Floor(targetTilesH);\n tileWidth = (xMax - xMin) / nTilesW;\n tileHeight = (yMax - yMin) / nTilesH;\n }\n }\n else\n {\n if (hasBorder)\n {\n // Texture on the border is repeated only in one direction.\n nTilesW = (long)Math.Ceiling((xMax - xMin) / tileWidth);\n nTilesH = (long)Math.Ceiling((yMax - yMin) / tileHeight);\n double nVertices = (nTilesH + nTilesW + 2.0 /*corners*/) * 2.0 /*sides*/ * 4.0 /*vertices per tile*/;\n if (nVertices > 65000.0)\n {\n Debug.LogError(\"Too many sprite tiles on Image \\\"\" + name + \"\\\". The tile size will be increased. To remove the limit on the number of tiles, set the Wrap mode to Repeat in the Image Import Settings\", this);\n\n double maxTiles = 65000.0 / 4.0; // Max number of vertices is 65000; 4 vertices per tile.\n double imageRatio = (double)nTilesW / nTilesH;\n double targetTilesW = (maxTiles - 4 /*corners*/) / (2 * (1.0 + imageRatio));\n double targetTilesH = targetTilesW * imageRatio;\n\n nTilesW = (long)Math.Floor(targetTilesW);\n nTilesH = (long)Math.Floor(targetTilesH);\n tileWidth = (xMax - xMin) / nTilesW;\n tileHeight = (yMax - yMin) / nTilesH;\n }\n }\n else\n {\n nTilesH = nTilesW = 0;\n }\n }\n\n if (m_FillCenter)\n {\n // TODO: we could share vertices between quads. If vertex sharing is implemented. update the computation for the number of vertices accordingly.\n for (long j = 0; j < nTilesH; j++)\n {\n float y1 = yMin + j * tileHeight;\n float y2 = yMin + (j + 1) * tileHeight;\n if (y2 > yMax)\n {\n clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);\n y2 = yMax;\n }\n clipped.x = uvMax.x;\n for (long i = 0; i < nTilesW; i++)\n {\n float x1 = xMin + i * tileWidth;\n float x2 = xMin + (i + 1) * tileWidth;\n if (x2 > xMax)\n {\n clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);\n x2 = xMax;\n }\n AddQuad(toFill, new Vector2(x1, y1) + rect.position, new Vector2(x2, y2) + rect.position, color, uvMin, clipped);\n }\n }\n }\n if (hasBorder)\n {\n clipped = uvMax;\n for (long j = 0; j < nTilesH; j++)\n {\n float y1 = yMin + j * tileHeight;\n float y2 = yMin + (j + 1) * tileHeight;\n if (y2 > yMax)\n {\n clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);\n y2 = yMax;\n }\n AddQuad(toFill,\n new Vector2(0, y1) + rect.position,\n new Vector2(xMin, y2) + rect.position,\n color,\n new Vector2(outer.x, uvMin.y),\n new Vector2(uvMin.x, clipped.y));\n AddQuad(toFill,\n new Vector2(xMax, y1) + rect.position,\n new Vector2(rect.width, y2) + rect.position,\n color,\n new Vector2(uvMax.x, uvMin.y),\n new Vector2(outer.z, clipped.y));\n }\n\n // Bottom and top tiled border\n clipped = uvMax;\n for (long i = 0; i < nTilesW; i++)\n {\n float x1 = xMin + i * tileWidth;\n float x2 = xMin + (i + 1) * tileWidth;\n if (x2 > xMax)\n {\n clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);\n x2 = xMax;\n }\n AddQuad(toFill,\n new Vector2(x1, 0) + rect.position,\n new Vector2(x2, yMin) + rect.position,\n color,\n new Vector2(uvMin.x, outer.y),\n new Vector2(clipped.x, uvMin.y));\n AddQuad(toFill,\n new Vector2(x1, yMax) + rect.position,\n new Vector2(x2, rect.height) + rect.position,\n color,\n new Vector2(uvMin.x, uvMax.y),\n new Vector2(clipped.x, outer.w));\n }\n\n // Corners\n AddQuad(toFill,\n new Vector2(0, 0) + rect.position,\n new Vector2(xMin, yMin) + rect.position,\n color,\n new Vector2(outer.x, outer.y),\n new Vector2(uvMin.x, uvMin.y));\n AddQuad(toFill,\n new Vector2(xMax, 0) + rect.position,\n new Vector2(rect.width, yMin) + rect.position,\n color,\n new Vector2(uvMax.x, outer.y),\n new Vector2(outer.z, uvMin.y));\n AddQuad(toFill,\n new Vector2(0, yMax) + rect.position,\n new Vector2(xMin, rect.height) + rect.position,\n color,\n new Vector2(outer.x, uvMax.y),\n new Vector2(uvMin.x, outer.w));\n AddQuad(toFill,\n new Vector2(xMax, yMax) + rect.position,\n new Vector2(rect.width, rect.height) + rect.position,\n color,\n new Vector2(uvMax.x, uvMax.y),\n new Vector2(outer.z, outer.w));\n }\n }\n else\n {\n // Texture has no border, is in repeat mode and not packed. Use texture tiling.\n Vector2 uvScale = new Vector2((xMax - xMin) / tileWidth, (yMax - yMin) / tileHeight);\n\n if (m_FillCenter)\n {\n AddQuad(toFill, new Vector2(xMin, yMin) + rect.position, new Vector2(xMax, yMax) + rect.position, color, Vector2.Scale(uvMin, uvScale), Vector2.Scale(uvMax, uvScale));\n }\n }\n }\n\n static void AddQuad(VertexHelper vertexHelper, Vector3[] quadPositions, Color32 color, Vector3[] quadUVs)\n {\n int startIndex = vertexHelper.currentVertCount;\n\n for (int i = 0; i < 4; ++i)\n vertexHelper.AddVert(quadPositions[i], color, quadUVs[i]);\n\n vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);\n vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);\n }\n\n static void AddQuad(VertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, Color32 color, Vector2 uvMin, Vector2 uvMax)\n {\n int startIndex = vertexHelper.currentVertCount;\n\n vertexHelper.AddVert(new Vector3(posMin.x, posMin.y, 0), color, new Vector2(uvMin.x, uvMin.y));\n vertexHelper.AddVert(new Vector3(posMin.x, posMax.y, 0), color, new Vector2(uvMin.x, uvMax.y));\n vertexHelper.AddVert(new Vector3(posMax.x, posMax.y, 0), color, new Vector2(uvMax.x, uvMax.y));\n vertexHelper.AddVert(new Vector3(posMax.x, posMin.y, 0), color, new Vector2(uvMax.x, uvMin.y));\n\n vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);\n vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);\n }\n\n private Vector4 GetAdjustedBorders(Vector4 border, Rect adjustedRect)\n {\n Rect originalRect = rectTransform.rect;\n\n for (int axis = 0; axis <= 1; axis++)\n {\n float borderScaleRatio;\n\n // The adjusted rect (adjusted for pixel correctness)\n // may be slightly larger than the original rect.\n // Adjust the border to match the adjustedRect to avoid\n // small gaps between borders (case 833201).\n if (originalRect.size[axis] != 0)\n {\n borderScaleRatio = adjustedRect.size[axis] / originalRect.size[axis];\n border[axis] *= borderScaleRatio;\n border[axis + 2] *= borderScaleRatio;\n }\n\n // If the rect is smaller than the combined borders, then there's not room for the borders at their normal size.\n // In order to avoid artefacts with overlapping borders, we scale the borders down to fit.\n float combinedBorders = border[axis] + border[axis + 2];\n if (adjustedRect.size[axis] < combinedBorders && combinedBorders != 0)\n {\n borderScaleRatio = adjustedRect.size[axis] / combinedBorders;\n border[axis] *= borderScaleRatio;\n border[axis + 2] *= borderScaleRatio;\n }\n }\n return border;\n }\n\n static readonly Vector3[] s_Xy = new Vector3[4];\n static readonly Vector3[] s_Uv = new Vector3[4];\n\n /// <summary>\n /// Generate vertices for a filled Image.\n /// </summary>\n void GenerateFilledSprite(VertexHelper toFill, bool preserveAspect)\n {\n toFill.Clear();\n\n if (m_FillAmount < 0.001f)\n return;\n\n Vector4 v = GetDrawingDimensions(preserveAspect);\n Vector4 outer = activeSprite != null ? Sprites.DataUtility.GetOuterUV(activeSprite) : Vector4.zero;\n UIVertex uiv = UIVertex.simpleVert;\n uiv.color = color;\n\n float tx0 = outer.x;\n float ty0 = outer.y;\n float tx1 = outer.z;\n float ty1 = outer.w;\n\n // Horizontal and vertical filled sprites are simple -- just end the Image prematurely\n if (m_FillMethod == FillMethod.Horizontal || m_FillMethod == FillMethod.Vertical)\n {\n if (fillMethod == FillMethod.Horizontal)\n {\n float fill = (tx1 - tx0) * m_FillAmount;\n\n if (m_FillOrigin == 1)\n {\n v.x = v.z - (v.z - v.x) * m_FillAmount;\n tx0 = tx1 - fill;\n }\n else\n {\n v.z = v.x + (v.z - v.x) * m_FillAmount;\n tx1 = tx0 + fill;\n }\n }\n else if (fillMethod == FillMethod.Vertical)\n {\n float fill = (ty1 - ty0) * m_FillAmount;\n\n if (m_FillOrigin == 1)\n {\n v.y = v.w - (v.w - v.y) * m_FillAmount;\n ty0 = ty1 - fill;\n }\n else\n {\n v.w = v.y + (v.w - v.y) * m_FillAmount;\n ty1 = ty0 + fill;\n }\n }\n }\n\n s_Xy[0] = new Vector2(v.x, v.y);\n s_Xy[1] = new Vector2(v.x, v.w);\n s_Xy[2] = new Vector2(v.z, v.w);\n s_Xy[3] = new Vector2(v.z, v.y);\n\n s_Uv[0] = new Vector2(tx0, ty0);\n s_Uv[1] = new Vector2(tx0, ty1);\n s_Uv[2] = new Vector2(tx1, ty1);\n s_Uv[3] = new Vector2(tx1, ty0);\n\n {\n if (m_FillAmount < 1f && m_FillMethod != FillMethod.Horizontal && m_FillMethod != FillMethod.Vertical)\n {\n if (fillMethod == FillMethod.Radial90)\n {\n if (RadialCut(s_Xy, s_Uv, m_FillAmount, m_FillClockwise, m_FillOrigin))\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n else if (fillMethod == FillMethod.Radial180)\n {\n for (int side = 0; side < 2; ++side)\n {\n float fx0, fx1, fy0, fy1;\n int even = m_FillOrigin > 1 ? 1 : 0;\n\n if (m_FillOrigin == 0 || m_FillOrigin == 2)\n {\n fy0 = 0f;\n fy1 = 1f;\n if (side == even)\n {\n fx0 = 0f;\n fx1 = 0.5f;\n }\n else\n {\n fx0 = 0.5f;\n fx1 = 1f;\n }\n }\n else\n {\n fx0 = 0f;\n fx1 = 1f;\n if (side == even)\n {\n fy0 = 0.5f;\n fy1 = 1f;\n }\n else\n {\n fy0 = 0f;\n fy1 = 0.5f;\n }\n }\n\n s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);\n s_Xy[1].x = s_Xy[0].x;\n s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);\n s_Xy[3].x = s_Xy[2].x;\n\n s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);\n s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);\n s_Xy[2].y = s_Xy[1].y;\n s_Xy[3].y = s_Xy[0].y;\n\n s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);\n s_Uv[1].x = s_Uv[0].x;\n s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);\n s_Uv[3].x = s_Uv[2].x;\n\n s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);\n s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);\n s_Uv[2].y = s_Uv[1].y;\n s_Uv[3].y = s_Uv[0].y;\n\n float val = m_FillClockwise ? fillAmount * 2f - side : m_FillAmount * 2f - (1 - side);\n\n if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((side + m_FillOrigin + 3) % 4)))\n {\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n else if (fillMethod == FillMethod.Radial360)\n {\n for (int corner = 0; corner < 4; ++corner)\n {\n float fx0, fx1, fy0, fy1;\n\n if (corner < 2)\n {\n fx0 = 0f;\n fx1 = 0.5f;\n }\n else\n {\n fx0 = 0.5f;\n fx1 = 1f;\n }\n\n if (corner == 0 || corner == 3)\n {\n fy0 = 0f;\n fy1 = 0.5f;\n }\n else\n {\n fy0 = 0.5f;\n fy1 = 1f;\n }\n\n s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);\n s_Xy[1].x = s_Xy[0].x;\n s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);\n s_Xy[3].x = s_Xy[2].x;\n\n s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);\n s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);\n s_Xy[2].y = s_Xy[1].y;\n s_Xy[3].y = s_Xy[0].y;\n\n s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);\n s_Uv[1].x = s_Uv[0].x;\n s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);\n s_Uv[3].x = s_Uv[2].x;\n\n s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);\n s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);\n s_Uv[2].y = s_Uv[1].y;\n s_Uv[3].y = s_Uv[0].y;\n\n float val = m_FillClockwise ?\n m_FillAmount * 4f - ((corner + m_FillOrigin) % 4) :\n m_FillAmount * 4f - (3 - ((corner + m_FillOrigin) % 4));\n\n if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((corner + 2) % 4)))\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n else\n {\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n\n /// <summary>\n /// Adjust the specified quad, making it be radially filled instead.\n /// </summary>\n\n static bool RadialCut(Vector3[] xy, Vector3[] uv, float fill, bool invert, int corner)\n {\n // Nothing to fill\n if (fill < 0.001f) return false;\n\n // Even corners invert the fill direction\n if ((corner & 1) == 1) invert = !invert;\n\n // Nothing to adjust\n if (!invert && fill > 0.999f) return true;\n\n // Convert 0-1 value into 0 to 90 degrees angle in radians\n float angle = Mathf.Clamp01(fill);\n if (invert) angle = 1f - angle;\n angle *= 90f * Mathf.Deg2Rad;\n\n // Calculate the effective X and Y factors\n float cos = Mathf.Cos(angle);\n float sin = Mathf.Sin(angle);\n\n RadialCut(xy, cos, sin, invert, corner);\n RadialCut(uv, cos, sin, invert, corner);\n return true;\n }\n\n /// <summary>\n /// Adjust the specified quad, making it be radially filled instead.\n /// </summary>\n\n static void RadialCut(Vector3[] xy, float cos, float sin, bool invert, int corner)\n {\n int i0 = corner;\n int i1 = ((corner + 1) % 4);\n int i2 = ((corner + 2) % 4);\n int i3 = ((corner + 3) % 4);\n\n if ((corner & 1) == 1)\n {\n if (sin > cos)\n {\n cos /= sin;\n sin = 1f;\n\n if (invert)\n {\n xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n xy[i2].x = xy[i1].x;\n }\n }\n else if (cos > sin)\n {\n sin /= cos;\n cos = 1f;\n\n if (!invert)\n {\n xy[i2].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n xy[i3].y = xy[i2].y;\n }\n }\n else\n {\n cos = 1f;\n sin = 1f;\n }\n\n if (!invert) xy[i3].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n else xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n }\n else\n {\n if (cos > sin)\n {\n sin /= cos;\n cos = 1f;\n\n if (!invert)\n {\n xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n xy[i2].y = xy[i1].y;\n }\n }\n else if (sin > cos)\n {\n cos /= sin;\n sin = 1f;\n\n if (invert)\n {\n xy[i2].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n xy[i3].x = xy[i2].x;\n }\n }\n else\n {\n cos = 1f;\n sin = 1f;\n }\n\n if (invert) xy[i3].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n else xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n }\n }\n\n /// <summary>\n /// See ILayoutElement.CalculateLayoutInputHorizontal.\n /// </summary>\n public virtual void CalculateLayoutInputHorizontal() {}\n\n /// <summary>\n /// See ILayoutElement.CalculateLayoutInputVertical.\n /// </summary>\n public virtual void CalculateLayoutInputVertical() {}\n\n /// <summary>\n /// See ILayoutElement.minWidth.\n /// </summary>\n public virtual float minWidth { get { return 0; } }\n\n /// <summary>\n /// If there is a sprite being rendered returns the size of that sprite.\n /// In the case of a slided or tiled sprite will return the calculated minimum size possible\n /// </summary>\n public virtual float preferredWidth\n {\n get\n {\n if (activeSprite == null)\n return 0;\n if (type == Type.Sliced || type == Type.Tiled)\n return Sprites.DataUtility.GetMinSize(activeSprite).x / pixelsPerUnit;\n return activeSprite.rect.size.x / pixelsPerUnit;\n }\n }\n\n /// <summary>\n /// See ILayoutElement.flexibleWidth.\n /// </summary>\n public virtual float flexibleWidth { get { return -1; } }\n\n /// <summary>\n /// See ILayoutElement.minHeight.\n /// </summary>\n public virtual float minHeight { get { return 0; } }\n\n /// <summary>\n /// If there is a sprite being rendered returns the size of that sprite.\n /// In the case of a slided or tiled sprite will return the calculated minimum size possible\n /// </summary>\n public virtual float preferredHeight\n {\n get\n {\n if (activeSprite == null)\n return 0;\n if (type == Type.Sliced || type == Type.Tiled)\n return Sprites.DataUtility.GetMinSize(activeSprite).y / pixelsPerUnit;\n return activeSprite.rect.size.y / pixelsPerUnit;\n }\n }\n\n /// <summary>\n /// See ILayoutElement.flexibleHeight.\n /// </summary>\n public virtual float flexibleHeight { get { return -1; } }\n\n /// <summary>\n /// See ILayoutElement.layoutPriority.\n /// </summary>\n public virtual int layoutPriority { get { return 0; } }\n\n /// <summary>\n /// Calculate if the ray location for this image is a valid hit location. Takes into account a Alpha test threshold.\n /// </summary>\n /// <param name=\"screenPoint\">The screen point to check against</param>\n /// <param name=\"eventCamera\">The camera in which to use to calculate the coordinating position</param>\n /// <returns>If the location is a valid hit or not.</returns>\n /// <remarks> Also see See:ICanvasRaycastFilter.</remarks>\n public virtual bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)\n {\n if (alphaHitTestMinimumThreshold <= 0)\n return true;\n\n if (alphaHitTestMinimumThreshold > 1)\n return false;\n\n if (activeSprite == null)\n return true;\n\n Vector2 local;\n if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out local))\n return false;\n\n Rect rect = GetPixelAdjustedRect();\n\n if (m_PreserveAspect)\n PreserveSpriteAspectRatio(ref rect, new Vector2(activeSprite.texture.width, activeSprite.texture.height));\n\n // Convert to have lower left corner as reference point.\n local.x += rectTransform.pivot.x * rect.width;\n local.y += rectTransform.pivot.y * rect.height;\n\n local = MapCoordinate(local, rect);\n\n // Convert local coordinates to texture space.\n float x = local.x / activeSprite.texture.width;\n float y = local.y / activeSprite.texture.height;\n\n try\n {\n return activeSprite.texture.GetPixelBilinear(x, y).a >= alphaHitTestMinimumThreshold;\n }\n catch (UnityException e)\n {\n Debug.LogError(\"Using alphaHitTestMinimumThreshold greater than 0 on Image whose sprite texture cannot be read. \" + e.Message + \" Also make sure to disable sprite packing for this sprite.\", this);\n return true;\n }\n }\n\n private Vector2 MapCoordinate(Vector2 local, Rect rect)\n {\n Rect spriteRect = activeSprite.rect;\n if (type == Type.Simple || type == Type.Filled)\n return new Vector2(spriteRect.position.x + local.x * spriteRect.width / rect.width, spriteRect.position.y + local.y * spriteRect.height / rect.height);\n\n Vector4 border = activeSprite.border;\n Vector4 adjustedBorder = GetAdjustedBorders(border / pixelsPerUnit, rect);\n\n for (int i = 0; i < 2; i++)\n {\n if (local[i] <= adjustedBorder[i])\n continue;\n\n if (rect.size[i] - local[i] <= adjustedBorder[i + 2])\n {\n local[i] -= (rect.size[i] - spriteRect.size[i]);\n continue;\n }\n\n if (type == Type.Sliced)\n {\n float lerp = Mathf.InverseLerp(adjustedBorder[i], rect.size[i] - adjustedBorder[i + 2], local[i]);\n local[i] = Mathf.Lerp(border[i], spriteRect.size[i] - border[i + 2], lerp);\n }\n else\n {\n local[i] -= adjustedBorder[i];\n local[i] = Mathf.Repeat(local[i], spriteRect.size[i] - border[i] - border[i + 2]);\n local[i] += border[i];\n }\n }\n\n return local + spriteRect.position;\n }\n\n // To track textureless images, which will be rebuild if sprite atlas manager registered a Sprite Atlas that will give this image new texture\n static List<Image> m_TrackedTexturelessImages = new List<Image>();\n static bool s_Initialized;\n\n static void RebuildImage(SpriteAtlas spriteAtlas)\n {\n for (var i = m_TrackedTexturelessImages.Count - 1; i >= 0; i--)\n {\n var g = m_TrackedTexturelessImages[i];\n if (null != g.activeSprite && spriteAtlas.CanBindTo(g.activeSprite))\n {\n g.SetAllDirty();\n m_TrackedTexturelessImages.RemoveAt(i);\n }\n }\n }\n\n private static void TrackImage(Image g)\n {\n if (!s_Initialized)\n {\n SpriteAtlasManager.atlasRegistered += RebuildImage;\n s_Initialized = true;\n }\n\n m_TrackedTexturelessImages.Add(g);\n }\n\n private static void UnTrackImage(Image g)\n {\n m_TrackedTexturelessImages.Remove(g);\n }\n\n protected override void OnDidApplyAnimationProperties()\n {\n SetMaterialDirty();\n SetVerticesDirty();\n SetRaycastDirty();\n }\n\n#if UNITY_EDITOR\n protected override void OnValidate()\n {\n base.OnValidate();\n m_PixelsPerUnitMultiplier = Mathf.Max(0.01f, m_PixelsPerUnitMultiplier);\n }\n\n#endif\n }\n}\n"
  169. },
  170. {
  171. "Script": "Image",
  172. "Material": "None",
  173. "Color": "RGBA(0.000, 0.000, 0.000, 1.000)",
  174. "Raycast Target": "True",
  175. "Raycast Padding": "(0.00, 0.00, 0.00, 0.00)",
  176. "Maskable": "True",
  177. "On Cull State Changed": "<Unsupported Type>",
  178. "Sprite": "Background",
  179. "Type": "Sliced",
  180. "Preserve Aspect": "False",
  181. "Fill Center": "True",
  182. "Fill Method": "Radial360",
  183. "Fill Amount": "1",
  184. "Fill Clockwise": "True",
  185. "Fill Origin": "0",
  186. "Use Sprite Mesh": "False",
  187. "Pixels Per Unit Multiplier": "1"
  188. }
  189. ],
  190. "Children": []
  191. },
  192. {
  193. "Name": "Record Button",
  194. "Components": [
  195. {
  196. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  197. "Local Position": "(801.90, 0.00, 0.00)",
  198. "Local Scale": "(2.00, 2.00, 1.00)",
  199. "Constrain Proportions Scale": "False",
  200. "Anchor Min": "(1.00, 0.50)",
  201. "Anchor Max": "(1.00, 0.50)",
  202. "Anchored Position": "(-158.10, 0.00)",
  203. "Size Delta": "(160.00, 160.00)",
  204. "Pivot": "(0.50, 0.50)"
  205. },
  206. {
  207. "Cull Transparent Mesh": "True"
  208. },
  209. {
  210. "Name": "Image",
  211. "Content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n#if UNITY_EDITOR\nusing UnityEditor;\n#endif\nusing UnityEngine.Experimental.Rendering;\nusing UnityEngine.Serialization;\nusing UnityEngine.U2D;\n\nnamespace UnityEngine.UI\n{\n /// <summary>\n /// Image is a textured element in the UI hierarchy.\n /// </summary>\n\n [RequireComponent(typeof(CanvasRenderer))]\n [AddComponentMenu(\"UI/Image\", 11)]\n /// <summary>\n /// Displays a Sprite inside the UI System.\n /// </summary>\n public class Image : MaskableGraphic, ISerializationCallbackReceiver, ILayoutElement, ICanvasRaycastFilter\n {\n /// <summary>\n /// Image fill type controls how to display the image.\n /// </summary>\n public enum Type\n {\n /// <summary>\n /// Displays the full Image\n /// </summary>\n /// <remarks>\n /// This setting shows the entire image stretched across the Image's RectTransform\n /// </remarks>\n Simple,\n\n /// <summary>\n /// Displays the Image as a 9-sliced graphic.\n /// </summary>\n /// <remarks>\n /// A 9-sliced image displays a central area stretched across the image surrounded by a border comprising of 4 corners and 4 stretched edges.\n ///\n /// This has the effect of creating a resizable skinned rectangular element suitable for dialog boxes, windows, and general UI elements.\n ///\n /// Note: For this method to work properly the Sprite assigned to Image.sprite needs to have Sprite.border defined.\n /// </remarks>\n Sliced,\n\n /// <summary>\n /// Displays a sliced Sprite with its resizable sections tiled instead of stretched.\n /// </summary>\n /// <remarks>\n /// A Tiled image behaves similarly to a UI.Image.Type.Sliced|Sliced image, except that the resizable sections of the image are repeated instead of being stretched. This can be useful for detailed UI graphics that do not look good when stretched.\n ///\n /// It uses the Sprite.border value to determine how each part (border and center) should be tiled.\n ///\n /// The Image sections will repeat the corresponding section in the Sprite until the whole section is filled. The corner sections will be unaffected and will draw in the same way as a Sliced Image. The edges will repeat along their lengths. The center section will repeat across the whole central part of the Image.\n ///\n /// The Image section will repeat the corresponding section in the Sprite until the whole section is filled.\n ///\n /// Be aware that if you are tiling a Sprite with borders or a packed sprite, a mesh will be generated to create the tiles. The size of the mesh will be limited to 16250 quads; if your tiling would require more tiles, the size of the tiles will be enlarged to ensure that the number of generated quads stays below this limit.\n ///\n /// For optimum efficiency, use a Sprite with no borders and with no packing, and make sure the Sprite.texture wrap mode is set to TextureWrapMode.Repeat.These settings will prevent the generation of additional geometry.If this is not possible, limit the number of tiles in your Image.\n /// </remarks>\n Tiled,\n\n /// <summary>\n /// Displays only a portion of the Image.\n /// </summary>\n /// <remarks>\n /// A Filled Image will display a section of the Sprite, with the rest of the RectTransform left transparent. The Image.fillAmount determines how much of the Image to show, and Image.fillMethod controls the shape in which the Image will be cut.\n ///\n /// This can be used for example to display circular or linear status information such as timers, health bars, and loading bars.\n /// </remarks>\n Filled\n }\n\n /// <summary>\n /// The possible fill method types for a Filled Image.\n /// </summary>\n public enum FillMethod\n {\n /// <summary>\n /// The Image will be filled Horizontally.\n /// </summary>\n /// <remarks>\n /// The Image will be Cropped at either left or right size depending on Image.fillOriging at the Image.fillAmount\n /// </remarks>\n Horizontal,\n\n /// <summary>\n /// The Image will be filled Vertically.\n /// </summary>\n /// <remarks>\n /// The Image will be Cropped at either top or Bottom size depending on Image.fillOrigin at the Image.fillAmount\n /// </remarks>\n Vertical,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center in one of the corners.\n /// </summary>\n /// <remarks>\n /// For this method the Image.fillAmount represents an angle between 0 and 90 degrees. The Image will be cut by a line passing at the Image.fillOrigin at the specified angle.\n /// </remarks>\n Radial90,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center in one of the edges.\n /// </summary>\n /// <remarks>\n /// For this method the Image.fillAmount represents an angle between 0 and 180 degrees. The Image will be cut by a line passing at the Image.fillOrigin at the specified angle.\n /// </remarks>\n Radial180,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center at the center.\n /// </summary>\n /// <remarks>\n /// or this method the Image.fillAmount represents an angle between 0 and 360 degrees. The Arc defined by the center of the Image, the Image.fillOrigin and the angle will be cut from the Image.\n /// </remarks>\n Radial360,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Horizontal.\n /// </summary>\n public enum OriginHorizontal\n {\n /// <summary>\n /// >Origin at the Left side.\n /// </summary>\n Left,\n\n /// <summary>\n /// >Origin at the Right side.\n /// </summary>\n Right,\n }\n\n\n /// <summary>\n /// Origin for the Image.FillMethod.Vertical.\n /// </summary>\n public enum OriginVertical\n {\n /// <summary>\n /// >Origin at the Bottom Edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// >Origin at the Top Edge.\n /// </summary>\n Top,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Radial90.\n /// </summary>\n public enum Origin90\n {\n /// <summary>\n /// Radial starting at the Bottom Left corner.\n /// </summary>\n BottomLeft,\n\n /// <summary>\n /// Radial starting at the Top Left corner.\n /// </summary>\n TopLeft,\n\n /// <summary>\n /// Radial starting at the Top Right corner.\n /// </summary>\n TopRight,\n\n /// <summary>\n /// Radial starting at the Bottom Right corner.\n /// </summary>\n BottomRight,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Radial180.\n /// </summary>\n public enum Origin180\n {\n /// <summary>\n /// Center of the radial at the center of the Bottom edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// Center of the radial at the center of the Left edge.\n /// </summary>\n Left,\n\n /// <summary>\n /// Center of the radial at the center of the Top edge.\n /// </summary>\n Top,\n\n /// <summary>\n /// Center of the radial at the center of the Right edge.\n /// </summary>\n Right,\n }\n\n /// <summary>\n /// One of the points of the Arc for the Image.FillMethod.Radial360.\n /// </summary>\n public enum Origin360\n {\n /// <summary>\n /// Arc starting at the center of the Bottom edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// Arc starting at the center of the Right edge.\n /// </summary>\n Right,\n\n /// <summary>\n /// Arc starting at the center of the Top edge.\n /// </summary>\n Top,\n\n /// <summary>\n /// Arc starting at the center of the Left edge.\n /// </summary>\n Left,\n }\n\n static protected Material s_ETC1DefaultUI = null;\n\n [FormerlySerializedAs(\"m_Frame\")]\n [SerializeField]\n private Sprite m_Sprite;\n\n /// <summary>\n /// The sprite that is used to render this image.\n /// </summary>\n /// <remarks>\n /// This returns the source Sprite of an Image. This Sprite can also be viewed and changed in the Inspector as part of an Image component. This can also be used to change the Sprite using a script.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// //Attach this script to an Image GameObject and set its Source Image to the Sprite you would like.\n /// //Press the space key to change the Sprite. Remember to assign a second Sprite in this script's section of the Inspector.\n ///\n /// using UnityEngine;\n /// using UnityEngine.UI;\n ///\n /// public class Example : MonoBehaviour\n /// {\n /// Image m_Image;\n /// //Set this in the Inspector\n /// public Sprite m_Sprite;\n ///\n /// void Start()\n /// {\n /// //Fetch the Image from the GameObject\n /// m_Image = GetComponent<Image>();\n /// }\n ///\n /// void Update()\n /// {\n /// //Press space to change the Sprite of the Image\n /// if (Input.GetKey(KeyCode.Space))\n /// {\n /// m_Image.sprite = m_Sprite;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n\n public Sprite sprite\n {\n get { return m_Sprite; }\n set\n {\n if (m_Sprite != null)\n {\n if (m_Sprite != value)\n {\n m_SkipLayoutUpdate = m_Sprite.rect.size.Equals(value ? value.rect.size : Vector2.zero);\n m_SkipMaterialUpdate = m_Sprite.texture == (value ? value.texture : null);\n m_Sprite = value;\n\n ResetAlphaHitThresholdIfNeeded();\n SetAllDirty();\n TrackSprite();\n }\n }\n else if (value != null)\n {\n m_SkipLayoutUpdate = value.rect.size == Vector2.zero;\n m_SkipMaterialUpdate = value.texture == null;\n m_Sprite = value;\n\n ResetAlphaHitThresholdIfNeeded();\n SetAllDirty();\n TrackSprite();\n }\n\n void ResetAlphaHitThresholdIfNeeded()\n {\n if (!SpriteSupportsAlphaHitTest() && m_AlphaHitTestMinimumThreshold > 0)\n {\n Debug.LogWarning(\"Sprite was changed for one not readable or with Crunch Compression. Resetting the AlphaHitThreshold to 0.\", this);\n m_AlphaHitTestMinimumThreshold = 0;\n }\n }\n\n bool SpriteSupportsAlphaHitTest()\n {\n return m_Sprite != null && m_Sprite.texture != null && !GraphicsFormatUtility.IsCrunchFormat(m_Sprite.texture.format) && m_Sprite.texture.isReadable;\n }\n }\n }\n\n\n /// <summary>\n /// Disable all automatic sprite optimizations.\n /// </summary>\n /// <remarks>\n /// When a new Sprite is assigned update optimizations are automatically applied.\n /// </remarks>\n\n public void DisableSpriteOptimizations()\n {\n m_SkipLayoutUpdate = false;\n m_SkipMaterialUpdate = false;\n }\n\n [NonSerialized]\n private Sprite m_OverrideSprite;\n\n /// <summary>\n /// Set an override sprite to be used for rendering.\n /// </summary>\n /// <remarks>\n /// The UI.Image-overrideSprite|overrideSprite variable allows a sprite to have the\n /// sprite changed.This change happens immediately.When the changed\n /// sprite is no longer needed the sprite can be reverted back to the\n /// original version.This happens when the overrideSprite\n /// is set to /null/.\n /// </remarks>\n /// <example>\n /// Note: The script example below has two buttons. The button textures are loaded from the\n /// /Resources/ folder. (They are not used in the shown example). Two sprites are added to\n /// the example code. /Example1/ and /Example2/ are functions called by the button OnClick\n /// functions. Example1 calls overrideSprite and Example2 sets overrideSprite to null.\n /// <code>\n /// <![CDATA[\n /// using System.Collections;\n /// using System.Collections.Generic;\n /// using UnityEngine;\n /// using UnityEngine.UI;\n ///\n /// public class ExampleClass : MonoBehaviour\n /// {\n /// private Sprite sprite1;\n /// private Sprite sprite2;\n /// private Image i;\n ///\n /// public void Start()\n /// {\n /// i = GetComponent<Image>();\n /// sprite1 = Resources.Load<Sprite>(\"texture1\");\n /// sprite2 = Resources.Load<Sprite>(\"texture2\");\n ///\n /// i.sprite = sprite1;\n /// }\n ///\n /// // Called by a Button OnClick() with ExampleClass.Example1\n /// // Uses overrideSprite to make this change temporary\n /// public void Example1()\n /// {\n /// i.overrideSprite = sprite2;\n /// }\n ///\n /// // Called by a Button OnClick() with ExampleClass.Example2\n /// // Removes the overrideSprite which causes the original sprite to be used again.\n /// public void Example2()\n /// {\n /// i.overrideSprite = null;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public Sprite overrideSprite\n {\n get { return activeSprite; }\n set\n {\n if (SetPropertyUtility.SetClass(ref m_OverrideSprite, value))\n {\n SetAllDirty();\n TrackSprite();\n }\n }\n }\n\n private Sprite activeSprite { get { return m_OverrideSprite != null ? m_OverrideSprite : sprite; } }\n\n /// How the Image is drawn.\n [SerializeField] private Type m_Type = Type.Simple;\n\n /// <summary>\n /// How to display the image.\n /// </summary>\n /// <remarks>\n /// Unity can interpret an Image in various different ways depending on the intended purpose. This can be used to display:\n /// - Whole images stretched to fit the RectTransform of the Image.\n /// - A 9-sliced image useful for various decorated UI boxes and other rectangular elements.\n /// - A tiled image with sections of the sprite repeated.\n /// - As a partial image, useful for wipes, fades, timers, status bars etc.\n /// </remarks>\n public Type type { get { return m_Type; } set { if (SetPropertyUtility.SetStruct(ref m_Type, value)) SetVerticesDirty(); } }\n\n [SerializeField] private bool m_PreserveAspect = false;\n\n /// <summary>\n /// Whether this image should preserve its Sprite aspect ratio.\n /// </summary>\n public bool preserveAspect { get { return m_PreserveAspect; } set { if (SetPropertyUtility.SetStruct(ref m_PreserveAspect, value)) SetVerticesDirty(); } }\n\n [SerializeField] private bool m_FillCenter = true;\n\n /// <summary>\n /// Whether or not to render the center of a Tiled or Sliced image.\n /// </summary>\n /// <remarks>\n /// This will only have any effect if the Image.sprite has borders.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI;\n ///\n /// public class FillCenterScript : MonoBehaviour\n /// {\n /// public Image xmasCalenderDoor;\n ///\n /// // removes the center of the image to reveal the image behind it\n /// void OpenCalendarDoor()\n /// {\n /// xmasCalenderDoor.fillCenter = false;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public bool fillCenter { get { return m_FillCenter; } set { if (SetPropertyUtility.SetStruct(ref m_FillCenter, value)) SetVerticesDirty(); } }\n\n /// Filling method for filled sprites.\n [SerializeField] private FillMethod m_FillMethod = FillMethod.Radial360;\n public FillMethod fillMethod { get { return m_FillMethod; } set { if (SetPropertyUtility.SetStruct(ref m_FillMethod, value)) { SetVerticesDirty(); m_FillOrigin = 0; } } }\n\n /// Amount of the Image shown. 0-1 range with 0 being nothing shown, and 1 being the full Image.\n [Range(0, 1)]\n [SerializeField]\n private float m_FillAmount = 1.0f;\n\n /// <summary>\n /// Amount of the Image shown when the Image.type is set to Image.Type.Filled.\n /// </summary>\n /// <remarks>\n /// 0-1 range with 0 being nothing shown, and 1 being the full Image.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class Cooldown : MonoBehaviour\n /// {\n /// public Image cooldown;\n /// public bool coolingDown;\n /// public float waitTime = 30.0f;\n ///\n /// // Update is called once per frame\n /// void Update()\n /// {\n /// if (coolingDown == true)\n /// {\n /// //Reduce fill amount over 30 seconds\n /// cooldown.fillAmount -= 1.0f / waitTime * Time.deltaTime;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public float fillAmount { get { return m_FillAmount; } set { if (SetPropertyUtility.SetStruct(ref m_FillAmount, Mathf.Clamp01(value))) SetVerticesDirty(); } }\n\n /// Whether the Image should be filled clockwise (true) or counter-clockwise (false).\n [SerializeField] private bool m_FillClockwise = true;\n\n /// <summary>\n /// Whether the Image should be filled clockwise (true) or counter-clockwise (false).\n /// </summary>\n /// <remarks>\n /// This will only have any effect if the Image.type is set to Image.Type.Filled and Image.fillMethod is set to any of the Radial methods.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class FillClockwiseScript : MonoBehaviour\n /// {\n /// public Image healthCircle;\n ///\n /// // This method sets the direction of the health circle.\n /// // Clockwise for the Player, Counter Clockwise for the opponent.\n /// void SetHealthDirection(GameObject target)\n /// {\n /// if (target.tag == \"Player\")\n /// {\n /// healthCircle.fillClockwise = true;\n /// }\n /// else if (target.tag == \"Opponent\")\n /// {\n /// healthCircle.fillClockwise = false;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public bool fillClockwise { get { return m_FillClockwise; } set { if (SetPropertyUtility.SetStruct(ref m_FillClockwise, value)) SetVerticesDirty(); } }\n\n /// Controls the origin point of the Fill process. Value means different things with each fill method.\n [SerializeField] private int m_FillOrigin;\n\n /// <summary>\n /// Controls the origin point of the Fill process. Value means different things with each fill method.\n /// </summary>\n /// <remarks>\n /// You should cast to the appropriate origin type: Image.OriginHorizontal, Image.OriginVertical, Image.Origin90, Image.Origin180 or Image.Origin360 depending on the Image.Fillmethod.\n /// Note: This will only have any effect if the Image.type is set to Image.Type.Filled.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using UnityEngine.UI;\n /// using System.Collections;\n ///\n /// [RequireComponent(typeof(Image))]\n /// public class ImageOriginCycle : MonoBehaviour\n /// {\n /// void OnEnable()\n /// {\n /// Image image = GetComponent<Image>();\n /// string fillOriginName = \"\";\n ///\n /// switch ((Image.FillMethod)image.fillMethod)\n /// {\n /// case Image.FillMethod.Horizontal:\n /// fillOriginName = ((Image.OriginHorizontal)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Vertical:\n /// fillOriginName = ((Image.OriginVertical)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial90:\n ///\n /// fillOriginName = ((Image.Origin90)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial180:\n ///\n /// fillOriginName = ((Image.Origin180)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial360:\n /// fillOriginName = ((Image.Origin360)image.fillOrigin).ToString();\n /// break;\n /// }\n /// Debug.Log(string.Format(\"{0} is using {1} fill method with the origin on {2}\", name, image.fillMethod, fillOriginName));\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public int fillOrigin { get { return m_FillOrigin; } set { if (SetPropertyUtility.SetStruct(ref m_FillOrigin, value)) SetVerticesDirty(); } }\n\n // Not serialized until we support read-enabled sprites better.\n private float m_AlphaHitTestMinimumThreshold = 0;\n\n // Whether this is being tracked for Atlas Binding.\n private bool m_Tracked = false;\n\n [Obsolete(\"eventAlphaThreshold has been deprecated. Use eventMinimumAlphaThreshold instead (UnityUpgradable) -> alphaHitTestMinimumThreshold\")]\n\n /// <summary>\n /// Obsolete. You should use UI.Image.alphaHitTestMinimumThreshold instead.\n /// The alpha threshold specifies the minimum alpha a pixel must have for the event to considered a \"hit\" on the Image.\n /// </summary>\n public float eventAlphaThreshold { get { return 1 - alphaHitTestMinimumThreshold; } set { alphaHitTestMinimumThreshold = 1 - value; } }\n\n /// <summary>\n /// The alpha threshold specifies the minimum alpha a pixel must have for the event to considered a \"hit\" on the Image.\n /// </summary>\n /// <remarks>\n /// Alpha values less than the threshold will cause raycast events to pass through the Image. An value of 1 would cause only fully opaque pixels to register raycast events on the Image. The alpha tested is retrieved from the image sprite only, while the alpha of the Image [[UI.Graphic.color]] is disregarded.\n ///\n /// alphaHitTestMinimumThreshold defaults to 0; all raycast events inside the Image rectangle are considered a hit. In order for greater than 0 to values to work, the sprite used by the Image must have readable pixels. This can be achieved by enabling Read/Write enabled in the advanced Texture Import Settings for the sprite and disabling atlassing for the sprite.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class ExampleClass : MonoBehaviour\n /// {\n /// public Image theButton;\n ///\n /// // Use this for initialization\n /// void Start()\n /// {\n /// theButton.alphaHitTestMinimumThreshold = 0.5f;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public float alphaHitTestMinimumThreshold { get { return m_AlphaHitTestMinimumThreshold; }\n set\n {\n if (sprite != null && (GraphicsFormatUtility.IsCrunchFormat(sprite.texture.format) || !sprite.texture.isReadable))\n throw new InvalidOperationException(\"alphaHitTestMinimumThreshold should not be modified on a texture not readeable or not using Crunch Compression.\");\n\n m_AlphaHitTestMinimumThreshold = value;\n }\n }\n\n /// Controls whether or not to use the generated mesh from the sprite importer.\n [SerializeField] private bool m_UseSpriteMesh;\n\n /// <summary>\n /// Allows you to specify whether the UI Image should be displayed using the mesh generated by the TextureImporter, or by a simple quad mesh.\n /// </summary>\n /// <remarks>\n /// When this property is set to false, the UI Image uses a simple quad. When set to true, the UI Image uses the sprite mesh generated by the [[TextureImporter]]. You should set this to true if you want to use a tightly fitted sprite mesh based on the alpha values in your image.\n /// Note: If the texture importer's SpriteMeshType property is set to SpriteMeshType.FullRect, it will only generate a quad, and not a tightly fitted sprite mesh, which means this UI image will be drawn using a quad regardless of the value of this property. Therefore, when enabling this property to use a tightly fitted sprite mesh, you must also ensure the texture importer's SpriteMeshType property is set to Tight.\n /// </remarks>\n public bool useSpriteMesh { get { return m_UseSpriteMesh; } set { if (SetPropertyUtility.SetStruct(ref m_UseSpriteMesh, value)) SetVerticesDirty(); } }\n\n\n protected Image()\n {\n useLegacyMeshGeneration = false;\n }\n\n /// <summary>\n /// Cache of the default Canvas Ericsson Texture Compression 1 (ETC1) and alpha Material.\n /// </summary>\n /// <remarks>\n /// Stores the ETC1 supported Canvas Material that is returned from GetETC1SupportedCanvasMaterial().\n /// Note: Always specify the UI/DefaultETC1 Shader in the Always Included Shader list, to use the ETC1 and alpha Material.\n /// </remarks>\n static public Material defaultETC1GraphicMaterial\n {\n get\n {\n if (s_ETC1DefaultUI == null)\n s_ETC1DefaultUI = Canvas.GetETC1SupportedCanvasMaterial();\n return s_ETC1DefaultUI;\n }\n }\n\n /// <summary>\n /// Image's texture comes from the UnityEngine.Image.\n /// </summary>\n public override Texture mainTexture\n {\n get\n {\n if (activeSprite == null)\n {\n if (material != null && material.mainTexture != null)\n {\n return material.mainTexture;\n }\n return s_WhiteTexture;\n }\n\n return activeSprite.texture;\n }\n }\n\n /// <summary>\n /// Whether the Sprite of the image has a border to work with.\n /// </summary>\n\n public bool hasBorder\n {\n get\n {\n if (activeSprite != null)\n {\n Vector4 v = activeSprite.border;\n return v.sqrMagnitude > 0f;\n }\n return false;\n }\n }\n\n\n [SerializeField]\n private float m_PixelsPerUnitMultiplier = 1.0f;\n\n /// <summary>\n /// Pixel per unit modifier to change how sliced sprites are generated.\n /// </summary>\n public float pixelsPerUnitMultiplier\n {\n get { return m_PixelsPerUnitMultiplier; }\n set\n {\n m_PixelsPerUnitMultiplier = Mathf.Max(0.01f, value);\n SetVerticesDirty();\n }\n }\n\n // case 1066689 cache referencePixelsPerUnit when canvas parent is disabled;\n private float m_CachedReferencePixelsPerUnit = 100;\n\n public float pixelsPerUnit\n {\n get\n {\n float spritePixelsPerUnit = 100;\n if (activeSprite)\n spritePixelsPerUnit = activeSprite.pixelsPerUnit;\n\n if (canvas)\n m_CachedReferencePixelsPerUnit = canvas.referencePixelsPerUnit;\n\n return spritePixelsPerUnit / m_CachedReferencePixelsPerUnit;\n }\n }\n\n protected float multipliedPixelsPerUnit\n {\n get { return pixelsPerUnit * m_PixelsPerUnitMultiplier; }\n }\n\n /// <summary>\n /// The specified Material used by this Image. The default Material is used instead if one wasn't specified.\n /// </summary>\n public override Material material\n {\n get\n {\n if (m_Material != null)\n return m_Material;\n\n //Edit and Runtime should use Split Alpha Shader if EditorSettings.spritePackerMode = Sprite Atlas V2\n#if UNITY_EDITOR\n if ((Application.isPlaying || EditorSettings.spritePackerMode == SpritePackerMode.SpriteAtlasV2) &&\n activeSprite && activeSprite.associatedAlphaSplitTexture != null)\n {\n return defaultETC1GraphicMaterial;\n }\n#else\n\n if (activeSprite && activeSprite.associatedAlphaSplitTexture != null)\n return defaultETC1GraphicMaterial;\n#endif\n\n return defaultMaterial;\n }\n\n set\n {\n base.material = value;\n }\n }\n\n /// <summary>\n /// See ISerializationCallbackReceiver.\n /// </summary>\n public virtual void OnBeforeSerialize() {}\n\n /// <summary>\n /// See ISerializationCallbackReceiver.\n /// </summary>\n public virtual void OnAfterDeserialize()\n {\n if (m_FillOrigin < 0)\n m_FillOrigin = 0;\n else if (m_FillMethod == FillMethod.Horizontal && m_FillOrigin > 1)\n m_FillOrigin = 0;\n else if (m_FillMethod == FillMethod.Vertical && m_FillOrigin > 1)\n m_FillOrigin = 0;\n else if (m_FillOrigin > 3)\n m_FillOrigin = 0;\n\n m_FillAmount = Mathf.Clamp(m_FillAmount, 0f, 1f);\n }\n\n private void PreserveSpriteAspectRatio(ref Rect rect, Vector2 spriteSize)\n {\n var spriteRatio = spriteSize.x / spriteSize.y;\n var rectRatio = rect.width / rect.height;\n\n if (spriteRatio > rectRatio)\n {\n var oldHeight = rect.height;\n rect.height = rect.width * (1.0f / spriteRatio);\n rect.y += (oldHeight - rect.height) * rectTransform.pivot.y;\n }\n else\n {\n var oldWidth = rect.width;\n rect.width = rect.height * spriteRatio;\n rect.x += (oldWidth - rect.width) * rectTransform.pivot.x;\n }\n }\n\n /// Image's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top.\n private Vector4 GetDrawingDimensions(bool shouldPreserveAspect)\n {\n var padding = activeSprite == null ? Vector4.zero : Sprites.DataUtility.GetPadding(activeSprite);\n var size = activeSprite == null ? Vector2.zero : new Vector2(activeSprite.rect.width, activeSprite.rect.height);\n\n Rect r = GetPixelAdjustedRect();\n // Debug.Log(string.Format(\"r:{2}, size:{0}, padding:{1}\", size, padding, r));\n\n int spriteW = Mathf.RoundToInt(size.x);\n int spriteH = Mathf.RoundToInt(size.y);\n\n var v = new Vector4(\n padding.x / spriteW,\n padding.y / spriteH,\n (spriteW - padding.z) / spriteW,\n (spriteH - padding.w) / spriteH);\n\n if (shouldPreserveAspect && size.sqrMagnitude > 0.0f)\n {\n PreserveSpriteAspectRatio(ref r, size);\n }\n\n v = new Vector4(\n r.x + r.width * v.x,\n r.y + r.height * v.y,\n r.x + r.width * v.z,\n r.y + r.height * v.w\n );\n\n return v;\n }\n\n /// <summary>\n /// Adjusts the image size to make it pixel-perfect.\n /// </summary>\n /// <remarks>\n /// This means setting the Images RectTransform.sizeDelta to be equal to the Sprite dimensions.\n /// </remarks>\n public override void SetNativeSize()\n {\n if (activeSprite != null)\n {\n float w = activeSprite.rect.width / pixelsPerUnit;\n float h = activeSprite.rect.height / pixelsPerUnit;\n rectTransform.anchorMax = rectTransform.anchorMin;\n rectTransform.sizeDelta = new Vector2(w, h);\n SetAllDirty();\n }\n }\n\n /// <summary>\n /// Update the UI renderer mesh.\n /// </summary>\n protected override void OnPopulateMesh(VertexHelper toFill)\n {\n if (activeSprite == null)\n {\n base.OnPopulateMesh(toFill);\n return;\n }\n\n switch (type)\n {\n case Type.Simple:\n if (!useSpriteMesh)\n GenerateSimpleSprite(toFill, m_PreserveAspect);\n else\n GenerateSprite(toFill, m_PreserveAspect);\n break;\n case Type.Sliced:\n GenerateSlicedSprite(toFill);\n break;\n case Type.Tiled:\n GenerateTiledSprite(toFill);\n break;\n case Type.Filled:\n GenerateFilledSprite(toFill, m_PreserveAspect);\n break;\n }\n }\n\n private void TrackSprite()\n {\n if (activeSprite != null && activeSprite.texture == null)\n {\n TrackImage(this);\n m_Tracked = true;\n }\n }\n\n protected override void OnEnable()\n {\n base.OnEnable();\n TrackSprite();\n }\n\n protected override void OnDisable()\n {\n base.OnDisable();\n\n if (m_Tracked)\n UnTrackImage(this);\n }\n\n /// <summary>\n /// Update the renderer's material.\n /// </summary>\n\n protected override void UpdateMaterial()\n {\n base.UpdateMaterial();\n\n // check if this sprite has an associated alpha texture (generated when splitting RGBA = RGB + A as two textures without alpha)\n\n if (activeSprite == null)\n {\n canvasRenderer.SetAlphaTexture(null);\n return;\n }\n\n Texture2D alphaTex = activeSprite.associatedAlphaSplitTexture;\n\n if (alphaTex != null)\n {\n canvasRenderer.SetAlphaTexture(alphaTex);\n }\n }\n\n protected override void OnCanvasHierarchyChanged()\n {\n base.OnCanvasHierarchyChanged();\n if (canvas == null)\n {\n m_CachedReferencePixelsPerUnit = 100;\n }\n else if (canvas.referencePixelsPerUnit != m_CachedReferencePixelsPerUnit)\n {\n m_CachedReferencePixelsPerUnit = canvas.referencePixelsPerUnit;\n if (type == Type.Sliced || type == Type.Tiled)\n {\n SetVerticesDirty();\n SetLayoutDirty();\n }\n }\n }\n\n /// <summary>\n /// Generate vertices for a simple Image.\n /// </summary>\n void GenerateSimpleSprite(VertexHelper vh, bool lPreserveAspect)\n {\n Vector4 v = GetDrawingDimensions(lPreserveAspect);\n var uv = (activeSprite != null) ? Sprites.DataUtility.GetOuterUV(activeSprite) : Vector4.zero;\n\n var color32 = color;\n vh.Clear();\n vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));\n vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));\n vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));\n vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));\n\n vh.AddTriangle(0, 1, 2);\n vh.AddTriangle(2, 3, 0);\n }\n\n private void GenerateSprite(VertexHelper vh, bool lPreserveAspect)\n {\n var spriteSize = new Vector2(activeSprite.rect.width, activeSprite.rect.height);\n\n // Covert sprite pivot into normalized space.\n var spritePivot = activeSprite.pivot / spriteSize;\n var rectPivot = rectTransform.pivot;\n Rect r = GetPixelAdjustedRect();\n\n if (lPreserveAspect & spriteSize.sqrMagnitude > 0.0f)\n {\n PreserveSpriteAspectRatio(ref r, spriteSize);\n }\n\n var drawingSize = new Vector2(r.width, r.height);\n var spriteBoundSize = activeSprite.bounds.size;\n\n // Calculate the drawing offset based on the difference between the two pivots.\n var drawOffset = (rectPivot - spritePivot) * drawingSize;\n\n var color32 = color;\n vh.Clear();\n\n Vector2[] vertices = activeSprite.vertices;\n Vector2[] uvs = activeSprite.uv;\n for (int i = 0; i < vertices.Length; ++i)\n {\n vh.AddVert(new Vector3((vertices[i].x / spriteBoundSize.x) * drawingSize.x - drawOffset.x, (vertices[i].y / spriteBoundSize.y) * drawingSize.y - drawOffset.y), color32, new Vector2(uvs[i].x, uvs[i].y));\n }\n\n UInt16[] triangles = activeSprite.triangles;\n for (int i = 0; i < triangles.Length; i += 3)\n {\n vh.AddTriangle(triangles[i + 0], triangles[i + 1], triangles[i + 2]);\n }\n }\n\n static readonly Vector2[] s_VertScratch = new Vector2[4];\n static readonly Vector2[] s_UVScratch = new Vector2[4];\n\n /// <summary>\n /// Generate vertices for a 9-sliced Image.\n /// </summary>\n private void GenerateSlicedSprite(VertexHelper toFill)\n {\n if (!hasBorder)\n {\n GenerateSimpleSprite(toFill, false);\n return;\n }\n\n Vector4 outer, inner, padding, border;\n\n if (activeSprite != null)\n {\n outer = Sprites.DataUtility.GetOuterUV(activeSprite);\n inner = Sprites.DataUtility.GetInnerUV(activeSprite);\n padding = Sprites.DataUtility.GetPadding(activeSprite);\n border = activeSprite.border;\n }\n else\n {\n outer = Vector4.zero;\n inner = Vector4.zero;\n padding = Vector4.zero;\n border = Vector4.zero;\n }\n\n Rect rect = GetPixelAdjustedRect();\n\n Vector4 adjustedBorders = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);\n padding = padding / multipliedPixelsPerUnit;\n\n s_VertScratch[0] = new Vector2(padding.x, padding.y);\n s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);\n\n s_VertScratch[1].x = adjustedBorders.x;\n s_VertScratch[1].y = adjustedBorders.y;\n\n s_VertScratch[2].x = rect.width - adjustedBorders.z;\n s_VertScratch[2].y = rect.height - adjustedBorders.w;\n\n for (int i = 0; i < 4; ++i)\n {\n s_VertScratch[i].x += rect.x;\n s_VertScratch[i].y += rect.y;\n }\n\n s_UVScratch[0] = new Vector2(outer.x, outer.y);\n s_UVScratch[1] = new Vector2(inner.x, inner.y);\n s_UVScratch[2] = new Vector2(inner.z, inner.w);\n s_UVScratch[3] = new Vector2(outer.z, outer.w);\n\n toFill.Clear();\n\n for (int x = 0; x < 3; ++x)\n {\n int x2 = x + 1;\n\n for (int y = 0; y < 3; ++y)\n {\n if (!m_FillCenter && x == 1 && y == 1)\n continue;\n\n int y2 = y + 1;\n\n\n AddQuad(toFill,\n new Vector2(s_VertScratch[x].x, s_VertScratch[y].y),\n new Vector2(s_VertScratch[x2].x, s_VertScratch[y2].y),\n color,\n new Vector2(s_UVScratch[x].x, s_UVScratch[y].y),\n new Vector2(s_UVScratch[x2].x, s_UVScratch[y2].y));\n }\n }\n }\n\n /// <summary>\n /// Generate vertices for a tiled Image.\n /// </summary>\n\n void GenerateTiledSprite(VertexHelper toFill)\n {\n Vector4 outer, inner, border;\n Vector2 spriteSize;\n\n if (activeSprite != null)\n {\n outer = Sprites.DataUtility.GetOuterUV(activeSprite);\n inner = Sprites.DataUtility.GetInnerUV(activeSprite);\n border = activeSprite.border;\n spriteSize = activeSprite.rect.size;\n }\n else\n {\n outer = Vector4.zero;\n inner = Vector4.zero;\n border = Vector4.zero;\n spriteSize = Vector2.one * 100;\n }\n\n Rect rect = GetPixelAdjustedRect();\n float tileWidth = (spriteSize.x - border.x - border.z) / multipliedPixelsPerUnit;\n float tileHeight = (spriteSize.y - border.y - border.w) / multipliedPixelsPerUnit;\n\n border = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);\n\n var uvMin = new Vector2(inner.x, inner.y);\n var uvMax = new Vector2(inner.z, inner.w);\n\n // Min to max max range for tiled region in coordinates relative to lower left corner.\n float xMin = border.x;\n float xMax = rect.width - border.z;\n float yMin = border.y;\n float yMax = rect.height - border.w;\n\n toFill.Clear();\n var clipped = uvMax;\n\n // if either width is zero we cant tile so just assume it was the full width.\n if (tileWidth <= 0)\n tileWidth = xMax - xMin;\n\n if (tileHeight <= 0)\n tileHeight = yMax - yMin;\n\n if (activeSprite != null && (hasBorder || activeSprite.packed || activeSprite.texture != null && activeSprite.texture.wrapMode != TextureWrapMode.Repeat))\n {\n // Sprite has border, or is not in repeat mode, or cannot be repeated because of packing.\n // We cannot use texture tiling so we will generate a mesh of quads to tile the texture.\n\n // Evaluate how many vertices we will generate. Limit this number to something sane,\n // especially since meshes can not have more than 65000 vertices.\n\n long nTilesW = 0;\n long nTilesH = 0;\n if (m_FillCenter)\n {\n nTilesW = (long)Math.Ceiling((xMax - xMin) / tileWidth);\n nTilesH = (long)Math.Ceiling((yMax - yMin) / tileHeight);\n\n double nVertices = 0;\n if (hasBorder)\n {\n nVertices = (nTilesW + 2.0) * (nTilesH + 2.0) * 4.0; // 4 vertices per tile\n }\n else\n {\n nVertices = nTilesW * nTilesH * 4.0; // 4 vertices per tile\n }\n\n if (nVertices > 65000.0)\n {\n Debug.LogError(\"Too many sprite tiles on Image \\\"\" + name + \"\\\". The tile size will be increased. To remove the limit on the number of tiles, set the Wrap mode to Repeat in the Image Import Settings\", this);\n\n double maxTiles = 65000.0 / 4.0; // Max number of vertices is 65000; 4 vertices per tile.\n double imageRatio;\n if (hasBorder)\n {\n imageRatio = (nTilesW + 2.0) / (nTilesH + 2.0);\n }\n else\n {\n imageRatio = (double)nTilesW / nTilesH;\n }\n\n double targetTilesW = Math.Sqrt(maxTiles / imageRatio);\n double targetTilesH = targetTilesW * imageRatio;\n if (hasBorder)\n {\n targetTilesW -= 2;\n targetTilesH -= 2;\n }\n\n nTilesW = (long)Math.Floor(targetTilesW);\n nTilesH = (long)Math.Floor(targetTilesH);\n tileWidth = (xMax - xMin) / nTilesW;\n tileHeight = (yMax - yMin) / nTilesH;\n }\n }\n else\n {\n if (hasBorder)\n {\n // Texture on the border is repeated only in one direction.\n nTilesW = (long)Math.Ceiling((xMax - xMin) / tileWidth);\n nTilesH = (long)Math.Ceiling((yMax - yMin) / tileHeight);\n double nVertices = (nTilesH + nTilesW + 2.0 /*corners*/) * 2.0 /*sides*/ * 4.0 /*vertices per tile*/;\n if (nVertices > 65000.0)\n {\n Debug.LogError(\"Too many sprite tiles on Image \\\"\" + name + \"\\\". The tile size will be increased. To remove the limit on the number of tiles, set the Wrap mode to Repeat in the Image Import Settings\", this);\n\n double maxTiles = 65000.0 / 4.0; // Max number of vertices is 65000; 4 vertices per tile.\n double imageRatio = (double)nTilesW / nTilesH;\n double targetTilesW = (maxTiles - 4 /*corners*/) / (2 * (1.0 + imageRatio));\n double targetTilesH = targetTilesW * imageRatio;\n\n nTilesW = (long)Math.Floor(targetTilesW);\n nTilesH = (long)Math.Floor(targetTilesH);\n tileWidth = (xMax - xMin) / nTilesW;\n tileHeight = (yMax - yMin) / nTilesH;\n }\n }\n else\n {\n nTilesH = nTilesW = 0;\n }\n }\n\n if (m_FillCenter)\n {\n // TODO: we could share vertices between quads. If vertex sharing is implemented. update the computation for the number of vertices accordingly.\n for (long j = 0; j < nTilesH; j++)\n {\n float y1 = yMin + j * tileHeight;\n float y2 = yMin + (j + 1) * tileHeight;\n if (y2 > yMax)\n {\n clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);\n y2 = yMax;\n }\n clipped.x = uvMax.x;\n for (long i = 0; i < nTilesW; i++)\n {\n float x1 = xMin + i * tileWidth;\n float x2 = xMin + (i + 1) * tileWidth;\n if (x2 > xMax)\n {\n clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);\n x2 = xMax;\n }\n AddQuad(toFill, new Vector2(x1, y1) + rect.position, new Vector2(x2, y2) + rect.position, color, uvMin, clipped);\n }\n }\n }\n if (hasBorder)\n {\n clipped = uvMax;\n for (long j = 0; j < nTilesH; j++)\n {\n float y1 = yMin + j * tileHeight;\n float y2 = yMin + (j + 1) * tileHeight;\n if (y2 > yMax)\n {\n clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);\n y2 = yMax;\n }\n AddQuad(toFill,\n new Vector2(0, y1) + rect.position,\n new Vector2(xMin, y2) + rect.position,\n color,\n new Vector2(outer.x, uvMin.y),\n new Vector2(uvMin.x, clipped.y));\n AddQuad(toFill,\n new Vector2(xMax, y1) + rect.position,\n new Vector2(rect.width, y2) + rect.position,\n color,\n new Vector2(uvMax.x, uvMin.y),\n new Vector2(outer.z, clipped.y));\n }\n\n // Bottom and top tiled border\n clipped = uvMax;\n for (long i = 0; i < nTilesW; i++)\n {\n float x1 = xMin + i * tileWidth;\n float x2 = xMin + (i + 1) * tileWidth;\n if (x2 > xMax)\n {\n clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);\n x2 = xMax;\n }\n AddQuad(toFill,\n new Vector2(x1, 0) + rect.position,\n new Vector2(x2, yMin) + rect.position,\n color,\n new Vector2(uvMin.x, outer.y),\n new Vector2(clipped.x, uvMin.y));\n AddQuad(toFill,\n new Vector2(x1, yMax) + rect.position,\n new Vector2(x2, rect.height) + rect.position,\n color,\n new Vector2(uvMin.x, uvMax.y),\n new Vector2(clipped.x, outer.w));\n }\n\n // Corners\n AddQuad(toFill,\n new Vector2(0, 0) + rect.position,\n new Vector2(xMin, yMin) + rect.position,\n color,\n new Vector2(outer.x, outer.y),\n new Vector2(uvMin.x, uvMin.y));\n AddQuad(toFill,\n new Vector2(xMax, 0) + rect.position,\n new Vector2(rect.width, yMin) + rect.position,\n color,\n new Vector2(uvMax.x, outer.y),\n new Vector2(outer.z, uvMin.y));\n AddQuad(toFill,\n new Vector2(0, yMax) + rect.position,\n new Vector2(xMin, rect.height) + rect.position,\n color,\n new Vector2(outer.x, uvMax.y),\n new Vector2(uvMin.x, outer.w));\n AddQuad(toFill,\n new Vector2(xMax, yMax) + rect.position,\n new Vector2(rect.width, rect.height) + rect.position,\n color,\n new Vector2(uvMax.x, uvMax.y),\n new Vector2(outer.z, outer.w));\n }\n }\n else\n {\n // Texture has no border, is in repeat mode and not packed. Use texture tiling.\n Vector2 uvScale = new Vector2((xMax - xMin) / tileWidth, (yMax - yMin) / tileHeight);\n\n if (m_FillCenter)\n {\n AddQuad(toFill, new Vector2(xMin, yMin) + rect.position, new Vector2(xMax, yMax) + rect.position, color, Vector2.Scale(uvMin, uvScale), Vector2.Scale(uvMax, uvScale));\n }\n }\n }\n\n static void AddQuad(VertexHelper vertexHelper, Vector3[] quadPositions, Color32 color, Vector3[] quadUVs)\n {\n int startIndex = vertexHelper.currentVertCount;\n\n for (int i = 0; i < 4; ++i)\n vertexHelper.AddVert(quadPositions[i], color, quadUVs[i]);\n\n vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);\n vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);\n }\n\n static void AddQuad(VertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, Color32 color, Vector2 uvMin, Vector2 uvMax)\n {\n int startIndex = vertexHelper.currentVertCount;\n\n vertexHelper.AddVert(new Vector3(posMin.x, posMin.y, 0), color, new Vector2(uvMin.x, uvMin.y));\n vertexHelper.AddVert(new Vector3(posMin.x, posMax.y, 0), color, new Vector2(uvMin.x, uvMax.y));\n vertexHelper.AddVert(new Vector3(posMax.x, posMax.y, 0), color, new Vector2(uvMax.x, uvMax.y));\n vertexHelper.AddVert(new Vector3(posMax.x, posMin.y, 0), color, new Vector2(uvMax.x, uvMin.y));\n\n vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);\n vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);\n }\n\n private Vector4 GetAdjustedBorders(Vector4 border, Rect adjustedRect)\n {\n Rect originalRect = rectTransform.rect;\n\n for (int axis = 0; axis <= 1; axis++)\n {\n float borderScaleRatio;\n\n // The adjusted rect (adjusted for pixel correctness)\n // may be slightly larger than the original rect.\n // Adjust the border to match the adjustedRect to avoid\n // small gaps between borders (case 833201).\n if (originalRect.size[axis] != 0)\n {\n borderScaleRatio = adjustedRect.size[axis] / originalRect.size[axis];\n border[axis] *= borderScaleRatio;\n border[axis + 2] *= borderScaleRatio;\n }\n\n // If the rect is smaller than the combined borders, then there's not room for the borders at their normal size.\n // In order to avoid artefacts with overlapping borders, we scale the borders down to fit.\n float combinedBorders = border[axis] + border[axis + 2];\n if (adjustedRect.size[axis] < combinedBorders && combinedBorders != 0)\n {\n borderScaleRatio = adjustedRect.size[axis] / combinedBorders;\n border[axis] *= borderScaleRatio;\n border[axis + 2] *= borderScaleRatio;\n }\n }\n return border;\n }\n\n static readonly Vector3[] s_Xy = new Vector3[4];\n static readonly Vector3[] s_Uv = new Vector3[4];\n\n /// <summary>\n /// Generate vertices for a filled Image.\n /// </summary>\n void GenerateFilledSprite(VertexHelper toFill, bool preserveAspect)\n {\n toFill.Clear();\n\n if (m_FillAmount < 0.001f)\n return;\n\n Vector4 v = GetDrawingDimensions(preserveAspect);\n Vector4 outer = activeSprite != null ? Sprites.DataUtility.GetOuterUV(activeSprite) : Vector4.zero;\n UIVertex uiv = UIVertex.simpleVert;\n uiv.color = color;\n\n float tx0 = outer.x;\n float ty0 = outer.y;\n float tx1 = outer.z;\n float ty1 = outer.w;\n\n // Horizontal and vertical filled sprites are simple -- just end the Image prematurely\n if (m_FillMethod == FillMethod.Horizontal || m_FillMethod == FillMethod.Vertical)\n {\n if (fillMethod == FillMethod.Horizontal)\n {\n float fill = (tx1 - tx0) * m_FillAmount;\n\n if (m_FillOrigin == 1)\n {\n v.x = v.z - (v.z - v.x) * m_FillAmount;\n tx0 = tx1 - fill;\n }\n else\n {\n v.z = v.x + (v.z - v.x) * m_FillAmount;\n tx1 = tx0 + fill;\n }\n }\n else if (fillMethod == FillMethod.Vertical)\n {\n float fill = (ty1 - ty0) * m_FillAmount;\n\n if (m_FillOrigin == 1)\n {\n v.y = v.w - (v.w - v.y) * m_FillAmount;\n ty0 = ty1 - fill;\n }\n else\n {\n v.w = v.y + (v.w - v.y) * m_FillAmount;\n ty1 = ty0 + fill;\n }\n }\n }\n\n s_Xy[0] = new Vector2(v.x, v.y);\n s_Xy[1] = new Vector2(v.x, v.w);\n s_Xy[2] = new Vector2(v.z, v.w);\n s_Xy[3] = new Vector2(v.z, v.y);\n\n s_Uv[0] = new Vector2(tx0, ty0);\n s_Uv[1] = new Vector2(tx0, ty1);\n s_Uv[2] = new Vector2(tx1, ty1);\n s_Uv[3] = new Vector2(tx1, ty0);\n\n {\n if (m_FillAmount < 1f && m_FillMethod != FillMethod.Horizontal && m_FillMethod != FillMethod.Vertical)\n {\n if (fillMethod == FillMethod.Radial90)\n {\n if (RadialCut(s_Xy, s_Uv, m_FillAmount, m_FillClockwise, m_FillOrigin))\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n else if (fillMethod == FillMethod.Radial180)\n {\n for (int side = 0; side < 2; ++side)\n {\n float fx0, fx1, fy0, fy1;\n int even = m_FillOrigin > 1 ? 1 : 0;\n\n if (m_FillOrigin == 0 || m_FillOrigin == 2)\n {\n fy0 = 0f;\n fy1 = 1f;\n if (side == even)\n {\n fx0 = 0f;\n fx1 = 0.5f;\n }\n else\n {\n fx0 = 0.5f;\n fx1 = 1f;\n }\n }\n else\n {\n fx0 = 0f;\n fx1 = 1f;\n if (side == even)\n {\n fy0 = 0.5f;\n fy1 = 1f;\n }\n else\n {\n fy0 = 0f;\n fy1 = 0.5f;\n }\n }\n\n s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);\n s_Xy[1].x = s_Xy[0].x;\n s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);\n s_Xy[3].x = s_Xy[2].x;\n\n s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);\n s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);\n s_Xy[2].y = s_Xy[1].y;\n s_Xy[3].y = s_Xy[0].y;\n\n s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);\n s_Uv[1].x = s_Uv[0].x;\n s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);\n s_Uv[3].x = s_Uv[2].x;\n\n s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);\n s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);\n s_Uv[2].y = s_Uv[1].y;\n s_Uv[3].y = s_Uv[0].y;\n\n float val = m_FillClockwise ? fillAmount * 2f - side : m_FillAmount * 2f - (1 - side);\n\n if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((side + m_FillOrigin + 3) % 4)))\n {\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n else if (fillMethod == FillMethod.Radial360)\n {\n for (int corner = 0; corner < 4; ++corner)\n {\n float fx0, fx1, fy0, fy1;\n\n if (corner < 2)\n {\n fx0 = 0f;\n fx1 = 0.5f;\n }\n else\n {\n fx0 = 0.5f;\n fx1 = 1f;\n }\n\n if (corner == 0 || corner == 3)\n {\n fy0 = 0f;\n fy1 = 0.5f;\n }\n else\n {\n fy0 = 0.5f;\n fy1 = 1f;\n }\n\n s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);\n s_Xy[1].x = s_Xy[0].x;\n s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);\n s_Xy[3].x = s_Xy[2].x;\n\n s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);\n s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);\n s_Xy[2].y = s_Xy[1].y;\n s_Xy[3].y = s_Xy[0].y;\n\n s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);\n s_Uv[1].x = s_Uv[0].x;\n s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);\n s_Uv[3].x = s_Uv[2].x;\n\n s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);\n s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);\n s_Uv[2].y = s_Uv[1].y;\n s_Uv[3].y = s_Uv[0].y;\n\n float val = m_FillClockwise ?\n m_FillAmount * 4f - ((corner + m_FillOrigin) % 4) :\n m_FillAmount * 4f - (3 - ((corner + m_FillOrigin) % 4));\n\n if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((corner + 2) % 4)))\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n else\n {\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n\n /// <summary>\n /// Adjust the specified quad, making it be radially filled instead.\n /// </summary>\n\n static bool RadialCut(Vector3[] xy, Vector3[] uv, float fill, bool invert, int corner)\n {\n // Nothing to fill\n if (fill < 0.001f) return false;\n\n // Even corners invert the fill direction\n if ((corner & 1) == 1) invert = !invert;\n\n // Nothing to adjust\n if (!invert && fill > 0.999f) return true;\n\n // Convert 0-1 value into 0 to 90 degrees angle in radians\n float angle = Mathf.Clamp01(fill);\n if (invert) angle = 1f - angle;\n angle *= 90f * Mathf.Deg2Rad;\n\n // Calculate the effective X and Y factors\n float cos = Mathf.Cos(angle);\n float sin = Mathf.Sin(angle);\n\n RadialCut(xy, cos, sin, invert, corner);\n RadialCut(uv, cos, sin, invert, corner);\n return true;\n }\n\n /// <summary>\n /// Adjust the specified quad, making it be radially filled instead.\n /// </summary>\n\n static void RadialCut(Vector3[] xy, float cos, float sin, bool invert, int corner)\n {\n int i0 = corner;\n int i1 = ((corner + 1) % 4);\n int i2 = ((corner + 2) % 4);\n int i3 = ((corner + 3) % 4);\n\n if ((corner & 1) == 1)\n {\n if (sin > cos)\n {\n cos /= sin;\n sin = 1f;\n\n if (invert)\n {\n xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n xy[i2].x = xy[i1].x;\n }\n }\n else if (cos > sin)\n {\n sin /= cos;\n cos = 1f;\n\n if (!invert)\n {\n xy[i2].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n xy[i3].y = xy[i2].y;\n }\n }\n else\n {\n cos = 1f;\n sin = 1f;\n }\n\n if (!invert) xy[i3].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n else xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n }\n else\n {\n if (cos > sin)\n {\n sin /= cos;\n cos = 1f;\n\n if (!invert)\n {\n xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n xy[i2].y = xy[i1].y;\n }\n }\n else if (sin > cos)\n {\n cos /= sin;\n sin = 1f;\n\n if (invert)\n {\n xy[i2].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n xy[i3].x = xy[i2].x;\n }\n }\n else\n {\n cos = 1f;\n sin = 1f;\n }\n\n if (invert) xy[i3].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n else xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n }\n }\n\n /// <summary>\n /// See ILayoutElement.CalculateLayoutInputHorizontal.\n /// </summary>\n public virtual void CalculateLayoutInputHorizontal() {}\n\n /// <summary>\n /// See ILayoutElement.CalculateLayoutInputVertical.\n /// </summary>\n public virtual void CalculateLayoutInputVertical() {}\n\n /// <summary>\n /// See ILayoutElement.minWidth.\n /// </summary>\n public virtual float minWidth { get { return 0; } }\n\n /// <summary>\n /// If there is a sprite being rendered returns the size of that sprite.\n /// In the case of a slided or tiled sprite will return the calculated minimum size possible\n /// </summary>\n public virtual float preferredWidth\n {\n get\n {\n if (activeSprite == null)\n return 0;\n if (type == Type.Sliced || type == Type.Tiled)\n return Sprites.DataUtility.GetMinSize(activeSprite).x / pixelsPerUnit;\n return activeSprite.rect.size.x / pixelsPerUnit;\n }\n }\n\n /// <summary>\n /// See ILayoutElement.flexibleWidth.\n /// </summary>\n public virtual float flexibleWidth { get { return -1; } }\n\n /// <summary>\n /// See ILayoutElement.minHeight.\n /// </summary>\n public virtual float minHeight { get { return 0; } }\n\n /// <summary>\n /// If there is a sprite being rendered returns the size of that sprite.\n /// In the case of a slided or tiled sprite will return the calculated minimum size possible\n /// </summary>\n public virtual float preferredHeight\n {\n get\n {\n if (activeSprite == null)\n return 0;\n if (type == Type.Sliced || type == Type.Tiled)\n return Sprites.DataUtility.GetMinSize(activeSprite).y / pixelsPerUnit;\n return activeSprite.rect.size.y / pixelsPerUnit;\n }\n }\n\n /// <summary>\n /// See ILayoutElement.flexibleHeight.\n /// </summary>\n public virtual float flexibleHeight { get { return -1; } }\n\n /// <summary>\n /// See ILayoutElement.layoutPriority.\n /// </summary>\n public virtual int layoutPriority { get { return 0; } }\n\n /// <summary>\n /// Calculate if the ray location for this image is a valid hit location. Takes into account a Alpha test threshold.\n /// </summary>\n /// <param name=\"screenPoint\">The screen point to check against</param>\n /// <param name=\"eventCamera\">The camera in which to use to calculate the coordinating position</param>\n /// <returns>If the location is a valid hit or not.</returns>\n /// <remarks> Also see See:ICanvasRaycastFilter.</remarks>\n public virtual bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)\n {\n if (alphaHitTestMinimumThreshold <= 0)\n return true;\n\n if (alphaHitTestMinimumThreshold > 1)\n return false;\n\n if (activeSprite == null)\n return true;\n\n Vector2 local;\n if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out local))\n return false;\n\n Rect rect = GetPixelAdjustedRect();\n\n if (m_PreserveAspect)\n PreserveSpriteAspectRatio(ref rect, new Vector2(activeSprite.texture.width, activeSprite.texture.height));\n\n // Convert to have lower left corner as reference point.\n local.x += rectTransform.pivot.x * rect.width;\n local.y += rectTransform.pivot.y * rect.height;\n\n local = MapCoordinate(local, rect);\n\n // Convert local coordinates to texture space.\n float x = local.x / activeSprite.texture.width;\n float y = local.y / activeSprite.texture.height;\n\n try\n {\n return activeSprite.texture.GetPixelBilinear(x, y).a >= alphaHitTestMinimumThreshold;\n }\n catch (UnityException e)\n {\n Debug.LogError(\"Using alphaHitTestMinimumThreshold greater than 0 on Image whose sprite texture cannot be read. \" + e.Message + \" Also make sure to disable sprite packing for this sprite.\", this);\n return true;\n }\n }\n\n private Vector2 MapCoordinate(Vector2 local, Rect rect)\n {\n Rect spriteRect = activeSprite.rect;\n if (type == Type.Simple || type == Type.Filled)\n return new Vector2(spriteRect.position.x + local.x * spriteRect.width / rect.width, spriteRect.position.y + local.y * spriteRect.height / rect.height);\n\n Vector4 border = activeSprite.border;\n Vector4 adjustedBorder = GetAdjustedBorders(border / pixelsPerUnit, rect);\n\n for (int i = 0; i < 2; i++)\n {\n if (local[i] <= adjustedBorder[i])\n continue;\n\n if (rect.size[i] - local[i] <= adjustedBorder[i + 2])\n {\n local[i] -= (rect.size[i] - spriteRect.size[i]);\n continue;\n }\n\n if (type == Type.Sliced)\n {\n float lerp = Mathf.InverseLerp(adjustedBorder[i], rect.size[i] - adjustedBorder[i + 2], local[i]);\n local[i] = Mathf.Lerp(border[i], spriteRect.size[i] - border[i + 2], lerp);\n }\n else\n {\n local[i] -= adjustedBorder[i];\n local[i] = Mathf.Repeat(local[i], spriteRect.size[i] - border[i] - border[i + 2]);\n local[i] += border[i];\n }\n }\n\n return local + spriteRect.position;\n }\n\n // To track textureless images, which will be rebuild if sprite atlas manager registered a Sprite Atlas that will give this image new texture\n static List<Image> m_TrackedTexturelessImages = new List<Image>();\n static bool s_Initialized;\n\n static void RebuildImage(SpriteAtlas spriteAtlas)\n {\n for (var i = m_TrackedTexturelessImages.Count - 1; i >= 0; i--)\n {\n var g = m_TrackedTexturelessImages[i];\n if (null != g.activeSprite && spriteAtlas.CanBindTo(g.activeSprite))\n {\n g.SetAllDirty();\n m_TrackedTexturelessImages.RemoveAt(i);\n }\n }\n }\n\n private static void TrackImage(Image g)\n {\n if (!s_Initialized)\n {\n SpriteAtlasManager.atlasRegistered += RebuildImage;\n s_Initialized = true;\n }\n\n m_TrackedTexturelessImages.Add(g);\n }\n\n private static void UnTrackImage(Image g)\n {\n m_TrackedTexturelessImages.Remove(g);\n }\n\n protected override void OnDidApplyAnimationProperties()\n {\n SetMaterialDirty();\n SetVerticesDirty();\n SetRaycastDirty();\n }\n\n#if UNITY_EDITOR\n protected override void OnValidate()\n {\n base.OnValidate();\n m_PixelsPerUnitMultiplier = Mathf.Max(0.01f, m_PixelsPerUnitMultiplier);\n }\n\n#endif\n }\n}\n"
  212. },
  213. {
  214. "Script": "Image",
  215. "Material": "None",
  216. "Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  217. "Raycast Target": "True",
  218. "Raycast Padding": "(0.00, 0.00, 0.00, 0.00)",
  219. "Maskable": "True",
  220. "On Cull State Changed": "<Unsupported Type>",
  221. "Sprite": "pngimg.com - buttons_PNG152",
  222. "Type": "Filled",
  223. "Preserve Aspect": "False",
  224. "Fill Center": "True",
  225. "Fill Method": "Radial360",
  226. "Fill Amount": "1",
  227. "Fill Clockwise": "True",
  228. "Fill Origin": "0",
  229. "Use Sprite Mesh": "False",
  230. "Pixels Per Unit Multiplier": "1"
  231. },
  232. {
  233. "Name": "Button",
  234. "Content": "using System;\nusing System.Collections;\nusing UnityEngine.Events;\nusing UnityEngine.EventSystems;\nusing UnityEngine.Serialization;\n\nnamespace UnityEngine.UI\n{\n /// <summary>\n /// A standard button that sends an event when clicked.\n /// </summary>\n [AddComponentMenu(\"UI/Button\", 30)]\n public class Button : Selectable, IPointerClickHandler, ISubmitHandler\n {\n [Serializable]\n /// <summary>\n /// Function definition for a button click event.\n /// </summary>\n public class ButtonClickedEvent : UnityEvent {}\n\n // Event delegates triggered on click.\n [FormerlySerializedAs(\"onClick\")]\n [SerializeField]\n private ButtonClickedEvent m_OnClick = new ButtonClickedEvent();\n\n protected Button()\n {}\n\n /// <summary>\n /// UnityEvent that is triggered when the button is pressed.\n /// Note: Triggered on MouseUp after MouseDown on the same object.\n /// </summary>\n ///<example>\n ///<code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using UnityEngine.UI;\n /// using System.Collections;\n ///\n /// public class ClickExample : MonoBehaviour\n /// {\n /// public Button yourButton;\n ///\n /// void Start()\n /// {\n /// Button btn = yourButton.GetComponent<Button>();\n /// btn.onClick.AddListener(TaskOnClick);\n /// }\n ///\n /// void TaskOnClick()\n /// {\n /// Debug.Log(\"You have clicked the button!\");\n /// }\n /// }\n /// ]]>\n ///</code>\n ///</example>\n public ButtonClickedEvent onClick\n {\n get { return m_OnClick; }\n set { m_OnClick = value; }\n }\n\n private void Press()\n {\n if (!IsActive() || !IsInteractable())\n return;\n\n UISystemProfilerApi.AddMarker(\"Button.onClick\", this);\n m_OnClick.Invoke();\n }\n\n /// <summary>\n /// Call all registered IPointerClickHandlers.\n /// Register button presses using the IPointerClickHandler. You can also use it to tell what type of click happened (left, right etc.).\n /// Make sure your Scene has an EventSystem.\n /// </summary>\n /// <param name=\"eventData\">Pointer Data associated with the event. Typically by the event system.</param>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// //Attatch this script to a Button GameObject\n /// using UnityEngine;\n /// using UnityEngine.EventSystems;\n ///\n /// public class Example : MonoBehaviour, IPointerClickHandler\n /// {\n /// //Detect if a click occurs\n /// public void OnPointerClick(PointerEventData pointerEventData)\n /// {\n /// //Use this to tell when the user right-clicks on the Button\n /// if (pointerEventData.button == PointerEventData.InputButton.Right)\n /// {\n /// //Output to console the clicked GameObject's name and the following message. You can replace this with your own actions for when clicking the GameObject.\n /// Debug.Log(name + \" Game Object Right Clicked!\");\n /// }\n ///\n /// //Use this to tell when the user left-clicks on the Button\n /// if (pointerEventData.button == PointerEventData.InputButton.Left)\n /// {\n /// Debug.Log(name + \" Game Object Left Clicked!\");\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n\n public virtual void OnPointerClick(PointerEventData eventData)\n {\n if (eventData.button != PointerEventData.InputButton.Left)\n return;\n\n Press();\n }\n\n /// <summary>\n /// Call all registered ISubmitHandler.\n /// </summary>\n /// <param name=\"eventData\">Associated data with the event. Typically by the event system.</param>\n /// <remarks>\n /// This detects when a Button has been selected via a \"submit\" key you specify (default is the return key).\n ///\n /// To change the submit key, either:\n ///\n /// 1. Go to Edit->Project Settings->Input.\n ///\n /// 2. Next, expand the Axes section and go to the Submit section if it exists.\n ///\n /// 3. If Submit doesn’t exist, add 1 number to the Size field. This creates a new section at the bottom. Expand the new section and change the Name field to “Submit”.\n ///\n /// 4. Change the Positive Button field to the key you want (e.g. space).\n ///\n ///\n /// Or:\n ///\n /// 1. Go to your EventSystem in your Project\n ///\n /// 2. Go to the Inspector window and change the Submit Button field to one of the sections in the Input Manager (e.g. \"Submit\"), or create your own by naming it what you like, then following the next few steps.\n ///\n /// 3. Go to Edit->Project Settings->Input to get to the Input Manager.\n ///\n /// 4. Expand the Axes section in the Inspector window. Add 1 to the number in the Size field. This creates a new section at the bottom.\n ///\n /// 5. Expand the new section and name it the same as the name you inserted in the Submit Button field in the EventSystem. Set the Positive Button field to the key you want (e.g. space)\n /// </remarks>\n\n public virtual void OnSubmit(BaseEventData eventData)\n {\n Press();\n\n // if we get set disabled during the press\n // don't run the coroutine.\n if (!IsActive() || !IsInteractable())\n return;\n\n DoStateTransition(SelectionState.Pressed, false);\n StartCoroutine(OnFinishSubmit());\n }\n\n private IEnumerator OnFinishSubmit()\n {\n var fadeTime = colors.fadeDuration;\n var elapsedTime = 0f;\n\n while (elapsedTime < fadeTime)\n {\n elapsedTime += Time.unscaledDeltaTime;\n yield return null;\n }\n\n DoStateTransition(currentSelectionState, false);\n }\n }\n}\n"
  235. },
  236. {
  237. "Script": "Button",
  238. "Navigation": "<Unsupported Type>",
  239. "Transition": "ColorTint",
  240. "Colors": "<Unsupported Type>",
  241. "Sprite State": "<Unsupported Type>",
  242. "Animation Triggers": "<Unsupported Type>",
  243. "Interactable": "True",
  244. "Target Graphic": "Record Button",
  245. "On Click": "<Unsupported Type>"
  246. }
  247. ],
  248. "Children": [
  249. {
  250. "Name": "Text (TMP)",
  251. "Components": [
  252. {
  253. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  254. "Local Position": "(-2.00, 0.00, 0.00)",
  255. "Local Scale": "(1.00, 1.00, 1.00)",
  256. "Constrain Proportions Scale": "False",
  257. "Anchor Min": "(0.00, 0.00)",
  258. "Anchor Max": "(1.00, 1.00)",
  259. "Anchored Position": "(-2.00, 0.00)",
  260. "Size Delta": "(0.00, 0.00)",
  261. "Pivot": "(0.50, 0.50)"
  262. },
  263. {
  264. "Cull Transparent Mesh": "True"
  265. },
  266. {
  267. "Name": "TextMeshProUGUI",
  268. "Content": "using System;\nusing System.Collections;\nusing UnityEngine;\nusing UnityEngine.Rendering;\nusing UnityEngine.UI;\n\n#pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor.\n\n\nnamespace TMPro\n{\n [DisallowMultipleComponent]\n [RequireComponent(typeof(RectTransform))]\n [RequireComponent(typeof(CanvasRenderer))]\n [AddComponentMenu(\"UI/TextMeshPro - Text (UI)\", 11)]\n [ExecuteAlways]\n [HelpURL(\"https://docs.unity3d.com/Packages/[email protected]\")]\n public partial class TextMeshProUGUI : TMP_Text, ILayoutElement\n {\n /// <summary>\n /// Get the material that will be used for rendering.\n /// </summary>\n public override Material materialForRendering\n {\n get { return TMP_MaterialManager.GetMaterialForRendering(this, m_sharedMaterial); }\n }\n\n\n /// <summary>\n /// Determines if the size of the text container will be adjusted to fit the text object when it is first created.\n /// </summary>\n public override bool autoSizeTextContainer\n {\n get { return m_autoSizeTextContainer; }\n\n set { if (m_autoSizeTextContainer == value) return; m_autoSizeTextContainer = value; if (m_autoSizeTextContainer) { CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); SetLayoutDirty(); } }\n }\n\n\n /// <summary>\n /// Reference to the Mesh used by the text object.\n /// </summary>\n public override Mesh mesh\n {\n get { return m_mesh; }\n }\n\n\n /// <summary>\n /// Reference to the CanvasRenderer used by the text object.\n /// </summary>\n public new CanvasRenderer canvasRenderer\n {\n get\n {\n if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();\n\n return m_canvasRenderer;\n }\n }\n\n\n /// <summary>\n /// Anchor dampening prevents the anchor position from being adjusted unless the positional change exceeds about 40% of the width of the underline character. This essentially stabilizes the anchor position.\n /// </summary>\n //public bool anchorDampening\n //{\n // get { return m_anchorDampening; }\n // set { if (m_anchorDampening != value) { havePropertiesChanged = true; m_anchorDampening = value; /* ScheduleUpdate(); */ } }\n //}\n\n #if !UNITY_2019_3_OR_NEWER\n [SerializeField]\n private bool m_Maskable = true;\n #endif\n\n private bool m_isRebuildingLayout = false;\n private Coroutine m_DelayedGraphicRebuild;\n private Coroutine m_DelayedMaterialRebuild;\n\n /// <summary>\n /// Function called by Unity when the horizontal layout needs to be recalculated.\n /// </summary>\n public void CalculateLayoutInputHorizontal()\n {\n //Debug.Log(\"*** CalculateLayoutHorizontal() on Object ID: \" + GetInstanceID() + \" at frame: \" + Time.frameCount + \"***\");\n }\n\n\n /// <summary>\n /// Function called by Unity when the vertical layout needs to be recalculated.\n /// </summary>\n public void CalculateLayoutInputVertical()\n {\n //Debug.Log(\"*** CalculateLayoutInputVertical() on Object ID: \" + GetInstanceID() + \" at frame: \" + Time.frameCount + \"***\");\n }\n\n\n public override void SetVerticesDirty()\n {\n if (this == null || !this.IsActive())\n return;\n\n if (CanvasUpdateRegistry.IsRebuildingGraphics())\n return;\n\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyVertsCallback != null)\n m_OnDirtyVertsCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetLayoutDirty()\n {\n m_isPreferredWidthDirty = true;\n m_isPreferredHeightDirty = true;\n\n if (this == null || !this.IsActive())\n return;\n\n LayoutRebuilder.MarkLayoutForRebuild(this.rectTransform);\n\n m_isLayoutDirty = true;\n\n if (m_OnDirtyLayoutCallback != null)\n m_OnDirtyLayoutCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetMaterialDirty()\n {\n if (this == null || !this.IsActive())\n return;\n\n if (CanvasUpdateRegistry.IsRebuildingGraphics())\n return;\n\n m_isMaterialDirty = true;\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyMaterialCallback != null)\n m_OnDirtyMaterialCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetAllDirty()\n {\n SetLayoutDirty();\n SetVerticesDirty();\n SetMaterialDirty();\n }\n\n\n /// <summary>\n /// Delay registration of text object for graphic rebuild by one frame.\n /// </summary>\n /// <returns></returns>\n IEnumerator DelayedGraphicRebuild()\n {\n yield return null;\n\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyVertsCallback != null)\n m_OnDirtyVertsCallback();\n\n m_DelayedGraphicRebuild = null;\n }\n\n\n /// <summary>\n /// Delay registration of text object for graphic rebuild by one frame.\n /// </summary>\n /// <returns></returns>\n IEnumerator DelayedMaterialRebuild()\n {\n yield return null;\n\n m_isMaterialDirty = true;\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyMaterialCallback != null)\n m_OnDirtyMaterialCallback();\n\n m_DelayedMaterialRebuild = null;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n /// <param name=\"update\"></param>\n public override void Rebuild(CanvasUpdate update)\n {\n if (this == null) return;\n\n if (update == CanvasUpdate.Prelayout)\n {\n if (m_autoSizeTextContainer)\n {\n m_rectTransform.sizeDelta = GetPreferredValues(Mathf.Infinity, Mathf.Infinity);\n }\n }\n else if (update == CanvasUpdate.PreRender)\n {\n OnPreRenderCanvas();\n\n if (!m_isMaterialDirty) return;\n\n UpdateMaterial();\n m_isMaterialDirty = false;\n }\n }\n\n\n /// <summary>\n /// Method to keep the pivot of the sub text objects in sync with the parent pivot.\n /// </summary>\n private void UpdateSubObjectPivot()\n {\n if (m_textInfo == null) return;\n\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].SetPivotDirty();\n }\n //m_isPivotDirty = false;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n /// <param name=\"baseMaterial\"></param>\n /// <returns></returns>\n public override Material GetModifiedMaterial(Material baseMaterial)\n {\n Material mat = baseMaterial;\n\n if (m_ShouldRecalculateStencil)\n {\n var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);\n m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0;\n m_ShouldRecalculateStencil = false;\n }\n\n if (m_StencilValue > 0)\n {\n var maskMat = StencilMaterial.Add(mat, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0);\n StencilMaterial.Remove(m_MaskMaterial);\n m_MaskMaterial = maskMat;\n mat = m_MaskMaterial;\n }\n\n return mat;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n protected override void UpdateMaterial()\n {\n //Debug.Log(\"*** UpdateMaterial() ***\");\n\n //if (!this.IsActive())\n // return;\n\n if (m_sharedMaterial == null || canvasRenderer == null) return;\n\n m_canvasRenderer.materialCount = 1;\n m_canvasRenderer.SetMaterial(materialForRendering, 0);\n //m_canvasRenderer.SetTexture(materialForRendering.mainTexture);\n }\n\n\n //public override void OnRebuildRequested()\n //{\n // //Debug.Log(\"OnRebuildRequested\");\n\n // base.OnRebuildRequested();\n //}\n\n\n\n //public override bool Raycast(Vector2 sp, Camera eventCamera)\n //{\n // //Debug.Log(\"Raycast Event. ScreenPoint: \" + sp);\n // return base.Raycast(sp, eventCamera);\n //}\n\n\n // MASKING RELATED PROPERTIES\n /// <summary>\n /// Sets the masking offset from the bounds of the object\n /// </summary>\n public Vector4 maskOffset\n {\n get { return m_maskOffset; }\n set { m_maskOffset = value; UpdateMask(); m_havePropertiesChanged = true; }\n }\n\n\n //public override Material defaultMaterial\n //{\n // get { Debug.Log(\"Default Material called.\"); return m_sharedMaterial; }\n //}\n\n\n\n //protected override void OnCanvasHierarchyChanged()\n //{\n // //Debug.Log(\"OnCanvasHierarchyChanged...\");\n //}\n\n\n // IClippable implementation\n /// <summary>\n /// Method called when the state of a parent changes.\n /// </summary>\n public override void RecalculateClipping()\n {\n //Debug.Log(\"***** RecalculateClipping() *****\");\n\n base.RecalculateClipping();\n }\n\n\n // IMaskable Implementation\n /// <summary>\n /// Method called when Stencil Mask needs to be updated on this element and parents.\n /// </summary>\n // public override void RecalculateMasking()\n // {\n // //Debug.Log(\"***** RecalculateMasking() *****\");\n //\n // this.m_ShouldRecalculateStencil = true;\n // SetMaterialDirty();\n // }\n\n\n //public override void SetClipRect(Rect clipRect, bool validRect)\n //{\n // //Debug.Log(\"***** SetClipRect (\" + clipRect + \", \" + validRect + \") *****\");\n\n // base.SetClipRect(clipRect, validRect);\n //}\n\n\n /// <summary>\n /// Override of the Cull function to provide for the ability to override the culling of the text object.\n /// </summary>\n /// <param name=\"clipRect\"></param>\n /// <param name=\"validRect\"></param>\n public override void Cull(Rect clipRect, bool validRect)\n {\n // Delay culling check in the event the text layout is dirty and geometry has to be updated.\n if (m_isLayoutDirty)\n {\n TMP_UpdateManager.RegisterTextElementForCullingUpdate(this);\n m_ClipRect = clipRect;\n m_ValidRect = validRect;\n return;\n }\n\n // Get compound rect for the text object and sub text objects in local canvas space.\n Rect rect = GetCanvasSpaceClippingRect();\n\n // No point culling if geometry bounds have no width or height.\n if (rect.width == 0 || rect.height == 0)\n return;\n\n var cull = !validRect || !clipRect.Overlaps(rect, true);\n if (m_canvasRenderer.cull != cull)\n {\n m_canvasRenderer.cull = cull;\n onCullStateChanged.Invoke(cull);\n OnCullingChanged();\n\n // Update any potential sub mesh objects\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].canvasRenderer.cull = cull;\n }\n }\n }\n\n private Rect m_ClipRect;\n private bool m_ValidRect;\n\n /// <summary>\n /// Internal function to allow delay of culling until the text geometry has been updated.\n /// </summary>\n internal override void UpdateCulling()\n {\n // Get compound rect for the text object and sub text objects in local canvas space.\n Rect rect = GetCanvasSpaceClippingRect();\n\n // No point culling if geometry bounds have no width or height.\n if (rect.width == 0 || rect.height == 0)\n return;\n\n var cull = !m_ValidRect || !m_ClipRect.Overlaps(rect, true);\n if (m_canvasRenderer.cull != cull)\n {\n m_canvasRenderer.cull = cull;\n onCullStateChanged.Invoke(cull);\n OnCullingChanged();\n\n // Update any potential sub mesh objects\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].canvasRenderer.cull = cull;\n }\n }\n }\n\n\n /*\n /// <summary>\n /// Sets the mask type\n /// </summary>\n public MaskingTypes mask\n {\n get { return m_mask; }\n set { m_mask = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n\n\n /// <summary>\n /// Set the masking offset mode (as percentage or pixels)\n /// </summary>\n public MaskingOffsetMode maskOffsetMode\n {\n get { return m_maskOffsetMode; }\n set { m_maskOffsetMode = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n */\n\n\n /*\n /// <summary>\n /// Sets the softness of the mask\n /// </summary>\n public Vector2 maskSoftness\n {\n get { return m_maskSoftness; }\n set { m_maskSoftness = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n\n\n /// <summary>\n /// Allows to move / offset the mesh vertices by a set amount\n /// </summary>\n public Vector2 vertexOffset\n {\n get { return m_vertexOffset; }\n set { m_vertexOffset = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n */\n\n\n /// <summary>\n /// Function to be used to force recomputing of character padding when Shader / Material properties have been changed via script.\n /// </summary>\n public override void UpdateMeshPadding()\n {\n m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);\n m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);\n m_havePropertiesChanged = true;\n checkPaddingRequired = false;\n\n // Return if text object is not awake yet.\n if (m_textInfo == null) return;\n\n // Update sub text objects\n for (int i = 1; i < m_textInfo.materialCount; i++)\n m_subTextObjects[i].UpdateMeshPadding(m_enableExtraPadding, m_isUsingBold);\n }\n\n\n /// <summary>\n /// Tweens the CanvasRenderer color associated with this Graphic.\n /// </summary>\n /// <param name=\"targetColor\">Target color.</param>\n /// <param name=\"duration\">Tween duration.</param>\n /// <param name=\"ignoreTimeScale\">Should ignore Time.scale?</param>\n /// <param name=\"useAlpha\">Should also Tween the alpha channel?</param>\n protected override void InternalCrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha)\n {\n if (m_textInfo == null)\n return;\n\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 1; i < materialCount; i++)\n {\n m_subTextObjects[i].CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha);\n }\n }\n\n\n /// <summary>\n /// Tweens the alpha of the CanvasRenderer color associated with this Graphic.\n /// </summary>\n /// <param name=\"alpha\">Target alpha.</param>\n /// <param name=\"duration\">Duration of the tween in seconds.</param>\n /// <param name=\"ignoreTimeScale\">Should ignore Time.scale?</param>\n protected override void InternalCrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale)\n {\n if (m_textInfo == null)\n return;\n\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 1; i < materialCount; i++)\n {\n m_subTextObjects[i].CrossFadeAlpha(alpha, duration, ignoreTimeScale);\n }\n }\n\n\n /// <summary>\n /// Function to force regeneration of the text object before its normal process time. This is useful when changes to the text object properties need to be applied immediately.\n /// </summary>\n /// <param name=\"ignoreActiveState\">Ignore Active State of text objects. Inactive objects are ignored by default.</param>\n /// <param name=\"forceTextReparsing\">Force re-parsing of the text.</param>\n public override void ForceMeshUpdate(bool ignoreActiveState = false, bool forceTextReparsing = false)\n {\n m_havePropertiesChanged = true;\n m_ignoreActiveState = ignoreActiveState;\n\n // Special handling in the event the Canvas is only disabled\n if (m_canvas == null)\n m_canvas = GetComponentInParent<Canvas>();\n\n OnPreRenderCanvas();\n }\n\n\n /// <summary>\n /// Function used to evaluate the length of a text string.\n /// </summary>\n /// <param name=\"text\"></param>\n /// <returns></returns>\n public override TMP_TextInfo GetTextInfo(string text)\n {\n SetText(text);\n SetArraySizes(m_TextProcessingArray);\n\n m_renderMode = TextRenderFlags.DontRender;\n\n ComputeMarginSize();\n\n // Need to make sure we have a valid reference to a Canvas.\n if (m_canvas == null) m_canvas = this.canvas;\n\n GenerateTextMesh();\n\n m_renderMode = TextRenderFlags.Render;\n\n return this.textInfo;\n }\n\n\n /// <summary>\n /// Function to clear the geometry of the Primary and Sub Text objects.\n /// </summary>\n public override void ClearMesh()\n {\n m_canvasRenderer.SetMesh(null);\n\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n m_subTextObjects[i].canvasRenderer.SetMesh(null);\n }\n\n\n /// <summary>\n /// Event to allow users to modify the content of the text info before the text is rendered.\n /// </summary>\n public override event Action<TMP_TextInfo> OnPreRenderText;\n\n\n /// <summary>\n /// Function to update the geometry of the main and sub text objects.\n /// </summary>\n /// <param name=\"mesh\"></param>\n /// <param name=\"index\"></param>\n public override void UpdateGeometry(Mesh mesh, int index)\n {\n mesh.RecalculateBounds();\n\n if (index == 0)\n {\n m_canvasRenderer.SetMesh(mesh);\n }\n else\n {\n m_subTextObjects[index].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n /// <summary>\n /// Function to upload the updated vertex data and renderer.\n /// </summary>\n public override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)\n {\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 0; i < materialCount; i++)\n {\n Mesh mesh;\n\n if (i == 0)\n mesh = m_mesh;\n else\n {\n // Clear unused vertices\n // TODO: Causes issues when sorting geometry as last vertex data attribute get wiped out.\n //m_textInfo.meshInfo[i].ClearUnusedVertices();\n\n mesh = m_subTextObjects[i].mesh;\n }\n\n if ((flags & TMP_VertexDataUpdateFlags.Vertices) == TMP_VertexDataUpdateFlags.Vertices)\n mesh.vertices = m_textInfo.meshInfo[i].vertices;\n\n if ((flags & TMP_VertexDataUpdateFlags.Uv0) == TMP_VertexDataUpdateFlags.Uv0)\n mesh.uv = m_textInfo.meshInfo[i].uvs0;\n\n if ((flags & TMP_VertexDataUpdateFlags.Uv2) == TMP_VertexDataUpdateFlags.Uv2)\n mesh.uv2 = m_textInfo.meshInfo[i].uvs2;\n\n //if ((flags & TMP_VertexDataUpdateFlags.Uv4) == TMP_VertexDataUpdateFlags.Uv4)\n // mesh.uv4 = m_textInfo.meshInfo[i].uvs4;\n\n if ((flags & TMP_VertexDataUpdateFlags.Colors32) == TMP_VertexDataUpdateFlags.Colors32)\n mesh.colors32 = m_textInfo.meshInfo[i].colors32;\n\n mesh.RecalculateBounds();\n\n if (i == 0)\n m_canvasRenderer.SetMesh(mesh);\n else\n m_subTextObjects[i].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n /// <summary>\n /// Function to upload the updated vertex data and renderer.\n /// </summary>\n public override void UpdateVertexData()\n {\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 0; i < materialCount; i++)\n {\n Mesh mesh;\n\n if (i == 0)\n mesh = m_mesh;\n else\n {\n // Clear unused vertices\n m_textInfo.meshInfo[i].ClearUnusedVertices();\n\n mesh = m_subTextObjects[i].mesh;\n }\n\n //mesh.MarkDynamic();\n mesh.vertices = m_textInfo.meshInfo[i].vertices;\n mesh.uv = m_textInfo.meshInfo[i].uvs0;\n mesh.uv2 = m_textInfo.meshInfo[i].uvs2;\n //mesh.uv4 = m_textInfo.meshInfo[i].uvs4;\n mesh.colors32 = m_textInfo.meshInfo[i].colors32;\n\n mesh.RecalculateBounds();\n\n if (i == 0)\n m_canvasRenderer.SetMesh(mesh);\n else\n m_subTextObjects[i].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n public void UpdateFontAsset()\n {\n LoadFontAsset();\n }\n\n }\n}\n"
  269. },
  270. {
  271. "Script": "TextMeshProUGUI",
  272. "Material": "None",
  273. "Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  274. "Raycast Target": "True",
  275. "Raycast Padding": "(0.00, 0.00, 0.00, 0.00)",
  276. "Maskable": "True",
  277. "On Cull State Changed": "<Unsupported Type>",
  278. "Text": "RECORD",
  279. "Is Right To Left": "False",
  280. "Font Asset": "LiberationSans SDF",
  281. "Shared Material": "LiberationSans SDF Material",
  282. "Font Shared Materials": "<Unsupported Type>",
  283. "Font Material": "None",
  284. "Font Materials": "<Unsupported Type>",
  285. "Font Color 32": "RGBA(0.973, 0.804, 0.804, 1.000)",
  286. "Font Color": "RGBA(0.972, 0.802, 0.802, 1.000)",
  287. "Enable Vertex Gradient": "False",
  288. "Color Mode": "FourCornersGradient",
  289. "Font Color Gradient": "<Unsupported Type>",
  290. "Font Color Gradient Preset": "None",
  291. "Sprite Asset": "None",
  292. "Tint All Sprites": "False",
  293. "Style Sheet": "None",
  294. "Text Style Hash Code": "-1183493901",
  295. "Override Html Colors": "False",
  296. "Face Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  297. "Font Size": "20",
  298. "Font Size Base": "20",
  299. "Font Weight": "Regular",
  300. "Enable Auto Sizing": "False",
  301. "Font Size Min": "0",
  302. "Font Size Max": "0",
  303. "Font Style": "Normal",
  304. "Horizontal Alignment": "Center",
  305. "Vertical Alignment": "Middle",
  306. "Text Alignment": "Converted",
  307. "Character Spacing": "0",
  308. "Word Spacing": "0",
  309. "Line Spacing": "0",
  310. "Line Spacing Max": "0",
  311. "Paragraph Spacing": "0",
  312. "Char Width Max Adj": "0",
  313. "Enable Word Wrapping": "False",
  314. "Word Wrapping Ratios": "0.4",
  315. "Overflow Mode": "Overflow",
  316. "Linked Text Component": "None",
  317. "Parent Linked Component": "None",
  318. "Enable Kerning": "False",
  319. "Enable Extra Padding": "False",
  320. "Check Padding Required": "False",
  321. "Is Rich Text": "True",
  322. "Parse Ctrl Characters": "True",
  323. "Is Orthographic": "True",
  324. "Is Culling Enabled": "False",
  325. "Horizontal Mapping": "Character",
  326. "Vertical Mapping": "Character",
  327. "Uv Line Offset": "0",
  328. "Geometry Sorting Order": "Normal",
  329. "Is Text Object Scale Static": "False",
  330. "Vertex Buffer Auto Size Reduction": "False",
  331. "Use Max Visible Descender": "True",
  332. "Page To Display": "1",
  333. "Margin": "(0.00, 0.00, 0.00, 0.00)",
  334. "Is Using Legacy Animation Component": "False",
  335. "Is Volumetric Text": "False",
  336. "Has Font Asset Changed": "False",
  337. "Base Material": "None",
  338. "Mask Offset": "(0.00, 0.00, 0.00, 0.00)"
  339. }
  340. ],
  341. "Children": []
  342. }
  343. ]
  344. },
  345. {
  346. "Name": "Pause Resume Button",
  347. "Components": [
  348. {
  349. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  350. "Local Position": "(-872.00, 0.00, 0.00)",
  351. "Local Scale": "(1.00, 1.00, 1.00)",
  352. "Constrain Proportions Scale": "False",
  353. "Anchor Min": "(1.00, 0.50)",
  354. "Anchor Max": "(1.00, 0.50)",
  355. "Anchored Position": "(-1832.00, 0.00)",
  356. "Size Delta": "(160.00, 160.00)",
  357. "Pivot": "(0.50, 0.50)"
  358. },
  359. {
  360. "Cull Transparent Mesh": "True"
  361. },
  362. {
  363. "Name": "Image",
  364. "Content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n#if UNITY_EDITOR\nusing UnityEditor;\n#endif\nusing UnityEngine.Experimental.Rendering;\nusing UnityEngine.Serialization;\nusing UnityEngine.U2D;\n\nnamespace UnityEngine.UI\n{\n /// <summary>\n /// Image is a textured element in the UI hierarchy.\n /// </summary>\n\n [RequireComponent(typeof(CanvasRenderer))]\n [AddComponentMenu(\"UI/Image\", 11)]\n /// <summary>\n /// Displays a Sprite inside the UI System.\n /// </summary>\n public class Image : MaskableGraphic, ISerializationCallbackReceiver, ILayoutElement, ICanvasRaycastFilter\n {\n /// <summary>\n /// Image fill type controls how to display the image.\n /// </summary>\n public enum Type\n {\n /// <summary>\n /// Displays the full Image\n /// </summary>\n /// <remarks>\n /// This setting shows the entire image stretched across the Image's RectTransform\n /// </remarks>\n Simple,\n\n /// <summary>\n /// Displays the Image as a 9-sliced graphic.\n /// </summary>\n /// <remarks>\n /// A 9-sliced image displays a central area stretched across the image surrounded by a border comprising of 4 corners and 4 stretched edges.\n ///\n /// This has the effect of creating a resizable skinned rectangular element suitable for dialog boxes, windows, and general UI elements.\n ///\n /// Note: For this method to work properly the Sprite assigned to Image.sprite needs to have Sprite.border defined.\n /// </remarks>\n Sliced,\n\n /// <summary>\n /// Displays a sliced Sprite with its resizable sections tiled instead of stretched.\n /// </summary>\n /// <remarks>\n /// A Tiled image behaves similarly to a UI.Image.Type.Sliced|Sliced image, except that the resizable sections of the image are repeated instead of being stretched. This can be useful for detailed UI graphics that do not look good when stretched.\n ///\n /// It uses the Sprite.border value to determine how each part (border and center) should be tiled.\n ///\n /// The Image sections will repeat the corresponding section in the Sprite until the whole section is filled. The corner sections will be unaffected and will draw in the same way as a Sliced Image. The edges will repeat along their lengths. The center section will repeat across the whole central part of the Image.\n ///\n /// The Image section will repeat the corresponding section in the Sprite until the whole section is filled.\n ///\n /// Be aware that if you are tiling a Sprite with borders or a packed sprite, a mesh will be generated to create the tiles. The size of the mesh will be limited to 16250 quads; if your tiling would require more tiles, the size of the tiles will be enlarged to ensure that the number of generated quads stays below this limit.\n ///\n /// For optimum efficiency, use a Sprite with no borders and with no packing, and make sure the Sprite.texture wrap mode is set to TextureWrapMode.Repeat.These settings will prevent the generation of additional geometry.If this is not possible, limit the number of tiles in your Image.\n /// </remarks>\n Tiled,\n\n /// <summary>\n /// Displays only a portion of the Image.\n /// </summary>\n /// <remarks>\n /// A Filled Image will display a section of the Sprite, with the rest of the RectTransform left transparent. The Image.fillAmount determines how much of the Image to show, and Image.fillMethod controls the shape in which the Image will be cut.\n ///\n /// This can be used for example to display circular or linear status information such as timers, health bars, and loading bars.\n /// </remarks>\n Filled\n }\n\n /// <summary>\n /// The possible fill method types for a Filled Image.\n /// </summary>\n public enum FillMethod\n {\n /// <summary>\n /// The Image will be filled Horizontally.\n /// </summary>\n /// <remarks>\n /// The Image will be Cropped at either left or right size depending on Image.fillOriging at the Image.fillAmount\n /// </remarks>\n Horizontal,\n\n /// <summary>\n /// The Image will be filled Vertically.\n /// </summary>\n /// <remarks>\n /// The Image will be Cropped at either top or Bottom size depending on Image.fillOrigin at the Image.fillAmount\n /// </remarks>\n Vertical,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center in one of the corners.\n /// </summary>\n /// <remarks>\n /// For this method the Image.fillAmount represents an angle between 0 and 90 degrees. The Image will be cut by a line passing at the Image.fillOrigin at the specified angle.\n /// </remarks>\n Radial90,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center in one of the edges.\n /// </summary>\n /// <remarks>\n /// For this method the Image.fillAmount represents an angle between 0 and 180 degrees. The Image will be cut by a line passing at the Image.fillOrigin at the specified angle.\n /// </remarks>\n Radial180,\n\n /// <summary>\n /// The Image will be filled Radially with the radial center at the center.\n /// </summary>\n /// <remarks>\n /// or this method the Image.fillAmount represents an angle between 0 and 360 degrees. The Arc defined by the center of the Image, the Image.fillOrigin and the angle will be cut from the Image.\n /// </remarks>\n Radial360,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Horizontal.\n /// </summary>\n public enum OriginHorizontal\n {\n /// <summary>\n /// >Origin at the Left side.\n /// </summary>\n Left,\n\n /// <summary>\n /// >Origin at the Right side.\n /// </summary>\n Right,\n }\n\n\n /// <summary>\n /// Origin for the Image.FillMethod.Vertical.\n /// </summary>\n public enum OriginVertical\n {\n /// <summary>\n /// >Origin at the Bottom Edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// >Origin at the Top Edge.\n /// </summary>\n Top,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Radial90.\n /// </summary>\n public enum Origin90\n {\n /// <summary>\n /// Radial starting at the Bottom Left corner.\n /// </summary>\n BottomLeft,\n\n /// <summary>\n /// Radial starting at the Top Left corner.\n /// </summary>\n TopLeft,\n\n /// <summary>\n /// Radial starting at the Top Right corner.\n /// </summary>\n TopRight,\n\n /// <summary>\n /// Radial starting at the Bottom Right corner.\n /// </summary>\n BottomRight,\n }\n\n /// <summary>\n /// Origin for the Image.FillMethod.Radial180.\n /// </summary>\n public enum Origin180\n {\n /// <summary>\n /// Center of the radial at the center of the Bottom edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// Center of the radial at the center of the Left edge.\n /// </summary>\n Left,\n\n /// <summary>\n /// Center of the radial at the center of the Top edge.\n /// </summary>\n Top,\n\n /// <summary>\n /// Center of the radial at the center of the Right edge.\n /// </summary>\n Right,\n }\n\n /// <summary>\n /// One of the points of the Arc for the Image.FillMethod.Radial360.\n /// </summary>\n public enum Origin360\n {\n /// <summary>\n /// Arc starting at the center of the Bottom edge.\n /// </summary>\n Bottom,\n\n /// <summary>\n /// Arc starting at the center of the Right edge.\n /// </summary>\n Right,\n\n /// <summary>\n /// Arc starting at the center of the Top edge.\n /// </summary>\n Top,\n\n /// <summary>\n /// Arc starting at the center of the Left edge.\n /// </summary>\n Left,\n }\n\n static protected Material s_ETC1DefaultUI = null;\n\n [FormerlySerializedAs(\"m_Frame\")]\n [SerializeField]\n private Sprite m_Sprite;\n\n /// <summary>\n /// The sprite that is used to render this image.\n /// </summary>\n /// <remarks>\n /// This returns the source Sprite of an Image. This Sprite can also be viewed and changed in the Inspector as part of an Image component. This can also be used to change the Sprite using a script.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// //Attach this script to an Image GameObject and set its Source Image to the Sprite you would like.\n /// //Press the space key to change the Sprite. Remember to assign a second Sprite in this script's section of the Inspector.\n ///\n /// using UnityEngine;\n /// using UnityEngine.UI;\n ///\n /// public class Example : MonoBehaviour\n /// {\n /// Image m_Image;\n /// //Set this in the Inspector\n /// public Sprite m_Sprite;\n ///\n /// void Start()\n /// {\n /// //Fetch the Image from the GameObject\n /// m_Image = GetComponent<Image>();\n /// }\n ///\n /// void Update()\n /// {\n /// //Press space to change the Sprite of the Image\n /// if (Input.GetKey(KeyCode.Space))\n /// {\n /// m_Image.sprite = m_Sprite;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n\n public Sprite sprite\n {\n get { return m_Sprite; }\n set\n {\n if (m_Sprite != null)\n {\n if (m_Sprite != value)\n {\n m_SkipLayoutUpdate = m_Sprite.rect.size.Equals(value ? value.rect.size : Vector2.zero);\n m_SkipMaterialUpdate = m_Sprite.texture == (value ? value.texture : null);\n m_Sprite = value;\n\n ResetAlphaHitThresholdIfNeeded();\n SetAllDirty();\n TrackSprite();\n }\n }\n else if (value != null)\n {\n m_SkipLayoutUpdate = value.rect.size == Vector2.zero;\n m_SkipMaterialUpdate = value.texture == null;\n m_Sprite = value;\n\n ResetAlphaHitThresholdIfNeeded();\n SetAllDirty();\n TrackSprite();\n }\n\n void ResetAlphaHitThresholdIfNeeded()\n {\n if (!SpriteSupportsAlphaHitTest() && m_AlphaHitTestMinimumThreshold > 0)\n {\n Debug.LogWarning(\"Sprite was changed for one not readable or with Crunch Compression. Resetting the AlphaHitThreshold to 0.\", this);\n m_AlphaHitTestMinimumThreshold = 0;\n }\n }\n\n bool SpriteSupportsAlphaHitTest()\n {\n return m_Sprite != null && m_Sprite.texture != null && !GraphicsFormatUtility.IsCrunchFormat(m_Sprite.texture.format) && m_Sprite.texture.isReadable;\n }\n }\n }\n\n\n /// <summary>\n /// Disable all automatic sprite optimizations.\n /// </summary>\n /// <remarks>\n /// When a new Sprite is assigned update optimizations are automatically applied.\n /// </remarks>\n\n public void DisableSpriteOptimizations()\n {\n m_SkipLayoutUpdate = false;\n m_SkipMaterialUpdate = false;\n }\n\n [NonSerialized]\n private Sprite m_OverrideSprite;\n\n /// <summary>\n /// Set an override sprite to be used for rendering.\n /// </summary>\n /// <remarks>\n /// The UI.Image-overrideSprite|overrideSprite variable allows a sprite to have the\n /// sprite changed.This change happens immediately.When the changed\n /// sprite is no longer needed the sprite can be reverted back to the\n /// original version.This happens when the overrideSprite\n /// is set to /null/.\n /// </remarks>\n /// <example>\n /// Note: The script example below has two buttons. The button textures are loaded from the\n /// /Resources/ folder. (They are not used in the shown example). Two sprites are added to\n /// the example code. /Example1/ and /Example2/ are functions called by the button OnClick\n /// functions. Example1 calls overrideSprite and Example2 sets overrideSprite to null.\n /// <code>\n /// <![CDATA[\n /// using System.Collections;\n /// using System.Collections.Generic;\n /// using UnityEngine;\n /// using UnityEngine.UI;\n ///\n /// public class ExampleClass : MonoBehaviour\n /// {\n /// private Sprite sprite1;\n /// private Sprite sprite2;\n /// private Image i;\n ///\n /// public void Start()\n /// {\n /// i = GetComponent<Image>();\n /// sprite1 = Resources.Load<Sprite>(\"texture1\");\n /// sprite2 = Resources.Load<Sprite>(\"texture2\");\n ///\n /// i.sprite = sprite1;\n /// }\n ///\n /// // Called by a Button OnClick() with ExampleClass.Example1\n /// // Uses overrideSprite to make this change temporary\n /// public void Example1()\n /// {\n /// i.overrideSprite = sprite2;\n /// }\n ///\n /// // Called by a Button OnClick() with ExampleClass.Example2\n /// // Removes the overrideSprite which causes the original sprite to be used again.\n /// public void Example2()\n /// {\n /// i.overrideSprite = null;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public Sprite overrideSprite\n {\n get { return activeSprite; }\n set\n {\n if (SetPropertyUtility.SetClass(ref m_OverrideSprite, value))\n {\n SetAllDirty();\n TrackSprite();\n }\n }\n }\n\n private Sprite activeSprite { get { return m_OverrideSprite != null ? m_OverrideSprite : sprite; } }\n\n /// How the Image is drawn.\n [SerializeField] private Type m_Type = Type.Simple;\n\n /// <summary>\n /// How to display the image.\n /// </summary>\n /// <remarks>\n /// Unity can interpret an Image in various different ways depending on the intended purpose. This can be used to display:\n /// - Whole images stretched to fit the RectTransform of the Image.\n /// - A 9-sliced image useful for various decorated UI boxes and other rectangular elements.\n /// - A tiled image with sections of the sprite repeated.\n /// - As a partial image, useful for wipes, fades, timers, status bars etc.\n /// </remarks>\n public Type type { get { return m_Type; } set { if (SetPropertyUtility.SetStruct(ref m_Type, value)) SetVerticesDirty(); } }\n\n [SerializeField] private bool m_PreserveAspect = false;\n\n /// <summary>\n /// Whether this image should preserve its Sprite aspect ratio.\n /// </summary>\n public bool preserveAspect { get { return m_PreserveAspect; } set { if (SetPropertyUtility.SetStruct(ref m_PreserveAspect, value)) SetVerticesDirty(); } }\n\n [SerializeField] private bool m_FillCenter = true;\n\n /// <summary>\n /// Whether or not to render the center of a Tiled or Sliced image.\n /// </summary>\n /// <remarks>\n /// This will only have any effect if the Image.sprite has borders.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI;\n ///\n /// public class FillCenterScript : MonoBehaviour\n /// {\n /// public Image xmasCalenderDoor;\n ///\n /// // removes the center of the image to reveal the image behind it\n /// void OpenCalendarDoor()\n /// {\n /// xmasCalenderDoor.fillCenter = false;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public bool fillCenter { get { return m_FillCenter; } set { if (SetPropertyUtility.SetStruct(ref m_FillCenter, value)) SetVerticesDirty(); } }\n\n /// Filling method for filled sprites.\n [SerializeField] private FillMethod m_FillMethod = FillMethod.Radial360;\n public FillMethod fillMethod { get { return m_FillMethod; } set { if (SetPropertyUtility.SetStruct(ref m_FillMethod, value)) { SetVerticesDirty(); m_FillOrigin = 0; } } }\n\n /// Amount of the Image shown. 0-1 range with 0 being nothing shown, and 1 being the full Image.\n [Range(0, 1)]\n [SerializeField]\n private float m_FillAmount = 1.0f;\n\n /// <summary>\n /// Amount of the Image shown when the Image.type is set to Image.Type.Filled.\n /// </summary>\n /// <remarks>\n /// 0-1 range with 0 being nothing shown, and 1 being the full Image.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class Cooldown : MonoBehaviour\n /// {\n /// public Image cooldown;\n /// public bool coolingDown;\n /// public float waitTime = 30.0f;\n ///\n /// // Update is called once per frame\n /// void Update()\n /// {\n /// if (coolingDown == true)\n /// {\n /// //Reduce fill amount over 30 seconds\n /// cooldown.fillAmount -= 1.0f / waitTime * Time.deltaTime;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public float fillAmount { get { return m_FillAmount; } set { if (SetPropertyUtility.SetStruct(ref m_FillAmount, Mathf.Clamp01(value))) SetVerticesDirty(); } }\n\n /// Whether the Image should be filled clockwise (true) or counter-clockwise (false).\n [SerializeField] private bool m_FillClockwise = true;\n\n /// <summary>\n /// Whether the Image should be filled clockwise (true) or counter-clockwise (false).\n /// </summary>\n /// <remarks>\n /// This will only have any effect if the Image.type is set to Image.Type.Filled and Image.fillMethod is set to any of the Radial methods.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class FillClockwiseScript : MonoBehaviour\n /// {\n /// public Image healthCircle;\n ///\n /// // This method sets the direction of the health circle.\n /// // Clockwise for the Player, Counter Clockwise for the opponent.\n /// void SetHealthDirection(GameObject target)\n /// {\n /// if (target.tag == \"Player\")\n /// {\n /// healthCircle.fillClockwise = true;\n /// }\n /// else if (target.tag == \"Opponent\")\n /// {\n /// healthCircle.fillClockwise = false;\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public bool fillClockwise { get { return m_FillClockwise; } set { if (SetPropertyUtility.SetStruct(ref m_FillClockwise, value)) SetVerticesDirty(); } }\n\n /// Controls the origin point of the Fill process. Value means different things with each fill method.\n [SerializeField] private int m_FillOrigin;\n\n /// <summary>\n /// Controls the origin point of the Fill process. Value means different things with each fill method.\n /// </summary>\n /// <remarks>\n /// You should cast to the appropriate origin type: Image.OriginHorizontal, Image.OriginVertical, Image.Origin90, Image.Origin180 or Image.Origin360 depending on the Image.Fillmethod.\n /// Note: This will only have any effect if the Image.type is set to Image.Type.Filled.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using UnityEngine.UI;\n /// using System.Collections;\n ///\n /// [RequireComponent(typeof(Image))]\n /// public class ImageOriginCycle : MonoBehaviour\n /// {\n /// void OnEnable()\n /// {\n /// Image image = GetComponent<Image>();\n /// string fillOriginName = \"\";\n ///\n /// switch ((Image.FillMethod)image.fillMethod)\n /// {\n /// case Image.FillMethod.Horizontal:\n /// fillOriginName = ((Image.OriginHorizontal)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Vertical:\n /// fillOriginName = ((Image.OriginVertical)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial90:\n ///\n /// fillOriginName = ((Image.Origin90)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial180:\n ///\n /// fillOriginName = ((Image.Origin180)image.fillOrigin).ToString();\n /// break;\n /// case Image.FillMethod.Radial360:\n /// fillOriginName = ((Image.Origin360)image.fillOrigin).ToString();\n /// break;\n /// }\n /// Debug.Log(string.Format(\"{0} is using {1} fill method with the origin on {2}\", name, image.fillMethod, fillOriginName));\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public int fillOrigin { get { return m_FillOrigin; } set { if (SetPropertyUtility.SetStruct(ref m_FillOrigin, value)) SetVerticesDirty(); } }\n\n // Not serialized until we support read-enabled sprites better.\n private float m_AlphaHitTestMinimumThreshold = 0;\n\n // Whether this is being tracked for Atlas Binding.\n private bool m_Tracked = false;\n\n [Obsolete(\"eventAlphaThreshold has been deprecated. Use eventMinimumAlphaThreshold instead (UnityUpgradable) -> alphaHitTestMinimumThreshold\")]\n\n /// <summary>\n /// Obsolete. You should use UI.Image.alphaHitTestMinimumThreshold instead.\n /// The alpha threshold specifies the minimum alpha a pixel must have for the event to considered a \"hit\" on the Image.\n /// </summary>\n public float eventAlphaThreshold { get { return 1 - alphaHitTestMinimumThreshold; } set { alphaHitTestMinimumThreshold = 1 - value; } }\n\n /// <summary>\n /// The alpha threshold specifies the minimum alpha a pixel must have for the event to considered a \"hit\" on the Image.\n /// </summary>\n /// <remarks>\n /// Alpha values less than the threshold will cause raycast events to pass through the Image. An value of 1 would cause only fully opaque pixels to register raycast events on the Image. The alpha tested is retrieved from the image sprite only, while the alpha of the Image [[UI.Graphic.color]] is disregarded.\n ///\n /// alphaHitTestMinimumThreshold defaults to 0; all raycast events inside the Image rectangle are considered a hit. In order for greater than 0 to values to work, the sprite used by the Image must have readable pixels. This can be achieved by enabling Read/Write enabled in the advanced Texture Import Settings for the sprite and disabling atlassing for the sprite.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.UI; // Required when Using UI elements.\n ///\n /// public class ExampleClass : MonoBehaviour\n /// {\n /// public Image theButton;\n ///\n /// // Use this for initialization\n /// void Start()\n /// {\n /// theButton.alphaHitTestMinimumThreshold = 0.5f;\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public float alphaHitTestMinimumThreshold { get { return m_AlphaHitTestMinimumThreshold; }\n set\n {\n if (sprite != null && (GraphicsFormatUtility.IsCrunchFormat(sprite.texture.format) || !sprite.texture.isReadable))\n throw new InvalidOperationException(\"alphaHitTestMinimumThreshold should not be modified on a texture not readeable or not using Crunch Compression.\");\n\n m_AlphaHitTestMinimumThreshold = value;\n }\n }\n\n /// Controls whether or not to use the generated mesh from the sprite importer.\n [SerializeField] private bool m_UseSpriteMesh;\n\n /// <summary>\n /// Allows you to specify whether the UI Image should be displayed using the mesh generated by the TextureImporter, or by a simple quad mesh.\n /// </summary>\n /// <remarks>\n /// When this property is set to false, the UI Image uses a simple quad. When set to true, the UI Image uses the sprite mesh generated by the [[TextureImporter]]. You should set this to true if you want to use a tightly fitted sprite mesh based on the alpha values in your image.\n /// Note: If the texture importer's SpriteMeshType property is set to SpriteMeshType.FullRect, it will only generate a quad, and not a tightly fitted sprite mesh, which means this UI image will be drawn using a quad regardless of the value of this property. Therefore, when enabling this property to use a tightly fitted sprite mesh, you must also ensure the texture importer's SpriteMeshType property is set to Tight.\n /// </remarks>\n public bool useSpriteMesh { get { return m_UseSpriteMesh; } set { if (SetPropertyUtility.SetStruct(ref m_UseSpriteMesh, value)) SetVerticesDirty(); } }\n\n\n protected Image()\n {\n useLegacyMeshGeneration = false;\n }\n\n /// <summary>\n /// Cache of the default Canvas Ericsson Texture Compression 1 (ETC1) and alpha Material.\n /// </summary>\n /// <remarks>\n /// Stores the ETC1 supported Canvas Material that is returned from GetETC1SupportedCanvasMaterial().\n /// Note: Always specify the UI/DefaultETC1 Shader in the Always Included Shader list, to use the ETC1 and alpha Material.\n /// </remarks>\n static public Material defaultETC1GraphicMaterial\n {\n get\n {\n if (s_ETC1DefaultUI == null)\n s_ETC1DefaultUI = Canvas.GetETC1SupportedCanvasMaterial();\n return s_ETC1DefaultUI;\n }\n }\n\n /// <summary>\n /// Image's texture comes from the UnityEngine.Image.\n /// </summary>\n public override Texture mainTexture\n {\n get\n {\n if (activeSprite == null)\n {\n if (material != null && material.mainTexture != null)\n {\n return material.mainTexture;\n }\n return s_WhiteTexture;\n }\n\n return activeSprite.texture;\n }\n }\n\n /// <summary>\n /// Whether the Sprite of the image has a border to work with.\n /// </summary>\n\n public bool hasBorder\n {\n get\n {\n if (activeSprite != null)\n {\n Vector4 v = activeSprite.border;\n return v.sqrMagnitude > 0f;\n }\n return false;\n }\n }\n\n\n [SerializeField]\n private float m_PixelsPerUnitMultiplier = 1.0f;\n\n /// <summary>\n /// Pixel per unit modifier to change how sliced sprites are generated.\n /// </summary>\n public float pixelsPerUnitMultiplier\n {\n get { return m_PixelsPerUnitMultiplier; }\n set\n {\n m_PixelsPerUnitMultiplier = Mathf.Max(0.01f, value);\n SetVerticesDirty();\n }\n }\n\n // case 1066689 cache referencePixelsPerUnit when canvas parent is disabled;\n private float m_CachedReferencePixelsPerUnit = 100;\n\n public float pixelsPerUnit\n {\n get\n {\n float spritePixelsPerUnit = 100;\n if (activeSprite)\n spritePixelsPerUnit = activeSprite.pixelsPerUnit;\n\n if (canvas)\n m_CachedReferencePixelsPerUnit = canvas.referencePixelsPerUnit;\n\n return spritePixelsPerUnit / m_CachedReferencePixelsPerUnit;\n }\n }\n\n protected float multipliedPixelsPerUnit\n {\n get { return pixelsPerUnit * m_PixelsPerUnitMultiplier; }\n }\n\n /// <summary>\n /// The specified Material used by this Image. The default Material is used instead if one wasn't specified.\n /// </summary>\n public override Material material\n {\n get\n {\n if (m_Material != null)\n return m_Material;\n\n //Edit and Runtime should use Split Alpha Shader if EditorSettings.spritePackerMode = Sprite Atlas V2\n#if UNITY_EDITOR\n if ((Application.isPlaying || EditorSettings.spritePackerMode == SpritePackerMode.SpriteAtlasV2) &&\n activeSprite && activeSprite.associatedAlphaSplitTexture != null)\n {\n return defaultETC1GraphicMaterial;\n }\n#else\n\n if (activeSprite && activeSprite.associatedAlphaSplitTexture != null)\n return defaultETC1GraphicMaterial;\n#endif\n\n return defaultMaterial;\n }\n\n set\n {\n base.material = value;\n }\n }\n\n /// <summary>\n /// See ISerializationCallbackReceiver.\n /// </summary>\n public virtual void OnBeforeSerialize() {}\n\n /// <summary>\n /// See ISerializationCallbackReceiver.\n /// </summary>\n public virtual void OnAfterDeserialize()\n {\n if (m_FillOrigin < 0)\n m_FillOrigin = 0;\n else if (m_FillMethod == FillMethod.Horizontal && m_FillOrigin > 1)\n m_FillOrigin = 0;\n else if (m_FillMethod == FillMethod.Vertical && m_FillOrigin > 1)\n m_FillOrigin = 0;\n else if (m_FillOrigin > 3)\n m_FillOrigin = 0;\n\n m_FillAmount = Mathf.Clamp(m_FillAmount, 0f, 1f);\n }\n\n private void PreserveSpriteAspectRatio(ref Rect rect, Vector2 spriteSize)\n {\n var spriteRatio = spriteSize.x / spriteSize.y;\n var rectRatio = rect.width / rect.height;\n\n if (spriteRatio > rectRatio)\n {\n var oldHeight = rect.height;\n rect.height = rect.width * (1.0f / spriteRatio);\n rect.y += (oldHeight - rect.height) * rectTransform.pivot.y;\n }\n else\n {\n var oldWidth = rect.width;\n rect.width = rect.height * spriteRatio;\n rect.x += (oldWidth - rect.width) * rectTransform.pivot.x;\n }\n }\n\n /// Image's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top.\n private Vector4 GetDrawingDimensions(bool shouldPreserveAspect)\n {\n var padding = activeSprite == null ? Vector4.zero : Sprites.DataUtility.GetPadding(activeSprite);\n var size = activeSprite == null ? Vector2.zero : new Vector2(activeSprite.rect.width, activeSprite.rect.height);\n\n Rect r = GetPixelAdjustedRect();\n // Debug.Log(string.Format(\"r:{2}, size:{0}, padding:{1}\", size, padding, r));\n\n int spriteW = Mathf.RoundToInt(size.x);\n int spriteH = Mathf.RoundToInt(size.y);\n\n var v = new Vector4(\n padding.x / spriteW,\n padding.y / spriteH,\n (spriteW - padding.z) / spriteW,\n (spriteH - padding.w) / spriteH);\n\n if (shouldPreserveAspect && size.sqrMagnitude > 0.0f)\n {\n PreserveSpriteAspectRatio(ref r, size);\n }\n\n v = new Vector4(\n r.x + r.width * v.x,\n r.y + r.height * v.y,\n r.x + r.width * v.z,\n r.y + r.height * v.w\n );\n\n return v;\n }\n\n /// <summary>\n /// Adjusts the image size to make it pixel-perfect.\n /// </summary>\n /// <remarks>\n /// This means setting the Images RectTransform.sizeDelta to be equal to the Sprite dimensions.\n /// </remarks>\n public override void SetNativeSize()\n {\n if (activeSprite != null)\n {\n float w = activeSprite.rect.width / pixelsPerUnit;\n float h = activeSprite.rect.height / pixelsPerUnit;\n rectTransform.anchorMax = rectTransform.anchorMin;\n rectTransform.sizeDelta = new Vector2(w, h);\n SetAllDirty();\n }\n }\n\n /// <summary>\n /// Update the UI renderer mesh.\n /// </summary>\n protected override void OnPopulateMesh(VertexHelper toFill)\n {\n if (activeSprite == null)\n {\n base.OnPopulateMesh(toFill);\n return;\n }\n\n switch (type)\n {\n case Type.Simple:\n if (!useSpriteMesh)\n GenerateSimpleSprite(toFill, m_PreserveAspect);\n else\n GenerateSprite(toFill, m_PreserveAspect);\n break;\n case Type.Sliced:\n GenerateSlicedSprite(toFill);\n break;\n case Type.Tiled:\n GenerateTiledSprite(toFill);\n break;\n case Type.Filled:\n GenerateFilledSprite(toFill, m_PreserveAspect);\n break;\n }\n }\n\n private void TrackSprite()\n {\n if (activeSprite != null && activeSprite.texture == null)\n {\n TrackImage(this);\n m_Tracked = true;\n }\n }\n\n protected override void OnEnable()\n {\n base.OnEnable();\n TrackSprite();\n }\n\n protected override void OnDisable()\n {\n base.OnDisable();\n\n if (m_Tracked)\n UnTrackImage(this);\n }\n\n /// <summary>\n /// Update the renderer's material.\n /// </summary>\n\n protected override void UpdateMaterial()\n {\n base.UpdateMaterial();\n\n // check if this sprite has an associated alpha texture (generated when splitting RGBA = RGB + A as two textures without alpha)\n\n if (activeSprite == null)\n {\n canvasRenderer.SetAlphaTexture(null);\n return;\n }\n\n Texture2D alphaTex = activeSprite.associatedAlphaSplitTexture;\n\n if (alphaTex != null)\n {\n canvasRenderer.SetAlphaTexture(alphaTex);\n }\n }\n\n protected override void OnCanvasHierarchyChanged()\n {\n base.OnCanvasHierarchyChanged();\n if (canvas == null)\n {\n m_CachedReferencePixelsPerUnit = 100;\n }\n else if (canvas.referencePixelsPerUnit != m_CachedReferencePixelsPerUnit)\n {\n m_CachedReferencePixelsPerUnit = canvas.referencePixelsPerUnit;\n if (type == Type.Sliced || type == Type.Tiled)\n {\n SetVerticesDirty();\n SetLayoutDirty();\n }\n }\n }\n\n /// <summary>\n /// Generate vertices for a simple Image.\n /// </summary>\n void GenerateSimpleSprite(VertexHelper vh, bool lPreserveAspect)\n {\n Vector4 v = GetDrawingDimensions(lPreserveAspect);\n var uv = (activeSprite != null) ? Sprites.DataUtility.GetOuterUV(activeSprite) : Vector4.zero;\n\n var color32 = color;\n vh.Clear();\n vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y));\n vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w));\n vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w));\n vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y));\n\n vh.AddTriangle(0, 1, 2);\n vh.AddTriangle(2, 3, 0);\n }\n\n private void GenerateSprite(VertexHelper vh, bool lPreserveAspect)\n {\n var spriteSize = new Vector2(activeSprite.rect.width, activeSprite.rect.height);\n\n // Covert sprite pivot into normalized space.\n var spritePivot = activeSprite.pivot / spriteSize;\n var rectPivot = rectTransform.pivot;\n Rect r = GetPixelAdjustedRect();\n\n if (lPreserveAspect & spriteSize.sqrMagnitude > 0.0f)\n {\n PreserveSpriteAspectRatio(ref r, spriteSize);\n }\n\n var drawingSize = new Vector2(r.width, r.height);\n var spriteBoundSize = activeSprite.bounds.size;\n\n // Calculate the drawing offset based on the difference between the two pivots.\n var drawOffset = (rectPivot - spritePivot) * drawingSize;\n\n var color32 = color;\n vh.Clear();\n\n Vector2[] vertices = activeSprite.vertices;\n Vector2[] uvs = activeSprite.uv;\n for (int i = 0; i < vertices.Length; ++i)\n {\n vh.AddVert(new Vector3((vertices[i].x / spriteBoundSize.x) * drawingSize.x - drawOffset.x, (vertices[i].y / spriteBoundSize.y) * drawingSize.y - drawOffset.y), color32, new Vector2(uvs[i].x, uvs[i].y));\n }\n\n UInt16[] triangles = activeSprite.triangles;\n for (int i = 0; i < triangles.Length; i += 3)\n {\n vh.AddTriangle(triangles[i + 0], triangles[i + 1], triangles[i + 2]);\n }\n }\n\n static readonly Vector2[] s_VertScratch = new Vector2[4];\n static readonly Vector2[] s_UVScratch = new Vector2[4];\n\n /// <summary>\n /// Generate vertices for a 9-sliced Image.\n /// </summary>\n private void GenerateSlicedSprite(VertexHelper toFill)\n {\n if (!hasBorder)\n {\n GenerateSimpleSprite(toFill, false);\n return;\n }\n\n Vector4 outer, inner, padding, border;\n\n if (activeSprite != null)\n {\n outer = Sprites.DataUtility.GetOuterUV(activeSprite);\n inner = Sprites.DataUtility.GetInnerUV(activeSprite);\n padding = Sprites.DataUtility.GetPadding(activeSprite);\n border = activeSprite.border;\n }\n else\n {\n outer = Vector4.zero;\n inner = Vector4.zero;\n padding = Vector4.zero;\n border = Vector4.zero;\n }\n\n Rect rect = GetPixelAdjustedRect();\n\n Vector4 adjustedBorders = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);\n padding = padding / multipliedPixelsPerUnit;\n\n s_VertScratch[0] = new Vector2(padding.x, padding.y);\n s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);\n\n s_VertScratch[1].x = adjustedBorders.x;\n s_VertScratch[1].y = adjustedBorders.y;\n\n s_VertScratch[2].x = rect.width - adjustedBorders.z;\n s_VertScratch[2].y = rect.height - adjustedBorders.w;\n\n for (int i = 0; i < 4; ++i)\n {\n s_VertScratch[i].x += rect.x;\n s_VertScratch[i].y += rect.y;\n }\n\n s_UVScratch[0] = new Vector2(outer.x, outer.y);\n s_UVScratch[1] = new Vector2(inner.x, inner.y);\n s_UVScratch[2] = new Vector2(inner.z, inner.w);\n s_UVScratch[3] = new Vector2(outer.z, outer.w);\n\n toFill.Clear();\n\n for (int x = 0; x < 3; ++x)\n {\n int x2 = x + 1;\n\n for (int y = 0; y < 3; ++y)\n {\n if (!m_FillCenter && x == 1 && y == 1)\n continue;\n\n int y2 = y + 1;\n\n\n AddQuad(toFill,\n new Vector2(s_VertScratch[x].x, s_VertScratch[y].y),\n new Vector2(s_VertScratch[x2].x, s_VertScratch[y2].y),\n color,\n new Vector2(s_UVScratch[x].x, s_UVScratch[y].y),\n new Vector2(s_UVScratch[x2].x, s_UVScratch[y2].y));\n }\n }\n }\n\n /// <summary>\n /// Generate vertices for a tiled Image.\n /// </summary>\n\n void GenerateTiledSprite(VertexHelper toFill)\n {\n Vector4 outer, inner, border;\n Vector2 spriteSize;\n\n if (activeSprite != null)\n {\n outer = Sprites.DataUtility.GetOuterUV(activeSprite);\n inner = Sprites.DataUtility.GetInnerUV(activeSprite);\n border = activeSprite.border;\n spriteSize = activeSprite.rect.size;\n }\n else\n {\n outer = Vector4.zero;\n inner = Vector4.zero;\n border = Vector4.zero;\n spriteSize = Vector2.one * 100;\n }\n\n Rect rect = GetPixelAdjustedRect();\n float tileWidth = (spriteSize.x - border.x - border.z) / multipliedPixelsPerUnit;\n float tileHeight = (spriteSize.y - border.y - border.w) / multipliedPixelsPerUnit;\n\n border = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);\n\n var uvMin = new Vector2(inner.x, inner.y);\n var uvMax = new Vector2(inner.z, inner.w);\n\n // Min to max max range for tiled region in coordinates relative to lower left corner.\n float xMin = border.x;\n float xMax = rect.width - border.z;\n float yMin = border.y;\n float yMax = rect.height - border.w;\n\n toFill.Clear();\n var clipped = uvMax;\n\n // if either width is zero we cant tile so just assume it was the full width.\n if (tileWidth <= 0)\n tileWidth = xMax - xMin;\n\n if (tileHeight <= 0)\n tileHeight = yMax - yMin;\n\n if (activeSprite != null && (hasBorder || activeSprite.packed || activeSprite.texture != null && activeSprite.texture.wrapMode != TextureWrapMode.Repeat))\n {\n // Sprite has border, or is not in repeat mode, or cannot be repeated because of packing.\n // We cannot use texture tiling so we will generate a mesh of quads to tile the texture.\n\n // Evaluate how many vertices we will generate. Limit this number to something sane,\n // especially since meshes can not have more than 65000 vertices.\n\n long nTilesW = 0;\n long nTilesH = 0;\n if (m_FillCenter)\n {\n nTilesW = (long)Math.Ceiling((xMax - xMin) / tileWidth);\n nTilesH = (long)Math.Ceiling((yMax - yMin) / tileHeight);\n\n double nVertices = 0;\n if (hasBorder)\n {\n nVertices = (nTilesW + 2.0) * (nTilesH + 2.0) * 4.0; // 4 vertices per tile\n }\n else\n {\n nVertices = nTilesW * nTilesH * 4.0; // 4 vertices per tile\n }\n\n if (nVertices > 65000.0)\n {\n Debug.LogError(\"Too many sprite tiles on Image \\\"\" + name + \"\\\". The tile size will be increased. To remove the limit on the number of tiles, set the Wrap mode to Repeat in the Image Import Settings\", this);\n\n double maxTiles = 65000.0 / 4.0; // Max number of vertices is 65000; 4 vertices per tile.\n double imageRatio;\n if (hasBorder)\n {\n imageRatio = (nTilesW + 2.0) / (nTilesH + 2.0);\n }\n else\n {\n imageRatio = (double)nTilesW / nTilesH;\n }\n\n double targetTilesW = Math.Sqrt(maxTiles / imageRatio);\n double targetTilesH = targetTilesW * imageRatio;\n if (hasBorder)\n {\n targetTilesW -= 2;\n targetTilesH -= 2;\n }\n\n nTilesW = (long)Math.Floor(targetTilesW);\n nTilesH = (long)Math.Floor(targetTilesH);\n tileWidth = (xMax - xMin) / nTilesW;\n tileHeight = (yMax - yMin) / nTilesH;\n }\n }\n else\n {\n if (hasBorder)\n {\n // Texture on the border is repeated only in one direction.\n nTilesW = (long)Math.Ceiling((xMax - xMin) / tileWidth);\n nTilesH = (long)Math.Ceiling((yMax - yMin) / tileHeight);\n double nVertices = (nTilesH + nTilesW + 2.0 /*corners*/) * 2.0 /*sides*/ * 4.0 /*vertices per tile*/;\n if (nVertices > 65000.0)\n {\n Debug.LogError(\"Too many sprite tiles on Image \\\"\" + name + \"\\\". The tile size will be increased. To remove the limit on the number of tiles, set the Wrap mode to Repeat in the Image Import Settings\", this);\n\n double maxTiles = 65000.0 / 4.0; // Max number of vertices is 65000; 4 vertices per tile.\n double imageRatio = (double)nTilesW / nTilesH;\n double targetTilesW = (maxTiles - 4 /*corners*/) / (2 * (1.0 + imageRatio));\n double targetTilesH = targetTilesW * imageRatio;\n\n nTilesW = (long)Math.Floor(targetTilesW);\n nTilesH = (long)Math.Floor(targetTilesH);\n tileWidth = (xMax - xMin) / nTilesW;\n tileHeight = (yMax - yMin) / nTilesH;\n }\n }\n else\n {\n nTilesH = nTilesW = 0;\n }\n }\n\n if (m_FillCenter)\n {\n // TODO: we could share vertices between quads. If vertex sharing is implemented. update the computation for the number of vertices accordingly.\n for (long j = 0; j < nTilesH; j++)\n {\n float y1 = yMin + j * tileHeight;\n float y2 = yMin + (j + 1) * tileHeight;\n if (y2 > yMax)\n {\n clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);\n y2 = yMax;\n }\n clipped.x = uvMax.x;\n for (long i = 0; i < nTilesW; i++)\n {\n float x1 = xMin + i * tileWidth;\n float x2 = xMin + (i + 1) * tileWidth;\n if (x2 > xMax)\n {\n clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);\n x2 = xMax;\n }\n AddQuad(toFill, new Vector2(x1, y1) + rect.position, new Vector2(x2, y2) + rect.position, color, uvMin, clipped);\n }\n }\n }\n if (hasBorder)\n {\n clipped = uvMax;\n for (long j = 0; j < nTilesH; j++)\n {\n float y1 = yMin + j * tileHeight;\n float y2 = yMin + (j + 1) * tileHeight;\n if (y2 > yMax)\n {\n clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1);\n y2 = yMax;\n }\n AddQuad(toFill,\n new Vector2(0, y1) + rect.position,\n new Vector2(xMin, y2) + rect.position,\n color,\n new Vector2(outer.x, uvMin.y),\n new Vector2(uvMin.x, clipped.y));\n AddQuad(toFill,\n new Vector2(xMax, y1) + rect.position,\n new Vector2(rect.width, y2) + rect.position,\n color,\n new Vector2(uvMax.x, uvMin.y),\n new Vector2(outer.z, clipped.y));\n }\n\n // Bottom and top tiled border\n clipped = uvMax;\n for (long i = 0; i < nTilesW; i++)\n {\n float x1 = xMin + i * tileWidth;\n float x2 = xMin + (i + 1) * tileWidth;\n if (x2 > xMax)\n {\n clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1);\n x2 = xMax;\n }\n AddQuad(toFill,\n new Vector2(x1, 0) + rect.position,\n new Vector2(x2, yMin) + rect.position,\n color,\n new Vector2(uvMin.x, outer.y),\n new Vector2(clipped.x, uvMin.y));\n AddQuad(toFill,\n new Vector2(x1, yMax) + rect.position,\n new Vector2(x2, rect.height) + rect.position,\n color,\n new Vector2(uvMin.x, uvMax.y),\n new Vector2(clipped.x, outer.w));\n }\n\n // Corners\n AddQuad(toFill,\n new Vector2(0, 0) + rect.position,\n new Vector2(xMin, yMin) + rect.position,\n color,\n new Vector2(outer.x, outer.y),\n new Vector2(uvMin.x, uvMin.y));\n AddQuad(toFill,\n new Vector2(xMax, 0) + rect.position,\n new Vector2(rect.width, yMin) + rect.position,\n color,\n new Vector2(uvMax.x, outer.y),\n new Vector2(outer.z, uvMin.y));\n AddQuad(toFill,\n new Vector2(0, yMax) + rect.position,\n new Vector2(xMin, rect.height) + rect.position,\n color,\n new Vector2(outer.x, uvMax.y),\n new Vector2(uvMin.x, outer.w));\n AddQuad(toFill,\n new Vector2(xMax, yMax) + rect.position,\n new Vector2(rect.width, rect.height) + rect.position,\n color,\n new Vector2(uvMax.x, uvMax.y),\n new Vector2(outer.z, outer.w));\n }\n }\n else\n {\n // Texture has no border, is in repeat mode and not packed. Use texture tiling.\n Vector2 uvScale = new Vector2((xMax - xMin) / tileWidth, (yMax - yMin) / tileHeight);\n\n if (m_FillCenter)\n {\n AddQuad(toFill, new Vector2(xMin, yMin) + rect.position, new Vector2(xMax, yMax) + rect.position, color, Vector2.Scale(uvMin, uvScale), Vector2.Scale(uvMax, uvScale));\n }\n }\n }\n\n static void AddQuad(VertexHelper vertexHelper, Vector3[] quadPositions, Color32 color, Vector3[] quadUVs)\n {\n int startIndex = vertexHelper.currentVertCount;\n\n for (int i = 0; i < 4; ++i)\n vertexHelper.AddVert(quadPositions[i], color, quadUVs[i]);\n\n vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);\n vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);\n }\n\n static void AddQuad(VertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, Color32 color, Vector2 uvMin, Vector2 uvMax)\n {\n int startIndex = vertexHelper.currentVertCount;\n\n vertexHelper.AddVert(new Vector3(posMin.x, posMin.y, 0), color, new Vector2(uvMin.x, uvMin.y));\n vertexHelper.AddVert(new Vector3(posMin.x, posMax.y, 0), color, new Vector2(uvMin.x, uvMax.y));\n vertexHelper.AddVert(new Vector3(posMax.x, posMax.y, 0), color, new Vector2(uvMax.x, uvMax.y));\n vertexHelper.AddVert(new Vector3(posMax.x, posMin.y, 0), color, new Vector2(uvMax.x, uvMin.y));\n\n vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);\n vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);\n }\n\n private Vector4 GetAdjustedBorders(Vector4 border, Rect adjustedRect)\n {\n Rect originalRect = rectTransform.rect;\n\n for (int axis = 0; axis <= 1; axis++)\n {\n float borderScaleRatio;\n\n // The adjusted rect (adjusted for pixel correctness)\n // may be slightly larger than the original rect.\n // Adjust the border to match the adjustedRect to avoid\n // small gaps between borders (case 833201).\n if (originalRect.size[axis] != 0)\n {\n borderScaleRatio = adjustedRect.size[axis] / originalRect.size[axis];\n border[axis] *= borderScaleRatio;\n border[axis + 2] *= borderScaleRatio;\n }\n\n // If the rect is smaller than the combined borders, then there's not room for the borders at their normal size.\n // In order to avoid artefacts with overlapping borders, we scale the borders down to fit.\n float combinedBorders = border[axis] + border[axis + 2];\n if (adjustedRect.size[axis] < combinedBorders && combinedBorders != 0)\n {\n borderScaleRatio = adjustedRect.size[axis] / combinedBorders;\n border[axis] *= borderScaleRatio;\n border[axis + 2] *= borderScaleRatio;\n }\n }\n return border;\n }\n\n static readonly Vector3[] s_Xy = new Vector3[4];\n static readonly Vector3[] s_Uv = new Vector3[4];\n\n /// <summary>\n /// Generate vertices for a filled Image.\n /// </summary>\n void GenerateFilledSprite(VertexHelper toFill, bool preserveAspect)\n {\n toFill.Clear();\n\n if (m_FillAmount < 0.001f)\n return;\n\n Vector4 v = GetDrawingDimensions(preserveAspect);\n Vector4 outer = activeSprite != null ? Sprites.DataUtility.GetOuterUV(activeSprite) : Vector4.zero;\n UIVertex uiv = UIVertex.simpleVert;\n uiv.color = color;\n\n float tx0 = outer.x;\n float ty0 = outer.y;\n float tx1 = outer.z;\n float ty1 = outer.w;\n\n // Horizontal and vertical filled sprites are simple -- just end the Image prematurely\n if (m_FillMethod == FillMethod.Horizontal || m_FillMethod == FillMethod.Vertical)\n {\n if (fillMethod == FillMethod.Horizontal)\n {\n float fill = (tx1 - tx0) * m_FillAmount;\n\n if (m_FillOrigin == 1)\n {\n v.x = v.z - (v.z - v.x) * m_FillAmount;\n tx0 = tx1 - fill;\n }\n else\n {\n v.z = v.x + (v.z - v.x) * m_FillAmount;\n tx1 = tx0 + fill;\n }\n }\n else if (fillMethod == FillMethod.Vertical)\n {\n float fill = (ty1 - ty0) * m_FillAmount;\n\n if (m_FillOrigin == 1)\n {\n v.y = v.w - (v.w - v.y) * m_FillAmount;\n ty0 = ty1 - fill;\n }\n else\n {\n v.w = v.y + (v.w - v.y) * m_FillAmount;\n ty1 = ty0 + fill;\n }\n }\n }\n\n s_Xy[0] = new Vector2(v.x, v.y);\n s_Xy[1] = new Vector2(v.x, v.w);\n s_Xy[2] = new Vector2(v.z, v.w);\n s_Xy[3] = new Vector2(v.z, v.y);\n\n s_Uv[0] = new Vector2(tx0, ty0);\n s_Uv[1] = new Vector2(tx0, ty1);\n s_Uv[2] = new Vector2(tx1, ty1);\n s_Uv[3] = new Vector2(tx1, ty0);\n\n {\n if (m_FillAmount < 1f && m_FillMethod != FillMethod.Horizontal && m_FillMethod != FillMethod.Vertical)\n {\n if (fillMethod == FillMethod.Radial90)\n {\n if (RadialCut(s_Xy, s_Uv, m_FillAmount, m_FillClockwise, m_FillOrigin))\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n else if (fillMethod == FillMethod.Radial180)\n {\n for (int side = 0; side < 2; ++side)\n {\n float fx0, fx1, fy0, fy1;\n int even = m_FillOrigin > 1 ? 1 : 0;\n\n if (m_FillOrigin == 0 || m_FillOrigin == 2)\n {\n fy0 = 0f;\n fy1 = 1f;\n if (side == even)\n {\n fx0 = 0f;\n fx1 = 0.5f;\n }\n else\n {\n fx0 = 0.5f;\n fx1 = 1f;\n }\n }\n else\n {\n fx0 = 0f;\n fx1 = 1f;\n if (side == even)\n {\n fy0 = 0.5f;\n fy1 = 1f;\n }\n else\n {\n fy0 = 0f;\n fy1 = 0.5f;\n }\n }\n\n s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);\n s_Xy[1].x = s_Xy[0].x;\n s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);\n s_Xy[3].x = s_Xy[2].x;\n\n s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);\n s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);\n s_Xy[2].y = s_Xy[1].y;\n s_Xy[3].y = s_Xy[0].y;\n\n s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);\n s_Uv[1].x = s_Uv[0].x;\n s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);\n s_Uv[3].x = s_Uv[2].x;\n\n s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);\n s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);\n s_Uv[2].y = s_Uv[1].y;\n s_Uv[3].y = s_Uv[0].y;\n\n float val = m_FillClockwise ? fillAmount * 2f - side : m_FillAmount * 2f - (1 - side);\n\n if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((side + m_FillOrigin + 3) % 4)))\n {\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n else if (fillMethod == FillMethod.Radial360)\n {\n for (int corner = 0; corner < 4; ++corner)\n {\n float fx0, fx1, fy0, fy1;\n\n if (corner < 2)\n {\n fx0 = 0f;\n fx1 = 0.5f;\n }\n else\n {\n fx0 = 0.5f;\n fx1 = 1f;\n }\n\n if (corner == 0 || corner == 3)\n {\n fy0 = 0f;\n fy1 = 0.5f;\n }\n else\n {\n fy0 = 0.5f;\n fy1 = 1f;\n }\n\n s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0);\n s_Xy[1].x = s_Xy[0].x;\n s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1);\n s_Xy[3].x = s_Xy[2].x;\n\n s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0);\n s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1);\n s_Xy[2].y = s_Xy[1].y;\n s_Xy[3].y = s_Xy[0].y;\n\n s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0);\n s_Uv[1].x = s_Uv[0].x;\n s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1);\n s_Uv[3].x = s_Uv[2].x;\n\n s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0);\n s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1);\n s_Uv[2].y = s_Uv[1].y;\n s_Uv[3].y = s_Uv[0].y;\n\n float val = m_FillClockwise ?\n m_FillAmount * 4f - ((corner + m_FillOrigin) % 4) :\n m_FillAmount * 4f - (3 - ((corner + m_FillOrigin) % 4));\n\n if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((corner + 2) % 4)))\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n else\n {\n AddQuad(toFill, s_Xy, color, s_Uv);\n }\n }\n }\n\n /// <summary>\n /// Adjust the specified quad, making it be radially filled instead.\n /// </summary>\n\n static bool RadialCut(Vector3[] xy, Vector3[] uv, float fill, bool invert, int corner)\n {\n // Nothing to fill\n if (fill < 0.001f) return false;\n\n // Even corners invert the fill direction\n if ((corner & 1) == 1) invert = !invert;\n\n // Nothing to adjust\n if (!invert && fill > 0.999f) return true;\n\n // Convert 0-1 value into 0 to 90 degrees angle in radians\n float angle = Mathf.Clamp01(fill);\n if (invert) angle = 1f - angle;\n angle *= 90f * Mathf.Deg2Rad;\n\n // Calculate the effective X and Y factors\n float cos = Mathf.Cos(angle);\n float sin = Mathf.Sin(angle);\n\n RadialCut(xy, cos, sin, invert, corner);\n RadialCut(uv, cos, sin, invert, corner);\n return true;\n }\n\n /// <summary>\n /// Adjust the specified quad, making it be radially filled instead.\n /// </summary>\n\n static void RadialCut(Vector3[] xy, float cos, float sin, bool invert, int corner)\n {\n int i0 = corner;\n int i1 = ((corner + 1) % 4);\n int i2 = ((corner + 2) % 4);\n int i3 = ((corner + 3) % 4);\n\n if ((corner & 1) == 1)\n {\n if (sin > cos)\n {\n cos /= sin;\n sin = 1f;\n\n if (invert)\n {\n xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n xy[i2].x = xy[i1].x;\n }\n }\n else if (cos > sin)\n {\n sin /= cos;\n cos = 1f;\n\n if (!invert)\n {\n xy[i2].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n xy[i3].y = xy[i2].y;\n }\n }\n else\n {\n cos = 1f;\n sin = 1f;\n }\n\n if (!invert) xy[i3].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n else xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n }\n else\n {\n if (cos > sin)\n {\n sin /= cos;\n cos = 1f;\n\n if (!invert)\n {\n xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n xy[i2].y = xy[i1].y;\n }\n }\n else if (sin > cos)\n {\n cos /= sin;\n sin = 1f;\n\n if (invert)\n {\n xy[i2].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n xy[i3].x = xy[i2].x;\n }\n }\n else\n {\n cos = 1f;\n sin = 1f;\n }\n\n if (invert) xy[i3].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin);\n else xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos);\n }\n }\n\n /// <summary>\n /// See ILayoutElement.CalculateLayoutInputHorizontal.\n /// </summary>\n public virtual void CalculateLayoutInputHorizontal() {}\n\n /// <summary>\n /// See ILayoutElement.CalculateLayoutInputVertical.\n /// </summary>\n public virtual void CalculateLayoutInputVertical() {}\n\n /// <summary>\n /// See ILayoutElement.minWidth.\n /// </summary>\n public virtual float minWidth { get { return 0; } }\n\n /// <summary>\n /// If there is a sprite being rendered returns the size of that sprite.\n /// In the case of a slided or tiled sprite will return the calculated minimum size possible\n /// </summary>\n public virtual float preferredWidth\n {\n get\n {\n if (activeSprite == null)\n return 0;\n if (type == Type.Sliced || type == Type.Tiled)\n return Sprites.DataUtility.GetMinSize(activeSprite).x / pixelsPerUnit;\n return activeSprite.rect.size.x / pixelsPerUnit;\n }\n }\n\n /// <summary>\n /// See ILayoutElement.flexibleWidth.\n /// </summary>\n public virtual float flexibleWidth { get { return -1; } }\n\n /// <summary>\n /// See ILayoutElement.minHeight.\n /// </summary>\n public virtual float minHeight { get { return 0; } }\n\n /// <summary>\n /// If there is a sprite being rendered returns the size of that sprite.\n /// In the case of a slided or tiled sprite will return the calculated minimum size possible\n /// </summary>\n public virtual float preferredHeight\n {\n get\n {\n if (activeSprite == null)\n return 0;\n if (type == Type.Sliced || type == Type.Tiled)\n return Sprites.DataUtility.GetMinSize(activeSprite).y / pixelsPerUnit;\n return activeSprite.rect.size.y / pixelsPerUnit;\n }\n }\n\n /// <summary>\n /// See ILayoutElement.flexibleHeight.\n /// </summary>\n public virtual float flexibleHeight { get { return -1; } }\n\n /// <summary>\n /// See ILayoutElement.layoutPriority.\n /// </summary>\n public virtual int layoutPriority { get { return 0; } }\n\n /// <summary>\n /// Calculate if the ray location for this image is a valid hit location. Takes into account a Alpha test threshold.\n /// </summary>\n /// <param name=\"screenPoint\">The screen point to check against</param>\n /// <param name=\"eventCamera\">The camera in which to use to calculate the coordinating position</param>\n /// <returns>If the location is a valid hit or not.</returns>\n /// <remarks> Also see See:ICanvasRaycastFilter.</remarks>\n public virtual bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)\n {\n if (alphaHitTestMinimumThreshold <= 0)\n return true;\n\n if (alphaHitTestMinimumThreshold > 1)\n return false;\n\n if (activeSprite == null)\n return true;\n\n Vector2 local;\n if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out local))\n return false;\n\n Rect rect = GetPixelAdjustedRect();\n\n if (m_PreserveAspect)\n PreserveSpriteAspectRatio(ref rect, new Vector2(activeSprite.texture.width, activeSprite.texture.height));\n\n // Convert to have lower left corner as reference point.\n local.x += rectTransform.pivot.x * rect.width;\n local.y += rectTransform.pivot.y * rect.height;\n\n local = MapCoordinate(local, rect);\n\n // Convert local coordinates to texture space.\n float x = local.x / activeSprite.texture.width;\n float y = local.y / activeSprite.texture.height;\n\n try\n {\n return activeSprite.texture.GetPixelBilinear(x, y).a >= alphaHitTestMinimumThreshold;\n }\n catch (UnityException e)\n {\n Debug.LogError(\"Using alphaHitTestMinimumThreshold greater than 0 on Image whose sprite texture cannot be read. \" + e.Message + \" Also make sure to disable sprite packing for this sprite.\", this);\n return true;\n }\n }\n\n private Vector2 MapCoordinate(Vector2 local, Rect rect)\n {\n Rect spriteRect = activeSprite.rect;\n if (type == Type.Simple || type == Type.Filled)\n return new Vector2(spriteRect.position.x + local.x * spriteRect.width / rect.width, spriteRect.position.y + local.y * spriteRect.height / rect.height);\n\n Vector4 border = activeSprite.border;\n Vector4 adjustedBorder = GetAdjustedBorders(border / pixelsPerUnit, rect);\n\n for (int i = 0; i < 2; i++)\n {\n if (local[i] <= adjustedBorder[i])\n continue;\n\n if (rect.size[i] - local[i] <= adjustedBorder[i + 2])\n {\n local[i] -= (rect.size[i] - spriteRect.size[i]);\n continue;\n }\n\n if (type == Type.Sliced)\n {\n float lerp = Mathf.InverseLerp(adjustedBorder[i], rect.size[i] - adjustedBorder[i + 2], local[i]);\n local[i] = Mathf.Lerp(border[i], spriteRect.size[i] - border[i + 2], lerp);\n }\n else\n {\n local[i] -= adjustedBorder[i];\n local[i] = Mathf.Repeat(local[i], spriteRect.size[i] - border[i] - border[i + 2]);\n local[i] += border[i];\n }\n }\n\n return local + spriteRect.position;\n }\n\n // To track textureless images, which will be rebuild if sprite atlas manager registered a Sprite Atlas that will give this image new texture\n static List<Image> m_TrackedTexturelessImages = new List<Image>();\n static bool s_Initialized;\n\n static void RebuildImage(SpriteAtlas spriteAtlas)\n {\n for (var i = m_TrackedTexturelessImages.Count - 1; i >= 0; i--)\n {\n var g = m_TrackedTexturelessImages[i];\n if (null != g.activeSprite && spriteAtlas.CanBindTo(g.activeSprite))\n {\n g.SetAllDirty();\n m_TrackedTexturelessImages.RemoveAt(i);\n }\n }\n }\n\n private static void TrackImage(Image g)\n {\n if (!s_Initialized)\n {\n SpriteAtlasManager.atlasRegistered += RebuildImage;\n s_Initialized = true;\n }\n\n m_TrackedTexturelessImages.Add(g);\n }\n\n private static void UnTrackImage(Image g)\n {\n m_TrackedTexturelessImages.Remove(g);\n }\n\n protected override void OnDidApplyAnimationProperties()\n {\n SetMaterialDirty();\n SetVerticesDirty();\n SetRaycastDirty();\n }\n\n#if UNITY_EDITOR\n protected override void OnValidate()\n {\n base.OnValidate();\n m_PixelsPerUnitMultiplier = Mathf.Max(0.01f, m_PixelsPerUnitMultiplier);\n }\n\n#endif\n }\n}\n"
  365. },
  366. {
  367. "Script": "Image",
  368. "Material": "None",
  369. "Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  370. "Raycast Target": "True",
  371. "Raycast Padding": "(0.00, 0.00, 0.00, 0.00)",
  372. "Maskable": "True",
  373. "On Cull State Changed": "<Unsupported Type>",
  374. "Sprite": "play-button-icon-png-18931",
  375. "Type": "Filled",
  376. "Preserve Aspect": "False",
  377. "Fill Center": "True",
  378. "Fill Method": "Radial360",
  379. "Fill Amount": "1",
  380. "Fill Clockwise": "True",
  381. "Fill Origin": "0",
  382. "Use Sprite Mesh": "False",
  383. "Pixels Per Unit Multiplier": "1"
  384. },
  385. {
  386. "Name": "Button",
  387. "Content": "using System;\nusing System.Collections;\nusing UnityEngine.Events;\nusing UnityEngine.EventSystems;\nusing UnityEngine.Serialization;\n\nnamespace UnityEngine.UI\n{\n /// <summary>\n /// A standard button that sends an event when clicked.\n /// </summary>\n [AddComponentMenu(\"UI/Button\", 30)]\n public class Button : Selectable, IPointerClickHandler, ISubmitHandler\n {\n [Serializable]\n /// <summary>\n /// Function definition for a button click event.\n /// </summary>\n public class ButtonClickedEvent : UnityEvent {}\n\n // Event delegates triggered on click.\n [FormerlySerializedAs(\"onClick\")]\n [SerializeField]\n private ButtonClickedEvent m_OnClick = new ButtonClickedEvent();\n\n protected Button()\n {}\n\n /// <summary>\n /// UnityEvent that is triggered when the button is pressed.\n /// Note: Triggered on MouseUp after MouseDown on the same object.\n /// </summary>\n ///<example>\n ///<code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using UnityEngine.UI;\n /// using System.Collections;\n ///\n /// public class ClickExample : MonoBehaviour\n /// {\n /// public Button yourButton;\n ///\n /// void Start()\n /// {\n /// Button btn = yourButton.GetComponent<Button>();\n /// btn.onClick.AddListener(TaskOnClick);\n /// }\n ///\n /// void TaskOnClick()\n /// {\n /// Debug.Log(\"You have clicked the button!\");\n /// }\n /// }\n /// ]]>\n ///</code>\n ///</example>\n public ButtonClickedEvent onClick\n {\n get { return m_OnClick; }\n set { m_OnClick = value; }\n }\n\n private void Press()\n {\n if (!IsActive() || !IsInteractable())\n return;\n\n UISystemProfilerApi.AddMarker(\"Button.onClick\", this);\n m_OnClick.Invoke();\n }\n\n /// <summary>\n /// Call all registered IPointerClickHandlers.\n /// Register button presses using the IPointerClickHandler. You can also use it to tell what type of click happened (left, right etc.).\n /// Make sure your Scene has an EventSystem.\n /// </summary>\n /// <param name=\"eventData\">Pointer Data associated with the event. Typically by the event system.</param>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// //Attatch this script to a Button GameObject\n /// using UnityEngine;\n /// using UnityEngine.EventSystems;\n ///\n /// public class Example : MonoBehaviour, IPointerClickHandler\n /// {\n /// //Detect if a click occurs\n /// public void OnPointerClick(PointerEventData pointerEventData)\n /// {\n /// //Use this to tell when the user right-clicks on the Button\n /// if (pointerEventData.button == PointerEventData.InputButton.Right)\n /// {\n /// //Output to console the clicked GameObject's name and the following message. You can replace this with your own actions for when clicking the GameObject.\n /// Debug.Log(name + \" Game Object Right Clicked!\");\n /// }\n ///\n /// //Use this to tell when the user left-clicks on the Button\n /// if (pointerEventData.button == PointerEventData.InputButton.Left)\n /// {\n /// Debug.Log(name + \" Game Object Left Clicked!\");\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n\n public virtual void OnPointerClick(PointerEventData eventData)\n {\n if (eventData.button != PointerEventData.InputButton.Left)\n return;\n\n Press();\n }\n\n /// <summary>\n /// Call all registered ISubmitHandler.\n /// </summary>\n /// <param name=\"eventData\">Associated data with the event. Typically by the event system.</param>\n /// <remarks>\n /// This detects when a Button has been selected via a \"submit\" key you specify (default is the return key).\n ///\n /// To change the submit key, either:\n ///\n /// 1. Go to Edit->Project Settings->Input.\n ///\n /// 2. Next, expand the Axes section and go to the Submit section if it exists.\n ///\n /// 3. If Submit doesn’t exist, add 1 number to the Size field. This creates a new section at the bottom. Expand the new section and change the Name field to “Submit”.\n ///\n /// 4. Change the Positive Button field to the key you want (e.g. space).\n ///\n ///\n /// Or:\n ///\n /// 1. Go to your EventSystem in your Project\n ///\n /// 2. Go to the Inspector window and change the Submit Button field to one of the sections in the Input Manager (e.g. \"Submit\"), or create your own by naming it what you like, then following the next few steps.\n ///\n /// 3. Go to Edit->Project Settings->Input to get to the Input Manager.\n ///\n /// 4. Expand the Axes section in the Inspector window. Add 1 to the number in the Size field. This creates a new section at the bottom.\n ///\n /// 5. Expand the new section and name it the same as the name you inserted in the Submit Button field in the EventSystem. Set the Positive Button field to the key you want (e.g. space)\n /// </remarks>\n\n public virtual void OnSubmit(BaseEventData eventData)\n {\n Press();\n\n // if we get set disabled during the press\n // don't run the coroutine.\n if (!IsActive() || !IsInteractable())\n return;\n\n DoStateTransition(SelectionState.Pressed, false);\n StartCoroutine(OnFinishSubmit());\n }\n\n private IEnumerator OnFinishSubmit()\n {\n var fadeTime = colors.fadeDuration;\n var elapsedTime = 0f;\n\n while (elapsedTime < fadeTime)\n {\n elapsedTime += Time.unscaledDeltaTime;\n yield return null;\n }\n\n DoStateTransition(currentSelectionState, false);\n }\n }\n}\n"
  388. },
  389. {
  390. "Script": "Button",
  391. "Navigation": "<Unsupported Type>",
  392. "Transition": "ColorTint",
  393. "Colors": "<Unsupported Type>",
  394. "Sprite State": "<Unsupported Type>",
  395. "Animation Triggers": "<Unsupported Type>",
  396. "Interactable": "True",
  397. "Target Graphic": "Pause Resume Button",
  398. "On Click": "<Unsupported Type>"
  399. }
  400. ],
  401. "Children": [
  402. {
  403. "Name": "Text (TMP)",
  404. "Components": [
  405. {
  406. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  407. "Local Position": "(0.00, 0.00, 0.00)",
  408. "Local Scale": "(1.00, 1.00, 1.00)",
  409. "Constrain Proportions Scale": "False",
  410. "Anchor Min": "(0.00, 0.00)",
  411. "Anchor Max": "(1.00, 1.00)",
  412. "Anchored Position": "(0.00, 0.00)",
  413. "Size Delta": "(0.00, 0.00)",
  414. "Pivot": "(0.50, 0.50)"
  415. },
  416. {
  417. "Cull Transparent Mesh": "True"
  418. },
  419. {
  420. "Name": "TextMeshProUGUI",
  421. "Content": "using System;\nusing System.Collections;\nusing UnityEngine;\nusing UnityEngine.Rendering;\nusing UnityEngine.UI;\n\n#pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor.\n\n\nnamespace TMPro\n{\n [DisallowMultipleComponent]\n [RequireComponent(typeof(RectTransform))]\n [RequireComponent(typeof(CanvasRenderer))]\n [AddComponentMenu(\"UI/TextMeshPro - Text (UI)\", 11)]\n [ExecuteAlways]\n [HelpURL(\"https://docs.unity3d.com/Packages/[email protected]\")]\n public partial class TextMeshProUGUI : TMP_Text, ILayoutElement\n {\n /// <summary>\n /// Get the material that will be used for rendering.\n /// </summary>\n public override Material materialForRendering\n {\n get { return TMP_MaterialManager.GetMaterialForRendering(this, m_sharedMaterial); }\n }\n\n\n /// <summary>\n /// Determines if the size of the text container will be adjusted to fit the text object when it is first created.\n /// </summary>\n public override bool autoSizeTextContainer\n {\n get { return m_autoSizeTextContainer; }\n\n set { if (m_autoSizeTextContainer == value) return; m_autoSizeTextContainer = value; if (m_autoSizeTextContainer) { CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); SetLayoutDirty(); } }\n }\n\n\n /// <summary>\n /// Reference to the Mesh used by the text object.\n /// </summary>\n public override Mesh mesh\n {\n get { return m_mesh; }\n }\n\n\n /// <summary>\n /// Reference to the CanvasRenderer used by the text object.\n /// </summary>\n public new CanvasRenderer canvasRenderer\n {\n get\n {\n if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();\n\n return m_canvasRenderer;\n }\n }\n\n\n /// <summary>\n /// Anchor dampening prevents the anchor position from being adjusted unless the positional change exceeds about 40% of the width of the underline character. This essentially stabilizes the anchor position.\n /// </summary>\n //public bool anchorDampening\n //{\n // get { return m_anchorDampening; }\n // set { if (m_anchorDampening != value) { havePropertiesChanged = true; m_anchorDampening = value; /* ScheduleUpdate(); */ } }\n //}\n\n #if !UNITY_2019_3_OR_NEWER\n [SerializeField]\n private bool m_Maskable = true;\n #endif\n\n private bool m_isRebuildingLayout = false;\n private Coroutine m_DelayedGraphicRebuild;\n private Coroutine m_DelayedMaterialRebuild;\n\n /// <summary>\n /// Function called by Unity when the horizontal layout needs to be recalculated.\n /// </summary>\n public void CalculateLayoutInputHorizontal()\n {\n //Debug.Log(\"*** CalculateLayoutHorizontal() on Object ID: \" + GetInstanceID() + \" at frame: \" + Time.frameCount + \"***\");\n }\n\n\n /// <summary>\n /// Function called by Unity when the vertical layout needs to be recalculated.\n /// </summary>\n public void CalculateLayoutInputVertical()\n {\n //Debug.Log(\"*** CalculateLayoutInputVertical() on Object ID: \" + GetInstanceID() + \" at frame: \" + Time.frameCount + \"***\");\n }\n\n\n public override void SetVerticesDirty()\n {\n if (this == null || !this.IsActive())\n return;\n\n if (CanvasUpdateRegistry.IsRebuildingGraphics())\n return;\n\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyVertsCallback != null)\n m_OnDirtyVertsCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetLayoutDirty()\n {\n m_isPreferredWidthDirty = true;\n m_isPreferredHeightDirty = true;\n\n if (this == null || !this.IsActive())\n return;\n\n LayoutRebuilder.MarkLayoutForRebuild(this.rectTransform);\n\n m_isLayoutDirty = true;\n\n if (m_OnDirtyLayoutCallback != null)\n m_OnDirtyLayoutCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetMaterialDirty()\n {\n if (this == null || !this.IsActive())\n return;\n\n if (CanvasUpdateRegistry.IsRebuildingGraphics())\n return;\n\n m_isMaterialDirty = true;\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyMaterialCallback != null)\n m_OnDirtyMaterialCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetAllDirty()\n {\n SetLayoutDirty();\n SetVerticesDirty();\n SetMaterialDirty();\n }\n\n\n /// <summary>\n /// Delay registration of text object for graphic rebuild by one frame.\n /// </summary>\n /// <returns></returns>\n IEnumerator DelayedGraphicRebuild()\n {\n yield return null;\n\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyVertsCallback != null)\n m_OnDirtyVertsCallback();\n\n m_DelayedGraphicRebuild = null;\n }\n\n\n /// <summary>\n /// Delay registration of text object for graphic rebuild by one frame.\n /// </summary>\n /// <returns></returns>\n IEnumerator DelayedMaterialRebuild()\n {\n yield return null;\n\n m_isMaterialDirty = true;\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyMaterialCallback != null)\n m_OnDirtyMaterialCallback();\n\n m_DelayedMaterialRebuild = null;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n /// <param name=\"update\"></param>\n public override void Rebuild(CanvasUpdate update)\n {\n if (this == null) return;\n\n if (update == CanvasUpdate.Prelayout)\n {\n if (m_autoSizeTextContainer)\n {\n m_rectTransform.sizeDelta = GetPreferredValues(Mathf.Infinity, Mathf.Infinity);\n }\n }\n else if (update == CanvasUpdate.PreRender)\n {\n OnPreRenderCanvas();\n\n if (!m_isMaterialDirty) return;\n\n UpdateMaterial();\n m_isMaterialDirty = false;\n }\n }\n\n\n /// <summary>\n /// Method to keep the pivot of the sub text objects in sync with the parent pivot.\n /// </summary>\n private void UpdateSubObjectPivot()\n {\n if (m_textInfo == null) return;\n\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].SetPivotDirty();\n }\n //m_isPivotDirty = false;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n /// <param name=\"baseMaterial\"></param>\n /// <returns></returns>\n public override Material GetModifiedMaterial(Material baseMaterial)\n {\n Material mat = baseMaterial;\n\n if (m_ShouldRecalculateStencil)\n {\n var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);\n m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0;\n m_ShouldRecalculateStencil = false;\n }\n\n if (m_StencilValue > 0)\n {\n var maskMat = StencilMaterial.Add(mat, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0);\n StencilMaterial.Remove(m_MaskMaterial);\n m_MaskMaterial = maskMat;\n mat = m_MaskMaterial;\n }\n\n return mat;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n protected override void UpdateMaterial()\n {\n //Debug.Log(\"*** UpdateMaterial() ***\");\n\n //if (!this.IsActive())\n // return;\n\n if (m_sharedMaterial == null || canvasRenderer == null) return;\n\n m_canvasRenderer.materialCount = 1;\n m_canvasRenderer.SetMaterial(materialForRendering, 0);\n //m_canvasRenderer.SetTexture(materialForRendering.mainTexture);\n }\n\n\n //public override void OnRebuildRequested()\n //{\n // //Debug.Log(\"OnRebuildRequested\");\n\n // base.OnRebuildRequested();\n //}\n\n\n\n //public override bool Raycast(Vector2 sp, Camera eventCamera)\n //{\n // //Debug.Log(\"Raycast Event. ScreenPoint: \" + sp);\n // return base.Raycast(sp, eventCamera);\n //}\n\n\n // MASKING RELATED PROPERTIES\n /// <summary>\n /// Sets the masking offset from the bounds of the object\n /// </summary>\n public Vector4 maskOffset\n {\n get { return m_maskOffset; }\n set { m_maskOffset = value; UpdateMask(); m_havePropertiesChanged = true; }\n }\n\n\n //public override Material defaultMaterial\n //{\n // get { Debug.Log(\"Default Material called.\"); return m_sharedMaterial; }\n //}\n\n\n\n //protected override void OnCanvasHierarchyChanged()\n //{\n // //Debug.Log(\"OnCanvasHierarchyChanged...\");\n //}\n\n\n // IClippable implementation\n /// <summary>\n /// Method called when the state of a parent changes.\n /// </summary>\n public override void RecalculateClipping()\n {\n //Debug.Log(\"***** RecalculateClipping() *****\");\n\n base.RecalculateClipping();\n }\n\n\n // IMaskable Implementation\n /// <summary>\n /// Method called when Stencil Mask needs to be updated on this element and parents.\n /// </summary>\n // public override void RecalculateMasking()\n // {\n // //Debug.Log(\"***** RecalculateMasking() *****\");\n //\n // this.m_ShouldRecalculateStencil = true;\n // SetMaterialDirty();\n // }\n\n\n //public override void SetClipRect(Rect clipRect, bool validRect)\n //{\n // //Debug.Log(\"***** SetClipRect (\" + clipRect + \", \" + validRect + \") *****\");\n\n // base.SetClipRect(clipRect, validRect);\n //}\n\n\n /// <summary>\n /// Override of the Cull function to provide for the ability to override the culling of the text object.\n /// </summary>\n /// <param name=\"clipRect\"></param>\n /// <param name=\"validRect\"></param>\n public override void Cull(Rect clipRect, bool validRect)\n {\n // Delay culling check in the event the text layout is dirty and geometry has to be updated.\n if (m_isLayoutDirty)\n {\n TMP_UpdateManager.RegisterTextElementForCullingUpdate(this);\n m_ClipRect = clipRect;\n m_ValidRect = validRect;\n return;\n }\n\n // Get compound rect for the text object and sub text objects in local canvas space.\n Rect rect = GetCanvasSpaceClippingRect();\n\n // No point culling if geometry bounds have no width or height.\n if (rect.width == 0 || rect.height == 0)\n return;\n\n var cull = !validRect || !clipRect.Overlaps(rect, true);\n if (m_canvasRenderer.cull != cull)\n {\n m_canvasRenderer.cull = cull;\n onCullStateChanged.Invoke(cull);\n OnCullingChanged();\n\n // Update any potential sub mesh objects\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].canvasRenderer.cull = cull;\n }\n }\n }\n\n private Rect m_ClipRect;\n private bool m_ValidRect;\n\n /// <summary>\n /// Internal function to allow delay of culling until the text geometry has been updated.\n /// </summary>\n internal override void UpdateCulling()\n {\n // Get compound rect for the text object and sub text objects in local canvas space.\n Rect rect = GetCanvasSpaceClippingRect();\n\n // No point culling if geometry bounds have no width or height.\n if (rect.width == 0 || rect.height == 0)\n return;\n\n var cull = !m_ValidRect || !m_ClipRect.Overlaps(rect, true);\n if (m_canvasRenderer.cull != cull)\n {\n m_canvasRenderer.cull = cull;\n onCullStateChanged.Invoke(cull);\n OnCullingChanged();\n\n // Update any potential sub mesh objects\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].canvasRenderer.cull = cull;\n }\n }\n }\n\n\n /*\n /// <summary>\n /// Sets the mask type\n /// </summary>\n public MaskingTypes mask\n {\n get { return m_mask; }\n set { m_mask = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n\n\n /// <summary>\n /// Set the masking offset mode (as percentage or pixels)\n /// </summary>\n public MaskingOffsetMode maskOffsetMode\n {\n get { return m_maskOffsetMode; }\n set { m_maskOffsetMode = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n */\n\n\n /*\n /// <summary>\n /// Sets the softness of the mask\n /// </summary>\n public Vector2 maskSoftness\n {\n get { return m_maskSoftness; }\n set { m_maskSoftness = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n\n\n /// <summary>\n /// Allows to move / offset the mesh vertices by a set amount\n /// </summary>\n public Vector2 vertexOffset\n {\n get { return m_vertexOffset; }\n set { m_vertexOffset = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n */\n\n\n /// <summary>\n /// Function to be used to force recomputing of character padding when Shader / Material properties have been changed via script.\n /// </summary>\n public override void UpdateMeshPadding()\n {\n m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);\n m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);\n m_havePropertiesChanged = true;\n checkPaddingRequired = false;\n\n // Return if text object is not awake yet.\n if (m_textInfo == null) return;\n\n // Update sub text objects\n for (int i = 1; i < m_textInfo.materialCount; i++)\n m_subTextObjects[i].UpdateMeshPadding(m_enableExtraPadding, m_isUsingBold);\n }\n\n\n /// <summary>\n /// Tweens the CanvasRenderer color associated with this Graphic.\n /// </summary>\n /// <param name=\"targetColor\">Target color.</param>\n /// <param name=\"duration\">Tween duration.</param>\n /// <param name=\"ignoreTimeScale\">Should ignore Time.scale?</param>\n /// <param name=\"useAlpha\">Should also Tween the alpha channel?</param>\n protected override void InternalCrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha)\n {\n if (m_textInfo == null)\n return;\n\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 1; i < materialCount; i++)\n {\n m_subTextObjects[i].CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha);\n }\n }\n\n\n /// <summary>\n /// Tweens the alpha of the CanvasRenderer color associated with this Graphic.\n /// </summary>\n /// <param name=\"alpha\">Target alpha.</param>\n /// <param name=\"duration\">Duration of the tween in seconds.</param>\n /// <param name=\"ignoreTimeScale\">Should ignore Time.scale?</param>\n protected override void InternalCrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale)\n {\n if (m_textInfo == null)\n return;\n\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 1; i < materialCount; i++)\n {\n m_subTextObjects[i].CrossFadeAlpha(alpha, duration, ignoreTimeScale);\n }\n }\n\n\n /// <summary>\n /// Function to force regeneration of the text object before its normal process time. This is useful when changes to the text object properties need to be applied immediately.\n /// </summary>\n /// <param name=\"ignoreActiveState\">Ignore Active State of text objects. Inactive objects are ignored by default.</param>\n /// <param name=\"forceTextReparsing\">Force re-parsing of the text.</param>\n public override void ForceMeshUpdate(bool ignoreActiveState = false, bool forceTextReparsing = false)\n {\n m_havePropertiesChanged = true;\n m_ignoreActiveState = ignoreActiveState;\n\n // Special handling in the event the Canvas is only disabled\n if (m_canvas == null)\n m_canvas = GetComponentInParent<Canvas>();\n\n OnPreRenderCanvas();\n }\n\n\n /// <summary>\n /// Function used to evaluate the length of a text string.\n /// </summary>\n /// <param name=\"text\"></param>\n /// <returns></returns>\n public override TMP_TextInfo GetTextInfo(string text)\n {\n SetText(text);\n SetArraySizes(m_TextProcessingArray);\n\n m_renderMode = TextRenderFlags.DontRender;\n\n ComputeMarginSize();\n\n // Need to make sure we have a valid reference to a Canvas.\n if (m_canvas == null) m_canvas = this.canvas;\n\n GenerateTextMesh();\n\n m_renderMode = TextRenderFlags.Render;\n\n return this.textInfo;\n }\n\n\n /// <summary>\n /// Function to clear the geometry of the Primary and Sub Text objects.\n /// </summary>\n public override void ClearMesh()\n {\n m_canvasRenderer.SetMesh(null);\n\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n m_subTextObjects[i].canvasRenderer.SetMesh(null);\n }\n\n\n /// <summary>\n /// Event to allow users to modify the content of the text info before the text is rendered.\n /// </summary>\n public override event Action<TMP_TextInfo> OnPreRenderText;\n\n\n /// <summary>\n /// Function to update the geometry of the main and sub text objects.\n /// </summary>\n /// <param name=\"mesh\"></param>\n /// <param name=\"index\"></param>\n public override void UpdateGeometry(Mesh mesh, int index)\n {\n mesh.RecalculateBounds();\n\n if (index == 0)\n {\n m_canvasRenderer.SetMesh(mesh);\n }\n else\n {\n m_subTextObjects[index].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n /// <summary>\n /// Function to upload the updated vertex data and renderer.\n /// </summary>\n public override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)\n {\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 0; i < materialCount; i++)\n {\n Mesh mesh;\n\n if (i == 0)\n mesh = m_mesh;\n else\n {\n // Clear unused vertices\n // TODO: Causes issues when sorting geometry as last vertex data attribute get wiped out.\n //m_textInfo.meshInfo[i].ClearUnusedVertices();\n\n mesh = m_subTextObjects[i].mesh;\n }\n\n if ((flags & TMP_VertexDataUpdateFlags.Vertices) == TMP_VertexDataUpdateFlags.Vertices)\n mesh.vertices = m_textInfo.meshInfo[i].vertices;\n\n if ((flags & TMP_VertexDataUpdateFlags.Uv0) == TMP_VertexDataUpdateFlags.Uv0)\n mesh.uv = m_textInfo.meshInfo[i].uvs0;\n\n if ((flags & TMP_VertexDataUpdateFlags.Uv2) == TMP_VertexDataUpdateFlags.Uv2)\n mesh.uv2 = m_textInfo.meshInfo[i].uvs2;\n\n //if ((flags & TMP_VertexDataUpdateFlags.Uv4) == TMP_VertexDataUpdateFlags.Uv4)\n // mesh.uv4 = m_textInfo.meshInfo[i].uvs4;\n\n if ((flags & TMP_VertexDataUpdateFlags.Colors32) == TMP_VertexDataUpdateFlags.Colors32)\n mesh.colors32 = m_textInfo.meshInfo[i].colors32;\n\n mesh.RecalculateBounds();\n\n if (i == 0)\n m_canvasRenderer.SetMesh(mesh);\n else\n m_subTextObjects[i].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n /// <summary>\n /// Function to upload the updated vertex data and renderer.\n /// </summary>\n public override void UpdateVertexData()\n {\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 0; i < materialCount; i++)\n {\n Mesh mesh;\n\n if (i == 0)\n mesh = m_mesh;\n else\n {\n // Clear unused vertices\n m_textInfo.meshInfo[i].ClearUnusedVertices();\n\n mesh = m_subTextObjects[i].mesh;\n }\n\n //mesh.MarkDynamic();\n mesh.vertices = m_textInfo.meshInfo[i].vertices;\n mesh.uv = m_textInfo.meshInfo[i].uvs0;\n mesh.uv2 = m_textInfo.meshInfo[i].uvs2;\n //mesh.uv4 = m_textInfo.meshInfo[i].uvs4;\n mesh.colors32 = m_textInfo.meshInfo[i].colors32;\n\n mesh.RecalculateBounds();\n\n if (i == 0)\n m_canvasRenderer.SetMesh(mesh);\n else\n m_subTextObjects[i].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n public void UpdateFontAsset()\n {\n LoadFontAsset();\n }\n\n }\n}\n"
  422. },
  423. {
  424. "Script": "TextMeshProUGUI",
  425. "Material": "None",
  426. "Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  427. "Raycast Target": "True",
  428. "Raycast Padding": "(0.00, 0.00, 0.00, 0.00)",
  429. "Maskable": "True",
  430. "On Cull State Changed": "<Unsupported Type>",
  431. "Text": "",
  432. "Is Right To Left": "False",
  433. "Font Asset": "LiberationSans SDF",
  434. "Shared Material": "LiberationSans SDF Material",
  435. "Font Shared Materials": "<Unsupported Type>",
  436. "Font Material": "None",
  437. "Font Materials": "<Unsupported Type>",
  438. "Font Color 32": "RGBA(0.973, 0.804, 0.804, 1.000)",
  439. "Font Color": "RGBA(0.972, 0.802, 0.802, 1.000)",
  440. "Enable Vertex Gradient": "False",
  441. "Color Mode": "FourCornersGradient",
  442. "Font Color Gradient": "<Unsupported Type>",
  443. "Font Color Gradient Preset": "None",
  444. "Sprite Asset": "None",
  445. "Tint All Sprites": "False",
  446. "Style Sheet": "None",
  447. "Text Style Hash Code": "-1183493901",
  448. "Override Html Colors": "False",
  449. "Face Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  450. "Font Size": "30",
  451. "Font Size Base": "30",
  452. "Font Weight": "Regular",
  453. "Enable Auto Sizing": "False",
  454. "Font Size Min": "0",
  455. "Font Size Max": "0",
  456. "Font Style": "Normal",
  457. "Horizontal Alignment": "Center",
  458. "Vertical Alignment": "Middle",
  459. "Text Alignment": "Converted",
  460. "Character Spacing": "0",
  461. "Word Spacing": "0",
  462. "Line Spacing": "0",
  463. "Line Spacing Max": "0",
  464. "Paragraph Spacing": "0",
  465. "Char Width Max Adj": "0",
  466. "Enable Word Wrapping": "False",
  467. "Word Wrapping Ratios": "0.4",
  468. "Overflow Mode": "Overflow",
  469. "Linked Text Component": "None",
  470. "Parent Linked Component": "None",
  471. "Enable Kerning": "False",
  472. "Enable Extra Padding": "False",
  473. "Check Padding Required": "False",
  474. "Is Rich Text": "True",
  475. "Parse Ctrl Characters": "True",
  476. "Is Orthographic": "True",
  477. "Is Culling Enabled": "False",
  478. "Horizontal Mapping": "Character",
  479. "Vertical Mapping": "Character",
  480. "Uv Line Offset": "0",
  481. "Geometry Sorting Order": "Normal",
  482. "Is Text Object Scale Static": "False",
  483. "Vertex Buffer Auto Size Reduction": "False",
  484. "Use Max Visible Descender": "True",
  485. "Page To Display": "1",
  486. "Margin": "(0.00, 0.00, 0.00, 0.00)",
  487. "Is Using Legacy Animation Component": "False",
  488. "Is Volumetric Text": "False",
  489. "Has Font Asset Changed": "False",
  490. "Base Material": "None",
  491. "Mask Offset": "(0.00, 0.00, 0.00, 0.00)"
  492. }
  493. ],
  494. "Children": []
  495. }
  496. ]
  497. },
  498. {
  499. "Name": "Counting Text",
  500. "Components": [
  501. {
  502. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  503. "Local Position": "(0.00, 95.00, 0.00)",
  504. "Local Scale": "(1.00, 1.00, 1.00)",
  505. "Constrain Proportions Scale": "False",
  506. "Anchor Min": "(0.50, 0.50)",
  507. "Anchor Max": "(0.50, 0.50)",
  508. "Anchored Position": "(0.00, 95.00)",
  509. "Size Delta": "(200.00, 50.00)",
  510. "Pivot": "(0.50, 0.50)"
  511. },
  512. {
  513. "Cull Transparent Mesh": "True"
  514. },
  515. {
  516. "Name": "TextMeshProUGUI",
  517. "Content": "using System;\nusing System.Collections;\nusing UnityEngine;\nusing UnityEngine.Rendering;\nusing UnityEngine.UI;\n\n#pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor.\n\n\nnamespace TMPro\n{\n [DisallowMultipleComponent]\n [RequireComponent(typeof(RectTransform))]\n [RequireComponent(typeof(CanvasRenderer))]\n [AddComponentMenu(\"UI/TextMeshPro - Text (UI)\", 11)]\n [ExecuteAlways]\n [HelpURL(\"https://docs.unity3d.com/Packages/[email protected]\")]\n public partial class TextMeshProUGUI : TMP_Text, ILayoutElement\n {\n /// <summary>\n /// Get the material that will be used for rendering.\n /// </summary>\n public override Material materialForRendering\n {\n get { return TMP_MaterialManager.GetMaterialForRendering(this, m_sharedMaterial); }\n }\n\n\n /// <summary>\n /// Determines if the size of the text container will be adjusted to fit the text object when it is first created.\n /// </summary>\n public override bool autoSizeTextContainer\n {\n get { return m_autoSizeTextContainer; }\n\n set { if (m_autoSizeTextContainer == value) return; m_autoSizeTextContainer = value; if (m_autoSizeTextContainer) { CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); SetLayoutDirty(); } }\n }\n\n\n /// <summary>\n /// Reference to the Mesh used by the text object.\n /// </summary>\n public override Mesh mesh\n {\n get { return m_mesh; }\n }\n\n\n /// <summary>\n /// Reference to the CanvasRenderer used by the text object.\n /// </summary>\n public new CanvasRenderer canvasRenderer\n {\n get\n {\n if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();\n\n return m_canvasRenderer;\n }\n }\n\n\n /// <summary>\n /// Anchor dampening prevents the anchor position from being adjusted unless the positional change exceeds about 40% of the width of the underline character. This essentially stabilizes the anchor position.\n /// </summary>\n //public bool anchorDampening\n //{\n // get { return m_anchorDampening; }\n // set { if (m_anchorDampening != value) { havePropertiesChanged = true; m_anchorDampening = value; /* ScheduleUpdate(); */ } }\n //}\n\n #if !UNITY_2019_3_OR_NEWER\n [SerializeField]\n private bool m_Maskable = true;\n #endif\n\n private bool m_isRebuildingLayout = false;\n private Coroutine m_DelayedGraphicRebuild;\n private Coroutine m_DelayedMaterialRebuild;\n\n /// <summary>\n /// Function called by Unity when the horizontal layout needs to be recalculated.\n /// </summary>\n public void CalculateLayoutInputHorizontal()\n {\n //Debug.Log(\"*** CalculateLayoutHorizontal() on Object ID: \" + GetInstanceID() + \" at frame: \" + Time.frameCount + \"***\");\n }\n\n\n /// <summary>\n /// Function called by Unity when the vertical layout needs to be recalculated.\n /// </summary>\n public void CalculateLayoutInputVertical()\n {\n //Debug.Log(\"*** CalculateLayoutInputVertical() on Object ID: \" + GetInstanceID() + \" at frame: \" + Time.frameCount + \"***\");\n }\n\n\n public override void SetVerticesDirty()\n {\n if (this == null || !this.IsActive())\n return;\n\n if (CanvasUpdateRegistry.IsRebuildingGraphics())\n return;\n\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyVertsCallback != null)\n m_OnDirtyVertsCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetLayoutDirty()\n {\n m_isPreferredWidthDirty = true;\n m_isPreferredHeightDirty = true;\n\n if (this == null || !this.IsActive())\n return;\n\n LayoutRebuilder.MarkLayoutForRebuild(this.rectTransform);\n\n m_isLayoutDirty = true;\n\n if (m_OnDirtyLayoutCallback != null)\n m_OnDirtyLayoutCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetMaterialDirty()\n {\n if (this == null || !this.IsActive())\n return;\n\n if (CanvasUpdateRegistry.IsRebuildingGraphics())\n return;\n\n m_isMaterialDirty = true;\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyMaterialCallback != null)\n m_OnDirtyMaterialCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetAllDirty()\n {\n SetLayoutDirty();\n SetVerticesDirty();\n SetMaterialDirty();\n }\n\n\n /// <summary>\n /// Delay registration of text object for graphic rebuild by one frame.\n /// </summary>\n /// <returns></returns>\n IEnumerator DelayedGraphicRebuild()\n {\n yield return null;\n\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyVertsCallback != null)\n m_OnDirtyVertsCallback();\n\n m_DelayedGraphicRebuild = null;\n }\n\n\n /// <summary>\n /// Delay registration of text object for graphic rebuild by one frame.\n /// </summary>\n /// <returns></returns>\n IEnumerator DelayedMaterialRebuild()\n {\n yield return null;\n\n m_isMaterialDirty = true;\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyMaterialCallback != null)\n m_OnDirtyMaterialCallback();\n\n m_DelayedMaterialRebuild = null;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n /// <param name=\"update\"></param>\n public override void Rebuild(CanvasUpdate update)\n {\n if (this == null) return;\n\n if (update == CanvasUpdate.Prelayout)\n {\n if (m_autoSizeTextContainer)\n {\n m_rectTransform.sizeDelta = GetPreferredValues(Mathf.Infinity, Mathf.Infinity);\n }\n }\n else if (update == CanvasUpdate.PreRender)\n {\n OnPreRenderCanvas();\n\n if (!m_isMaterialDirty) return;\n\n UpdateMaterial();\n m_isMaterialDirty = false;\n }\n }\n\n\n /// <summary>\n /// Method to keep the pivot of the sub text objects in sync with the parent pivot.\n /// </summary>\n private void UpdateSubObjectPivot()\n {\n if (m_textInfo == null) return;\n\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].SetPivotDirty();\n }\n //m_isPivotDirty = false;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n /// <param name=\"baseMaterial\"></param>\n /// <returns></returns>\n public override Material GetModifiedMaterial(Material baseMaterial)\n {\n Material mat = baseMaterial;\n\n if (m_ShouldRecalculateStencil)\n {\n var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);\n m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0;\n m_ShouldRecalculateStencil = false;\n }\n\n if (m_StencilValue > 0)\n {\n var maskMat = StencilMaterial.Add(mat, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0);\n StencilMaterial.Remove(m_MaskMaterial);\n m_MaskMaterial = maskMat;\n mat = m_MaskMaterial;\n }\n\n return mat;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n protected override void UpdateMaterial()\n {\n //Debug.Log(\"*** UpdateMaterial() ***\");\n\n //if (!this.IsActive())\n // return;\n\n if (m_sharedMaterial == null || canvasRenderer == null) return;\n\n m_canvasRenderer.materialCount = 1;\n m_canvasRenderer.SetMaterial(materialForRendering, 0);\n //m_canvasRenderer.SetTexture(materialForRendering.mainTexture);\n }\n\n\n //public override void OnRebuildRequested()\n //{\n // //Debug.Log(\"OnRebuildRequested\");\n\n // base.OnRebuildRequested();\n //}\n\n\n\n //public override bool Raycast(Vector2 sp, Camera eventCamera)\n //{\n // //Debug.Log(\"Raycast Event. ScreenPoint: \" + sp);\n // return base.Raycast(sp, eventCamera);\n //}\n\n\n // MASKING RELATED PROPERTIES\n /// <summary>\n /// Sets the masking offset from the bounds of the object\n /// </summary>\n public Vector4 maskOffset\n {\n get { return m_maskOffset; }\n set { m_maskOffset = value; UpdateMask(); m_havePropertiesChanged = true; }\n }\n\n\n //public override Material defaultMaterial\n //{\n // get { Debug.Log(\"Default Material called.\"); return m_sharedMaterial; }\n //}\n\n\n\n //protected override void OnCanvasHierarchyChanged()\n //{\n // //Debug.Log(\"OnCanvasHierarchyChanged...\");\n //}\n\n\n // IClippable implementation\n /// <summary>\n /// Method called when the state of a parent changes.\n /// </summary>\n public override void RecalculateClipping()\n {\n //Debug.Log(\"***** RecalculateClipping() *****\");\n\n base.RecalculateClipping();\n }\n\n\n // IMaskable Implementation\n /// <summary>\n /// Method called when Stencil Mask needs to be updated on this element and parents.\n /// </summary>\n // public override void RecalculateMasking()\n // {\n // //Debug.Log(\"***** RecalculateMasking() *****\");\n //\n // this.m_ShouldRecalculateStencil = true;\n // SetMaterialDirty();\n // }\n\n\n //public override void SetClipRect(Rect clipRect, bool validRect)\n //{\n // //Debug.Log(\"***** SetClipRect (\" + clipRect + \", \" + validRect + \") *****\");\n\n // base.SetClipRect(clipRect, validRect);\n //}\n\n\n /// <summary>\n /// Override of the Cull function to provide for the ability to override the culling of the text object.\n /// </summary>\n /// <param name=\"clipRect\"></param>\n /// <param name=\"validRect\"></param>\n public override void Cull(Rect clipRect, bool validRect)\n {\n // Delay culling check in the event the text layout is dirty and geometry has to be updated.\n if (m_isLayoutDirty)\n {\n TMP_UpdateManager.RegisterTextElementForCullingUpdate(this);\n m_ClipRect = clipRect;\n m_ValidRect = validRect;\n return;\n }\n\n // Get compound rect for the text object and sub text objects in local canvas space.\n Rect rect = GetCanvasSpaceClippingRect();\n\n // No point culling if geometry bounds have no width or height.\n if (rect.width == 0 || rect.height == 0)\n return;\n\n var cull = !validRect || !clipRect.Overlaps(rect, true);\n if (m_canvasRenderer.cull != cull)\n {\n m_canvasRenderer.cull = cull;\n onCullStateChanged.Invoke(cull);\n OnCullingChanged();\n\n // Update any potential sub mesh objects\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].canvasRenderer.cull = cull;\n }\n }\n }\n\n private Rect m_ClipRect;\n private bool m_ValidRect;\n\n /// <summary>\n /// Internal function to allow delay of culling until the text geometry has been updated.\n /// </summary>\n internal override void UpdateCulling()\n {\n // Get compound rect for the text object and sub text objects in local canvas space.\n Rect rect = GetCanvasSpaceClippingRect();\n\n // No point culling if geometry bounds have no width or height.\n if (rect.width == 0 || rect.height == 0)\n return;\n\n var cull = !m_ValidRect || !m_ClipRect.Overlaps(rect, true);\n if (m_canvasRenderer.cull != cull)\n {\n m_canvasRenderer.cull = cull;\n onCullStateChanged.Invoke(cull);\n OnCullingChanged();\n\n // Update any potential sub mesh objects\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].canvasRenderer.cull = cull;\n }\n }\n }\n\n\n /*\n /// <summary>\n /// Sets the mask type\n /// </summary>\n public MaskingTypes mask\n {\n get { return m_mask; }\n set { m_mask = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n\n\n /// <summary>\n /// Set the masking offset mode (as percentage or pixels)\n /// </summary>\n public MaskingOffsetMode maskOffsetMode\n {\n get { return m_maskOffsetMode; }\n set { m_maskOffsetMode = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n */\n\n\n /*\n /// <summary>\n /// Sets the softness of the mask\n /// </summary>\n public Vector2 maskSoftness\n {\n get { return m_maskSoftness; }\n set { m_maskSoftness = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n\n\n /// <summary>\n /// Allows to move / offset the mesh vertices by a set amount\n /// </summary>\n public Vector2 vertexOffset\n {\n get { return m_vertexOffset; }\n set { m_vertexOffset = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n */\n\n\n /// <summary>\n /// Function to be used to force recomputing of character padding when Shader / Material properties have been changed via script.\n /// </summary>\n public override void UpdateMeshPadding()\n {\n m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);\n m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);\n m_havePropertiesChanged = true;\n checkPaddingRequired = false;\n\n // Return if text object is not awake yet.\n if (m_textInfo == null) return;\n\n // Update sub text objects\n for (int i = 1; i < m_textInfo.materialCount; i++)\n m_subTextObjects[i].UpdateMeshPadding(m_enableExtraPadding, m_isUsingBold);\n }\n\n\n /// <summary>\n /// Tweens the CanvasRenderer color associated with this Graphic.\n /// </summary>\n /// <param name=\"targetColor\">Target color.</param>\n /// <param name=\"duration\">Tween duration.</param>\n /// <param name=\"ignoreTimeScale\">Should ignore Time.scale?</param>\n /// <param name=\"useAlpha\">Should also Tween the alpha channel?</param>\n protected override void InternalCrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha)\n {\n if (m_textInfo == null)\n return;\n\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 1; i < materialCount; i++)\n {\n m_subTextObjects[i].CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha);\n }\n }\n\n\n /// <summary>\n /// Tweens the alpha of the CanvasRenderer color associated with this Graphic.\n /// </summary>\n /// <param name=\"alpha\">Target alpha.</param>\n /// <param name=\"duration\">Duration of the tween in seconds.</param>\n /// <param name=\"ignoreTimeScale\">Should ignore Time.scale?</param>\n protected override void InternalCrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale)\n {\n if (m_textInfo == null)\n return;\n\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 1; i < materialCount; i++)\n {\n m_subTextObjects[i].CrossFadeAlpha(alpha, duration, ignoreTimeScale);\n }\n }\n\n\n /// <summary>\n /// Function to force regeneration of the text object before its normal process time. This is useful when changes to the text object properties need to be applied immediately.\n /// </summary>\n /// <param name=\"ignoreActiveState\">Ignore Active State of text objects. Inactive objects are ignored by default.</param>\n /// <param name=\"forceTextReparsing\">Force re-parsing of the text.</param>\n public override void ForceMeshUpdate(bool ignoreActiveState = false, bool forceTextReparsing = false)\n {\n m_havePropertiesChanged = true;\n m_ignoreActiveState = ignoreActiveState;\n\n // Special handling in the event the Canvas is only disabled\n if (m_canvas == null)\n m_canvas = GetComponentInParent<Canvas>();\n\n OnPreRenderCanvas();\n }\n\n\n /// <summary>\n /// Function used to evaluate the length of a text string.\n /// </summary>\n /// <param name=\"text\"></param>\n /// <returns></returns>\n public override TMP_TextInfo GetTextInfo(string text)\n {\n SetText(text);\n SetArraySizes(m_TextProcessingArray);\n\n m_renderMode = TextRenderFlags.DontRender;\n\n ComputeMarginSize();\n\n // Need to make sure we have a valid reference to a Canvas.\n if (m_canvas == null) m_canvas = this.canvas;\n\n GenerateTextMesh();\n\n m_renderMode = TextRenderFlags.Render;\n\n return this.textInfo;\n }\n\n\n /// <summary>\n /// Function to clear the geometry of the Primary and Sub Text objects.\n /// </summary>\n public override void ClearMesh()\n {\n m_canvasRenderer.SetMesh(null);\n\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n m_subTextObjects[i].canvasRenderer.SetMesh(null);\n }\n\n\n /// <summary>\n /// Event to allow users to modify the content of the text info before the text is rendered.\n /// </summary>\n public override event Action<TMP_TextInfo> OnPreRenderText;\n\n\n /// <summary>\n /// Function to update the geometry of the main and sub text objects.\n /// </summary>\n /// <param name=\"mesh\"></param>\n /// <param name=\"index\"></param>\n public override void UpdateGeometry(Mesh mesh, int index)\n {\n mesh.RecalculateBounds();\n\n if (index == 0)\n {\n m_canvasRenderer.SetMesh(mesh);\n }\n else\n {\n m_subTextObjects[index].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n /// <summary>\n /// Function to upload the updated vertex data and renderer.\n /// </summary>\n public override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)\n {\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 0; i < materialCount; i++)\n {\n Mesh mesh;\n\n if (i == 0)\n mesh = m_mesh;\n else\n {\n // Clear unused vertices\n // TODO: Causes issues when sorting geometry as last vertex data attribute get wiped out.\n //m_textInfo.meshInfo[i].ClearUnusedVertices();\n\n mesh = m_subTextObjects[i].mesh;\n }\n\n if ((flags & TMP_VertexDataUpdateFlags.Vertices) == TMP_VertexDataUpdateFlags.Vertices)\n mesh.vertices = m_textInfo.meshInfo[i].vertices;\n\n if ((flags & TMP_VertexDataUpdateFlags.Uv0) == TMP_VertexDataUpdateFlags.Uv0)\n mesh.uv = m_textInfo.meshInfo[i].uvs0;\n\n if ((flags & TMP_VertexDataUpdateFlags.Uv2) == TMP_VertexDataUpdateFlags.Uv2)\n mesh.uv2 = m_textInfo.meshInfo[i].uvs2;\n\n //if ((flags & TMP_VertexDataUpdateFlags.Uv4) == TMP_VertexDataUpdateFlags.Uv4)\n // mesh.uv4 = m_textInfo.meshInfo[i].uvs4;\n\n if ((flags & TMP_VertexDataUpdateFlags.Colors32) == TMP_VertexDataUpdateFlags.Colors32)\n mesh.colors32 = m_textInfo.meshInfo[i].colors32;\n\n mesh.RecalculateBounds();\n\n if (i == 0)\n m_canvasRenderer.SetMesh(mesh);\n else\n m_subTextObjects[i].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n /// <summary>\n /// Function to upload the updated vertex data and renderer.\n /// </summary>\n public override void UpdateVertexData()\n {\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 0; i < materialCount; i++)\n {\n Mesh mesh;\n\n if (i == 0)\n mesh = m_mesh;\n else\n {\n // Clear unused vertices\n m_textInfo.meshInfo[i].ClearUnusedVertices();\n\n mesh = m_subTextObjects[i].mesh;\n }\n\n //mesh.MarkDynamic();\n mesh.vertices = m_textInfo.meshInfo[i].vertices;\n mesh.uv = m_textInfo.meshInfo[i].uvs0;\n mesh.uv2 = m_textInfo.meshInfo[i].uvs2;\n //mesh.uv4 = m_textInfo.meshInfo[i].uvs4;\n mesh.colors32 = m_textInfo.meshInfo[i].colors32;\n\n mesh.RecalculateBounds();\n\n if (i == 0)\n m_canvasRenderer.SetMesh(mesh);\n else\n m_subTextObjects[i].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n public void UpdateFontAsset()\n {\n LoadFontAsset();\n }\n\n }\n}\n"
  518. },
  519. {
  520. "Script": "TextMeshProUGUI",
  521. "Material": "None",
  522. "Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  523. "Raycast Target": "True",
  524. "Raycast Padding": "(0.00, 0.00, 0.00, 0.00)",
  525. "Maskable": "True",
  526. "On Cull State Changed": "<Unsupported Type>",
  527. "Text": "",
  528. "Is Right To Left": "False",
  529. "Font Asset": "LiberationSans SDF",
  530. "Shared Material": "LiberationSans SDF Material",
  531. "Font Shared Materials": "<Unsupported Type>",
  532. "Font Material": "None",
  533. "Font Materials": "<Unsupported Type>",
  534. "Font Color 32": "RGBA(1.000, 0.000, 0.000, 1.000)",
  535. "Font Color": "RGBA(1.000, 0.000, 0.000, 1.000)",
  536. "Enable Vertex Gradient": "False",
  537. "Color Mode": "FourCornersGradient",
  538. "Font Color Gradient": "<Unsupported Type>",
  539. "Font Color Gradient Preset": "None",
  540. "Sprite Asset": "None",
  541. "Tint All Sprites": "False",
  542. "Style Sheet": "None",
  543. "Text Style Hash Code": "-1183493901",
  544. "Override Html Colors": "False",
  545. "Face Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  546. "Font Size": "200",
  547. "Font Size Base": "200",
  548. "Font Weight": "Regular",
  549. "Enable Auto Sizing": "False",
  550. "Font Size Min": "18",
  551. "Font Size Max": "72",
  552. "Font Style": "Normal",
  553. "Horizontal Alignment": "Left",
  554. "Vertical Alignment": "Top",
  555. "Text Alignment": "Converted",
  556. "Character Spacing": "0",
  557. "Word Spacing": "0",
  558. "Line Spacing": "0",
  559. "Line Spacing Max": "0",
  560. "Paragraph Spacing": "0",
  561. "Char Width Max Adj": "0",
  562. "Enable Word Wrapping": "True",
  563. "Word Wrapping Ratios": "0.4",
  564. "Overflow Mode": "Overflow",
  565. "Linked Text Component": "None",
  566. "Parent Linked Component": "None",
  567. "Enable Kerning": "True",
  568. "Enable Extra Padding": "False",
  569. "Check Padding Required": "False",
  570. "Is Rich Text": "True",
  571. "Parse Ctrl Characters": "True",
  572. "Is Orthographic": "True",
  573. "Is Culling Enabled": "False",
  574. "Horizontal Mapping": "Character",
  575. "Vertical Mapping": "Character",
  576. "Uv Line Offset": "0",
  577. "Geometry Sorting Order": "Normal",
  578. "Is Text Object Scale Static": "False",
  579. "Vertex Buffer Auto Size Reduction": "False",
  580. "Use Max Visible Descender": "True",
  581. "Page To Display": "1",
  582. "Margin": "(0.00, 0.00, 0.00, 0.00)",
  583. "Is Using Legacy Animation Component": "False",
  584. "Is Volumetric Text": "False",
  585. "Has Font Asset Changed": "False",
  586. "Base Material": "None",
  587. "Mask Offset": "(0.00, 0.00, 0.00, 0.00)"
  588. }
  589. ],
  590. "Children": []
  591. },
  592. {
  593. "Name": "Frame Rate",
  594. "Components": [
  595. {
  596. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  597. "Local Position": "(-450.00, 16.00, 0.00)",
  598. "Local Scale": "(1.00, 1.00, 1.00)",
  599. "Constrain Proportions Scale": "False",
  600. "Anchor Min": "(0.50, 0.50)",
  601. "Anchor Max": "(0.50, 0.50)",
  602. "Anchored Position": "(-450.00, 16.00)",
  603. "Size Delta": "(300.00, 50.00)",
  604. "Pivot": "(0.50, 0.50)"
  605. },
  606. {
  607. "Cull Transparent Mesh": "True"
  608. },
  609. {
  610. "Name": "TextMeshProUGUI",
  611. "Content": "using System;\nusing System.Collections;\nusing UnityEngine;\nusing UnityEngine.Rendering;\nusing UnityEngine.UI;\n\n#pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor.\n\n\nnamespace TMPro\n{\n [DisallowMultipleComponent]\n [RequireComponent(typeof(RectTransform))]\n [RequireComponent(typeof(CanvasRenderer))]\n [AddComponentMenu(\"UI/TextMeshPro - Text (UI)\", 11)]\n [ExecuteAlways]\n [HelpURL(\"https://docs.unity3d.com/Packages/[email protected]\")]\n public partial class TextMeshProUGUI : TMP_Text, ILayoutElement\n {\n /// <summary>\n /// Get the material that will be used for rendering.\n /// </summary>\n public override Material materialForRendering\n {\n get { return TMP_MaterialManager.GetMaterialForRendering(this, m_sharedMaterial); }\n }\n\n\n /// <summary>\n /// Determines if the size of the text container will be adjusted to fit the text object when it is first created.\n /// </summary>\n public override bool autoSizeTextContainer\n {\n get { return m_autoSizeTextContainer; }\n\n set { if (m_autoSizeTextContainer == value) return; m_autoSizeTextContainer = value; if (m_autoSizeTextContainer) { CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); SetLayoutDirty(); } }\n }\n\n\n /// <summary>\n /// Reference to the Mesh used by the text object.\n /// </summary>\n public override Mesh mesh\n {\n get { return m_mesh; }\n }\n\n\n /// <summary>\n /// Reference to the CanvasRenderer used by the text object.\n /// </summary>\n public new CanvasRenderer canvasRenderer\n {\n get\n {\n if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();\n\n return m_canvasRenderer;\n }\n }\n\n\n /// <summary>\n /// Anchor dampening prevents the anchor position from being adjusted unless the positional change exceeds about 40% of the width of the underline character. This essentially stabilizes the anchor position.\n /// </summary>\n //public bool anchorDampening\n //{\n // get { return m_anchorDampening; }\n // set { if (m_anchorDampening != value) { havePropertiesChanged = true; m_anchorDampening = value; /* ScheduleUpdate(); */ } }\n //}\n\n #if !UNITY_2019_3_OR_NEWER\n [SerializeField]\n private bool m_Maskable = true;\n #endif\n\n private bool m_isRebuildingLayout = false;\n private Coroutine m_DelayedGraphicRebuild;\n private Coroutine m_DelayedMaterialRebuild;\n\n /// <summary>\n /// Function called by Unity when the horizontal layout needs to be recalculated.\n /// </summary>\n public void CalculateLayoutInputHorizontal()\n {\n //Debug.Log(\"*** CalculateLayoutHorizontal() on Object ID: \" + GetInstanceID() + \" at frame: \" + Time.frameCount + \"***\");\n }\n\n\n /// <summary>\n /// Function called by Unity when the vertical layout needs to be recalculated.\n /// </summary>\n public void CalculateLayoutInputVertical()\n {\n //Debug.Log(\"*** CalculateLayoutInputVertical() on Object ID: \" + GetInstanceID() + \" at frame: \" + Time.frameCount + \"***\");\n }\n\n\n public override void SetVerticesDirty()\n {\n if (this == null || !this.IsActive())\n return;\n\n if (CanvasUpdateRegistry.IsRebuildingGraphics())\n return;\n\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyVertsCallback != null)\n m_OnDirtyVertsCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetLayoutDirty()\n {\n m_isPreferredWidthDirty = true;\n m_isPreferredHeightDirty = true;\n\n if (this == null || !this.IsActive())\n return;\n\n LayoutRebuilder.MarkLayoutForRebuild(this.rectTransform);\n\n m_isLayoutDirty = true;\n\n if (m_OnDirtyLayoutCallback != null)\n m_OnDirtyLayoutCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetMaterialDirty()\n {\n if (this == null || !this.IsActive())\n return;\n\n if (CanvasUpdateRegistry.IsRebuildingGraphics())\n return;\n\n m_isMaterialDirty = true;\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyMaterialCallback != null)\n m_OnDirtyMaterialCallback();\n }\n\n\n /// <summary>\n ///\n /// </summary>\n public override void SetAllDirty()\n {\n SetLayoutDirty();\n SetVerticesDirty();\n SetMaterialDirty();\n }\n\n\n /// <summary>\n /// Delay registration of text object for graphic rebuild by one frame.\n /// </summary>\n /// <returns></returns>\n IEnumerator DelayedGraphicRebuild()\n {\n yield return null;\n\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyVertsCallback != null)\n m_OnDirtyVertsCallback();\n\n m_DelayedGraphicRebuild = null;\n }\n\n\n /// <summary>\n /// Delay registration of text object for graphic rebuild by one frame.\n /// </summary>\n /// <returns></returns>\n IEnumerator DelayedMaterialRebuild()\n {\n yield return null;\n\n m_isMaterialDirty = true;\n CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);\n\n if (m_OnDirtyMaterialCallback != null)\n m_OnDirtyMaterialCallback();\n\n m_DelayedMaterialRebuild = null;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n /// <param name=\"update\"></param>\n public override void Rebuild(CanvasUpdate update)\n {\n if (this == null) return;\n\n if (update == CanvasUpdate.Prelayout)\n {\n if (m_autoSizeTextContainer)\n {\n m_rectTransform.sizeDelta = GetPreferredValues(Mathf.Infinity, Mathf.Infinity);\n }\n }\n else if (update == CanvasUpdate.PreRender)\n {\n OnPreRenderCanvas();\n\n if (!m_isMaterialDirty) return;\n\n UpdateMaterial();\n m_isMaterialDirty = false;\n }\n }\n\n\n /// <summary>\n /// Method to keep the pivot of the sub text objects in sync with the parent pivot.\n /// </summary>\n private void UpdateSubObjectPivot()\n {\n if (m_textInfo == null) return;\n\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].SetPivotDirty();\n }\n //m_isPivotDirty = false;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n /// <param name=\"baseMaterial\"></param>\n /// <returns></returns>\n public override Material GetModifiedMaterial(Material baseMaterial)\n {\n Material mat = baseMaterial;\n\n if (m_ShouldRecalculateStencil)\n {\n var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);\n m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0;\n m_ShouldRecalculateStencil = false;\n }\n\n if (m_StencilValue > 0)\n {\n var maskMat = StencilMaterial.Add(mat, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0);\n StencilMaterial.Remove(m_MaskMaterial);\n m_MaskMaterial = maskMat;\n mat = m_MaskMaterial;\n }\n\n return mat;\n }\n\n\n /// <summary>\n ///\n /// </summary>\n protected override void UpdateMaterial()\n {\n //Debug.Log(\"*** UpdateMaterial() ***\");\n\n //if (!this.IsActive())\n // return;\n\n if (m_sharedMaterial == null || canvasRenderer == null) return;\n\n m_canvasRenderer.materialCount = 1;\n m_canvasRenderer.SetMaterial(materialForRendering, 0);\n //m_canvasRenderer.SetTexture(materialForRendering.mainTexture);\n }\n\n\n //public override void OnRebuildRequested()\n //{\n // //Debug.Log(\"OnRebuildRequested\");\n\n // base.OnRebuildRequested();\n //}\n\n\n\n //public override bool Raycast(Vector2 sp, Camera eventCamera)\n //{\n // //Debug.Log(\"Raycast Event. ScreenPoint: \" + sp);\n // return base.Raycast(sp, eventCamera);\n //}\n\n\n // MASKING RELATED PROPERTIES\n /// <summary>\n /// Sets the masking offset from the bounds of the object\n /// </summary>\n public Vector4 maskOffset\n {\n get { return m_maskOffset; }\n set { m_maskOffset = value; UpdateMask(); m_havePropertiesChanged = true; }\n }\n\n\n //public override Material defaultMaterial\n //{\n // get { Debug.Log(\"Default Material called.\"); return m_sharedMaterial; }\n //}\n\n\n\n //protected override void OnCanvasHierarchyChanged()\n //{\n // //Debug.Log(\"OnCanvasHierarchyChanged...\");\n //}\n\n\n // IClippable implementation\n /// <summary>\n /// Method called when the state of a parent changes.\n /// </summary>\n public override void RecalculateClipping()\n {\n //Debug.Log(\"***** RecalculateClipping() *****\");\n\n base.RecalculateClipping();\n }\n\n\n // IMaskable Implementation\n /// <summary>\n /// Method called when Stencil Mask needs to be updated on this element and parents.\n /// </summary>\n // public override void RecalculateMasking()\n // {\n // //Debug.Log(\"***** RecalculateMasking() *****\");\n //\n // this.m_ShouldRecalculateStencil = true;\n // SetMaterialDirty();\n // }\n\n\n //public override void SetClipRect(Rect clipRect, bool validRect)\n //{\n // //Debug.Log(\"***** SetClipRect (\" + clipRect + \", \" + validRect + \") *****\");\n\n // base.SetClipRect(clipRect, validRect);\n //}\n\n\n /// <summary>\n /// Override of the Cull function to provide for the ability to override the culling of the text object.\n /// </summary>\n /// <param name=\"clipRect\"></param>\n /// <param name=\"validRect\"></param>\n public override void Cull(Rect clipRect, bool validRect)\n {\n // Delay culling check in the event the text layout is dirty and geometry has to be updated.\n if (m_isLayoutDirty)\n {\n TMP_UpdateManager.RegisterTextElementForCullingUpdate(this);\n m_ClipRect = clipRect;\n m_ValidRect = validRect;\n return;\n }\n\n // Get compound rect for the text object and sub text objects in local canvas space.\n Rect rect = GetCanvasSpaceClippingRect();\n\n // No point culling if geometry bounds have no width or height.\n if (rect.width == 0 || rect.height == 0)\n return;\n\n var cull = !validRect || !clipRect.Overlaps(rect, true);\n if (m_canvasRenderer.cull != cull)\n {\n m_canvasRenderer.cull = cull;\n onCullStateChanged.Invoke(cull);\n OnCullingChanged();\n\n // Update any potential sub mesh objects\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].canvasRenderer.cull = cull;\n }\n }\n }\n\n private Rect m_ClipRect;\n private bool m_ValidRect;\n\n /// <summary>\n /// Internal function to allow delay of culling until the text geometry has been updated.\n /// </summary>\n internal override void UpdateCulling()\n {\n // Get compound rect for the text object and sub text objects in local canvas space.\n Rect rect = GetCanvasSpaceClippingRect();\n\n // No point culling if geometry bounds have no width or height.\n if (rect.width == 0 || rect.height == 0)\n return;\n\n var cull = !m_ValidRect || !m_ClipRect.Overlaps(rect, true);\n if (m_canvasRenderer.cull != cull)\n {\n m_canvasRenderer.cull = cull;\n onCullStateChanged.Invoke(cull);\n OnCullingChanged();\n\n // Update any potential sub mesh objects\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n {\n m_subTextObjects[i].canvasRenderer.cull = cull;\n }\n }\n }\n\n\n /*\n /// <summary>\n /// Sets the mask type\n /// </summary>\n public MaskingTypes mask\n {\n get { return m_mask; }\n set { m_mask = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n\n\n /// <summary>\n /// Set the masking offset mode (as percentage or pixels)\n /// </summary>\n public MaskingOffsetMode maskOffsetMode\n {\n get { return m_maskOffsetMode; }\n set { m_maskOffsetMode = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n */\n\n\n /*\n /// <summary>\n /// Sets the softness of the mask\n /// </summary>\n public Vector2 maskSoftness\n {\n get { return m_maskSoftness; }\n set { m_maskSoftness = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n\n\n /// <summary>\n /// Allows to move / offset the mesh vertices by a set amount\n /// </summary>\n public Vector2 vertexOffset\n {\n get { return m_vertexOffset; }\n set { m_vertexOffset = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }\n }\n */\n\n\n /// <summary>\n /// Function to be used to force recomputing of character padding when Shader / Material properties have been changed via script.\n /// </summary>\n public override void UpdateMeshPadding()\n {\n m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);\n m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);\n m_havePropertiesChanged = true;\n checkPaddingRequired = false;\n\n // Return if text object is not awake yet.\n if (m_textInfo == null) return;\n\n // Update sub text objects\n for (int i = 1; i < m_textInfo.materialCount; i++)\n m_subTextObjects[i].UpdateMeshPadding(m_enableExtraPadding, m_isUsingBold);\n }\n\n\n /// <summary>\n /// Tweens the CanvasRenderer color associated with this Graphic.\n /// </summary>\n /// <param name=\"targetColor\">Target color.</param>\n /// <param name=\"duration\">Tween duration.</param>\n /// <param name=\"ignoreTimeScale\">Should ignore Time.scale?</param>\n /// <param name=\"useAlpha\">Should also Tween the alpha channel?</param>\n protected override void InternalCrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha)\n {\n if (m_textInfo == null)\n return;\n\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 1; i < materialCount; i++)\n {\n m_subTextObjects[i].CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha);\n }\n }\n\n\n /// <summary>\n /// Tweens the alpha of the CanvasRenderer color associated with this Graphic.\n /// </summary>\n /// <param name=\"alpha\">Target alpha.</param>\n /// <param name=\"duration\">Duration of the tween in seconds.</param>\n /// <param name=\"ignoreTimeScale\">Should ignore Time.scale?</param>\n protected override void InternalCrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale)\n {\n if (m_textInfo == null)\n return;\n\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 1; i < materialCount; i++)\n {\n m_subTextObjects[i].CrossFadeAlpha(alpha, duration, ignoreTimeScale);\n }\n }\n\n\n /// <summary>\n /// Function to force regeneration of the text object before its normal process time. This is useful when changes to the text object properties need to be applied immediately.\n /// </summary>\n /// <param name=\"ignoreActiveState\">Ignore Active State of text objects. Inactive objects are ignored by default.</param>\n /// <param name=\"forceTextReparsing\">Force re-parsing of the text.</param>\n public override void ForceMeshUpdate(bool ignoreActiveState = false, bool forceTextReparsing = false)\n {\n m_havePropertiesChanged = true;\n m_ignoreActiveState = ignoreActiveState;\n\n // Special handling in the event the Canvas is only disabled\n if (m_canvas == null)\n m_canvas = GetComponentInParent<Canvas>();\n\n OnPreRenderCanvas();\n }\n\n\n /// <summary>\n /// Function used to evaluate the length of a text string.\n /// </summary>\n /// <param name=\"text\"></param>\n /// <returns></returns>\n public override TMP_TextInfo GetTextInfo(string text)\n {\n SetText(text);\n SetArraySizes(m_TextProcessingArray);\n\n m_renderMode = TextRenderFlags.DontRender;\n\n ComputeMarginSize();\n\n // Need to make sure we have a valid reference to a Canvas.\n if (m_canvas == null) m_canvas = this.canvas;\n\n GenerateTextMesh();\n\n m_renderMode = TextRenderFlags.Render;\n\n return this.textInfo;\n }\n\n\n /// <summary>\n /// Function to clear the geometry of the Primary and Sub Text objects.\n /// </summary>\n public override void ClearMesh()\n {\n m_canvasRenderer.SetMesh(null);\n\n for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)\n m_subTextObjects[i].canvasRenderer.SetMesh(null);\n }\n\n\n /// <summary>\n /// Event to allow users to modify the content of the text info before the text is rendered.\n /// </summary>\n public override event Action<TMP_TextInfo> OnPreRenderText;\n\n\n /// <summary>\n /// Function to update the geometry of the main and sub text objects.\n /// </summary>\n /// <param name=\"mesh\"></param>\n /// <param name=\"index\"></param>\n public override void UpdateGeometry(Mesh mesh, int index)\n {\n mesh.RecalculateBounds();\n\n if (index == 0)\n {\n m_canvasRenderer.SetMesh(mesh);\n }\n else\n {\n m_subTextObjects[index].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n /// <summary>\n /// Function to upload the updated vertex data and renderer.\n /// </summary>\n public override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)\n {\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 0; i < materialCount; i++)\n {\n Mesh mesh;\n\n if (i == 0)\n mesh = m_mesh;\n else\n {\n // Clear unused vertices\n // TODO: Causes issues when sorting geometry as last vertex data attribute get wiped out.\n //m_textInfo.meshInfo[i].ClearUnusedVertices();\n\n mesh = m_subTextObjects[i].mesh;\n }\n\n if ((flags & TMP_VertexDataUpdateFlags.Vertices) == TMP_VertexDataUpdateFlags.Vertices)\n mesh.vertices = m_textInfo.meshInfo[i].vertices;\n\n if ((flags & TMP_VertexDataUpdateFlags.Uv0) == TMP_VertexDataUpdateFlags.Uv0)\n mesh.uv = m_textInfo.meshInfo[i].uvs0;\n\n if ((flags & TMP_VertexDataUpdateFlags.Uv2) == TMP_VertexDataUpdateFlags.Uv2)\n mesh.uv2 = m_textInfo.meshInfo[i].uvs2;\n\n //if ((flags & TMP_VertexDataUpdateFlags.Uv4) == TMP_VertexDataUpdateFlags.Uv4)\n // mesh.uv4 = m_textInfo.meshInfo[i].uvs4;\n\n if ((flags & TMP_VertexDataUpdateFlags.Colors32) == TMP_VertexDataUpdateFlags.Colors32)\n mesh.colors32 = m_textInfo.meshInfo[i].colors32;\n\n mesh.RecalculateBounds();\n\n if (i == 0)\n m_canvasRenderer.SetMesh(mesh);\n else\n m_subTextObjects[i].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n /// <summary>\n /// Function to upload the updated vertex data and renderer.\n /// </summary>\n public override void UpdateVertexData()\n {\n int materialCount = m_textInfo.materialCount;\n\n for (int i = 0; i < materialCount; i++)\n {\n Mesh mesh;\n\n if (i == 0)\n mesh = m_mesh;\n else\n {\n // Clear unused vertices\n m_textInfo.meshInfo[i].ClearUnusedVertices();\n\n mesh = m_subTextObjects[i].mesh;\n }\n\n //mesh.MarkDynamic();\n mesh.vertices = m_textInfo.meshInfo[i].vertices;\n mesh.uv = m_textInfo.meshInfo[i].uvs0;\n mesh.uv2 = m_textInfo.meshInfo[i].uvs2;\n //mesh.uv4 = m_textInfo.meshInfo[i].uvs4;\n mesh.colors32 = m_textInfo.meshInfo[i].colors32;\n\n mesh.RecalculateBounds();\n\n if (i == 0)\n m_canvasRenderer.SetMesh(mesh);\n else\n m_subTextObjects[i].canvasRenderer.SetMesh(mesh);\n }\n }\n\n\n public void UpdateFontAsset()\n {\n LoadFontAsset();\n }\n\n }\n}\n"
  612. },
  613. {
  614. "Script": "TextMeshProUGUI",
  615. "Material": "None",
  616. "Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  617. "Raycast Target": "True",
  618. "Raycast Padding": "(0.00, 0.00, 0.00, 0.00)",
  619. "Maskable": "True",
  620. "On Cull State Changed": "<Unsupported Type>",
  621. "Text": "",
  622. "Is Right To Left": "False",
  623. "Font Asset": "LiberationSans SDF",
  624. "Shared Material": "LiberationSans SDF Material",
  625. "Font Shared Materials": "<Unsupported Type>",
  626. "Font Material": "None",
  627. "Font Materials": "<Unsupported Type>",
  628. "Font Color 32": "RGBA(1.000, 0.000, 0.000, 1.000)",
  629. "Font Color": "RGBA(1.000, 0.000, 0.000, 1.000)",
  630. "Enable Vertex Gradient": "False",
  631. "Color Mode": "FourCornersGradient",
  632. "Font Color Gradient": "<Unsupported Type>",
  633. "Font Color Gradient Preset": "None",
  634. "Sprite Asset": "None",
  635. "Tint All Sprites": "False",
  636. "Style Sheet": "None",
  637. "Text Style Hash Code": "-1183493901",
  638. "Override Html Colors": "False",
  639. "Face Color": "RGBA(1.000, 1.000, 1.000, 1.000)",
  640. "Font Size": "100",
  641. "Font Size Base": "100",
  642. "Font Weight": "Regular",
  643. "Enable Auto Sizing": "False",
  644. "Font Size Min": "18",
  645. "Font Size Max": "72",
  646. "Font Style": "Normal",
  647. "Horizontal Alignment": "Center",
  648. "Vertical Alignment": "Middle",
  649. "Text Alignment": "Converted",
  650. "Character Spacing": "0",
  651. "Word Spacing": "0",
  652. "Line Spacing": "0",
  653. "Line Spacing Max": "0",
  654. "Paragraph Spacing": "0",
  655. "Char Width Max Adj": "0",
  656. "Enable Word Wrapping": "False",
  657. "Word Wrapping Ratios": "0.4",
  658. "Overflow Mode": "Overflow",
  659. "Linked Text Component": "None",
  660. "Parent Linked Component": "None",
  661. "Enable Kerning": "True",
  662. "Enable Extra Padding": "False",
  663. "Check Padding Required": "False",
  664. "Is Rich Text": "True",
  665. "Parse Ctrl Characters": "True",
  666. "Is Orthographic": "True",
  667. "Is Culling Enabled": "False",
  668. "Horizontal Mapping": "Character",
  669. "Vertical Mapping": "Character",
  670. "Uv Line Offset": "0",
  671. "Geometry Sorting Order": "Normal",
  672. "Is Text Object Scale Static": "False",
  673. "Vertex Buffer Auto Size Reduction": "False",
  674. "Use Max Visible Descender": "True",
  675. "Page To Display": "1",
  676. "Margin": "(0.00, 0.00, 0.00, 0.00)",
  677. "Is Using Legacy Animation Component": "False",
  678. "Is Volumetric Text": "False",
  679. "Has Font Asset Changed": "False",
  680. "Base Material": "None",
  681. "Mask Offset": "(0.00, 0.00, 0.00, 0.00)"
  682. }
  683. ],
  684. "Children": []
  685. }
  686. ]
  687. },
  688. {
  689. "Name": "EventSystem",
  690. "Components": [
  691. {
  692. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  693. "Local Position": "(0.00, 0.00, 0.00)",
  694. "Local Scale": "(1.00, 1.00, 1.00)",
  695. "Constrain Proportions Scale": "False"
  696. },
  697. {
  698. "Name": "EventSystem",
  699. "Content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing UnityEngine;\nusing UnityEngine.Rendering;\nusing UnityEngine.Serialization;\nusing UnityEngine.UIElements;\n\nnamespace UnityEngine.EventSystems\n{\n [AddComponentMenu(\"Event/Event System\")]\n [DisallowMultipleComponent]\n /// <summary>\n /// Handles input, raycasting, and sending events.\n /// </summary>\n /// <remarks>\n /// The EventSystem is responsible for processing and handling events in a Unity scene. A scene should only contain one EventSystem. The EventSystem works in conjunction with a number of modules and mostly just holds state and delegates functionality to specific, overrideable components.\n /// When the EventSystem is started it searches for any BaseInputModules attached to the same GameObject and adds them to an internal list. On update each attached module receives an UpdateModules call, where the module can modify internal state. After each module has been Updated the active module has the Process call executed.This is where custom module processing can take place.\n /// </remarks>\n public class EventSystem : UIBehaviour\n {\n private List<BaseInputModule> m_SystemInputModules = new List<BaseInputModule>();\n\n private BaseInputModule m_CurrentInputModule;\n\n private static List<EventSystem> m_EventSystems = new List<EventSystem>();\n\n /// <summary>\n /// Return the current EventSystem.\n /// </summary>\n public static EventSystem current\n {\n get { return m_EventSystems.Count > 0 ? m_EventSystems[0] : null; }\n set\n {\n int index = m_EventSystems.IndexOf(value);\n\n if (index > 0)\n {\n m_EventSystems.RemoveAt(index);\n m_EventSystems.Insert(0, value);\n }\n else if (index < 0)\n {\n Debug.LogError(\"Failed setting EventSystem.current to unknown EventSystem \" + value);\n }\n }\n }\n\n [SerializeField]\n [FormerlySerializedAs(\"m_Selected\")]\n private GameObject m_FirstSelected;\n\n [SerializeField]\n private bool m_sendNavigationEvents = true;\n\n /// <summary>\n /// Should the EventSystem allow navigation events (move / submit / cancel).\n /// </summary>\n public bool sendNavigationEvents\n {\n get { return m_sendNavigationEvents; }\n set { m_sendNavigationEvents = value; }\n }\n\n [SerializeField]\n private int m_DragThreshold = 10;\n\n /// <summary>\n /// The soft area for dragging in pixels.\n /// </summary>\n public int pixelDragThreshold\n {\n get { return m_DragThreshold; }\n set { m_DragThreshold = value; }\n }\n\n private GameObject m_CurrentSelected;\n\n /// <summary>\n /// The currently active EventSystems.BaseInputModule.\n /// </summary>\n public BaseInputModule currentInputModule\n {\n get { return m_CurrentInputModule; }\n }\n\n /// <summary>\n /// Only one object can be selected at a time. Think: controller-selected button.\n /// </summary>\n public GameObject firstSelectedGameObject\n {\n get { return m_FirstSelected; }\n set { m_FirstSelected = value; }\n }\n\n /// <summary>\n /// The GameObject currently considered active by the EventSystem.\n /// </summary>\n public GameObject currentSelectedGameObject\n {\n get { return m_CurrentSelected; }\n }\n\n [Obsolete(\"lastSelectedGameObject is no longer supported\")]\n public GameObject lastSelectedGameObject\n {\n get { return null; }\n }\n\n private bool m_HasFocus = true;\n\n /// <summary>\n /// Flag to say whether the EventSystem thinks it should be paused or not based upon focused state.\n /// </summary>\n /// <remarks>\n /// Used to determine inside the individual InputModules if the module should be ticked while the application doesnt have focus.\n /// </remarks>\n public bool isFocused\n {\n get { return m_HasFocus; }\n }\n\n protected EventSystem()\n {}\n\n /// <summary>\n /// Recalculate the internal list of BaseInputModules.\n /// </summary>\n public void UpdateModules()\n {\n GetComponents(m_SystemInputModules);\n var systemInputModulesCount = m_SystemInputModules.Count;\n for (int i = systemInputModulesCount - 1; i >= 0; i--)\n {\n if (m_SystemInputModules[i] && m_SystemInputModules[i].IsActive())\n continue;\n\n m_SystemInputModules.RemoveAt(i);\n }\n }\n\n private bool m_SelectionGuard;\n\n /// <summary>\n /// Returns true if the EventSystem is already in a SetSelectedGameObject.\n /// </summary>\n public bool alreadySelecting\n {\n get { return m_SelectionGuard; }\n }\n\n /// <summary>\n /// Set the object as selected. Will send an OnDeselect the the old selected object and OnSelect to the new selected object.\n /// </summary>\n /// <param name=\"selected\">GameObject to select.</param>\n /// <param name=\"pointer\">Associated EventData.</param>\n public void SetSelectedGameObject(GameObject selected, BaseEventData pointer)\n {\n if (m_SelectionGuard)\n {\n Debug.LogError(\"Attempting to select \" + selected + \"while already selecting an object.\");\n return;\n }\n\n m_SelectionGuard = true;\n if (selected == m_CurrentSelected)\n {\n m_SelectionGuard = false;\n return;\n }\n\n // Debug.Log(\"Selection: new (\" + selected + \") old (\" + m_CurrentSelected + \")\");\n ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.deselectHandler);\n m_CurrentSelected = selected;\n ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.selectHandler);\n m_SelectionGuard = false;\n }\n\n private BaseEventData m_DummyData;\n private BaseEventData baseEventDataCache\n {\n get\n {\n if (m_DummyData == null)\n m_DummyData = new BaseEventData(this);\n\n return m_DummyData;\n }\n }\n\n /// <summary>\n /// Set the object as selected. Will send an OnDeselect the the old selected object and OnSelect to the new selected object.\n /// </summary>\n /// <param name=\"selected\">GameObject to select.</param>\n public void SetSelectedGameObject(GameObject selected)\n {\n SetSelectedGameObject(selected, baseEventDataCache);\n }\n\n private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)\n {\n if (lhs.module != rhs.module)\n {\n var lhsEventCamera = lhs.module.eventCamera;\n var rhsEventCamera = rhs.module.eventCamera;\n if (lhsEventCamera != null && rhsEventCamera != null && lhsEventCamera.depth != rhsEventCamera.depth)\n {\n // need to reverse the standard compareTo\n if (lhsEventCamera.depth < rhsEventCamera.depth)\n return 1;\n if (lhsEventCamera.depth == rhsEventCamera.depth)\n return 0;\n\n return -1;\n }\n\n if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority)\n return rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority);\n\n if (lhs.module.renderOrderPriority != rhs.module.renderOrderPriority)\n return rhs.module.renderOrderPriority.CompareTo(lhs.module.renderOrderPriority);\n }\n\n // Renderer sorting\n if (lhs.sortingLayer != rhs.sortingLayer)\n {\n // Uses the layer value to properly compare the relative order of the layers.\n var rid = SortingLayer.GetLayerValueFromID(rhs.sortingLayer);\n var lid = SortingLayer.GetLayerValueFromID(lhs.sortingLayer);\n return rid.CompareTo(lid);\n }\n\n if (lhs.sortingOrder != rhs.sortingOrder)\n return rhs.sortingOrder.CompareTo(lhs.sortingOrder);\n\n // comparing depth only makes sense if the two raycast results have the same root canvas (case 912396)\n if (lhs.depth != rhs.depth && lhs.module.rootRaycaster == rhs.module.rootRaycaster)\n return rhs.depth.CompareTo(lhs.depth);\n\n if (lhs.distance != rhs.distance)\n return lhs.distance.CompareTo(rhs.distance);\n\n #if PACKAGE_PHYSICS2D\n\t\t\t// Sorting group\n if (lhs.sortingGroupID != SortingGroup.invalidSortingGroupID && rhs.sortingGroupID != SortingGroup.invalidSortingGroupID)\n {\n if (lhs.sortingGroupID != rhs.sortingGroupID)\n return lhs.sortingGroupID.CompareTo(rhs.sortingGroupID);\n if (lhs.sortingGroupOrder != rhs.sortingGroupOrder)\n return rhs.sortingGroupOrder.CompareTo(lhs.sortingGroupOrder);\n }\n #endif\n\n return lhs.index.CompareTo(rhs.index);\n }\n\n private static readonly Comparison<RaycastResult> s_RaycastComparer = RaycastComparer;\n\n /// <summary>\n /// Raycast into the scene using all configured BaseRaycasters.\n /// </summary>\n /// <param name=\"eventData\">Current pointer data.</param>\n /// <param name=\"raycastResults\">List of 'hits' to populate.</param>\n public void RaycastAll(PointerEventData eventData, List<RaycastResult> raycastResults)\n {\n raycastResults.Clear();\n var modules = RaycasterManager.GetRaycasters();\n var modulesCount = modules.Count;\n for (int i = 0; i < modulesCount; ++i)\n {\n var module = modules[i];\n if (module == null || !module.IsActive())\n continue;\n\n module.Raycast(eventData, raycastResults);\n }\n\n raycastResults.Sort(s_RaycastComparer);\n }\n\n /// <summary>\n /// Is the pointer with the given ID over an EventSystem object?\n /// </summary>\n public bool IsPointerOverGameObject()\n {\n return IsPointerOverGameObject(PointerInputModule.kMouseLeftId);\n }\n\n /// <summary>\n /// Is the pointer with the given ID over an EventSystem object?\n /// </summary>\n /// <remarks>\n /// If you use IsPointerOverGameObject() without a parameter, it points to the \"left mouse button\" (pointerId = -1); therefore when you use IsPointerOverGameObject for touch, you should consider passing a pointerId to it\n /// Note that for touch, IsPointerOverGameObject should be used with ''OnMouseDown()'' or ''Input.GetMouseButtonDown(0)'' or ''Input.GetTouch(0).phase == TouchPhase.Began''.\n /// </remarks>\n /// <example>\n /// <code>\n /// <![CDATA[\n /// using UnityEngine;\n /// using System.Collections;\n /// using UnityEngine.EventSystems;\n ///\n /// public class MouseExample : MonoBehaviour\n /// {\n /// void Update()\n /// {\n /// // Check if the left mouse button was clicked\n /// if (Input.GetMouseButtonDown(0))\n /// {\n /// // Check if the mouse was clicked over a UI element\n /// if (EventSystem.current.IsPointerOverGameObject())\n /// {\n /// Debug.Log(\"Clicked on the UI\");\n /// }\n /// }\n /// }\n /// }\n /// ]]>\n ///</code>\n /// </example>\n public bool IsPointerOverGameObject(int pointerId)\n {\n return m_CurrentInputModule != null && m_CurrentInputModule.IsPointerOverGameObject(pointerId);\n }\n\n // This code is disabled unless the UI Toolkit package or the com.unity.modules.uielements module are present.\n // The UIElements module is always present in the Editor but it can be stripped from a project build if unused.\n#if PACKAGE_UITOOLKIT\n private struct UIToolkitOverrideConfig\n {\n public EventSystem activeEventSystem;\n public bool sendEvents;\n public bool createPanelGameObjectsOnStart;\n }\n\n private static UIToolkitOverrideConfig s_UIToolkitOverride = new UIToolkitOverrideConfig\n {\n activeEventSystem = null,\n sendEvents = true,\n createPanelGameObjectsOnStart = true\n };\n\n private bool isUIToolkitActiveEventSystem =>\n s_UIToolkitOverride.activeEventSystem == this || s_UIToolkitOverride.activeEventSystem == null;\n\n private bool sendUIToolkitEvents =>\n s_UIToolkitOverride.sendEvents && isUIToolkitActiveEventSystem;\n\n private bool createUIToolkitPanelGameObjectsOnStart =>\n s_UIToolkitOverride.createPanelGameObjectsOnStart && isUIToolkitActiveEventSystem;\n#endif\n\n /// <summary>\n /// Sets how UI Toolkit runtime panels receive events and handle selection\n /// when interacting with other objects that use the EventSystem, such as components from the Unity UI package.\n /// </summary>\n /// <param name=\"activeEventSystem\">\n /// The EventSystem used to override UI Toolkit panel events and selection.\n /// If activeEventSystem is null, UI Toolkit panels will use current enabled EventSystem\n /// or, if there is none, the default InputManager-based event system will be used.\n /// </param>\n /// <param name=\"sendEvents\">\n /// If true, UI Toolkit events will come from this EventSystem\n /// instead of the default InputManager-based event system.\n /// </param>\n /// <param name=\"createPanelGameObjectsOnStart\">\n /// If true, UI Toolkit panels' unassigned selectableGameObject will be automatically initialized\n /// with children GameObjects of this EventSystem on Start.\n /// </param>\n public static void SetUITookitEventSystemOverride(EventSystem activeEventSystem, bool sendEvents = true, bool createPanelGameObjectsOnStart = true)\n {\n#if PACKAGE_UITOOLKIT\n UIElementsRuntimeUtility.UnregisterEventSystem(UIElementsRuntimeUtility.activeEventSystem);\n\n s_UIToolkitOverride = new UIToolkitOverrideConfig\n {\n activeEventSystem = activeEventSystem,\n sendEvents = sendEvents,\n createPanelGameObjectsOnStart = createPanelGameObjectsOnStart,\n };\n\n if (sendEvents)\n {\n var eventSystem = activeEventSystem != null ? activeEventSystem : EventSystem.current;\n if (eventSystem.isActiveAndEnabled)\n UIElementsRuntimeUtility.RegisterEventSystem(activeEventSystem);\n }\n#endif\n }\n\n#if PACKAGE_UITOOLKIT\n private bool m_Started;\n private bool m_IsTrackingUIToolkitPanels;\n\n private void StartTrackingUIToolkitPanels()\n {\n if (createUIToolkitPanelGameObjectsOnStart)\n {\n foreach (BaseRuntimePanel panel in UIElementsRuntimeUtility.GetSortedPlayerPanels())\n {\n CreateUIToolkitPanelGameObject(panel);\n }\n UIElementsRuntimeUtility.onCreatePanel += CreateUIToolkitPanelGameObject;\n m_IsTrackingUIToolkitPanels = true;\n }\n }\n\n private void StopTrackingUIToolkitPanels()\n {\n if (m_IsTrackingUIToolkitPanels)\n {\n UIElementsRuntimeUtility.onCreatePanel -= CreateUIToolkitPanelGameObject;\n m_IsTrackingUIToolkitPanels = false;\n }\n }\n\n private void CreateUIToolkitPanelGameObject(BaseRuntimePanel panel)\n {\n if (panel.selectableGameObject == null)\n {\n var go = new GameObject(panel.name, typeof(PanelEventHandler), typeof(PanelRaycaster));\n go.transform.SetParent(transform);\n panel.selectableGameObject = go;\n panel.destroyed += () => DestroyImmediate(go);\n }\n }\n#endif\n\n protected override void Start()\n {\n base.Start();\n\n#if PACKAGE_UITOOLKIT\n m_Started = true;\n StartTrackingUIToolkitPanels();\n#endif\n }\n\n protected override void OnEnable()\n {\n base.OnEnable();\n m_EventSystems.Add(this);\n\n#if PACKAGE_UITOOLKIT\n if (m_Started && !m_IsTrackingUIToolkitPanels)\n {\n StartTrackingUIToolkitPanels();\n }\n if (sendUIToolkitEvents)\n {\n UIElementsRuntimeUtility.RegisterEventSystem(this);\n }\n#endif\n }\n\n protected override void OnDisable()\n {\n#if PACKAGE_UITOOLKIT\n StopTrackingUIToolkitPanels();\n UIElementsRuntimeUtility.UnregisterEventSystem(this);\n#endif\n\n if (m_CurrentInputModule != null)\n {\n m_CurrentInputModule.DeactivateModule();\n m_CurrentInputModule = null;\n }\n\n m_EventSystems.Remove(this);\n\n base.OnDisable();\n }\n\n private void TickModules()\n {\n var systemInputModulesCount = m_SystemInputModules.Count;\n for (var i = 0; i < systemInputModulesCount; i++)\n {\n if (m_SystemInputModules[i] != null)\n m_SystemInputModules[i].UpdateModule();\n }\n }\n\n protected virtual void OnApplicationFocus(bool hasFocus)\n {\n m_HasFocus = hasFocus;\n if (!m_HasFocus)\n TickModules();\n }\n\n protected virtual void Update()\n {\n if (current != this)\n return;\n TickModules();\n\n bool changedModule = false;\n var systemInputModulesCount = m_SystemInputModules.Count;\n for (var i = 0; i < systemInputModulesCount; i++)\n {\n var module = m_SystemInputModules[i];\n if (module.IsModuleSupported() && module.ShouldActivateModule())\n {\n if (m_CurrentInputModule != module)\n {\n ChangeEventModule(module);\n changedModule = true;\n }\n break;\n }\n }\n\n // no event module set... set the first valid one...\n if (m_CurrentInputModule == null)\n {\n for (var i = 0; i < systemInputModulesCount; i++)\n {\n var module = m_SystemInputModules[i];\n if (module.IsModuleSupported())\n {\n ChangeEventModule(module);\n changedModule = true;\n break;\n }\n }\n }\n\n if (!changedModule && m_CurrentInputModule != null)\n m_CurrentInputModule.Process();\n\n#if UNITY_EDITOR\n if (Application.isPlaying)\n {\n int eventSystemCount = 0;\n for (int i = 0; i < m_EventSystems.Count; i++)\n {\n if (m_EventSystems[i].GetType() == typeof(EventSystem))\n eventSystemCount++;\n }\n\n if (eventSystemCount > 1)\n Debug.LogWarning(\"There are \" + eventSystemCount + \" event systems in the scene. Please ensure there is always exactly one event system in the scene\");\n }\n#endif\n }\n\n private void ChangeEventModule(BaseInputModule module)\n {\n if (m_CurrentInputModule == module)\n return;\n\n if (m_CurrentInputModule != null)\n m_CurrentInputModule.DeactivateModule();\n\n if (module != null)\n module.ActivateModule();\n m_CurrentInputModule = module;\n }\n\n public override string ToString()\n {\n var sb = new StringBuilder();\n sb.AppendLine(\"<b>Selected:</b>\" + currentSelectedGameObject);\n sb.AppendLine();\n sb.AppendLine();\n sb.AppendLine(m_CurrentInputModule != null ? m_CurrentInputModule.ToString() : \"No module\");\n return sb.ToString();\n }\n }\n}\n"
  700. },
  701. {
  702. "Script": "EventSystem",
  703. "First Selected": "None",
  704. "Send Navigation Events": "True",
  705. "Drag Threshold": "10"
  706. },
  707. {
  708. "Name": "StandaloneInputModule",
  709. "Content": "using System;\nusing UnityEngine;\nusing UnityEngine.Serialization;\n\nnamespace UnityEngine.EventSystems\n{\n [AddComponentMenu(\"Event/Standalone Input Module\")]\n /// <summary>\n /// A BaseInputModule designed for mouse / keyboard / controller input.\n /// </summary>\n /// <remarks>\n /// Input module for working with, mouse, keyboard, or controller.\n /// </remarks>\n public class StandaloneInputModule : PointerInputModule\n {\n private float m_PrevActionTime;\n private Vector2 m_LastMoveVector;\n private int m_ConsecutiveMoveCount = 0;\n\n private Vector2 m_LastMousePosition;\n private Vector2 m_MousePosition;\n\n private GameObject m_CurrentFocusedGameObject;\n\n private PointerEventData m_InputPointerEvent;\n\n private const float doubleClickTime = 0.3f;\n\n protected StandaloneInputModule()\n {\n }\n\n [Obsolete(\"Mode is no longer needed on input module as it handles both mouse and keyboard simultaneously.\", false)]\n public enum InputMode\n {\n Mouse,\n Buttons\n }\n\n [Obsolete(\"Mode is no longer needed on input module as it handles both mouse and keyboard simultaneously.\", false)]\n public InputMode inputMode\n {\n get { return InputMode.Mouse; }\n }\n\n [SerializeField]\n private string m_HorizontalAxis = \"Horizontal\";\n\n /// <summary>\n /// Name of the vertical axis for movement (if axis events are used).\n /// </summary>\n [SerializeField]\n private string m_VerticalAxis = \"Vertical\";\n\n /// <summary>\n /// Name of the submit button.\n /// </summary>\n [SerializeField]\n private string m_SubmitButton = \"Submit\";\n\n /// <summary>\n /// Name of the submit button.\n /// </summary>\n [SerializeField]\n private string m_CancelButton = \"Cancel\";\n\n [SerializeField]\n private float m_InputActionsPerSecond = 10;\n\n [SerializeField]\n private float m_RepeatDelay = 0.5f;\n\n [SerializeField]\n [FormerlySerializedAs(\"m_AllowActivationOnMobileDevice\")]\n [HideInInspector]\n private bool m_ForceModuleActive;\n\n [Obsolete(\"allowActivationOnMobileDevice has been deprecated. Use forceModuleActive instead (UnityUpgradable) -> forceModuleActive\")]\n public bool allowActivationOnMobileDevice\n {\n get { return m_ForceModuleActive; }\n set { m_ForceModuleActive = value; }\n }\n\n /// <summary>\n /// Force this module to be active.\n /// </summary>\n /// <remarks>\n /// If there is no module active with higher priority (ordered in the inspector) this module will be forced active even if valid enabling conditions are not met.\n /// </remarks>\n\n [Obsolete(\"forceModuleActive has been deprecated. There is no need to force the module awake as StandaloneInputModule works for all platforms\")]\n public bool forceModuleActive\n {\n get { return m_ForceModuleActive; }\n set { m_ForceModuleActive = value; }\n }\n\n /// <summary>\n /// Number of keyboard / controller inputs allowed per second.\n /// </summary>\n public float inputActionsPerSecond\n {\n get { return m_InputActionsPerSecond; }\n set { m_InputActionsPerSecond = value; }\n }\n\n /// <summary>\n /// Delay in seconds before the input actions per second repeat rate takes effect.\n /// </summary>\n /// <remarks>\n /// If the same direction is sustained, the inputActionsPerSecond property can be used to control the rate at which events are fired. However, it can be desirable that the first repetition is delayed, so the user doesn't get repeated actions by accident.\n /// </remarks>\n public float repeatDelay\n {\n get { return m_RepeatDelay; }\n set { m_RepeatDelay = value; }\n }\n\n /// <summary>\n /// Name of the horizontal axis for movement (if axis events are used).\n /// </summary>\n public string horizontalAxis\n {\n get { return m_HorizontalAxis; }\n set { m_HorizontalAxis = value; }\n }\n\n /// <summary>\n /// Name of the vertical axis for movement (if axis events are used).\n /// </summary>\n public string verticalAxis\n {\n get { return m_VerticalAxis; }\n set { m_VerticalAxis = value; }\n }\n\n /// <summary>\n /// Maximum number of input events handled per second.\n /// </summary>\n public string submitButton\n {\n get { return m_SubmitButton; }\n set { m_SubmitButton = value; }\n }\n\n /// <summary>\n /// Input manager name for the 'cancel' button.\n /// </summary>\n public string cancelButton\n {\n get { return m_CancelButton; }\n set { m_CancelButton = value; }\n }\n\n private bool ShouldIgnoreEventsOnNoFocus()\n {\n#if UNITY_EDITOR\n return !UnityEditor.EditorApplication.isRemoteConnected;\n#else\n return true;\n#endif\n }\n\n public override void UpdateModule()\n {\n if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus())\n {\n if (m_InputPointerEvent != null && m_InputPointerEvent.pointerDrag != null && m_InputPointerEvent.dragging)\n {\n ReleaseMouse(m_InputPointerEvent, m_InputPointerEvent.pointerCurrentRaycast.gameObject);\n }\n\n m_InputPointerEvent = null;\n\n return;\n }\n\n m_LastMousePosition = m_MousePosition;\n m_MousePosition = input.mousePosition;\n }\n\n private void ReleaseMouse(PointerEventData pointerEvent, GameObject currentOverGo)\n {\n ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler);\n\n var pointerClickHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);\n\n // PointerClick and Drop events\n if (pointerEvent.pointerClick == pointerClickHandler && pointerEvent.eligibleForClick)\n {\n ExecuteEvents.Execute(pointerEvent.pointerClick, pointerEvent, ExecuteEvents.pointerClickHandler);\n }\n if (pointerEvent.pointerDrag != null && pointerEvent.dragging)\n {\n ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler);\n }\n\n pointerEvent.eligibleForClick = false;\n pointerEvent.pointerPress = null;\n pointerEvent.rawPointerPress = null;\n pointerEvent.pointerClick = null;\n\n if (pointerEvent.pointerDrag != null && pointerEvent.dragging)\n ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler);\n\n pointerEvent.dragging = false;\n pointerEvent.pointerDrag = null;\n\n // redo pointer enter / exit to refresh state\n // so that if we moused over something that ignored it before\n // due to having pressed on something else\n // it now gets it.\n if (currentOverGo != pointerEvent.pointerEnter)\n {\n HandlePointerExitAndEnter(pointerEvent, null);\n HandlePointerExitAndEnter(pointerEvent, currentOverGo);\n }\n\n m_InputPointerEvent = pointerEvent;\n }\n\n public override bool ShouldActivateModule()\n {\n if (!base.ShouldActivateModule())\n return false;\n\n var shouldActivate = m_ForceModuleActive;\n shouldActivate |= input.GetButtonDown(m_SubmitButton);\n shouldActivate |= input.GetButtonDown(m_CancelButton);\n shouldActivate |= !Mathf.Approximately(input.GetAxisRaw(m_HorizontalAxis), 0.0f);\n shouldActivate |= !Mathf.Approximately(input.GetAxisRaw(m_VerticalAxis), 0.0f);\n shouldActivate |= (m_MousePosition - m_LastMousePosition).sqrMagnitude > 0.0f;\n shouldActivate |= input.GetMouseButtonDown(0);\n\n if (input.touchCount > 0)\n shouldActivate = true;\n\n return shouldActivate;\n }\n\n /// <summary>\n /// See BaseInputModule.\n /// </summary>\n public override void ActivateModule()\n {\n if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus())\n return;\n\n base.ActivateModule();\n m_MousePosition = input.mousePosition;\n m_LastMousePosition = input.mousePosition;\n\n var toSelect = eventSystem.currentSelectedGameObject;\n if (toSelect == null)\n toSelect = eventSystem.firstSelectedGameObject;\n\n eventSystem.SetSelectedGameObject(toSelect, GetBaseEventData());\n }\n\n /// <summary>\n /// See BaseInputModule.\n /// </summary>\n public override void DeactivateModule()\n {\n base.DeactivateModule();\n ClearSelection();\n }\n\n public override void Process()\n {\n if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus())\n return;\n\n bool usedEvent = SendUpdateEventToSelectedObject();\n\n // case 1004066 - touch / mouse events should be processed before navigation events in case\n // they change the current selected gameobject and the submit button is a touch / mouse button.\n\n // touch needs to take precedence because of the mouse emulation layer\n if (!ProcessTouchEvents() && input.mousePresent)\n ProcessMouseEvent();\n\n if (eventSystem.sendNavigationEvents)\n {\n if (!usedEvent)\n usedEvent |= SendMoveEventToSelectedObject();\n\n if (!usedEvent)\n SendSubmitEventToSelectedObject();\n }\n }\n\n private bool ProcessTouchEvents()\n {\n for (int i = 0; i < input.touchCount; ++i)\n {\n Touch touch = input.GetTouch(i);\n\n if (touch.type == TouchType.Indirect)\n continue;\n\n bool released;\n bool pressed;\n var pointer = GetTouchPointerEventData(touch, out pressed, out released);\n\n ProcessTouchPress(pointer, pressed, released);\n\n if (!released)\n {\n ProcessMove(pointer);\n ProcessDrag(pointer);\n }\n else\n RemovePointerData(pointer);\n }\n return input.touchCount > 0;\n }\n\n /// <summary>\n /// This method is called by Unity whenever a touch event is processed. Override this method with a custom implementation to process touch events yourself.\n /// </summary>\n /// <param name=\"pointerEvent\">Event data relating to the touch event, such as position and ID to be passed to the touch event destination object.</param>\n /// <param name=\"pressed\">This is true for the first frame of a touch event, and false thereafter. This can therefore be used to determine the instant a touch event occurred.</param>\n /// <param name=\"released\">This is true only for the last frame of a touch event.</param>\n /// <remarks>\n /// This method can be overridden in derived classes to change how touch press events are handled.\n /// </remarks>\n protected void ProcessTouchPress(PointerEventData pointerEvent, bool pressed, bool released)\n {\n var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject;\n\n // PointerDown notification\n if (pressed)\n {\n pointerEvent.eligibleForClick = true;\n pointerEvent.delta = Vector2.zero;\n pointerEvent.dragging = false;\n pointerEvent.useDragThreshold = true;\n pointerEvent.pressPosition = pointerEvent.position;\n pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast;\n\n DeselectIfSelectionChanged(currentOverGo, pointerEvent);\n\n if (pointerEvent.pointerEnter != currentOverGo)\n {\n // send a pointer enter to the touched element if it isn't the one to select...\n HandlePointerExitAndEnter(pointerEvent, currentOverGo);\n pointerEvent.pointerEnter = currentOverGo;\n }\n\n var resetDiffTime = Time.unscaledTime - pointerEvent.clickTime;\n if (resetDiffTime >= doubleClickTime)\n {\n pointerEvent.clickCount = 0;\n }\n\n // search for the control that will receive the press\n // if we can't find a press handler set the press\n // handler to be what would receive a click.\n var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler);\n\n var newClick = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);\n\n // didnt find a press handler... search for a click handler\n if (newPressed == null)\n newPressed = newClick;\n\n // Debug.Log(\"Pressed: \" + newPressed);\n\n float time = Time.unscaledTime;\n\n if (newPressed == pointerEvent.lastPress)\n {\n var diffTime = time - pointerEvent.clickTime;\n if (diffTime < doubleClickTime)\n ++pointerEvent.clickCount;\n else\n pointerEvent.clickCount = 1;\n\n pointerEvent.clickTime = time;\n }\n else\n {\n pointerEvent.clickCount = 1;\n }\n\n pointerEvent.pointerPress = newPressed;\n pointerEvent.rawPointerPress = currentOverGo;\n pointerEvent.pointerClick = newClick;\n\n pointerEvent.clickTime = time;\n\n // Save the drag handler as well\n pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);\n\n if (pointerEvent.pointerDrag != null)\n ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag);\n }\n\n // PointerUp notification\n if (released)\n {\n // Debug.Log(\"Executing pressup on: \" + pointer.pointerPress);\n ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler);\n\n // Debug.Log(\"KeyCode: \" + pointer.eventData.keyCode);\n\n // see if we mouse up on the same element that we clicked on...\n var pointerClickHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);\n\n // PointerClick and Drop events\n if (pointerEvent.pointerClick == pointerClickHandler && pointerEvent.eligibleForClick)\n {\n ExecuteEvents.Execute(pointerEvent.pointerClick, pointerEvent, ExecuteEvents.pointerClickHandler);\n }\n\n if (pointerEvent.pointerDrag != null && pointerEvent.dragging)\n {\n ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler);\n }\n\n pointerEvent.eligibleForClick = false;\n pointerEvent.pointerPress = null;\n pointerEvent.rawPointerPress = null;\n pointerEvent.pointerClick = null;\n\n if (pointerEvent.pointerDrag != null && pointerEvent.dragging)\n ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler);\n\n pointerEvent.dragging = false;\n pointerEvent.pointerDrag = null;\n\n // send exit events as we need to simulate this on touch up on touch device\n ExecuteEvents.ExecuteHierarchy(pointerEvent.pointerEnter, pointerEvent, ExecuteEvents.pointerExitHandler);\n pointerEvent.pointerEnter = null;\n }\n\n m_InputPointerEvent = pointerEvent;\n }\n\n /// <summary>\n /// Calculate and send a submit event to the current selected object.\n /// </summary>\n /// <returns>If the submit event was used by the selected object.</returns>\n protected bool SendSubmitEventToSelectedObject()\n {\n if (eventSystem.currentSelectedGameObject == null)\n return false;\n\n var data = GetBaseEventData();\n if (input.GetButtonDown(m_SubmitButton))\n ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.submitHandler);\n\n if (input.GetButtonDown(m_CancelButton))\n ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.cancelHandler);\n return data.used;\n }\n\n private Vector2 GetRawMoveVector()\n {\n Vector2 move = Vector2.zero;\n move.x = input.GetAxisRaw(m_HorizontalAxis);\n move.y = input.GetAxisRaw(m_VerticalAxis);\n\n if (input.GetButtonDown(m_HorizontalAxis))\n {\n if (move.x < 0)\n move.x = -1f;\n if (move.x > 0)\n move.x = 1f;\n }\n if (input.GetButtonDown(m_VerticalAxis))\n {\n if (move.y < 0)\n move.y = -1f;\n if (move.y > 0)\n move.y = 1f;\n }\n return move;\n }\n\n /// <summary>\n /// Calculate and send a move event to the current selected object.\n /// </summary>\n /// <returns>If the move event was used by the selected object.</returns>\n protected bool SendMoveEventToSelectedObject()\n {\n float time = Time.unscaledTime;\n\n Vector2 movement = GetRawMoveVector();\n if (Mathf.Approximately(movement.x, 0f) && Mathf.Approximately(movement.y, 0f))\n {\n m_ConsecutiveMoveCount = 0;\n return false;\n }\n\n bool similarDir = (Vector2.Dot(movement, m_LastMoveVector) > 0);\n\n // If direction didn't change at least 90 degrees, wait for delay before allowing consequtive event.\n if (similarDir && m_ConsecutiveMoveCount == 1)\n {\n if (time <= m_PrevActionTime + m_RepeatDelay)\n return false;\n }\n // If direction changed at least 90 degree, or we already had the delay, repeat at repeat rate.\n else\n {\n if (time <= m_PrevActionTime + 1f / m_InputActionsPerSecond)\n return false;\n }\n\n var axisEventData = GetAxisEventData(movement.x, movement.y, 0.6f);\n\n if (axisEventData.moveDir != MoveDirection.None)\n {\n ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler);\n if (!similarDir)\n m_ConsecutiveMoveCount = 0;\n m_ConsecutiveMoveCount++;\n m_PrevActionTime = time;\n m_LastMoveVector = movement;\n }\n else\n {\n m_ConsecutiveMoveCount = 0;\n }\n\n return axisEventData.used;\n }\n\n protected void ProcessMouseEvent()\n {\n ProcessMouseEvent(0);\n }\n\n [Obsolete(\"This method is no longer checked, overriding it with return true does nothing!\")]\n protected virtual bool ForceAutoSelect()\n {\n return false;\n }\n\n /// <summary>\n /// Process all mouse events.\n /// </summary>\n protected void ProcessMouseEvent(int id)\n {\n var mouseData = GetMousePointerEventData(id);\n var leftButtonData = mouseData.GetButtonState(PointerEventData.InputButton.Left).eventData;\n\n m_CurrentFocusedGameObject = leftButtonData.buttonData.pointerCurrentRaycast.gameObject;\n\n // Process the first mouse button fully\n ProcessMousePress(leftButtonData);\n ProcessMove(leftButtonData.buttonData);\n ProcessDrag(leftButtonData.buttonData);\n\n // Now process right / middle clicks\n ProcessMousePress(mouseData.GetButtonState(PointerEventData.InputButton.Right).eventData);\n ProcessDrag(mouseData.GetButtonState(PointerEventData.InputButton.Right).eventData.buttonData);\n ProcessMousePress(mouseData.GetButtonState(PointerEventData.InputButton.Middle).eventData);\n ProcessDrag(mouseData.GetButtonState(PointerEventData.InputButton.Middle).eventData.buttonData);\n\n if (!Mathf.Approximately(leftButtonData.buttonData.scrollDelta.sqrMagnitude, 0.0f))\n {\n var scrollHandler = ExecuteEvents.GetEventHandler<IScrollHandler>(leftButtonData.buttonData.pointerCurrentRaycast.gameObject);\n ExecuteEvents.ExecuteHierarchy(scrollHandler, leftButtonData.buttonData, ExecuteEvents.scrollHandler);\n }\n }\n\n protected bool SendUpdateEventToSelectedObject()\n {\n if (eventSystem.currentSelectedGameObject == null)\n return false;\n\n var data = GetBaseEventData();\n ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler);\n return data.used;\n }\n\n /// <summary>\n /// Calculate and process any mouse button state changes.\n /// </summary>\n protected void ProcessMousePress(MouseButtonEventData data)\n {\n var pointerEvent = data.buttonData;\n var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject;\n\n // PointerDown notification\n if (data.PressedThisFrame())\n {\n pointerEvent.eligibleForClick = true;\n pointerEvent.delta = Vector2.zero;\n pointerEvent.dragging = false;\n pointerEvent.useDragThreshold = true;\n pointerEvent.pressPosition = pointerEvent.position;\n pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast;\n\n DeselectIfSelectionChanged(currentOverGo, pointerEvent);\n\n var resetDiffTime = Time.unscaledTime - pointerEvent.clickTime;\n if (resetDiffTime >= doubleClickTime)\n {\n pointerEvent.clickCount = 0;\n }\n\n // search for the control that will receive the press\n // if we can't find a press handler set the press\n // handler to be what would receive a click.\n var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler);\n var newClick = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);\n\n // didnt find a press handler... search for a click handler\n if (newPressed == null)\n newPressed = newClick;\n\n // Debug.Log(\"Pressed: \" + newPressed);\n\n float time = Time.unscaledTime;\n\n if (newPressed == pointerEvent.lastPress)\n {\n var diffTime = time - pointerEvent.clickTime;\n if (diffTime < doubleClickTime)\n ++pointerEvent.clickCount;\n else\n pointerEvent.clickCount = 1;\n\n pointerEvent.clickTime = time;\n }\n else\n {\n pointerEvent.clickCount = 1;\n }\n\n pointerEvent.pointerPress = newPressed;\n pointerEvent.rawPointerPress = currentOverGo;\n pointerEvent.pointerClick = newClick;\n\n pointerEvent.clickTime = time;\n\n // Save the drag handler as well\n pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);\n\n if (pointerEvent.pointerDrag != null)\n ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag);\n\n m_InputPointerEvent = pointerEvent;\n }\n\n // PointerUp notification\n if (data.ReleasedThisFrame())\n {\n ReleaseMouse(pointerEvent, currentOverGo);\n }\n }\n\n protected GameObject GetCurrentFocusedGameObject()\n {\n return m_CurrentFocusedGameObject;\n }\n }\n}\n"
  710. },
  711. {
  712. "Script": "StandaloneInputModule",
  713. "Send Pointer Hover To Parent": "True",
  714. "Horizontal Axis": "Horizontal",
  715. "Vertical Axis": "Vertical",
  716. "Submit Button": "Submit",
  717. "Cancel Button": "Cancel",
  718. "Input Actions Per Second": "10",
  719. "Repeat Delay": "0.5"
  720. }
  721. ],
  722. "Children": []
  723. },
  724. {
  725. "Name": "Recording",
  726. "Components": [
  727. {
  728. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  729. "Local Position": "(0.00, 0.00, 0.00)",
  730. "Local Scale": "(1.00, 1.00, 1.00)",
  731. "Constrain Proportions Scale": "False"
  732. },
  733. {
  734. "Name": "RecordingUIController",
  735. "Content": "using UnityEngine;\r\nusing TMPro;\r\nusing UnityEngine.UI;\r\nusing System.Collections;\r\n\r\npublic class RecordingUIController : MonoBehaviour\r\n{\r\n public Button recordButton;\r\n public Sprite playSprite; // Icon when ready to play/start\r\n public Sprite pauseSprite; // Icon when recording is ongoing\r\n public TMP_Text frameRateText;\r\n public TMP_Text recordButtonText;\r\n public RecordingCore recordingCore;\r\n\r\n private float deltaTime = 0.0f;\r\n private bool isMinimized = false;\r\n private Color recordButtonColor;\r\n\r\n void Start()\r\n {\r\n UpdateFrameRateDisplay();\r\n recordButton.onClick.AddListener(HandleRecordButtonClick);\r\n recordButtonColor = recordButton.image.color;\r\n }\r\n\r\n void Update()\r\n {\r\n UpdateFrameRateDisplay();\r\n }\r\n\r\n void UpdateFrameRateDisplay()\r\n {\r\n deltaTime += (Time.unscaledDeltaTime - deltaTime) * 0.1f;\r\n float fps = 1.0f / deltaTime;\r\n frameRateText.text = string.Format(\"{0:0.0} FPS\", fps);\r\n }\r\n\r\n void HandleRecordButtonClick()\r\n {\r\n if (!recordingCore.IsRecording)\r\n {\r\n recordButtonText.text = \"STOP\";\r\n recordButton.image.color = Color.gray;\r\n StartCoroutine(recordingCore.StartRecording());\r\n }\r\n else\r\n {\r\n recordButtonText.text = \"RECORD\";\r\n recordButton.image.color = recordButtonColor;\r\n recordingCore.StopRecording();\r\n }\r\n }\r\n\r\n public void OnApplicationFocus(bool hasFocus)\r\n {\r\n if (!hasFocus)\r\n {\r\n // Only pause if we haven't already marked it as minimized\r\n if (!isMinimized && recordingCore.IsRecording)\r\n {\r\n recordingCore.PauseRecording();\r\n isMinimized = true; // Mark as minimized\r\n }\r\n }\r\n else if (hasFocus)\r\n {\r\n // Only resume if it was minimized before\r\n if (isMinimized)\r\n {\r\n StartCoroutine(recordingCore.ResumeRecording());\r\n isMinimized = false; // Reset the minimized flag\r\n }\r\n }\r\n }\r\n}"
  736. },
  737. {
  738. "Script": "RecordingUIController",
  739. "Record Button": "Record Button",
  740. "Play Sprite": "play-button-icon-png-18931",
  741. "Pause Sprite": "Pause-Button-PNG-Image",
  742. "Frame Rate Text": "Frame Rate",
  743. "Record Button Text": "Text (TMP)",
  744. "Recording Core": "Recording"
  745. },
  746. {
  747. "Name": "RecordingCore",
  748. "Content": "using UnityEngine;\r\nusing System.Collections;\r\n\r\npublic class RecordingCore : MonoBehaviour\r\n{\r\n public bool IsRecording { get; private set; } = false;\r\n\r\n public IEnumerator StartRecording()\r\n {\r\n Debug.Log(\"Start Recording...\");\r\n IsRecording = true;\r\n // Implement the recording startup logic here\r\n yield return new WaitForSeconds(1); // Simulate start-up delay\r\n }\r\n\r\n public void StopRecording()\r\n {\r\n Debug.Log(\"Stop Recording.\");\r\n IsRecording = false;\r\n // Implement the recording stop logic here\r\n }\r\n\r\n public IEnumerator ResumeRecording()\r\n {\r\n Debug.Log(\"Resume Recording...\");\r\n IsRecording = true;\r\n // Implement the recording resume logic here\r\n yield return new WaitForSeconds(1); // Simulate resume delay\r\n }\r\n\r\n public void PauseRecording()\r\n {\r\n Debug.Log(\"Pause Recording.\");\r\n IsRecording = false;\r\n // Implement the recording pause logic here\r\n }\r\n}"
  749. },
  750. {
  751. "Script": "RecordingCore"
  752. }
  753. ],
  754. "Children": []
  755. },
  756. {
  757. "Name": "Camera",
  758. "Components": [
  759. {
  760. "Local Rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
  761. "Local Position": "(0.00, 0.00, 0.00)",
  762. "Local Scale": "(1.00, 1.00, 1.00)",
  763. "Constrain Proportions Scale": "False"
  764. },
  765. {
  766. "Clear Flags": "Solid Color",
  767. "Back Ground Color": "RGBA(0.000, 0.000, 0.000, 0.000)",
  768. "Projection Matrix Mode": "1",
  769. "Gate Fit Mode": "2",
  770. "FOV Axis Mode": "0",
  771. "Iso": "200",
  772. "Shutter Speed": "0.005",
  773. "Aperture": "16",
  774. "Focus Distance": "10",
  775. "Focal Length": "50",
  776. "Blade Count": "5",
  777. "Curvature": "(2.00, 11.00)",
  778. "Barrel Clipping": "0.25",
  779. "Anamorphism": "0",
  780. "Sensor Size": "(36.00, 24.00)",
  781. "Lens Shift": "(0.00, 0.00)",
  782. "Normalized View Port Rect": "(x:0.00, y:0.00, width:1.00, height:1.00)",
  783. "Near clip plane": "0.3",
  784. "Far clip plane": "1000",
  785. "Field of view": "60",
  786. "Orthographic": "False",
  787. "Orthographic size": "5",
  788. "Depth": "0",
  789. "Culling Mask": "Invalid layer",
  790. "Rendering Path": "Use Graphics Settings",
  791. "Target Texture": "New Render Texture",
  792. "Target Display": "0",
  793. "Target Eye": "3",
  794. "HDR": "True",
  795. "Allow MSAA": "True",
  796. "Allow Dynamic Resolution": "False",
  797. "Force Into RT": "False",
  798. "Occlusion Culling": "True",
  799. "Stereo Convergence": "10",
  800. "Stereo Separation": "0.022"
  801. }
  802. ],
  803. "Children": []
  804. }
  805. ]
Add Comment
Please, Sign In to add comment