完成大地图主要界面
This commit is contained in:
1 parent
5156473bb2
commit
d22eecd133
78 files changed
+8684
-6941
No files matched your search
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3d31d70cf492e34096ffdc82042d396
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,565 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
#if TMP_PRESENT
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Assets.Scripts.UI.UIEffect.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for effects that modify the generated Mesh.
|
||||
/// It works well not only for standard Graphic components (Image, RawImage, Text, etc.) but also for TextMeshPro and TextMeshProUGUI.
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
public abstract class BaseMeshEffect : UIBehaviour, IMeshModifier
|
||||
{
|
||||
//################################
|
||||
// Constant or Static Members.
|
||||
//################################
|
||||
#if TMP_PRESENT
|
||||
static readonly List<Vector2> s_Uv0 = new List<Vector2> (4096);
|
||||
static readonly List<Vector2> s_Uv1 = new List<Vector2> (4096);
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
static readonly List<Vector2> s_Uv2 = new List<Vector2> (4096);
|
||||
static readonly List<Vector2> s_Uv3 = new List<Vector2> (4096);
|
||||
#endif
|
||||
static readonly List<Vector3> s_Vertices = new List<Vector3> (4096);
|
||||
static readonly List<int> s_Indices = new List<int> (4096);
|
||||
static readonly List<Vector3> s_Normals = new List<Vector3> (4096);
|
||||
static readonly List<Vector4> s_Tangents = new List<Vector4> (4096);
|
||||
static readonly List<Color32> s_Colors = new List<Color32> (4096);
|
||||
static readonly VertexHelper s_VertexHelper = new VertexHelper ();
|
||||
static readonly List<TMP_SubMeshUI> s_SubMeshUIs = new List<TMP_SubMeshUI> (4096);
|
||||
static readonly List<Mesh> s_Meshes = new List<Mesh> (4096);
|
||||
static readonly List<UIVertex> s_UIVertices = new List<UIVertex> (4096);
|
||||
static readonly List<BaseMeshEffect> s_TmpEffects = new List<BaseMeshEffect>(4);
|
||||
#endif
|
||||
static readonly Material[] s_EmptyMaterials = new Material[0];
|
||||
|
||||
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
/// <summary>
|
||||
/// The Graphic attached to this GameObject.
|
||||
/// </summary>
|
||||
public Graphic graphic { get { Initialize(); return _graphic; } }
|
||||
|
||||
/// <summary>
|
||||
/// The CanvasRenderer attached to this GameObject.
|
||||
/// </summary>
|
||||
public CanvasRenderer canvasRenderer { get { Initialize(); return _canvasRenderer; } }
|
||||
|
||||
#if TMP_PRESENT
|
||||
/// <summary>
|
||||
/// The TMP_Text attached to this GameObject.
|
||||
/// </summary>
|
||||
public TMP_Text textMeshPro { get { Initialize (); return _textMeshPro; } }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The RectTransform attached to this GameObject.
|
||||
/// </summary>
|
||||
public RectTransform rectTransform { get { Initialize(); return _rectTransform; } }
|
||||
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
/// <summary>
|
||||
/// Additional canvas shader channels to use this component.
|
||||
/// </summary>
|
||||
public virtual AdditionalCanvasShaderChannels requiredChannels { get { return AdditionalCanvasShaderChannels.None; } }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Is TextMeshPro or TextMeshProUGUI attached to this GameObject?
|
||||
/// </summary>
|
||||
public bool isTMPro
|
||||
{
|
||||
get
|
||||
{
|
||||
#if TMP_PRESENT
|
||||
return textMeshPro != null;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The material for rendering.
|
||||
/// </summary>
|
||||
public virtual Material material
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
#if TMP_PRESENT
|
||||
if (textMeshPro)
|
||||
{
|
||||
return textMeshPro.fontSharedMaterial;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (graphic)
|
||||
{
|
||||
return graphic.material;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
#if TMP_PRESENT
|
||||
if (textMeshPro)
|
||||
{
|
||||
textMeshPro.fontSharedMaterial = value;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (graphic)
|
||||
{
|
||||
graphic.material = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Material[] materials
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
#if TMP_PRESENT
|
||||
if (textMeshPro)
|
||||
{
|
||||
return textMeshPro.fontSharedMaterials ?? s_EmptyMaterials;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (graphic)
|
||||
{
|
||||
_materials[0] = graphic.material;
|
||||
return _materials;
|
||||
}
|
||||
else
|
||||
{
|
||||
return s_EmptyMaterials;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call used to modify mesh. (legacy)
|
||||
/// </summary>
|
||||
/// <param name="mesh">Mesh.</param>
|
||||
public virtual void ModifyMesh(Mesh mesh)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call used to modify mesh.
|
||||
/// </summary>
|
||||
/// <param name="vh">VertexHelper.</param>
|
||||
public virtual void ModifyMesh(VertexHelper vh)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mark the vertices as dirty.
|
||||
/// </summary>
|
||||
public virtual void SetVerticesDirty()
|
||||
{
|
||||
#if TMP_PRESENT
|
||||
if (textMeshPro)
|
||||
{
|
||||
foreach (var info in textMeshPro.textInfo.meshInfo)
|
||||
{
|
||||
var mesh = info.mesh;
|
||||
if (mesh)
|
||||
{
|
||||
mesh.Clear ();
|
||||
mesh.vertices = info.vertices;
|
||||
mesh.uv = info.uvs0;
|
||||
mesh.uv2 = info.uvs2;
|
||||
mesh.colors32 = info.colors32;
|
||||
mesh.normals = info.normals;
|
||||
mesh.tangents = info.tangents;
|
||||
mesh.triangles = info.triangles;
|
||||
}
|
||||
}
|
||||
|
||||
if (canvasRenderer)
|
||||
{
|
||||
canvasRenderer.SetMesh (textMeshPro.mesh);
|
||||
|
||||
GetComponentsInChildren (false, s_SubMeshUIs);
|
||||
foreach (var sm in s_SubMeshUIs)
|
||||
{
|
||||
sm.canvasRenderer.SetMesh (sm.mesh);
|
||||
}
|
||||
s_SubMeshUIs.Clear ();
|
||||
}
|
||||
textMeshPro.havePropertiesChanged = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (graphic)
|
||||
{
|
||||
graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowTMProWarning(Shader shader, Shader mobileShader, Shader spriteShader, System.Action<Material> onCreatedMaterial)
|
||||
{
|
||||
#if UNITY_EDITOR && TMP_PRESENT
|
||||
if(!textMeshPro || !textMeshPro.fontSharedMaterial)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the material preset for dissolve?
|
||||
Material m = textMeshPro.fontSharedMaterial;
|
||||
if (m.shader != shader && m.shader != mobileShader)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal ();
|
||||
EditorGUILayout.HelpBox (string.Format("{0} requires '{1}' or '{2}' as a shader for material preset.", GetType().Name, shader.name, mobileShader.name), MessageType.Warning);
|
||||
if(GUILayout.Button ("Fix"))
|
||||
{
|
||||
var correctShader = m.shader.name.Contains ("Mobile") ? mobileShader : shader;
|
||||
textMeshPro.fontSharedMaterial = ModifyTMProMaterialPreset (m, correctShader, onCreatedMaterial);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal ();
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the sprite asset for dissolve?
|
||||
TMP_SpriteAsset spriteAsset = textMeshPro.spriteAsset ?? TMP_Settings.GetSpriteAsset ();
|
||||
// Sprite asset might not exist at all
|
||||
if(spriteAsset == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
m = spriteAsset.material;
|
||||
if (m && m.shader != spriteShader && textMeshPro.richText && textMeshPro.text.Contains("<sprite="))
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal ();
|
||||
EditorGUILayout.HelpBox (string.Format ("{0} requires '{1}' as a shader for sprite asset.", GetType().Name,spriteShader.name), MessageType.Warning);
|
||||
if (GUILayout.Button ("Fix"))
|
||||
{
|
||||
GetComponentsInChildren<TMP_SubMesh> ().Select (x => x.gameObject).ToList ().ForEach (DestroyImmediate);
|
||||
GetComponentsInChildren<TMP_SubMeshUI> ().Select (x => x.gameObject).ToList ().ForEach (DestroyImmediate);
|
||||
textMeshPro.spriteAsset = ModifyTMProSpriteAsset (m, spriteShader, onCreatedMaterial);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Material ModifyTMProMaterialPreset (Material baseMaterial, Shader shader, System.Action<Material> onCreatedMaterial)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath (baseMaterial);
|
||||
string filename = Path.GetFileNameWithoutExtension (path) + " (" + GetType ().Name + ")";
|
||||
Material mat = Resources.Load<Material> (TMP_Settings.defaultFontAssetPath + filename);
|
||||
if (!mat)
|
||||
{
|
||||
mat = new Material (baseMaterial)
|
||||
{
|
||||
shaderKeywords = baseMaterial.shaderKeywords,
|
||||
shader = shader,
|
||||
};
|
||||
onCreatedMaterial (mat);
|
||||
AssetDatabase.CreateAsset (mat, Path.GetDirectoryName (path) + "/" + filename + ".mat");
|
||||
|
||||
EditorUtility.FocusProjectWindow ();
|
||||
EditorGUIUtility.PingObject (mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.shader = shader;
|
||||
}
|
||||
EditorUtility.SetDirty (mat);
|
||||
return mat;
|
||||
}
|
||||
|
||||
TMP_SpriteAsset ModifyTMProSpriteAsset (Material baseMaterial, Shader shader, System.Action<Material> onCreatedMaterial)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath (baseMaterial);
|
||||
string filename = Path.GetFileNameWithoutExtension (path) + " (" + this.GetType ().Name + ")";
|
||||
TMP_SpriteAsset spriteAsset = Resources.Load<TMP_SpriteAsset> (TMP_Settings.defaultSpriteAssetPath + filename);
|
||||
if (!spriteAsset)
|
||||
{
|
||||
AssetDatabase.CopyAsset (path, Path.GetDirectoryName (path) + "/" + filename + ".mat");
|
||||
spriteAsset = Resources.Load<TMP_SpriteAsset> (TMP_Settings.defaultSpriteAssetPath + filename);
|
||||
spriteAsset.material.shader = shader;
|
||||
spriteAsset.material.name = shader.name;
|
||||
onCreatedMaterial (spriteAsset.material);
|
||||
|
||||
EditorUtility.FocusProjectWindow ();
|
||||
EditorGUIUtility.PingObject (spriteAsset);
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteAsset.material.shader = shader;
|
||||
}
|
||||
EditorUtility.SetDirty (spriteAsset);
|
||||
return spriteAsset;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//################################
|
||||
// Protected Members.
|
||||
//################################
|
||||
/// <summary>
|
||||
/// Should the effect modify the mesh directly for TMPro?
|
||||
/// </summary>
|
||||
protected virtual bool isLegacyMeshModifier { get { return false; } }
|
||||
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
_initialized = true;
|
||||
_graphic = _graphic ?? GetComponent<Graphic>();
|
||||
_canvasRenderer = _canvasRenderer ?? GetComponent<CanvasRenderer>();
|
||||
_rectTransform = _rectTransform ?? GetComponent<RectTransform>();
|
||||
#if TMP_PRESENT
|
||||
_textMeshPro = _textMeshPro ?? GetComponent<TMP_Text> ();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the object becomes enabled and active.
|
||||
/// </summary>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
_initialized = false;
|
||||
SetVerticesDirty();
|
||||
#if TMP_PRESENT
|
||||
if (textMeshPro)
|
||||
{
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Add (OnTextChanged);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR && TMP_PRESENT
|
||||
if (graphic && textMeshPro)
|
||||
{
|
||||
GraphicRebuildTracker.TrackGraphic (graphic);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
if (graphic)
|
||||
{
|
||||
AdditionalCanvasShaderChannels channels = requiredChannels;
|
||||
var canvas = graphic.canvas;
|
||||
if (canvas && (canvas.additionalShaderChannels & channels) != channels)
|
||||
{
|
||||
Debug.LogWarningFormat(this, "Enable {1} of Canvas.additionalShaderChannels to use {0}.", GetType().Name, channels);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is called when the behaviour becomes disabled () or inactive.
|
||||
/// </summary>
|
||||
protected override void OnDisable()
|
||||
{
|
||||
#if TMP_PRESENT
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove (OnTextChanged);
|
||||
#endif
|
||||
SetVerticesDirty();
|
||||
|
||||
#if UNITY_EDITOR && TMP_PRESENT
|
||||
if (graphic && textMeshPro)
|
||||
{
|
||||
GraphicRebuildTracker.UnTrackGraphic (graphic);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// LateUpdate is called every frame, if the Behaviour is enabled.
|
||||
/// </summary>
|
||||
protected virtual void LateUpdate()
|
||||
{
|
||||
#if TMP_PRESENT
|
||||
if (textMeshPro)
|
||||
{
|
||||
if (textMeshPro.havePropertiesChanged || _isTextMeshProActive != textMeshPro.isActiveAndEnabled)
|
||||
{
|
||||
SetVerticesDirty ();
|
||||
}
|
||||
_isTextMeshProActive = textMeshPro.isActiveAndEnabled;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for when properties have been changed by animation.
|
||||
/// </summary>
|
||||
protected override void OnDidApplyAnimationProperties()
|
||||
{
|
||||
SetVerticesDirty();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).
|
||||
/// </summary>
|
||||
protected override void OnValidate()
|
||||
{
|
||||
SetVerticesDirty();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
bool _initialized;
|
||||
CanvasRenderer _canvasRenderer;
|
||||
RectTransform _rectTransform;
|
||||
Graphic _graphic;
|
||||
Material[] _materials = new Material[1];
|
||||
|
||||
#if TMP_PRESENT
|
||||
bool _isTextMeshProActive;
|
||||
TMP_Text _textMeshPro;
|
||||
|
||||
/// <summary>
|
||||
/// Called when any TextMeshPro generated the mesh.
|
||||
/// </summary>
|
||||
/// <param name="obj">TextMeshPro object.</param>
|
||||
void OnTextChanged (Object obj)
|
||||
{
|
||||
// Skip if the object is different from the current object or the text is empty.
|
||||
var textInfo = textMeshPro.textInfo;
|
||||
if (textMeshPro != obj || textInfo.characterCount - textInfo.spaceCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetComponents<BaseMeshEffect>(s_TmpEffects);
|
||||
for (int i = 0; i < s_TmpEffects.Count; i++)
|
||||
{
|
||||
if (s_TmpEffects[i].enabled)
|
||||
{
|
||||
if (s_TmpEffects[i] == this)
|
||||
break;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect the meshes.
|
||||
s_Meshes.Clear ();
|
||||
foreach (var info in textInfo.meshInfo)
|
||||
{
|
||||
s_Meshes.Add (info.mesh);
|
||||
}
|
||||
|
||||
// Modify the meshes.
|
||||
foreach (var e in s_TmpEffects)
|
||||
{
|
||||
if (!e.enabled)
|
||||
continue;
|
||||
|
||||
if (e.isLegacyMeshModifier)
|
||||
{
|
||||
// Legacy mode: Modify the meshes directly.
|
||||
foreach (var m in s_Meshes)
|
||||
{
|
||||
if (m)
|
||||
{
|
||||
e.ModifyMesh(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert meshes to VertexHelpers and modify them.
|
||||
foreach (var m in s_Meshes)
|
||||
{
|
||||
if (m)
|
||||
{
|
||||
FillVertexHelper(s_VertexHelper, m);
|
||||
e.ModifyMesh(s_VertexHelper);
|
||||
s_VertexHelper.FillMesh(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the modified meshes to the CanvasRenderers (for UI only).
|
||||
if (canvasRenderer)
|
||||
{
|
||||
canvasRenderer.SetMesh (textMeshPro.mesh);
|
||||
GetComponentsInChildren (false, s_SubMeshUIs);
|
||||
foreach (var sm in s_SubMeshUIs)
|
||||
{
|
||||
sm.canvasRenderer.SetMesh (sm.mesh);
|
||||
}
|
||||
s_SubMeshUIs.Clear ();
|
||||
}
|
||||
|
||||
// Clear.
|
||||
s_Meshes.Clear ();
|
||||
}
|
||||
|
||||
void FillVertexHelper (VertexHelper vh, Mesh mesh)
|
||||
{
|
||||
vh.Clear ();
|
||||
|
||||
mesh.GetVertices (s_Vertices);
|
||||
mesh.GetColors (s_Colors);
|
||||
mesh.GetUVs (0, s_Uv0);
|
||||
mesh.GetUVs (1, s_Uv1);
|
||||
mesh.GetNormals (s_Normals);
|
||||
mesh.GetTangents (s_Tangents);
|
||||
mesh.GetIndices (s_Indices, 0);
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
mesh.GetUVs (2, s_Uv2);
|
||||
mesh.GetUVs (3, s_Uv3);
|
||||
bool useUv2 = 0 < s_Uv2.Count;
|
||||
bool useUv3 = 0 < s_Uv3.Count;
|
||||
#endif
|
||||
|
||||
s_UIVertices.Clear();
|
||||
UIVertex v = default(UIVertex);
|
||||
for (int i = 0; i < s_Vertices.Count; i++)
|
||||
{
|
||||
v.position = s_Vertices[i];
|
||||
v.color = s_Colors[i];
|
||||
v.uv0 = s_Uv0[i];
|
||||
v.uv1 = s_Uv1[i];
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
if (useUv2 && i < s_Uv2.Count)
|
||||
v.uv2 = s_Uv2[i];
|
||||
if (useUv3 && i < s_Uv3.Count)
|
||||
v.uv3 = s_Uv3[i];
|
||||
#endif
|
||||
v.normal = s_Normals[i];
|
||||
v.tangent = s_Tangents[i];
|
||||
|
||||
s_UIVertices.Add(v);
|
||||
}
|
||||
s_VertexHelper.AddUIVertexStream(s_UIVertices, s_Indices);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c52a957894a7bbf418d6b190bd7816a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,386 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.UI.UIEffect
|
||||
{
|
||||
/// <summary>
|
||||
/// UIGradient.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
[AddComponentMenu("UI/MeshEffectForTextMeshPro/UIGradient", 101)]
|
||||
public class UIGradient : Assets.Scripts.UI.UIEffect.Common.BaseMeshEffect
|
||||
{
|
||||
//################################
|
||||
// Constant or Static Members.
|
||||
//################################
|
||||
|
||||
/// <summary>
|
||||
/// Gradient direction.
|
||||
/// </summary>
|
||||
public enum Direction
|
||||
{
|
||||
Horizontal,
|
||||
Vertical,
|
||||
Angle,
|
||||
Diagonal,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gradient space for Text.
|
||||
/// </summary>
|
||||
public enum GradientStyle
|
||||
{
|
||||
Rect,
|
||||
Fit,
|
||||
Split,
|
||||
}
|
||||
|
||||
|
||||
//################################
|
||||
// Serialize Members.
|
||||
//################################
|
||||
|
||||
[Tooltip("Gradient Direction.")]
|
||||
[SerializeField] Direction m_Direction;
|
||||
|
||||
[Tooltip("Color1: Top or Left.")]
|
||||
[SerializeField] Color m_Color1 = Color.white;
|
||||
|
||||
[Tooltip("Color2: Bottom or Right.")]
|
||||
[SerializeField] Color m_Color2 = Color.white;
|
||||
|
||||
[Tooltip("Color3: For diagonal.")]
|
||||
[SerializeField] Color m_Color3 = Color.white;
|
||||
|
||||
[Tooltip("Color4: For diagonal.")]
|
||||
[SerializeField] Color m_Color4 = Color.white;
|
||||
|
||||
[Tooltip("Gradient rotation.")]
|
||||
[SerializeField] [Range(-180, 180)] float m_Rotation;
|
||||
|
||||
[Tooltip("Gradient offset for Horizontal, Vertical or Angle.")]
|
||||
[SerializeField] [Range(-1, 1)] float m_Offset1;
|
||||
|
||||
[Tooltip("Gradient offset for Diagonal.")]
|
||||
[SerializeField] [Range(-1, 1)] float m_Offset2;
|
||||
|
||||
[Tooltip("Gradient style for Text.")]
|
||||
[SerializeField] GradientStyle m_GradientStyle;
|
||||
|
||||
[Tooltip("Color space to correct color.")]
|
||||
[SerializeField] ColorSpace m_ColorSpace = ColorSpace.Uninitialized;
|
||||
|
||||
[Tooltip("Ignore aspect ratio.")]
|
||||
[SerializeField] bool m_IgnoreAspectRatio = true;
|
||||
|
||||
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
public Graphic targetGraphic { get { return base.graphic; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gradient Direction.
|
||||
/// </summary>
|
||||
public Direction direction
|
||||
{
|
||||
get { return m_Direction; }
|
||||
set
|
||||
{
|
||||
if (m_Direction != value)
|
||||
{
|
||||
m_Direction = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Color1: Top or Left.
|
||||
/// </summary>
|
||||
public Color color1
|
||||
{
|
||||
get { return m_Color1; }
|
||||
set
|
||||
{
|
||||
if (m_Color1 != value)
|
||||
{
|
||||
m_Color1 = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Color2: Bottom or Right.
|
||||
/// </summary>
|
||||
public Color color2
|
||||
{
|
||||
get { return m_Color2; }
|
||||
set
|
||||
{
|
||||
if (m_Color2 != value)
|
||||
{
|
||||
m_Color2 = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Color3: For diagonal.
|
||||
/// </summary>
|
||||
public Color color3
|
||||
{
|
||||
get { return m_Color3; }
|
||||
set
|
||||
{
|
||||
if (m_Color3 != value)
|
||||
{
|
||||
m_Color3 = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Color4: For diagonal.
|
||||
/// </summary>
|
||||
public Color color4
|
||||
{
|
||||
get { return m_Color4; }
|
||||
set
|
||||
{
|
||||
if (m_Color4 != value)
|
||||
{
|
||||
m_Color4 = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gradient rotation.
|
||||
/// </summary>
|
||||
public float rotation
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Direction == Direction.Horizontal ? -90
|
||||
: m_Direction == Direction.Vertical ? 0
|
||||
: m_Rotation;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!Mathf.Approximately(m_Rotation, value))
|
||||
{
|
||||
m_Rotation = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gradient offset for Horizontal, Vertical or Angle.
|
||||
/// </summary>
|
||||
public float offset
|
||||
{
|
||||
get { return m_Offset1; }
|
||||
set
|
||||
{
|
||||
if (m_Offset1 != value)
|
||||
{
|
||||
m_Offset1 = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gradient offset for Diagonal.
|
||||
/// </summary>
|
||||
public Vector2 offset2
|
||||
{
|
||||
get { return new Vector2(m_Offset2, m_Offset1); }
|
||||
set
|
||||
{
|
||||
if (m_Offset1 != value.y || m_Offset2 != value.x)
|
||||
{
|
||||
m_Offset1 = value.y;
|
||||
m_Offset2 = value.x;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gradient style for Text.
|
||||
/// </summary>
|
||||
public GradientStyle gradientStyle
|
||||
{
|
||||
get { return m_GradientStyle; }
|
||||
set
|
||||
{
|
||||
if (m_GradientStyle != value)
|
||||
{
|
||||
m_GradientStyle = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Color space to correct color.
|
||||
/// </summary>
|
||||
public ColorSpace colorSpace
|
||||
{
|
||||
get { return m_ColorSpace; }
|
||||
set
|
||||
{
|
||||
if (m_ColorSpace != value)
|
||||
{
|
||||
m_ColorSpace = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore aspect ratio.
|
||||
/// </summary>
|
||||
public bool ignoreAspectRatio
|
||||
{
|
||||
get { return m_IgnoreAspectRatio; }
|
||||
set
|
||||
{
|
||||
if (m_IgnoreAspectRatio != value)
|
||||
{
|
||||
m_IgnoreAspectRatio = value;
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Call used to modify mesh.
|
||||
/// </summary>
|
||||
public override void ModifyMesh(VertexHelper vh)
|
||||
{
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
// Gradient space.
|
||||
Rect rect = default(Rect);
|
||||
UIVertex vertex = default(UIVertex);
|
||||
if (m_GradientStyle == GradientStyle.Rect)
|
||||
{
|
||||
// RectTransform.
|
||||
rect = graphic.rectTransform.rect;
|
||||
}
|
||||
else if (m_GradientStyle == GradientStyle.Split)
|
||||
{
|
||||
// Each characters.
|
||||
rect.Set(0, 0, 1, 1);
|
||||
}
|
||||
else if (m_GradientStyle == GradientStyle.Fit)
|
||||
{
|
||||
// Fit to contents.
|
||||
rect.xMin = rect.yMin = float.MaxValue;
|
||||
rect.xMax = rect.yMax = float.MinValue;
|
||||
for (int i = 0; i < vh.currentVertCount; i++)
|
||||
{
|
||||
vh.PopulateUIVertex(ref vertex, i);
|
||||
rect.xMin = Mathf.Min(rect.xMin, vertex.position.x);
|
||||
rect.yMin = Mathf.Min(rect.yMin, vertex.position.y);
|
||||
rect.xMax = Mathf.Max(rect.xMax, vertex.position.x);
|
||||
rect.yMax = Mathf.Max(rect.yMax, vertex.position.y);
|
||||
}
|
||||
}
|
||||
|
||||
// Gradient rotation.
|
||||
float rad = rotation * Mathf.Deg2Rad;
|
||||
Vector2 dir = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
|
||||
if (!m_IgnoreAspectRatio && Direction.Angle <= m_Direction)
|
||||
{
|
||||
dir.x *= rect.height / rect.width;
|
||||
dir = dir.normalized;
|
||||
}
|
||||
|
||||
// Calculate vertex color.
|
||||
Color color;
|
||||
Vector2 nomalizedPos;
|
||||
Matrix2x3 localMatrix = new Matrix2x3(rect, dir.x, dir.y); // Get local matrix.
|
||||
for (int i = 0; i < vh.currentVertCount; i++)
|
||||
{
|
||||
vh.PopulateUIVertex(ref vertex, i);
|
||||
|
||||
// Normalize vertex position by local matrix.
|
||||
if (m_GradientStyle == GradientStyle.Split)
|
||||
{
|
||||
// Each characters.
|
||||
nomalizedPos = localMatrix * s_SplitedCharacterPosition[i % 4] + offset2;
|
||||
}
|
||||
else
|
||||
{
|
||||
nomalizedPos = localMatrix * vertex.position + offset2;
|
||||
}
|
||||
|
||||
// Interpolate vertex color.
|
||||
if (direction == Direction.Diagonal)
|
||||
{
|
||||
color = Color.LerpUnclamped(
|
||||
Color.LerpUnclamped(m_Color1, m_Color2, nomalizedPos.x),
|
||||
Color.LerpUnclamped(m_Color3, m_Color4, nomalizedPos.x),
|
||||
nomalizedPos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
color = Color.LerpUnclamped(m_Color2, m_Color1, nomalizedPos.y);
|
||||
}
|
||||
|
||||
// Correct color.
|
||||
vertex.color *= (m_ColorSpace == ColorSpace.Gamma) ? color.gamma
|
||||
: (m_ColorSpace == ColorSpace.Linear) ? color.linear
|
||||
: color;
|
||||
|
||||
vh.SetUIVertex(vertex, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
static readonly Vector2[] s_SplitedCharacterPosition = { Vector2.up, Vector2.one, Vector2.right, Vector2.zero };
|
||||
|
||||
/// <summary>
|
||||
/// Matrix2x3.
|
||||
/// </summary>
|
||||
struct Matrix2x3
|
||||
{
|
||||
public float m00, m01, m02, m10, m11, m12;
|
||||
|
||||
public Matrix2x3(Rect rect, float cos, float sin)
|
||||
{
|
||||
const float center = 0.5f;
|
||||
float dx = -rect.xMin / rect.width - center;
|
||||
float dy = -rect.yMin / rect.height - center;
|
||||
m00 = cos / rect.width;
|
||||
m01 = -sin / rect.height;
|
||||
m02 = dx * cos - dy * sin + center;
|
||||
m10 = sin / rect.width;
|
||||
m11 = cos / rect.height;
|
||||
m12 = dx * sin + dy * cos + center;
|
||||
}
|
||||
|
||||
public static Vector2 operator *(Matrix2x3 m, Vector2 v)
|
||||
{
|
||||
return new Vector2(
|
||||
(m.m00 * v.x) + (m.m01 * v.y) + m.m02,
|
||||
(m.m10 * v.x) + (m.m11 * v.y) + m.m12
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7245fe6cb36dc7b4e921e9ae44200f43
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user