mirror of
https://github.com/imperialsushi/gutterball-3.git
synced 2025-06-15 05:07:42 +00:00
New Version 1.42
Moving cam replay. Fixed the bugs. New Version 1.42 Moving cam replay. Fixed the bugs. New Version 1.42 Moving cam replay, Fixed the bugs.
This commit is contained in:
parent
dcb7df5fd1
commit
1c033119df
7079 changed files with 186851 additions and 48991 deletions
|
@ -0,0 +1,11 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Allow internal visibility for testing purposes.
|
||||
[assembly: InternalsVisibleTo("Unity.TextCore")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.FontEngine.Tests")]
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[assembly: InternalsVisibleTo("Unity.TextCore.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.TextMeshPro.Editor")]
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1c147d10db452eb4b854a35f84472017
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,154 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class FastAction
|
||||
{
|
||||
|
||||
LinkedList<System.Action> delegates = new LinkedList<System.Action>();
|
||||
|
||||
Dictionary<System.Action, LinkedListNode<System.Action>> lookup = new Dictionary<System.Action, LinkedListNode<System.Action>>();
|
||||
|
||||
public void Add(System.Action rhs)
|
||||
{
|
||||
if (lookup.ContainsKey(rhs)) return;
|
||||
|
||||
lookup[rhs] = delegates.AddLast(rhs);
|
||||
}
|
||||
|
||||
public void Remove(System.Action rhs)
|
||||
{
|
||||
LinkedListNode<System.Action> node;
|
||||
|
||||
if (lookup.TryGetValue(rhs, out node))
|
||||
{
|
||||
lookup.Remove(rhs);
|
||||
delegates.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void Call()
|
||||
{
|
||||
var node = delegates.First;
|
||||
while (node != null)
|
||||
{
|
||||
node.Value();
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class FastAction<A>
|
||||
{
|
||||
|
||||
LinkedList<System.Action<A>> delegates = new LinkedList<System.Action<A>>();
|
||||
|
||||
Dictionary<System.Action<A>, LinkedListNode<System.Action<A>>> lookup = new Dictionary<System.Action<A>, LinkedListNode<System.Action<A>>>();
|
||||
|
||||
public void Add(System.Action<A> rhs)
|
||||
{
|
||||
if (lookup.ContainsKey(rhs)) return;
|
||||
|
||||
lookup[rhs] = delegates.AddLast(rhs);
|
||||
}
|
||||
|
||||
public void Remove(System.Action<A> rhs)
|
||||
{
|
||||
LinkedListNode<System.Action<A>> node;
|
||||
|
||||
if (lookup.TryGetValue(rhs, out node))
|
||||
{
|
||||
lookup.Remove(rhs);
|
||||
delegates.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void Call(A a)
|
||||
{
|
||||
var node = delegates.First;
|
||||
while (node != null)
|
||||
{
|
||||
node.Value(a);
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class FastAction<A, B>
|
||||
{
|
||||
|
||||
LinkedList<System.Action<A, B>> delegates = new LinkedList<System.Action<A, B>>();
|
||||
|
||||
Dictionary<System.Action<A, B>, LinkedListNode<System.Action<A, B>>> lookup = new Dictionary<System.Action<A, B>, LinkedListNode<System.Action<A, B>>>();
|
||||
|
||||
public void Add(System.Action<A, B> rhs)
|
||||
{
|
||||
if (lookup.ContainsKey(rhs)) return;
|
||||
|
||||
lookup[rhs] = delegates.AddLast(rhs);
|
||||
}
|
||||
|
||||
public void Remove(System.Action<A, B> rhs)
|
||||
{
|
||||
LinkedListNode<System.Action<A, B>> node;
|
||||
|
||||
if (lookup.TryGetValue(rhs, out node))
|
||||
{
|
||||
lookup.Remove(rhs);
|
||||
delegates.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void Call(A a, B b)
|
||||
{
|
||||
var node = delegates.First;
|
||||
while (node != null)
|
||||
{
|
||||
node.Value(a, b);
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class FastAction<A, B, C>
|
||||
{
|
||||
|
||||
LinkedList<System.Action<A, B, C>> delegates = new LinkedList<System.Action<A, B, C>>();
|
||||
|
||||
Dictionary<System.Action<A, B, C>, LinkedListNode<System.Action<A, B, C>>> lookup = new Dictionary<System.Action<A, B, C>, LinkedListNode<System.Action<A, B, C>>>();
|
||||
|
||||
public void Add(System.Action<A, B, C> rhs)
|
||||
{
|
||||
if (lookup.ContainsKey(rhs)) return;
|
||||
|
||||
lookup[rhs] = delegates.AddLast(rhs);
|
||||
}
|
||||
|
||||
public void Remove(System.Action<A, B, C> rhs)
|
||||
{
|
||||
LinkedListNode<System.Action<A, B, C>> node;
|
||||
|
||||
if (lookup.TryGetValue(rhs, out node))
|
||||
{
|
||||
lookup.Remove(rhs);
|
||||
delegates.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
public void Call(A a, B b, C c)
|
||||
{
|
||||
var node = delegates.First;
|
||||
while (node != null)
|
||||
{
|
||||
node.Value(a, b, c);
|
||||
node = node.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 871f8edd56e84b8fb295b10cc3c78f36
|
||||
timeCreated: 1435956061
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,646 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public class MaterialReferenceManager
|
||||
{
|
||||
private static MaterialReferenceManager s_Instance;
|
||||
|
||||
// Dictionaries used to track Asset references.
|
||||
private Dictionary<int, Material> m_FontMaterialReferenceLookup = new Dictionary<int, Material>();
|
||||
private Dictionary<int, TMP_FontAsset> m_FontAssetReferenceLookup = new Dictionary<int, TMP_FontAsset>();
|
||||
private Dictionary<int, TMP_SpriteAsset> m_SpriteAssetReferenceLookup = new Dictionary<int, TMP_SpriteAsset>();
|
||||
private Dictionary<int, TMP_ColorGradient> m_ColorGradientReferenceLookup = new Dictionary<int, TMP_ColorGradient>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the registry
|
||||
/// </summary>
|
||||
public static MaterialReferenceManager instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (MaterialReferenceManager.s_Instance == null)
|
||||
MaterialReferenceManager.s_Instance = new MaterialReferenceManager();
|
||||
return MaterialReferenceManager.s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new font asset reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
public static void AddFontAsset(TMP_FontAsset fontAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddFontAssetInternal(fontAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add new Font Asset reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
private void AddFontAssetInternal(TMP_FontAsset fontAsset)
|
||||
{
|
||||
if (m_FontAssetReferenceLookup.ContainsKey(fontAsset.hashCode)) return;
|
||||
|
||||
// Add reference to the font asset.
|
||||
m_FontAssetReferenceLookup.Add(fontAsset.hashCode, fontAsset);
|
||||
|
||||
// Add reference to the font material.
|
||||
m_FontMaterialReferenceLookup.Add(fontAsset.materialHashCode, fontAsset.material);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new Sprite Asset to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
public static void AddSpriteAsset(TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddSpriteAssetInternal(spriteAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method to add a new sprite asset to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
private void AddSpriteAssetInternal(TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
if (m_SpriteAssetReferenceLookup.ContainsKey(spriteAsset.hashCode)) return;
|
||||
|
||||
// Add reference to sprite asset.
|
||||
m_SpriteAssetReferenceLookup.Add(spriteAsset.hashCode, spriteAsset);
|
||||
|
||||
// Adding reference to the sprite asset material as well
|
||||
m_FontMaterialReferenceLookup.Add(spriteAsset.hashCode, spriteAsset.material);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add new Sprite Asset to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
public static void AddSpriteAsset(int hashCode, TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddSpriteAssetInternal(hashCode, spriteAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method to add a new sprite asset to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
private void AddSpriteAssetInternal(int hashCode, TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
if (m_SpriteAssetReferenceLookup.ContainsKey(hashCode)) return;
|
||||
|
||||
// Add reference to Sprite Asset.
|
||||
m_SpriteAssetReferenceLookup.Add(hashCode, spriteAsset);
|
||||
|
||||
// Add reference to Sprite Asset using the asset hashcode.
|
||||
m_FontMaterialReferenceLookup.Add(hashCode, spriteAsset.material);
|
||||
|
||||
// Compatibility check
|
||||
if (spriteAsset.hashCode == 0) spriteAsset.hashCode = hashCode;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new Material reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
public static void AddFontMaterial(int hashCode, Material material)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddFontMaterialInternal(hashCode, material);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add new material reference to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
private void AddFontMaterialInternal(int hashCode, Material material)
|
||||
{
|
||||
// Since this function is called after checking if the material is
|
||||
// contained in the dictionary, there is no need to check again.
|
||||
m_FontMaterialReferenceLookup.Add(hashCode, material);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new Color Gradient Preset to dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
public static void AddColorGradientPreset(int hashCode, TMP_ColorGradient spriteAsset)
|
||||
{
|
||||
MaterialReferenceManager.instance.AddColorGradientPreset_Internal(hashCode, spriteAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method to add a new Color Gradient Preset to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
private void AddColorGradientPreset_Internal(int hashCode, TMP_ColorGradient spriteAsset)
|
||||
{
|
||||
if (m_ColorGradientReferenceLookup.ContainsKey(hashCode)) return;
|
||||
|
||||
// Add reference to Color Gradient Preset Asset.
|
||||
m_ColorGradientReferenceLookup.Add(hashCode, spriteAsset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new material reference and return the index of this new reference in the materialReferences array.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="materialHashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
//public int AddMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset)
|
||||
//{
|
||||
// if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
|
||||
// {
|
||||
// int index = m_MaterialReferenceLookup.Count;
|
||||
|
||||
// materialReferences[index].fontAsset = fontAsset;
|
||||
// materialReferences[index].material = material;
|
||||
// materialReferences[index].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
|
||||
// materialReferences[index].index = index;
|
||||
// materialReferences[index].referenceCount = 0;
|
||||
|
||||
// m_MaterialReferenceLookup[materialHashCode] = index;
|
||||
|
||||
// // Compute Padding value and store it
|
||||
// // TODO
|
||||
|
||||
// int fontAssetHashCode = fontAsset.hashCode;
|
||||
|
||||
// if (!m_FontAssetReferenceLookup.ContainsKey(fontAssetHashCode))
|
||||
// m_FontAssetReferenceLookup.Add(fontAssetHashCode, fontAsset);
|
||||
|
||||
// m_countInternal += 1;
|
||||
|
||||
// return index;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return m_MaterialReferenceLookup[materialHashCode];
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add new material reference and return the index of this new reference in the materialReferences array.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="materialHashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <returns></returns>
|
||||
//public int AddMaterial(Material material, int materialHashCode, TMP_SpriteAsset spriteAsset)
|
||||
//{
|
||||
// if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
|
||||
// {
|
||||
// int index = m_MaterialReferenceLookup.Count;
|
||||
|
||||
// materialReferences[index].fontAsset = materialReferences[0].fontAsset;
|
||||
// materialReferences[index].spriteAsset = spriteAsset;
|
||||
// materialReferences[index].material = material;
|
||||
// materialReferences[index].isDefaultMaterial = true;
|
||||
// materialReferences[index].index = index;
|
||||
// materialReferences[index].referenceCount = 0;
|
||||
|
||||
// m_MaterialReferenceLookup[materialHashCode] = index;
|
||||
|
||||
// int spriteAssetHashCode = spriteAsset.hashCode;
|
||||
|
||||
// if (!m_SpriteAssetReferenceLookup.ContainsKey(spriteAssetHashCode))
|
||||
// m_SpriteAssetReferenceLookup.Add(spriteAssetHashCode, spriteAsset);
|
||||
|
||||
// m_countInternal += 1;
|
||||
|
||||
// return index;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return m_MaterialReferenceLookup[materialHashCode];
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to check if the font asset is already referenced.
|
||||
/// </summary>
|
||||
/// <param name="font"></param>
|
||||
/// <returns></returns>
|
||||
public bool Contains(TMP_FontAsset font)
|
||||
{
|
||||
if (m_FontAssetReferenceLookup.ContainsKey(font.hashCode))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to check if the sprite asset is already referenced.
|
||||
/// </summary>
|
||||
/// <param name="font"></param>
|
||||
/// <returns></returns>
|
||||
public bool Contains(TMP_SpriteAsset sprite)
|
||||
{
|
||||
if (m_FontAssetReferenceLookup.ContainsKey(sprite.hashCode))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the Font Asset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetFontAsset(int hashCode, out TMP_FontAsset fontAsset)
|
||||
{
|
||||
return MaterialReferenceManager.instance.TryGetFontAssetInternal(hashCode, out fontAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal Function returning the Font Asset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetFontAssetInternal(int hashCode, out TMP_FontAsset fontAsset)
|
||||
{
|
||||
fontAsset = null;
|
||||
|
||||
if (m_FontAssetReferenceLookup.TryGetValue(hashCode, out fontAsset))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the Sprite Asset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetSpriteAsset(int hashCode, out TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
return MaterialReferenceManager.instance.TryGetSpriteAssetInternal(hashCode, out spriteAsset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal function returning the Sprite Asset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetSpriteAssetInternal(int hashCode, out TMP_SpriteAsset spriteAsset)
|
||||
{
|
||||
spriteAsset = null;
|
||||
|
||||
if (m_SpriteAssetReferenceLookup.TryGetValue(hashCode, out spriteAsset))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the Color Gradient Preset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="gradientPreset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetColorGradientPreset(int hashCode, out TMP_ColorGradient gradientPreset)
|
||||
{
|
||||
return MaterialReferenceManager.instance.TryGetColorGradientPresetInternal(hashCode, out gradientPreset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal function returning the Color Gradient Preset corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetColorGradientPresetInternal(int hashCode, out TMP_ColorGradient gradientPreset)
|
||||
{
|
||||
gradientPreset = null;
|
||||
|
||||
if (m_ColorGradientReferenceLookup.TryGetValue(hashCode, out gradientPreset))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the Font Material corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryGetMaterial(int hashCode, out Material material)
|
||||
{
|
||||
return MaterialReferenceManager.instance.TryGetMaterialInternal(hashCode, out material);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal function returning the Font Material corresponding to the provided hash code.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
/// <returns></returns>
|
||||
private bool TryGetMaterialInternal(int hashCode, out Material material)
|
||||
{
|
||||
material = null;
|
||||
|
||||
if (m_FontMaterialReferenceLookup.TryGetValue(hashCode, out material))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to lookup a material based on hash code and returning the MaterialReference containing this material.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="material"></param>
|
||||
/// <returns></returns>
|
||||
//public bool TryGetMaterial(int hashCode, out MaterialReference materialReference)
|
||||
//{
|
||||
// int materialIndex = -1;
|
||||
|
||||
// if (m_MaterialReferenceLookup.TryGetValue(hashCode, out materialIndex))
|
||||
// {
|
||||
// materialReference = materialReferences[materialIndex];
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// materialReference = new MaterialReference();
|
||||
|
||||
// return false;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
//public int GetMaterialIndex(TMP_FontAsset fontAsset)
|
||||
//{
|
||||
// if (m_MaterialReferenceLookup.ContainsKey(fontAsset.materialHashCode))
|
||||
// return m_MaterialReferenceLookup[fontAsset.materialHashCode];
|
||||
|
||||
// return -1;
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
//public TMP_FontAsset GetFontAsset(int index)
|
||||
//{
|
||||
// if (index >= 0 && index < materialReferences.Length)
|
||||
// return materialReferences[index].fontAsset;
|
||||
|
||||
// return null;
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="materialHashCode"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
//public void SetDefaultMaterial(Material material, int materialHashCode, TMP_FontAsset fontAsset)
|
||||
//{
|
||||
// if (!m_MaterialReferenceLookup.ContainsKey(materialHashCode))
|
||||
// {
|
||||
// materialReferences[0].fontAsset = fontAsset;
|
||||
// materialReferences[0].material = material;
|
||||
// materialReferences[0].index = 0;
|
||||
// materialReferences[0].isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
|
||||
// materialReferences[0].referenceCount = 0;
|
||||
// m_MaterialReferenceLookup[materialHashCode] = 0;
|
||||
|
||||
// // Compute Padding value and store it
|
||||
// // TODO
|
||||
|
||||
// int fontHashCode = fontAsset.hashCode;
|
||||
|
||||
// if (!m_FontAssetReferenceLookup.ContainsKey(fontHashCode))
|
||||
// m_FontAssetReferenceLookup.Add(fontHashCode, fontAsset);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// materialReferences[0].fontAsset = fontAsset;
|
||||
// materialReferences[0].material = material;
|
||||
// materialReferences[0].index = 0;
|
||||
// materialReferences[0].referenceCount = 0;
|
||||
// m_MaterialReferenceLookup[materialHashCode] = 0;
|
||||
// }
|
||||
// // Compute padding
|
||||
// // TODO
|
||||
|
||||
// m_countInternal = 1;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
//public void Clear()
|
||||
//{
|
||||
// //m_currentIndex = 0;
|
||||
// m_MaterialReferenceLookup.Clear();
|
||||
// m_SpriteAssetReferenceLookup.Clear();
|
||||
// m_FontAssetReferenceLookup.Clear();
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the reference count for each of the material references.
|
||||
/// </summary>
|
||||
//public void ClearReferenceCount()
|
||||
//{
|
||||
// m_countInternal = 0;
|
||||
|
||||
// for (int i = 0; i < materialReferences.Length; i++)
|
||||
// {
|
||||
// if (materialReferences[i].fontAsset == null)
|
||||
// return;
|
||||
|
||||
// materialReferences[i].referenceCount = 0;
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public struct MaterialReference
|
||||
{
|
||||
|
||||
public int index;
|
||||
public TMP_FontAsset fontAsset;
|
||||
public TMP_SpriteAsset spriteAsset;
|
||||
public Material material;
|
||||
public bool isDefaultMaterial;
|
||||
public bool isFallbackMaterial;
|
||||
public Material fallbackMaterial;
|
||||
public float padding;
|
||||
public int referenceCount;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new Material Reference.
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="padding"></param>
|
||||
public MaterialReference(int index, TMP_FontAsset fontAsset, TMP_SpriteAsset spriteAsset, Material material, float padding)
|
||||
{
|
||||
this.index = index;
|
||||
this.fontAsset = fontAsset;
|
||||
this.spriteAsset = spriteAsset;
|
||||
this.material = material;
|
||||
this.isDefaultMaterial = material.GetInstanceID() == fontAsset.material.GetInstanceID() ? true : false;
|
||||
this.isFallbackMaterial = false;
|
||||
this.fallbackMaterial = null;
|
||||
this.padding = padding;
|
||||
this.referenceCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to check if a certain font asset is contained in the material reference array.
|
||||
/// </summary>
|
||||
/// <param name="materialReferences"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Contains(MaterialReference[] materialReferences, TMP_FontAsset fontAsset)
|
||||
{
|
||||
int id = fontAsset.GetInstanceID();
|
||||
|
||||
for (int i = 0; i < materialReferences.Length && materialReferences[i].fontAsset != null; i++)
|
||||
{
|
||||
if (materialReferences[i].fontAsset.GetInstanceID() == id)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to add a new material reference and returning its index in the material reference array.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="fontAsset"></param>
|
||||
/// <param name="materialReferences"></param>
|
||||
/// <param name="materialReferenceIndexLookup"></param>
|
||||
/// <returns></returns>
|
||||
public static int AddMaterialReference(Material material, TMP_FontAsset fontAsset, MaterialReference[] materialReferences, Dictionary<int, int> materialReferenceIndexLookup)
|
||||
{
|
||||
int materialID = material.GetInstanceID();
|
||||
int index;
|
||||
|
||||
if (materialReferenceIndexLookup.TryGetValue(materialID, out index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = materialReferenceIndexLookup.Count;
|
||||
|
||||
// Add new reference index
|
||||
materialReferenceIndexLookup[materialID] = index;
|
||||
|
||||
materialReferences[index].index = index;
|
||||
materialReferences[index].fontAsset = fontAsset;
|
||||
materialReferences[index].spriteAsset = null;
|
||||
materialReferences[index].material = material;
|
||||
materialReferences[index].isDefaultMaterial = materialID == fontAsset.material.GetInstanceID() ? true : false;
|
||||
//materialReferences[index].padding = 0;
|
||||
materialReferences[index].referenceCount = 0;
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="materialReferences"></param>
|
||||
/// <param name="materialReferenceIndexLookup"></param>
|
||||
/// <returns></returns>
|
||||
public static int AddMaterialReference(Material material, TMP_SpriteAsset spriteAsset, MaterialReference[] materialReferences, Dictionary<int, int> materialReferenceIndexLookup)
|
||||
{
|
||||
int materialID = material.GetInstanceID();
|
||||
int index;
|
||||
|
||||
if (materialReferenceIndexLookup.TryGetValue(materialID, out index))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = materialReferenceIndexLookup.Count;
|
||||
|
||||
// Add new reference index
|
||||
materialReferenceIndexLookup[materialID] = index;
|
||||
|
||||
materialReferences[index].index = index;
|
||||
materialReferences[index].fontAsset = materialReferences[0].fontAsset;
|
||||
materialReferences[index].spriteAsset = spriteAsset;
|
||||
materialReferences[index].material = material;
|
||||
materialReferences[index].isDefaultMaterial = true;
|
||||
//materialReferences[index].padding = 0;
|
||||
materialReferences[index].referenceCount = 0;
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 11a6a034ab84493cbed6af5ae7aae78b
|
||||
timeCreated: 1449743129
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,26 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
// Base class inherited by the various TextMeshPro Assets.
|
||||
[System.Serializable]
|
||||
public class TMP_Asset : ScriptableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// HashCode based on the name of the asset.
|
||||
/// </summary>
|
||||
public int hashCode;
|
||||
|
||||
/// <summary>
|
||||
/// The material used by this asset.
|
||||
/// </summary>
|
||||
public Material material;
|
||||
|
||||
/// <summary>
|
||||
/// HashCode based on the name of the material assigned to this asset.
|
||||
/// </summary>
|
||||
public int materialHashCode;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3bda1886f58f4e0ab1139400b160c3ee
|
||||
timeCreated: 1459318952
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using UnityEngine.TextCore;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// A basic element of text.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_Character : TMP_TextElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
public TMP_Character()
|
||||
{
|
||||
m_ElementType = TextElementType.Character;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new character
|
||||
/// </summary>
|
||||
/// <param name="unicode">Unicode value.</param>
|
||||
/// <param name="glyph">Glyph</param>
|
||||
public TMP_Character(uint unicode, Glyph glyph)
|
||||
{
|
||||
m_ElementType = TextElementType.Character;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.glyph = glyph;
|
||||
this.glyphIndex = glyph.index;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new character
|
||||
/// </summary>
|
||||
/// <param name="unicode">Unicode value.</param>
|
||||
/// <param name="glyphIndex">Glyph index.</param>
|
||||
internal TMP_Character(uint unicode, uint glyphIndex)
|
||||
{
|
||||
m_ElementType = TextElementType.Character;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.glyph = null;
|
||||
this.glyphIndex = glyphIndex;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ac5b6a65aaeb59478e3b78660e9f134
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,73 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public struct TMP_Vertex
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector2 uv;
|
||||
public Vector2 uv2;
|
||||
public Vector2 uv4;
|
||||
public Color32 color;
|
||||
|
||||
//public Vector3 normal;
|
||||
//public Vector4 tangent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Structure containing information about individual text elements (character or sprites).
|
||||
/// </summary>
|
||||
public struct TMP_CharacterInfo
|
||||
{
|
||||
public char character; // Should be changed to an int to handle UTF 32
|
||||
/// <summary>
|
||||
/// Index of the character in the raw string.
|
||||
/// </summary>
|
||||
public int index; // Index of the character in the input string.
|
||||
public int stringLength;
|
||||
public TMP_TextElementType elementType;
|
||||
|
||||
public TMP_TextElement textElement;
|
||||
public TMP_FontAsset fontAsset;
|
||||
public TMP_SpriteAsset spriteAsset;
|
||||
public int spriteIndex;
|
||||
public Material material;
|
||||
public int materialReferenceIndex;
|
||||
public bool isUsingAlternateTypeface;
|
||||
|
||||
public float pointSize;
|
||||
|
||||
//public short wordNumber;
|
||||
public int lineNumber;
|
||||
//public short charNumber;
|
||||
public int pageNumber;
|
||||
|
||||
|
||||
public int vertexIndex;
|
||||
public TMP_Vertex vertex_BL;
|
||||
public TMP_Vertex vertex_TL;
|
||||
public TMP_Vertex vertex_TR;
|
||||
public TMP_Vertex vertex_BR;
|
||||
|
||||
public Vector3 topLeft;
|
||||
public Vector3 bottomLeft;
|
||||
public Vector3 topRight;
|
||||
public Vector3 bottomRight;
|
||||
public float origin;
|
||||
public float ascender;
|
||||
public float baseLine;
|
||||
public float descender;
|
||||
|
||||
public float xAdvance;
|
||||
public float aspectRatio;
|
||||
public float scale;
|
||||
public Color32 color;
|
||||
public Color32 underlineColor;
|
||||
public Color32 strikethroughColor;
|
||||
public Color32 highlightColor;
|
||||
public FontStyles style;
|
||||
public bool isVisible;
|
||||
//public bool isIgnoringAlignment;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 90fe1c65e6bb3bc4e90862df7297719e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,68 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public enum ColorMode
|
||||
{
|
||||
Single,
|
||||
HorizontalGradient,
|
||||
VerticalGradient,
|
||||
FourCornersGradient
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class TMP_ColorGradient : ScriptableObject
|
||||
{
|
||||
public ColorMode colorMode = ColorMode.FourCornersGradient;
|
||||
|
||||
public Color topLeft;
|
||||
public Color topRight;
|
||||
public Color bottomLeft;
|
||||
public Color bottomRight;
|
||||
|
||||
const ColorMode k_DefaultColorMode = ColorMode.FourCornersGradient;
|
||||
static readonly Color k_DefaultColor = Color.white;
|
||||
|
||||
/// <summary>
|
||||
/// Default Constructor which sets each of the colors as white.
|
||||
/// </summary>
|
||||
public TMP_ColorGradient()
|
||||
{
|
||||
colorMode = k_DefaultColorMode;
|
||||
topLeft = k_DefaultColor;
|
||||
topRight = k_DefaultColor;
|
||||
bottomLeft = k_DefaultColor;
|
||||
bottomRight = k_DefaultColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor allowing to set the default color of the Color Gradient.
|
||||
/// </summary>
|
||||
/// <param name="color"></param>
|
||||
public TMP_ColorGradient(Color color)
|
||||
{
|
||||
colorMode = k_DefaultColorMode;
|
||||
topLeft = color;
|
||||
topRight = color;
|
||||
bottomLeft = color;
|
||||
bottomRight = color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The vertex colors at the corners of the characters.
|
||||
/// </summary>
|
||||
/// <param name="color0">Top left color.</param>
|
||||
/// <param name="color1">Top right color.</param>
|
||||
/// <param name="color2">Bottom left color.</param>
|
||||
/// <param name="color3">Bottom right color.</param>
|
||||
public TMP_ColorGradient(Color color0, Color color1, Color color2, Color color3)
|
||||
{
|
||||
colorMode = k_DefaultColorMode;
|
||||
this.topLeft = color0;
|
||||
this.topRight = color1;
|
||||
this.bottomLeft = color2;
|
||||
this.bottomRight = color3;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 54d21f6ece3b46479f0c328f8c6007e0
|
||||
timeCreated: 1468187202
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,246 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
// Base interface for tweeners,
|
||||
// using an interface instead of
|
||||
// an abstract class as we want the
|
||||
// tweens to be structs.
|
||||
internal interface ITweenValue
|
||||
{
|
||||
void TweenValue(float floatPercentage);
|
||||
bool ignoreTimeScale { get; }
|
||||
float duration { get; }
|
||||
bool ValidTarget();
|
||||
}
|
||||
|
||||
// Color tween class, receives the
|
||||
// TweenValue callback and then sets
|
||||
// the value on the target.
|
||||
internal struct ColorTween : ITweenValue
|
||||
{
|
||||
public enum ColorTweenMode
|
||||
{
|
||||
All,
|
||||
RGB,
|
||||
Alpha
|
||||
}
|
||||
|
||||
public class ColorTweenCallback : UnityEvent<Color> { }
|
||||
|
||||
private ColorTweenCallback m_Target;
|
||||
private Color m_StartColor;
|
||||
private Color m_TargetColor;
|
||||
private ColorTweenMode m_TweenMode;
|
||||
|
||||
private float m_Duration;
|
||||
private bool m_IgnoreTimeScale;
|
||||
|
||||
public Color startColor
|
||||
{
|
||||
get { return m_StartColor; }
|
||||
set { m_StartColor = value; }
|
||||
}
|
||||
|
||||
public Color targetColor
|
||||
{
|
||||
get { return m_TargetColor; }
|
||||
set { m_TargetColor = value; }
|
||||
}
|
||||
|
||||
public ColorTweenMode tweenMode
|
||||
{
|
||||
get { return m_TweenMode; }
|
||||
set { m_TweenMode = value; }
|
||||
}
|
||||
|
||||
public float duration
|
||||
{
|
||||
get { return m_Duration; }
|
||||
set { m_Duration = value; }
|
||||
}
|
||||
|
||||
public bool ignoreTimeScale
|
||||
{
|
||||
get { return m_IgnoreTimeScale; }
|
||||
set { m_IgnoreTimeScale = value; }
|
||||
}
|
||||
|
||||
public void TweenValue(float floatPercentage)
|
||||
{
|
||||
if (!ValidTarget())
|
||||
return;
|
||||
|
||||
var newColor = Color.Lerp(m_StartColor, m_TargetColor, floatPercentage);
|
||||
|
||||
if (m_TweenMode == ColorTweenMode.Alpha)
|
||||
{
|
||||
newColor.r = m_StartColor.r;
|
||||
newColor.g = m_StartColor.g;
|
||||
newColor.b = m_StartColor.b;
|
||||
}
|
||||
else if (m_TweenMode == ColorTweenMode.RGB)
|
||||
{
|
||||
newColor.a = m_StartColor.a;
|
||||
}
|
||||
m_Target.Invoke(newColor);
|
||||
}
|
||||
|
||||
public void AddOnChangedCallback(UnityAction<Color> callback)
|
||||
{
|
||||
if (m_Target == null)
|
||||
m_Target = new ColorTweenCallback();
|
||||
|
||||
m_Target.AddListener(callback);
|
||||
}
|
||||
|
||||
public bool GetIgnoreTimescale()
|
||||
{
|
||||
return m_IgnoreTimeScale;
|
||||
}
|
||||
|
||||
public float GetDuration()
|
||||
{
|
||||
return m_Duration;
|
||||
}
|
||||
|
||||
public bool ValidTarget()
|
||||
{
|
||||
return m_Target != null;
|
||||
}
|
||||
}
|
||||
|
||||
// Float tween class, receives the
|
||||
// TweenValue callback and then sets
|
||||
// the value on the target.
|
||||
internal struct FloatTween : ITweenValue
|
||||
{
|
||||
public class FloatTweenCallback : UnityEvent<float> { }
|
||||
|
||||
private FloatTweenCallback m_Target;
|
||||
private float m_StartValue;
|
||||
private float m_TargetValue;
|
||||
|
||||
private float m_Duration;
|
||||
private bool m_IgnoreTimeScale;
|
||||
|
||||
public float startValue
|
||||
{
|
||||
get { return m_StartValue; }
|
||||
set { m_StartValue = value; }
|
||||
}
|
||||
|
||||
public float targetValue
|
||||
{
|
||||
get { return m_TargetValue; }
|
||||
set { m_TargetValue = value; }
|
||||
}
|
||||
|
||||
public float duration
|
||||
{
|
||||
get { return m_Duration; }
|
||||
set { m_Duration = value; }
|
||||
}
|
||||
|
||||
public bool ignoreTimeScale
|
||||
{
|
||||
get { return m_IgnoreTimeScale; }
|
||||
set { m_IgnoreTimeScale = value; }
|
||||
}
|
||||
|
||||
public void TweenValue(float floatPercentage)
|
||||
{
|
||||
if (!ValidTarget())
|
||||
return;
|
||||
|
||||
var newValue = Mathf.Lerp(m_StartValue, m_TargetValue, floatPercentage);
|
||||
m_Target.Invoke(newValue);
|
||||
}
|
||||
|
||||
public void AddOnChangedCallback(UnityAction<float> callback)
|
||||
{
|
||||
if (m_Target == null)
|
||||
m_Target = new FloatTweenCallback();
|
||||
|
||||
m_Target.AddListener(callback);
|
||||
}
|
||||
|
||||
public bool GetIgnoreTimescale()
|
||||
{
|
||||
return m_IgnoreTimeScale;
|
||||
}
|
||||
|
||||
public float GetDuration()
|
||||
{
|
||||
return m_Duration;
|
||||
}
|
||||
|
||||
public bool ValidTarget()
|
||||
{
|
||||
return m_Target != null;
|
||||
}
|
||||
}
|
||||
|
||||
// Tween runner, executes the given tween.
|
||||
// The coroutine will live within the given
|
||||
// behaviour container.
|
||||
internal class TweenRunner<T> where T : struct, ITweenValue
|
||||
{
|
||||
protected MonoBehaviour m_CoroutineContainer;
|
||||
protected IEnumerator m_Tween;
|
||||
|
||||
// utility function for starting the tween
|
||||
private static IEnumerator Start(T tweenInfo)
|
||||
{
|
||||
if (!tweenInfo.ValidTarget())
|
||||
yield break;
|
||||
|
||||
var elapsedTime = 0.0f;
|
||||
while (elapsedTime < tweenInfo.duration)
|
||||
{
|
||||
elapsedTime += tweenInfo.ignoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime;
|
||||
var percentage = Mathf.Clamp01(elapsedTime / tweenInfo.duration);
|
||||
tweenInfo.TweenValue(percentage);
|
||||
yield return null;
|
||||
}
|
||||
tweenInfo.TweenValue(1.0f);
|
||||
}
|
||||
|
||||
public void Init(MonoBehaviour coroutineContainer)
|
||||
{
|
||||
m_CoroutineContainer = coroutineContainer;
|
||||
}
|
||||
|
||||
public void StartTween(T info)
|
||||
{
|
||||
if (m_CoroutineContainer == null)
|
||||
{
|
||||
Debug.LogWarning("Coroutine container not configured... did you forget to call Init?");
|
||||
return;
|
||||
}
|
||||
|
||||
StopTween();
|
||||
|
||||
if (!m_CoroutineContainer.gameObject.activeInHierarchy)
|
||||
{
|
||||
info.TweenValue(1.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Tween = Start(info);
|
||||
m_CoroutineContainer.StartCoroutine(m_Tween);
|
||||
}
|
||||
|
||||
public void StopTween()
|
||||
{
|
||||
if (m_Tween != null)
|
||||
{
|
||||
m_CoroutineContainer.StopCoroutine(m_Tween);
|
||||
m_Tween = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 658c1fb149e7498aa072b0c0f3bf13f0
|
||||
timeCreated: 1464850953
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,385 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public static class TMP_DefaultControls
|
||||
{
|
||||
public struct Resources
|
||||
{
|
||||
public Sprite standard;
|
||||
public Sprite background;
|
||||
public Sprite inputField;
|
||||
public Sprite knob;
|
||||
public Sprite checkmark;
|
||||
public Sprite dropdown;
|
||||
public Sprite mask;
|
||||
}
|
||||
|
||||
private const float kWidth = 160f;
|
||||
private const float kThickHeight = 30f;
|
||||
private const float kThinHeight = 20f;
|
||||
private static Vector2 s_ThickElementSize = new Vector2(kWidth, kThickHeight);
|
||||
private static Vector2 s_ThinElementSize = new Vector2(kWidth, kThinHeight);
|
||||
//private static Vector2 s_ImageElementSize = new Vector2(100f, 100f);
|
||||
private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f);
|
||||
//private static Color s_PanelColor = new Color(1f, 1f, 1f, 0.392f);
|
||||
private static Color s_TextColor = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f);
|
||||
|
||||
|
||||
private static GameObject CreateUIElementRoot(string name, Vector2 size)
|
||||
{
|
||||
GameObject child = new GameObject(name);
|
||||
RectTransform rectTransform = child.AddComponent<RectTransform>();
|
||||
rectTransform.sizeDelta = size;
|
||||
return child;
|
||||
}
|
||||
|
||||
static GameObject CreateUIObject(string name, GameObject parent)
|
||||
{
|
||||
GameObject go = new GameObject(name);
|
||||
go.AddComponent<RectTransform>();
|
||||
SetParentAndAlign(go, parent);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static void SetDefaultTextValues(TMP_Text lbl)
|
||||
{
|
||||
// Set text values we want across UI elements in default controls.
|
||||
// Don't set values which are the same as the default values for the Text component,
|
||||
// since there's no point in that, and it's good to keep them as consistent as possible.
|
||||
lbl.color = s_TextColor;
|
||||
lbl.fontSize = 14;
|
||||
}
|
||||
|
||||
private static void SetDefaultColorTransitionValues(Selectable slider)
|
||||
{
|
||||
ColorBlock colors = slider.colors;
|
||||
colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f);
|
||||
colors.pressedColor = new Color(0.698f, 0.698f, 0.698f);
|
||||
colors.disabledColor = new Color(0.521f, 0.521f, 0.521f);
|
||||
}
|
||||
|
||||
private static void SetParentAndAlign(GameObject child, GameObject parent)
|
||||
{
|
||||
if (parent == null)
|
||||
return;
|
||||
|
||||
child.transform.SetParent(parent.transform, false);
|
||||
SetLayerRecursively(child, parent.layer);
|
||||
}
|
||||
|
||||
private static void SetLayerRecursively(GameObject go, int layer)
|
||||
{
|
||||
go.layer = layer;
|
||||
Transform t = go.transform;
|
||||
for (int i = 0; i < t.childCount; i++)
|
||||
SetLayerRecursively(t.GetChild(i).gameObject, layer);
|
||||
}
|
||||
|
||||
// Actual controls
|
||||
|
||||
public static GameObject CreateScrollbar(Resources resources)
|
||||
{
|
||||
// Create GOs Hierarchy
|
||||
GameObject scrollbarRoot = CreateUIElementRoot("Scrollbar", s_ThinElementSize);
|
||||
|
||||
GameObject sliderArea = CreateUIObject("Sliding Area", scrollbarRoot);
|
||||
GameObject handle = CreateUIObject("Handle", sliderArea);
|
||||
|
||||
Image bgImage = scrollbarRoot.AddComponent<Image>();
|
||||
bgImage.sprite = resources.background;
|
||||
bgImage.type = Image.Type.Sliced;
|
||||
bgImage.color = s_DefaultSelectableColor;
|
||||
|
||||
Image handleImage = handle.AddComponent<Image>();
|
||||
handleImage.sprite = resources.standard;
|
||||
handleImage.type = Image.Type.Sliced;
|
||||
handleImage.color = s_DefaultSelectableColor;
|
||||
|
||||
RectTransform sliderAreaRect = sliderArea.GetComponent<RectTransform>();
|
||||
sliderAreaRect.sizeDelta = new Vector2(-20, -20);
|
||||
sliderAreaRect.anchorMin = Vector2.zero;
|
||||
sliderAreaRect.anchorMax = Vector2.one;
|
||||
|
||||
RectTransform handleRect = handle.GetComponent<RectTransform>();
|
||||
handleRect.sizeDelta = new Vector2(20, 20);
|
||||
|
||||
Scrollbar scrollbar = scrollbarRoot.AddComponent<Scrollbar>();
|
||||
scrollbar.handleRect = handleRect;
|
||||
scrollbar.targetGraphic = handleImage;
|
||||
SetDefaultColorTransitionValues(scrollbar);
|
||||
|
||||
return scrollbarRoot;
|
||||
}
|
||||
|
||||
public static GameObject CreateButton(Resources resources)
|
||||
{
|
||||
GameObject buttonRoot = CreateUIElementRoot("Button", s_ThickElementSize);
|
||||
|
||||
GameObject childText = new GameObject("Text (TMP)");
|
||||
childText.AddComponent<RectTransform>();
|
||||
SetParentAndAlign(childText, buttonRoot);
|
||||
|
||||
Image image = buttonRoot.AddComponent<Image>();
|
||||
image.sprite = resources.standard;
|
||||
image.type = Image.Type.Sliced;
|
||||
image.color = s_DefaultSelectableColor;
|
||||
|
||||
Button bt = buttonRoot.AddComponent<Button>();
|
||||
SetDefaultColorTransitionValues(bt);
|
||||
|
||||
TextMeshProUGUI text = childText.AddComponent<TextMeshProUGUI>();
|
||||
text.text = "Button";
|
||||
text.alignment = TextAlignmentOptions.Center;
|
||||
SetDefaultTextValues(text);
|
||||
|
||||
RectTransform textRectTransform = childText.GetComponent<RectTransform>();
|
||||
textRectTransform.anchorMin = Vector2.zero;
|
||||
textRectTransform.anchorMax = Vector2.one;
|
||||
textRectTransform.sizeDelta = Vector2.zero;
|
||||
|
||||
return buttonRoot;
|
||||
}
|
||||
|
||||
public static GameObject CreateText(Resources resources)
|
||||
{
|
||||
GameObject go = CreateUIElementRoot("Text (TMP)", s_ThickElementSize);
|
||||
|
||||
TextMeshProUGUI lbl = go.AddComponent<TextMeshProUGUI>();
|
||||
lbl.text = "New Text";
|
||||
SetDefaultTextValues(lbl);
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
|
||||
public static GameObject CreateInputField(Resources resources)
|
||||
{
|
||||
GameObject root = CreateUIElementRoot("InputField (TMP)", s_ThickElementSize);
|
||||
|
||||
GameObject textArea = CreateUIObject("Text Area", root);
|
||||
GameObject childPlaceholder = CreateUIObject("Placeholder", textArea);
|
||||
GameObject childText = CreateUIObject("Text", textArea);
|
||||
|
||||
Image image = root.AddComponent<Image>();
|
||||
image.sprite = resources.inputField;
|
||||
image.type = Image.Type.Sliced;
|
||||
image.color = s_DefaultSelectableColor;
|
||||
|
||||
TMP_InputField inputField = root.AddComponent<TMP_InputField>();
|
||||
SetDefaultColorTransitionValues(inputField);
|
||||
|
||||
// Use UI.Mask for Unity 5.0 - 5.1 and 2D RectMask for Unity 5.2 and up
|
||||
textArea.AddComponent<RectMask2D>();
|
||||
|
||||
RectTransform textAreaRectTransform = textArea.GetComponent<RectTransform>();
|
||||
textAreaRectTransform.anchorMin = Vector2.zero;
|
||||
textAreaRectTransform.anchorMax = Vector2.one;
|
||||
textAreaRectTransform.sizeDelta = Vector2.zero;
|
||||
textAreaRectTransform.offsetMin = new Vector2(10, 6);
|
||||
textAreaRectTransform.offsetMax = new Vector2(-10, -7);
|
||||
|
||||
|
||||
TextMeshProUGUI text = childText.AddComponent<TextMeshProUGUI>();
|
||||
text.text = "";
|
||||
text.enableWordWrapping = false;
|
||||
text.extraPadding = true;
|
||||
text.richText = true;
|
||||
SetDefaultTextValues(text);
|
||||
|
||||
TextMeshProUGUI placeholder = childPlaceholder.AddComponent<TextMeshProUGUI>();
|
||||
placeholder.text = "Enter text...";
|
||||
placeholder.fontSize = 14;
|
||||
placeholder.fontStyle = FontStyles.Italic;
|
||||
placeholder.enableWordWrapping = false;
|
||||
placeholder.extraPadding = true;
|
||||
|
||||
// Make placeholder color half as opaque as normal text color.
|
||||
Color placeholderColor = text.color;
|
||||
placeholderColor.a *= 0.5f;
|
||||
placeholder.color = placeholderColor;
|
||||
|
||||
RectTransform textRectTransform = childText.GetComponent<RectTransform>();
|
||||
textRectTransform.anchorMin = Vector2.zero;
|
||||
textRectTransform.anchorMax = Vector2.one;
|
||||
textRectTransform.sizeDelta = Vector2.zero;
|
||||
textRectTransform.offsetMin = new Vector2(0, 0);
|
||||
textRectTransform.offsetMax = new Vector2(0, 0);
|
||||
|
||||
RectTransform placeholderRectTransform = childPlaceholder.GetComponent<RectTransform>();
|
||||
placeholderRectTransform.anchorMin = Vector2.zero;
|
||||
placeholderRectTransform.anchorMax = Vector2.one;
|
||||
placeholderRectTransform.sizeDelta = Vector2.zero;
|
||||
placeholderRectTransform.offsetMin = new Vector2(0, 0);
|
||||
placeholderRectTransform.offsetMax = new Vector2(0, 0);
|
||||
|
||||
inputField.textViewport = textAreaRectTransform;
|
||||
inputField.textComponent = text;
|
||||
inputField.placeholder = placeholder;
|
||||
inputField.fontAsset = text.font;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public static GameObject CreateDropdown(Resources resources)
|
||||
{
|
||||
GameObject root = CreateUIElementRoot("Dropdown", s_ThickElementSize);
|
||||
|
||||
GameObject label = CreateUIObject("Label", root);
|
||||
GameObject arrow = CreateUIObject("Arrow", root);
|
||||
GameObject template = CreateUIObject("Template", root);
|
||||
GameObject viewport = CreateUIObject("Viewport", template);
|
||||
GameObject content = CreateUIObject("Content", viewport);
|
||||
GameObject item = CreateUIObject("Item", content);
|
||||
GameObject itemBackground = CreateUIObject("Item Background", item);
|
||||
GameObject itemCheckmark = CreateUIObject("Item Checkmark", item);
|
||||
GameObject itemLabel = CreateUIObject("Item Label", item);
|
||||
|
||||
// Sub controls.
|
||||
|
||||
GameObject scrollbar = CreateScrollbar(resources);
|
||||
scrollbar.name = "Scrollbar";
|
||||
SetParentAndAlign(scrollbar, template);
|
||||
|
||||
Scrollbar scrollbarScrollbar = scrollbar.GetComponent<Scrollbar>();
|
||||
scrollbarScrollbar.SetDirection(Scrollbar.Direction.BottomToTop, true);
|
||||
|
||||
RectTransform vScrollbarRT = scrollbar.GetComponent<RectTransform>();
|
||||
vScrollbarRT.anchorMin = Vector2.right;
|
||||
vScrollbarRT.anchorMax = Vector2.one;
|
||||
vScrollbarRT.pivot = Vector2.one;
|
||||
vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0);
|
||||
|
||||
// Setup item UI components.
|
||||
|
||||
TextMeshProUGUI itemLabelText = itemLabel.AddComponent<TextMeshProUGUI>();
|
||||
SetDefaultTextValues(itemLabelText);
|
||||
itemLabelText.alignment = TextAlignmentOptions.Left;
|
||||
|
||||
Image itemBackgroundImage = itemBackground.AddComponent<Image>();
|
||||
itemBackgroundImage.color = new Color32(245, 245, 245, 255);
|
||||
|
||||
Image itemCheckmarkImage = itemCheckmark.AddComponent<Image>();
|
||||
itemCheckmarkImage.sprite = resources.checkmark;
|
||||
|
||||
Toggle itemToggle = item.AddComponent<Toggle>();
|
||||
itemToggle.targetGraphic = itemBackgroundImage;
|
||||
itemToggle.graphic = itemCheckmarkImage;
|
||||
itemToggle.isOn = true;
|
||||
|
||||
// Setup template UI components.
|
||||
|
||||
Image templateImage = template.AddComponent<Image>();
|
||||
templateImage.sprite = resources.standard;
|
||||
templateImage.type = Image.Type.Sliced;
|
||||
|
||||
ScrollRect templateScrollRect = template.AddComponent<ScrollRect>();
|
||||
templateScrollRect.content = (RectTransform)content.transform;
|
||||
templateScrollRect.viewport = (RectTransform)viewport.transform;
|
||||
templateScrollRect.horizontal = false;
|
||||
templateScrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
templateScrollRect.verticalScrollbar = scrollbarScrollbar;
|
||||
templateScrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
|
||||
templateScrollRect.verticalScrollbarSpacing = -3;
|
||||
|
||||
Mask scrollRectMask = viewport.AddComponent<Mask>();
|
||||
scrollRectMask.showMaskGraphic = false;
|
||||
|
||||
Image viewportImage = viewport.AddComponent<Image>();
|
||||
viewportImage.sprite = resources.mask;
|
||||
viewportImage.type = Image.Type.Sliced;
|
||||
|
||||
// Setup dropdown UI components.
|
||||
|
||||
TextMeshProUGUI labelText = label.AddComponent<TextMeshProUGUI>();
|
||||
SetDefaultTextValues(labelText);
|
||||
labelText.alignment = TextAlignmentOptions.Left;
|
||||
|
||||
Image arrowImage = arrow.AddComponent<Image>();
|
||||
arrowImage.sprite = resources.dropdown;
|
||||
|
||||
Image backgroundImage = root.AddComponent<Image>();
|
||||
backgroundImage.sprite = resources.standard;
|
||||
backgroundImage.color = s_DefaultSelectableColor;
|
||||
backgroundImage.type = Image.Type.Sliced;
|
||||
|
||||
TMP_Dropdown dropdown = root.AddComponent<TMP_Dropdown>();
|
||||
dropdown.targetGraphic = backgroundImage;
|
||||
SetDefaultColorTransitionValues(dropdown);
|
||||
dropdown.template = template.GetComponent<RectTransform>();
|
||||
dropdown.captionText = labelText;
|
||||
dropdown.itemText = itemLabelText;
|
||||
|
||||
// Setting default Item list.
|
||||
itemLabelText.text = "Option A";
|
||||
dropdown.options.Add(new TMP_Dropdown.OptionData {text = "Option A" });
|
||||
dropdown.options.Add(new TMP_Dropdown.OptionData {text = "Option B" });
|
||||
dropdown.options.Add(new TMP_Dropdown.OptionData {text = "Option C" });
|
||||
dropdown.RefreshShownValue();
|
||||
|
||||
// Set up RectTransforms.
|
||||
|
||||
RectTransform labelRT = label.GetComponent<RectTransform>();
|
||||
labelRT.anchorMin = Vector2.zero;
|
||||
labelRT.anchorMax = Vector2.one;
|
||||
labelRT.offsetMin = new Vector2(10, 6);
|
||||
labelRT.offsetMax = new Vector2(-25, -7);
|
||||
|
||||
RectTransform arrowRT = arrow.GetComponent<RectTransform>();
|
||||
arrowRT.anchorMin = new Vector2(1, 0.5f);
|
||||
arrowRT.anchorMax = new Vector2(1, 0.5f);
|
||||
arrowRT.sizeDelta = new Vector2(20, 20);
|
||||
arrowRT.anchoredPosition = new Vector2(-15, 0);
|
||||
|
||||
RectTransform templateRT = template.GetComponent<RectTransform>();
|
||||
templateRT.anchorMin = new Vector2(0, 0);
|
||||
templateRT.anchorMax = new Vector2(1, 0);
|
||||
templateRT.pivot = new Vector2(0.5f, 1);
|
||||
templateRT.anchoredPosition = new Vector2(0, 2);
|
||||
templateRT.sizeDelta = new Vector2(0, 150);
|
||||
|
||||
RectTransform viewportRT = viewport.GetComponent<RectTransform>();
|
||||
viewportRT.anchorMin = new Vector2(0, 0);
|
||||
viewportRT.anchorMax = new Vector2(1, 1);
|
||||
viewportRT.sizeDelta = new Vector2(-18, 0);
|
||||
viewportRT.pivot = new Vector2(0, 1);
|
||||
|
||||
RectTransform contentRT = content.GetComponent<RectTransform>();
|
||||
contentRT.anchorMin = new Vector2(0f, 1);
|
||||
contentRT.anchorMax = new Vector2(1f, 1);
|
||||
contentRT.pivot = new Vector2(0.5f, 1);
|
||||
contentRT.anchoredPosition = new Vector2(0, 0);
|
||||
contentRT.sizeDelta = new Vector2(0, 28);
|
||||
|
||||
RectTransform itemRT = item.GetComponent<RectTransform>();
|
||||
itemRT.anchorMin = new Vector2(0, 0.5f);
|
||||
itemRT.anchorMax = new Vector2(1, 0.5f);
|
||||
itemRT.sizeDelta = new Vector2(0, 20);
|
||||
|
||||
RectTransform itemBackgroundRT = itemBackground.GetComponent<RectTransform>();
|
||||
itemBackgroundRT.anchorMin = Vector2.zero;
|
||||
itemBackgroundRT.anchorMax = Vector2.one;
|
||||
itemBackgroundRT.sizeDelta = Vector2.zero;
|
||||
|
||||
RectTransform itemCheckmarkRT = itemCheckmark.GetComponent<RectTransform>();
|
||||
itemCheckmarkRT.anchorMin = new Vector2(0, 0.5f);
|
||||
itemCheckmarkRT.anchorMax = new Vector2(0, 0.5f);
|
||||
itemCheckmarkRT.sizeDelta = new Vector2(20, 20);
|
||||
itemCheckmarkRT.anchoredPosition = new Vector2(10, 0);
|
||||
|
||||
RectTransform itemLabelRT = itemLabel.GetComponent<RectTransform>();
|
||||
itemLabelRT.anchorMin = Vector2.zero;
|
||||
itemLabelRT.anchorMax = Vector2.one;
|
||||
itemLabelRT.offsetMin = new Vector2(20, 1);
|
||||
itemLabelRT.offsetMax = new Vector2(-10, -2);
|
||||
|
||||
template.SetActive(false);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 322392995be44d23a3c86cfd972f838f
|
||||
timeCreated: 1446378357
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7b743370ac3e4ec2a1668f5455a8ef8a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: a7ec9e7ad8b847b7ae4510af83c5d868, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,142 @@
|
|||
#if UNITY_EDITOR
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class TMP_EditorResourceManager
|
||||
{
|
||||
private static TMP_EditorResourceManager s_Instance;
|
||||
|
||||
private readonly List<Object> m_ObjectUpdateQueue = new List<Object>();
|
||||
private Dictionary<int, int> m_ObjectUpdateQueueLookup = new Dictionary<int, int>();
|
||||
|
||||
private readonly List<Object> m_ObjectReImportQueue = new List<Object>();
|
||||
private Dictionary<int, int> m_ObjectReImportQueueLookup = new Dictionary<int, int>();
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the manager.
|
||||
/// </summary>
|
||||
public static TMP_EditorResourceManager instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_Instance == null)
|
||||
s_Instance = new TMP_EditorResourceManager();
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register to receive rendering callbacks.
|
||||
/// </summary>
|
||||
private TMP_EditorResourceManager()
|
||||
{
|
||||
Camera.onPostRender += OnCameraPostRender;
|
||||
}
|
||||
|
||||
|
||||
void OnCameraPostRender(Camera cam)
|
||||
{
|
||||
// Exclude the PreRenderCamera
|
||||
if (cam.cameraType == CameraType.Preview)
|
||||
return;
|
||||
|
||||
DoUpdates();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register resource for re-import.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
internal static void RegisterResourceForReimport(Object obj)
|
||||
{
|
||||
instance.InternalRegisterResourceForReimport(obj);
|
||||
}
|
||||
|
||||
private void InternalRegisterResourceForReimport(Object obj)
|
||||
{
|
||||
int id = obj.GetInstanceID();
|
||||
|
||||
if (m_ObjectReImportQueueLookup.ContainsKey(id))
|
||||
return;
|
||||
|
||||
m_ObjectReImportQueueLookup[id] = id;
|
||||
m_ObjectReImportQueue.Add(obj);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register resource to be updated.
|
||||
/// </summary>
|
||||
/// <param name="textObject"></param>
|
||||
internal static void RegisterResourceForUpdate(Object obj)
|
||||
{
|
||||
instance.InternalRegisterResourceForUpdate(obj);
|
||||
}
|
||||
|
||||
private void InternalRegisterResourceForUpdate(Object obj)
|
||||
{
|
||||
int id = obj.GetInstanceID();
|
||||
|
||||
if (m_ObjectUpdateQueueLookup.ContainsKey(id))
|
||||
return;
|
||||
|
||||
m_ObjectUpdateQueueLookup[id] = id;
|
||||
m_ObjectUpdateQueue.Add(obj);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void DoUpdates()
|
||||
{
|
||||
// Handle objects that need updating
|
||||
int objUpdateCount = m_ObjectUpdateQueue.Count;
|
||||
|
||||
for (int i = 0; i < objUpdateCount; i++)
|
||||
{
|
||||
Object obj = m_ObjectUpdateQueue[i];
|
||||
if (obj != null)
|
||||
{
|
||||
EditorUtility.SetDirty(obj);
|
||||
}
|
||||
}
|
||||
|
||||
if (objUpdateCount > 0)
|
||||
{
|
||||
//Debug.Log("Saving assets");
|
||||
//AssetDatabase.SaveAssets();
|
||||
|
||||
m_ObjectUpdateQueue.Clear();
|
||||
m_ObjectUpdateQueueLookup.Clear();
|
||||
}
|
||||
|
||||
// Handle objects that need re-importing
|
||||
int objReImportCount = m_ObjectReImportQueue.Count;
|
||||
|
||||
for (int i = 0; i < objReImportCount; i++)
|
||||
{
|
||||
Object obj = m_ObjectReImportQueue[i];
|
||||
if (obj != null)
|
||||
{
|
||||
//Debug.Log("Re-importing [" + obj.name + "]");
|
||||
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(obj));
|
||||
}
|
||||
}
|
||||
|
||||
if (objReImportCount > 0)
|
||||
{
|
||||
m_ObjectReImportQueue.Clear();
|
||||
m_ObjectReImportQueueLookup.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6b259c4003a802847b9ada90744e34c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 71c1514a6bd24e1e882cebbe1904ce04
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: ee148e281f3c41c5b4ff5f8a5afe5a6c, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,456 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.TextCore;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that contains the basic information about the font.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class FaceInfo_Legacy
|
||||
{
|
||||
public string Name;
|
||||
public float PointSize;
|
||||
public float Scale;
|
||||
|
||||
public int CharacterCount;
|
||||
|
||||
public float LineHeight;
|
||||
public float Baseline;
|
||||
public float Ascender;
|
||||
public float CapHeight;
|
||||
public float Descender;
|
||||
public float CenterLine;
|
||||
|
||||
public float SuperscriptOffset;
|
||||
public float SubscriptOffset;
|
||||
public float SubSize;
|
||||
|
||||
public float Underline;
|
||||
public float UnderlineThickness;
|
||||
|
||||
public float strikethrough;
|
||||
public float strikethroughThickness;
|
||||
|
||||
public float TabWidth;
|
||||
|
||||
public float Padding;
|
||||
public float AtlasWidth;
|
||||
public float AtlasHeight;
|
||||
}
|
||||
|
||||
|
||||
// Class which contains the Glyph Info / Character definition for each character contained in the font asset.
|
||||
[Serializable]
|
||||
public class TMP_Glyph : TMP_TextElement_Legacy
|
||||
{
|
||||
/// <summary>
|
||||
/// Function to create a deep copy of a GlyphInfo.
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static TMP_Glyph Clone(TMP_Glyph source)
|
||||
{
|
||||
TMP_Glyph copy = new TMP_Glyph();
|
||||
|
||||
copy.id = source.id;
|
||||
copy.x = source.x;
|
||||
copy.y = source.y;
|
||||
copy.width = source.width;
|
||||
copy.height = source.height;
|
||||
copy.xOffset = source.xOffset;
|
||||
copy.yOffset = source.yOffset;
|
||||
copy.xAdvance = source.xAdvance;
|
||||
copy.scale = source.scale;
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Structure which holds the font creation settings
|
||||
[Serializable]
|
||||
public struct FontAssetCreationSettings
|
||||
{
|
||||
public string sourceFontFileName;
|
||||
public string sourceFontFileGUID;
|
||||
public int pointSizeSamplingMode;
|
||||
public int pointSize;
|
||||
public int padding;
|
||||
public int packingMode;
|
||||
public int atlasWidth;
|
||||
public int atlasHeight;
|
||||
public int characterSetSelectionMode;
|
||||
public string characterSequence;
|
||||
public string referencedFontAssetGUID;
|
||||
public string referencedTextAssetGUID;
|
||||
public int fontStyle;
|
||||
public float fontStyleModifier;
|
||||
public int renderMode;
|
||||
public bool includeFontFeatures;
|
||||
|
||||
internal FontAssetCreationSettings(string sourceFontFileGUID, int pointSize, int pointSizeSamplingMode, int padding, int packingMode, int atlasWidth, int atlasHeight, int characterSelectionMode, string characterSet, int renderMode)
|
||||
{
|
||||
this.sourceFontFileName = string.Empty;
|
||||
this.sourceFontFileGUID = sourceFontFileGUID;
|
||||
this.pointSize = pointSize;
|
||||
this.pointSizeSamplingMode = pointSizeSamplingMode;
|
||||
this.padding = padding;
|
||||
this.packingMode = packingMode;
|
||||
this.atlasWidth = atlasWidth;
|
||||
this.atlasHeight = atlasHeight;
|
||||
this.characterSequence = characterSet;
|
||||
this.characterSetSelectionMode = characterSelectionMode;
|
||||
this.renderMode = renderMode;
|
||||
|
||||
this.referencedFontAssetGUID = string.Empty;
|
||||
this.referencedTextAssetGUID = string.Empty;
|
||||
this.fontStyle = 0;
|
||||
this.fontStyleModifier = 0;
|
||||
this.includeFontFeatures = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the font assets for the regular and italic styles associated with a given font weight.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TMP_FontWeightPair
|
||||
{
|
||||
public TMP_FontAsset regularTypeface;
|
||||
public TMP_FontAsset italicTypeface;
|
||||
}
|
||||
|
||||
|
||||
public struct KerningPairKey
|
||||
{
|
||||
public uint ascii_Left;
|
||||
public uint ascii_Right;
|
||||
public uint key;
|
||||
|
||||
public KerningPairKey(uint ascii_left, uint ascii_right)
|
||||
{
|
||||
ascii_Left = ascii_left;
|
||||
ascii_Right = ascii_right;
|
||||
key = (ascii_right << 16) + ascii_left;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Positional adjustments of a glyph
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct GlyphValueRecord_Legacy
|
||||
{
|
||||
public float xPlacement;
|
||||
public float yPlacement;
|
||||
public float xAdvance;
|
||||
public float yAdvance;
|
||||
|
||||
internal GlyphValueRecord_Legacy(UnityEngine.TextCore.LowLevel.GlyphValueRecord valueRecord)
|
||||
{
|
||||
this.xPlacement = valueRecord.xPlacement;
|
||||
this.yPlacement = valueRecord.yPlacement;
|
||||
this.xAdvance = valueRecord.xAdvance;
|
||||
this.yAdvance = valueRecord.yAdvance;
|
||||
}
|
||||
|
||||
public static GlyphValueRecord_Legacy operator +(GlyphValueRecord_Legacy a, GlyphValueRecord_Legacy b)
|
||||
{
|
||||
GlyphValueRecord_Legacy c;
|
||||
c.xPlacement = a.xPlacement + b.xPlacement;
|
||||
c.yPlacement = a.yPlacement + b.yPlacement;
|
||||
c.xAdvance = a.xAdvance + b.xAdvance;
|
||||
c.yAdvance = a.yAdvance + b.yAdvance;
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class KerningPair
|
||||
{
|
||||
/// <summary>
|
||||
/// The first glyph part of a kerning pair.
|
||||
/// </summary>
|
||||
public uint firstGlyph
|
||||
{
|
||||
get { return m_FirstGlyph; }
|
||||
set { m_FirstGlyph = value; }
|
||||
}
|
||||
[FormerlySerializedAs("AscII_Left")]
|
||||
[SerializeField]
|
||||
private uint m_FirstGlyph;
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment of the first glyph.
|
||||
/// </summary>
|
||||
public GlyphValueRecord_Legacy firstGlyphAdjustments
|
||||
{
|
||||
get { return m_FirstGlyphAdjustments; }
|
||||
}
|
||||
[SerializeField]
|
||||
private GlyphValueRecord_Legacy m_FirstGlyphAdjustments;
|
||||
|
||||
/// <summary>
|
||||
/// The second glyph part of a kerning pair.
|
||||
/// </summary>
|
||||
public uint secondGlyph
|
||||
{
|
||||
get { return m_SecondGlyph; }
|
||||
set { m_SecondGlyph = value; }
|
||||
}
|
||||
[FormerlySerializedAs("AscII_Right")]
|
||||
[SerializeField]
|
||||
private uint m_SecondGlyph;
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment of the second glyph.
|
||||
/// </summary>
|
||||
public GlyphValueRecord_Legacy secondGlyphAdjustments
|
||||
{
|
||||
get { return m_SecondGlyphAdjustments; }
|
||||
}
|
||||
[SerializeField]
|
||||
private GlyphValueRecord_Legacy m_SecondGlyphAdjustments;
|
||||
|
||||
[FormerlySerializedAs("XadvanceOffset")]
|
||||
public float xOffset;
|
||||
|
||||
internal static KerningPair empty = new KerningPair(0, new GlyphValueRecord_Legacy(), 0, new GlyphValueRecord_Legacy());
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the Character Spacing property of the text object will affect the kerning pair.
|
||||
/// This is mostly relevant when using Diacritical marks to prevent Character Spacing from altering the
|
||||
/// </summary>
|
||||
public bool ignoreSpacingAdjustments
|
||||
{
|
||||
get { return m_IgnoreSpacingAdjustments; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_IgnoreSpacingAdjustments = false;
|
||||
|
||||
public KerningPair()
|
||||
{
|
||||
m_FirstGlyph = 0;
|
||||
m_FirstGlyphAdjustments = new GlyphValueRecord_Legacy();
|
||||
|
||||
m_SecondGlyph = 0;
|
||||
m_SecondGlyphAdjustments = new GlyphValueRecord_Legacy();
|
||||
}
|
||||
|
||||
public KerningPair(uint left, uint right, float offset)
|
||||
{
|
||||
firstGlyph = left;
|
||||
m_SecondGlyph = right;
|
||||
xOffset = offset;
|
||||
}
|
||||
|
||||
public KerningPair(uint firstGlyph, GlyphValueRecord_Legacy firstGlyphAdjustments, uint secondGlyph, GlyphValueRecord_Legacy secondGlyphAdjustments)
|
||||
{
|
||||
m_FirstGlyph = firstGlyph;
|
||||
m_FirstGlyphAdjustments = firstGlyphAdjustments;
|
||||
m_SecondGlyph = secondGlyph;
|
||||
m_SecondGlyphAdjustments = secondGlyphAdjustments;
|
||||
}
|
||||
|
||||
internal void ConvertLegacyKerningData()
|
||||
{
|
||||
m_FirstGlyphAdjustments.xAdvance = xOffset;
|
||||
//xOffset = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class KerningTable
|
||||
{
|
||||
public List<KerningPair> kerningPairs;
|
||||
|
||||
public KerningTable()
|
||||
{
|
||||
kerningPairs = new List<KerningPair>();
|
||||
}
|
||||
|
||||
|
||||
public void AddKerningPair()
|
||||
{
|
||||
if (kerningPairs.Count == 0)
|
||||
{
|
||||
kerningPairs.Add(new KerningPair(0, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint left = kerningPairs.Last().firstGlyph;
|
||||
uint right = kerningPairs.Last().secondGlyph;
|
||||
float xoffset = kerningPairs.Last().xOffset;
|
||||
|
||||
kerningPairs.Add(new KerningPair(left, right, xoffset));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add Kerning Pair
|
||||
/// </summary>
|
||||
/// <param name="first">First glyph</param>
|
||||
/// <param name="second">Second glyph</param>
|
||||
/// <param name="offset">xAdvance value</param>
|
||||
/// <returns></returns>
|
||||
public int AddKerningPair(uint first, uint second, float offset)
|
||||
{
|
||||
int index = kerningPairs.FindIndex(item => item.firstGlyph == first && item.secondGlyph == second);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
kerningPairs.Add(new KerningPair(first, second, offset));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return -1 if Kerning Pair already exists.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Glyph pair adjustment record
|
||||
/// </summary>
|
||||
/// <param name="firstGlyph">The first glyph</param>
|
||||
/// <param name="firstGlyphAdjustments">Adjustment record for the first glyph</param>
|
||||
/// <param name="secondGlyph">The second glyph</param>
|
||||
/// <param name="secondGlyphAdjustments">Adjustment record for the second glyph</param>
|
||||
/// <returns></returns>
|
||||
public int AddGlyphPairAdjustmentRecord(uint first, GlyphValueRecord_Legacy firstAdjustments, uint second, GlyphValueRecord_Legacy secondAdjustments)
|
||||
{
|
||||
int index = kerningPairs.FindIndex(item => item.firstGlyph == first && item.secondGlyph == second);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
kerningPairs.Add(new KerningPair(first, firstAdjustments, second, secondAdjustments));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return -1 if Kerning Pair already exists.
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void RemoveKerningPair(int left, int right)
|
||||
{
|
||||
int index = kerningPairs.FindIndex(item => item.firstGlyph == left && item.secondGlyph == right);
|
||||
|
||||
if (index != -1)
|
||||
kerningPairs.RemoveAt(index);
|
||||
}
|
||||
|
||||
|
||||
public void RemoveKerningPair(int index)
|
||||
{
|
||||
kerningPairs.RemoveAt(index);
|
||||
}
|
||||
|
||||
|
||||
public void SortKerningPairs()
|
||||
{
|
||||
// Sort List of Kerning Info
|
||||
if (kerningPairs.Count > 0)
|
||||
kerningPairs = kerningPairs.OrderBy(s => s.firstGlyph).ThenBy(s => s.secondGlyph).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TMP_FontUtilities
|
||||
{
|
||||
private static List<int> k_searchedFontAssets;
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given font and its fallbacks for the specified character.
|
||||
/// </summary>
|
||||
/// <param name="font">The font asset to search for the given character.</param>
|
||||
/// <param name="unicode">The character to find.</param>
|
||||
/// <param name="character">out parameter containing the glyph for the specified character (if found).</param>
|
||||
/// <returns></returns>
|
||||
public static TMP_FontAsset SearchForCharacter(TMP_FontAsset font, uint unicode, out TMP_Character character)
|
||||
{
|
||||
if (k_searchedFontAssets == null)
|
||||
k_searchedFontAssets = new List<int>();
|
||||
|
||||
k_searchedFontAssets.Clear();
|
||||
|
||||
return SearchForCharacterInternal(font, unicode, out character);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given list of fonts and their possible fallbacks for the specified character.
|
||||
/// </summary>
|
||||
/// <param name="fonts"></param>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="character"></param>
|
||||
/// <returns></returns>
|
||||
public static TMP_FontAsset SearchForCharacter(List<TMP_FontAsset> fonts, uint unicode, out TMP_Character character)
|
||||
{
|
||||
return SearchForCharacterInternal(fonts, unicode, out character);
|
||||
}
|
||||
|
||||
|
||||
private static TMP_FontAsset SearchForCharacterInternal(TMP_FontAsset font, uint unicode, out TMP_Character character)
|
||||
{
|
||||
character = null;
|
||||
|
||||
if (font == null) return null;
|
||||
|
||||
if (font.characterLookupTable.TryGetValue(unicode, out character))
|
||||
{
|
||||
return font;
|
||||
}
|
||||
else if (font.fallbackFontAssetTable != null && font.fallbackFontAssetTable.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < font.fallbackFontAssetTable.Count && character == null; i++)
|
||||
{
|
||||
TMP_FontAsset temp = font.fallbackFontAssetTable[i];
|
||||
if (temp == null) continue;
|
||||
|
||||
int id = temp.GetInstanceID();
|
||||
|
||||
// Skip over the fallback font asset in the event it is null or if already searched.
|
||||
if (k_searchedFontAssets.Contains(id)) continue;
|
||||
|
||||
// Add to list of font assets already searched.
|
||||
k_searchedFontAssets.Add(id);
|
||||
|
||||
temp = SearchForCharacterInternal(temp, unicode, out character);
|
||||
|
||||
if (temp != null)
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static TMP_FontAsset SearchForCharacterInternal(List<TMP_FontAsset> fonts, uint unicode, out TMP_Character character)
|
||||
{
|
||||
character = null;
|
||||
|
||||
if (fonts != null && fonts.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < fonts.Count; i++)
|
||||
{
|
||||
TMP_FontAsset fontAsset = SearchForCharacterInternal(fonts[i], unicode, out character);
|
||||
|
||||
if (fontAsset != null)
|
||||
return fontAsset;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f695b5f9415c40b39ae877eaff41c96e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,360 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class TMP_FontAssetUtilities
|
||||
{
|
||||
private static readonly TMP_FontAssetUtilities s_Instance = new TMP_FontAssetUtilities();
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
static TMP_FontAssetUtilities() { }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the Font Asset Utilities class.
|
||||
/// </summary>
|
||||
public static TMP_FontAssetUtilities instance
|
||||
{
|
||||
get { return s_Instance; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// List containing instance ID of font assets already searched.
|
||||
/// </summary>
|
||||
private static List<int> k_SearchedFontAssets;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the text element (character) for the given unicode value taking into consideration the requested font style and weight.
|
||||
/// Function searches the source font asset, its list of font assets assigned as alternative typefaces and potentially its fallbacks.
|
||||
/// The font asset out parameter contains a reference to the font asset containing the character.
|
||||
/// The typeface type indicates whether the returned font asset is the source font asset, an alternative typeface or fallback font asset.
|
||||
/// </summary>
|
||||
/// <param name="unicode">The unicode value of the requested character</param>
|
||||
/// <param name="sourceFontAsset">The font asset to be searched</param>
|
||||
/// <param name="includeFallbacks">Include the fallback font assets in the search</param>
|
||||
/// <param name="fontStyle">The font style</param>
|
||||
/// <param name="fontWeight">The font weight</param>
|
||||
/// <param name="type">Indicates if the OUT font asset is an alternative typeface or fallback font asset</param>
|
||||
/// <param name="fontAsset">The font asset that contains the requested character</param>
|
||||
/// <returns></returns>
|
||||
public static TMP_Character GetCharacterFromFontAsset(uint unicode, TMP_FontAsset sourceFontAsset, bool includeFallbacks, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface, out TMP_FontAsset fontAsset)
|
||||
{
|
||||
if (includeFallbacks)
|
||||
{
|
||||
if (k_SearchedFontAssets == null)
|
||||
k_SearchedFontAssets = new List<int>();
|
||||
else
|
||||
k_SearchedFontAssets.Clear();
|
||||
}
|
||||
|
||||
return GetCharacterFromFontAsset_Internal(unicode, sourceFontAsset, includeFallbacks, fontStyle, fontWeight, out isAlternativeTypeface, out fontAsset);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Internal function returning the text element character for the given unicode value taking into consideration the font style and weight.
|
||||
/// Function searches the source font asset, list of font assets assigned as alternative typefaces and list of fallback font assets.
|
||||
/// </summary>
|
||||
private static TMP_Character GetCharacterFromFontAsset_Internal(uint unicode, TMP_FontAsset sourceFontAsset, bool includeFallbacks, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface, out TMP_FontAsset fontAsset)
|
||||
{
|
||||
fontAsset = null;
|
||||
isAlternativeTypeface = false;
|
||||
TMP_Character characterData = null;
|
||||
|
||||
#region FONT WEIGHT AND FONT STYLE HANDLING
|
||||
// Determine if a font weight or style is used. If so check if an alternative typeface is assigned for the given weight and / or style.
|
||||
bool isItalic = (fontStyle & FontStyles.Italic) == FontStyles.Italic;
|
||||
|
||||
if (isItalic || fontWeight != FontWeight.Regular)
|
||||
{
|
||||
// Get reference to the font weight pairs of the given font asset.
|
||||
TMP_FontWeightPair[] fontWeights = sourceFontAsset.fontWeightTable;
|
||||
|
||||
int fontWeightIndex = 4;
|
||||
switch (fontWeight)
|
||||
{
|
||||
case FontWeight.Thin:
|
||||
fontWeightIndex = 1;
|
||||
break;
|
||||
case FontWeight.ExtraLight:
|
||||
fontWeightIndex = 2;
|
||||
break;
|
||||
case FontWeight.Light:
|
||||
fontWeightIndex = 3;
|
||||
break;
|
||||
case FontWeight.Regular:
|
||||
fontWeightIndex = 4;
|
||||
break;
|
||||
case FontWeight.Medium:
|
||||
fontWeightIndex = 5;
|
||||
break;
|
||||
case FontWeight.SemiBold:
|
||||
fontWeightIndex = 6;
|
||||
break;
|
||||
case FontWeight.Bold:
|
||||
fontWeightIndex = 7;
|
||||
break;
|
||||
case FontWeight.Heavy:
|
||||
fontWeightIndex = 8;
|
||||
break;
|
||||
case FontWeight.Black:
|
||||
fontWeightIndex = 9;
|
||||
break;
|
||||
}
|
||||
|
||||
fontAsset = isItalic ? fontWeights[fontWeightIndex].italicTypeface : fontWeights[fontWeightIndex].regularTypeface;
|
||||
|
||||
if (fontAsset != null)
|
||||
{
|
||||
if (fontAsset.characterLookupTable.TryGetValue(unicode, out characterData))
|
||||
{
|
||||
isAlternativeTypeface = true;
|
||||
|
||||
return characterData;
|
||||
}
|
||||
else if (fontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic)
|
||||
{
|
||||
if (fontAsset.TryAddCharacterInternal(unicode, out characterData))
|
||||
{
|
||||
isAlternativeTypeface = true;
|
||||
|
||||
return characterData;
|
||||
}
|
||||
|
||||
// Check if the source font file contains the requested character.
|
||||
//if (TryGetCharacterFromFontFile(unicode, fontAsset, out characterData))
|
||||
//{
|
||||
// isAlternativeTypeface = true;
|
||||
|
||||
// return characterData;
|
||||
//}
|
||||
|
||||
// If we find the requested character, we add it to the font asset character table
|
||||
// and return its character data.
|
||||
// We also add this character to the list of characters we will need to add to the font atlas.
|
||||
// We assume the font atlas has room otherwise this font asset should not be marked as dynamic.
|
||||
// Alternatively, we could also add multiple pages of font atlas textures (feature consideration).
|
||||
}
|
||||
|
||||
// At this point, we were not able to find the requested character in the alternative typeface
|
||||
// so we check the source font asset and its potential fallbacks.
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
// Search the source font asset for the requested character.
|
||||
if (sourceFontAsset.characterLookupTable.TryGetValue(unicode, out characterData))
|
||||
{
|
||||
// We were able to locate the requested character in the given font asset.
|
||||
fontAsset = sourceFontAsset;
|
||||
|
||||
return characterData;
|
||||
}
|
||||
else if (sourceFontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic)
|
||||
{
|
||||
if (sourceFontAsset.TryAddCharacterInternal(unicode, out characterData))
|
||||
{
|
||||
fontAsset = sourceFontAsset;
|
||||
|
||||
return characterData;
|
||||
}
|
||||
|
||||
//// Check if the source font file contains the requested character.
|
||||
//if (TryGetCharacterFromFontFile(unicode, sourceFontAsset, out characterData))
|
||||
//{
|
||||
// fontAsset = sourceFontAsset;
|
||||
|
||||
// //fontAsset.AddCharacterToRasterList(unicode);
|
||||
|
||||
// return characterData;
|
||||
//}
|
||||
|
||||
// If we find the requested character, we add it to the font asset character table
|
||||
// and return its character data.
|
||||
// We also add this character to the list of characters we will need to add to the font atlas.
|
||||
// We assume the font atlas has room otherwise this font asset should not be marked as dynamic.
|
||||
// Alternatively, we could also add multiple pages of font atlas textures (feature consideration)
|
||||
}
|
||||
|
||||
// Search fallback font assets if we still don't have a valid character and include fallback is set to true.
|
||||
if (characterData == null && includeFallbacks && sourceFontAsset.fallbackFontAssetTable != null)
|
||||
{
|
||||
// Get reference to the list of fallback font assets.
|
||||
List<TMP_FontAsset> fallbackFontAssets = sourceFontAsset.fallbackFontAssetTable;
|
||||
int fallbackCount = fallbackFontAssets.Count;
|
||||
|
||||
if (fallbackFontAssets != null && fallbackCount > 0)
|
||||
{
|
||||
for (int i = 0; i < fallbackCount && characterData == null; i++)
|
||||
{
|
||||
TMP_FontAsset temp = fallbackFontAssets[i];
|
||||
|
||||
if (temp == null) continue;
|
||||
|
||||
int id = temp.GetInstanceID();
|
||||
|
||||
// Skip over the fallback font asset in the event it is null or if already searched.
|
||||
if (k_SearchedFontAssets.Contains(id))
|
||||
continue;
|
||||
|
||||
// Add to list of font assets already searched.
|
||||
k_SearchedFontAssets.Add(id);
|
||||
|
||||
characterData = GetCharacterFromFontAsset_Internal(unicode, temp, includeFallbacks, fontStyle, fontWeight, out isAlternativeTypeface, out fontAsset);
|
||||
|
||||
if (characterData != null)
|
||||
{
|
||||
return characterData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the text element (character) for the given unicode value taking into consideration the requested font style and weight.
|
||||
/// Function searches the provided list of font assets, the list of font assets assigned as alternative typefaces to them as well as their fallbacks.
|
||||
/// The font asset out parameter contains a reference to the font asset containing the character.
|
||||
/// The typeface type indicates whether the returned font asset is the source font asset, an alternative typeface or fallback font asset.
|
||||
/// </summary>
|
||||
/// <param name="unicode">The unicode value of the requested character</param>
|
||||
/// <param name="fontAssets">The list of font assets to search</param>
|
||||
/// <param name="includeFallbacks">Determines if the fallback of each font assets on the list will be searched</param>
|
||||
/// <param name="fontStyle">The font style</param>
|
||||
/// <param name="fontWeight">The font weight</param>
|
||||
/// <param name="type">Determines if the OUT font asset is an alternative typeface or fallback font asset</param>
|
||||
/// <param name="fontAsset">The font asset that contains the requested character</param>
|
||||
/// <returns></returns>
|
||||
public static TMP_Character GetCharacterFromFontAssets(uint unicode, List<TMP_FontAsset> fontAssets, bool includeFallbacks, FontStyles fontStyle, FontWeight fontWeight, out bool isAlternativeTypeface, out TMP_FontAsset fontAsset)
|
||||
{
|
||||
isAlternativeTypeface = false;
|
||||
|
||||
// Make sure font asset list is valid
|
||||
if (fontAssets == null || fontAssets.Count == 0)
|
||||
{
|
||||
fontAsset = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (includeFallbacks)
|
||||
{
|
||||
if (k_SearchedFontAssets == null)
|
||||
k_SearchedFontAssets = new List<int>();
|
||||
else
|
||||
k_SearchedFontAssets.Clear();
|
||||
}
|
||||
|
||||
int fontAssetCount = fontAssets.Count;
|
||||
|
||||
for (int i = 0; i < fontAssetCount; i++)
|
||||
{
|
||||
if (fontAssets[i] == null) continue;
|
||||
|
||||
TMP_Character characterData = GetCharacterFromFontAsset_Internal(unicode, fontAssets[i], includeFallbacks, fontStyle, fontWeight, out isAlternativeTypeface, out fontAsset);
|
||||
|
||||
if (characterData != null)
|
||||
return characterData;
|
||||
}
|
||||
|
||||
fontAsset = null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// FONT ENGINE & FONT FILE MANAGEMENT - Fields, Properties and Functions
|
||||
// =====================================================================
|
||||
|
||||
private static bool k_IsFontEngineInitialized;
|
||||
|
||||
|
||||
private static bool TryGetCharacterFromFontFile(uint unicode, TMP_FontAsset fontAsset, out TMP_Character character)
|
||||
{
|
||||
character = null;
|
||||
|
||||
// Initialize Font Engine library if not already initialized
|
||||
if (k_IsFontEngineInitialized == false)
|
||||
{
|
||||
FontEngineError error = FontEngine.InitializeFontEngine();
|
||||
|
||||
if (error == 0)
|
||||
k_IsFontEngineInitialized = true;
|
||||
}
|
||||
|
||||
// Load the font face for the given font asset.
|
||||
// TODO: Add manager to keep track of which font faces are currently loaded.
|
||||
FontEngine.LoadFontFace(fontAsset.sourceFontFile, fontAsset.faceInfo.pointSize);
|
||||
|
||||
Glyph glyph = null;
|
||||
uint glyphIndex = FontEngine.GetGlyphIndex(unicode);
|
||||
|
||||
// Check if glyph is already contained in the font asset as the same glyph might be referenced by multiple character.
|
||||
if (fontAsset.glyphLookupTable.TryGetValue(glyphIndex, out glyph))
|
||||
{
|
||||
character = fontAsset.AddCharacter_Internal(unicode, glyph);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GlyphLoadFlags glyphLoadFlags = ((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_HINTED) == GlyphRasterModes.RASTER_MODE_HINTED ? GlyphLoadFlags.LOAD_RENDER : GlyphLoadFlags.LOAD_RENDER | GlyphLoadFlags.LOAD_NO_HINTING;
|
||||
|
||||
if (FontEngine.TryGetGlyphWithUnicodeValue(unicode, glyphLoadFlags, out glyph))
|
||||
{
|
||||
// Add new character to font asset (if needed)
|
||||
character = fontAsset.AddCharacter_Internal(unicode, glyph);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static bool TryGetGlyphFromFontFile(uint glyphIndex, TMP_FontAsset fontAsset, out Glyph glyph)
|
||||
{
|
||||
glyph = null;
|
||||
|
||||
// Initialize Font Engine library if not already initialized
|
||||
if (k_IsFontEngineInitialized == false)
|
||||
{
|
||||
FontEngineError error = FontEngine.InitializeFontEngine();
|
||||
|
||||
if (error == 0)
|
||||
k_IsFontEngineInitialized = true;
|
||||
}
|
||||
|
||||
// Load the font face for the given font asset.
|
||||
// TODO: Add manager to keep track of which font faces are currently loaded.
|
||||
FontEngine.LoadFontFace(fontAsset.sourceFontFile, fontAsset.faceInfo.pointSize);
|
||||
|
||||
GlyphLoadFlags glyphLoadFlags = ((GlyphRasterModes)fontAsset.atlasRenderMode & GlyphRasterModes.RASTER_MODE_HINTED) == GlyphRasterModes.RASTER_MODE_HINTED ? GlyphLoadFlags.LOAD_RENDER : GlyphLoadFlags.LOAD_RENDER | GlyphLoadFlags.LOAD_NO_HINTING;
|
||||
|
||||
if (FontEngine.TryGetGlyphWithIndexValue(glyphIndex, glyphLoadFlags, out glyph))
|
||||
{
|
||||
// Add new glyph to font asset (if needed)
|
||||
//fontAsset.AddGlyph_Internal(glyph);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0a017569bfe174e4890797b4d64cbabc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Table that contains the various font features available for the given font asset.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_FontFeatureTable
|
||||
{
|
||||
/// <summary>
|
||||
/// List that contains the glyph pair adjustment records.
|
||||
/// </summary>
|
||||
internal List<TMP_GlyphPairAdjustmentRecord> glyphPairAdjustmentRecords
|
||||
{
|
||||
get { return m_GlyphPairAdjustmentRecords; }
|
||||
set { m_GlyphPairAdjustmentRecords = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
internal List<TMP_GlyphPairAdjustmentRecord> m_GlyphPairAdjustmentRecords;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal Dictionary<long, TMP_GlyphPairAdjustmentRecord> m_GlyphPairAdjustmentRecordLookupDictionary;
|
||||
|
||||
// =============================================
|
||||
// Constructor(s)
|
||||
// =============================================
|
||||
|
||||
public TMP_FontFeatureTable()
|
||||
{
|
||||
m_GlyphPairAdjustmentRecords = new List<TMP_GlyphPairAdjustmentRecord>();
|
||||
m_GlyphPairAdjustmentRecordLookupDictionary = new Dictionary<long, TMP_GlyphPairAdjustmentRecord>();
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// Utility Functions
|
||||
// =============================================
|
||||
|
||||
/// <summary>
|
||||
/// Sort the glyph pair adjustment records by glyph index.
|
||||
/// </summary>
|
||||
public void SortGlyphPairAdjustmentRecords()
|
||||
{
|
||||
// Sort List of Kerning Info
|
||||
if (m_GlyphPairAdjustmentRecords.Count > 0)
|
||||
m_GlyphPairAdjustmentRecords = m_GlyphPairAdjustmentRecords.OrderBy(s => s.firstAdjustmentRecord.glyphIndex).ThenBy(s => s.secondAdjustmentRecord.glyphIndex).ToList();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5ea9f573d4b800a49b9d83a1f61c0a88
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,223 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public enum FontFeatureLookupFlags
|
||||
{
|
||||
IgnoreLigatures = 0x004,
|
||||
IgnoreSpacingAdjustments = 0x100,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The values used to adjust the position of a glyph or set of glyphs.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TMP_GlyphValueRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// The positional adjustment affecting the horizontal bearing X of the glyph.
|
||||
/// </summary>
|
||||
public float xPlacement { get { return m_XPlacement; } set { m_XPlacement = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment affecting the horizontal bearing Y of the glyph.
|
||||
/// </summary>
|
||||
public float yPlacement { get { return m_YPlacement; } set { m_YPlacement = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment affecting the horizontal advance of the glyph.
|
||||
/// </summary>
|
||||
public float xAdvance { get { return m_XAdvance; } set { m_XAdvance = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment affecting the vertical advance of the glyph.
|
||||
/// </summary>
|
||||
public float yAdvance { get { return m_YAdvance; } set { m_YAdvance = value; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
private float m_XPlacement;
|
||||
|
||||
[SerializeField]
|
||||
private float m_YPlacement;
|
||||
|
||||
[SerializeField]
|
||||
private float m_XAdvance;
|
||||
|
||||
[SerializeField]
|
||||
private float m_YAdvance;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="xPlacement">The positional adjustment affecting the horizontal bearing X of the glyph.</param>
|
||||
/// <param name="yPlacement">The positional adjustment affecting the horizontal bearing Y of the glyph.</param>
|
||||
/// <param name="xAdvance">The positional adjustment affecting the horizontal advance of the glyph.</param>
|
||||
/// <param name="yAdvance">The positional adjustment affecting the vertical advance of the glyph.</param>
|
||||
public TMP_GlyphValueRecord(float xPlacement, float yPlacement, float xAdvance, float yAdvance)
|
||||
{
|
||||
m_XPlacement = xPlacement;
|
||||
m_YPlacement = yPlacement;
|
||||
m_XAdvance = xAdvance;
|
||||
m_YAdvance = yAdvance;
|
||||
}
|
||||
|
||||
internal TMP_GlyphValueRecord(GlyphValueRecord_Legacy valueRecord)
|
||||
{
|
||||
m_XPlacement = valueRecord.xPlacement;
|
||||
m_YPlacement = valueRecord.yPlacement;
|
||||
m_XAdvance = valueRecord.xAdvance;
|
||||
m_YAdvance = valueRecord.yAdvance;
|
||||
}
|
||||
|
||||
internal TMP_GlyphValueRecord(GlyphValueRecord valueRecord)
|
||||
{
|
||||
m_XPlacement = valueRecord.xPlacement;
|
||||
m_YPlacement = valueRecord.yPlacement;
|
||||
m_XAdvance = valueRecord.xAdvance;
|
||||
m_YAdvance = valueRecord.yAdvance;
|
||||
}
|
||||
|
||||
public static TMP_GlyphValueRecord operator +(TMP_GlyphValueRecord a, TMP_GlyphValueRecord b)
|
||||
{
|
||||
TMP_GlyphValueRecord c;
|
||||
c.m_XPlacement = a.xPlacement + b.xPlacement;
|
||||
c.m_YPlacement = a.yPlacement + b.yPlacement;
|
||||
c.m_XAdvance = a.xAdvance + b.xAdvance;
|
||||
c.m_YAdvance = a.yAdvance + b.yAdvance;
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment values of a glyph.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TMP_GlyphAdjustmentRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// The index of the glyph in the source font file.
|
||||
/// </summary>
|
||||
public uint glyphIndex { get { return m_GlyphIndex; } set { m_GlyphIndex = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The GlyphValueRecord contains the positional adjustments of the glyph.
|
||||
/// </summary>
|
||||
public TMP_GlyphValueRecord glyphValueRecord { get { return m_GlyphValueRecord; } set { m_GlyphValueRecord = value; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
private uint m_GlyphIndex;
|
||||
|
||||
[SerializeField]
|
||||
private TMP_GlyphValueRecord m_GlyphValueRecord;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="glyphIndex">The index of the glyph in the source font file.</param>
|
||||
/// <param name="glyphValueRecord">The GlyphValueRecord contains the positional adjustments of the glyph.</param>
|
||||
public TMP_GlyphAdjustmentRecord(uint glyphIndex, TMP_GlyphValueRecord glyphValueRecord)
|
||||
{
|
||||
m_GlyphIndex = glyphIndex;
|
||||
m_GlyphValueRecord = glyphValueRecord;
|
||||
}
|
||||
|
||||
internal TMP_GlyphAdjustmentRecord(GlyphAdjustmentRecord adjustmentRecord)
|
||||
{
|
||||
m_GlyphIndex = adjustmentRecord.glyphIndex;
|
||||
m_GlyphValueRecord = new TMP_GlyphValueRecord(adjustmentRecord.glyphValueRecord);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The positional adjustment values for a pair of glyphs.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_GlyphPairAdjustmentRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the positional adjustment values for the first glyph.
|
||||
/// </summary>
|
||||
public TMP_GlyphAdjustmentRecord firstAdjustmentRecord { get { return m_FirstAdjustmentRecord; } set { m_FirstAdjustmentRecord = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the positional adjustment values for the second glyph.
|
||||
/// </summary>
|
||||
public TMP_GlyphAdjustmentRecord secondAdjustmentRecord { get { return m_SecondAdjustmentRecord; } set { m_SecondAdjustmentRecord = value; } }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public FontFeatureLookupFlags featureLookupFlags { get { return m_FeatureLookupFlags; } set { m_FeatureLookupFlags = value; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
private TMP_GlyphAdjustmentRecord m_FirstAdjustmentRecord;
|
||||
|
||||
[SerializeField]
|
||||
private TMP_GlyphAdjustmentRecord m_SecondAdjustmentRecord;
|
||||
|
||||
[SerializeField]
|
||||
private FontFeatureLookupFlags m_FeatureLookupFlags;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="firstAdjustmentRecord">First glyph adjustment record.</param>
|
||||
/// <param name="secondAdjustmentRecord">Second glyph adjustment record.</param>
|
||||
public TMP_GlyphPairAdjustmentRecord(TMP_GlyphAdjustmentRecord firstAdjustmentRecord, TMP_GlyphAdjustmentRecord secondAdjustmentRecord)
|
||||
{
|
||||
m_FirstAdjustmentRecord = firstAdjustmentRecord;
|
||||
m_SecondAdjustmentRecord = secondAdjustmentRecord;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal constructor
|
||||
/// </summary>
|
||||
/// <param name="firstAdjustmentRecord"></param>
|
||||
/// <param name="secondAdjustmentRecord"></param>
|
||||
internal TMP_GlyphPairAdjustmentRecord(GlyphPairAdjustmentRecord glyphPairAdjustmentRecord)
|
||||
{
|
||||
m_FirstAdjustmentRecord = new TMP_GlyphAdjustmentRecord(glyphPairAdjustmentRecord.firstAdjustmentRecord);
|
||||
m_SecondAdjustmentRecord = new TMP_GlyphAdjustmentRecord(glyphPairAdjustmentRecord.secondAdjustmentRecord);
|
||||
}
|
||||
}
|
||||
|
||||
public struct GlyphPairKey
|
||||
{
|
||||
public uint firstGlyphIndex;
|
||||
public uint secondGlyphIndex;
|
||||
public long key;
|
||||
|
||||
public GlyphPairKey(uint firstGlyphIndex, uint secondGlyphIndex)
|
||||
{
|
||||
this.firstGlyphIndex = firstGlyphIndex;
|
||||
this.secondGlyphIndex = secondGlyphIndex;
|
||||
key = (long)secondGlyphIndex << 32 | firstGlyphIndex;
|
||||
}
|
||||
|
||||
internal GlyphPairKey(TMP_GlyphPairAdjustmentRecord record)
|
||||
{
|
||||
firstGlyphIndex = record.firstAdjustmentRecord.glyphIndex;
|
||||
secondGlyphIndex = record.secondAdjustmentRecord.glyphIndex;
|
||||
key = (long)secondGlyphIndex << 32 | firstGlyphIndex;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 27df3b12f30d0b74a9b10a3968c402ff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2da0c512f12947e489f739169773d7ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 3ee40aa79cd242a5b53b0b0ca4f13f0f, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom text input validator where user can implement their own custom character validation.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public abstract class TMP_InputValidator : ScriptableObject
|
||||
{
|
||||
public abstract char Validate(ref string text, ref int pos, char ch);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 79ff392d1bde4ad78a3836a4a480392d
|
||||
timeCreated: 1473021069
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,52 @@
|
|||
namespace TMPro
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Structure which contains information about the individual lines of text.
|
||||
/// </summary>
|
||||
public struct TMP_LineInfo
|
||||
{
|
||||
internal int controlCharacterCount;
|
||||
|
||||
public int characterCount;
|
||||
public int visibleCharacterCount;
|
||||
public int spaceCount;
|
||||
public int wordCount;
|
||||
public int firstCharacterIndex;
|
||||
public int firstVisibleCharacterIndex;
|
||||
public int lastCharacterIndex;
|
||||
public int lastVisibleCharacterIndex;
|
||||
|
||||
public float length;
|
||||
public float lineHeight;
|
||||
public float ascender;
|
||||
public float baseline;
|
||||
public float descender;
|
||||
public float maxAdvance;
|
||||
|
||||
public float width;
|
||||
public float marginLeft;
|
||||
public float marginRight;
|
||||
|
||||
public TextAlignmentOptions alignment;
|
||||
public Extents lineExtents;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the current line of text.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
//public string GetLineText()
|
||||
//{
|
||||
// string word = string.Empty;
|
||||
// TMP_CharacterInfo[] charInfo = textComponent.textInfo.characterInfo;
|
||||
|
||||
// for (int i = firstCharacterIndex; i < lastCharacterIndex + 1; i++)
|
||||
// {
|
||||
// word += charInfo[i].character;
|
||||
// }
|
||||
|
||||
// return word;
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b6e75d7f429a4e7e9e1ffb4f85cff49f
|
||||
timeCreated: 1464310403
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
internal static class TMP_ListPool<T>
|
||||
{
|
||||
// Object pool to avoid allocations.
|
||||
private static readonly TMP_ObjectPool<List<T>> s_ListPool = new TMP_ObjectPool<List<T>>(null, l => l.Clear());
|
||||
|
||||
public static List<T> Get()
|
||||
{
|
||||
return s_ListPool.Get();
|
||||
}
|
||||
|
||||
public static void Release(List<T> toRelease)
|
||||
{
|
||||
s_ListPool.Release(toRelease);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 28375447bcea455c9b51a6650b10c9d7
|
||||
timeCreated: 1458521386
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,633 @@
|
|||
//#define TMP_DEBUG_MODE
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public static class TMP_MaterialManager
|
||||
{
|
||||
private static List<MaskingMaterial> m_materialList = new List<MaskingMaterial>();
|
||||
|
||||
private static Dictionary<long, FallbackMaterial> m_fallbackMaterials = new Dictionary<long, FallbackMaterial>();
|
||||
private static Dictionary<int, long> m_fallbackMaterialLookup = new Dictionary<int, long>();
|
||||
private static List<FallbackMaterial> m_fallbackCleanupList = new List<FallbackMaterial>();
|
||||
|
||||
private static bool isFallbackListDirty;
|
||||
|
||||
static TMP_MaterialManager()
|
||||
{
|
||||
Camera.onPreRender += new Camera.CameraCallback(OnPreRender);
|
||||
Canvas.willRenderCanvases += new Canvas.WillRenderCanvases(OnPreRenderCanvas);
|
||||
}
|
||||
|
||||
|
||||
static void OnPreRender(Camera cam)
|
||||
{
|
||||
if (isFallbackListDirty)
|
||||
{
|
||||
//Debug.Log("1 - Cleaning up Fallback Materials.");
|
||||
CleanupFallbackMaterials();
|
||||
isFallbackListDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void OnPreRenderCanvas()
|
||||
{
|
||||
if (isFallbackListDirty)
|
||||
{
|
||||
//Debug.Log("2 - Cleaning up Fallback Materials.");
|
||||
CleanupFallbackMaterials();
|
||||
isFallbackListDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a Masking Material Instance for the given ID
|
||||
/// </summary>
|
||||
/// <param name="baseMaterial"></param>
|
||||
/// <param name="stencilID"></param>
|
||||
/// <returns></returns>
|
||||
public static Material GetStencilMaterial(Material baseMaterial, int stencilID)
|
||||
{
|
||||
// Check if Material supports masking
|
||||
if (!baseMaterial.HasProperty(ShaderUtilities.ID_StencilID))
|
||||
{
|
||||
Debug.LogWarning("Selected Shader does not support Stencil Masking. Please select the Distance Field or Mobile Distance Field Shader.");
|
||||
return baseMaterial;
|
||||
}
|
||||
|
||||
int baseMaterialID = baseMaterial.GetInstanceID();
|
||||
|
||||
// If baseMaterial already has a corresponding masking material, return it.
|
||||
for (int i = 0; i < m_materialList.Count; i++)
|
||||
{
|
||||
if (m_materialList[i].baseMaterial.GetInstanceID() == baseMaterialID && m_materialList[i].stencilID == stencilID)
|
||||
{
|
||||
m_materialList[i].count += 1;
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
|
||||
return m_materialList[i].stencilMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
// No matching masking material found. Create and return a new one.
|
||||
|
||||
Material stencilMaterial;
|
||||
|
||||
//Create new Masking Material Instance for this Base Material
|
||||
stencilMaterial = new Material(baseMaterial);
|
||||
stencilMaterial.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
stencilMaterial.name += " Masking ID:" + stencilID;
|
||||
#endif
|
||||
|
||||
stencilMaterial.shaderKeywords = baseMaterial.shaderKeywords;
|
||||
|
||||
// Set Stencil Properties
|
||||
ShaderUtilities.GetShaderPropertyIDs();
|
||||
stencilMaterial.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
|
||||
//stencilMaterial.SetFloat(ShaderUtilities.ID_StencilOp, 0);
|
||||
stencilMaterial.SetFloat(ShaderUtilities.ID_StencilComp, 4);
|
||||
//stencilMaterial.SetFloat(ShaderUtilities.ID_StencilReadMask, stencilID);
|
||||
//stencilMaterial.SetFloat(ShaderUtilities.ID_StencilWriteMask, 0);
|
||||
|
||||
MaskingMaterial temp = new MaskingMaterial();
|
||||
temp.baseMaterial = baseMaterial;
|
||||
temp.stencilMaterial = stencilMaterial;
|
||||
temp.stencilID = stencilID;
|
||||
temp.count = 1;
|
||||
|
||||
m_materialList.Add(temp);
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
|
||||
return stencilMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to release the stencil material.
|
||||
/// </summary>
|
||||
/// <param name="stencilMaterial"></param>
|
||||
public static void ReleaseStencilMaterial(Material stencilMaterial)
|
||||
{
|
||||
int stencilMaterialID = stencilMaterial.GetInstanceID();
|
||||
|
||||
for (int i = 0; i < m_materialList.Count; i++)
|
||||
{
|
||||
if (m_materialList[i].stencilMaterial.GetInstanceID() == stencilMaterialID)
|
||||
{
|
||||
if (m_materialList[i].count > 1)
|
||||
m_materialList[i].count -= 1;
|
||||
else
|
||||
{
|
||||
Object.DestroyImmediate(m_materialList[i].stencilMaterial);
|
||||
m_materialList.RemoveAt(i);
|
||||
stencilMaterial = null;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Function which returns the base material associated with a Masking Material
|
||||
public static Material GetBaseMaterial(Material stencilMaterial)
|
||||
{
|
||||
// Check if maskingMaterial already has a base material associated with it.
|
||||
int index = m_materialList.FindIndex(item => item.stencilMaterial == stencilMaterial);
|
||||
|
||||
if (index == -1)
|
||||
return null;
|
||||
else
|
||||
return m_materialList[index].baseMaterial;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to set the Material Stencil ID
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <param name="stencilID"></param>
|
||||
/// <returns></returns>
|
||||
public static Material SetStencil(Material material, int stencilID)
|
||||
{
|
||||
material.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
|
||||
|
||||
if (stencilID == 0)
|
||||
material.SetFloat(ShaderUtilities.ID_StencilComp, 8);
|
||||
else
|
||||
material.SetFloat(ShaderUtilities.ID_StencilComp, 4);
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
|
||||
public static void AddMaskingMaterial(Material baseMaterial, Material stencilMaterial, int stencilID)
|
||||
{
|
||||
// Check if maskingMaterial already has a base material associated with it.
|
||||
int index = m_materialList.FindIndex(item => item.stencilMaterial == stencilMaterial);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
MaskingMaterial temp = new MaskingMaterial();
|
||||
temp.baseMaterial = baseMaterial;
|
||||
temp.stencilMaterial = stencilMaterial;
|
||||
temp.stencilID = stencilID;
|
||||
temp.count = 1;
|
||||
|
||||
m_materialList.Add(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
stencilMaterial = m_materialList[index].stencilMaterial;
|
||||
m_materialList[index].count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void RemoveStencilMaterial(Material stencilMaterial)
|
||||
{
|
||||
// Check if maskingMaterial is already on the list.
|
||||
int index = m_materialList.FindIndex(item => item.stencilMaterial == stencilMaterial);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
m_materialList.RemoveAt(index);
|
||||
}
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void ReleaseBaseMaterial(Material baseMaterial)
|
||||
{
|
||||
// Check if baseMaterial already has a masking material associated with it.
|
||||
int index = m_materialList.FindIndex(item => item.baseMaterial == baseMaterial);
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
Debug.Log("No Masking Material exists for " + baseMaterial.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_materialList[index].count > 1)
|
||||
{
|
||||
m_materialList[index].count -= 1;
|
||||
Debug.Log("Removed (1) reference to " + m_materialList[index].stencilMaterial.name + ". There are " + m_materialList[index].count + " references left.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Removed last reference to " + m_materialList[index].stencilMaterial.name + " with ID " + m_materialList[index].stencilMaterial.GetInstanceID());
|
||||
Object.DestroyImmediate(m_materialList[index].stencilMaterial);
|
||||
m_materialList.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListMaterials();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public static void ClearMaterials()
|
||||
{
|
||||
if (m_materialList.Count == 0)
|
||||
{
|
||||
Debug.Log("Material List has already been cleared.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_materialList.Count; i++)
|
||||
{
|
||||
//Material baseMaterial = m_materialList[i].baseMaterial;
|
||||
Material stencilMaterial = m_materialList[i].stencilMaterial;
|
||||
|
||||
Object.DestroyImmediate(stencilMaterial);
|
||||
m_materialList.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to get the Stencil ID
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetStencilID(GameObject obj)
|
||||
{
|
||||
// Implementation is almost copied from Unity UI
|
||||
|
||||
var count = 0;
|
||||
|
||||
var transform = obj.transform;
|
||||
var stopAfter = FindRootSortOverrideCanvas(transform);
|
||||
if (transform == stopAfter)
|
||||
return count;
|
||||
|
||||
var t = transform.parent;
|
||||
var components = TMP_ListPool<Mask>.Get();
|
||||
while (t != null)
|
||||
{
|
||||
t.GetComponents<Mask>(components);
|
||||
for (var i = 0; i < components.Count; ++i)
|
||||
{
|
||||
var mask = components[i];
|
||||
if (mask != null && mask.MaskEnabled() && mask.graphic.IsActive())
|
||||
{
|
||||
++count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t == stopAfter)
|
||||
break;
|
||||
|
||||
t = t.parent;
|
||||
}
|
||||
TMP_ListPool<Mask>.Release(components);
|
||||
|
||||
return Mathf.Min((1 << count) - 1, 255);
|
||||
}
|
||||
|
||||
|
||||
public static Material GetMaterialForRendering(MaskableGraphic graphic, Material baseMaterial)
|
||||
{
|
||||
if (baseMaterial == null)
|
||||
return null;
|
||||
|
||||
var modifiers = TMP_ListPool<IMaterialModifier>.Get();
|
||||
graphic.GetComponents(modifiers);
|
||||
|
||||
var result = baseMaterial;
|
||||
for (int i = 0; i < modifiers.Count; i++)
|
||||
result = modifiers[i].GetModifiedMaterial(result);
|
||||
|
||||
TMP_ListPool<IMaterialModifier>.Release(modifiers);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Transform FindRootSortOverrideCanvas(Transform start)
|
||||
{
|
||||
// Implementation is copied from Unity UI
|
||||
|
||||
var canvasList = TMP_ListPool<Canvas>.Get();
|
||||
start.GetComponentsInParent(false, canvasList);
|
||||
Canvas canvas = null;
|
||||
|
||||
for (int i = 0; i < canvasList.Count; ++i)
|
||||
{
|
||||
canvas = canvasList[i];
|
||||
|
||||
// We found the canvas we want to use break
|
||||
if (canvas.overrideSorting)
|
||||
break;
|
||||
}
|
||||
TMP_ListPool<Canvas>.Release(canvasList);
|
||||
|
||||
return canvas != null ? canvas.transform : null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This function returns a material instance using the material properties of a previous material but using the font atlas texture of the new font asset.
|
||||
/// </summary>
|
||||
/// <param name="sourceMaterial">The material containing the source material properties to be copied to the new material.</param>
|
||||
/// <param name="targetMaterial">The font atlas texture that should be assigned to the new material.</param>
|
||||
/// <returns></returns>
|
||||
public static Material GetFallbackMaterial (Material sourceMaterial, Material targetMaterial)
|
||||
{
|
||||
int sourceID = sourceMaterial.GetInstanceID();
|
||||
Texture tex = targetMaterial.GetTexture(ShaderUtilities.ID_MainTex);
|
||||
int texID = tex.GetInstanceID();
|
||||
long key = (long)sourceID << 32 | (long)(uint)texID;
|
||||
FallbackMaterial fallback;
|
||||
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
//Debug.Log("Material [" + fallback.fallbackMaterial.name + "] already exists.");
|
||||
return fallback.fallbackMaterial;
|
||||
}
|
||||
|
||||
// Create new material from the source material and copy properties if using distance field shaders.
|
||||
Material fallbackMaterial = null;
|
||||
if (sourceMaterial.HasProperty(ShaderUtilities.ID_GradientScale) && targetMaterial.HasProperty(ShaderUtilities.ID_GradientScale))
|
||||
{
|
||||
fallbackMaterial = new Material(sourceMaterial);
|
||||
fallbackMaterial.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
fallbackMaterial.name += " + " + tex.name;
|
||||
//Debug.Log("Creating new fallback material for " + fallbackMaterial.name);
|
||||
#endif
|
||||
|
||||
fallbackMaterial.SetTexture(ShaderUtilities.ID_MainTex, tex);
|
||||
// Retain material properties unique to target material.
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_GradientScale, targetMaterial.GetFloat(ShaderUtilities.ID_GradientScale));
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_TextureWidth, targetMaterial.GetFloat(ShaderUtilities.ID_TextureWidth));
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_TextureHeight, targetMaterial.GetFloat(ShaderUtilities.ID_TextureHeight));
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_WeightNormal, targetMaterial.GetFloat(ShaderUtilities.ID_WeightNormal));
|
||||
fallbackMaterial.SetFloat(ShaderUtilities.ID_WeightBold, targetMaterial.GetFloat(ShaderUtilities.ID_WeightBold));
|
||||
}
|
||||
else
|
||||
{
|
||||
fallbackMaterial = new Material(targetMaterial);
|
||||
}
|
||||
|
||||
fallback = new FallbackMaterial();
|
||||
fallback.baseID = sourceID;
|
||||
fallback.baseMaterial = sourceMaterial;
|
||||
fallback.fallbackID = key;
|
||||
fallback.fallbackMaterial = fallbackMaterial;
|
||||
fallback.count = 0;
|
||||
|
||||
m_fallbackMaterials.Add(key, fallback);
|
||||
m_fallbackMaterialLookup.Add(fallbackMaterial.GetInstanceID(), key);
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListFallbackMaterials();
|
||||
#endif
|
||||
|
||||
return fallbackMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="targetMaterial"></param>
|
||||
public static void AddFallbackMaterialReference(Material targetMaterial)
|
||||
{
|
||||
if (targetMaterial == null) return;
|
||||
|
||||
int sourceID = targetMaterial.GetInstanceID();
|
||||
long key;
|
||||
FallbackMaterial fallback;
|
||||
|
||||
// Lookup key to retrieve
|
||||
if (m_fallbackMaterialLookup.TryGetValue(sourceID, out key))
|
||||
{
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
//Debug.Log("Adding Fallback material " + fallback.fallbackMaterial.name + " with reference count of " + (fallback.count + 1));
|
||||
fallback.count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="targetMaterial"></param>
|
||||
public static void RemoveFallbackMaterialReference(Material targetMaterial)
|
||||
{
|
||||
if (targetMaterial == null) return;
|
||||
|
||||
int sourceID = targetMaterial.GetInstanceID();
|
||||
long key;
|
||||
FallbackMaterial fallback;
|
||||
|
||||
// Lookup key to retrieve
|
||||
if (m_fallbackMaterialLookup.TryGetValue(sourceID, out key))
|
||||
{
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
fallback.count -= 1;
|
||||
|
||||
if (fallback.count < 1)
|
||||
m_fallbackCleanupList.Add(fallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void CleanupFallbackMaterials()
|
||||
{
|
||||
// Return if the list is empty.
|
||||
if (m_fallbackCleanupList.Count == 0) return;
|
||||
|
||||
for (int i = 0; i < m_fallbackCleanupList.Count; i++)
|
||||
{
|
||||
FallbackMaterial fallback = m_fallbackCleanupList[i];
|
||||
|
||||
if (fallback.count < 1)
|
||||
{
|
||||
//Debug.Log("Cleaning up " + fallback.fallbackMaterial.name);
|
||||
|
||||
Material mat = fallback.fallbackMaterial;
|
||||
m_fallbackMaterials.Remove(fallback.fallbackID);
|
||||
m_fallbackMaterialLookup.Remove(mat.GetInstanceID());
|
||||
Object.DestroyImmediate(mat);
|
||||
mat = null;
|
||||
}
|
||||
}
|
||||
|
||||
m_fallbackCleanupList.Clear();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to release the fallback material.
|
||||
/// </summary>
|
||||
/// <param name="fallackMaterial"></param>
|
||||
public static void ReleaseFallbackMaterial(Material fallackMaterial)
|
||||
{
|
||||
if (fallackMaterial == null) return;
|
||||
|
||||
int materialID = fallackMaterial.GetInstanceID();
|
||||
long key;
|
||||
FallbackMaterial fallback;
|
||||
|
||||
if (m_fallbackMaterialLookup.TryGetValue(materialID, out key))
|
||||
{
|
||||
if (m_fallbackMaterials.TryGetValue(key, out fallback))
|
||||
{
|
||||
//Debug.Log("Releasing Fallback material " + fallback.fallbackMaterial.name + " with remaining reference count of " + (fallback.count - 1));
|
||||
|
||||
fallback.count -= 1;
|
||||
|
||||
if (fallback.count < 1)
|
||||
m_fallbackCleanupList.Add(fallback);
|
||||
}
|
||||
}
|
||||
|
||||
isFallbackListDirty = true;
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
ListFallbackMaterials();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
private class FallbackMaterial
|
||||
{
|
||||
public int baseID;
|
||||
public Material baseMaterial;
|
||||
public long fallbackID;
|
||||
public Material fallbackMaterial;
|
||||
public int count;
|
||||
}
|
||||
|
||||
|
||||
private class MaskingMaterial
|
||||
{
|
||||
public Material baseMaterial;
|
||||
public Material stencilMaterial;
|
||||
public int count;
|
||||
public int stencilID;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to copy the properties of a source material preset to another while preserving the unique font asset properties of the destination material.
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="destination"></param>
|
||||
public static void CopyMaterialPresetProperties(Material source, Material destination)
|
||||
{
|
||||
if (!source.HasProperty(ShaderUtilities.ID_GradientScale) || !destination.HasProperty(ShaderUtilities.ID_GradientScale))
|
||||
return;
|
||||
|
||||
// Save unique material properties
|
||||
Texture dst_texture = destination.GetTexture(ShaderUtilities.ID_MainTex);
|
||||
float dst_gradientScale = destination.GetFloat(ShaderUtilities.ID_GradientScale);
|
||||
float dst_texWidth = destination.GetFloat(ShaderUtilities.ID_TextureWidth);
|
||||
float dst_texHeight = destination.GetFloat(ShaderUtilities.ID_TextureHeight);
|
||||
float dst_weightNormal = destination.GetFloat(ShaderUtilities.ID_WeightNormal);
|
||||
float dst_weightBold = destination.GetFloat(ShaderUtilities.ID_WeightBold);
|
||||
|
||||
// Copy all material properties
|
||||
destination.CopyPropertiesFromMaterial(source);
|
||||
|
||||
// Copy shader keywords
|
||||
destination.shaderKeywords = source.shaderKeywords;
|
||||
|
||||
// Restore unique material properties
|
||||
destination.SetTexture(ShaderUtilities.ID_MainTex, dst_texture);
|
||||
destination.SetFloat(ShaderUtilities.ID_GradientScale, dst_gradientScale);
|
||||
destination.SetFloat(ShaderUtilities.ID_TextureWidth, dst_texWidth);
|
||||
destination.SetFloat(ShaderUtilities.ID_TextureHeight, dst_texHeight);
|
||||
destination.SetFloat(ShaderUtilities.ID_WeightNormal, dst_weightNormal);
|
||||
destination.SetFloat(ShaderUtilities.ID_WeightBold, dst_weightBold);
|
||||
}
|
||||
|
||||
|
||||
#if TMP_DEBUG_MODE
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void ListMaterials()
|
||||
{
|
||||
|
||||
if (m_materialList.Count() == 0)
|
||||
{
|
||||
Debug.Log("Material List is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Log("List contains " + m_materialList.Count() + " items.");
|
||||
|
||||
for (int i = 0; i < m_materialList.Count(); i++)
|
||||
{
|
||||
Material baseMaterial = m_materialList[i].baseMaterial;
|
||||
Material stencilMaterial = m_materialList[i].stencilMaterial;
|
||||
|
||||
Debug.Log("Item #" + (i + 1) + " - Base Material is [" + baseMaterial.name + "] with ID " + baseMaterial.GetInstanceID() + " is associated with [" + (stencilMaterial != null ? stencilMaterial.name : "Null") + "] Stencil ID " + m_materialList[i].stencilID + " with ID " + (stencilMaterial != null ? stencilMaterial.GetInstanceID() : 0) + " and is referenced " + m_materialList[i].count + " time(s).");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void ListFallbackMaterials()
|
||||
{
|
||||
|
||||
if (m_fallbackMaterialList.Count() == 0)
|
||||
{
|
||||
Debug.Log("Material List is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log("List contains " + m_fallbackMaterialList.Count() + " items.");
|
||||
|
||||
for (int i = 0; i < m_fallbackMaterialList.Count(); i++)
|
||||
{
|
||||
Material baseMaterial = m_fallbackMaterialList[i].baseMaterial;
|
||||
Material fallbackMaterial = m_fallbackMaterialList[i].fallbackMaterial;
|
||||
|
||||
Debug.Log("Item #" + (i + 1) + " - Base Material is [" + baseMaterial.name + "] with ID " + baseMaterial.GetInstanceID() + " is associated with [" + (fallbackMaterial != null ? fallbackMaterial.name : "Null") + "] with ID " + (fallbackMaterial != null ? fallbackMaterial.GetInstanceID() : 0) + " and is referenced " + m_fallbackMaterialList[i].count + " time(s).");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6d9df2bc198c417db00037803568139c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,668 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public enum VertexSortingOrder { Normal, Reverse };
|
||||
|
||||
/// <summary>
|
||||
/// Structure which contains the vertex attributes (geometry) of the text object.
|
||||
/// </summary>
|
||||
public struct TMP_MeshInfo
|
||||
{
|
||||
private static readonly Color32 s_DefaultColor = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
|
||||
private static readonly Vector3 s_DefaultNormal = new Vector3(0.0f, 0.0f, -1f);
|
||||
private static readonly Vector4 s_DefaultTangent = new Vector4(-1f, 0.0f, 0.0f, 1f);
|
||||
private static readonly Bounds s_DefaultBounds = new Bounds();
|
||||
|
||||
public Mesh mesh;
|
||||
public int vertexCount;
|
||||
|
||||
public Vector3[] vertices;
|
||||
public Vector3[] normals;
|
||||
public Vector4[] tangents;
|
||||
|
||||
public Vector2[] uvs0;
|
||||
public Vector2[] uvs2;
|
||||
//public Vector2[] uvs4;
|
||||
public Color32[] colors32;
|
||||
public int[] triangles;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to pre-allocate vertex attributes for a mesh of size X.
|
||||
/// </summary>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="size"></param>
|
||||
public TMP_MeshInfo(Mesh mesh, int size)
|
||||
{
|
||||
// Reference to the TMP Text Component.
|
||||
//this.textComponent = null;
|
||||
|
||||
// Clear existing mesh data
|
||||
if (mesh == null)
|
||||
mesh = new Mesh();
|
||||
else
|
||||
mesh.Clear();
|
||||
|
||||
this.mesh = mesh;
|
||||
|
||||
// Limit the mesh to less than 65535 vertices which is the limit for Unity's Mesh.
|
||||
size = Mathf.Min(size, 16383);
|
||||
|
||||
int sizeX4 = size * 4;
|
||||
int sizeX6 = size * 6;
|
||||
|
||||
this.vertexCount = 0;
|
||||
|
||||
this.vertices = new Vector3[sizeX4];
|
||||
this.uvs0 = new Vector2[sizeX4];
|
||||
this.uvs2 = new Vector2[sizeX4];
|
||||
//this.uvs4 = new Vector2[sizeX4]; // SDF scale data
|
||||
this.colors32 = new Color32[sizeX4];
|
||||
|
||||
this.normals = new Vector3[sizeX4];
|
||||
this.tangents = new Vector4[sizeX4];
|
||||
|
||||
this.triangles = new int[sizeX6];
|
||||
|
||||
int index_X6 = 0;
|
||||
int index_X4 = 0;
|
||||
while (index_X4 / 4 < size)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
this.vertices[index_X4 + i] = Vector3.zero;
|
||||
this.uvs0[index_X4 + i] = Vector2.zero;
|
||||
this.uvs2[index_X4 + i] = Vector2.zero;
|
||||
//this.uvs4[index_X4 + i] = Vector2.zero;
|
||||
this.colors32[index_X4 + i] = s_DefaultColor;
|
||||
this.normals[index_X4 + i] = s_DefaultNormal;
|
||||
this.tangents[index_X4 + i] = s_DefaultTangent;
|
||||
}
|
||||
|
||||
this.triangles[index_X6 + 0] = index_X4 + 0;
|
||||
this.triangles[index_X6 + 1] = index_X4 + 1;
|
||||
this.triangles[index_X6 + 2] = index_X4 + 2;
|
||||
this.triangles[index_X6 + 3] = index_X4 + 2;
|
||||
this.triangles[index_X6 + 4] = index_X4 + 3;
|
||||
this.triangles[index_X6 + 5] = index_X4 + 0;
|
||||
|
||||
index_X4 += 4;
|
||||
index_X6 += 6;
|
||||
}
|
||||
|
||||
// Pre-assign base vertex attributes.
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
this.mesh.triangles = this.triangles;
|
||||
this.mesh.bounds = s_DefaultBounds;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to pre-allocate vertex attributes for a mesh of size X.
|
||||
/// </summary>
|
||||
/// <param name="mesh"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="isVolumetric"></param>
|
||||
public TMP_MeshInfo(Mesh mesh, int size, bool isVolumetric)
|
||||
{
|
||||
// Reference to the TMP Text Component.
|
||||
//this.textComponent = null;
|
||||
|
||||
// Clear existing mesh data
|
||||
if (mesh == null)
|
||||
mesh = new Mesh();
|
||||
else
|
||||
mesh.Clear();
|
||||
|
||||
this.mesh = mesh;
|
||||
|
||||
int s0 = !isVolumetric ? 4 : 8;
|
||||
int s1 = !isVolumetric ? 6 : 36;
|
||||
|
||||
// Limit the mesh to less than 65535 vertices which is the limit for Unity's Mesh.
|
||||
size = Mathf.Min(size, 65532 / s0);
|
||||
|
||||
int size_x_s0 = size * s0;
|
||||
int size_x_s1 = size * s1;
|
||||
|
||||
this.vertexCount = 0;
|
||||
|
||||
this.vertices = new Vector3[size_x_s0];
|
||||
this.uvs0 = new Vector2[size_x_s0];
|
||||
this.uvs2 = new Vector2[size_x_s0];
|
||||
//this.uvs4 = new Vector2[sizeX8]; // SDF scale data
|
||||
this.colors32 = new Color32[size_x_s0];
|
||||
|
||||
this.normals = new Vector3[size_x_s0];
|
||||
this.tangents = new Vector4[size_x_s0];
|
||||
|
||||
this.triangles = new int[size_x_s1];
|
||||
|
||||
int index_x_s0 = 0;
|
||||
int index_x_s1 = 0;
|
||||
while (index_x_s0 / s0 < size)
|
||||
{
|
||||
for (int i = 0; i < s0; i++)
|
||||
{
|
||||
this.vertices[index_x_s0 + i] = Vector3.zero;
|
||||
this.uvs0[index_x_s0 + i] = Vector2.zero;
|
||||
this.uvs2[index_x_s0 + i] = Vector2.zero;
|
||||
//this.uvs4[index_X4 + i] = Vector2.zero;
|
||||
this.colors32[index_x_s0 + i] = s_DefaultColor;
|
||||
this.normals[index_x_s0 + i] = s_DefaultNormal;
|
||||
this.tangents[index_x_s0 + i] = s_DefaultTangent;
|
||||
}
|
||||
|
||||
// Front Face
|
||||
this.triangles[index_x_s1 + 0] = index_x_s0 + 0;
|
||||
this.triangles[index_x_s1 + 1] = index_x_s0 + 1;
|
||||
this.triangles[index_x_s1 + 2] = index_x_s0 + 2;
|
||||
this.triangles[index_x_s1 + 3] = index_x_s0 + 2;
|
||||
this.triangles[index_x_s1 + 4] = index_x_s0 + 3;
|
||||
this.triangles[index_x_s1 + 5] = index_x_s0 + 0;
|
||||
|
||||
if (isVolumetric)
|
||||
{
|
||||
// Left Face
|
||||
this.triangles[index_x_s1 + 6] = index_x_s0 + 4;
|
||||
this.triangles[index_x_s1 + 7] = index_x_s0 + 5;
|
||||
this.triangles[index_x_s1 + 8] = index_x_s0 + 1;
|
||||
this.triangles[index_x_s1 + 9] = index_x_s0 + 1;
|
||||
this.triangles[index_x_s1 + 10] = index_x_s0 + 0;
|
||||
this.triangles[index_x_s1 + 11] = index_x_s0 + 4;
|
||||
|
||||
// Right Face
|
||||
this.triangles[index_x_s1 + 12] = index_x_s0 + 3;
|
||||
this.triangles[index_x_s1 + 13] = index_x_s0 + 2;
|
||||
this.triangles[index_x_s1 + 14] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 15] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 16] = index_x_s0 + 7;
|
||||
this.triangles[index_x_s1 + 17] = index_x_s0 + 3;
|
||||
|
||||
// Top Face
|
||||
this.triangles[index_x_s1 + 18] = index_x_s0 + 1;
|
||||
this.triangles[index_x_s1 + 19] = index_x_s0 + 5;
|
||||
this.triangles[index_x_s1 + 20] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 21] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 22] = index_x_s0 + 2;
|
||||
this.triangles[index_x_s1 + 23] = index_x_s0 + 1;
|
||||
|
||||
// Bottom Face
|
||||
this.triangles[index_x_s1 + 24] = index_x_s0 + 4;
|
||||
this.triangles[index_x_s1 + 25] = index_x_s0 + 0;
|
||||
this.triangles[index_x_s1 + 26] = index_x_s0 + 3;
|
||||
this.triangles[index_x_s1 + 27] = index_x_s0 + 3;
|
||||
this.triangles[index_x_s1 + 28] = index_x_s0 + 7;
|
||||
this.triangles[index_x_s1 + 29] = index_x_s0 + 4;
|
||||
|
||||
// Back Face
|
||||
this.triangles[index_x_s1 + 30] = index_x_s0 + 7;
|
||||
this.triangles[index_x_s1 + 31] = index_x_s0 + 6;
|
||||
this.triangles[index_x_s1 + 32] = index_x_s0 + 5;
|
||||
this.triangles[index_x_s1 + 33] = index_x_s0 + 5;
|
||||
this.triangles[index_x_s1 + 34] = index_x_s0 + 4;
|
||||
this.triangles[index_x_s1 + 35] = index_x_s0 + 7;
|
||||
}
|
||||
|
||||
index_x_s0 += s0;
|
||||
index_x_s1 += s1;
|
||||
}
|
||||
|
||||
// Pre-assign base vertex attributes.
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
this.mesh.triangles = this.triangles;
|
||||
this.mesh.bounds = s_DefaultBounds;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to resized the content of MeshData and re-assign normals, tangents and triangles.
|
||||
/// </summary>
|
||||
/// <param name="meshData"></param>
|
||||
/// <param name="size"></param>
|
||||
public void ResizeMeshInfo(int size)
|
||||
{
|
||||
// Limit the mesh to less than 65535 vertices which is the limit for Unity's Mesh.
|
||||
size = Mathf.Min(size, 16383);
|
||||
|
||||
int size_X4 = size * 4;
|
||||
int size_X6 = size * 6;
|
||||
|
||||
int previousSize = this.vertices.Length / 4;
|
||||
|
||||
Array.Resize(ref this.vertices, size_X4);
|
||||
Array.Resize(ref this.normals, size_X4);
|
||||
Array.Resize(ref this.tangents, size_X4);
|
||||
|
||||
Array.Resize(ref this.uvs0, size_X4);
|
||||
Array.Resize(ref this.uvs2, size_X4);
|
||||
//Array.Resize(ref this.uvs4, size_X4);
|
||||
|
||||
Array.Resize(ref this.colors32, size_X4);
|
||||
|
||||
Array.Resize(ref this.triangles, size_X6);
|
||||
|
||||
|
||||
// Re-assign Normals, Tangents and Triangles
|
||||
if (size <= previousSize)
|
||||
{
|
||||
this.mesh.triangles = this.triangles;
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = previousSize; i < size; i++)
|
||||
{
|
||||
int index_X4 = i * 4;
|
||||
int index_X6 = i * 6;
|
||||
|
||||
this.normals[0 + index_X4] = s_DefaultNormal;
|
||||
this.normals[1 + index_X4] = s_DefaultNormal;
|
||||
this.normals[2 + index_X4] = s_DefaultNormal;
|
||||
this.normals[3 + index_X4] = s_DefaultNormal;
|
||||
|
||||
this.tangents[0 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[1 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[2 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[3 + index_X4] = s_DefaultTangent;
|
||||
|
||||
// Setup Triangles
|
||||
this.triangles[0 + index_X6] = 0 + index_X4;
|
||||
this.triangles[1 + index_X6] = 1 + index_X4;
|
||||
this.triangles[2 + index_X6] = 2 + index_X4;
|
||||
this.triangles[3 + index_X6] = 2 + index_X4;
|
||||
this.triangles[4 + index_X6] = 3 + index_X4;
|
||||
this.triangles[5 + index_X6] = 0 + index_X4;
|
||||
}
|
||||
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
this.mesh.triangles = this.triangles;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to resized the content of MeshData and re-assign normals, tangents and triangles.
|
||||
/// </summary>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="isVolumetric"></param>
|
||||
public void ResizeMeshInfo(int size, bool isVolumetric)
|
||||
{
|
||||
int s0 = !isVolumetric ? 4 : 8;
|
||||
int s1 = !isVolumetric ? 6 : 36;
|
||||
|
||||
// Limit the mesh to less than 65535 vertices which is the limit for Unity's Mesh.
|
||||
size = Mathf.Min(size, 65532 / s0);
|
||||
|
||||
int size_X4 = size * s0;
|
||||
int size_X6 = size * s1;
|
||||
|
||||
int previousSize = this.vertices.Length / s0;
|
||||
|
||||
Array.Resize(ref this.vertices, size_X4);
|
||||
Array.Resize(ref this.normals, size_X4);
|
||||
Array.Resize(ref this.tangents, size_X4);
|
||||
|
||||
Array.Resize(ref this.uvs0, size_X4);
|
||||
Array.Resize(ref this.uvs2, size_X4);
|
||||
//Array.Resize(ref this.uvs4, size_X4);
|
||||
|
||||
Array.Resize(ref this.colors32, size_X4);
|
||||
|
||||
Array.Resize(ref this.triangles, size_X6);
|
||||
|
||||
|
||||
// Re-assign Normals, Tangents and Triangles
|
||||
if (size <= previousSize)
|
||||
{
|
||||
this.mesh.triangles = this.triangles;
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = previousSize; i < size; i++)
|
||||
{
|
||||
int index_X4 = i * s0;
|
||||
int index_X6 = i * s1;
|
||||
|
||||
this.normals[0 + index_X4] = s_DefaultNormal;
|
||||
this.normals[1 + index_X4] = s_DefaultNormal;
|
||||
this.normals[2 + index_X4] = s_DefaultNormal;
|
||||
this.normals[3 + index_X4] = s_DefaultNormal;
|
||||
|
||||
this.tangents[0 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[1 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[2 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[3 + index_X4] = s_DefaultTangent;
|
||||
|
||||
if (isVolumetric)
|
||||
{
|
||||
this.normals[4 + index_X4] = s_DefaultNormal;
|
||||
this.normals[5 + index_X4] = s_DefaultNormal;
|
||||
this.normals[6 + index_X4] = s_DefaultNormal;
|
||||
this.normals[7 + index_X4] = s_DefaultNormal;
|
||||
|
||||
this.tangents[4 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[5 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[6 + index_X4] = s_DefaultTangent;
|
||||
this.tangents[7 + index_X4] = s_DefaultTangent;
|
||||
}
|
||||
|
||||
// Setup Triangles
|
||||
this.triangles[0 + index_X6] = 0 + index_X4;
|
||||
this.triangles[1 + index_X6] = 1 + index_X4;
|
||||
this.triangles[2 + index_X6] = 2 + index_X4;
|
||||
this.triangles[3 + index_X6] = 2 + index_X4;
|
||||
this.triangles[4 + index_X6] = 3 + index_X4;
|
||||
this.triangles[5 + index_X6] = 0 + index_X4;
|
||||
|
||||
if (isVolumetric)
|
||||
{
|
||||
// Left Face
|
||||
this.triangles[index_X6 + 6] = index_X4 + 4;
|
||||
this.triangles[index_X6 + 7] = index_X4 + 5;
|
||||
this.triangles[index_X6 + 8] = index_X4 + 1;
|
||||
this.triangles[index_X6 + 9] = index_X4 + 1;
|
||||
this.triangles[index_X6 + 10] = index_X4 + 0;
|
||||
this.triangles[index_X6 + 11] = index_X4 + 4;
|
||||
|
||||
// Right Face
|
||||
this.triangles[index_X6 + 12] = index_X4 + 3;
|
||||
this.triangles[index_X6 + 13] = index_X4 + 2;
|
||||
this.triangles[index_X6 + 14] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 15] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 16] = index_X4 + 7;
|
||||
this.triangles[index_X6 + 17] = index_X4 + 3;
|
||||
|
||||
// Top Face
|
||||
this.triangles[index_X6 + 18] = index_X4 + 1;
|
||||
this.triangles[index_X6 + 19] = index_X4 + 5;
|
||||
this.triangles[index_X6 + 20] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 21] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 22] = index_X4 + 2;
|
||||
this.triangles[index_X6 + 23] = index_X4 + 1;
|
||||
|
||||
// Bottom Face
|
||||
this.triangles[index_X6 + 24] = index_X4 + 4;
|
||||
this.triangles[index_X6 + 25] = index_X4 + 0;
|
||||
this.triangles[index_X6 + 26] = index_X4 + 3;
|
||||
this.triangles[index_X6 + 27] = index_X4 + 3;
|
||||
this.triangles[index_X6 + 28] = index_X4 + 7;
|
||||
this.triangles[index_X6 + 29] = index_X4 + 4;
|
||||
|
||||
// Back Face
|
||||
this.triangles[index_X6 + 30] = index_X4 + 7;
|
||||
this.triangles[index_X6 + 31] = index_X4 + 6;
|
||||
this.triangles[index_X6 + 32] = index_X4 + 5;
|
||||
this.triangles[index_X6 + 33] = index_X4 + 5;
|
||||
this.triangles[index_X6 + 34] = index_X4 + 4;
|
||||
this.triangles[index_X6 + 35] = index_X4 + 7;
|
||||
}
|
||||
}
|
||||
|
||||
this.mesh.vertices = this.vertices;
|
||||
this.mesh.normals = this.normals;
|
||||
this.mesh.tangents = this.tangents;
|
||||
this.mesh.triangles = this.triangles;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the vertices while preserving the Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
if (this.vertices == null) return;
|
||||
|
||||
Array.Clear(this.vertices, 0, this.vertices.Length);
|
||||
this.vertexCount = 0;
|
||||
|
||||
if (this.mesh != null)
|
||||
this.mesh.vertices = this.vertices;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the vertices while preserving the Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void Clear(bool uploadChanges)
|
||||
{
|
||||
if (this.vertices == null) return;
|
||||
|
||||
Array.Clear(this.vertices, 0, this.vertices.Length);
|
||||
this.vertexCount = 0;
|
||||
|
||||
if (uploadChanges && this.mesh != null)
|
||||
this.mesh.vertices = this.vertices;
|
||||
|
||||
if (this.mesh != null)
|
||||
this.mesh.bounds = s_DefaultBounds;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the vertices while preserving the Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void ClearUnusedVertices()
|
||||
{
|
||||
int length = vertices.Length - vertexCount;
|
||||
|
||||
if (length > 0)
|
||||
Array.Clear(vertices, vertexCount, length);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to mark unused vertices as degenerate.
|
||||
/// </summary>
|
||||
/// <param name="startIndex"></param>
|
||||
public void ClearUnusedVertices(int startIndex)
|
||||
{
|
||||
int length = this.vertices.Length - startIndex;
|
||||
|
||||
if (length > 0)
|
||||
Array.Clear(this.vertices, startIndex, length);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to mark unused vertices as degenerate an upload resulting data to the mesh.
|
||||
/// </summary>
|
||||
/// <param name="startIndex"></param>
|
||||
public void ClearUnusedVertices(int startIndex, bool updateMesh)
|
||||
{
|
||||
int length = this.vertices.Length - startIndex;
|
||||
|
||||
if (length > 0)
|
||||
Array.Clear(this.vertices, startIndex, length);
|
||||
|
||||
if (updateMesh && mesh != null)
|
||||
this.mesh.vertices = this.vertices;
|
||||
}
|
||||
|
||||
|
||||
public void SortGeometry (VertexSortingOrder order)
|
||||
{
|
||||
switch (order)
|
||||
{
|
||||
case VertexSortingOrder.Normal:
|
||||
// Do nothing
|
||||
break;
|
||||
case VertexSortingOrder.Reverse:
|
||||
int size = vertexCount / 4;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
int src = i * 4;
|
||||
int dst = (size - i - 1) * 4;
|
||||
|
||||
if (src < dst)
|
||||
SwapVertexData(src, dst);
|
||||
|
||||
}
|
||||
break;
|
||||
//case VertexSortingOrder.Depth:
|
||||
// break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to rearrange the quads of the text object to change their rendering order.
|
||||
/// </summary>
|
||||
/// <param name="sortingOrder"></param>
|
||||
public void SortGeometry(IList<int> sortingOrder)
|
||||
{
|
||||
// Make sure the sorting order array is not larger than the vertices array.
|
||||
int indexCount = sortingOrder.Count;
|
||||
|
||||
if (indexCount * 4 > vertices.Length) return;
|
||||
|
||||
int src_index;
|
||||
|
||||
for (int dst_index = 0; dst_index < indexCount; dst_index++)
|
||||
{
|
||||
src_index = sortingOrder[dst_index];
|
||||
|
||||
while (src_index < dst_index)
|
||||
{
|
||||
src_index = sortingOrder[src_index];
|
||||
}
|
||||
|
||||
// Swap items
|
||||
if (src_index != dst_index)
|
||||
SwapVertexData(src_index * 4, dst_index * 4);
|
||||
|
||||
//Debug.Log("Swap element [" + dst_index + "] with [" + src_index + "]. Vertex[" + dst_index + "] is " + vertices[dst_index * 4].z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to swap the vertex attributes between src and dst quads.
|
||||
/// </summary>
|
||||
/// <param name="src">Index of the first vertex attribute of the source character / quad.</param>
|
||||
/// <param name="dst">Index of the first vertex attribute of the destination character / quad.</param>
|
||||
public void SwapVertexData(int src, int dst)
|
||||
{
|
||||
int src_Index = src; // * 4;
|
||||
int dst_Index = dst; // * 4;
|
||||
|
||||
// Swap vertices
|
||||
Vector3 vertex;
|
||||
vertex = vertices[dst_Index + 0];
|
||||
vertices[dst_Index + 0] = vertices[src_Index + 0];
|
||||
vertices[src_Index + 0] = vertex;
|
||||
|
||||
vertex = vertices[dst_Index + 1];
|
||||
vertices[dst_Index + 1] = vertices[src_Index + 1];
|
||||
vertices[src_Index + 1] = vertex;
|
||||
|
||||
vertex = vertices[dst_Index + 2];
|
||||
vertices[dst_Index + 2] = vertices[src_Index + 2];
|
||||
vertices[src_Index + 2] = vertex;
|
||||
|
||||
vertex = vertices[dst_Index + 3];
|
||||
vertices[dst_Index + 3] = vertices[src_Index + 3];
|
||||
vertices[src_Index + 3] = vertex;
|
||||
|
||||
|
||||
//Swap UVs0
|
||||
Vector2 uvs;
|
||||
uvs = uvs0[dst_Index + 0];
|
||||
uvs0[dst_Index + 0] = uvs0[src_Index + 0];
|
||||
uvs0[src_Index + 0] = uvs;
|
||||
|
||||
uvs = uvs0[dst_Index + 1];
|
||||
uvs0[dst_Index + 1] = uvs0[src_Index + 1];
|
||||
uvs0[src_Index + 1] = uvs;
|
||||
|
||||
uvs = uvs0[dst_Index + 2];
|
||||
uvs0[dst_Index + 2] = uvs0[src_Index + 2];
|
||||
uvs0[src_Index + 2] = uvs;
|
||||
|
||||
uvs = uvs0[dst_Index + 3];
|
||||
uvs0[dst_Index + 3] = uvs0[src_Index + 3];
|
||||
uvs0[src_Index + 3] = uvs;
|
||||
|
||||
// Swap UVs2
|
||||
uvs = uvs2[dst_Index + 0];
|
||||
uvs2[dst_Index + 0] = uvs2[src_Index + 0];
|
||||
uvs2[src_Index + 0] = uvs;
|
||||
|
||||
uvs = uvs2[dst_Index + 1];
|
||||
uvs2[dst_Index + 1] = uvs2[src_Index + 1];
|
||||
uvs2[src_Index + 1] = uvs;
|
||||
|
||||
uvs = uvs2[dst_Index + 2];
|
||||
uvs2[dst_Index + 2] = uvs2[src_Index + 2];
|
||||
uvs2[src_Index + 2] = uvs;
|
||||
|
||||
uvs = uvs2[dst_Index + 3];
|
||||
uvs2[dst_Index + 3] = uvs2[src_Index + 3];
|
||||
uvs2[src_Index + 3] = uvs;
|
||||
|
||||
// Vertex Colors
|
||||
Color32 color;
|
||||
color = colors32[dst_Index + 0];
|
||||
colors32[dst_Index + 0] = colors32[src_Index + 0];
|
||||
colors32[src_Index + 0] = color;
|
||||
|
||||
color = colors32[dst_Index + 1];
|
||||
colors32[dst_Index + 1] = colors32[src_Index + 1];
|
||||
colors32[src_Index + 1] = color;
|
||||
|
||||
color = colors32[dst_Index + 2];
|
||||
colors32[dst_Index + 2] = colors32[src_Index + 2];
|
||||
colors32[src_Index + 2] = color;
|
||||
|
||||
color = colors32[dst_Index + 3];
|
||||
colors32[dst_Index + 3] = colors32[src_Index + 3];
|
||||
colors32[src_Index + 3] = color;
|
||||
}
|
||||
|
||||
|
||||
//int Partition (int start, int end)
|
||||
//{
|
||||
// float pivot = vertices[end].z;
|
||||
|
||||
// int partitionIndex = start;
|
||||
// for (int i = start; i < end; i++)
|
||||
// {
|
||||
// if (vertices[i].z <= pivot)
|
||||
// {
|
||||
// Swap(vertices[i], vertices[partitionIndex]);
|
||||
// partitionIndex += 1;
|
||||
// }
|
||||
// }
|
||||
// Swap(vertices[partitionIndex], vertices[end]);
|
||||
// return partitionIndex;
|
||||
//}
|
||||
|
||||
|
||||
//void Swap(Vector3 a, Vector3 b)
|
||||
//{
|
||||
// Vector3 temp = a;
|
||||
// a = b;
|
||||
// b = a;
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e21bec35f48a44298911b25ead550ce3
|
||||
timeCreated: 1462398762
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,51 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
internal class TMP_ObjectPool<T> where T : new()
|
||||
{
|
||||
private readonly Stack<T> m_Stack = new Stack<T>();
|
||||
private readonly UnityAction<T> m_ActionOnGet;
|
||||
private readonly UnityAction<T> m_ActionOnRelease;
|
||||
|
||||
public int countAll { get; private set; }
|
||||
public int countActive { get { return countAll - countInactive; } }
|
||||
public int countInactive { get { return m_Stack.Count; } }
|
||||
|
||||
public TMP_ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease)
|
||||
{
|
||||
m_ActionOnGet = actionOnGet;
|
||||
m_ActionOnRelease = actionOnRelease;
|
||||
}
|
||||
|
||||
public T Get()
|
||||
{
|
||||
T element;
|
||||
if (m_Stack.Count == 0)
|
||||
{
|
||||
element = new T();
|
||||
countAll++;
|
||||
}
|
||||
else
|
||||
{
|
||||
element = m_Stack.Pop();
|
||||
}
|
||||
if (m_ActionOnGet != null)
|
||||
m_ActionOnGet(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
public void Release(T element)
|
||||
{
|
||||
if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element))
|
||||
Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
|
||||
if (m_ActionOnRelease != null)
|
||||
m_ActionOnRelease(element);
|
||||
m_Stack.Push(element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e69259f6ff914146ad610be5491eb44a
|
||||
timeCreated: 1458521389
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,212 @@
|
|||
#if UNITY_EDITOR
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[System.Serializable]
|
||||
public class TMP_PackageResourceImporter
|
||||
{
|
||||
bool m_EssentialResourcesImported;
|
||||
bool m_ExamplesAndExtrasResourcesImported;
|
||||
internal bool m_IsImportingExamples;
|
||||
|
||||
public TMP_PackageResourceImporter() { }
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
// Check if the resources state has changed.
|
||||
m_EssentialResourcesImported = Directory.Exists("Assets/TextMesh Pro");
|
||||
m_ExamplesAndExtrasResourcesImported = Directory.Exists("Assets/TextMesh Pro/Examples & Extras");
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
// Display options to import Essential resources
|
||||
GUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
{
|
||||
GUILayout.Label("TMP Essentials", EditorStyles.boldLabel);
|
||||
GUILayout.Label("This appears to be the first time you access TextMesh Pro, as such we need to add resources to your project that are essential for using TextMesh Pro. These new resources will be placed at the root of your project in the \"TextMesh Pro\" folder.", new GUIStyle(EditorStyles.label) { wordWrap = true } );
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUI.enabled = !m_EssentialResourcesImported;
|
||||
if (GUILayout.Button("Import TMP Essentials"))
|
||||
{
|
||||
AssetDatabase.importPackageCompleted += ImportCallback;
|
||||
|
||||
string packageFullPath = GetPackageFullPath();
|
||||
AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Essential Resources.unitypackage", false);
|
||||
}
|
||||
GUILayout.Space(5f);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
// Display options to import Examples & Extras
|
||||
GUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
{
|
||||
GUILayout.Label("TMP Examples & Extras", EditorStyles.boldLabel);
|
||||
GUILayout.Label("The Examples & Extras package contains addition resources and examples that will make discovering and learning about TextMesh Pro's powerful features easier. These additional resources will be placed in the same folder as the TMP essential resources.", new GUIStyle(EditorStyles.label) { wordWrap = true });
|
||||
GUILayout.Space(5f);
|
||||
|
||||
GUI.enabled = m_EssentialResourcesImported && !m_ExamplesAndExtrasResourcesImported;
|
||||
if (GUILayout.Button("Import TMP Examples & Extras"))
|
||||
{
|
||||
// Set flag to get around importing scripts as per of this package which results in an assembly reload which in turn prevents / clears any callbacks.
|
||||
m_IsImportingExamples = true;
|
||||
|
||||
var packageFullPath = GetPackageFullPath();
|
||||
AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Examples & Extras.unitypackage", false);
|
||||
}
|
||||
GUILayout.Space(5f);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Space(5f);
|
||||
}
|
||||
|
||||
internal void RegisterResourceImportCallback()
|
||||
{
|
||||
AssetDatabase.importPackageCompleted += ImportCallback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="packageName"></param>
|
||||
void ImportCallback(string packageName)
|
||||
{
|
||||
if (packageName == "TMP Essential Resources")
|
||||
{
|
||||
m_EssentialResourcesImported = true;
|
||||
TMPro_EventManager.ON_RESOURCES_LOADED();
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
SettingsService.NotifySettingsProviderChanged();
|
||||
#endif
|
||||
}
|
||||
else if (packageName == "TMP Examples & Extras")
|
||||
{
|
||||
m_ExamplesAndExtrasResourcesImported = true;
|
||||
m_IsImportingExamples = false;
|
||||
}
|
||||
|
||||
Debug.Log("[" + packageName + "] have been imported.");
|
||||
|
||||
AssetDatabase.importPackageCompleted -= ImportCallback;
|
||||
}
|
||||
|
||||
static string GetPackageFullPath()
|
||||
{
|
||||
// Check for potential UPM package
|
||||
string packagePath = Path.GetFullPath("Packages/com.unity.textmeshpro");
|
||||
if (Directory.Exists(packagePath))
|
||||
{
|
||||
return packagePath;
|
||||
}
|
||||
|
||||
packagePath = Path.GetFullPath("Assets/..");
|
||||
if (Directory.Exists(packagePath))
|
||||
{
|
||||
// Search default location for development package
|
||||
if (Directory.Exists(packagePath + "/Assets/Packages/com.unity.TextMeshPro/Editor Resources"))
|
||||
{
|
||||
return packagePath + "/Assets/Packages/com.unity.TextMeshPro";
|
||||
}
|
||||
|
||||
// Search for default location of normal TextMesh Pro AssetStore package
|
||||
if (Directory.Exists(packagePath + "/Assets/TextMesh Pro/Editor Resources"))
|
||||
{
|
||||
return packagePath + "/Assets/TextMesh Pro";
|
||||
}
|
||||
|
||||
// Search for potential alternative locations in the user project
|
||||
string[] matchingPaths = Directory.GetDirectories(packagePath, "TextMesh Pro", SearchOption.AllDirectories);
|
||||
string path = ValidateLocation(matchingPaths, packagePath);
|
||||
if (path != null) return packagePath + path;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static string ValidateLocation(string[] paths, string projectPath)
|
||||
{
|
||||
for (int i = 0; i < paths.Length; i++)
|
||||
{
|
||||
// Check if the Editor Resources folder exists.
|
||||
if (Directory.Exists(paths[i] + "/Editor Resources"))
|
||||
{
|
||||
string folderPath = paths[i].Replace(projectPath, "");
|
||||
folderPath = folderPath.TrimStart('\\', '/');
|
||||
return folderPath;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class TMP_PackageResourceImporterWindow : EditorWindow
|
||||
{
|
||||
[SerializeField]
|
||||
TMP_PackageResourceImporter m_ResourceImporter;
|
||||
|
||||
public static void ShowPackageImporterWindow()
|
||||
{
|
||||
var window = GetWindow<TMP_PackageResourceImporterWindow>();
|
||||
window.titleContent = new GUIContent("TMP Importer");
|
||||
window.Focus();
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
// Set Editor Window Size
|
||||
SetEditorWindowSize();
|
||||
|
||||
if (m_ResourceImporter == null)
|
||||
m_ResourceImporter = new TMP_PackageResourceImporter();
|
||||
|
||||
if (m_ResourceImporter.m_IsImportingExamples)
|
||||
m_ResourceImporter.RegisterResourceImportCallback();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
m_ResourceImporter.OnDestroy();
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
m_ResourceImporter.OnGUI();
|
||||
}
|
||||
|
||||
void OnInspectorUpdate()
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Limits the minimum size of the editor window.
|
||||
/// </summary>
|
||||
void SetEditorWindowSize()
|
||||
{
|
||||
EditorWindow editorWindow = this;
|
||||
|
||||
Vector2 windowSize = new Vector2(640, 210);
|
||||
editorWindow.minSize = windowSize;
|
||||
editorWindow.maxSize = windowSize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cf1fe50a641faac4691bf49eb32ce333
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- m_PersistentViewDataDictionary: {instanceID: 0}
|
||||
- LightSkin: {fileID: 11400000, guid: 0c156a7b2f4d450da1716b1625b5441d, type: 2}
|
||||
- DarkSkin: {fileID: 11400000, guid: 9d345c3252c147c89e8b61a249a46a9d, type: 2}
|
||||
- TMPEssentials: {fileID: 102900000, guid: ce4ff17ca867d2b48b5c8a4181611901, type: 3}
|
||||
- TMPExamples: {fileID: 102900000, guid: bc00e25696e4132499f56528d3fed2e3, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,278 @@
|
|||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Structure used to track basic XML tags which are binary (on / off)
|
||||
/// </summary>
|
||||
public struct TMP_FontStyleStack
|
||||
{
|
||||
public byte bold;
|
||||
public byte italic;
|
||||
public byte underline;
|
||||
public byte strikethrough;
|
||||
public byte highlight;
|
||||
public byte superscript;
|
||||
public byte subscript;
|
||||
public byte uppercase;
|
||||
public byte lowercase;
|
||||
public byte smallcaps;
|
||||
|
||||
/// <summary>
|
||||
/// Clear the basic XML tag stack.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
bold = 0;
|
||||
italic = 0;
|
||||
underline = 0;
|
||||
strikethrough = 0;
|
||||
highlight = 0;
|
||||
superscript = 0;
|
||||
subscript = 0;
|
||||
uppercase = 0;
|
||||
lowercase = 0;
|
||||
smallcaps = 0;
|
||||
}
|
||||
|
||||
public byte Add(FontStyles style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case FontStyles.Bold:
|
||||
bold++;
|
||||
return bold;
|
||||
case FontStyles.Italic:
|
||||
italic++;
|
||||
return italic;
|
||||
case FontStyles.Underline:
|
||||
underline++;
|
||||
return underline;
|
||||
case FontStyles.Strikethrough:
|
||||
strikethrough++;
|
||||
return strikethrough;
|
||||
case FontStyles.Superscript:
|
||||
superscript++;
|
||||
return superscript;
|
||||
case FontStyles.Subscript:
|
||||
subscript++;
|
||||
return subscript;
|
||||
case FontStyles.Highlight:
|
||||
highlight++;
|
||||
return highlight;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public byte Remove(FontStyles style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case FontStyles.Bold:
|
||||
if (bold > 1)
|
||||
bold--;
|
||||
else
|
||||
bold = 0;
|
||||
return bold;
|
||||
case FontStyles.Italic:
|
||||
if (italic > 1)
|
||||
italic--;
|
||||
else
|
||||
italic = 0;
|
||||
return italic;
|
||||
case FontStyles.Underline:
|
||||
if (underline > 1)
|
||||
underline--;
|
||||
else
|
||||
underline = 0;
|
||||
return underline;
|
||||
case FontStyles.Strikethrough:
|
||||
if (strikethrough > 1)
|
||||
strikethrough--;
|
||||
else
|
||||
strikethrough = 0;
|
||||
return strikethrough;
|
||||
case FontStyles.Highlight:
|
||||
if (highlight > 1)
|
||||
highlight--;
|
||||
else
|
||||
highlight = 0;
|
||||
return highlight;
|
||||
case FontStyles.Superscript:
|
||||
if (superscript > 1)
|
||||
superscript--;
|
||||
else
|
||||
superscript = 0;
|
||||
return superscript;
|
||||
case FontStyles.Subscript:
|
||||
if (subscript > 1)
|
||||
subscript--;
|
||||
else
|
||||
subscript = 0;
|
||||
return subscript;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Structure used to track XML tags of various types.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public struct TMP_RichTextTagStack<T>
|
||||
{
|
||||
public T[] m_ItemStack;
|
||||
public int m_Index;
|
||||
private int m_Capacity;
|
||||
|
||||
private T m_DefaultItem;
|
||||
|
||||
private const int k_DefaultCapacity = 4;
|
||||
//static readonly T[] m_EmptyStack = new T[0];
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to create a new item stack.
|
||||
/// </summary>
|
||||
/// <param name="tagStack"></param>
|
||||
public TMP_RichTextTagStack(T[] tagStack)
|
||||
{
|
||||
m_ItemStack = tagStack;
|
||||
m_Capacity = tagStack.Length;
|
||||
m_Index = 0;
|
||||
|
||||
m_DefaultItem = default(T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for a new item stack with the given capacity.
|
||||
/// </summary>
|
||||
/// <param name="capacity"></param>
|
||||
public TMP_RichTextTagStack(int capacity)
|
||||
{
|
||||
m_ItemStack = new T[capacity];
|
||||
m_Capacity = capacity;
|
||||
m_Index = 0;
|
||||
|
||||
m_DefaultItem = default(T);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear and reset stack to first item.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
m_Index = 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to set the first item on the stack and reset index.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public void SetDefault(T item)
|
||||
{
|
||||
m_ItemStack[0] = item;
|
||||
m_Index = 1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to add a new item to the stack.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public void Add(T item)
|
||||
{
|
||||
if (m_Index < m_ItemStack.Length)
|
||||
{
|
||||
m_ItemStack[m_Index] = item;
|
||||
m_Index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to retrieve an item from the stack.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T Remove()
|
||||
{
|
||||
m_Index -= 1;
|
||||
|
||||
if (m_Index <= 0)
|
||||
{
|
||||
m_Index = 1;
|
||||
return m_ItemStack[0];
|
||||
|
||||
}
|
||||
|
||||
return m_ItemStack[m_Index - 1];
|
||||
}
|
||||
|
||||
public void Push(T item)
|
||||
{
|
||||
if (m_Index == m_Capacity)
|
||||
{
|
||||
m_Capacity *= 2;
|
||||
if (m_Capacity == 0)
|
||||
m_Capacity = k_DefaultCapacity;
|
||||
|
||||
System.Array.Resize(ref m_ItemStack, m_Capacity);
|
||||
}
|
||||
|
||||
m_ItemStack[m_Index] = item;
|
||||
m_Index += 1;
|
||||
}
|
||||
|
||||
public T Pop()
|
||||
{
|
||||
if (m_Index == 0)
|
||||
return default(T);
|
||||
|
||||
m_Index -= 1;
|
||||
T item = m_ItemStack[m_Index];
|
||||
m_ItemStack[m_Index] = m_DefaultItem;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T Peek()
|
||||
{
|
||||
if (m_Index == 0)
|
||||
return m_DefaultItem;
|
||||
|
||||
return m_ItemStack[m_Index - 1];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to retrieve the current item from the stack.
|
||||
/// </summary>
|
||||
/// <returns>itemStack <T></returns>
|
||||
public T CurrentItem()
|
||||
{
|
||||
if (m_Index > 0)
|
||||
return m_ItemStack[m_Index - 1];
|
||||
|
||||
return m_ItemStack[0];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to retrieve the previous item without affecting the stack.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public T PreviousItem()
|
||||
{
|
||||
if (m_Index > 1)
|
||||
return m_ItemStack[m_Index - 2];
|
||||
|
||||
return m_ItemStack[0];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 20a9b557a46149dfbfa04a3a7080f5aa
|
||||
timeCreated: 1448242247
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,113 @@
|
|||
using System;
|
||||
using UnityEngine.Bindings;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Rich Text Tags and Attribute definitions and their respective HashCode values.
|
||||
/// </summary>
|
||||
enum RichTextTag : uint
|
||||
{
|
||||
// Rich Text Tags
|
||||
BOLD = 66, // <b>
|
||||
SLASH_BOLD = 1613, // </b>
|
||||
ITALIC = 73, // <i>
|
||||
SLASH_ITALIC = 1606, // </i>
|
||||
UNDERLINE = 85, // <u>
|
||||
SLASH_UNDERLINE = 1626, // </u>
|
||||
STRIKETHROUGH = 83, // <s>
|
||||
SLASH_STRIKETHROUGH = 1628, // </s>
|
||||
COLOR = 81999901, // <color>
|
||||
SLASH_COLOR = 1909026194, // </color>
|
||||
SIZE = 3061285, // <size>
|
||||
SLASH_SIZE = 58429962, // </size>
|
||||
SPRITE = 3303439849, // <sprite>
|
||||
BR = 2256, // <br>
|
||||
STYLE = 100252951, // <style>
|
||||
SLASH_STYLE = 1927738392, // </style>
|
||||
FONT = 2586451, // <font>
|
||||
SLASH_FONT = 57747708, // </font>
|
||||
LINK = 2656128, // <link>
|
||||
SLASH_LINK = 57686191, // </link>
|
||||
FONT_WEIGHT = 2405071134, // <font-weight=xxx>
|
||||
SLASH_FONT_WEIGHT = 3536990865, // </font-weight>
|
||||
|
||||
|
||||
// Font Features
|
||||
LIGA = 2655971, // <liga>
|
||||
SLASH_LIGA = 57686604, // </liga>
|
||||
FRAC = 2598518, // <frac>
|
||||
SLASH_FRAC = 57774681, // </frac>
|
||||
|
||||
// Attributes
|
||||
NAME = 2875623, // <sprite name="Name of Sprite">
|
||||
INDEX = 84268030, // <sprite index=7>
|
||||
TINT = 2960519, // <tint=bool>
|
||||
ANIM = 2283339, // <anim="first frame, last frame, frame rate">
|
||||
MATERIAL = 825491659, // <font="Name of font asset" material="Name of material">
|
||||
|
||||
// Named Colors
|
||||
RED = 91635,
|
||||
GREEN = 87065851,
|
||||
BLUE = 2457214,
|
||||
YELLOW = 3412522628,
|
||||
ORANGE = 3186379376,
|
||||
|
||||
// Prefix and Unit suffix
|
||||
PLUS = 43,
|
||||
MINUS = 45,
|
||||
PX = 2568,
|
||||
PLUS_PX = 49507,
|
||||
MINUS_PX = 47461,
|
||||
EM = 2216,
|
||||
PLUS_EM = 49091,
|
||||
MINUS_EM = 46789,
|
||||
PCT = 85031,
|
||||
PLUS_PCT = 1634348,
|
||||
MINUS_PCT = 1567082,
|
||||
PERCENTAGE = 37,
|
||||
PLUS_PERCENTAGE = 1454,
|
||||
MINUS_PERCENTAGE = 1512,
|
||||
|
||||
TRUE = 2932022,
|
||||
FALSE = 85422813,
|
||||
|
||||
DEFAULT = 3673993291, // <font="Default">
|
||||
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Defines the type of value used by a rich text tag or tag attribute.
|
||||
/// </summary>
|
||||
public enum TagValueType
|
||||
{
|
||||
None = 0x0,
|
||||
NumericalValue = 0x1,
|
||||
StringValue = 0x2,
|
||||
ColorValue = 0x4,
|
||||
}
|
||||
|
||||
public enum TagUnitType
|
||||
{
|
||||
Pixels = 0x0,
|
||||
FontUnits = 0x1,
|
||||
Percentage = 0x2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commonly referenced Unicode characters in the text generation process.
|
||||
/// </summary>
|
||||
enum UnicodeCharacter : uint
|
||||
{
|
||||
HYPHEN_MINUS = 0x2D,
|
||||
SOFT_HYPHEN = 0xAD,
|
||||
HYPHEN = 0x2010,
|
||||
NON_BREAKING_HYPHEN = 0x2011,
|
||||
ZERO_WIDTH_SPACE = 0x200B,
|
||||
RIGHT_SINGLE_QUOTATION = 0x2019,
|
||||
APOSTROPHE = 0x27,
|
||||
WORD_JOINER = 0x2060, // Prohibits line break.
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b458b2c7f196bdc4581b2f9fd6a5d931
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
using System;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public class TMP_ScrollbarEventHandler : MonoBehaviour, IPointerClickHandler, ISelectHandler, IDeselectHandler
|
||||
{
|
||||
public bool isSelected;
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
Debug.Log("Scrollbar click...");
|
||||
}
|
||||
|
||||
public void OnSelect(BaseEventData eventData)
|
||||
{
|
||||
Debug.Log("Scrollbar selected");
|
||||
isSelected = true;
|
||||
}
|
||||
|
||||
public void OnDeselect(BaseEventData eventData)
|
||||
{
|
||||
Debug.Log("Scrollbar De-Selected");
|
||||
isSelected = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 34e150112c1c42ac83170b52d898e322
|
||||
timeCreated: 1484171293
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,23 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple component that can be added to a newly created object where inheriting from MaskableGraphic is needed.
|
||||
/// </summary>
|
||||
public class TMP_SelectionCaret : MaskableGraphic
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Override to Cull function of MaskableGraphic to prevent Culling.
|
||||
/// </summary>
|
||||
/// <param name="clipRect"></param>
|
||||
/// <param name="validRect"></param>
|
||||
public override void Cull(Rect clipRect, bool validRect)
|
||||
{
|
||||
//base.Cull(clipRect, validRect);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ca819640f53b48919bf7774744f7f15e
|
||||
timeCreated: 1477609203
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,440 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
#pragma warning disable 0649 // Disabled warnings related to serialized fields not assigned in this script but used in the editor.
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[System.Serializable]
|
||||
public class TMP_Settings : ScriptableObject
|
||||
{
|
||||
private static TMP_Settings s_Instance;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the release version of the product.
|
||||
/// </summary>
|
||||
public static string version
|
||||
{
|
||||
get { return "1.4.0"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Word Wrapping will be enabled on newly created text objects by default.
|
||||
/// </summary>
|
||||
public static bool enableWordWrapping
|
||||
{
|
||||
get { return instance.m_enableWordWrapping; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableWordWrapping;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Kerning is enabled on newly created text objects by default.
|
||||
/// </summary>
|
||||
public static bool enableKerning
|
||||
{
|
||||
get { return instance.m_enableKerning; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableKerning;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Extra Padding is enabled on newly created text objects by default.
|
||||
/// </summary>
|
||||
public static bool enableExtraPadding
|
||||
{
|
||||
get { return instance.m_enableExtraPadding; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableExtraPadding;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if TintAllSprites is enabled on newly created text objects by default.
|
||||
/// </summary>
|
||||
public static bool enableTintAllSprites
|
||||
{
|
||||
get { return instance.m_enableTintAllSprites; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableTintAllSprites;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Escape Characters will be parsed in the Text Input Box on newly created text objects.
|
||||
/// </summary>
|
||||
public static bool enableParseEscapeCharacters
|
||||
{
|
||||
get { return instance.m_enableParseEscapeCharacters; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableParseEscapeCharacters;
|
||||
|
||||
/// <summary>
|
||||
/// Controls if Raycast Target is enabled by default on newly created text objects.
|
||||
/// </summary>
|
||||
public static bool enableRaycastTarget
|
||||
{
|
||||
get { return instance.m_EnableRaycastTarget; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_EnableRaycastTarget = true;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if OpenType Font Features should be retrieved at runtime from the source font file.
|
||||
/// </summary>
|
||||
public static bool getFontFeaturesAtRuntime
|
||||
{
|
||||
get { return instance.m_GetFontFeaturesAtRuntime; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_GetFontFeaturesAtRuntime = true;
|
||||
|
||||
/// <summary>
|
||||
/// The character that will be used as a replacement for missing glyphs in a font asset.
|
||||
/// </summary>
|
||||
public static int missingGlyphCharacter
|
||||
{
|
||||
get { return instance.m_missingGlyphCharacter; }
|
||||
set { instance.m_missingGlyphCharacter = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private int m_missingGlyphCharacter;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the display of warning message in the console.
|
||||
/// </summary>
|
||||
public static bool warningsDisabled
|
||||
{
|
||||
get { return instance.m_warningsDisabled; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_warningsDisabled;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Default Font Asset to be used by newly created text objects.
|
||||
/// </summary>
|
||||
public static TMP_FontAsset defaultFontAsset
|
||||
{
|
||||
get { return instance.m_defaultFontAsset; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_FontAsset m_defaultFontAsset;
|
||||
|
||||
/// <summary>
|
||||
/// The relative path to a Resources folder in the project.
|
||||
/// </summary>
|
||||
public static string defaultFontAssetPath
|
||||
{
|
||||
get { return instance.m_defaultFontAssetPath; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_defaultFontAssetPath;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Point Size of newly created text objects.
|
||||
/// </summary>
|
||||
public static float defaultFontSize
|
||||
{
|
||||
get { return instance.m_defaultFontSize; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_defaultFontSize;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier used to computer the default Min point size when Text Auto Sizing is used.
|
||||
/// </summary>
|
||||
public static float defaultTextAutoSizingMinRatio
|
||||
{
|
||||
get { return instance.m_defaultAutoSizeMinRatio; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_defaultAutoSizeMinRatio;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier used to computer the default Max point size when Text Auto Sizing is used.
|
||||
/// </summary>
|
||||
public static float defaultTextAutoSizingMaxRatio
|
||||
{
|
||||
get { return instance.m_defaultAutoSizeMaxRatio; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_defaultAutoSizeMaxRatio;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Size of the Text Container of a TextMeshPro object.
|
||||
/// </summary>
|
||||
public static Vector2 defaultTextMeshProTextContainerSize
|
||||
{
|
||||
get { return instance.m_defaultTextMeshProTextContainerSize; }
|
||||
}
|
||||
[SerializeField]
|
||||
private Vector2 m_defaultTextMeshProTextContainerSize;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Width of the Text Container of a TextMeshProUI object.
|
||||
/// </summary>
|
||||
public static Vector2 defaultTextMeshProUITextContainerSize
|
||||
{
|
||||
get { return instance.m_defaultTextMeshProUITextContainerSize; }
|
||||
}
|
||||
[SerializeField]
|
||||
private Vector2 m_defaultTextMeshProUITextContainerSize;
|
||||
|
||||
/// <summary>
|
||||
/// Set the size of the text container of newly created text objects to match the size of the text.
|
||||
/// </summary>
|
||||
public static bool autoSizeTextContainer
|
||||
{
|
||||
get { return instance.m_autoSizeTextContainer; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_autoSizeTextContainer;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the list of Fallback Fonts defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
public static List<TMP_FontAsset> fallbackFontAssets
|
||||
{
|
||||
get { return instance.m_fallbackFontAssets; }
|
||||
}
|
||||
[SerializeField]
|
||||
private List<TMP_FontAsset> m_fallbackFontAssets;
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether or not TMP will create a matching material preset or use the default material of the fallback font asset.
|
||||
/// </summary>
|
||||
public static bool matchMaterialPreset
|
||||
{
|
||||
get { return instance.m_matchMaterialPreset; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_matchMaterialPreset;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Sprite Asset to be used by default.
|
||||
/// </summary>
|
||||
public static TMP_SpriteAsset defaultSpriteAsset
|
||||
{
|
||||
get { return instance.m_defaultSpriteAsset; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_SpriteAsset m_defaultSpriteAsset;
|
||||
|
||||
/// <summary>
|
||||
/// The relative path to a Resources folder in the project.
|
||||
/// </summary>
|
||||
public static string defaultSpriteAssetPath
|
||||
{
|
||||
get { return instance.m_defaultSpriteAssetPath; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_defaultSpriteAssetPath;
|
||||
|
||||
/// <summary>
|
||||
/// The relative path to a Resources folder in the project that contains Color Gradient Presets.
|
||||
/// </summary>
|
||||
public static string defaultColorGradientPresetsPath
|
||||
{
|
||||
get { return instance.m_defaultColorGradientPresetsPath; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_defaultColorGradientPresetsPath;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if Emoji support is enabled in the Input Field TouchScreenKeyboard.
|
||||
/// </summary>
|
||||
public static bool enableEmojiSupport
|
||||
{
|
||||
get { return instance.m_enableEmojiSupport; }
|
||||
set { instance.m_enableEmojiSupport = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_enableEmojiSupport;
|
||||
|
||||
/// <summary>
|
||||
/// The Default Style Sheet used by the text objects.
|
||||
/// </summary>
|
||||
public static TMP_StyleSheet defaultStyleSheet
|
||||
{
|
||||
get { return instance.m_defaultStyleSheet; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_StyleSheet m_defaultStyleSheet;
|
||||
|
||||
/// <summary>
|
||||
/// Text file that contains the leading characters used for line breaking for Asian languages.
|
||||
/// </summary>
|
||||
public static TextAsset leadingCharacters
|
||||
{
|
||||
get { return instance.m_leadingCharacters; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TextAsset m_leadingCharacters;
|
||||
|
||||
/// <summary>
|
||||
/// Text file that contains the following characters used for line breaking for Asian languages.
|
||||
/// </summary>
|
||||
public static TextAsset followingCharacters
|
||||
{
|
||||
get { return instance.m_followingCharacters; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TextAsset m_followingCharacters;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static LineBreakingTable linebreakingRules
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance.m_linebreakingRules == null)
|
||||
LoadLinebreakingRules();
|
||||
|
||||
return instance.m_linebreakingRules;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private LineBreakingTable m_linebreakingRules;
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the settings class.
|
||||
/// </summary>
|
||||
public static TMP_Settings instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (TMP_Settings.s_Instance == null)
|
||||
{
|
||||
TMP_Settings.s_Instance = Resources.Load<TMP_Settings>("TMP Settings");
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Make sure TextMesh Pro UPM packages resources have been added to the user project
|
||||
if (TMP_Settings.s_Instance == null)
|
||||
{
|
||||
// Open TMP Resources Importer
|
||||
TMP_PackageResourceImporterWindow.ShowPackageImporterWindow();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return TMP_Settings.s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Static Function to load the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_Settings LoadDefaultSettings()
|
||||
{
|
||||
if (s_Instance == null)
|
||||
{
|
||||
// Load settings from TMP_Settings file
|
||||
TMP_Settings settings = Resources.Load<TMP_Settings>("TMP Settings");
|
||||
if (settings != null)
|
||||
s_Instance = settings;
|
||||
}
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Sprite Asset defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_Settings GetSettings()
|
||||
{
|
||||
if (TMP_Settings.instance == null) return null;
|
||||
|
||||
return TMP_Settings.instance;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Font Asset defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_FontAsset GetFontAsset()
|
||||
{
|
||||
if (TMP_Settings.instance == null) return null;
|
||||
|
||||
return TMP_Settings.instance.m_defaultFontAsset;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Sprite Asset defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_SpriteAsset GetSpriteAsset()
|
||||
{
|
||||
if (TMP_Settings.instance == null) return null;
|
||||
|
||||
return TMP_Settings.instance.m_defaultSpriteAsset;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Sprite Asset defined in the TMP Settings file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_StyleSheet GetStyleSheet()
|
||||
{
|
||||
if (TMP_Settings.instance == null) return null;
|
||||
|
||||
return TMP_Settings.instance.m_defaultStyleSheet;
|
||||
}
|
||||
|
||||
|
||||
public static void LoadLinebreakingRules()
|
||||
{
|
||||
//Debug.Log("Loading Line Breaking Rules for Asian Languages.");
|
||||
|
||||
if (TMP_Settings.instance == null) return;
|
||||
|
||||
if (s_Instance.m_linebreakingRules == null)
|
||||
s_Instance.m_linebreakingRules = new LineBreakingTable();
|
||||
|
||||
s_Instance.m_linebreakingRules.leadingCharacters = GetCharacters(s_Instance.m_leadingCharacters);
|
||||
s_Instance.m_linebreakingRules.followingCharacters = GetCharacters(s_Instance.m_followingCharacters);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the characters from the line breaking files
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
private static Dictionary<int, char> GetCharacters(TextAsset file)
|
||||
{
|
||||
Dictionary<int, char> dict = new Dictionary<int, char>();
|
||||
string text = file.text;
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
char c = text[i];
|
||||
// Check to make sure we don't include duplicates
|
||||
if (dict.ContainsKey((int)c) == false)
|
||||
{
|
||||
dict.Add((int)c, c);
|
||||
//Debug.Log("Adding [" + (int)c + "] to dictionary.");
|
||||
}
|
||||
//else
|
||||
// Debug.Log("Character [" + text[i] + "] is a duplicate.");
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
|
||||
public class LineBreakingTable
|
||||
{
|
||||
public Dictionary<int, char> leadingCharacters;
|
||||
public Dictionary<int, char> followingCharacters;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2705215ac5b84b70bacc50632be6e391
|
||||
timeCreated: 1457654851
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,563 @@
|
|||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public static class ShaderUtilities
|
||||
{
|
||||
// Shader Property IDs
|
||||
public static int ID_MainTex;
|
||||
|
||||
public static int ID_FaceTex;
|
||||
public static int ID_FaceColor;
|
||||
public static int ID_FaceDilate;
|
||||
public static int ID_Shininess;
|
||||
|
||||
public static int ID_UnderlayColor;
|
||||
public static int ID_UnderlayOffsetX;
|
||||
public static int ID_UnderlayOffsetY;
|
||||
public static int ID_UnderlayDilate;
|
||||
public static int ID_UnderlaySoftness;
|
||||
|
||||
public static int ID_WeightNormal;
|
||||
public static int ID_WeightBold;
|
||||
|
||||
public static int ID_OutlineTex;
|
||||
public static int ID_OutlineWidth;
|
||||
public static int ID_OutlineSoftness;
|
||||
public static int ID_OutlineColor;
|
||||
|
||||
public static int ID_Padding;
|
||||
public static int ID_GradientScale;
|
||||
public static int ID_ScaleX;
|
||||
public static int ID_ScaleY;
|
||||
public static int ID_PerspectiveFilter;
|
||||
public static int ID_Sharpness;
|
||||
|
||||
public static int ID_TextureWidth;
|
||||
public static int ID_TextureHeight;
|
||||
|
||||
public static int ID_BevelAmount;
|
||||
|
||||
public static int ID_GlowColor;
|
||||
public static int ID_GlowOffset;
|
||||
public static int ID_GlowPower;
|
||||
public static int ID_GlowOuter;
|
||||
|
||||
public static int ID_LightAngle;
|
||||
|
||||
public static int ID_EnvMap;
|
||||
public static int ID_EnvMatrix;
|
||||
public static int ID_EnvMatrixRotation;
|
||||
|
||||
//public static int ID_MaskID;
|
||||
public static int ID_MaskCoord;
|
||||
public static int ID_ClipRect;
|
||||
public static int ID_MaskSoftnessX;
|
||||
public static int ID_MaskSoftnessY;
|
||||
public static int ID_VertexOffsetX;
|
||||
public static int ID_VertexOffsetY;
|
||||
public static int ID_UseClipRect;
|
||||
|
||||
public static int ID_StencilID;
|
||||
public static int ID_StencilOp;
|
||||
public static int ID_StencilComp;
|
||||
public static int ID_StencilReadMask;
|
||||
public static int ID_StencilWriteMask;
|
||||
|
||||
public static int ID_ShaderFlags;
|
||||
public static int ID_ScaleRatio_A;
|
||||
public static int ID_ScaleRatio_B;
|
||||
public static int ID_ScaleRatio_C;
|
||||
|
||||
public static string Keyword_Bevel = "BEVEL_ON";
|
||||
public static string Keyword_Glow = "GLOW_ON";
|
||||
public static string Keyword_Underlay = "UNDERLAY_ON";
|
||||
public static string Keyword_Ratios = "RATIOS_OFF";
|
||||
//public static string Keyword_MASK_OFF = "MASK_OFF";
|
||||
public static string Keyword_MASK_SOFT = "MASK_SOFT";
|
||||
public static string Keyword_MASK_HARD = "MASK_HARD";
|
||||
public static string Keyword_MASK_TEX = "MASK_TEX";
|
||||
public static string Keyword_Outline = "OUTLINE_ON";
|
||||
|
||||
public static string ShaderTag_ZTestMode = "unity_GUIZTestMode";
|
||||
public static string ShaderTag_CullMode = "_CullMode";
|
||||
|
||||
private static float m_clamp = 1.0f;
|
||||
public static bool isInitialized = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a reference to the mobile distance field shader.
|
||||
/// </summary>
|
||||
internal static Shader ShaderRef_MobileSDF
|
||||
{
|
||||
get
|
||||
{
|
||||
if (k_ShaderRef_MobileSDF == null)
|
||||
k_ShaderRef_MobileSDF = Shader.Find("TextMeshPro/Mobile/Distance Field");
|
||||
|
||||
return k_ShaderRef_MobileSDF;
|
||||
}
|
||||
}
|
||||
static Shader k_ShaderRef_MobileSDF;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a reference to the mobile bitmap shader.
|
||||
/// </summary>
|
||||
internal static Shader ShaderRef_MobileBitmap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (k_ShaderRef_MobileBitmap == null)
|
||||
k_ShaderRef_MobileBitmap = Shader.Find("TextMeshPro/Mobile/Bitmap");
|
||||
|
||||
return k_ShaderRef_MobileBitmap;
|
||||
}
|
||||
}
|
||||
static Shader k_ShaderRef_MobileBitmap;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
static ShaderUtilities()
|
||||
{
|
||||
GetShaderPropertyIDs();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void GetShaderPropertyIDs()
|
||||
{
|
||||
if (isInitialized == false)
|
||||
{
|
||||
//Debug.Log("Getting Shader property IDs");
|
||||
isInitialized = true;
|
||||
|
||||
ID_MainTex = Shader.PropertyToID("_MainTex");
|
||||
|
||||
ID_FaceTex = Shader.PropertyToID("_FaceTex");
|
||||
ID_FaceColor = Shader.PropertyToID("_FaceColor");
|
||||
ID_FaceDilate = Shader.PropertyToID("_FaceDilate");
|
||||
ID_Shininess = Shader.PropertyToID("_FaceShininess");
|
||||
|
||||
ID_UnderlayColor = Shader.PropertyToID("_UnderlayColor");
|
||||
ID_UnderlayOffsetX = Shader.PropertyToID("_UnderlayOffsetX");
|
||||
ID_UnderlayOffsetY = Shader.PropertyToID("_UnderlayOffsetY");
|
||||
ID_UnderlayDilate = Shader.PropertyToID("_UnderlayDilate");
|
||||
ID_UnderlaySoftness = Shader.PropertyToID("_UnderlaySoftness");
|
||||
|
||||
ID_WeightNormal = Shader.PropertyToID("_WeightNormal");
|
||||
ID_WeightBold = Shader.PropertyToID("_WeightBold");
|
||||
|
||||
ID_OutlineTex = Shader.PropertyToID("_OutlineTex");
|
||||
ID_OutlineWidth = Shader.PropertyToID("_OutlineWidth");
|
||||
ID_OutlineSoftness = Shader.PropertyToID("_OutlineSoftness");
|
||||
ID_OutlineColor = Shader.PropertyToID("_OutlineColor");
|
||||
|
||||
ID_Padding = Shader.PropertyToID("_Padding");
|
||||
ID_GradientScale = Shader.PropertyToID("_GradientScale");
|
||||
ID_ScaleX = Shader.PropertyToID("_ScaleX");
|
||||
ID_ScaleY = Shader.PropertyToID("_ScaleY");
|
||||
ID_PerspectiveFilter = Shader.PropertyToID("_PerspectiveFilter");
|
||||
ID_Sharpness = Shader.PropertyToID("_Sharpness");
|
||||
|
||||
ID_TextureWidth = Shader.PropertyToID("_TextureWidth");
|
||||
ID_TextureHeight = Shader.PropertyToID("_TextureHeight");
|
||||
|
||||
ID_BevelAmount = Shader.PropertyToID("_Bevel");
|
||||
|
||||
ID_LightAngle = Shader.PropertyToID("_LightAngle");
|
||||
|
||||
ID_EnvMap = Shader.PropertyToID("_Cube");
|
||||
ID_EnvMatrix = Shader.PropertyToID("_EnvMatrix");
|
||||
ID_EnvMatrixRotation = Shader.PropertyToID("_EnvMatrixRotation");
|
||||
|
||||
|
||||
ID_GlowColor = Shader.PropertyToID("_GlowColor");
|
||||
ID_GlowOffset = Shader.PropertyToID("_GlowOffset");
|
||||
ID_GlowPower = Shader.PropertyToID("_GlowPower");
|
||||
ID_GlowOuter = Shader.PropertyToID("_GlowOuter");
|
||||
|
||||
//ID_MaskID = Shader.PropertyToID("_MaskID");
|
||||
ID_MaskCoord = Shader.PropertyToID("_MaskCoord");
|
||||
ID_ClipRect = Shader.PropertyToID("_ClipRect");
|
||||
ID_UseClipRect = Shader.PropertyToID("_UseClipRect");
|
||||
ID_MaskSoftnessX = Shader.PropertyToID("_MaskSoftnessX");
|
||||
ID_MaskSoftnessY = Shader.PropertyToID("_MaskSoftnessY");
|
||||
ID_VertexOffsetX = Shader.PropertyToID("_VertexOffsetX");
|
||||
ID_VertexOffsetY = Shader.PropertyToID("_VertexOffsetY");
|
||||
|
||||
ID_StencilID = Shader.PropertyToID("_Stencil");
|
||||
ID_StencilOp = Shader.PropertyToID("_StencilOp");
|
||||
ID_StencilComp = Shader.PropertyToID("_StencilComp");
|
||||
ID_StencilReadMask = Shader.PropertyToID("_StencilReadMask");
|
||||
ID_StencilWriteMask = Shader.PropertyToID("_StencilWriteMask");
|
||||
|
||||
ID_ShaderFlags = Shader.PropertyToID("_ShaderFlags");
|
||||
ID_ScaleRatio_A = Shader.PropertyToID("_ScaleRatioA");
|
||||
ID_ScaleRatio_B = Shader.PropertyToID("_ScaleRatioB");
|
||||
ID_ScaleRatio_C = Shader.PropertyToID("_ScaleRatioC");
|
||||
|
||||
// Set internal shader references
|
||||
if (k_ShaderRef_MobileSDF == null)
|
||||
k_ShaderRef_MobileSDF = Shader.Find("TextMeshPro/Mobile/Distance Field");
|
||||
|
||||
if (k_ShaderRef_MobileBitmap == null)
|
||||
k_ShaderRef_MobileBitmap = Shader.Find("TextMeshPro/Mobile/Bitmap");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Scale Ratios to ensure property ranges are optimum in Material Editor
|
||||
public static void UpdateShaderRatios(Material mat)
|
||||
{
|
||||
//Debug.Log("UpdateShaderRatios() called.");
|
||||
|
||||
float ratio_A = 1;
|
||||
float ratio_B = 1;
|
||||
float ratio_C = 1;
|
||||
|
||||
bool isRatioEnabled = !mat.shaderKeywords.Contains(Keyword_Ratios);
|
||||
|
||||
// Compute Ratio A
|
||||
float scale = mat.GetFloat(ID_GradientScale);
|
||||
float faceDilate = mat.GetFloat(ID_FaceDilate);
|
||||
float outlineThickness = mat.GetFloat(ID_OutlineWidth);
|
||||
float outlineSoftness = mat.GetFloat(ID_OutlineSoftness);
|
||||
|
||||
float weight = Mathf.Max(mat.GetFloat(ID_WeightNormal), mat.GetFloat(ID_WeightBold)) / 4.0f;
|
||||
|
||||
float t = Mathf.Max(1, weight + faceDilate + outlineThickness + outlineSoftness);
|
||||
|
||||
ratio_A = isRatioEnabled ? (scale - m_clamp) / (scale * t) : 1;
|
||||
|
||||
//float ratio_A_old = mat.GetFloat(ID_ScaleRatio_A);
|
||||
|
||||
// Only set the ratio if it has changed.
|
||||
//if (ratio_A != ratio_A_old)
|
||||
mat.SetFloat(ID_ScaleRatio_A, ratio_A);
|
||||
|
||||
// Compute Ratio B
|
||||
if (mat.HasProperty(ID_GlowOffset))
|
||||
{
|
||||
float glowOffset = mat.GetFloat(ID_GlowOffset);
|
||||
float glowOuter = mat.GetFloat(ID_GlowOuter);
|
||||
|
||||
float range = (weight + faceDilate) * (scale - m_clamp);
|
||||
|
||||
t = Mathf.Max(1, glowOffset + glowOuter);
|
||||
|
||||
ratio_B = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1;
|
||||
//float ratio_B_old = mat.GetFloat(ID_ScaleRatio_B);
|
||||
|
||||
// Only set the ratio if it has changed.
|
||||
//if (ratio_B != ratio_B_old)
|
||||
mat.SetFloat(ID_ScaleRatio_B, ratio_B);
|
||||
}
|
||||
|
||||
// Compute Ratio C
|
||||
if (mat.HasProperty(ID_UnderlayOffsetX))
|
||||
{
|
||||
float underlayOffsetX = mat.GetFloat(ID_UnderlayOffsetX);
|
||||
float underlayOffsetY = mat.GetFloat(ID_UnderlayOffsetY);
|
||||
float underlayDilate = mat.GetFloat(ID_UnderlayDilate);
|
||||
float underlaySoftness = mat.GetFloat(ID_UnderlaySoftness);
|
||||
|
||||
float range = (weight + faceDilate) * (scale - m_clamp);
|
||||
|
||||
t = Mathf.Max(1, Mathf.Max(Mathf.Abs(underlayOffsetX), Mathf.Abs(underlayOffsetY)) + underlayDilate + underlaySoftness);
|
||||
|
||||
ratio_C = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1;
|
||||
//float ratio_C_old = mat.GetFloat(ID_ScaleRatio_C);
|
||||
|
||||
// Only set the ratio if it has changed.
|
||||
//if (ratio_C != ratio_C_old)
|
||||
mat.SetFloat(ID_ScaleRatio_C, ratio_C);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Function to calculate padding required for Outline Width & Dilation for proper text alignment
|
||||
public static Vector4 GetFontExtent(Material material)
|
||||
{
|
||||
// Revised implementation where style no longer affects alignment
|
||||
return Vector4.zero;
|
||||
|
||||
/*
|
||||
if (material == null || !material.HasProperty(ShaderUtilities.ID_GradientScale))
|
||||
return Vector4.zero; // We are using an non SDF Shader.
|
||||
|
||||
float scaleRatioA = material.GetFloat(ID_ScaleRatio_A);
|
||||
float faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatioA;
|
||||
float outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatioA;
|
||||
|
||||
float extent = Mathf.Min(1, faceDilate + outlineThickness);
|
||||
extent *= material.GetFloat(ID_GradientScale);
|
||||
|
||||
return new Vector4(extent, extent, extent, extent);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// Function to check if Masking is enabled
|
||||
public static bool IsMaskingEnabled(Material material)
|
||||
{
|
||||
if (material == null || !material.HasProperty(ShaderUtilities.ID_ClipRect))
|
||||
return false;
|
||||
|
||||
if (material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_SOFT) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_HARD) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_TEX))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc...
|
||||
public static float GetPadding(Material material, bool enableExtraPadding, bool isBold)
|
||||
{
|
||||
//Debug.Log("GetPadding() called.");
|
||||
|
||||
if (isInitialized == false)
|
||||
GetShaderPropertyIDs();
|
||||
|
||||
// Return if Material is null
|
||||
if (material == null) return 0;
|
||||
|
||||
int extraPadding = enableExtraPadding ? 4 : 0;
|
||||
|
||||
// Check if we are using a non Distance Field Shader
|
||||
if (material.HasProperty(ID_GradientScale) == false)
|
||||
{
|
||||
if (material.HasProperty(ID_Padding))
|
||||
extraPadding += (int)material.GetFloat(ID_Padding);
|
||||
|
||||
return extraPadding;
|
||||
}
|
||||
|
||||
Vector4 padding = Vector4.zero;
|
||||
Vector4 maxPadding = Vector4.zero;
|
||||
|
||||
//float weight = 0;
|
||||
float faceDilate = 0;
|
||||
float faceSoftness = 0;
|
||||
float outlineThickness = 0;
|
||||
float scaleRatio_A = 0;
|
||||
float scaleRatio_B = 0;
|
||||
float scaleRatio_C = 0;
|
||||
|
||||
float glowOffset = 0;
|
||||
float glowOuter = 0;
|
||||
|
||||
float uniformPadding = 0;
|
||||
// Iterate through each of the assigned materials to find the max values to set the padding.
|
||||
|
||||
// Update Shader Ratios prior to computing padding
|
||||
UpdateShaderRatios(material);
|
||||
|
||||
string[] shaderKeywords = material.shaderKeywords;
|
||||
|
||||
if (material.HasProperty(ID_ScaleRatio_A))
|
||||
scaleRatio_A = material.GetFloat(ID_ScaleRatio_A);
|
||||
|
||||
//weight = 0; // Mathf.Max(material.GetFloat(ID_WeightNormal), material.GetFloat(ID_WeightBold)) / 2.0f * scaleRatio_A;
|
||||
|
||||
if (material.HasProperty(ID_FaceDilate))
|
||||
faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatio_A;
|
||||
|
||||
if (material.HasProperty(ID_OutlineSoftness))
|
||||
faceSoftness = material.GetFloat(ID_OutlineSoftness) * scaleRatio_A;
|
||||
|
||||
if (material.HasProperty(ID_OutlineWidth))
|
||||
outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatio_A;
|
||||
|
||||
uniformPadding = outlineThickness + faceSoftness + faceDilate;
|
||||
|
||||
// Glow padding contribution
|
||||
if (material.HasProperty(ID_GlowOffset) && shaderKeywords.Contains(Keyword_Glow)) // Generates GC
|
||||
{
|
||||
if (material.HasProperty(ID_ScaleRatio_B))
|
||||
scaleRatio_B = material.GetFloat(ID_ScaleRatio_B);
|
||||
|
||||
glowOffset = material.GetFloat(ID_GlowOffset) * scaleRatio_B;
|
||||
glowOuter = material.GetFloat(ID_GlowOuter) * scaleRatio_B;
|
||||
}
|
||||
|
||||
uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter);
|
||||
|
||||
// Underlay padding contribution
|
||||
if (material.HasProperty(ID_UnderlaySoftness) && shaderKeywords.Contains(Keyword_Underlay)) // Generates GC
|
||||
{
|
||||
if (material.HasProperty(ID_ScaleRatio_C))
|
||||
scaleRatio_C = material.GetFloat(ID_ScaleRatio_C);
|
||||
|
||||
float offsetX = material.GetFloat(ID_UnderlayOffsetX) * scaleRatio_C;
|
||||
float offsetY = material.GetFloat(ID_UnderlayOffsetY) * scaleRatio_C;
|
||||
float dilate = material.GetFloat(ID_UnderlayDilate) * scaleRatio_C;
|
||||
float softness = material.GetFloat(ID_UnderlaySoftness) * scaleRatio_C;
|
||||
|
||||
padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
|
||||
padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
|
||||
padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
|
||||
padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
|
||||
}
|
||||
|
||||
padding.x = Mathf.Max(padding.x, uniformPadding);
|
||||
padding.y = Mathf.Max(padding.y, uniformPadding);
|
||||
padding.z = Mathf.Max(padding.z, uniformPadding);
|
||||
padding.w = Mathf.Max(padding.w, uniformPadding);
|
||||
|
||||
padding.x += extraPadding;
|
||||
padding.y += extraPadding;
|
||||
padding.z += extraPadding;
|
||||
padding.w += extraPadding;
|
||||
|
||||
padding.x = Mathf.Min(padding.x, 1);
|
||||
padding.y = Mathf.Min(padding.y, 1);
|
||||
padding.z = Mathf.Min(padding.z, 1);
|
||||
padding.w = Mathf.Min(padding.w, 1);
|
||||
|
||||
maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
|
||||
maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
|
||||
maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
|
||||
maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
|
||||
|
||||
float gradientScale = material.GetFloat(ID_GradientScale);
|
||||
padding *= gradientScale;
|
||||
|
||||
// Set UniformPadding to the maximum value of any of its components.
|
||||
uniformPadding = Mathf.Max(padding.x, padding.y);
|
||||
uniformPadding = Mathf.Max(padding.z, uniformPadding);
|
||||
uniformPadding = Mathf.Max(padding.w, uniformPadding);
|
||||
|
||||
return uniformPadding + 1.25f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc...
|
||||
public static float GetPadding(Material[] materials, bool enableExtraPadding, bool isBold)
|
||||
{
|
||||
//Debug.Log("GetPadding() called.");
|
||||
|
||||
if (isInitialized == false)
|
||||
GetShaderPropertyIDs();
|
||||
|
||||
// Return if Material is null
|
||||
if (materials == null) return 0;
|
||||
|
||||
int extraPadding = enableExtraPadding ? 4 : 0;
|
||||
|
||||
// Check if we are using a Bitmap Shader
|
||||
if (materials[0].HasProperty(ID_Padding))
|
||||
return extraPadding + materials[0].GetFloat(ID_Padding);
|
||||
|
||||
Vector4 padding = Vector4.zero;
|
||||
Vector4 maxPadding = Vector4.zero;
|
||||
|
||||
float faceDilate = 0;
|
||||
float faceSoftness = 0;
|
||||
float outlineThickness = 0;
|
||||
float scaleRatio_A = 0;
|
||||
float scaleRatio_B = 0;
|
||||
float scaleRatio_C = 0;
|
||||
|
||||
float glowOffset = 0;
|
||||
float glowOuter = 0;
|
||||
|
||||
float uniformPadding = 0;
|
||||
// Iterate through each of the assigned materials to find the max values to set the padding.
|
||||
for (int i = 0; i < materials.Length; i++)
|
||||
{
|
||||
// Update Shader Ratios prior to computing padding
|
||||
ShaderUtilities.UpdateShaderRatios(materials[i]);
|
||||
|
||||
string[] shaderKeywords = materials[i].shaderKeywords;
|
||||
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_A))
|
||||
scaleRatio_A = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_A);
|
||||
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_FaceDilate))
|
||||
faceDilate = materials[i].GetFloat(ShaderUtilities.ID_FaceDilate) * scaleRatio_A;
|
||||
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_OutlineSoftness))
|
||||
faceSoftness = materials[i].GetFloat(ShaderUtilities.ID_OutlineSoftness) * scaleRatio_A;
|
||||
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_OutlineWidth))
|
||||
outlineThickness = materials[i].GetFloat(ShaderUtilities.ID_OutlineWidth) * scaleRatio_A;
|
||||
|
||||
uniformPadding = outlineThickness + faceSoftness + faceDilate;
|
||||
|
||||
// Glow padding contribution
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_GlowOffset) && shaderKeywords.Contains(ShaderUtilities.Keyword_Glow))
|
||||
{
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_B))
|
||||
scaleRatio_B = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_B);
|
||||
|
||||
glowOffset = materials[i].GetFloat(ShaderUtilities.ID_GlowOffset) * scaleRatio_B;
|
||||
glowOuter = materials[i].GetFloat(ShaderUtilities.ID_GlowOuter) * scaleRatio_B;
|
||||
}
|
||||
|
||||
uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter);
|
||||
|
||||
// Underlay padding contribution
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_UnderlaySoftness) && shaderKeywords.Contains(ShaderUtilities.Keyword_Underlay))
|
||||
{
|
||||
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_C))
|
||||
scaleRatio_C = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_C);
|
||||
|
||||
float offsetX = materials[i].GetFloat(ShaderUtilities.ID_UnderlayOffsetX) * scaleRatio_C;
|
||||
float offsetY = materials[i].GetFloat(ShaderUtilities.ID_UnderlayOffsetY) * scaleRatio_C;
|
||||
float dilate = materials[i].GetFloat(ShaderUtilities.ID_UnderlayDilate) * scaleRatio_C;
|
||||
float softness = materials[i].GetFloat(ShaderUtilities.ID_UnderlaySoftness) * scaleRatio_C;
|
||||
|
||||
padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
|
||||
padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
|
||||
padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
|
||||
padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
|
||||
}
|
||||
|
||||
padding.x = Mathf.Max(padding.x, uniformPadding);
|
||||
padding.y = Mathf.Max(padding.y, uniformPadding);
|
||||
padding.z = Mathf.Max(padding.z, uniformPadding);
|
||||
padding.w = Mathf.Max(padding.w, uniformPadding);
|
||||
|
||||
padding.x += extraPadding;
|
||||
padding.y += extraPadding;
|
||||
padding.z += extraPadding;
|
||||
padding.w += extraPadding;
|
||||
|
||||
padding.x = Mathf.Min(padding.x, 1);
|
||||
padding.y = Mathf.Min(padding.y, 1);
|
||||
padding.z = Mathf.Min(padding.z, 1);
|
||||
padding.w = Mathf.Min(padding.w, 1);
|
||||
|
||||
maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
|
||||
maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
|
||||
maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
|
||||
maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
|
||||
|
||||
}
|
||||
|
||||
float gradientScale = materials[0].GetFloat(ShaderUtilities.ID_GradientScale);
|
||||
padding *= gradientScale;
|
||||
|
||||
// Set UniformPadding to the maximum value of any of its components.
|
||||
uniformPadding = Mathf.Max(padding.x, padding.y);
|
||||
uniformPadding = Mathf.Max(padding.z, uniformPadding);
|
||||
uniformPadding = Mathf.Max(padding.w, uniformPadding);
|
||||
|
||||
return uniformPadding + 0.25f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fea49a0730244a98bf1087f7ca9410a8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
// Class which contains the Sprite Info for each sprite contained in the sprite asset.
|
||||
[Serializable]
|
||||
public class TMP_Sprite : TMP_TextElement_Legacy
|
||||
{
|
||||
//public int fileID;
|
||||
//public int id;
|
||||
public string name;
|
||||
public int hashCode;
|
||||
public int unicode;
|
||||
//public float x;
|
||||
//public float y;
|
||||
//public float width;
|
||||
//public float height;
|
||||
public Vector2 pivot;
|
||||
//public float xOffset; // Pivot X
|
||||
//public float yOffset; // Pivot Y
|
||||
//public float xAdvance;
|
||||
//public float scale;
|
||||
|
||||
public Sprite sprite;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 968a09f153574430a6e15ae975145768
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,149 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public class TMP_SpriteAnimator : MonoBehaviour
|
||||
{
|
||||
private Dictionary<int, bool> m_animations = new Dictionary<int, bool>(16);
|
||||
//private bool isPlaying = false;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
m_TextComponent = GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
//m_playAnimations = true;
|
||||
}
|
||||
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
//m_playAnimations = false;
|
||||
}
|
||||
|
||||
|
||||
public void StopAllAnimations()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
m_animations.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void DoSpriteAnimation(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
|
||||
{
|
||||
bool isPlaying;
|
||||
|
||||
// Need to add tracking of coroutines that have been lunched for this text object.
|
||||
if (!m_animations.TryGetValue(currentCharacter, out isPlaying))
|
||||
{
|
||||
StartCoroutine(DoSpriteAnimationInternal(currentCharacter, spriteAsset, start, end, framerate));
|
||||
m_animations.Add(currentCharacter, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IEnumerator DoSpriteAnimationInternal(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
|
||||
{
|
||||
if (m_TextComponent == null) yield break;
|
||||
|
||||
// We yield otherwise this gets called before the sprite has rendered.
|
||||
yield return null;
|
||||
|
||||
int currentFrame = start;
|
||||
|
||||
// Make sure end frame does not exceed the number of sprites in the sprite asset.
|
||||
if (end > spriteAsset.spriteCharacterTable.Count)
|
||||
end = spriteAsset.spriteCharacterTable.Count - 1;
|
||||
|
||||
// Get a reference to the geometry of the current character.
|
||||
TMP_CharacterInfo charInfo = m_TextComponent.textInfo.characterInfo[currentCharacter];
|
||||
|
||||
int materialIndex = charInfo.materialReferenceIndex;
|
||||
int vertexIndex = charInfo.vertexIndex;
|
||||
|
||||
TMP_MeshInfo meshInfo = m_TextComponent.textInfo.meshInfo[materialIndex];
|
||||
|
||||
float elapsedTime = 0;
|
||||
float targetTime = 1f / Mathf.Abs(framerate);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (elapsedTime > targetTime)
|
||||
{
|
||||
elapsedTime = 0;
|
||||
|
||||
// Get a reference to the current sprite
|
||||
TMP_SpriteCharacter spriteCharacter = spriteAsset.spriteCharacterTable[currentFrame];
|
||||
|
||||
// Update the vertices for the new sprite
|
||||
Vector3[] vertices = meshInfo.vertices;
|
||||
|
||||
Vector2 origin = new Vector2(charInfo.origin, charInfo.baseLine);
|
||||
float spriteScale = charInfo.fontAsset.faceInfo.ascentLine / spriteCharacter.glyph.metrics.height * spriteCharacter.scale * charInfo.scale;
|
||||
|
||||
Vector3 bl = new Vector3(origin.x + spriteCharacter.glyph.metrics.horizontalBearingX * spriteScale, origin.y + (spriteCharacter.glyph.metrics.horizontalBearingY - spriteCharacter.glyph.metrics.height) * spriteScale);
|
||||
Vector3 tl = new Vector3(bl.x, origin.y + spriteCharacter.glyph.metrics.horizontalBearingY * spriteScale);
|
||||
Vector3 tr = new Vector3(origin.x + (spriteCharacter.glyph.metrics.horizontalBearingX + spriteCharacter.glyph.metrics.width) * spriteScale, tl.y);
|
||||
Vector3 br = new Vector3(tr.x, bl.y);
|
||||
|
||||
vertices[vertexIndex + 0] = bl;
|
||||
vertices[vertexIndex + 1] = tl;
|
||||
vertices[vertexIndex + 2] = tr;
|
||||
vertices[vertexIndex + 3] = br;
|
||||
|
||||
// Update the UV to point to the new sprite
|
||||
Vector2[] uvs0 = meshInfo.uvs0;
|
||||
|
||||
Vector2 uv0 = new Vector2((float)spriteCharacter.glyph.glyphRect.x / spriteAsset.spriteSheet.width, (float)spriteCharacter.glyph.glyphRect.y / spriteAsset.spriteSheet.height);
|
||||
Vector2 uv1 = new Vector2(uv0.x, (float)(spriteCharacter.glyph.glyphRect.y + spriteCharacter.glyph.glyphRect.height) / spriteAsset.spriteSheet.height);
|
||||
Vector2 uv2 = new Vector2((float)(spriteCharacter.glyph.glyphRect.x + spriteCharacter.glyph.glyphRect.width) / spriteAsset.spriteSheet.width, uv1.y);
|
||||
Vector2 uv3 = new Vector2(uv2.x, uv0.y);
|
||||
|
||||
uvs0[vertexIndex + 0] = uv0;
|
||||
uvs0[vertexIndex + 1] = uv1;
|
||||
uvs0[vertexIndex + 2] = uv2;
|
||||
uvs0[vertexIndex + 3] = uv3;
|
||||
|
||||
// Update the modified vertex attributes
|
||||
meshInfo.mesh.vertices = vertices;
|
||||
meshInfo.mesh.uv = uvs0;
|
||||
m_TextComponent.UpdateGeometry(meshInfo.mesh, materialIndex);
|
||||
|
||||
|
||||
if (framerate > 0)
|
||||
{
|
||||
if (currentFrame < end)
|
||||
currentFrame += 1;
|
||||
else
|
||||
currentFrame = start;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentFrame > start)
|
||||
currentFrame -= 1;
|
||||
else
|
||||
currentFrame = end;
|
||||
}
|
||||
}
|
||||
|
||||
elapsedTime += Time.deltaTime;
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6366ee97f6b541449155028b9487355a
|
||||
timeCreated: 1471590333
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,508 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public class TMP_SpriteAsset : TMP_Asset
|
||||
{
|
||||
internal Dictionary<uint, int> m_UnicodeLookup;
|
||||
internal Dictionary<int, int> m_NameLookup;
|
||||
internal Dictionary<uint, int> m_GlyphIndexLookup;
|
||||
|
||||
/// <summary>
|
||||
/// The version of the sprite asset class.
|
||||
/// Version 1.1.0 updates the asset data structure to be compatible with new font asset structure.
|
||||
/// </summary>
|
||||
public string version
|
||||
{
|
||||
get { return m_Version; }
|
||||
internal set { m_Version = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private string m_Version;
|
||||
|
||||
// The texture which contains the sprites.
|
||||
public Texture spriteSheet;
|
||||
|
||||
public List<TMP_SpriteCharacter> spriteCharacterTable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_GlyphIndexLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
return m_SpriteCharacterTable;
|
||||
}
|
||||
internal set { m_SpriteCharacterTable = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private List<TMP_SpriteCharacter> m_SpriteCharacterTable = new List<TMP_SpriteCharacter>();
|
||||
|
||||
|
||||
public List<TMP_SpriteGlyph> spriteGlyphTable
|
||||
{
|
||||
get { return m_SpriteGlyphTable; }
|
||||
internal set { m_SpriteGlyphTable = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private List<TMP_SpriteGlyph> m_SpriteGlyphTable = new List<TMP_SpriteGlyph>();
|
||||
|
||||
// List which contains the SpriteInfo for the sprites contained in the sprite sheet.
|
||||
public List<TMP_Sprite> spriteInfoList;
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary used to lookup the index of a given sprite based on a Unicode value.
|
||||
/// </summary>
|
||||
//private Dictionary<int, int> m_SpriteUnicodeLookup;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// List which contains the Fallback font assets for this font.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public List<TMP_SpriteAsset> fallbackSpriteAssets;
|
||||
|
||||
internal bool m_IsSpriteAssetLookupTablesDirty = false;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
// Check version number of sprite asset to see if it needs to be upgraded.
|
||||
if (this.material != null && string.IsNullOrEmpty(m_Version))
|
||||
UpgradeSpriteAsset();
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void OnValidate()
|
||||
{
|
||||
//Debug.Log("Sprite Asset [" + name + "] has changed.");
|
||||
|
||||
//UpdateLookupTables();
|
||||
|
||||
//TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a material for the sprite asset.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material GetDefaultSpriteMaterial()
|
||||
{
|
||||
//isEditingAsset = true;
|
||||
ShaderUtilities.GetShaderPropertyIDs();
|
||||
|
||||
// Add a new material
|
||||
Shader shader = Shader.Find("TextMeshPro/Sprite");
|
||||
Material tempMaterial = new Material(shader);
|
||||
tempMaterial.SetTexture(ShaderUtilities.ID_MainTex, spriteSheet);
|
||||
tempMaterial.hideFlags = HideFlags.HideInHierarchy;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.AssetDatabase.AddObjectToAsset(tempMaterial, this);
|
||||
UnityEditor.AssetDatabase.ImportAsset(UnityEditor.AssetDatabase.GetAssetPath(this));
|
||||
#endif
|
||||
//isEditingAsset = false;
|
||||
|
||||
return tempMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the sprite name and unicode lookup tables.
|
||||
/// This function should be called when a sprite's name or unicode value changes or when a new sprite is added.
|
||||
/// </summary>
|
||||
public void UpdateLookupTables()
|
||||
{
|
||||
//Debug.Log("Updating [" + this.name + "] Lookup tables.");
|
||||
|
||||
// Check version number of sprite asset to see if it needs to be upgraded.
|
||||
if (this.material != null && string.IsNullOrEmpty(m_Version))
|
||||
UpgradeSpriteAsset();
|
||||
|
||||
// Initialize / Clear glyph index lookup dictionary.
|
||||
if (m_GlyphIndexLookup == null)
|
||||
m_GlyphIndexLookup = new Dictionary<uint, int>();
|
||||
else
|
||||
m_GlyphIndexLookup.Clear();
|
||||
|
||||
for (int i = 0; i < m_SpriteGlyphTable.Count; i++)
|
||||
{
|
||||
uint glyphIndex = m_SpriteGlyphTable[i].index;
|
||||
|
||||
if (m_GlyphIndexLookup.ContainsKey(glyphIndex) == false)
|
||||
m_GlyphIndexLookup.Add(glyphIndex, i);
|
||||
}
|
||||
|
||||
if (m_NameLookup == null)
|
||||
m_NameLookup = new Dictionary<int, int>();
|
||||
else
|
||||
m_NameLookup.Clear();
|
||||
|
||||
if (m_UnicodeLookup == null)
|
||||
m_UnicodeLookup = new Dictionary<uint, int>();
|
||||
else
|
||||
m_UnicodeLookup.Clear();
|
||||
|
||||
for (int i = 0; i < m_SpriteCharacterTable.Count; i++)
|
||||
{
|
||||
int nameHashCode = m_SpriteCharacterTable[i].hashCode;
|
||||
|
||||
if (m_NameLookup.ContainsKey(nameHashCode) == false)
|
||||
m_NameLookup.Add(nameHashCode, i);
|
||||
|
||||
uint unicode = m_SpriteCharacterTable[i].unicode;
|
||||
|
||||
if (m_UnicodeLookup.ContainsKey(unicode) == false)
|
||||
m_UnicodeLookup.Add(unicode, i);
|
||||
|
||||
// Update glyph reference which is not serialized
|
||||
uint glyphIndex = m_SpriteCharacterTable[i].glyphIndex;
|
||||
int index;
|
||||
|
||||
if (m_GlyphIndexLookup.TryGetValue(glyphIndex, out index))
|
||||
m_SpriteCharacterTable[i].glyph = m_SpriteGlyphTable[index];
|
||||
}
|
||||
|
||||
m_IsSpriteAssetLookupTablesDirty = false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function which returns the sprite index using the hashcode of the name
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <returns></returns>
|
||||
public int GetSpriteIndexFromHashcode(int hashCode)
|
||||
{
|
||||
if (m_NameLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
int index;
|
||||
|
||||
if (m_NameLookup.TryGetValue(hashCode, out index))
|
||||
return index;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the sprite for the given unicode value.
|
||||
/// </summary>
|
||||
/// <param name="unicode"></param>
|
||||
/// <returns></returns>
|
||||
public int GetSpriteIndexFromUnicode (uint unicode)
|
||||
{
|
||||
if (m_UnicodeLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
int index;
|
||||
|
||||
if (m_UnicodeLookup.TryGetValue(unicode, out index))
|
||||
return index;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the sprite for the given name.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public int GetSpriteIndexFromName (string name)
|
||||
{
|
||||
if (m_NameLookup == null)
|
||||
UpdateLookupTables();
|
||||
|
||||
int hashCode = TMP_TextUtilities.GetSimpleHashCode(name);
|
||||
|
||||
return GetSpriteIndexFromHashcode(hashCode);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used to keep track of which Sprite Assets have been searched.
|
||||
/// </summary>
|
||||
private static List<int> k_searchedSpriteAssets;
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given sprite asset and its fallbacks for the specified sprite matching the given unicode character.
|
||||
/// </summary>
|
||||
/// <param name="spriteAsset">The font asset to search for the given character.</param>
|
||||
/// <param name="unicode">The character to find.</param>
|
||||
/// <param name="glyph">out parameter containing the glyph for the specified character (if found).</param>
|
||||
/// <returns></returns>
|
||||
public static TMP_SpriteAsset SearchForSpriteByUnicode(TMP_SpriteAsset spriteAsset, uint unicode, bool includeFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Check to make sure sprite asset is not null
|
||||
if (spriteAsset == null) { spriteIndex = -1; return null; }
|
||||
|
||||
// Get sprite index for the given unicode
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromUnicode(unicode);
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
// Initialize list to track instance of Sprite Assets that have already been searched.
|
||||
if (k_searchedSpriteAssets == null)
|
||||
k_searchedSpriteAssets = new List<int>();
|
||||
|
||||
k_searchedSpriteAssets.Clear();
|
||||
|
||||
// Get instance ID of sprite asset and add to list.
|
||||
int id = spriteAsset.GetInstanceID();
|
||||
k_searchedSpriteAssets.Add(id);
|
||||
|
||||
// Search potential fallback sprite assets if includeFallbacks is true.
|
||||
if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
return SearchForSpriteByUnicodeInternal(spriteAsset.fallbackSpriteAssets, unicode, includeFallbacks, out spriteIndex);
|
||||
|
||||
// Search default sprite asset potentially assigned in the TMP Settings.
|
||||
if (includeFallbacks && TMP_Settings.defaultSpriteAsset != null)
|
||||
return SearchForSpriteByUnicodeInternal(TMP_Settings.defaultSpriteAsset, unicode, includeFallbacks, out spriteIndex);
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given list of sprite assets and fallbacks for a sprite whose unicode value matches the target unicode.
|
||||
/// </summary>
|
||||
/// <param name="spriteAssets"></param>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="includeFallbacks"></param>
|
||||
/// <param name="spriteIndex"></param>
|
||||
/// <returns></returns>
|
||||
private static TMP_SpriteAsset SearchForSpriteByUnicodeInternal(List<TMP_SpriteAsset> spriteAssets, uint unicode, bool includeFallbacks, out int spriteIndex)
|
||||
{
|
||||
for (int i = 0; i < spriteAssets.Count; i++)
|
||||
{
|
||||
TMP_SpriteAsset temp = spriteAssets[i];
|
||||
if (temp == null) continue;
|
||||
|
||||
int id = temp.GetInstanceID();
|
||||
|
||||
// Skip over the fallback sprite asset if it has already been searched.
|
||||
if (k_searchedSpriteAssets.Contains(id)) continue;
|
||||
|
||||
// Add to list of font assets already searched.
|
||||
k_searchedSpriteAssets.Add(id);
|
||||
|
||||
temp = SearchForSpriteByUnicodeInternal(temp, unicode, includeFallbacks, out spriteIndex);
|
||||
|
||||
if (temp != null)
|
||||
return temp;
|
||||
}
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search the given sprite asset and fallbacks for a sprite whose unicode value matches the target unicode.
|
||||
/// </summary>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="unicode"></param>
|
||||
/// <param name="includeFallbacks"></param>
|
||||
/// <param name="spriteIndex"></param>
|
||||
/// <returns></returns>
|
||||
private static TMP_SpriteAsset SearchForSpriteByUnicodeInternal(TMP_SpriteAsset spriteAsset, uint unicode, bool includeFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Get sprite index for the given unicode
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromUnicode(unicode);
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
return SearchForSpriteByUnicodeInternal(spriteAsset.fallbackSpriteAssets, unicode, includeFallbacks, out spriteIndex);
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search the given sprite asset and fallbacks for a sprite whose hash code value of its name matches the target hash code.
|
||||
/// </summary>
|
||||
/// <param name="spriteAsset">The Sprite Asset to search for the given sprite whose name matches the hashcode value</param>
|
||||
/// <param name="hashCode">The hash code value matching the name of the sprite</param>
|
||||
/// <param name="includeFallbacks">Include fallback sprite assets in the search</param>
|
||||
/// <param name="spriteIndex">The index of the sprite matching the provided hash code</param>
|
||||
/// <returns>The Sprite Asset that contains the sprite</returns>
|
||||
public static TMP_SpriteAsset SearchForSpriteByHashCode(TMP_SpriteAsset spriteAsset, int hashCode, bool includeFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Make sure sprite asset is not null
|
||||
if (spriteAsset == null) { spriteIndex = -1; return null; }
|
||||
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromHashcode(hashCode);
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
// Initialize list to track instance of Sprite Assets that have already been searched.
|
||||
if (k_searchedSpriteAssets == null)
|
||||
k_searchedSpriteAssets = new List<int>();
|
||||
|
||||
k_searchedSpriteAssets.Clear();
|
||||
|
||||
int id = spriteAsset.GetInstanceID();
|
||||
// Add to list of font assets already searched.
|
||||
k_searchedSpriteAssets.Add(id);
|
||||
|
||||
if (includeFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
return SearchForSpriteByHashCodeInternal(spriteAsset.fallbackSpriteAssets, hashCode, includeFallbacks, out spriteIndex);
|
||||
|
||||
// Search default sprite asset potentially assigned in the TMP Settings.
|
||||
if (includeFallbacks && TMP_Settings.defaultSpriteAsset != null)
|
||||
return SearchForSpriteByHashCodeInternal(TMP_Settings.defaultSpriteAsset, hashCode, includeFallbacks, out spriteIndex);
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given list of sprite assets and fallbacks for a sprite whose hash code value of its name matches the target hash code.
|
||||
/// </summary>
|
||||
/// <param name="spriteAssets"></param>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="searchFallbacks"></param>
|
||||
/// <param name="spriteIndex"></param>
|
||||
/// <returns></returns>
|
||||
private static TMP_SpriteAsset SearchForSpriteByHashCodeInternal(List<TMP_SpriteAsset> spriteAssets, int hashCode, bool searchFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Search through the list of sprite assets
|
||||
for (int i = 0; i < spriteAssets.Count; i++)
|
||||
{
|
||||
TMP_SpriteAsset temp = spriteAssets[i];
|
||||
if (temp == null) continue;
|
||||
|
||||
int id = temp.GetInstanceID();
|
||||
|
||||
// Skip over the fallback sprite asset if it has already been searched.
|
||||
if (k_searchedSpriteAssets.Contains(id)) continue;
|
||||
|
||||
// Add to list of font assets already searched.
|
||||
k_searchedSpriteAssets.Add(id);
|
||||
|
||||
temp = SearchForSpriteByHashCodeInternal(temp, hashCode, searchFallbacks, out spriteIndex);
|
||||
|
||||
if (temp != null)
|
||||
return temp;
|
||||
}
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Search through the given sprite asset and fallbacks for a sprite whose hash code value of its name matches the target hash code.
|
||||
/// </summary>
|
||||
/// <param name="spriteAsset"></param>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <param name="searchFallbacks"></param>
|
||||
/// <param name="spriteIndex"></param>
|
||||
/// <returns></returns>
|
||||
private static TMP_SpriteAsset SearchForSpriteByHashCodeInternal(TMP_SpriteAsset spriteAsset, int hashCode, bool searchFallbacks, out int spriteIndex)
|
||||
{
|
||||
// Get the sprite for the given hash code.
|
||||
spriteIndex = spriteAsset.GetSpriteIndexFromHashcode(hashCode);
|
||||
if (spriteIndex != -1)
|
||||
return spriteAsset;
|
||||
|
||||
if (searchFallbacks && spriteAsset.fallbackSpriteAssets != null && spriteAsset.fallbackSpriteAssets.Count > 0)
|
||||
return SearchForSpriteByHashCodeInternal(spriteAsset.fallbackSpriteAssets, hashCode, searchFallbacks, out spriteIndex);
|
||||
|
||||
spriteIndex = -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sort the sprite glyph table by glyph index.
|
||||
/// </summary>
|
||||
public void SortGlyphTable()
|
||||
{
|
||||
if (m_SpriteGlyphTable == null || m_SpriteGlyphTable.Count == 0) return;
|
||||
|
||||
m_SpriteGlyphTable = m_SpriteGlyphTable.OrderBy(item => item.index).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort the sprite character table by Unicode values.
|
||||
/// </summary>
|
||||
internal void SortCharacterTable()
|
||||
{
|
||||
if (m_SpriteCharacterTable != null && m_SpriteCharacterTable.Count > 0)
|
||||
m_SpriteCharacterTable = m_SpriteCharacterTable.OrderBy(c => c.unicode).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort both sprite glyph and character tables.
|
||||
/// </summary>
|
||||
internal void SortGlyphAndCharacterTables()
|
||||
{
|
||||
SortGlyphTable();
|
||||
SortCharacterTable();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Internal method used to upgrade sprite asset.
|
||||
/// </summary>
|
||||
private void UpgradeSpriteAsset()
|
||||
{
|
||||
m_Version = "1.1.0";
|
||||
|
||||
Debug.Log("Upgrading sprite asset [" + this.name + "] to version " + m_Version + ".", this);
|
||||
|
||||
// Convert legacy glyph and character tables to new format
|
||||
m_SpriteCharacterTable.Clear();
|
||||
m_SpriteGlyphTable.Clear();
|
||||
|
||||
for (int i = 0; i < spriteInfoList.Count; i++)
|
||||
{
|
||||
TMP_Sprite oldSprite = spriteInfoList[i];
|
||||
|
||||
TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
|
||||
spriteGlyph.index = (uint)i;
|
||||
spriteGlyph.sprite = oldSprite.sprite;
|
||||
spriteGlyph.metrics = new GlyphMetrics(oldSprite.width, oldSprite.height, oldSprite.xOffset, oldSprite.yOffset, oldSprite.xAdvance);
|
||||
spriteGlyph.glyphRect = new GlyphRect((int)oldSprite.x, (int)oldSprite.y, (int)oldSprite.width, (int)oldSprite.height);
|
||||
|
||||
spriteGlyph.scale = 1.0f;
|
||||
spriteGlyph.atlasIndex = 0;
|
||||
|
||||
m_SpriteGlyphTable.Add(spriteGlyph);
|
||||
|
||||
TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter((uint)oldSprite.unicode, spriteGlyph);
|
||||
spriteCharacter.name = oldSprite.name;
|
||||
spriteCharacter.scale = oldSprite.scale;
|
||||
|
||||
m_SpriteCharacterTable.Add(spriteCharacter);
|
||||
}
|
||||
|
||||
// Clear legacy glyph info list.
|
||||
//spriteInfoList.Clear();
|
||||
|
||||
UpdateLookupTables();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 84a92b25f83d49b9bc132d206b370281
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: ec7c645d93308c04d8840982af12101e, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,61 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro.SpriteAssetUtilities
|
||||
{
|
||||
public enum SpriteAssetImportFormats { None = 0, TexturePacker = 0x1 };
|
||||
|
||||
public class TexturePacker
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct SpriteFrame
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float w;
|
||||
public float h;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string s = "x: " + x.ToString("f2") + " y: " + y.ToString("f2") + " h: " + h.ToString("f2") + " w: " + w.ToString("f2");
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct SpriteSize
|
||||
{
|
||||
public float w;
|
||||
public float h;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string s = "w: " + w.ToString("f2") + " h: " + h.ToString("f2");
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct SpriteData
|
||||
{
|
||||
public string filename;
|
||||
public SpriteFrame frame;
|
||||
public bool rotated;
|
||||
public bool trimmed;
|
||||
public SpriteFrame spriteSourceSize;
|
||||
public SpriteSize sourceSize;
|
||||
public Vector2 pivot;
|
||||
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class SpriteDataObject
|
||||
{
|
||||
public List<SpriteData> frames;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e4e0b1de1aee400d81ed4273141e7823
|
||||
timeCreated: 1480042510
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// A basic element of text representing a pictograph, image, sprite or emoji.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_SpriteCharacter : TMP_TextElement
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the sprite element.
|
||||
/// </summary>
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
set
|
||||
{
|
||||
if (value == m_Name)
|
||||
return;
|
||||
|
||||
m_Name = value;
|
||||
m_HashCode = TMP_TextParsingUtilities.GetHashCodeCaseSensitive(m_Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The hashcode value which is computed from the name of the sprite element.
|
||||
/// This value is read-only and updated when the name of the text sprite is changed.
|
||||
/// </summary>
|
||||
public int hashCode { get { return m_HashCode; } }
|
||||
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
private string m_Name;
|
||||
|
||||
[SerializeField]
|
||||
private int m_HashCode;
|
||||
|
||||
|
||||
// ********************
|
||||
// CONSTRUCTORS
|
||||
// ********************
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
public TMP_SpriteCharacter()
|
||||
{
|
||||
m_ElementType = TextElementType.Sprite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new sprite character.
|
||||
/// </summary>
|
||||
/// <param name="unicode">Unicode value of the sprite character.</param>
|
||||
/// <param name="glyph">Glyph used by the sprite character.</param>
|
||||
public TMP_SpriteCharacter(uint unicode, TMP_SpriteGlyph glyph)
|
||||
{
|
||||
m_ElementType = TextElementType.Sprite;
|
||||
|
||||
this.unicode = unicode;
|
||||
this.glyphIndex = glyph.index;
|
||||
this.glyph = glyph;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 202d758d102b6854a9710c8b93db742c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// The visual representation of the sprite character using this glyph.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_SpriteGlyph : Glyph
|
||||
{
|
||||
/// <summary>
|
||||
/// An optional reference to the underlying sprite used to create this glyph.
|
||||
/// </summary>
|
||||
public Sprite sprite;
|
||||
|
||||
|
||||
// ********************
|
||||
// CONSTRUCTORS
|
||||
// ********************
|
||||
|
||||
public TMP_SpriteGlyph() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new sprite glyph.
|
||||
/// </summary>
|
||||
/// <param name="index">Index of the sprite glyph.</param>
|
||||
/// <param name="metrics">Metrics which define the position of the glyph in the context of text layout.</param>
|
||||
/// <param name="glyphRect">GlyphRect which defines the coordinates of the glyph in the atlas texture.</param>
|
||||
/// <param name="scale">Scale of the glyph.</param>
|
||||
/// <param name="atlasIndex">Index of the atlas texture that contains the glyph.</param>
|
||||
public TMP_SpriteGlyph(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex)
|
||||
{
|
||||
this.index = index;
|
||||
this.metrics = metrics;
|
||||
this.glyphRect = glyphRect;
|
||||
this.scale = scale;
|
||||
this.atlasIndex = atlasIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for new sprite glyph.
|
||||
/// </summary>
|
||||
/// <param name="index">>Index of the sprite glyph.</param>
|
||||
/// <param name="metrics">Metrics which define the position of the glyph in the context of text layout.</param>
|
||||
/// <param name="glyphRect">GlyphRect which defines the coordinates of the glyph in the atlas texture.</param>
|
||||
/// <param name="scale">Scale of the glyph.</param>
|
||||
/// <param name="atlasIndex">Index of the atlas texture that contains the glyph.</param>
|
||||
/// <param name="sprite">A reference to the Unity Sprite representing this sprite glyph.</param>
|
||||
public TMP_SpriteGlyph(uint index, GlyphMetrics metrics, GlyphRect glyphRect, float scale, int atlasIndex, Sprite sprite)
|
||||
{
|
||||
this.index = index;
|
||||
this.metrics = metrics;
|
||||
this.glyphRect = glyphRect;
|
||||
this.scale = scale;
|
||||
this.atlasIndex = atlasIndex;
|
||||
this.sprite = sprite;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5b5c6a576605b3c4aab7d27193785f27
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,95 @@
|
|||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
#pragma warning disable 0649 // Disabled warnings.
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
[System.Serializable]
|
||||
public class TMP_Style
|
||||
{
|
||||
// PUBLIC PROPERTIES
|
||||
|
||||
/// <summary>
|
||||
/// The name identifying this style. ex. <style="name">.
|
||||
/// </summary>
|
||||
public string name
|
||||
{ get { return m_Name; } set { if (value != m_Name) m_Name = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The hash code corresponding to the name of this style.
|
||||
/// </summary>
|
||||
public int hashCode
|
||||
{ get { return m_HashCode; } set { if (value != m_HashCode) m_HashCode = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The initial definition of the style. ex. <b> <u>.
|
||||
/// </summary>
|
||||
public string styleOpeningDefinition
|
||||
{ get { return m_OpeningDefinition; } }
|
||||
|
||||
/// <summary>
|
||||
/// The closing definition of the style. ex. </b> </u>.
|
||||
/// </summary>
|
||||
public string styleClosingDefinition
|
||||
{ get { return m_ClosingDefinition; } }
|
||||
|
||||
|
||||
public int[] styleOpeningTagArray
|
||||
{ get { return m_OpeningTagArray; } }
|
||||
|
||||
|
||||
public int[] styleClosingTagArray
|
||||
{ get { return m_ClosingTagArray; } }
|
||||
|
||||
|
||||
// PRIVATE FIELDS
|
||||
[SerializeField]
|
||||
private string m_Name;
|
||||
|
||||
[SerializeField]
|
||||
private int m_HashCode;
|
||||
|
||||
[SerializeField]
|
||||
private string m_OpeningDefinition;
|
||||
|
||||
[SerializeField]
|
||||
private string m_ClosingDefinition;
|
||||
|
||||
[SerializeField]
|
||||
private int[] m_OpeningTagArray;
|
||||
|
||||
[SerializeField]
|
||||
private int[] m_ClosingTagArray;
|
||||
|
||||
|
||||
//public TMP_Style()
|
||||
//{
|
||||
//Debug.Log("New Style with Name: " + m_Name + " was created. ID: ");
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the content of the int[] resulting from changes to OpeningDefinition & ClosingDefinition.
|
||||
/// </summary>
|
||||
public void RefreshStyle()
|
||||
{
|
||||
m_HashCode = TMP_TextUtilities.GetSimpleHashCode(m_Name);
|
||||
|
||||
m_OpeningTagArray = new int[m_OpeningDefinition.Length];
|
||||
for (int i = 0; i < m_OpeningDefinition.Length; i++)
|
||||
m_OpeningTagArray[i] = m_OpeningDefinition[i];
|
||||
|
||||
m_ClosingTagArray = new int[m_ClosingDefinition.Length];
|
||||
for (int i = 0; i < m_ClosingDefinition.Length; i++)
|
||||
m_ClosingTagArray[i] = m_ClosingDefinition[i];
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Event to update objects when styles are changed in the editor.
|
||||
TMPro_EventManager.ON_TEXT_STYLE_PROPERTY_CHANGED(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 30bed781e402439ab8ce4e3357708115
|
||||
timeCreated: 1432681409
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,133 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
public class TMP_StyleSheet : ScriptableObject
|
||||
{
|
||||
private static TMP_StyleSheet s_Instance;
|
||||
|
||||
[SerializeField]
|
||||
private List<TMP_Style> m_StyleList = new List<TMP_Style>(1);
|
||||
private Dictionary<int, TMP_Style> m_StyleDictionary = new Dictionary<int, TMP_Style>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the TMP_StyleSheet
|
||||
/// </summary>
|
||||
public static TMP_StyleSheet instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_Instance == null)
|
||||
{
|
||||
s_Instance = TMP_Settings.defaultStyleSheet;
|
||||
|
||||
if (s_Instance == null)
|
||||
s_Instance = Resources.Load<TMP_StyleSheet>("Style Sheets/Default Style Sheet");
|
||||
|
||||
if (s_Instance == null) return null;
|
||||
|
||||
// Load the style dictionary.
|
||||
s_Instance.LoadStyleDictionaryInternal();
|
||||
}
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Static Function to load the Default Style Sheet.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TMP_StyleSheet LoadDefaultStyleSheet()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to retrieve the Style matching the HashCode.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <returns></returns>
|
||||
public static TMP_Style GetStyle(int hashCode)
|
||||
{
|
||||
return instance.GetStyleInternal(hashCode);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Internal method to retrieve the Style matching the Hashcode.
|
||||
/// </summary>
|
||||
/// <param name="hashCode"></param>
|
||||
/// <returns></returns>
|
||||
private TMP_Style GetStyleInternal(int hashCode)
|
||||
{
|
||||
TMP_Style style;
|
||||
|
||||
if (m_StyleDictionary.TryGetValue(hashCode, out style))
|
||||
{
|
||||
return style;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void UpdateStyleDictionaryKey(int old_key, int new_key)
|
||||
{
|
||||
if (m_StyleDictionary.ContainsKey(old_key))
|
||||
{
|
||||
TMP_Style style = m_StyleDictionary[old_key];
|
||||
m_StyleDictionary.Add(new_key, style);
|
||||
m_StyleDictionary.Remove(old_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the internal reference to a newly assigned style sheet in the TMP Settings.
|
||||
/// </summary>
|
||||
public static void UpdateStyleSheet()
|
||||
{
|
||||
// Reset instance
|
||||
s_Instance = null;
|
||||
|
||||
RefreshStyles();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to refresh the Style Dictionary.
|
||||
/// </summary>
|
||||
public static void RefreshStyles()
|
||||
{
|
||||
instance.LoadStyleDictionaryInternal();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void LoadStyleDictionaryInternal()
|
||||
{
|
||||
m_StyleDictionary.Clear();
|
||||
|
||||
// Read Styles from style list and store them into dictionary for faster access.
|
||||
for (int i = 0; i < m_StyleList.Count; i++)
|
||||
{
|
||||
m_StyleList[i].RefreshStyle();
|
||||
|
||||
if (!m_StyleDictionary.ContainsKey(m_StyleList[i].hashCode))
|
||||
m_StyleDictionary.Add(m_StyleList[i].hashCode, m_StyleList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ab2114bdc8544297b417dfefe9f1e410
|
||||
timeCreated: 1436650317
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- StyleSheet: {fileID: 11400000, guid: cab1ac28c8e6be24e995befe0c36d7c1, type: 2}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,580 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
#pragma warning disable 0109 // Disable warning due to conflict between Unity Editor DLL and Runtime DLL related to .renderer property being available in one but not the other.
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[RequireComponent(typeof(MeshRenderer))]
|
||||
[RequireComponent(typeof(MeshFilter))]
|
||||
[ExecuteAlways]
|
||||
public class TMP_SubMesh : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// The TMP Font Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public TMP_FontAsset fontAsset
|
||||
{
|
||||
get { return m_fontAsset; }
|
||||
set { m_fontAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_FontAsset m_fontAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The TMP Sprite Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public TMP_SpriteAsset spriteAsset
|
||||
{
|
||||
get { return m_spriteAsset; }
|
||||
set { m_spriteAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_SpriteAsset m_spriteAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The material to be assigned to this object. Returns an instance of the material.
|
||||
/// </summary>
|
||||
public Material material
|
||||
{
|
||||
// Return a new Instance of the Material if none exists. Otherwise return the current Material Instance.
|
||||
get { return GetMaterial(m_sharedMaterial); }
|
||||
|
||||
// Assign new font material
|
||||
set
|
||||
{
|
||||
if (m_sharedMaterial.GetInstanceID() == value.GetInstanceID())
|
||||
return;
|
||||
|
||||
m_sharedMaterial = m_material = value;
|
||||
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private Material m_material;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The material to be assigned to this text object.
|
||||
/// </summary>
|
||||
public Material sharedMaterial
|
||||
{
|
||||
get { return m_sharedMaterial; }
|
||||
set { SetSharedMaterial(value); }
|
||||
}
|
||||
[SerializeField]
|
||||
private Material m_sharedMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The fallback material created from the properties of the fallback source material.
|
||||
/// </summary>
|
||||
public Material fallbackMaterial
|
||||
{
|
||||
get { return m_fallbackMaterial; }
|
||||
set
|
||||
{
|
||||
if (m_fallbackMaterial == value) return;
|
||||
|
||||
if (m_fallbackMaterial != null && m_fallbackMaterial != value)
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
|
||||
m_fallbackMaterial = value;
|
||||
TMP_MaterialManager.AddFallbackMaterialReference(m_fallbackMaterial);
|
||||
|
||||
SetSharedMaterial(m_fallbackMaterial);
|
||||
}
|
||||
}
|
||||
private Material m_fallbackMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The source material used by the fallback font
|
||||
/// </summary>
|
||||
public Material fallbackSourceMaterial
|
||||
{
|
||||
get { return m_fallbackSourceMaterial; }
|
||||
set { m_fallbackSourceMaterial = value; }
|
||||
}
|
||||
private Material m_fallbackSourceMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Is the text object using the default font asset material.
|
||||
/// </summary>
|
||||
public bool isDefaultMaterial
|
||||
{
|
||||
get { return m_isDefaultMaterial; }
|
||||
set { m_isDefaultMaterial = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_isDefaultMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Padding value resulting for the property settings on the material.
|
||||
/// </summary>
|
||||
public float padding
|
||||
{
|
||||
get { return m_padding; }
|
||||
set { m_padding = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_padding;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Mesh Renderer of this text sub object.
|
||||
/// </summary>
|
||||
public new Renderer renderer
|
||||
{
|
||||
get { if (m_renderer == null) m_renderer = GetComponent<Renderer>();
|
||||
|
||||
return m_renderer;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private Renderer m_renderer;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The MeshFilter of this text sub object.
|
||||
/// </summary>
|
||||
public MeshFilter meshFilter
|
||||
{
|
||||
get { if (m_meshFilter == null) m_meshFilter = GetComponent<MeshFilter>();
|
||||
return m_meshFilter;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private MeshFilter m_meshFilter;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Mesh of this text sub object.
|
||||
/// </summary>
|
||||
public Mesh mesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_mesh == null)
|
||||
{
|
||||
m_mesh = new Mesh();
|
||||
m_mesh.hideFlags = HideFlags.HideAndDontSave;
|
||||
this.meshFilter.mesh = m_mesh;
|
||||
}
|
||||
|
||||
return m_mesh;
|
||||
}
|
||||
set { m_mesh = value; }
|
||||
}
|
||||
private Mesh m_mesh;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
//public BoxCollider boxCollider
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (m_boxCollider == null)
|
||||
// {
|
||||
// //
|
||||
// m_boxCollider = GetComponent<BoxCollider>();
|
||||
// if (m_boxCollider == null)
|
||||
// {
|
||||
// m_boxCollider = gameObject.AddComponent<BoxCollider>();
|
||||
// gameObject.AddComponent<Rigidbody>();
|
||||
// }
|
||||
// }
|
||||
|
||||
// return m_boxCollider;
|
||||
// }
|
||||
//}
|
||||
//[SerializeField]
|
||||
//private BoxCollider m_boxCollider;
|
||||
|
||||
[SerializeField]
|
||||
private TextMeshPro m_TextComponent;
|
||||
|
||||
[NonSerialized]
|
||||
private bool m_isRegisteredForEvents;
|
||||
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
// Register Callbacks for various events.
|
||||
if (!m_isRegisteredForEvents)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Add(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.FONT_PROPERTY_EVENT.Add(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Add(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Add(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
|
||||
TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT.Add(ON_SPRITE_ASSET_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Add(ON_TMP_SETTINGS_CHANGED);
|
||||
#endif
|
||||
|
||||
m_isRegisteredForEvents = true;
|
||||
}
|
||||
|
||||
// Make the geometry visible when the object is enabled.
|
||||
meshFilter.sharedMesh = mesh;
|
||||
|
||||
// Update _ClipRect values
|
||||
if (m_sharedMaterial != null)
|
||||
m_sharedMaterial.SetVector(ShaderUtilities.ID_ClipRect, new Vector4(-32767, -32767, 32767, 32767));
|
||||
}
|
||||
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
// Hide the geometry when the object is disabled.
|
||||
m_meshFilter.sharedMesh = null;
|
||||
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
m_fallbackMaterial = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
// Destroy Mesh
|
||||
if (m_mesh != null) DestroyImmediate(m_mesh);
|
||||
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
m_fallbackMaterial = null;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Unregister the event this object was listening to
|
||||
TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Remove(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.FONT_PROPERTY_EVENT.Remove(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Remove(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Remove(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
|
||||
TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT.Remove(ON_SPRITE_ASSET_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Remove(ON_TMP_SETTINGS_CHANGED);
|
||||
#endif
|
||||
m_isRegisteredForEvents = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Event received when custom material editor properties are changed.
|
||||
void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat)
|
||||
{
|
||||
//Debug.Log("*** ON_MATERIAL_PROPERTY_CHANGED ***");
|
||||
int targetMaterialID = mat.GetInstanceID();
|
||||
int sharedMaterialID = m_sharedMaterial.GetInstanceID();
|
||||
int fallbackSourceMaterialID = m_fallbackSourceMaterial == null ? 0 : m_fallbackSourceMaterial.GetInstanceID();
|
||||
|
||||
// Filter events and return if the affected material is not this object's material.
|
||||
if (targetMaterialID != sharedMaterialID)
|
||||
{
|
||||
// Check if event applies to the source fallback material
|
||||
if (m_fallbackMaterial != null && fallbackSourceMaterialID == targetMaterialID)
|
||||
TMP_MaterialManager.CopyMaterialPresetProperties(mat, m_fallbackMaterial);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_TextComponent == null) m_TextComponent = GetComponentInParent<TextMeshPro>();
|
||||
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
|
||||
|
||||
// Event to Track Material Changed resulting from Drag-n-drop.
|
||||
void ON_DRAG_AND_DROP_MATERIAL(GameObject obj, Material currentMaterial, Material newMaterial)
|
||||
{
|
||||
// Check if event applies to this current object
|
||||
#if UNITY_2018_2_OR_NEWER
|
||||
if (obj == gameObject || UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(gameObject) == obj)
|
||||
#else
|
||||
if (obj == gameObject || UnityEditor.PrefabUtility.GetPrefabParent(gameObject) == obj)
|
||||
#endif
|
||||
{
|
||||
if (!m_isDefaultMaterial) return;
|
||||
|
||||
// Make sure we have a valid reference to the renderer.
|
||||
if (m_renderer == null) m_renderer = GetComponent<Renderer>();
|
||||
|
||||
UnityEditor.Undo.RecordObject(this, "Material Assignment");
|
||||
UnityEditor.Undo.RecordObject(m_renderer, "Material Assignment");
|
||||
|
||||
SetSharedMaterial(newMaterial);
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Event received when font asset properties are changed in Font Inspector
|
||||
void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, UnityEngine.Object obj)
|
||||
{
|
||||
//if (spriteSheet != null && (obj as TMP_SpriteAsset == m_spriteAsset || obj as Texture2D == m_spriteAsset.spriteSheet))
|
||||
//{
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
//m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
// Event received when font asset properties are changed in Font Inspector
|
||||
void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font)
|
||||
{
|
||||
if (m_fontAsset != null && font.GetInstanceID() == m_fontAsset.GetInstanceID())
|
||||
{
|
||||
// Copy Normal and Bold Weight
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
m_fallbackMaterial.SetFloat(ShaderUtilities.ID_WeightNormal, m_fontAsset.normalStyle);
|
||||
m_fallbackMaterial.SetFloat(ShaderUtilities.ID_WeightBold, m_fontAsset.boldStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event received when the TMP Settings are changed.
|
||||
/// </summary>
|
||||
void ON_TMP_SETTINGS_CHANGED()
|
||||
{
|
||||
// //Debug.Log("TMP Setting have changed.");
|
||||
// //SetVerticesDirty();
|
||||
// SetMaterialDirty();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
public static TMP_SubMesh AddSubTextObject(TextMeshPro textComponent, MaterialReference materialReference)
|
||||
{
|
||||
GameObject go = new GameObject("TMP SubMesh [" + materialReference.material.name + "]", typeof(TMP_SubMesh));
|
||||
|
||||
TMP_SubMesh subMesh = go.GetComponent<TMP_SubMesh>();
|
||||
|
||||
go.transform.SetParent(textComponent.transform, false);
|
||||
go.transform.localPosition = Vector3.zero;
|
||||
go.transform.localRotation = Quaternion.identity;
|
||||
go.transform.localScale = Vector3.one;
|
||||
go.layer = textComponent.gameObject.layer;
|
||||
|
||||
subMesh.m_meshFilter = go.GetComponent<MeshFilter>();
|
||||
|
||||
subMesh.m_TextComponent = textComponent;
|
||||
subMesh.m_fontAsset = materialReference.fontAsset;
|
||||
subMesh.m_spriteAsset = materialReference.spriteAsset;
|
||||
subMesh.m_isDefaultMaterial = materialReference.isDefaultMaterial;
|
||||
subMesh.SetSharedMaterial(materialReference.material);
|
||||
|
||||
subMesh.renderer.sortingLayerID = textComponent.renderer.sortingLayerID;
|
||||
subMesh.renderer.sortingOrder = textComponent.renderer.sortingOrder;
|
||||
|
||||
return subMesh;
|
||||
}
|
||||
|
||||
|
||||
public void DestroySelf()
|
||||
{
|
||||
Destroy(this.gameObject, 1f);
|
||||
}
|
||||
|
||||
// Function called internally when a new material is assigned via the fontMaterial property.
|
||||
Material GetMaterial(Material mat)
|
||||
{
|
||||
// Check in case Object is disabled. If so, we don't have a valid reference to the Renderer.
|
||||
// This can occur when the Duplicate Material Context menu is used on an inactive object.
|
||||
if (m_renderer == null)
|
||||
m_renderer = GetComponent<Renderer>();
|
||||
|
||||
// Create Instance Material only if the new material is not the same instance previously used.
|
||||
if (m_material == null || m_material.GetInstanceID() != mat.GetInstanceID())
|
||||
m_material = CreateMaterialInstance(mat);
|
||||
|
||||
m_sharedMaterial = m_material;
|
||||
|
||||
// Compute and Set new padding values for this new material.
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
|
||||
return m_sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method used to create an instance of the material
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
Material CreateMaterialInstance(Material source)
|
||||
{
|
||||
Material mat = new Material(source);
|
||||
mat.shaderKeywords = source.shaderKeywords;
|
||||
mat.name += " (Instance)";
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method returning the shared material assigned to the text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material GetSharedMaterial()
|
||||
{
|
||||
if (m_renderer == null)
|
||||
m_renderer = GetComponent<Renderer>();
|
||||
|
||||
return m_renderer.sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to set the shared material.
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
void SetSharedMaterial(Material mat)
|
||||
{
|
||||
//Debug.Log("*** SetSharedMaterial() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
// Assign new material.
|
||||
m_sharedMaterial = mat;
|
||||
|
||||
// Compute and Set new padding values for this new material.
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetMaterialDirty();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (m_sharedMaterial != null)
|
||||
gameObject.name = "TMP SubMesh [" + m_sharedMaterial.name + "]";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function called when the padding value for the material needs to be re-calculated.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float GetPaddingForMaterial()
|
||||
{
|
||||
float padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_TextComponent.extraPadding, m_TextComponent.isUsingBold);
|
||||
|
||||
return padding;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the padding values of the object.
|
||||
/// </summary>
|
||||
/// <param name="isExtraPadding"></param>
|
||||
/// <param name="isBold"></param>
|
||||
public void UpdateMeshPadding(bool isExtraPadding, bool isUsingBold)
|
||||
{
|
||||
m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, isExtraPadding, isUsingBold);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetVerticesDirty()
|
||||
{
|
||||
if (!this.enabled)
|
||||
return;
|
||||
|
||||
// This is called on the parent TextMeshPro component.
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetMaterialDirty()
|
||||
{
|
||||
//if (!this.enabled)
|
||||
// return;
|
||||
|
||||
UpdateMaterial();
|
||||
|
||||
//m_materialDirty = true;
|
||||
//TMP_UpdateRegistry.RegisterCanvasElementForGraphicRebuild((ICanvasElement)this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected void UpdateMaterial()
|
||||
{
|
||||
//Debug.Log("*** STO - UpdateMaterial() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
//if (!this.enabled)
|
||||
// return;
|
||||
|
||||
if (m_renderer == null) m_renderer = this.renderer;
|
||||
|
||||
m_renderer.sharedMaterial = m_sharedMaterial;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (m_sharedMaterial != null && gameObject.name != "TMP SubMesh [" + m_sharedMaterial.name + "]")
|
||||
gameObject.name = "TMP SubMesh [" + m_sharedMaterial.name + "]";
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
//public void UpdateColliders(int vertexCount)
|
||||
//{
|
||||
// if (this.boxCollider == null) return;
|
||||
|
||||
// Vector2 bl = TMP_Math.MAX_16BIT;
|
||||
// Vector2 tr = TMP_Math.MIN_16BIT;
|
||||
// // Compute the bounds of the sub text object mesh (excluding the transform position).
|
||||
// for (int i = 0; i < vertexCount; i++)
|
||||
// {
|
||||
// bl.x = Mathf.Min(bl.x, m_mesh.vertices[i].x);
|
||||
// bl.y = Mathf.Min(bl.y, m_mesh.vertices[i].y);
|
||||
|
||||
// tr.x = Mathf.Max(tr.x, m_mesh.vertices[i].x);
|
||||
// tr.y = Mathf.Max(tr.y, m_mesh.vertices[i].y);
|
||||
// }
|
||||
|
||||
// Vector3 center = (bl + tr) / 2;
|
||||
// Vector3 size = tr - bl;
|
||||
// size.z = .1f;
|
||||
// this.boxCollider.center = center;
|
||||
// this.boxCollider.size = size;
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 07994bfe8b0e4adb97d706de5dea48d5
|
||||
timeCreated: 1454709708
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,807 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor.
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[ExecuteAlways]
|
||||
public class TMP_SubMeshUI : MaskableGraphic, IClippable, IMaskable, IMaterialModifier
|
||||
{
|
||||
/// <summary>
|
||||
/// The TMP Font Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public TMP_FontAsset fontAsset
|
||||
{
|
||||
get { return m_fontAsset; }
|
||||
set { m_fontAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_FontAsset m_fontAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The TMP Sprite Asset assigned to this sub text object.
|
||||
/// </summary>
|
||||
public TMP_SpriteAsset spriteAsset
|
||||
{
|
||||
get { return m_spriteAsset; }
|
||||
set { m_spriteAsset = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private TMP_SpriteAsset m_spriteAsset;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override Texture mainTexture
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.sharedMaterial != null)
|
||||
return this.sharedMaterial.GetTexture(ShaderUtilities.ID_MainTex);
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The material to be assigned to this object. Returns an instance of the material.
|
||||
/// </summary>
|
||||
public override Material material
|
||||
{
|
||||
// Return a new Instance of the Material if none exists. Otherwise return the current Material Instance.
|
||||
get { return GetMaterial(m_sharedMaterial); }
|
||||
|
||||
// Assign new font material
|
||||
set
|
||||
{
|
||||
if (m_sharedMaterial != null && m_sharedMaterial.GetInstanceID() == value.GetInstanceID())
|
||||
return;
|
||||
|
||||
m_sharedMaterial = m_material = value;
|
||||
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private Material m_material;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The material to be assigned to this text object.
|
||||
/// </summary>
|
||||
public Material sharedMaterial
|
||||
{
|
||||
get { return m_sharedMaterial; }
|
||||
set { SetSharedMaterial(value); }
|
||||
}
|
||||
[SerializeField]
|
||||
private Material m_sharedMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Material fallbackMaterial
|
||||
{
|
||||
get { return m_fallbackMaterial; }
|
||||
set
|
||||
{
|
||||
if (m_fallbackMaterial == value) return;
|
||||
|
||||
if (m_fallbackMaterial != null && m_fallbackMaterial != value)
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
|
||||
m_fallbackMaterial = value;
|
||||
TMP_MaterialManager.AddFallbackMaterialReference(m_fallbackMaterial);
|
||||
|
||||
SetSharedMaterial(m_fallbackMaterial);
|
||||
}
|
||||
}
|
||||
private Material m_fallbackMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The source material used by the fallback font
|
||||
/// </summary>
|
||||
public Material fallbackSourceMaterial
|
||||
{
|
||||
get { return m_fallbackSourceMaterial; }
|
||||
set { m_fallbackSourceMaterial = value; }
|
||||
}
|
||||
private Material m_fallbackSourceMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the material that will be used for rendering.
|
||||
/// </summary>
|
||||
public override Material materialForRendering
|
||||
{
|
||||
get
|
||||
{
|
||||
return TMP_MaterialManager.GetMaterialForRendering(this, m_sharedMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Is the text object using the default font asset material.
|
||||
/// </summary>
|
||||
public bool isDefaultMaterial
|
||||
{
|
||||
get { return m_isDefaultMaterial; }
|
||||
set { m_isDefaultMaterial = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private bool m_isDefaultMaterial;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Padding value resulting for the property settings on the material.
|
||||
/// </summary>
|
||||
public float padding
|
||||
{
|
||||
get { return m_padding; }
|
||||
set { m_padding = value; }
|
||||
}
|
||||
[SerializeField]
|
||||
private float m_padding;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Mesh Renderer of this text sub object.
|
||||
/// </summary>
|
||||
public new CanvasRenderer canvasRenderer
|
||||
{
|
||||
get { if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();
|
||||
|
||||
return m_canvasRenderer;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
private CanvasRenderer m_canvasRenderer;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Mesh of this text sub object.
|
||||
/// </summary>
|
||||
public Mesh mesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_mesh == null)
|
||||
{
|
||||
m_mesh = new Mesh();
|
||||
m_mesh.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
|
||||
return m_mesh;
|
||||
}
|
||||
set { m_mesh = value; }
|
||||
}
|
||||
private Mesh m_mesh;
|
||||
|
||||
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI m_TextComponent;
|
||||
|
||||
|
||||
[System.NonSerialized]
|
||||
private bool m_isRegisteredForEvents;
|
||||
private bool m_materialDirty;
|
||||
[SerializeField]
|
||||
private int m_materialReferenceIndex;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to add a new sub text object.
|
||||
/// </summary>
|
||||
/// <param name="textComponent"></param>
|
||||
/// <param name="materialReference"></param>
|
||||
/// <returns></returns>
|
||||
public static TMP_SubMeshUI AddSubTextObject(TextMeshProUGUI textComponent, MaterialReference materialReference)
|
||||
{
|
||||
GameObject go = new GameObject("TMP UI SubObject [" + materialReference.material.name + "]", typeof(RectTransform));
|
||||
|
||||
go.transform.SetParent(textComponent.transform, false);
|
||||
go.layer = textComponent.gameObject.layer;
|
||||
|
||||
RectTransform rectTransform = go.GetComponent<RectTransform>();
|
||||
rectTransform.anchorMin = Vector2.zero;
|
||||
rectTransform.anchorMax = Vector2.one;
|
||||
rectTransform.sizeDelta = Vector2.zero;
|
||||
rectTransform.pivot = textComponent.rectTransform.pivot;
|
||||
|
||||
TMP_SubMeshUI subMesh = go.AddComponent<TMP_SubMeshUI>();
|
||||
|
||||
subMesh.m_canvasRenderer = subMesh.canvasRenderer;
|
||||
subMesh.m_TextComponent = textComponent;
|
||||
|
||||
subMesh.m_materialReferenceIndex = materialReference.index;
|
||||
subMesh.m_fontAsset = materialReference.fontAsset;
|
||||
subMesh.m_spriteAsset = materialReference.spriteAsset;
|
||||
subMesh.m_isDefaultMaterial = materialReference.isDefaultMaterial;
|
||||
subMesh.SetSharedMaterial(materialReference.material);
|
||||
|
||||
return subMesh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
//Debug.Log("*** SubObject OnEnable() ***");
|
||||
|
||||
// Register Callbacks for various events.
|
||||
if (!m_isRegisteredForEvents)
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Add(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.FONT_PROPERTY_EVENT.Add(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Add(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Add(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Add(ON_TEXT_STYLE_CHANGED);
|
||||
TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT.Add(ON_SPRITE_ASSET_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Add(ON_TMP_SETTINGS_CHANGED);
|
||||
#endif
|
||||
|
||||
m_isRegisteredForEvents = true;
|
||||
}
|
||||
|
||||
m_ShouldRecalculateStencil = true;
|
||||
RecalculateClipping();
|
||||
RecalculateMasking();
|
||||
|
||||
//SetAllDirty();
|
||||
}
|
||||
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
//Debug.Log("*** SubObject OnDisable() ***");
|
||||
|
||||
//m_canvasRenderer.Clear();
|
||||
TMP_UpdateRegistry.UnRegisterCanvasElementForRebuild(this);
|
||||
|
||||
if (m_MaskMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
|
||||
m_MaskMaterial = null;
|
||||
}
|
||||
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
m_fallbackMaterial = null;
|
||||
}
|
||||
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
//Debug.Log("*** OnDestroy() ***");
|
||||
|
||||
// Destroy Mesh
|
||||
if (m_mesh != null) DestroyImmediate(m_mesh);
|
||||
|
||||
if (m_MaskMaterial != null)
|
||||
TMP_MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
|
||||
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
TMP_MaterialManager.ReleaseFallbackMaterial(m_fallbackMaterial);
|
||||
m_fallbackMaterial = null;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Unregister the event this object was listening to
|
||||
TMPro_EventManager.MATERIAL_PROPERTY_EVENT.Remove(ON_MATERIAL_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.FONT_PROPERTY_EVENT.Remove(ON_FONT_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TEXTMESHPRO_PROPERTY_EVENT.Remove(ON_TEXTMESHPRO_PROPERTY_CHANGED);
|
||||
TMPro_EventManager.DRAG_AND_DROP_MATERIAL_EVENT.Remove(ON_DRAG_AND_DROP_MATERIAL);
|
||||
//TMPro_EventManager.TEXT_STYLE_PROPERTY_EVENT.Remove(ON_TEXT_STYLE_CHANGED);
|
||||
TMPro_EventManager.SPRITE_ASSET_PROPERTY_EVENT.Remove(ON_SPRITE_ASSET_PROPERTY_CHANGED);
|
||||
//TMPro_EventManager.TMP_SETTINGS_PROPERTY_EVENT.Remove(ON_TMP_SETTINGS_CHANGED);
|
||||
#endif
|
||||
|
||||
m_isRegisteredForEvents = false;
|
||||
|
||||
RecalculateClipping();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// Event received when custom material editor properties are changed.
|
||||
void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat)
|
||||
{
|
||||
//Debug.Log("*** ON_MATERIAL_PROPERTY_CHANGED ***");
|
||||
|
||||
int targetMaterialID = mat.GetInstanceID();
|
||||
int sharedMaterialID = m_sharedMaterial.GetInstanceID();
|
||||
int maskingMaterialID = m_MaskMaterial == null ? 0 : m_MaskMaterial.GetInstanceID();
|
||||
int fallbackSourceMaterialID = m_fallbackSourceMaterial == null ? 0 : m_fallbackSourceMaterial.GetInstanceID();
|
||||
|
||||
// Filter events and return if the affected material is not this object's material.
|
||||
//if (targetMaterialID != sharedMaterialID && targetMaterialID != maskingMaterialID) return;
|
||||
|
||||
// Filter events and return if the affected material is not this object's material.
|
||||
if (m_fallbackMaterial != null && fallbackSourceMaterialID == targetMaterialID)
|
||||
TMP_MaterialManager.CopyMaterialPresetProperties(mat, m_fallbackMaterial);
|
||||
|
||||
if (m_TextComponent == null) m_TextComponent = GetComponentInParent<TextMeshProUGUI>();
|
||||
|
||||
// Make sure material properties are synchronized between the assigned material and masking material.
|
||||
if (m_MaskMaterial != null)
|
||||
{
|
||||
UnityEditor.Undo.RecordObject(m_MaskMaterial, "Material Property Changes");
|
||||
UnityEditor.Undo.RecordObject(m_sharedMaterial, "Material Property Changes");
|
||||
|
||||
if (targetMaterialID == sharedMaterialID)
|
||||
{
|
||||
//Debug.Log("Copy base material properties to masking material if not null.");
|
||||
float stencilID = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilID);
|
||||
float stencilComp = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilComp);
|
||||
m_MaskMaterial.CopyPropertiesFromMaterial(mat);
|
||||
m_MaskMaterial.shaderKeywords = mat.shaderKeywords;
|
||||
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilComp, stencilComp);
|
||||
}
|
||||
else if (targetMaterialID == maskingMaterialID)
|
||||
{
|
||||
// Update the padding
|
||||
GetPaddingForMaterial(mat);
|
||||
|
||||
m_sharedMaterial.CopyPropertiesFromMaterial(mat);
|
||||
m_sharedMaterial.shaderKeywords = mat.shaderKeywords;
|
||||
m_sharedMaterial.SetFloat(ShaderUtilities.ID_StencilID, 0);
|
||||
m_sharedMaterial.SetFloat(ShaderUtilities.ID_StencilComp, 8);
|
||||
}
|
||||
else if (fallbackSourceMaterialID == targetMaterialID)
|
||||
{
|
||||
float stencilID = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilID);
|
||||
float stencilComp = m_MaskMaterial.GetFloat(ShaderUtilities.ID_StencilComp);
|
||||
m_MaskMaterial.CopyPropertiesFromMaterial(m_fallbackMaterial);
|
||||
m_MaskMaterial.shaderKeywords = m_fallbackMaterial.shaderKeywords;
|
||||
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilID, stencilID);
|
||||
m_MaskMaterial.SetFloat(ShaderUtilities.ID_StencilComp, stencilComp);
|
||||
}
|
||||
}
|
||||
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
m_ShouldRecalculateStencil = true;
|
||||
RecalculateClipping();
|
||||
RecalculateMasking();
|
||||
}
|
||||
|
||||
|
||||
// Event to Track Material Changed resulting from Drag-n-drop.
|
||||
void ON_DRAG_AND_DROP_MATERIAL(GameObject obj, Material currentMaterial, Material newMaterial)
|
||||
{
|
||||
// Check if event applies to this current object
|
||||
#if UNITY_2018_2_OR_NEWER
|
||||
if (obj == gameObject || UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(gameObject) == obj)
|
||||
#else
|
||||
if (obj == gameObject || UnityEditor.PrefabUtility.GetPrefabParent(gameObject) == obj)
|
||||
#endif
|
||||
{
|
||||
if (!m_isDefaultMaterial) return;
|
||||
|
||||
// Make sure we have a valid reference to the renderer.
|
||||
if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();
|
||||
|
||||
UnityEditor.Undo.RecordObject(this, "Material Assignment");
|
||||
UnityEditor.Undo.RecordObject(m_canvasRenderer, "Material Assignment");
|
||||
|
||||
SetSharedMaterial(newMaterial);
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Event received when font asset properties are changed in Font Inspector
|
||||
void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, UnityEngine.Object obj)
|
||||
{
|
||||
//if (spriteSheet != null && (obj as TMP_SpriteAsset == m_spriteAsset || obj as Texture2D == m_spriteAsset.spriteSheet))
|
||||
//{
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
//m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
// Event received when font asset properties are changed in Font Inspector
|
||||
void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font)
|
||||
{
|
||||
if (m_fontAsset != null && font.GetInstanceID() == m_fontAsset.GetInstanceID())
|
||||
{
|
||||
// Copy Normal and Bold Weight
|
||||
if (m_fallbackMaterial != null)
|
||||
{
|
||||
m_fallbackMaterial.SetFloat(ShaderUtilities.ID_WeightNormal, m_fontAsset.normalStyle);
|
||||
m_fallbackMaterial.SetFloat(ShaderUtilities.ID_WeightBold, m_fontAsset.boldStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event received when the TMP Settings are changed.
|
||||
/// </summary>
|
||||
void ON_TMP_SETTINGS_CHANGED()
|
||||
{
|
||||
//Debug.Log("TMP Setting have changed.");
|
||||
//SetVerticesDirty();
|
||||
//SetMaterialDirty();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void OnTransformParentChanged()
|
||||
{
|
||||
if (!this.IsActive())
|
||||
return;
|
||||
|
||||
m_ShouldRecalculateStencil = true;
|
||||
RecalculateClipping();
|
||||
RecalculateMasking();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the modified material for masking if necessary.
|
||||
/// </summary>
|
||||
/// <param name="baseMaterial"></param>
|
||||
/// <returns></returns>
|
||||
public override Material GetModifiedMaterial(Material baseMaterial)
|
||||
{
|
||||
Material mat = baseMaterial;
|
||||
|
||||
if (m_ShouldRecalculateStencil)
|
||||
{
|
||||
m_StencilValue = TMP_MaterialManager.GetStencilID(gameObject);
|
||||
m_ShouldRecalculateStencil = false;
|
||||
}
|
||||
|
||||
if (m_StencilValue > 0)
|
||||
{
|
||||
mat = TMP_MaterialManager.GetStencilMaterial(baseMaterial, m_StencilValue);
|
||||
if (m_MaskMaterial != null)
|
||||
TMP_MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
|
||||
|
||||
m_MaskMaterial = mat;
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function called when the padding value for the material needs to be re-calculated.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float GetPaddingForMaterial()
|
||||
{
|
||||
float padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_TextComponent.extraPadding, m_TextComponent.isUsingBold);
|
||||
|
||||
return padding;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function called when the padding value for the material needs to be re-calculated.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float GetPaddingForMaterial(Material mat)
|
||||
{
|
||||
float padding = ShaderUtilities.GetPadding(mat, m_TextComponent.extraPadding, m_TextComponent.isUsingBold);
|
||||
|
||||
return padding;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="isExtraPadding"></param>
|
||||
/// <param name="isBold"></param>
|
||||
public void UpdateMeshPadding(bool isExtraPadding, bool isUsingBold)
|
||||
{
|
||||
m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, isExtraPadding, isUsingBold);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetAllDirty()
|
||||
{
|
||||
//SetLayoutDirty();
|
||||
//SetVerticesDirty();
|
||||
//SetMaterialDirty();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetVerticesDirty()
|
||||
{
|
||||
if (!this.IsActive())
|
||||
return;
|
||||
|
||||
// This is called on the parent TextMeshPro component.
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
m_TextComponent.havePropertiesChanged = true;
|
||||
m_TextComponent.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetLayoutDirty()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void SetMaterialDirty()
|
||||
{
|
||||
//Debug.Log("*** STO-UI - SetMaterialDirty() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
//if (!this.IsActive())
|
||||
// return;
|
||||
|
||||
m_materialDirty = true;
|
||||
|
||||
UpdateMaterial();
|
||||
|
||||
if (m_OnDirtyMaterialCallback != null)
|
||||
m_OnDirtyMaterialCallback();
|
||||
|
||||
//TMP_ITextElementUpdateManager.RegisterTextElementForGraphicRebuild(this);
|
||||
|
||||
//TMP_UpdateRegistry.RegisterCanvasElementForGraphicRebuild((ICanvasElement)this);
|
||||
//m_TextComponent.SetMaterialDirty();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetPivotDirty()
|
||||
{
|
||||
if (!this.IsActive())
|
||||
return;
|
||||
|
||||
this.rectTransform.pivot = m_TextComponent.rectTransform.pivot;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Override to Cull function of MaskableGraphic to prevent Culling.
|
||||
/// </summary>
|
||||
/// <param name="clipRect"></param>
|
||||
/// <param name="validRect"></param>
|
||||
public override void Cull(Rect clipRect, bool validRect)
|
||||
{
|
||||
if (m_TextComponent.ignoreRectMaskCulling) return;
|
||||
|
||||
base.Cull(clipRect, validRect);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void UpdateGeometry()
|
||||
{
|
||||
// Need to override to prevent Unity from changing the geometry of the object.
|
||||
Debug.Log("UpdateGeometry()");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="update"></param>
|
||||
public override void Rebuild(CanvasUpdate update)
|
||||
{
|
||||
if (update == CanvasUpdate.PreRender)
|
||||
{
|
||||
if (!m_materialDirty) return;
|
||||
|
||||
UpdateMaterial();
|
||||
m_materialDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to update the material from the parent text object.
|
||||
/// </summary>
|
||||
public void RefreshMaterial()
|
||||
{
|
||||
UpdateMaterial();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void UpdateMaterial()
|
||||
{
|
||||
//Debug.Log("*** STO-UI - UpdateMaterial() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
//if (!this.IsActive())
|
||||
// return;
|
||||
|
||||
if (m_canvasRenderer == null) m_canvasRenderer = this.canvasRenderer;
|
||||
|
||||
m_canvasRenderer.materialCount = 1;
|
||||
m_canvasRenderer.SetMaterial(materialForRendering, 0);
|
||||
m_canvasRenderer.SetTexture(mainTexture);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (m_sharedMaterial != null && gameObject.name != "TMP SubMeshUI [" + m_sharedMaterial.name + "]")
|
||||
gameObject.name = "TMP SubMeshUI [" + m_sharedMaterial.name + "]";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// IClippable implementation
|
||||
/// <summary>
|
||||
/// Method called when the state of a parent changes.
|
||||
/// </summary>
|
||||
public override void RecalculateClipping()
|
||||
{
|
||||
//Debug.Log("*** RecalculateClipping() ***");
|
||||
base.RecalculateClipping();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void RecalculateMasking()
|
||||
{
|
||||
//Debug.Log("RecalculateMasking()");
|
||||
|
||||
this.m_ShouldRecalculateStencil = true;
|
||||
SetMaterialDirty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method which returns an instance of the shared material
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material GetMaterial()
|
||||
{
|
||||
// Make sure we have a valid reference to the renderer.
|
||||
//if (m_renderer == null) m_renderer = GetComponent<Renderer>();
|
||||
|
||||
//if (m_material == null || m_isNewSharedMaterial)
|
||||
//{
|
||||
// m_renderer.material = m_sharedMaterial;
|
||||
// m_material = m_renderer.material;
|
||||
// m_sharedMaterial = m_material;
|
||||
// m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_TextMeshPro.extraPadding, false);
|
||||
// m_isNewSharedMaterial = false;
|
||||
//}
|
||||
|
||||
return m_sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
// Function called internally when a new material is assigned via the fontMaterial property.
|
||||
Material GetMaterial(Material mat)
|
||||
{
|
||||
// Check in case Object is disabled. If so, we don't have a valid reference to the Renderer.
|
||||
// This can occur when the Duplicate Material Context menu is used on an inactive object.
|
||||
//if (m_renderer == null)
|
||||
// m_renderer = GetComponent<Renderer>();
|
||||
|
||||
// Create Instance Material only if the new material is not the same instance previously used.
|
||||
if (m_material == null || m_material.GetInstanceID() != mat.GetInstanceID())
|
||||
m_material = CreateMaterialInstance(mat);
|
||||
|
||||
m_sharedMaterial = m_material;
|
||||
|
||||
// Compute and Set new padding values for this new material.
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
|
||||
return m_sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method used to create an instance of the material
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
Material CreateMaterialInstance(Material source)
|
||||
{
|
||||
Material mat = new Material(source);
|
||||
mat.shaderKeywords = source.shaderKeywords;
|
||||
mat.name += " (Instance)";
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method returning the shared material assigned to the text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material GetSharedMaterial()
|
||||
{
|
||||
if (m_canvasRenderer == null)
|
||||
m_canvasRenderer = GetComponent<CanvasRenderer>();
|
||||
|
||||
return m_canvasRenderer.GetMaterial();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to set the shared material.
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
void SetSharedMaterial(Material mat)
|
||||
{
|
||||
//Debug.Log("*** SetSharedMaterial UI() *** FRAME (" + Time.frameCount + ")");
|
||||
|
||||
// Assign new material.
|
||||
m_sharedMaterial = mat;
|
||||
m_Material = m_sharedMaterial;
|
||||
|
||||
//m_isDefaultMaterial = false;
|
||||
//if (mat.GetInstanceID() == m_fontAsset.material.GetInstanceID())
|
||||
// m_isDefaultMaterial = true;
|
||||
|
||||
// Compute and Set new padding values for this new material.
|
||||
m_padding = GetPaddingForMaterial();
|
||||
|
||||
//SetVerticesDirty();
|
||||
SetMaterialDirty();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
//if (m_sharedMaterial != null)
|
||||
// gameObject.name = "TMP SubMesh [" + m_sharedMaterial.name + "]";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 058cba836c1846c3aa1c5fd2e28aea77
|
||||
timeCreated: 1454709708
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5143f58107604835ab1a5efa2d8818fd
|
||||
timeCreated: 1445841744
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public enum TextElementType : byte
|
||||
{
|
||||
Character = 0x1,
|
||||
Sprite = 0x2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all text elements like Character and SpriteCharacter.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_TextElement
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of text element which can be a character or sprite.
|
||||
/// </summary>
|
||||
public TextElementType elementType { get { return m_ElementType; } }
|
||||
|
||||
/// <summary>
|
||||
/// The unicode value (code point) of the character.
|
||||
/// </summary>
|
||||
public uint unicode { get { return m_Unicode; } set { m_Unicode = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The glyph used by this text element.
|
||||
/// </summary>
|
||||
public Glyph glyph { get { return m_Glyph; } set { m_Glyph = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The index of the glyph used by this text element.
|
||||
/// </summary>
|
||||
public uint glyphIndex { get { return m_GlyphIndex; } set { m_GlyphIndex = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// The relative scale of the character.
|
||||
/// </summary>
|
||||
public float scale { get { return m_Scale; } set { m_Scale = value; } }
|
||||
|
||||
// =============================================
|
||||
// Private backing fields for public properties.
|
||||
// =============================================
|
||||
|
||||
[SerializeField]
|
||||
protected TextElementType m_ElementType;
|
||||
|
||||
[SerializeField]
|
||||
private uint m_Unicode;
|
||||
|
||||
private Glyph m_Glyph;
|
||||
|
||||
[SerializeField]
|
||||
private uint m_GlyphIndex;
|
||||
|
||||
[SerializeField]
|
||||
private float m_Scale;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 543674eec776b1442a192c932e6cd9b3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,25 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all text elements like characters (glyphs) and sprites.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_TextElement_Legacy
|
||||
{
|
||||
public int id;
|
||||
public float x;
|
||||
public float y;
|
||||
public float width;
|
||||
public float height;
|
||||
public float xOffset;
|
||||
public float yOffset;
|
||||
public float xAdvance;
|
||||
public float scale;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 87ab1bebe13f41f89d5427e7d2c34d58
|
||||
timeCreated: 1448407070
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,256 @@
|
|||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Class which contains information about every element contained within the text object.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TMP_TextInfo
|
||||
{
|
||||
private static Vector2 k_InfinityVectorPositive = new Vector2(32767, 32767);
|
||||
private static Vector2 k_InfinityVectorNegative = new Vector2(-32767, -32767);
|
||||
|
||||
public TMP_Text textComponent;
|
||||
|
||||
public int characterCount;
|
||||
public int spriteCount;
|
||||
public int spaceCount;
|
||||
public int wordCount;
|
||||
public int linkCount;
|
||||
public int lineCount;
|
||||
public int pageCount;
|
||||
|
||||
public int materialCount;
|
||||
|
||||
public TMP_CharacterInfo[] characterInfo;
|
||||
public TMP_WordInfo[] wordInfo;
|
||||
public TMP_LinkInfo[] linkInfo;
|
||||
public TMP_LineInfo[] lineInfo;
|
||||
public TMP_PageInfo[] pageInfo;
|
||||
public TMP_MeshInfo[] meshInfo;
|
||||
|
||||
private TMP_MeshInfo[] m_CachedMeshInfo;
|
||||
|
||||
// Default Constructor
|
||||
public TMP_TextInfo()
|
||||
{
|
||||
characterInfo = new TMP_CharacterInfo[8];
|
||||
wordInfo = new TMP_WordInfo[16];
|
||||
linkInfo = new TMP_LinkInfo[0];
|
||||
lineInfo = new TMP_LineInfo[2];
|
||||
pageInfo = new TMP_PageInfo[4];
|
||||
|
||||
meshInfo = new TMP_MeshInfo[1];
|
||||
}
|
||||
|
||||
|
||||
public TMP_TextInfo(TMP_Text textComponent)
|
||||
{
|
||||
this.textComponent = textComponent;
|
||||
|
||||
characterInfo = new TMP_CharacterInfo[8];
|
||||
|
||||
wordInfo = new TMP_WordInfo[4];
|
||||
linkInfo = new TMP_LinkInfo[0];
|
||||
|
||||
lineInfo = new TMP_LineInfo[2];
|
||||
pageInfo = new TMP_PageInfo[4];
|
||||
|
||||
meshInfo = new TMP_MeshInfo[1];
|
||||
meshInfo[0].mesh = textComponent.mesh;
|
||||
materialCount = 1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the counters of the text object.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
characterCount = 0;
|
||||
spaceCount = 0;
|
||||
wordCount = 0;
|
||||
linkCount = 0;
|
||||
lineCount = 0;
|
||||
pageCount = 0;
|
||||
spriteCount = 0;
|
||||
|
||||
for (int i = 0; i < this.meshInfo.Length; i++)
|
||||
{
|
||||
this.meshInfo[i].vertexCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the content of the MeshInfo array while preserving the Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void ClearMeshInfo(bool updateMesh)
|
||||
{
|
||||
for (int i = 0; i < this.meshInfo.Length; i++)
|
||||
this.meshInfo[i].Clear(updateMesh);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear the content of all the MeshInfo arrays while preserving their Triangles, Normals and Tangents.
|
||||
/// </summary>
|
||||
public void ClearAllMeshInfo()
|
||||
{
|
||||
for (int i = 0; i < this.meshInfo.Length; i++)
|
||||
this.meshInfo[i].Clear(true);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void ResetVertexLayout(bool isVolumetric)
|
||||
{
|
||||
for (int i = 0; i < this.meshInfo.Length; i++)
|
||||
this.meshInfo[i].ResizeMeshInfo(0, isVolumetric);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used to mark unused vertices as degenerate.
|
||||
/// </summary>
|
||||
/// <param name="materials"></param>
|
||||
public void ClearUnusedVertices(MaterialReference[] materials)
|
||||
{
|
||||
for (int i = 0; i < meshInfo.Length; i++)
|
||||
{
|
||||
int start = 0; // materials[i].referenceCount * 4;
|
||||
meshInfo[i].ClearUnusedVertices(start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to clear and initialize the lineInfo array.
|
||||
/// </summary>
|
||||
public void ClearLineInfo()
|
||||
{
|
||||
if (this.lineInfo == null)
|
||||
this.lineInfo = new TMP_LineInfo[2];
|
||||
|
||||
for (int i = 0; i < this.lineInfo.Length; i++)
|
||||
{
|
||||
this.lineInfo[i].characterCount = 0;
|
||||
this.lineInfo[i].spaceCount = 0;
|
||||
this.lineInfo[i].wordCount = 0;
|
||||
this.lineInfo[i].controlCharacterCount = 0;
|
||||
this.lineInfo[i].width = 0;
|
||||
|
||||
this.lineInfo[i].ascender = k_InfinityVectorNegative.x;
|
||||
this.lineInfo[i].descender = k_InfinityVectorPositive.x;
|
||||
|
||||
this.lineInfo[i].lineExtents.min = k_InfinityVectorPositive;
|
||||
this.lineInfo[i].lineExtents.max = k_InfinityVectorNegative;
|
||||
|
||||
this.lineInfo[i].maxAdvance = 0;
|
||||
//this.lineInfo[i].maxScale = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to copy the MeshInfo Arrays and their primary vertex data content.
|
||||
/// </summary>
|
||||
/// <returns>A copy of the MeshInfo[]</returns>
|
||||
public TMP_MeshInfo[] CopyMeshInfoVertexData()
|
||||
{
|
||||
if (m_CachedMeshInfo == null || m_CachedMeshInfo.Length != meshInfo.Length)
|
||||
{
|
||||
m_CachedMeshInfo = new TMP_MeshInfo[meshInfo.Length];
|
||||
|
||||
// Initialize all the vertex data arrays
|
||||
for (int i = 0; i < m_CachedMeshInfo.Length; i++)
|
||||
{
|
||||
int length = meshInfo[i].vertices.Length;
|
||||
|
||||
m_CachedMeshInfo[i].vertices = new Vector3[length];
|
||||
m_CachedMeshInfo[i].uvs0 = new Vector2[length];
|
||||
m_CachedMeshInfo[i].uvs2 = new Vector2[length];
|
||||
m_CachedMeshInfo[i].colors32 = new Color32[length];
|
||||
|
||||
//m_CachedMeshInfo[i].normals = new Vector3[length];
|
||||
//m_CachedMeshInfo[i].tangents = new Vector4[length];
|
||||
//m_CachedMeshInfo[i].triangles = new int[meshInfo[i].triangles.Length];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_CachedMeshInfo.Length; i++)
|
||||
{
|
||||
int length = meshInfo[i].vertices.Length;
|
||||
|
||||
if (m_CachedMeshInfo[i].vertices.Length != length)
|
||||
{
|
||||
m_CachedMeshInfo[i].vertices = new Vector3[length];
|
||||
m_CachedMeshInfo[i].uvs0 = new Vector2[length];
|
||||
m_CachedMeshInfo[i].uvs2 = new Vector2[length];
|
||||
m_CachedMeshInfo[i].colors32 = new Color32[length];
|
||||
|
||||
//m_CachedMeshInfo[i].normals = new Vector3[length];
|
||||
//m_CachedMeshInfo[i].tangents = new Vector4[length];
|
||||
//m_CachedMeshInfo[i].triangles = new int[meshInfo[i].triangles.Length];
|
||||
}
|
||||
|
||||
|
||||
// Only copy the primary vertex data
|
||||
Array.Copy(meshInfo[i].vertices, m_CachedMeshInfo[i].vertices, length);
|
||||
Array.Copy(meshInfo[i].uvs0, m_CachedMeshInfo[i].uvs0, length);
|
||||
Array.Copy(meshInfo[i].uvs2, m_CachedMeshInfo[i].uvs2, length);
|
||||
Array.Copy(meshInfo[i].colors32, m_CachedMeshInfo[i].colors32, length);
|
||||
|
||||
//Array.Copy(meshInfo[i].normals, m_CachedMeshInfo[i].normals, length);
|
||||
//Array.Copy(meshInfo[i].tangents, m_CachedMeshInfo[i].tangents, length);
|
||||
//Array.Copy(meshInfo[i].triangles, m_CachedMeshInfo[i].triangles, meshInfo[i].triangles.Length);
|
||||
}
|
||||
|
||||
return m_CachedMeshInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to resize any of the structure contained in the TMP_TextInfo class.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <param name="size"></param>
|
||||
public static void Resize<T> (ref T[] array, int size)
|
||||
{
|
||||
// Allocated to the next power of two
|
||||
int newSize = size > 1024 ? size + 256 : Mathf.NextPowerOfTwo(size);
|
||||
|
||||
Array.Resize(ref array, newSize);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to resize any of the structure contained in the TMP_TextInfo class.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="isFixedSize"></param>
|
||||
public static void Resize<T>(ref T[] array, int size, bool isBlockAllocated)
|
||||
{
|
||||
//if (size <= array.Length) return;
|
||||
|
||||
if (isBlockAllocated) size = size > 1024 ? size + 256 : Mathf.NextPowerOfTwo(size);
|
||||
|
||||
if (size == array.Length) return;
|
||||
|
||||
Array.Resize(ref array, size);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ae64f3f72004807a9f919f9c27af0db
|
||||
timeCreated: 1446589998
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,136 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class TMP_TextParsingUtilities
|
||||
{
|
||||
private static readonly TMP_TextParsingUtilities s_Instance = new TMP_TextParsingUtilities();
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
static TMP_TextParsingUtilities() { }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the TextModuleUtilities.
|
||||
/// </summary>
|
||||
public static TMP_TextParsingUtilities instance
|
||||
{
|
||||
get { return s_Instance; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function returning the hashcode value of a given string.
|
||||
/// </summary>
|
||||
public static uint GetHashCode(string s)
|
||||
{
|
||||
uint hashCode = 0;
|
||||
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
hashCode = ((hashCode << 5) + hashCode) ^ ToUpperASCIIFast(s[i]);
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public static int GetHashCodeCaseSensitive(string s)
|
||||
{
|
||||
int hashCode = 0;
|
||||
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
hashCode = ((hashCode << 5) + hashCode) ^ s[i];
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Table used to convert character to lowercase.
|
||||
/// </summary>
|
||||
const string k_LookupStringL = "-------------------------------- !-#$%&-()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[-]^_`abcdefghijklmnopqrstuvwxyz{|}~-";
|
||||
|
||||
/// <summary>
|
||||
/// Table used to convert character to uppercase.
|
||||
/// </summary>
|
||||
const string k_LookupStringU = "-------------------------------- !-#$%&-()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[-]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~-";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get lowercase version of this ASCII character.
|
||||
/// </summary>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static char ToLowerASCIIFast(char c)
|
||||
{
|
||||
if (c > k_LookupStringL.Length - 1)
|
||||
return c;
|
||||
|
||||
return k_LookupStringL[c];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get uppercase version of this ASCII character.
|
||||
/// </summary>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static char ToUpperASCIIFast(char c)
|
||||
{
|
||||
if (c > k_LookupStringU.Length - 1)
|
||||
return c;
|
||||
|
||||
return k_LookupStringU[c];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get uppercase version of this ASCII character.
|
||||
/// </summary>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToUpperASCIIFast(uint c)
|
||||
{
|
||||
if (c > k_LookupStringU.Length - 1)
|
||||
return c;
|
||||
|
||||
return k_LookupStringU[(int)c];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get lowercase version of this ASCII character.
|
||||
/// </summary>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToLowerASCIIFast(uint c)
|
||||
{
|
||||
if (c > k_LookupStringL.Length - 1)
|
||||
return c;
|
||||
|
||||
return k_LookupStringL[(int)c];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if Unicode is High Surrogate
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsHighSurrogate(uint c)
|
||||
{
|
||||
return c > 0xD800 && c < 0xDBFF;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if Unicode is Low Surrogate
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsLowSurrogate(uint c)
|
||||
{
|
||||
return c > 0xDC00 && c < 0xDFFF;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6ad632cbcc87f634d9b86006cdffdaf5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4f0ca6874aa74540bb3d4fe5a0f86bcc
|
||||
timeCreated: 1432117579
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,238 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
using UnityEngine.Rendering;
|
||||
#elif UNITY_2018_1_OR_NEWER
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
#endif
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
|
||||
public class TMP_UpdateManager
|
||||
{
|
||||
private static TMP_UpdateManager s_Instance;
|
||||
|
||||
private readonly List<TMP_Text> m_LayoutRebuildQueue = new List<TMP_Text>();
|
||||
private Dictionary<int, int> m_LayoutQueueLookup = new Dictionary<int, int>();
|
||||
|
||||
private readonly List<TMP_Text> m_GraphicRebuildQueue = new List<TMP_Text>();
|
||||
private Dictionary<int, int> m_GraphicQueueLookup = new Dictionary<int, int>();
|
||||
|
||||
private readonly List<TMP_Text> m_InternalUpdateQueue = new List<TMP_Text>();
|
||||
private Dictionary<int, int> m_InternalUpdateLookup = new Dictionary<int, int>();
|
||||
|
||||
//private bool m_PerformingGraphicRebuild;
|
||||
//private bool m_PerformingLayoutRebuild;
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the registry
|
||||
/// </summary>
|
||||
public static TMP_UpdateManager instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (TMP_UpdateManager.s_Instance == null)
|
||||
TMP_UpdateManager.s_Instance = new TMP_UpdateManager();
|
||||
return TMP_UpdateManager.s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Register to receive rendering callbacks.
|
||||
/// </summary>
|
||||
protected TMP_UpdateManager()
|
||||
{
|
||||
Camera.onPreCull += OnCameraPreCull;
|
||||
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
RenderPipelineManager.beginFrameRendering += OnBeginFrameRendering;
|
||||
#elif UNITY_2018_1_OR_NEWER
|
||||
RenderPipeline.beginFrameRendering += OnBeginFrameRendering;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function used as a replacement for LateUpdate() to handle SDF Scale updates and Legacy Animation updates.
|
||||
/// </summary>
|
||||
/// <param name="textObject"></param>
|
||||
internal static void RegisterTextObjectForUpdate(TMP_Text textObject)
|
||||
{
|
||||
TMP_UpdateManager.instance.InternalRegisterTextObjectForUpdate(textObject);
|
||||
}
|
||||
|
||||
private void InternalRegisterTextObjectForUpdate(TMP_Text textObject)
|
||||
{
|
||||
int id = textObject.GetInstanceID();
|
||||
|
||||
if (this.m_InternalUpdateLookup.ContainsKey(id))
|
||||
return;
|
||||
|
||||
m_InternalUpdateLookup[id] = id;
|
||||
this.m_InternalUpdateQueue.Add(textObject);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to register elements which require a layout rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void RegisterTextElementForLayoutRebuild(TMP_Text element)
|
||||
{
|
||||
TMP_UpdateManager.instance.InternalRegisterTextElementForLayoutRebuild(element);
|
||||
}
|
||||
|
||||
private bool InternalRegisterTextElementForLayoutRebuild(TMP_Text element)
|
||||
{
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
if (this.m_LayoutQueueLookup.ContainsKey(id))
|
||||
return false;
|
||||
|
||||
m_LayoutQueueLookup[id] = id;
|
||||
this.m_LayoutRebuildQueue.Add(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to register elements which require a layout rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void RegisterTextElementForGraphicRebuild(TMP_Text element)
|
||||
{
|
||||
TMP_UpdateManager.instance.InternalRegisterTextElementForGraphicRebuild(element);
|
||||
}
|
||||
|
||||
private bool InternalRegisterTextElementForGraphicRebuild(TMP_Text element)
|
||||
{
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
if (this.m_GraphicQueueLookup.ContainsKey(id))
|
||||
return false;
|
||||
|
||||
m_GraphicQueueLookup[id] = id;
|
||||
this.m_GraphicRebuildQueue.Add(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Callback which occurs just before the Scriptable Render Pipeline (SRP) begins rendering.
|
||||
/// </summary>
|
||||
/// <param name="cameras"></param>
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
void OnBeginFrameRendering(ScriptableRenderContext renderContext, Camera[] cameras)
|
||||
#elif UNITY_2018_1_OR_NEWER
|
||||
void OnBeginFrameRendering(Camera[] cameras)
|
||||
#endif
|
||||
{
|
||||
// Exclude the PreRenderCamera
|
||||
#if UNITY_EDITOR
|
||||
if (cameras.Length == 1 && cameras[0].cameraType == CameraType.Preview)
|
||||
return;
|
||||
#endif
|
||||
DoRebuilds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback which occurs just before the cam is rendered.
|
||||
/// </summary>
|
||||
/// <param name="cam"></param>
|
||||
void OnCameraPreCull(Camera cam)
|
||||
{
|
||||
// Exclude the PreRenderCamera
|
||||
#if UNITY_EDITOR
|
||||
if (cam.cameraType == CameraType.Preview)
|
||||
return;
|
||||
#endif
|
||||
DoRebuilds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the rebuild requests in the rebuild queues.
|
||||
/// </summary>
|
||||
void DoRebuilds()
|
||||
{
|
||||
// Handle text objects the require an update either as a result of scale changes or legacy animation.
|
||||
for (int i = 0; i < m_InternalUpdateQueue.Count; i++)
|
||||
{
|
||||
m_InternalUpdateQueue[i].InternalUpdate();
|
||||
}
|
||||
|
||||
// Handle Layout Rebuild Phase
|
||||
for (int i = 0; i < m_LayoutRebuildQueue.Count; i++)
|
||||
{
|
||||
m_LayoutRebuildQueue[i].Rebuild(CanvasUpdate.Prelayout);
|
||||
}
|
||||
|
||||
if (m_LayoutRebuildQueue.Count > 0)
|
||||
{
|
||||
m_LayoutRebuildQueue.Clear();
|
||||
m_LayoutQueueLookup.Clear();
|
||||
}
|
||||
|
||||
// Handle Graphic Rebuild Phase
|
||||
for (int i = 0; i < m_GraphicRebuildQueue.Count; i++)
|
||||
{
|
||||
m_GraphicRebuildQueue[i].Rebuild(CanvasUpdate.PreRender);
|
||||
}
|
||||
|
||||
// If there are no objects in the queue, we don't need to clear the lists again.
|
||||
if (m_GraphicRebuildQueue.Count > 0)
|
||||
{
|
||||
m_GraphicRebuildQueue.Clear();
|
||||
m_GraphicQueueLookup.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UnRegisterTextObjectForUpdate(TMP_Text textObject)
|
||||
{
|
||||
TMP_UpdateManager.instance.InternalUnRegisterTextObjectForUpdate(textObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function to unregister elements which no longer require a rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void UnRegisterTextElementForRebuild(TMP_Text element)
|
||||
{
|
||||
TMP_UpdateManager.instance.InternalUnRegisterTextElementForGraphicRebuild(element);
|
||||
TMP_UpdateManager.instance.InternalUnRegisterTextElementForLayoutRebuild(element);
|
||||
TMP_UpdateManager.instance.InternalUnRegisterTextObjectForUpdate(element);
|
||||
}
|
||||
|
||||
private void InternalUnRegisterTextElementForGraphicRebuild(TMP_Text element)
|
||||
{
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
TMP_UpdateManager.instance.m_GraphicRebuildQueue.Remove(element);
|
||||
m_GraphicQueueLookup.Remove(id);
|
||||
}
|
||||
|
||||
private void InternalUnRegisterTextElementForLayoutRebuild(TMP_Text element)
|
||||
{
|
||||
int id = element.GetInstanceID();
|
||||
|
||||
TMP_UpdateManager.instance.m_LayoutRebuildQueue.Remove(element);
|
||||
m_LayoutQueueLookup.Remove(id);
|
||||
}
|
||||
|
||||
private void InternalUnRegisterTextObjectForUpdate(TMP_Text textObject)
|
||||
{
|
||||
int id = textObject.GetInstanceID();
|
||||
|
||||
TMP_UpdateManager.instance.m_InternalUpdateQueue.Remove(textObject);
|
||||
m_InternalUpdateLookup.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 691db8cb70c4426a8ae718465c21345f
|
||||
timeCreated: 1447406424
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,178 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UI.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for handling and scheduling text object updates.
|
||||
/// </summary>
|
||||
public class TMP_UpdateRegistry
|
||||
{
|
||||
private static TMP_UpdateRegistry s_Instance;
|
||||
|
||||
private readonly List<ICanvasElement> m_LayoutRebuildQueue = new List<ICanvasElement>();
|
||||
private Dictionary<int, int> m_LayoutQueueLookup = new Dictionary<int, int>();
|
||||
|
||||
private readonly List<ICanvasElement> m_GraphicRebuildQueue = new List<ICanvasElement>();
|
||||
private Dictionary<int, int> m_GraphicQueueLookup = new Dictionary<int, int>();
|
||||
|
||||
//private bool m_PerformingLayoutUpdate;
|
||||
//private bool m_PerformingGraphicUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// Get a singleton instance of the registry
|
||||
/// </summary>
|
||||
public static TMP_UpdateRegistry instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (TMP_UpdateRegistry.s_Instance == null)
|
||||
TMP_UpdateRegistry.s_Instance = new TMP_UpdateRegistry();
|
||||
return TMP_UpdateRegistry.s_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Register to receive callback from the Canvas System.
|
||||
/// </summary>
|
||||
protected TMP_UpdateRegistry()
|
||||
{
|
||||
//Debug.Log("Adding WillRenderCanvases");
|
||||
Canvas.willRenderCanvases += PerformUpdateForCanvasRendererObjects;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to register elements which require a layout rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void RegisterCanvasElementForLayoutRebuild(ICanvasElement element)
|
||||
{
|
||||
TMP_UpdateRegistry.instance.InternalRegisterCanvasElementForLayoutRebuild(element);
|
||||
}
|
||||
|
||||
private bool InternalRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
|
||||
{
|
||||
int id = (element as Object).GetInstanceID();
|
||||
|
||||
if (this.m_LayoutQueueLookup.ContainsKey(id))
|
||||
return false;
|
||||
|
||||
m_LayoutQueueLookup[id] = id;
|
||||
this.m_LayoutRebuildQueue.Add(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to register elements which require a graphic rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void RegisterCanvasElementForGraphicRebuild(ICanvasElement element)
|
||||
{
|
||||
TMP_UpdateRegistry.instance.InternalRegisterCanvasElementForGraphicRebuild(element);
|
||||
}
|
||||
|
||||
private bool InternalRegisterCanvasElementForGraphicRebuild(ICanvasElement element)
|
||||
{
|
||||
int id = (element as Object).GetInstanceID();
|
||||
|
||||
if (this.m_GraphicQueueLookup.ContainsKey(id))
|
||||
return false;
|
||||
|
||||
m_GraphicQueueLookup[id] = id;
|
||||
this.m_GraphicRebuildQueue.Add(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to handle objects that need updating.
|
||||
/// </summary>
|
||||
private void PerformUpdateForCanvasRendererObjects()
|
||||
{
|
||||
//Debug.Log("Performing update of CanvasRenderer objects at Frame: " + Time.frameCount);
|
||||
|
||||
// Processing elements that require a layout rebuild.
|
||||
//this.m_PerformingLayoutUpdate = true;
|
||||
for (int index = 0; index < m_LayoutRebuildQueue.Count; index++)
|
||||
{
|
||||
ICanvasElement element = TMP_UpdateRegistry.instance.m_LayoutRebuildQueue[index];
|
||||
|
||||
element.Rebuild(CanvasUpdate.Prelayout);
|
||||
}
|
||||
|
||||
if (m_LayoutRebuildQueue.Count > 0)
|
||||
{
|
||||
m_LayoutRebuildQueue.Clear();
|
||||
m_LayoutQueueLookup.Clear();
|
||||
}
|
||||
|
||||
// Update font assets before graphic rebuild
|
||||
|
||||
|
||||
// Processing elements that require a graphic rebuild.
|
||||
for (int index = 0; index < m_GraphicRebuildQueue.Count; index++)
|
||||
{
|
||||
ICanvasElement element = TMP_UpdateRegistry.instance.m_GraphicRebuildQueue[index];
|
||||
|
||||
element.Rebuild(CanvasUpdate.PreRender);
|
||||
}
|
||||
|
||||
// If there are no objects in the queue, we don't need to clear the lists again.
|
||||
if (m_GraphicRebuildQueue.Count > 0)
|
||||
{
|
||||
m_GraphicRebuildQueue.Clear();
|
||||
m_GraphicQueueLookup.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to handle objects that need updating.
|
||||
/// </summary>
|
||||
private void PerformUpdateForMeshRendererObjects()
|
||||
{
|
||||
Debug.Log("Perform update of MeshRenderer objects.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Function to unregister elements which no longer require a rebuild.
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
public static void UnRegisterCanvasElementForRebuild(ICanvasElement element)
|
||||
{
|
||||
TMP_UpdateRegistry.instance.InternalUnRegisterCanvasElementForLayoutRebuild(element);
|
||||
TMP_UpdateRegistry.instance.InternalUnRegisterCanvasElementForGraphicRebuild(element);
|
||||
}
|
||||
|
||||
|
||||
private void InternalUnRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
|
||||
{
|
||||
int id = (element as Object).GetInstanceID();
|
||||
|
||||
//element.LayoutComplete();
|
||||
TMP_UpdateRegistry.instance.m_LayoutRebuildQueue.Remove(element);
|
||||
m_GraphicQueueLookup.Remove(id);
|
||||
}
|
||||
|
||||
|
||||
private void InternalUnRegisterCanvasElementForGraphicRebuild(ICanvasElement element)
|
||||
{
|
||||
int id = (element as Object).GetInstanceID();
|
||||
|
||||
//element.GraphicUpdateComplete();
|
||||
TMP_UpdateRegistry.instance.m_GraphicRebuildQueue.Remove(element);
|
||||
m_LayoutQueueLookup.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a55fb7b4961a425381d1282fc424f966
|
||||
timeCreated: 1446775434
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,150 @@
|
|||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public enum Compute_DistanceTransform_EventTypes { Processing, Completed };
|
||||
|
||||
|
||||
public static class TMPro_EventManager
|
||||
{
|
||||
public static readonly FastAction<object, Compute_DT_EventArgs> COMPUTE_DT_EVENT = new FastAction<object, Compute_DT_EventArgs>();
|
||||
|
||||
// Event & Delegate used to notify TextMesh Pro objects that Material properties have been changed.
|
||||
public static readonly FastAction<bool, Material> MATERIAL_PROPERTY_EVENT = new FastAction<bool, Material>();
|
||||
|
||||
public static readonly FastAction<bool, TMP_FontAsset> FONT_PROPERTY_EVENT = new FastAction<bool, TMP_FontAsset>();
|
||||
|
||||
public static readonly FastAction<bool, Object> SPRITE_ASSET_PROPERTY_EVENT = new FastAction<bool, Object>();
|
||||
|
||||
public static readonly FastAction<bool, TextMeshPro> TEXTMESHPRO_PROPERTY_EVENT = new FastAction<bool, TextMeshPro>();
|
||||
|
||||
public static readonly FastAction<GameObject, Material, Material> DRAG_AND_DROP_MATERIAL_EVENT = new FastAction<GameObject, Material, Material>();
|
||||
|
||||
public static readonly FastAction<bool> TEXT_STYLE_PROPERTY_EVENT = new FastAction<bool>();
|
||||
|
||||
public static readonly FastAction<TMP_ColorGradient> COLOR_GRADIENT_PROPERTY_EVENT = new FastAction<TMP_ColorGradient>();
|
||||
|
||||
public static readonly FastAction TMP_SETTINGS_PROPERTY_EVENT = new FastAction();
|
||||
|
||||
public static readonly FastAction RESOURCE_LOAD_EVENT = new FastAction();
|
||||
|
||||
public static readonly FastAction<bool, TextMeshProUGUI> TEXTMESHPRO_UGUI_PROPERTY_EVENT = new FastAction<bool, TextMeshProUGUI>();
|
||||
|
||||
public static readonly FastAction OnPreRenderObject_Event = new FastAction();
|
||||
|
||||
public static readonly FastAction<Object> TEXT_CHANGED_EVENT = new FastAction<Object>();
|
||||
|
||||
//public static readonly FastAction WILL_RENDER_CANVASES = new FastAction();
|
||||
|
||||
|
||||
|
||||
//static TMPro_EventManager()
|
||||
//{
|
||||
// // Register to the willRenderCanvases callback once
|
||||
// // then the WILL_RENDER_CANVASES FastAction will handle the rest
|
||||
// Canvas.willRenderCanvases += WILL_RENDER_CANVASES.Call;
|
||||
//}
|
||||
|
||||
public static void ON_PRE_RENDER_OBJECT_CHANGED()
|
||||
{
|
||||
OnPreRenderObject_Event.Call();
|
||||
}
|
||||
|
||||
public static void ON_MATERIAL_PROPERTY_CHANGED(bool isChanged, Material mat)
|
||||
{
|
||||
MATERIAL_PROPERTY_EVENT.Call(isChanged, mat);
|
||||
}
|
||||
|
||||
public static void ON_FONT_PROPERTY_CHANGED(bool isChanged, TMP_FontAsset font)
|
||||
{
|
||||
FONT_PROPERTY_EVENT.Call(isChanged, font);
|
||||
}
|
||||
|
||||
public static void ON_SPRITE_ASSET_PROPERTY_CHANGED(bool isChanged, Object obj)
|
||||
{
|
||||
SPRITE_ASSET_PROPERTY_EVENT.Call(isChanged, obj);
|
||||
}
|
||||
|
||||
public static void ON_TEXTMESHPRO_PROPERTY_CHANGED(bool isChanged, TextMeshPro obj)
|
||||
{
|
||||
TEXTMESHPRO_PROPERTY_EVENT.Call(isChanged, obj);
|
||||
}
|
||||
|
||||
public static void ON_DRAG_AND_DROP_MATERIAL_CHANGED(GameObject sender, Material currentMaterial, Material newMaterial)
|
||||
{
|
||||
DRAG_AND_DROP_MATERIAL_EVENT.Call(sender, currentMaterial, newMaterial);
|
||||
}
|
||||
|
||||
public static void ON_TEXT_STYLE_PROPERTY_CHANGED(bool isChanged)
|
||||
{
|
||||
TEXT_STYLE_PROPERTY_EVENT.Call(isChanged);
|
||||
}
|
||||
|
||||
public static void ON_COLOR_GRAIDENT_PROPERTY_CHANGED(TMP_ColorGradient gradient)
|
||||
{
|
||||
COLOR_GRADIENT_PROPERTY_EVENT.Call(gradient);
|
||||
}
|
||||
|
||||
|
||||
public static void ON_TEXT_CHANGED(Object obj)
|
||||
{
|
||||
TEXT_CHANGED_EVENT.Call(obj);
|
||||
}
|
||||
|
||||
public static void ON_TMP_SETTINGS_CHANGED()
|
||||
{
|
||||
TMP_SETTINGS_PROPERTY_EVENT.Call();
|
||||
}
|
||||
|
||||
public static void ON_RESOURCES_LOADED()
|
||||
{
|
||||
RESOURCE_LOAD_EVENT.Call();
|
||||
}
|
||||
|
||||
public static void ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED(bool isChanged, TextMeshProUGUI obj)
|
||||
{
|
||||
TEXTMESHPRO_UGUI_PROPERTY_EVENT.Call(isChanged, obj);
|
||||
}
|
||||
|
||||
//public static void ON_BASE_MATERIAL_CHANGED(Material mat)
|
||||
//{
|
||||
// BASE_MATERIAL_EVENT.Call(mat);
|
||||
//}
|
||||
|
||||
//public static void ON_PROGRESSBAR_UPDATE(Progress_Bar_EventTypes event_type, Progress_Bar_EventArgs eventArgs)
|
||||
//{
|
||||
// if (PROGRESS_BAR_EVENT != null)
|
||||
// PROGRESS_BAR_EVENT(event_type, eventArgs);
|
||||
//}
|
||||
|
||||
public static void ON_COMPUTE_DT_EVENT(object Sender, Compute_DT_EventArgs e)
|
||||
{
|
||||
COMPUTE_DT_EVENT.Call(Sender, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Compute_DT_EventArgs
|
||||
{
|
||||
public Compute_DistanceTransform_EventTypes EventType;
|
||||
public float ProgressPercentage;
|
||||
public Color[] Colors;
|
||||
|
||||
|
||||
public Compute_DT_EventArgs(Compute_DistanceTransform_EventTypes type, float progress)
|
||||
{
|
||||
EventType = type;
|
||||
ProgressPercentage = progress;
|
||||
}
|
||||
|
||||
public Compute_DT_EventArgs(Compute_DistanceTransform_EventTypes type, Color[] colors)
|
||||
{
|
||||
EventType = type;
|
||||
Colors = colors;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 96e9072453a441618754c478755b3028
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,224 @@
|
|||
using UnityEngine;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public static class TMPro_ExtensionMethods
|
||||
{
|
||||
|
||||
public static string ArrayToString(this char[] chars)
|
||||
{
|
||||
string s = string.Empty;
|
||||
|
||||
for (int i = 0; i < chars.Length && chars[i] != 0; i++)
|
||||
{
|
||||
s += chars[i];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static string IntToString(this int[] unicodes)
|
||||
{
|
||||
char[] chars = new char[unicodes.Length];
|
||||
|
||||
for (int i = 0; i < unicodes.Length; i++)
|
||||
{
|
||||
chars[i] = (char)unicodes[i];
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
public static string IntToString(this int[] unicodes, int start, int length)
|
||||
{
|
||||
if (start > unicodes.Length)
|
||||
return string.Empty;
|
||||
|
||||
int end = Mathf.Min(start + length, unicodes.Length);
|
||||
|
||||
char[] chars = new char[end - start];
|
||||
|
||||
int writeIndex = 0;
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
chars[writeIndex++] = (char)unicodes[i];
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
|
||||
public static int FindInstanceID <T> (this List<T> list, T target) where T : Object
|
||||
{
|
||||
int targetID = target.GetInstanceID();
|
||||
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (list[i].GetInstanceID() == targetID)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public static bool Compare(this Color32 a, Color32 b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
|
||||
}
|
||||
|
||||
public static bool CompareRGB(this Color32 a, Color32 b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b;
|
||||
}
|
||||
|
||||
public static bool Compare(this Color a, Color b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
|
||||
}
|
||||
|
||||
|
||||
public static bool CompareRGB(this Color a, Color b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b;
|
||||
}
|
||||
|
||||
|
||||
public static Color32 Multiply (this Color32 c1, Color32 c2)
|
||||
{
|
||||
byte r = (byte)((c1.r / 255f) * (c2.r / 255f) * 255);
|
||||
byte g = (byte)((c1.g / 255f) * (c2.g / 255f) * 255);
|
||||
byte b = (byte)((c1.b / 255f) * (c2.b / 255f) * 255);
|
||||
byte a = (byte)((c1.a / 255f) * (c2.a / 255f) * 255);
|
||||
|
||||
return new Color32(r, g, b, a);
|
||||
}
|
||||
|
||||
|
||||
public static Color32 Tint (this Color32 c1, Color32 c2)
|
||||
{
|
||||
byte r = (byte)((c1.r / 255f) * (c2.r / 255f) * 255);
|
||||
byte g = (byte)((c1.g / 255f) * (c2.g / 255f) * 255);
|
||||
byte b = (byte)((c1.b / 255f) * (c2.b / 255f) * 255);
|
||||
byte a = (byte)((c1.a / 255f) * (c2.a / 255f) * 255);
|
||||
|
||||
return new Color32(r, g, b, a);
|
||||
}
|
||||
|
||||
public static Color32 Tint(this Color32 c1, float tint)
|
||||
{
|
||||
byte r = (byte)(Mathf.Clamp(c1.r / 255f * tint * 255, 0, 255));
|
||||
byte g = (byte)(Mathf.Clamp(c1.g / 255f * tint * 255, 0, 255));
|
||||
byte b = (byte)(Mathf.Clamp(c1.b / 255f * tint * 255, 0, 255));
|
||||
byte a = (byte)(Mathf.Clamp(c1.a / 255f * tint * 255, 0, 255));
|
||||
|
||||
return new Color32(r, g, b, a);
|
||||
}
|
||||
|
||||
|
||||
public static bool Compare(this Vector3 v1, Vector3 v2, int accuracy)
|
||||
{
|
||||
bool x = (int)(v1.x * accuracy) == (int)(v2.x * accuracy);
|
||||
bool y = (int)(v1.y * accuracy) == (int)(v2.y * accuracy);
|
||||
bool z = (int)(v1.z * accuracy) == (int)(v2.z * accuracy);
|
||||
|
||||
return x && y && z;
|
||||
}
|
||||
|
||||
public static bool Compare(this Quaternion q1, Quaternion q2, int accuracy)
|
||||
{
|
||||
bool x = (int)(q1.x * accuracy) == (int)(q2.x * accuracy);
|
||||
bool y = (int)(q1.y * accuracy) == (int)(q2.y * accuracy);
|
||||
bool z = (int)(q1.z * accuracy) == (int)(q2.z * accuracy);
|
||||
bool w = (int)(q1.w * accuracy) == (int)(q2.w * accuracy);
|
||||
|
||||
return x && y && z && w;
|
||||
}
|
||||
|
||||
//public static void AddElementAtIndex<T>(this T[] array, int writeIndex, T item)
|
||||
//{
|
||||
// if (writeIndex >= array.Length)
|
||||
// System.Array.Resize(ref array, Mathf.NextPowerOfTwo(writeIndex + 1));
|
||||
|
||||
// array[writeIndex] = item;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Insert item into array at index.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="item"></param>
|
||||
//public static void Insert<T>(this T[] array, int index, T item)
|
||||
//{
|
||||
// if (index > array.Length - 1) return;
|
||||
|
||||
// T savedItem = item;
|
||||
|
||||
// for (int i = index; i < array.Length; i++)
|
||||
// {
|
||||
// savedItem = array[i];
|
||||
|
||||
// array[i] = item;
|
||||
|
||||
// item = savedItem;
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Insert item into array at index.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="item"></param>
|
||||
//public static void Insert<T>(this T[] array, int index, T[] items)
|
||||
//{
|
||||
// if (index > array.Length - 1) return;
|
||||
|
||||
// System.Array.Resize(ref array, array.Length + items.Length);
|
||||
|
||||
// int sourceIndex = 0;
|
||||
|
||||
// T savedItem = items[sourceIndex];
|
||||
|
||||
// for (int i = index; i < array.Length; i++)
|
||||
// {
|
||||
// savedItem = array[i];
|
||||
|
||||
// array[i] = items[sourceIndex];
|
||||
|
||||
// items[sourceIndex] = savedItem;
|
||||
|
||||
// if (sourceIndex < items.Length - 1)
|
||||
// sourceIndex += 1;
|
||||
// else
|
||||
// sourceIndex = 0;
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
public static class TMP_Math
|
||||
{
|
||||
public const float FLOAT_MAX = 32767;
|
||||
public const float FLOAT_MIN = -32767;
|
||||
public const int INT_MAX = 2147483647;
|
||||
public const int INT_MIN = -2147483647;
|
||||
|
||||
public const float FLOAT_UNSET = -32767;
|
||||
public const int INT_UNSET = -32767;
|
||||
|
||||
public static Vector2 MAX_16BIT = new Vector2(FLOAT_MAX, FLOAT_MAX);
|
||||
public static Vector2 MIN_16BIT = new Vector2(FLOAT_MIN, FLOAT_MIN);
|
||||
|
||||
public static bool Approximately(float a, float b)
|
||||
{
|
||||
return (b - 0.0001f) < a && a < (b + 0.0001f);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 77476292f9fa4905a787e6417853846b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue