The fucking 3rd time i had to upload this project to git
This commit is contained in:
@ -0,0 +1,121 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class Benchmark01 : MonoBehaviour
|
||||
{
|
||||
private const string label01 = "The <#0050FF>count is: </color>{0}";
|
||||
private const string label02 = "The <color=#0050FF>count is: </color>";
|
||||
|
||||
public int BenchmarkType;
|
||||
|
||||
public TMP_FontAsset TMProFont;
|
||||
public Font TextMeshFont;
|
||||
|
||||
//private string m_string;
|
||||
//private int m_frame;
|
||||
|
||||
private Material m_material01;
|
||||
private Material m_material02;
|
||||
private TextContainer m_textContainer;
|
||||
private TextMesh m_textMesh;
|
||||
|
||||
private TextMeshPro m_textMeshPro;
|
||||
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
if (BenchmarkType == 0) // TextMesh Pro Component
|
||||
{
|
||||
m_textMeshPro = gameObject.AddComponent<TextMeshPro>();
|
||||
m_textMeshPro.autoSizeTextContainer = true;
|
||||
|
||||
//m_textMeshPro.anchorDampening = true;
|
||||
|
||||
if (TMProFont != null)
|
||||
m_textMeshPro.font = TMProFont;
|
||||
|
||||
//m_textMeshPro.font = Resources.Load("Fonts & Materials/Anton SDF", typeof(TextMeshProFont)) as TextMeshProFont; // Make sure the Anton SDF exists before calling this...
|
||||
//m_textMeshPro.fontSharedMaterial = Resources.Load("Fonts & Materials/Anton SDF", typeof(Material)) as Material; // Same as above make sure this material exists.
|
||||
|
||||
m_textMeshPro.fontSize = 48;
|
||||
m_textMeshPro.alignment = TextAlignmentOptions.Center;
|
||||
//m_textMeshPro.anchor = AnchorPositions.Center;
|
||||
m_textMeshPro.extraPadding = true;
|
||||
//m_textMeshPro.outlineWidth = 0.25f;
|
||||
//m_textMeshPro.fontSharedMaterial.SetFloat("_OutlineWidth", 0.2f);
|
||||
//m_textMeshPro.fontSharedMaterial.EnableKeyword("UNDERLAY_ON");
|
||||
//m_textMeshPro.lineJustification = LineJustificationTypes.Center;
|
||||
m_textMeshPro.enableWordWrapping = false;
|
||||
//m_textMeshPro.lineLength = 60;
|
||||
//m_textMeshPro.characterSpacing = 0.2f;
|
||||
//m_textMeshPro.fontColor = new Color32(255, 255, 255, 255);
|
||||
|
||||
m_material01 = m_textMeshPro.font.material;
|
||||
m_material02 =
|
||||
Resources.Load<Material>(
|
||||
"Fonts & Materials/LiberationSans SDF - Drop Shadow"); // Make sure the LiberationSans SDF exists before calling this...
|
||||
}
|
||||
else if (BenchmarkType == 1) // TextMesh
|
||||
{
|
||||
m_textMesh = gameObject.AddComponent<TextMesh>();
|
||||
|
||||
if (TextMeshFont != null)
|
||||
{
|
||||
m_textMesh.font = TextMeshFont;
|
||||
m_textMesh.GetComponent<Renderer>().sharedMaterial = m_textMesh.font.material;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textMesh.font = Resources.Load("Fonts/ARIAL", typeof(Font)) as Font;
|
||||
m_textMesh.GetComponent<Renderer>().sharedMaterial = m_textMesh.font.material;
|
||||
}
|
||||
|
||||
m_textMesh.fontSize = 48;
|
||||
m_textMesh.anchor = TextAnchor.MiddleCenter;
|
||||
|
||||
//m_textMesh.color = new Color32(255, 255, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i <= 1000000; i++)
|
||||
{
|
||||
if (BenchmarkType == 0)
|
||||
{
|
||||
m_textMeshPro.SetText(label01, i % 1000);
|
||||
if (i % 1000 == 999)
|
||||
m_textMeshPro.fontSharedMaterial = m_textMeshPro.fontSharedMaterial == m_material01
|
||||
? m_textMeshPro.fontSharedMaterial = m_material02
|
||||
: m_textMeshPro.fontSharedMaterial = m_material01;
|
||||
}
|
||||
else if (BenchmarkType == 1)
|
||||
{
|
||||
m_textMesh.text = label02 + (i % 1000);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void Update()
|
||||
{
|
||||
if (BenchmarkType == 0)
|
||||
{
|
||||
m_textMeshPro.text = (m_frame % 1000).ToString();
|
||||
}
|
||||
else if (BenchmarkType == 1)
|
||||
{
|
||||
m_textMesh.text = (m_frame % 1000).ToString();
|
||||
}
|
||||
|
||||
m_frame += 1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f970ea55f9f84bf79b05dab180b8c125
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,126 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class Benchmark01_UGUI : MonoBehaviour
|
||||
{
|
||||
private const string label01 = "The <#0050FF>count is: </color>";
|
||||
private const string label02 = "The <color=#0050FF>count is: </color>";
|
||||
|
||||
public int BenchmarkType;
|
||||
|
||||
public Canvas canvas;
|
||||
public TMP_FontAsset TMProFont;
|
||||
public Font TextMeshFont;
|
||||
|
||||
//private const string label01 = "TextMesh <#0050FF>Pro!</color> The count is: {0}";
|
||||
//private const string label02 = "Text Mesh<color=#0050FF> The count is: </color>";
|
||||
|
||||
//private string m_string;
|
||||
//private int m_frame;
|
||||
|
||||
private Material m_material01;
|
||||
|
||||
private Material m_material02;
|
||||
|
||||
//private TextContainer m_textContainer;
|
||||
private Text m_textMesh;
|
||||
|
||||
private TextMeshProUGUI m_textMeshPro;
|
||||
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
if (BenchmarkType == 0) // TextMesh Pro Component
|
||||
{
|
||||
m_textMeshPro = gameObject.AddComponent<TextMeshProUGUI>();
|
||||
//m_textContainer = GetComponent<TextContainer>();
|
||||
|
||||
|
||||
//m_textMeshPro.anchorDampening = true;
|
||||
|
||||
if (TMProFont != null)
|
||||
m_textMeshPro.font = TMProFont;
|
||||
|
||||
//m_textMeshPro.font = Resources.Load("Fonts & Materials/Anton SDF", typeof(TextMeshProFont)) as TextMeshProFont; // Make sure the Anton SDF exists before calling this...
|
||||
//m_textMeshPro.fontSharedMaterial = Resources.Load("Fonts & Materials/Anton SDF", typeof(Material)) as Material; // Same as above make sure this material exists.
|
||||
|
||||
m_textMeshPro.fontSize = 48;
|
||||
m_textMeshPro.alignment = TextAlignmentOptions.Center;
|
||||
//m_textMeshPro.anchor = AnchorPositions.Center;
|
||||
m_textMeshPro.extraPadding = true;
|
||||
//m_textMeshPro.outlineWidth = 0.25f;
|
||||
//m_textMeshPro.fontSharedMaterial.SetFloat("_OutlineWidth", 0.2f);
|
||||
//m_textMeshPro.fontSharedMaterial.EnableKeyword("UNDERLAY_ON");
|
||||
//m_textMeshPro.lineJustification = LineJustificationTypes.Center;
|
||||
//m_textMeshPro.enableWordWrapping = true;
|
||||
//m_textMeshPro.lineLength = 60;
|
||||
//m_textMeshPro.characterSpacing = 0.2f;
|
||||
//m_textMeshPro.fontColor = new Color32(255, 255, 255, 255);
|
||||
|
||||
m_material01 = m_textMeshPro.font.material;
|
||||
m_material02 =
|
||||
Resources.Load<Material>(
|
||||
"Fonts & Materials/LiberationSans SDF - BEVEL"); // Make sure the LiberationSans SDF exists before calling this...
|
||||
}
|
||||
else if (BenchmarkType == 1) // TextMesh
|
||||
{
|
||||
m_textMesh = gameObject.AddComponent<Text>();
|
||||
|
||||
if (TextMeshFont != null)
|
||||
{
|
||||
m_textMesh.font = TextMeshFont;
|
||||
//m_textMesh.renderer.sharedMaterial = m_textMesh.font.material;
|
||||
}
|
||||
|
||||
//m_textMesh.font = Resources.Load("Fonts/ARIAL", typeof(Font)) as Font;
|
||||
//m_textMesh.renderer.sharedMaterial = m_textMesh.font.material;
|
||||
m_textMesh.fontSize = 48;
|
||||
m_textMesh.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
//m_textMesh.color = new Color32(255, 255, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i <= 1000000; i++)
|
||||
{
|
||||
if (BenchmarkType == 0)
|
||||
{
|
||||
m_textMeshPro.text = label01 + i % 1000;
|
||||
if (i % 1000 == 999)
|
||||
m_textMeshPro.fontSharedMaterial = m_textMeshPro.fontSharedMaterial == m_material01
|
||||
? m_textMeshPro.fontSharedMaterial = m_material02
|
||||
: m_textMeshPro.fontSharedMaterial = m_material01;
|
||||
}
|
||||
else if (BenchmarkType == 1)
|
||||
{
|
||||
m_textMesh.text = label02 + (i % 1000);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void Update()
|
||||
{
|
||||
if (BenchmarkType == 0)
|
||||
{
|
||||
m_textMeshPro.text = (m_frame % 1000).ToString();
|
||||
}
|
||||
else if (BenchmarkType == 1)
|
||||
{
|
||||
m_textMesh.text = (m_frame % 1000).ToString();
|
||||
}
|
||||
|
||||
m_frame += 1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ef7be1c625941f7ba8ed7cc71718c0d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,85 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class Benchmark02 : MonoBehaviour
|
||||
{
|
||||
public int SpawnType;
|
||||
public int NumberOfNPC = 12;
|
||||
|
||||
public bool IsTextObjectScaleStatic;
|
||||
private TextMeshProFloatingText floatingText_Script;
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
for (var i = 0; i < NumberOfNPC; i++)
|
||||
if (SpawnType == 0)
|
||||
{
|
||||
// TextMesh Pro Implementation
|
||||
var go = new GameObject();
|
||||
go.transform.position = new Vector3(Random.Range(-95f, 95f), 0.25f, Random.Range(-95f, 95f));
|
||||
|
||||
var textMeshPro = go.AddComponent<TextMeshPro>();
|
||||
|
||||
textMeshPro.autoSizeTextContainer = true;
|
||||
textMeshPro.rectTransform.pivot = new Vector2(0.5f, 0);
|
||||
|
||||
textMeshPro.alignment = TextAlignmentOptions.Bottom;
|
||||
textMeshPro.fontSize = 96;
|
||||
textMeshPro.enableKerning = false;
|
||||
|
||||
textMeshPro.color = new Color32(255, 255, 0, 255);
|
||||
textMeshPro.text = "!";
|
||||
textMeshPro.isTextObjectScaleStatic = IsTextObjectScaleStatic;
|
||||
|
||||
// Spawn Floating Text
|
||||
floatingText_Script = go.AddComponent<TextMeshProFloatingText>();
|
||||
floatingText_Script.SpawnType = 0;
|
||||
floatingText_Script.IsTextObjectScaleStatic = IsTextObjectScaleStatic;
|
||||
}
|
||||
else if (SpawnType == 1)
|
||||
{
|
||||
// TextMesh Implementation
|
||||
var go = new GameObject();
|
||||
go.transform.position = new Vector3(Random.Range(-95f, 95f), 0.25f, Random.Range(-95f, 95f));
|
||||
|
||||
var textMesh = go.AddComponent<TextMesh>();
|
||||
textMesh.font = Resources.Load<Font>("Fonts/ARIAL");
|
||||
textMesh.GetComponent<Renderer>().sharedMaterial = textMesh.font.material;
|
||||
|
||||
textMesh.anchor = TextAnchor.LowerCenter;
|
||||
textMesh.fontSize = 96;
|
||||
|
||||
textMesh.color = new Color32(255, 255, 0, 255);
|
||||
textMesh.text = "!";
|
||||
|
||||
// Spawn Floating Text
|
||||
floatingText_Script = go.AddComponent<TextMeshProFloatingText>();
|
||||
floatingText_Script.SpawnType = 1;
|
||||
}
|
||||
else if (SpawnType == 2)
|
||||
{
|
||||
// Canvas WorldSpace Camera
|
||||
var go = new GameObject();
|
||||
var canvas = go.AddComponent<Canvas>();
|
||||
canvas.worldCamera = Camera.main;
|
||||
|
||||
go.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
|
||||
go.transform.position = new Vector3(Random.Range(-95f, 95f), 5f, Random.Range(-95f, 95f));
|
||||
|
||||
var textObject = new GameObject().AddComponent<TextMeshProUGUI>();
|
||||
textObject.rectTransform.SetParent(go.transform, false);
|
||||
|
||||
textObject.color = new Color32(255, 255, 0, 255);
|
||||
textObject.alignment = TextAlignmentOptions.Bottom;
|
||||
textObject.fontSize = 96;
|
||||
textObject.text = "!";
|
||||
|
||||
// Spawn Floating Text
|
||||
floatingText_Script = go.AddComponent<TextMeshProFloatingText>();
|
||||
floatingText_Script.SpawnType = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8538afcddc14efbb5d9e94b7ae50197
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- TheFont: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,91 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class Benchmark03 : MonoBehaviour
|
||||
{
|
||||
public enum BenchmarkType
|
||||
{
|
||||
TMP_SDF_MOBILE = 0,
|
||||
TMP_SDF__MOBILE_SSD = 1,
|
||||
TMP_SDF = 2,
|
||||
TMP_BITMAP_MOBILE = 3,
|
||||
TEXTMESH_BITMAP = 4
|
||||
}
|
||||
|
||||
public int NumberOfSamples = 100;
|
||||
public BenchmarkType Benchmark;
|
||||
|
||||
public Font SourceFont;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
TMP_FontAsset fontAsset = null;
|
||||
|
||||
// Create Dynamic Font Asset for the given font file.
|
||||
switch (Benchmark)
|
||||
{
|
||||
case BenchmarkType.TMP_SDF_MOBILE:
|
||||
fontAsset = TMP_FontAsset.CreateFontAsset(SourceFont, 90, 9, GlyphRenderMode.SDFAA, 256, 256);
|
||||
break;
|
||||
case BenchmarkType.TMP_SDF__MOBILE_SSD:
|
||||
fontAsset = TMP_FontAsset.CreateFontAsset(SourceFont, 90, 9, GlyphRenderMode.SDFAA, 256, 256);
|
||||
fontAsset.material.shader = Shader.Find("TextMeshPro/Mobile/Distance Field SSD");
|
||||
break;
|
||||
case BenchmarkType.TMP_SDF:
|
||||
fontAsset = TMP_FontAsset.CreateFontAsset(SourceFont, 90, 9, GlyphRenderMode.SDFAA, 256, 256);
|
||||
fontAsset.material.shader = Shader.Find("TextMeshPro/Distance Field");
|
||||
break;
|
||||
case BenchmarkType.TMP_BITMAP_MOBILE:
|
||||
fontAsset = TMP_FontAsset.CreateFontAsset(SourceFont, 90, 9, GlyphRenderMode.SMOOTH, 256, 256);
|
||||
break;
|
||||
}
|
||||
|
||||
for (var i = 0; i < NumberOfSamples; i++)
|
||||
switch (Benchmark)
|
||||
{
|
||||
case BenchmarkType.TMP_SDF_MOBILE:
|
||||
case BenchmarkType.TMP_SDF__MOBILE_SSD:
|
||||
case BenchmarkType.TMP_SDF:
|
||||
case BenchmarkType.TMP_BITMAP_MOBILE:
|
||||
{
|
||||
var go = new GameObject();
|
||||
go.transform.position = new Vector3(0, 1.2f, 0);
|
||||
|
||||
var textComponent = go.AddComponent<TextMeshPro>();
|
||||
textComponent.font = fontAsset;
|
||||
textComponent.fontSize = 128;
|
||||
textComponent.text = "@";
|
||||
textComponent.alignment = TextAlignmentOptions.Center;
|
||||
textComponent.color = new Color32(255, 255, 0, 255);
|
||||
|
||||
if (Benchmark == BenchmarkType.TMP_BITMAP_MOBILE)
|
||||
textComponent.fontSize = 132;
|
||||
}
|
||||
break;
|
||||
case BenchmarkType.TEXTMESH_BITMAP:
|
||||
{
|
||||
var go = new GameObject();
|
||||
go.transform.position = new Vector3(0, 1.2f, 0);
|
||||
|
||||
var textMesh = go.AddComponent<TextMesh>();
|
||||
textMesh.GetComponent<Renderer>().sharedMaterial = SourceFont.material;
|
||||
textMesh.font = SourceFont;
|
||||
textMesh.anchor = TextAnchor.MiddleCenter;
|
||||
textMesh.fontSize = 130;
|
||||
|
||||
textMesh.color = new Color32(255, 255, 0, 255);
|
||||
textMesh.text = "@";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a73109742c8d47ac822895a473300c29
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- TheFont: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,77 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class Benchmark04 : MonoBehaviour
|
||||
{
|
||||
public int SpawnType;
|
||||
|
||||
public int MinPointSize = 12;
|
||||
public int MaxPointSize = 64;
|
||||
public int Steps = 4;
|
||||
|
||||
private Transform m_Transform;
|
||||
//private TextMeshProFloatingText floatingText_Script;
|
||||
//public Material material;
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
m_Transform = transform;
|
||||
|
||||
float lineHeight = 0;
|
||||
var orthoSize = Camera.main.orthographicSize = Screen.height / 2;
|
||||
var ratio = (float)Screen.width / Screen.height;
|
||||
|
||||
for (var i = MinPointSize; i <= MaxPointSize; i += Steps)
|
||||
if (SpawnType == 0)
|
||||
{
|
||||
// TextMesh Pro Implementation
|
||||
var go = new GameObject("Text - " + i + " Pts");
|
||||
|
||||
if (lineHeight > orthoSize * 2) return;
|
||||
|
||||
go.transform.position = m_Transform.position +
|
||||
new Vector3(ratio * -orthoSize * 0.975f, orthoSize * 0.975f - lineHeight,
|
||||
0);
|
||||
|
||||
var textMeshPro = go.AddComponent<TextMeshPro>();
|
||||
|
||||
//textMeshPro.fontSharedMaterial = material;
|
||||
//textMeshPro.font = Resources.Load("Fonts & Materials/LiberationSans SDF", typeof(TextMeshProFont)) as TextMeshProFont;
|
||||
//textMeshPro.anchor = AnchorPositions.Left;
|
||||
textMeshPro.rectTransform.pivot = new Vector2(0, 0.5f);
|
||||
|
||||
textMeshPro.enableWordWrapping = false;
|
||||
textMeshPro.extraPadding = true;
|
||||
textMeshPro.isOrthographic = true;
|
||||
textMeshPro.fontSize = i;
|
||||
|
||||
textMeshPro.text = i + " pts - Lorem ipsum dolor sit...";
|
||||
textMeshPro.color = new Color32(255, 255, 255, 255);
|
||||
|
||||
lineHeight += i;
|
||||
}
|
||||
// TextMesh Implementation
|
||||
// Causes crashes since atlas needed exceeds 4096 X 4096
|
||||
/*
|
||||
GameObject go = new GameObject("Arial " + i);
|
||||
|
||||
//if (lineHeight > orthoSize * 2 * 0.9f) return;
|
||||
|
||||
go.transform.position = m_Transform.position + new Vector3(ratio * -orthoSize * 0.975f, orthoSize * 0.975f - lineHeight, 1);
|
||||
|
||||
TextMesh textMesh = go.AddComponent<TextMesh>();
|
||||
textMesh.font = Resources.Load("Fonts/ARIAL", typeof(Font)) as Font;
|
||||
textMesh.renderer.sharedMaterial = textMesh.font.material;
|
||||
textMesh.anchor = TextAnchor.MiddleLeft;
|
||||
textMesh.fontSize = i * 10;
|
||||
|
||||
textMesh.color = new Color32(255, 255, 255, 255);
|
||||
textMesh.text = i + " pts - Lorem ipsum dolor sit...";
|
||||
|
||||
lineHeight += i;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc20866c0d5e413ab7559440e15333ae
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- TheFont: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,278 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class CameraController : MonoBehaviour
|
||||
{
|
||||
public enum CameraModes
|
||||
{
|
||||
Follow,
|
||||
Isometric,
|
||||
Free
|
||||
}
|
||||
|
||||
// Controls for Touches on Mobile devices
|
||||
//private float prev_ZoomDelta;
|
||||
|
||||
|
||||
private const string event_SmoothingValue = "Slider - Smoothing Value";
|
||||
private const string event_FollowDistance = "Slider - Camera Zoom";
|
||||
|
||||
public Transform CameraTarget;
|
||||
|
||||
public float FollowDistance = 30.0f;
|
||||
public float MaxFollowDistance = 100.0f;
|
||||
public float MinFollowDistance = 2.0f;
|
||||
|
||||
public float ElevationAngle = 30.0f;
|
||||
public float MaxElevationAngle = 85.0f;
|
||||
public float MinElevationAngle;
|
||||
|
||||
public float OrbitalAngle;
|
||||
|
||||
public CameraModes CameraMode = CameraModes.Follow;
|
||||
|
||||
public bool MovementSmoothing = true;
|
||||
public bool RotationSmoothing;
|
||||
|
||||
public float MovementSmoothingValue = 25f;
|
||||
public float RotationSmoothingValue = 5.0f;
|
||||
|
||||
public float MoveSensitivity = 2.0f;
|
||||
|
||||
private Transform cameraTransform;
|
||||
|
||||
private Vector3 currentVelocity = Vector3.zero;
|
||||
private Vector3 desiredPosition;
|
||||
private Transform dummyTarget;
|
||||
private float mouseWheel;
|
||||
private float mouseX;
|
||||
private float mouseY;
|
||||
private Vector3 moveVector;
|
||||
private bool previousSmoothing;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (QualitySettings.vSyncCount > 0)
|
||||
Application.targetFrameRate = 60;
|
||||
else
|
||||
Application.targetFrameRate = -1;
|
||||
|
||||
if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android)
|
||||
Input.simulateMouseWithTouches = false;
|
||||
|
||||
cameraTransform = transform;
|
||||
previousSmoothing = MovementSmoothing;
|
||||
}
|
||||
|
||||
|
||||
// Use this for initialization
|
||||
private void Start()
|
||||
{
|
||||
if (CameraTarget == null)
|
||||
{
|
||||
// If we don't have a target (assigned by the player, create a dummy in the center of the scene).
|
||||
dummyTarget = new GameObject("Camera Target").transform;
|
||||
CameraTarget = dummyTarget;
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
private void LateUpdate()
|
||||
{
|
||||
GetPlayerInput();
|
||||
|
||||
|
||||
// Check if we still have a valid target
|
||||
if (CameraTarget != null)
|
||||
{
|
||||
if (CameraMode == CameraModes.Isometric)
|
||||
{
|
||||
desiredPosition = CameraTarget.position + Quaternion.Euler(ElevationAngle, OrbitalAngle, 0f) *
|
||||
new Vector3(0, 0, -FollowDistance);
|
||||
}
|
||||
else if (CameraMode == CameraModes.Follow)
|
||||
{
|
||||
desiredPosition = CameraTarget.position + CameraTarget.TransformDirection(
|
||||
Quaternion.Euler(ElevationAngle, OrbitalAngle, 0f) * new Vector3(0, 0, -FollowDistance));
|
||||
}
|
||||
|
||||
// Free Camera implementation
|
||||
if (MovementSmoothing)
|
||||
// Using Smoothing
|
||||
cameraTransform.position = Vector3.SmoothDamp(cameraTransform.position, desiredPosition,
|
||||
ref currentVelocity, MovementSmoothingValue * Time.fixedDeltaTime);
|
||||
//cameraTransform.position = Vector3.Lerp(cameraTransform.position, desiredPosition, Time.deltaTime * 5.0f);
|
||||
else
|
||||
// Not using Smoothing
|
||||
cameraTransform.position = desiredPosition;
|
||||
|
||||
if (RotationSmoothing)
|
||||
cameraTransform.rotation = Quaternion.Lerp(cameraTransform.rotation,
|
||||
Quaternion.LookRotation(CameraTarget.position - cameraTransform.position),
|
||||
RotationSmoothingValue * Time.deltaTime);
|
||||
else
|
||||
cameraTransform.LookAt(CameraTarget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void GetPlayerInput()
|
||||
{
|
||||
moveVector = Vector3.zero;
|
||||
|
||||
// Check Mouse Wheel Input prior to Shift Key so we can apply multiplier on Shift for Scrolling
|
||||
mouseWheel = Input.GetAxis("Mouse ScrollWheel");
|
||||
|
||||
float touchCount = Input.touchCount;
|
||||
|
||||
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) || touchCount > 0)
|
||||
{
|
||||
mouseWheel *= 10;
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.I))
|
||||
CameraMode = CameraModes.Isometric;
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.F))
|
||||
CameraMode = CameraModes.Follow;
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.S))
|
||||
MovementSmoothing = !MovementSmoothing;
|
||||
|
||||
|
||||
// Check for right mouse button to change camera follow and elevation angle
|
||||
if (Input.GetMouseButton(1))
|
||||
{
|
||||
mouseY = Input.GetAxis("Mouse Y");
|
||||
mouseX = Input.GetAxis("Mouse X");
|
||||
|
||||
if (mouseY > 0.01f || mouseY < -0.01f)
|
||||
{
|
||||
ElevationAngle -= mouseY * MoveSensitivity;
|
||||
// Limit Elevation angle between min & max values.
|
||||
ElevationAngle = Mathf.Clamp(ElevationAngle, MinElevationAngle, MaxElevationAngle);
|
||||
}
|
||||
|
||||
if (mouseX > 0.01f || mouseX < -0.01f)
|
||||
{
|
||||
OrbitalAngle += mouseX * MoveSensitivity;
|
||||
if (OrbitalAngle > 360)
|
||||
OrbitalAngle -= 360;
|
||||
if (OrbitalAngle < 0)
|
||||
OrbitalAngle += 360;
|
||||
}
|
||||
}
|
||||
|
||||
// Get Input from Mobile Device
|
||||
if (touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
|
||||
{
|
||||
var deltaPosition = Input.GetTouch(0).deltaPosition;
|
||||
|
||||
// Handle elevation changes
|
||||
if (deltaPosition.y > 0.01f || deltaPosition.y < -0.01f)
|
||||
{
|
||||
ElevationAngle -= deltaPosition.y * 0.1f;
|
||||
// Limit Elevation angle between min & max values.
|
||||
ElevationAngle = Mathf.Clamp(ElevationAngle, MinElevationAngle, MaxElevationAngle);
|
||||
}
|
||||
|
||||
|
||||
// Handle left & right
|
||||
if (deltaPosition.x > 0.01f || deltaPosition.x < -0.01f)
|
||||
{
|
||||
OrbitalAngle += deltaPosition.x * 0.1f;
|
||||
if (OrbitalAngle > 360)
|
||||
OrbitalAngle -= 360;
|
||||
if (OrbitalAngle < 0)
|
||||
OrbitalAngle += 360;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for left mouse button to select a new CameraTarget or to reset Follow position
|
||||
if (Input.GetMouseButton(0))
|
||||
{
|
||||
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||||
RaycastHit hit;
|
||||
|
||||
if (Physics.Raycast(ray, out hit, 300, (1 << 10) | (1 << 11) | (1 << 12) | (1 << 14)))
|
||||
{
|
||||
if (hit.transform == CameraTarget)
|
||||
{
|
||||
// Reset Follow Position
|
||||
OrbitalAngle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CameraTarget = hit.transform;
|
||||
OrbitalAngle = 0;
|
||||
MovementSmoothing = previousSmoothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Input.GetMouseButton(2))
|
||||
{
|
||||
if (dummyTarget == null)
|
||||
{
|
||||
// We need a Dummy Target to anchor the Camera
|
||||
dummyTarget = new GameObject("Camera Target").transform;
|
||||
dummyTarget.position = CameraTarget.position;
|
||||
dummyTarget.rotation = CameraTarget.rotation;
|
||||
CameraTarget = dummyTarget;
|
||||
previousSmoothing = MovementSmoothing;
|
||||
MovementSmoothing = false;
|
||||
}
|
||||
else if (dummyTarget != CameraTarget)
|
||||
{
|
||||
// Move DummyTarget to CameraTarget
|
||||
dummyTarget.position = CameraTarget.position;
|
||||
dummyTarget.rotation = CameraTarget.rotation;
|
||||
CameraTarget = dummyTarget;
|
||||
previousSmoothing = MovementSmoothing;
|
||||
MovementSmoothing = false;
|
||||
}
|
||||
|
||||
|
||||
mouseY = Input.GetAxis("Mouse Y");
|
||||
mouseX = Input.GetAxis("Mouse X");
|
||||
|
||||
moveVector = cameraTransform.TransformDirection(mouseX, mouseY, 0);
|
||||
|
||||
dummyTarget.Translate(-moveVector, Space.World);
|
||||
}
|
||||
}
|
||||
|
||||
// Check Pinching to Zoom in - out on Mobile device
|
||||
if (touchCount == 2)
|
||||
{
|
||||
var touch0 = Input.GetTouch(0);
|
||||
var touch1 = Input.GetTouch(1);
|
||||
|
||||
var touch0PrevPos = touch0.position - touch0.deltaPosition;
|
||||
var touch1PrevPos = touch1.position - touch1.deltaPosition;
|
||||
|
||||
var prevTouchDelta = (touch0PrevPos - touch1PrevPos).magnitude;
|
||||
var touchDelta = (touch0.position - touch1.position).magnitude;
|
||||
|
||||
var zoomDelta = prevTouchDelta - touchDelta;
|
||||
|
||||
if (zoomDelta > 0.01f || zoomDelta < -0.01f)
|
||||
{
|
||||
FollowDistance += zoomDelta * 0.25f;
|
||||
// Limit FollowDistance between min & max values.
|
||||
FollowDistance = Mathf.Clamp(FollowDistance, MinFollowDistance, MaxFollowDistance);
|
||||
}
|
||||
}
|
||||
|
||||
// Check MouseWheel to Zoom in-out
|
||||
if (mouseWheel < -0.01f || mouseWheel > 0.01f)
|
||||
{
|
||||
FollowDistance -= mouseWheel * 5.0f;
|
||||
// Limit FollowDistance between min & max values.
|
||||
FollowDistance = Mathf.Clamp(FollowDistance, MinFollowDistance, MaxFollowDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d687537154440a3913a9a3c7977978c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ChatController : MonoBehaviour
|
||||
{
|
||||
public TMP_InputField ChatInputField;
|
||||
|
||||
public TMP_Text ChatDisplayOutput;
|
||||
|
||||
public Scrollbar ChatScrollbar;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
ChatInputField.onSubmit.AddListener(AddToChatOutput);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
ChatInputField.onSubmit.RemoveListener(AddToChatOutput);
|
||||
}
|
||||
|
||||
|
||||
private void AddToChatOutput(string newText)
|
||||
{
|
||||
// Clear Input Field
|
||||
ChatInputField.text = string.Empty;
|
||||
|
||||
var timeNow = DateTime.Now;
|
||||
|
||||
var formattedInput = "[<#FFFF80>" + timeNow.Hour.ToString("d2") + ":" + timeNow.Minute.ToString("d2") + ":" +
|
||||
timeNow.Second.ToString("d2") + "</color>] " + newText;
|
||||
|
||||
if (ChatDisplayOutput != null)
|
||||
{
|
||||
// No special formatting for first entry
|
||||
// Add line feed before each subsequent entries
|
||||
if (ChatDisplayOutput.text == string.Empty)
|
||||
ChatDisplayOutput.text = formattedInput;
|
||||
else
|
||||
ChatDisplayOutput.text += "\n" + formattedInput;
|
||||
}
|
||||
|
||||
// Keep Chat input field active
|
||||
ChatInputField.ActivateInputField();
|
||||
|
||||
// Set the scrollbar to the bottom when next text is submitted.
|
||||
ChatScrollbar.value = 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53d91f98a2664f5cb9af11de72ac54ec
|
||||
timeCreated: 1487197841
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,18 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
public class DropdownSample : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TextMeshProUGUI text;
|
||||
|
||||
[SerializeField] private TMP_Dropdown dropdownWithoutPlaceholder;
|
||||
|
||||
[SerializeField] private TMP_Dropdown dropdownWithPlaceholder;
|
||||
|
||||
public void OnButtonClick()
|
||||
{
|
||||
text.text = dropdownWithPlaceholder.value > -1
|
||||
? "Selected values:\n" + dropdownWithoutPlaceholder.value + " - " + dropdownWithPlaceholder.value
|
||||
: "Error: Please make a selection";
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac1eb05af6d391b4eb0f4c070a99f1d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,37 @@
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
public class EnvMapAnimator : MonoBehaviour
|
||||
{
|
||||
//private Vector3 TranslationSpeeds;
|
||||
public Vector3 RotationSpeeds;
|
||||
private Material m_material;
|
||||
private TMP_Text m_textMeshPro;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
//Debug.Log("Awake() on Script called.");
|
||||
m_textMeshPro = GetComponent<TMP_Text>();
|
||||
m_material = m_textMeshPro.fontSharedMaterial;
|
||||
}
|
||||
|
||||
// Use this for initialization
|
||||
private IEnumerator Start()
|
||||
{
|
||||
var matrix = new Matrix4x4();
|
||||
|
||||
while (true)
|
||||
{
|
||||
//matrix.SetTRS(new Vector3 (Time.time * TranslationSpeeds.x, Time.time * TranslationSpeeds.y, Time.time * TranslationSpeeds.z), Quaternion.Euler(Time.time * RotationSpeeds.x, Time.time * RotationSpeeds.y , Time.time * RotationSpeeds.z), Vector3.one);
|
||||
matrix.SetTRS(Vector3.zero,
|
||||
Quaternion.Euler(Time.time * RotationSpeeds.x, Time.time * RotationSpeeds.y,
|
||||
Time.time * RotationSpeeds.z), Vector3.one);
|
||||
|
||||
m_material.SetMatrix("_EnvMatrix", matrix);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4b6f99e8bc54541bbd149b014ff441c
|
||||
timeCreated: 1449025325
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,72 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class ObjectSpin : MonoBehaviour
|
||||
{
|
||||
#pragma warning disable 0414
|
||||
|
||||
public float SpinSpeed = 5;
|
||||
public int RotationRange = 15;
|
||||
private Transform m_transform;
|
||||
|
||||
private float m_time;
|
||||
private Vector3 m_prevPOS;
|
||||
private Vector3 m_initial_Rotation;
|
||||
private Vector3 m_initial_Position;
|
||||
private Color32 m_lightColor;
|
||||
private int frames;
|
||||
|
||||
public enum MotionType
|
||||
{
|
||||
Rotation,
|
||||
BackAndForth,
|
||||
Translation
|
||||
}
|
||||
|
||||
public MotionType Motion;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_transform = transform;
|
||||
m_initial_Rotation = m_transform.rotation.eulerAngles;
|
||||
m_initial_Position = m_transform.position;
|
||||
|
||||
var light = GetComponent<Light>();
|
||||
m_lightColor = light != null ? light.color : Color.black;
|
||||
}
|
||||
|
||||
|
||||
// Update is called once per frame
|
||||
private void Update()
|
||||
{
|
||||
if (Motion == MotionType.Rotation)
|
||||
{
|
||||
m_transform.Rotate(0, SpinSpeed * Time.deltaTime, 0);
|
||||
}
|
||||
else if (Motion == MotionType.BackAndForth)
|
||||
{
|
||||
m_time += SpinSpeed * Time.deltaTime;
|
||||
m_transform.rotation = Quaternion.Euler(m_initial_Rotation.x,
|
||||
Mathf.Sin(m_time) * RotationRange + m_initial_Rotation.y, m_initial_Rotation.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_time += SpinSpeed * Time.deltaTime;
|
||||
|
||||
var x = 15 * Mathf.Cos(m_time * .95f);
|
||||
float y = 10; // *Mathf.Sin(m_time * 1f) * Mathf.Cos(m_time * 1f);
|
||||
var z = 0f; // *Mathf.Sin(m_time * .9f);
|
||||
|
||||
m_transform.position = m_initial_Position + new Vector3(x, z, y);
|
||||
|
||||
// Drawing light patterns because they can be cool looking.
|
||||
//if (frames > 2)
|
||||
// Debug.DrawLine(m_transform.position, m_prevPOS, m_lightColor, 100f);
|
||||
|
||||
m_prevPOS = m_transform.position;
|
||||
frames += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f19c7f94c794c5097d8bd11e39c750d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,48 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class ShaderPropAnimator : MonoBehaviour
|
||||
{
|
||||
public AnimationCurve GlowCurve;
|
||||
|
||||
public float m_frame;
|
||||
private Material m_Material;
|
||||
|
||||
private Renderer m_Renderer;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Cache a reference to object's renderer
|
||||
m_Renderer = GetComponent<Renderer>();
|
||||
|
||||
// Cache a reference to object's material and create an instance by doing so.
|
||||
m_Material = m_Renderer.material;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(AnimateProperties());
|
||||
}
|
||||
|
||||
private IEnumerator AnimateProperties()
|
||||
{
|
||||
//float lightAngle;
|
||||
float glowPower;
|
||||
m_frame = Random.Range(0f, 1f);
|
||||
|
||||
while (true)
|
||||
{
|
||||
//lightAngle = (m_Material.GetFloat(ShaderPropertyIDs.ID_LightAngle) + Time.deltaTime) % 6.2831853f;
|
||||
//m_Material.SetFloat(ShaderPropertyIDs.ID_LightAngle, lightAngle);
|
||||
|
||||
glowPower = GlowCurve.Evaluate(m_frame);
|
||||
m_Material.SetFloat(ShaderUtilities.ID_GlowPower, glowPower);
|
||||
|
||||
m_frame += Time.deltaTime * Random.Range(0.2f, 0.3f);
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2787a46a4dc848c1b4b7b9307b614bfd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class SimpleScript : MonoBehaviour
|
||||
{
|
||||
//private TMP_FontAsset m_FontAsset;
|
||||
|
||||
private const string label = "The <#0050FF>count is: </color>{0:2}";
|
||||
private float m_frame;
|
||||
|
||||
private TextMeshPro m_textMeshPro;
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Add new TextMesh Pro Component
|
||||
m_textMeshPro = gameObject.AddComponent<TextMeshPro>();
|
||||
|
||||
m_textMeshPro.autoSizeTextContainer = true;
|
||||
|
||||
// Load the Font Asset to be used.
|
||||
//m_FontAsset = Resources.Load("Fonts & Materials/LiberationSans SDF", typeof(TMP_FontAsset)) as TMP_FontAsset;
|
||||
//m_textMeshPro.font = m_FontAsset;
|
||||
|
||||
// Assign Material to TextMesh Pro Component
|
||||
//m_textMeshPro.fontSharedMaterial = Resources.Load("Fonts & Materials/LiberationSans SDF - Bevel", typeof(Material)) as Material;
|
||||
//m_textMeshPro.fontSharedMaterial.EnableKeyword("BEVEL_ON");
|
||||
|
||||
// Set various font settings.
|
||||
m_textMeshPro.fontSize = 48;
|
||||
|
||||
m_textMeshPro.alignment = TextAlignmentOptions.Center;
|
||||
|
||||
//m_textMeshPro.anchorDampening = true; // Has been deprecated but under consideration for re-implementation.
|
||||
//m_textMeshPro.enableAutoSizing = true;
|
||||
|
||||
//m_textMeshPro.characterSpacing = 0.2f;
|
||||
//m_textMeshPro.wordSpacing = 0.1f;
|
||||
|
||||
//m_textMeshPro.enableCulling = true;
|
||||
m_textMeshPro.enableWordWrapping = false;
|
||||
|
||||
//textMeshPro.fontColor = new Color32(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
m_textMeshPro.SetText(label, m_frame % 1000);
|
||||
m_frame += 1 * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9eff140b25d64601aabc6ba32245d099
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,168 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class SkewTextExample : MonoBehaviour
|
||||
{
|
||||
public AnimationCurve VertexCurve = new(new Keyframe(0, 0), new Keyframe(0.25f, 2.0f), new Keyframe(0.5f, 0),
|
||||
new Keyframe(0.75f, 2.0f), new Keyframe(1, 0f));
|
||||
|
||||
//public float AngleMultiplier = 1.0f;
|
||||
//public float SpeedMultiplier = 1.0f;
|
||||
public float CurveScale = 1.0f;
|
||||
public float ShearAmount = 1.0f;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextComponent = gameObject.GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(WarpText());
|
||||
}
|
||||
|
||||
|
||||
private AnimationCurve CopyAnimationCurve(AnimationCurve curve)
|
||||
{
|
||||
var newCurve = new AnimationCurve();
|
||||
|
||||
newCurve.keys = curve.keys;
|
||||
|
||||
return newCurve;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to curve text along a Unity animation curve.
|
||||
/// </summary>
|
||||
/// <param name="textComponent"></param>
|
||||
/// <returns></returns>
|
||||
private IEnumerator WarpText()
|
||||
{
|
||||
VertexCurve.preWrapMode = WrapMode.Clamp;
|
||||
VertexCurve.postWrapMode = WrapMode.Clamp;
|
||||
|
||||
//Mesh mesh = m_TextComponent.textInfo.meshInfo[0].mesh;
|
||||
|
||||
Vector3[] vertices;
|
||||
Matrix4x4 matrix;
|
||||
|
||||
m_TextComponent.havePropertiesChanged = true; // Need to force the TextMeshPro Object to be updated.
|
||||
CurveScale *= 10;
|
||||
var old_CurveScale = CurveScale;
|
||||
var old_ShearValue = ShearAmount;
|
||||
var old_curve = CopyAnimationCurve(VertexCurve);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!m_TextComponent.havePropertiesChanged && old_CurveScale == CurveScale &&
|
||||
old_curve.keys[1].value == VertexCurve.keys[1].value && old_ShearValue == ShearAmount)
|
||||
{
|
||||
yield return null;
|
||||
continue;
|
||||
}
|
||||
|
||||
old_CurveScale = CurveScale;
|
||||
old_curve = CopyAnimationCurve(VertexCurve);
|
||||
old_ShearValue = ShearAmount;
|
||||
|
||||
m_TextComponent
|
||||
.ForceMeshUpdate(); // Generate the mesh and populate the textInfo with data we can use and manipulate.
|
||||
|
||||
var textInfo = m_TextComponent.textInfo;
|
||||
var characterCount = textInfo.characterCount;
|
||||
|
||||
|
||||
if (characterCount == 0) continue;
|
||||
|
||||
//vertices = textInfo.meshInfo[0].vertices;
|
||||
//int lastVertexIndex = textInfo.characterInfo[characterCount - 1].vertexIndex;
|
||||
|
||||
var boundsMinX = m_TextComponent.bounds.min.x; //textInfo.meshInfo[0].mesh.bounds.min.x;
|
||||
var boundsMaxX = m_TextComponent.bounds.max.x; //textInfo.meshInfo[0].mesh.bounds.max.x;
|
||||
|
||||
|
||||
for (var i = 0; i < characterCount; i++)
|
||||
{
|
||||
if (!textInfo.characterInfo[i].isVisible)
|
||||
continue;
|
||||
|
||||
var vertexIndex = textInfo.characterInfo[i].vertexIndex;
|
||||
|
||||
// Get the index of the mesh used by this character.
|
||||
var materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
|
||||
|
||||
vertices = textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
// Compute the baseline mid point for each character
|
||||
Vector3 offsetToMidBaseline =
|
||||
new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2,
|
||||
textInfo.characterInfo[i].baseLine);
|
||||
//float offsetY = VertexCurve.Evaluate((float)i / characterCount + loopCount / 50f); // Random.Range(-0.25f, 0.25f);
|
||||
|
||||
// Apply offset to adjust our pivot point.
|
||||
vertices[vertexIndex + 0] += -offsetToMidBaseline;
|
||||
vertices[vertexIndex + 1] += -offsetToMidBaseline;
|
||||
vertices[vertexIndex + 2] += -offsetToMidBaseline;
|
||||
vertices[vertexIndex + 3] += -offsetToMidBaseline;
|
||||
|
||||
// Apply the Shearing FX
|
||||
var shear_value = ShearAmount * 0.01f;
|
||||
var topShear =
|
||||
new Vector3(
|
||||
shear_value * (textInfo.characterInfo[i].topRight.y - textInfo.characterInfo[i].baseLine),
|
||||
0, 0);
|
||||
var bottomShear =
|
||||
new Vector3(
|
||||
shear_value * (textInfo.characterInfo[i].baseLine -
|
||||
textInfo.characterInfo[i].bottomRight.y), 0, 0);
|
||||
|
||||
vertices[vertexIndex + 0] += -bottomShear;
|
||||
vertices[vertexIndex + 1] += topShear;
|
||||
vertices[vertexIndex + 2] += topShear;
|
||||
vertices[vertexIndex + 3] += -bottomShear;
|
||||
|
||||
|
||||
// Compute the angle of rotation for each character based on the animation curve
|
||||
var x0 = (offsetToMidBaseline.x - boundsMinX) /
|
||||
(boundsMaxX - boundsMinX); // Character's position relative to the bounds of the mesh.
|
||||
var x1 = x0 + 0.0001f;
|
||||
var y0 = VertexCurve.Evaluate(x0) * CurveScale;
|
||||
var y1 = VertexCurve.Evaluate(x1) * CurveScale;
|
||||
|
||||
var horizontal = new Vector3(1, 0, 0);
|
||||
//Vector3 normal = new Vector3(-(y1 - y0), (x1 * (boundsMaxX - boundsMinX) + boundsMinX) - offsetToMidBaseline.x, 0);
|
||||
var tangent = new Vector3(x1 * (boundsMaxX - boundsMinX) + boundsMinX, y1) -
|
||||
new Vector3(offsetToMidBaseline.x, y0);
|
||||
|
||||
var dot = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * 57.2957795f;
|
||||
var cross = Vector3.Cross(horizontal, tangent);
|
||||
var angle = cross.z > 0 ? dot : 360 - dot;
|
||||
|
||||
matrix = Matrix4x4.TRS(new Vector3(0, y0, 0), Quaternion.Euler(0, 0, angle), Vector3.one);
|
||||
|
||||
vertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
|
||||
vertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
|
||||
vertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
|
||||
vertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);
|
||||
|
||||
vertices[vertexIndex + 0] += offsetToMidBaseline;
|
||||
vertices[vertexIndex + 1] += offsetToMidBaseline;
|
||||
vertices[vertexIndex + 2] += offsetToMidBaseline;
|
||||
vertices[vertexIndex + 3] += offsetToMidBaseline;
|
||||
}
|
||||
|
||||
|
||||
// Upload the mesh with the revised information
|
||||
m_TextComponent.UpdateVertexData();
|
||||
|
||||
yield return null; // new WaitForSeconds(0.025f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d412675cfb3441efa3bf8dcd9b7624dc
|
||||
timeCreated: 1458801336
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// EXample of a Custom Character Input Validator to only allow digits from 0 to 9.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
//[CreateAssetMenu(fileName = "InputValidator - Digits.asset", menuName = "TextMeshPro/Input Validators/Digits", order = 100)]
|
||||
public class TMP_DigitValidator : TMP_InputValidator
|
||||
{
|
||||
// Custom text input validation function
|
||||
public override char Validate(ref string text, ref int pos, char ch)
|
||||
{
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
text += ch;
|
||||
pos += 1;
|
||||
return ch;
|
||||
}
|
||||
|
||||
return (char)0;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a7eb92a01ed499a987bde9def05fbce
|
||||
timeCreated: 1473112765
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,62 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TMP_ExampleScript_01 : MonoBehaviour
|
||||
{
|
||||
public enum objectType
|
||||
{
|
||||
TextMeshPro = 0,
|
||||
TextMeshProUGUI = 1
|
||||
}
|
||||
|
||||
//private TMP_InputField m_inputfield;
|
||||
|
||||
|
||||
private const string k_label = "The count is <#0080ff>{0}</color>";
|
||||
|
||||
public objectType ObjectType;
|
||||
public bool isStatic;
|
||||
private int count;
|
||||
|
||||
private TMP_Text m_text;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Get a reference to the TMP text component if one already exists otherwise add one.
|
||||
// This example show the convenience of having both TMP components derive from TMP_Text.
|
||||
if (ObjectType == 0)
|
||||
m_text = GetComponent<TextMeshPro>() ?? gameObject.AddComponent<TextMeshPro>();
|
||||
else
|
||||
m_text = GetComponent<TextMeshProUGUI>() ?? gameObject.AddComponent<TextMeshProUGUI>();
|
||||
|
||||
// Load a new font asset and assign it to the text object.
|
||||
m_text.font = Resources.Load<TMP_FontAsset>("Fonts & Materials/Anton SDF");
|
||||
|
||||
// Load a new material preset which was created with the context menu duplicate.
|
||||
m_text.fontSharedMaterial = Resources.Load<Material>("Fonts & Materials/Anton SDF - Drop Shadow");
|
||||
|
||||
// Set the size of the font.
|
||||
m_text.fontSize = 120;
|
||||
|
||||
// Set the text
|
||||
m_text.text = "A <#0080ff>simple</color> line of text.";
|
||||
|
||||
// Get the preferred width and height based on the supplied width and height as opposed to the actual size of the current text container.
|
||||
var size = m_text.GetPreferredValues(Mathf.Infinity, Mathf.Infinity);
|
||||
|
||||
// Set the size of the RectTransform based on the new calculated values.
|
||||
m_text.rectTransform.sizeDelta = new Vector2(size.x, size.y);
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!isStatic)
|
||||
{
|
||||
m_text.SetText(k_label, count % 1000);
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f2c5b59b6874405865e2616e4ec276a
|
||||
timeCreated: 1449625634
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,136 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TMP_FrameRateCounter : MonoBehaviour
|
||||
{
|
||||
public enum FpsCounterAnchorPositions
|
||||
{
|
||||
TopLeft,
|
||||
BottomLeft,
|
||||
TopRight,
|
||||
BottomRight
|
||||
}
|
||||
|
||||
private const string fpsLabel = "{0:2}</color> <#8080ff>FPS \n<#FF8000>{1:2} <#8080ff>MS";
|
||||
public float UpdateInterval = 5.0f;
|
||||
|
||||
public FpsCounterAnchorPositions AnchorPosition = FpsCounterAnchorPositions.TopRight;
|
||||
|
||||
private string htmlColorTag;
|
||||
|
||||
private FpsCounterAnchorPositions last_AnchorPosition;
|
||||
private Camera m_camera;
|
||||
private Transform m_frameCounter_transform;
|
||||
private int m_Frames;
|
||||
private float m_LastInterval;
|
||||
|
||||
private TextMeshPro m_TextMeshPro;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
m_camera = Camera.main;
|
||||
Application.targetFrameRate = 9999;
|
||||
|
||||
var frameCounter = new GameObject("Frame Counter");
|
||||
|
||||
m_TextMeshPro = frameCounter.AddComponent<TextMeshPro>();
|
||||
m_TextMeshPro.font = Resources.Load<TMP_FontAsset>("Fonts & Materials/LiberationSans SDF");
|
||||
m_TextMeshPro.fontSharedMaterial =
|
||||
Resources.Load<Material>("Fonts & Materials/LiberationSans SDF - Overlay");
|
||||
|
||||
|
||||
m_frameCounter_transform = frameCounter.transform;
|
||||
m_frameCounter_transform.SetParent(m_camera.transform);
|
||||
m_frameCounter_transform.localRotation = Quaternion.identity;
|
||||
|
||||
m_TextMeshPro.enableWordWrapping = false;
|
||||
m_TextMeshPro.fontSize = 24;
|
||||
//m_TextMeshPro.FontColor = new Color32(255, 255, 255, 128);
|
||||
//m_TextMeshPro.edgeWidth = .15f;
|
||||
//m_TextMeshPro.isOverlay = true;
|
||||
|
||||
//m_TextMeshPro.FaceColor = new Color32(255, 128, 0, 0);
|
||||
//m_TextMeshPro.EdgeColor = new Color32(0, 255, 0, 255);
|
||||
//m_TextMeshPro.FontMaterial.renderQueue = 4000;
|
||||
|
||||
//m_TextMeshPro.CreateSoftShadowClone(new Vector2(1f, -1f));
|
||||
|
||||
Set_FrameCounter_Position(AnchorPosition);
|
||||
last_AnchorPosition = AnchorPosition;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
m_LastInterval = Time.realtimeSinceStartup;
|
||||
m_Frames = 0;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (AnchorPosition != last_AnchorPosition)
|
||||
Set_FrameCounter_Position(AnchorPosition);
|
||||
|
||||
last_AnchorPosition = AnchorPosition;
|
||||
|
||||
m_Frames += 1;
|
||||
var timeNow = Time.realtimeSinceStartup;
|
||||
|
||||
if (timeNow > m_LastInterval + UpdateInterval)
|
||||
{
|
||||
// display two fractional digits (f2 format)
|
||||
var fps = m_Frames / (timeNow - m_LastInterval);
|
||||
var ms = 1000.0f / Mathf.Max(fps, 0.00001f);
|
||||
|
||||
if (fps < 30)
|
||||
htmlColorTag = "<color=yellow>";
|
||||
else if (fps < 10)
|
||||
htmlColorTag = "<color=red>";
|
||||
else
|
||||
htmlColorTag = "<color=green>";
|
||||
|
||||
//string format = System.String.Format(htmlColorTag + "{0:F2} </color>FPS \n{1:F2} <#8080ff>MS",fps, ms);
|
||||
//m_TextMeshPro.text = format;
|
||||
|
||||
m_TextMeshPro.SetText(htmlColorTag + fpsLabel, fps, ms);
|
||||
|
||||
m_Frames = 0;
|
||||
m_LastInterval = timeNow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Set_FrameCounter_Position(FpsCounterAnchorPositions anchor_position)
|
||||
{
|
||||
//Debug.Log("Changing frame counter anchor position.");
|
||||
m_TextMeshPro.margin = new Vector4(1f, 1f, 1f, 1f);
|
||||
|
||||
switch (anchor_position)
|
||||
{
|
||||
case FpsCounterAnchorPositions.TopLeft:
|
||||
m_TextMeshPro.alignment = TextAlignmentOptions.TopLeft;
|
||||
m_TextMeshPro.rectTransform.pivot = new Vector2(0, 1);
|
||||
m_frameCounter_transform.position = m_camera.ViewportToWorldPoint(new Vector3(0, 1, 100.0f));
|
||||
break;
|
||||
case FpsCounterAnchorPositions.BottomLeft:
|
||||
m_TextMeshPro.alignment = TextAlignmentOptions.BottomLeft;
|
||||
m_TextMeshPro.rectTransform.pivot = new Vector2(0, 0);
|
||||
m_frameCounter_transform.position = m_camera.ViewportToWorldPoint(new Vector3(0, 0, 100.0f));
|
||||
break;
|
||||
case FpsCounterAnchorPositions.TopRight:
|
||||
m_TextMeshPro.alignment = TextAlignmentOptions.TopRight;
|
||||
m_TextMeshPro.rectTransform.pivot = new Vector2(1, 1);
|
||||
m_frameCounter_transform.position = m_camera.ViewportToWorldPoint(new Vector3(1, 1, 100.0f));
|
||||
break;
|
||||
case FpsCounterAnchorPositions.BottomRight:
|
||||
m_TextMeshPro.alignment = TextAlignmentOptions.BottomRight;
|
||||
m_TextMeshPro.rectTransform.pivot = new Vector2(1, 0);
|
||||
m_frameCounter_transform.position = m_camera.ViewportToWorldPoint(new Vector3(1, 0, 100.0f));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 686ec78b56aa445795335fbadafcfaa4
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
/// <summary>
|
||||
/// Example of a Custom Character Input Validator to only allow phone number in the (800) 555-1212 format.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
//[CreateAssetMenu(fileName = "InputValidator - Phone Numbers.asset", menuName = "TextMeshPro/Input Validators/Phone Numbers")]
|
||||
public class TMP_PhoneNumberValidator : TMP_InputValidator
|
||||
{
|
||||
// Custom text input validation function
|
||||
public override char Validate(ref string text, ref int pos, char ch)
|
||||
{
|
||||
Debug.Log("Trying to validate...");
|
||||
|
||||
// Return unless the character is a valid digit
|
||||
if (ch < '0' && ch > '9') return (char)0;
|
||||
|
||||
var length = text.Length;
|
||||
|
||||
// Enforce Phone Number format for every character input.
|
||||
for (var i = 0; i < length + 1; i++)
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
if (i == length)
|
||||
text = "(" + ch;
|
||||
pos = 2;
|
||||
break;
|
||||
case 1:
|
||||
if (i == length)
|
||||
text += ch;
|
||||
pos = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (i == length)
|
||||
text += ch;
|
||||
pos = 3;
|
||||
break;
|
||||
case 3:
|
||||
if (i == length)
|
||||
text += ch + ") ";
|
||||
pos = 6;
|
||||
break;
|
||||
case 4:
|
||||
if (i == length)
|
||||
text += ") " + ch;
|
||||
pos = 7;
|
||||
break;
|
||||
case 5:
|
||||
if (i == length)
|
||||
text += " " + ch;
|
||||
pos = 7;
|
||||
break;
|
||||
case 6:
|
||||
if (i == length)
|
||||
text += ch;
|
||||
pos = 7;
|
||||
break;
|
||||
case 7:
|
||||
if (i == length)
|
||||
text += ch;
|
||||
pos = 8;
|
||||
break;
|
||||
case 8:
|
||||
if (i == length)
|
||||
text += ch + "-";
|
||||
pos = 10;
|
||||
break;
|
||||
case 9:
|
||||
if (i == length)
|
||||
text += "-" + ch;
|
||||
pos = 11;
|
||||
break;
|
||||
case 10:
|
||||
if (i == length)
|
||||
text += ch;
|
||||
pos = 11;
|
||||
break;
|
||||
case 11:
|
||||
if (i == length)
|
||||
text += ch;
|
||||
pos = 12;
|
||||
break;
|
||||
case 12:
|
||||
if (i == length)
|
||||
text += ch;
|
||||
pos = 13;
|
||||
break;
|
||||
case 13:
|
||||
if (i == length)
|
||||
text += ch;
|
||||
pos = 14;
|
||||
break;
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83680ab1a69f4102ac67d1459fe76e1f
|
||||
timeCreated: 1473056437
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,73 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TMP_TextEventCheck : MonoBehaviour
|
||||
{
|
||||
public TMP_TextEventHandler TextEventHandler;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (TextEventHandler != null)
|
||||
{
|
||||
// Get a reference to the text component
|
||||
m_TextComponent = TextEventHandler.GetComponent<TMP_Text>();
|
||||
|
||||
TextEventHandler.onCharacterSelection.AddListener(OnCharacterSelection);
|
||||
TextEventHandler.onSpriteSelection.AddListener(OnSpriteSelection);
|
||||
TextEventHandler.onWordSelection.AddListener(OnWordSelection);
|
||||
TextEventHandler.onLineSelection.AddListener(OnLineSelection);
|
||||
TextEventHandler.onLinkSelection.AddListener(OnLinkSelection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (TextEventHandler != null)
|
||||
{
|
||||
TextEventHandler.onCharacterSelection.RemoveListener(OnCharacterSelection);
|
||||
TextEventHandler.onSpriteSelection.RemoveListener(OnSpriteSelection);
|
||||
TextEventHandler.onWordSelection.RemoveListener(OnWordSelection);
|
||||
TextEventHandler.onLineSelection.RemoveListener(OnLineSelection);
|
||||
TextEventHandler.onLinkSelection.RemoveListener(OnLinkSelection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnCharacterSelection(char c, int index)
|
||||
{
|
||||
Debug.Log("Character [" + c + "] at Index: " + index + " has been selected.");
|
||||
}
|
||||
|
||||
private void OnSpriteSelection(char c, int index)
|
||||
{
|
||||
Debug.Log("Sprite [" + c + "] at Index: " + index + " has been selected.");
|
||||
}
|
||||
|
||||
private void OnWordSelection(string word, int firstCharacterIndex, int length)
|
||||
{
|
||||
Debug.Log("Word [" + word + "] with first character index of " + firstCharacterIndex + " and length of " +
|
||||
length + " has been selected.");
|
||||
}
|
||||
|
||||
private void OnLineSelection(string lineText, int firstCharacterIndex, int length)
|
||||
{
|
||||
Debug.Log("Line [" + lineText + "] with first character index of " + firstCharacterIndex +
|
||||
" and length of " + length + " has been selected.");
|
||||
}
|
||||
|
||||
private void OnLinkSelection(string linkID, string linkText, int linkIndex)
|
||||
{
|
||||
if (m_TextComponent != null)
|
||||
{
|
||||
var linkInfo = m_TextComponent.textInfo.linkInfo[linkIndex];
|
||||
}
|
||||
|
||||
Debug.Log("Link Index: " + linkIndex + " with ID [" + linkID + "] and Text \"" + linkText +
|
||||
"\" has been selected.");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d736ce056cf444ca96e424f4d9c42b76
|
||||
timeCreated: 1480416736
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,271 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class TMP_TextEventHandler : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
||||
{
|
||||
[SerializeField] private CharacterSelectionEvent m_OnCharacterSelection = new();
|
||||
|
||||
[SerializeField] private SpriteSelectionEvent m_OnSpriteSelection = new();
|
||||
|
||||
[SerializeField] private WordSelectionEvent m_OnWordSelection = new();
|
||||
|
||||
[SerializeField] private LineSelectionEvent m_OnLineSelection = new();
|
||||
|
||||
[SerializeField] private LinkSelectionEvent m_OnLinkSelection = new();
|
||||
|
||||
private Camera m_Camera;
|
||||
private Canvas m_Canvas;
|
||||
private int m_lastCharIndex = -1;
|
||||
private int m_lastLineIndex = -1;
|
||||
private int m_lastWordIndex = -1;
|
||||
|
||||
private int m_selectedLink = -1;
|
||||
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event delegate triggered when pointer is over a character.
|
||||
/// </summary>
|
||||
public CharacterSelectionEvent onCharacterSelection
|
||||
{
|
||||
get => m_OnCharacterSelection;
|
||||
set => m_OnCharacterSelection = value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event delegate triggered when pointer is over a sprite.
|
||||
/// </summary>
|
||||
public SpriteSelectionEvent onSpriteSelection
|
||||
{
|
||||
get => m_OnSpriteSelection;
|
||||
set => m_OnSpriteSelection = value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event delegate triggered when pointer is over a word.
|
||||
/// </summary>
|
||||
public WordSelectionEvent onWordSelection
|
||||
{
|
||||
get => m_OnWordSelection;
|
||||
set => m_OnWordSelection = value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event delegate triggered when pointer is over a line.
|
||||
/// </summary>
|
||||
public LineSelectionEvent onLineSelection
|
||||
{
|
||||
get => m_OnLineSelection;
|
||||
set => m_OnLineSelection = value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event delegate triggered when pointer is over a link.
|
||||
/// </summary>
|
||||
public LinkSelectionEvent onLinkSelection
|
||||
{
|
||||
get => m_OnLinkSelection;
|
||||
set => m_OnLinkSelection = value;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Get a reference to the text component.
|
||||
m_TextComponent = gameObject.GetComponent<TMP_Text>();
|
||||
|
||||
// Get a reference to the camera rendering the text taking into consideration the text component type.
|
||||
if (m_TextComponent.GetType() == typeof(TextMeshProUGUI))
|
||||
{
|
||||
m_Canvas = gameObject.GetComponentInParent<Canvas>();
|
||||
if (m_Canvas != null)
|
||||
{
|
||||
if (m_Canvas.renderMode == RenderMode.ScreenSpaceOverlay)
|
||||
m_Camera = null;
|
||||
else
|
||||
m_Camera = m_Canvas.worldCamera;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Camera = Camera.main;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (TMP_TextUtilities.IsIntersectingRectTransform(m_TextComponent.rectTransform, Input.mousePosition,
|
||||
m_Camera))
|
||||
{
|
||||
#region Example of Character or Sprite Selection
|
||||
|
||||
var charIndex =
|
||||
TMP_TextUtilities.FindIntersectingCharacter(m_TextComponent, Input.mousePosition, m_Camera, true);
|
||||
if (charIndex != -1 && charIndex != m_lastCharIndex)
|
||||
{
|
||||
m_lastCharIndex = charIndex;
|
||||
|
||||
var elementType = m_TextComponent.textInfo.characterInfo[charIndex].elementType;
|
||||
|
||||
// Send event to any event listeners depending on whether it is a character or sprite.
|
||||
if (elementType == TMP_TextElementType.Character)
|
||||
SendOnCharacterSelection(m_TextComponent.textInfo.characterInfo[charIndex].character,
|
||||
charIndex);
|
||||
else if (elementType == TMP_TextElementType.Sprite)
|
||||
SendOnSpriteSelection(m_TextComponent.textInfo.characterInfo[charIndex].character, charIndex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Example of Word Selection
|
||||
|
||||
// Check if Mouse intersects any words and if so assign a random color to that word.
|
||||
var wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextComponent, Input.mousePosition, m_Camera);
|
||||
if (wordIndex != -1 && wordIndex != m_lastWordIndex)
|
||||
{
|
||||
m_lastWordIndex = wordIndex;
|
||||
|
||||
// Get the information about the selected word.
|
||||
var wInfo = m_TextComponent.textInfo.wordInfo[wordIndex];
|
||||
|
||||
// Send the event to any listeners.
|
||||
SendOnWordSelection(wInfo.GetWord(), wInfo.firstCharacterIndex, wInfo.characterCount);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Example of Line Selection
|
||||
|
||||
// Check if Mouse intersects any words and if so assign a random color to that word.
|
||||
var lineIndex = TMP_TextUtilities.FindIntersectingLine(m_TextComponent, Input.mousePosition, m_Camera);
|
||||
if (lineIndex != -1 && lineIndex != m_lastLineIndex)
|
||||
{
|
||||
m_lastLineIndex = lineIndex;
|
||||
|
||||
// Get the information about the selected word.
|
||||
var lineInfo = m_TextComponent.textInfo.lineInfo[lineIndex];
|
||||
|
||||
// Send the event to any listeners.
|
||||
var buffer = new char[lineInfo.characterCount];
|
||||
for (var i = 0;
|
||||
i < lineInfo.characterCount && i < m_TextComponent.textInfo.characterInfo.Length;
|
||||
i++)
|
||||
buffer[i] = m_TextComponent.textInfo.characterInfo[i + lineInfo.firstCharacterIndex].character;
|
||||
|
||||
var lineText = new string(buffer);
|
||||
SendOnLineSelection(lineText, lineInfo.firstCharacterIndex, lineInfo.characterCount);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Example of Link Handling
|
||||
|
||||
// Check if mouse intersects with any links.
|
||||
var linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextComponent, Input.mousePosition, m_Camera);
|
||||
|
||||
// Handle new Link selection.
|
||||
if (linkIndex != -1 && linkIndex != m_selectedLink)
|
||||
{
|
||||
m_selectedLink = linkIndex;
|
||||
|
||||
// Get information about the link.
|
||||
var linkInfo = m_TextComponent.textInfo.linkInfo[linkIndex];
|
||||
|
||||
// Send the event to any listeners.
|
||||
SendOnLinkSelection(linkInfo.GetLinkID(), linkInfo.GetLinkText(), linkIndex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset all selections given we are hovering outside the text container bounds.
|
||||
m_selectedLink = -1;
|
||||
m_lastCharIndex = -1;
|
||||
m_lastWordIndex = -1;
|
||||
m_lastLineIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
//Debug.Log("OnPointerEnter()");
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
//Debug.Log("OnPointerExit()");
|
||||
}
|
||||
|
||||
|
||||
private void SendOnCharacterSelection(char character, int characterIndex)
|
||||
{
|
||||
if (onCharacterSelection != null)
|
||||
onCharacterSelection.Invoke(character, characterIndex);
|
||||
}
|
||||
|
||||
private void SendOnSpriteSelection(char character, int characterIndex)
|
||||
{
|
||||
if (onSpriteSelection != null)
|
||||
onSpriteSelection.Invoke(character, characterIndex);
|
||||
}
|
||||
|
||||
private void SendOnWordSelection(string word, int charIndex, int length)
|
||||
{
|
||||
if (onWordSelection != null)
|
||||
onWordSelection.Invoke(word, charIndex, length);
|
||||
}
|
||||
|
||||
private void SendOnLineSelection(string line, int charIndex, int length)
|
||||
{
|
||||
if (onLineSelection != null)
|
||||
onLineSelection.Invoke(line, charIndex, length);
|
||||
}
|
||||
|
||||
private void SendOnLinkSelection(string linkID, string linkText, int linkIndex)
|
||||
{
|
||||
if (onLinkSelection != null)
|
||||
onLinkSelection.Invoke(linkID, linkText, linkIndex);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CharacterSelectionEvent : UnityEvent<char, int>
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SpriteSelectionEvent : UnityEvent<char, int>
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class WordSelectionEvent : UnityEvent<string, int, int>
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class LineSelectionEvent : UnityEvent<string, int, int>
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class LinkSelectionEvent : UnityEvent<string, string, int>
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1312ae25639a4bae8e25ae223209cc50
|
||||
timeCreated: 1452811039
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,701 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TMP_TextInfoDebugTool : MonoBehaviour
|
||||
{
|
||||
// Since this script is used for debugging, we exclude it from builds.
|
||||
// TODO: Rework this script to make it into an editor utility.
|
||||
#if UNITY_EDITOR
|
||||
public bool ShowCharacters;
|
||||
public bool ShowWords;
|
||||
public bool ShowLinks;
|
||||
public bool ShowLines;
|
||||
public bool ShowMeshBounds;
|
||||
public bool ShowTextBounds;
|
||||
|
||||
[Space(10)] [TextArea(2, 2)] public string ObjectStats;
|
||||
|
||||
[SerializeField] private TMP_Text m_TextComponent;
|
||||
|
||||
private Transform m_Transform;
|
||||
private TMP_TextInfo m_TextInfo;
|
||||
|
||||
private float m_ScaleMultiplier;
|
||||
private float m_HandleSize;
|
||||
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
if (m_TextComponent == null)
|
||||
{
|
||||
m_TextComponent = GetComponent<TMP_Text>();
|
||||
|
||||
if (m_TextComponent == null)
|
||||
return;
|
||||
}
|
||||
|
||||
m_Transform = m_TextComponent.transform;
|
||||
|
||||
// Get a reference to the text object's textInfo
|
||||
m_TextInfo = m_TextComponent.textInfo;
|
||||
|
||||
// Update Text Statistics
|
||||
ObjectStats = "Characters: " + m_TextInfo.characterCount + " Words: " + m_TextInfo.wordCount +
|
||||
" Spaces: " + m_TextInfo.spaceCount + " Sprites: " + m_TextInfo.spriteCount +
|
||||
" Links: " + m_TextInfo.linkCount
|
||||
+ "\nLines: " + m_TextInfo.lineCount + " Pages: " + m_TextInfo.pageCount;
|
||||
|
||||
// Get the handle size for drawing the various
|
||||
m_ScaleMultiplier = m_TextComponent.GetType() == typeof(TextMeshPro) ? 1 : 0.1f;
|
||||
m_HandleSize = HandleUtility.GetHandleSize(m_Transform.position) * m_ScaleMultiplier;
|
||||
|
||||
// Draw line metrics
|
||||
|
||||
#region Draw Lines
|
||||
|
||||
if (ShowLines)
|
||||
DrawLineBounds();
|
||||
|
||||
#endregion
|
||||
|
||||
// Draw word metrics
|
||||
|
||||
#region Draw Words
|
||||
|
||||
if (ShowWords)
|
||||
DrawWordBounds();
|
||||
|
||||
#endregion
|
||||
|
||||
// Draw character metrics
|
||||
|
||||
#region Draw Characters
|
||||
|
||||
if (ShowCharacters)
|
||||
DrawCharactersBounds();
|
||||
|
||||
#endregion
|
||||
|
||||
// Draw Quads around each of the words
|
||||
|
||||
#region Draw Links
|
||||
|
||||
if (ShowLinks)
|
||||
DrawLinkBounds();
|
||||
|
||||
#endregion
|
||||
|
||||
// Draw Quad around the bounds of the text
|
||||
|
||||
#region Draw Bounds
|
||||
|
||||
if (ShowMeshBounds)
|
||||
DrawBounds();
|
||||
|
||||
#endregion
|
||||
|
||||
// Draw Quad around the rendered region of the text.
|
||||
|
||||
#region Draw Text Bounds
|
||||
|
||||
if (ShowTextBounds)
|
||||
DrawTextBounds();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to draw a rectangle around each character.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
private void DrawCharactersBounds()
|
||||
{
|
||||
var characterCount = m_TextInfo.characterCount;
|
||||
|
||||
for (var i = 0; i < characterCount; i++)
|
||||
{
|
||||
// Draw visible as well as invisible characters
|
||||
var characterInfo = m_TextInfo.characterInfo[i];
|
||||
|
||||
var isCharacterVisible = i < m_TextComponent.maxVisibleCharacters &&
|
||||
characterInfo.lineNumber < m_TextComponent.maxVisibleLines &&
|
||||
i >= m_TextComponent.firstVisibleCharacter;
|
||||
|
||||
if (m_TextComponent.overflowMode == TextOverflowModes.Page)
|
||||
isCharacterVisible = isCharacterVisible &&
|
||||
characterInfo.pageNumber + 1 == m_TextComponent.pageToDisplay;
|
||||
|
||||
if (!isCharacterVisible)
|
||||
continue;
|
||||
|
||||
float dottedLineSize = 6;
|
||||
|
||||
// Get Bottom Left and Top Right position of the current character
|
||||
var bottomLeft = m_Transform.TransformPoint(characterInfo.bottomLeft);
|
||||
var topLeft =
|
||||
m_Transform.TransformPoint(new Vector3(characterInfo.topLeft.x, characterInfo.topLeft.y, 0));
|
||||
var topRight = m_Transform.TransformPoint(characterInfo.topRight);
|
||||
var bottomRight =
|
||||
m_Transform.TransformPoint(new Vector3(characterInfo.bottomRight.x, characterInfo.bottomRight.y,
|
||||
0));
|
||||
|
||||
// Draw character bounds
|
||||
if (characterInfo.isVisible)
|
||||
{
|
||||
var color = Color.green;
|
||||
DrawDottedRectangle(bottomLeft, topRight, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
var color = Color.grey;
|
||||
|
||||
var whiteSpaceAdvance = Math.Abs(characterInfo.origin - characterInfo.xAdvance) > 0.01f
|
||||
? characterInfo.xAdvance
|
||||
: characterInfo.origin + (characterInfo.ascender - characterInfo.descender) * 0.03f;
|
||||
DrawDottedRectangle(
|
||||
m_Transform.TransformPoint(new Vector3(characterInfo.origin, characterInfo.descender, 0)),
|
||||
m_Transform.TransformPoint(new Vector3(whiteSpaceAdvance, characterInfo.ascender, 0)), color,
|
||||
4);
|
||||
}
|
||||
|
||||
var origin = characterInfo.origin;
|
||||
var advance = characterInfo.xAdvance;
|
||||
var ascentline = characterInfo.ascender;
|
||||
var baseline = characterInfo.baseLine;
|
||||
var descentline = characterInfo.descender;
|
||||
|
||||
//Draw Ascent line
|
||||
var ascentlineStart = m_Transform.TransformPoint(new Vector3(origin, ascentline, 0));
|
||||
var ascentlineEnd = m_Transform.TransformPoint(new Vector3(advance, ascentline, 0));
|
||||
|
||||
Handles.color = Color.cyan;
|
||||
Handles.DrawDottedLine(ascentlineStart, ascentlineEnd, dottedLineSize);
|
||||
|
||||
// Draw Cap Height & Mean line
|
||||
var capline = characterInfo.fontAsset == null
|
||||
? 0
|
||||
: baseline + characterInfo.fontAsset.faceInfo.capLine * characterInfo.scale;
|
||||
var capHeightStart =
|
||||
new Vector3(topLeft.x, m_Transform.TransformPoint(new Vector3(0, capline, 0)).y, 0);
|
||||
var capHeightEnd = new Vector3(topRight.x, m_Transform.TransformPoint(new Vector3(0, capline, 0)).y, 0);
|
||||
|
||||
var meanline = characterInfo.fontAsset == null
|
||||
? 0
|
||||
: baseline + characterInfo.fontAsset.faceInfo.meanLine * characterInfo.scale;
|
||||
var meanlineStart =
|
||||
new Vector3(topLeft.x, m_Transform.TransformPoint(new Vector3(0, meanline, 0)).y, 0);
|
||||
var meanlineEnd = new Vector3(topRight.x, m_Transform.TransformPoint(new Vector3(0, meanline, 0)).y, 0);
|
||||
|
||||
if (characterInfo.isVisible)
|
||||
{
|
||||
// Cap line
|
||||
Handles.color = Color.cyan;
|
||||
Handles.DrawDottedLine(capHeightStart, capHeightEnd, dottedLineSize);
|
||||
|
||||
// Mean line
|
||||
Handles.color = Color.cyan;
|
||||
Handles.DrawDottedLine(meanlineStart, meanlineEnd, dottedLineSize);
|
||||
}
|
||||
|
||||
//Draw Base line
|
||||
var baselineStart = m_Transform.TransformPoint(new Vector3(origin, baseline, 0));
|
||||
var baselineEnd = m_Transform.TransformPoint(new Vector3(advance, baseline, 0));
|
||||
|
||||
Handles.color = Color.cyan;
|
||||
Handles.DrawDottedLine(baselineStart, baselineEnd, dottedLineSize);
|
||||
|
||||
//Draw Descent line
|
||||
var descentlineStart = m_Transform.TransformPoint(new Vector3(origin, descentline, 0));
|
||||
var descentlineEnd = m_Transform.TransformPoint(new Vector3(advance, descentline, 0));
|
||||
|
||||
Handles.color = Color.cyan;
|
||||
Handles.DrawDottedLine(descentlineStart, descentlineEnd, dottedLineSize);
|
||||
|
||||
// Draw Origin
|
||||
var originPosition = m_Transform.TransformPoint(new Vector3(origin, baseline, 0));
|
||||
DrawCrosshair(originPosition, 0.05f / m_ScaleMultiplier, Color.cyan);
|
||||
|
||||
// Draw Horizontal Advance
|
||||
var advancePosition = m_Transform.TransformPoint(new Vector3(advance, baseline, 0));
|
||||
DrawSquare(advancePosition, 0.025f / m_ScaleMultiplier, Color.yellow);
|
||||
DrawCrosshair(advancePosition, 0.0125f / m_ScaleMultiplier, Color.yellow);
|
||||
|
||||
// Draw text labels for metrics
|
||||
if (m_HandleSize < 0.5f)
|
||||
{
|
||||
var style = new GUIStyle(GUI.skin.GetStyle("Label"));
|
||||
style.normal.textColor = new Color(0.6f, 0.6f, 0.6f, 1.0f);
|
||||
style.fontSize = 12;
|
||||
style.fixedWidth = 200;
|
||||
style.fixedHeight = 20;
|
||||
|
||||
Vector3 labelPosition;
|
||||
var center = (origin + advance) / 2;
|
||||
|
||||
//float baselineMetrics = 0;
|
||||
//float ascentlineMetrics = ascentline - baseline;
|
||||
//float caplineMetrics = capline - baseline;
|
||||
//float meanlineMetrics = meanline - baseline;
|
||||
//float descentlineMetrics = descentline - baseline;
|
||||
|
||||
// Ascent Line
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(center, ascentline, 0));
|
||||
style.alignment = TextAnchor.UpperCenter;
|
||||
Handles.Label(labelPosition, "Ascent Line", style);
|
||||
//Handles.Label(labelPosition, "Ascent Line (" + ascentlineMetrics.ToString("f3") + ")" , style);
|
||||
|
||||
// Base Line
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(center, baseline, 0));
|
||||
Handles.Label(labelPosition, "Base Line", style);
|
||||
//Handles.Label(labelPosition, "Base Line (" + baselineMetrics.ToString("f3") + ")" , style);
|
||||
|
||||
// Descent line
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(center, descentline, 0));
|
||||
Handles.Label(labelPosition, "Descent Line", style);
|
||||
//Handles.Label(labelPosition, "Descent Line (" + descentlineMetrics.ToString("f3") + ")" , style);
|
||||
|
||||
if (characterInfo.isVisible)
|
||||
{
|
||||
// Cap Line
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(center, capline, 0));
|
||||
style.alignment = TextAnchor.UpperCenter;
|
||||
Handles.Label(labelPosition, "Cap Line", style);
|
||||
//Handles.Label(labelPosition, "Cap Line (" + caplineMetrics.ToString("f3") + ")" , style);
|
||||
|
||||
// Mean Line
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(center, meanline, 0));
|
||||
style.alignment = TextAnchor.UpperCenter;
|
||||
Handles.Label(labelPosition, "Mean Line", style);
|
||||
//Handles.Label(labelPosition, "Mean Line (" + ascentlineMetrics.ToString("f3") + ")" , style);
|
||||
|
||||
// Origin
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(origin, baseline, 0));
|
||||
style.alignment = TextAnchor.UpperRight;
|
||||
Handles.Label(labelPosition, "Origin ", style);
|
||||
|
||||
// Advance
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(advance, baseline, 0));
|
||||
style.alignment = TextAnchor.UpperLeft;
|
||||
Handles.Label(labelPosition, " Advance", style);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to draw rectangles around each word of the text.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
private void DrawWordBounds()
|
||||
{
|
||||
for (var i = 0; i < m_TextInfo.wordCount; i++)
|
||||
{
|
||||
var wInfo = m_TextInfo.wordInfo[i];
|
||||
|
||||
var isBeginRegion = false;
|
||||
|
||||
var bottomLeft = Vector3.zero;
|
||||
var topLeft = Vector3.zero;
|
||||
var bottomRight = Vector3.zero;
|
||||
var topRight = Vector3.zero;
|
||||
|
||||
var maxAscender = -Mathf.Infinity;
|
||||
var minDescender = Mathf.Infinity;
|
||||
|
||||
var wordColor = Color.green;
|
||||
|
||||
// Iterate through each character of the word
|
||||
for (var j = 0; j < wInfo.characterCount; j++)
|
||||
{
|
||||
var characterIndex = wInfo.firstCharacterIndex + j;
|
||||
var currentCharInfo = m_TextInfo.characterInfo[characterIndex];
|
||||
var currentLine = currentCharInfo.lineNumber;
|
||||
|
||||
var isCharacterVisible = characterIndex > m_TextComponent.maxVisibleCharacters ||
|
||||
currentCharInfo.lineNumber > m_TextComponent.maxVisibleLines ||
|
||||
(m_TextComponent.overflowMode == TextOverflowModes.Page &&
|
||||
currentCharInfo.pageNumber + 1 != m_TextComponent.pageToDisplay)
|
||||
? false
|
||||
: true;
|
||||
|
||||
// Track Max Ascender and Min Descender
|
||||
maxAscender = Mathf.Max(maxAscender, currentCharInfo.ascender);
|
||||
minDescender = Mathf.Min(minDescender, currentCharInfo.descender);
|
||||
|
||||
if (isBeginRegion == false && isCharacterVisible)
|
||||
{
|
||||
isBeginRegion = true;
|
||||
|
||||
bottomLeft = new Vector3(currentCharInfo.bottomLeft.x, currentCharInfo.descender, 0);
|
||||
topLeft = new Vector3(currentCharInfo.bottomLeft.x, currentCharInfo.ascender, 0);
|
||||
|
||||
//Debug.Log("Start Word Region at [" + currentCharInfo.character + "]");
|
||||
|
||||
// If Word is one character
|
||||
if (wInfo.characterCount == 1)
|
||||
{
|
||||
isBeginRegion = false;
|
||||
|
||||
topLeft = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
|
||||
bottomLeft = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
|
||||
bottomRight =
|
||||
m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
|
||||
topRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender,
|
||||
0));
|
||||
|
||||
// Draw Region
|
||||
DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, wordColor);
|
||||
|
||||
//Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
|
||||
}
|
||||
}
|
||||
|
||||
// Last Character of Word
|
||||
if (isBeginRegion && j == wInfo.characterCount - 1)
|
||||
{
|
||||
isBeginRegion = false;
|
||||
|
||||
topLeft = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
|
||||
bottomLeft = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
|
||||
bottomRight =
|
||||
m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
|
||||
topRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));
|
||||
|
||||
// Draw Region
|
||||
DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, wordColor);
|
||||
|
||||
//Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
|
||||
}
|
||||
// If Word is split on more than one line.
|
||||
else if (isBeginRegion && currentLine != m_TextInfo.characterInfo[characterIndex + 1].lineNumber)
|
||||
{
|
||||
isBeginRegion = false;
|
||||
|
||||
topLeft = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
|
||||
bottomLeft = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
|
||||
bottomRight =
|
||||
m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
|
||||
topRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));
|
||||
|
||||
// Draw Region
|
||||
DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, wordColor);
|
||||
//Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
|
||||
maxAscender = -Mathf.Infinity;
|
||||
minDescender = Mathf.Infinity;
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Log(wInfo.GetWord(m_TextMeshPro.textInfo.characterInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Draw rectangle around each of the links contained in the text.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
private void DrawLinkBounds()
|
||||
{
|
||||
var textInfo = m_TextComponent.textInfo;
|
||||
|
||||
for (var i = 0; i < textInfo.linkCount; i++)
|
||||
{
|
||||
var linkInfo = textInfo.linkInfo[i];
|
||||
|
||||
var isBeginRegion = false;
|
||||
|
||||
var bottomLeft = Vector3.zero;
|
||||
var topLeft = Vector3.zero;
|
||||
var bottomRight = Vector3.zero;
|
||||
var topRight = Vector3.zero;
|
||||
|
||||
var maxAscender = -Mathf.Infinity;
|
||||
var minDescender = Mathf.Infinity;
|
||||
|
||||
Color32 linkColor = Color.cyan;
|
||||
|
||||
// Iterate through each character of the link text
|
||||
for (var j = 0; j < linkInfo.linkTextLength; j++)
|
||||
{
|
||||
var characterIndex = linkInfo.linkTextfirstCharacterIndex + j;
|
||||
var currentCharInfo = textInfo.characterInfo[characterIndex];
|
||||
var currentLine = currentCharInfo.lineNumber;
|
||||
|
||||
var isCharacterVisible = characterIndex > m_TextComponent.maxVisibleCharacters ||
|
||||
currentCharInfo.lineNumber > m_TextComponent.maxVisibleLines ||
|
||||
(m_TextComponent.overflowMode == TextOverflowModes.Page &&
|
||||
currentCharInfo.pageNumber + 1 != m_TextComponent.pageToDisplay)
|
||||
? false
|
||||
: true;
|
||||
|
||||
// Track Max Ascender and Min Descender
|
||||
maxAscender = Mathf.Max(maxAscender, currentCharInfo.ascender);
|
||||
minDescender = Mathf.Min(minDescender, currentCharInfo.descender);
|
||||
|
||||
if (isBeginRegion == false && isCharacterVisible)
|
||||
{
|
||||
isBeginRegion = true;
|
||||
|
||||
bottomLeft = new Vector3(currentCharInfo.bottomLeft.x, currentCharInfo.descender, 0);
|
||||
topLeft = new Vector3(currentCharInfo.bottomLeft.x, currentCharInfo.ascender, 0);
|
||||
|
||||
//Debug.Log("Start Word Region at [" + currentCharInfo.character + "]");
|
||||
|
||||
// If Link is one character
|
||||
if (linkInfo.linkTextLength == 1)
|
||||
{
|
||||
isBeginRegion = false;
|
||||
|
||||
topLeft = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
|
||||
bottomLeft = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
|
||||
bottomRight =
|
||||
m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
|
||||
topRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender,
|
||||
0));
|
||||
|
||||
// Draw Region
|
||||
DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, linkColor);
|
||||
|
||||
//Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
|
||||
}
|
||||
}
|
||||
|
||||
// Last Character of Link
|
||||
if (isBeginRegion && j == linkInfo.linkTextLength - 1)
|
||||
{
|
||||
isBeginRegion = false;
|
||||
|
||||
topLeft = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
|
||||
bottomLeft = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
|
||||
bottomRight =
|
||||
m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
|
||||
topRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));
|
||||
|
||||
// Draw Region
|
||||
DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, linkColor);
|
||||
|
||||
//Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
|
||||
}
|
||||
// If Link is split on more than one line.
|
||||
else if (isBeginRegion && currentLine != textInfo.characterInfo[characterIndex + 1].lineNumber)
|
||||
{
|
||||
isBeginRegion = false;
|
||||
|
||||
topLeft = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
|
||||
bottomLeft = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
|
||||
bottomRight =
|
||||
m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
|
||||
topRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));
|
||||
|
||||
// Draw Region
|
||||
DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, linkColor);
|
||||
|
||||
maxAscender = -Mathf.Infinity;
|
||||
minDescender = Mathf.Infinity;
|
||||
//Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Log(wInfo.GetWord(m_TextMeshPro.textInfo.characterInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Draw Rectangles around each lines of the text.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
private void DrawLineBounds()
|
||||
{
|
||||
var lineCount = m_TextInfo.lineCount;
|
||||
|
||||
for (var i = 0; i < lineCount; i++)
|
||||
{
|
||||
var lineInfo = m_TextInfo.lineInfo[i];
|
||||
var firstCharacterInfo = m_TextInfo.characterInfo[lineInfo.firstCharacterIndex];
|
||||
var lastCharacterInfo = m_TextInfo.characterInfo[lineInfo.lastCharacterIndex];
|
||||
|
||||
var isLineVisible = (lineInfo.characterCount == 1 && (firstCharacterInfo.character == 10 ||
|
||||
firstCharacterInfo.character == 11 ||
|
||||
firstCharacterInfo.character == 0x2028 ||
|
||||
firstCharacterInfo.character == 0x2029)) ||
|
||||
i > m_TextComponent.maxVisibleLines ||
|
||||
(m_TextComponent.overflowMode == TextOverflowModes.Page &&
|
||||
firstCharacterInfo.pageNumber + 1 != m_TextComponent.pageToDisplay)
|
||||
? false
|
||||
: true;
|
||||
|
||||
if (!isLineVisible) continue;
|
||||
|
||||
var lineBottomLeft = firstCharacterInfo.bottomLeft.x;
|
||||
var lineTopRight = lastCharacterInfo.topRight.x;
|
||||
|
||||
var ascentline = lineInfo.ascender;
|
||||
var baseline = lineInfo.baseline;
|
||||
var descentline = lineInfo.descender;
|
||||
|
||||
float dottedLineSize = 12;
|
||||
|
||||
// Draw line extents
|
||||
DrawDottedRectangle(m_Transform.TransformPoint(lineInfo.lineExtents.min),
|
||||
m_Transform.TransformPoint(lineInfo.lineExtents.max), Color.green, 4);
|
||||
|
||||
// Draw Ascent line
|
||||
var ascentlineStart = m_Transform.TransformPoint(new Vector3(lineBottomLeft, ascentline, 0));
|
||||
var ascentlineEnd = m_Transform.TransformPoint(new Vector3(lineTopRight, ascentline, 0));
|
||||
|
||||
Handles.color = Color.yellow;
|
||||
Handles.DrawDottedLine(ascentlineStart, ascentlineEnd, dottedLineSize);
|
||||
|
||||
// Draw Base line
|
||||
var baseLineStart = m_Transform.TransformPoint(new Vector3(lineBottomLeft, baseline, 0));
|
||||
var baseLineEnd = m_Transform.TransformPoint(new Vector3(lineTopRight, baseline, 0));
|
||||
|
||||
Handles.color = Color.yellow;
|
||||
Handles.DrawDottedLine(baseLineStart, baseLineEnd, dottedLineSize);
|
||||
|
||||
// Draw Descent line
|
||||
var descentLineStart = m_Transform.TransformPoint(new Vector3(lineBottomLeft, descentline, 0));
|
||||
var descentLineEnd = m_Transform.TransformPoint(new Vector3(lineTopRight, descentline, 0));
|
||||
|
||||
Handles.color = Color.yellow;
|
||||
Handles.DrawDottedLine(descentLineStart, descentLineEnd, dottedLineSize);
|
||||
|
||||
// Draw text labels for metrics
|
||||
if (m_HandleSize < 1.0f)
|
||||
{
|
||||
var style = new GUIStyle();
|
||||
style.normal.textColor = new Color(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
style.fontSize = 12;
|
||||
style.fixedWidth = 200;
|
||||
style.fixedHeight = 20;
|
||||
Vector3 labelPosition;
|
||||
|
||||
// Ascent Line
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(lineBottomLeft, ascentline, 0));
|
||||
style.padding = new RectOffset(0, 10, 0, 5);
|
||||
style.alignment = TextAnchor.MiddleRight;
|
||||
Handles.Label(labelPosition, "Ascent Line", style);
|
||||
|
||||
// Base Line
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(lineBottomLeft, baseline, 0));
|
||||
Handles.Label(labelPosition, "Base Line", style);
|
||||
|
||||
// Descent line
|
||||
labelPosition = m_Transform.TransformPoint(new Vector3(lineBottomLeft, descentline, 0));
|
||||
Handles.Label(labelPosition, "Descent Line", style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Draw Rectangle around the bounds of the text object.
|
||||
/// </summary>
|
||||
private void DrawBounds()
|
||||
{
|
||||
var meshBounds = m_TextComponent.bounds;
|
||||
|
||||
// Get Bottom Left and Top Right position of each word
|
||||
var bottomLeft = m_TextComponent.transform.position + meshBounds.min;
|
||||
var topRight = m_TextComponent.transform.position + meshBounds.max;
|
||||
|
||||
DrawRectangle(bottomLeft, topRight, new Color(1, 0.5f, 0));
|
||||
}
|
||||
|
||||
|
||||
private void DrawTextBounds()
|
||||
{
|
||||
var textBounds = m_TextComponent.textBounds;
|
||||
|
||||
var bottomLeft = m_TextComponent.transform.position + (textBounds.center - textBounds.extents);
|
||||
var topRight = m_TextComponent.transform.position + (textBounds.center + textBounds.extents);
|
||||
|
||||
DrawRectangle(bottomLeft, topRight, new Color(0f, 0.5f, 0.5f));
|
||||
}
|
||||
|
||||
|
||||
// Draw Rectangles
|
||||
private void DrawRectangle(Vector3 BL, Vector3 TR, Color color)
|
||||
{
|
||||
Gizmos.color = color;
|
||||
|
||||
Gizmos.DrawLine(new Vector3(BL.x, BL.y, 0), new Vector3(BL.x, TR.y, 0));
|
||||
Gizmos.DrawLine(new Vector3(BL.x, TR.y, 0), new Vector3(TR.x, TR.y, 0));
|
||||
Gizmos.DrawLine(new Vector3(TR.x, TR.y, 0), new Vector3(TR.x, BL.y, 0));
|
||||
Gizmos.DrawLine(new Vector3(TR.x, BL.y, 0), new Vector3(BL.x, BL.y, 0));
|
||||
}
|
||||
|
||||
private void DrawDottedRectangle(Vector3 bottomLeft, Vector3 topRight, Color color, float size = 5.0f)
|
||||
{
|
||||
Handles.color = color;
|
||||
Handles.DrawDottedLine(bottomLeft, new Vector3(bottomLeft.x, topRight.y, bottomLeft.z), size);
|
||||
Handles.DrawDottedLine(new Vector3(bottomLeft.x, topRight.y, bottomLeft.z), topRight, size);
|
||||
Handles.DrawDottedLine(topRight, new Vector3(topRight.x, bottomLeft.y, bottomLeft.z), size);
|
||||
Handles.DrawDottedLine(new Vector3(topRight.x, bottomLeft.y, bottomLeft.z), bottomLeft, size);
|
||||
}
|
||||
|
||||
private void DrawSolidRectangle(Vector3 bottomLeft, Vector3 topRight, Color color, float size = 5.0f)
|
||||
{
|
||||
Handles.color = color;
|
||||
var rect = new Rect(bottomLeft, topRight - bottomLeft);
|
||||
Handles.DrawSolidRectangleWithOutline(rect, color, Color.black);
|
||||
}
|
||||
|
||||
private void DrawSquare(Vector3 position, float size, Color color)
|
||||
{
|
||||
Handles.color = color;
|
||||
var bottomLeft = new Vector3(position.x - size, position.y - size, position.z);
|
||||
var topLeft = new Vector3(position.x - size, position.y + size, position.z);
|
||||
var topRight = new Vector3(position.x + size, position.y + size, position.z);
|
||||
var bottomRight = new Vector3(position.x + size, position.y - size, position.z);
|
||||
|
||||
Handles.DrawLine(bottomLeft, topLeft);
|
||||
Handles.DrawLine(topLeft, topRight);
|
||||
Handles.DrawLine(topRight, bottomRight);
|
||||
Handles.DrawLine(bottomRight, bottomLeft);
|
||||
}
|
||||
|
||||
private void DrawCrosshair(Vector3 position, float size, Color color)
|
||||
{
|
||||
Handles.color = color;
|
||||
|
||||
Handles.DrawLine(new Vector3(position.x - size, position.y, position.z),
|
||||
new Vector3(position.x + size, position.y, position.z));
|
||||
Handles.DrawLine(new Vector3(position.x, position.y - size, position.z),
|
||||
new Vector3(position.x, position.y + size, position.z));
|
||||
}
|
||||
|
||||
|
||||
// Draw Rectangles
|
||||
private void DrawRectangle(Vector3 bl, Vector3 tl, Vector3 tr, Vector3 br, Color color)
|
||||
{
|
||||
Gizmos.color = color;
|
||||
|
||||
Gizmos.DrawLine(bl, tl);
|
||||
Gizmos.DrawLine(tl, tr);
|
||||
Gizmos.DrawLine(tr, br);
|
||||
Gizmos.DrawLine(br, bl);
|
||||
}
|
||||
|
||||
|
||||
// Draw Rectangles
|
||||
private void DrawDottedRectangle(Vector3 bl, Vector3 tl, Vector3 tr, Vector3 br, Color color)
|
||||
{
|
||||
var cam = Camera.current;
|
||||
var dotSpacing = (cam.WorldToScreenPoint(br).x - cam.WorldToScreenPoint(bl).x) / 75f;
|
||||
Handles.color = color;
|
||||
|
||||
Handles.DrawDottedLine(bl, tl, dotSpacing);
|
||||
Handles.DrawDottedLine(tl, tr, dotSpacing);
|
||||
Handles.DrawDottedLine(tr, br, dotSpacing);
|
||||
Handles.DrawDottedLine(br, bl, dotSpacing);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21256c5b62f346f18640dad779911e20
|
||||
timeCreated: 1430348781
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,161 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TMP_TextSelector_A : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
||||
{
|
||||
private Camera m_Camera;
|
||||
|
||||
private bool m_isHoveringObject;
|
||||
private int m_lastCharIndex = -1;
|
||||
private int m_lastWordIndex = -1;
|
||||
private int m_selectedLink = -1;
|
||||
private TextMeshPro m_TextMeshPro;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextMeshPro = gameObject.GetComponent<TextMeshPro>();
|
||||
m_Camera = Camera.main;
|
||||
|
||||
// Force generation of the text object so we have valid data to work with. This is needed since LateUpdate() will be called before the text object has a chance to generated when entering play mode.
|
||||
m_TextMeshPro.ForceMeshUpdate();
|
||||
}
|
||||
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
m_isHoveringObject = false;
|
||||
|
||||
if (TMP_TextUtilities.IsIntersectingRectTransform(m_TextMeshPro.rectTransform, Input.mousePosition,
|
||||
Camera.main)) m_isHoveringObject = true;
|
||||
|
||||
if (m_isHoveringObject)
|
||||
{
|
||||
#region Example of Character Selection
|
||||
|
||||
var charIndex =
|
||||
TMP_TextUtilities.FindIntersectingCharacter(m_TextMeshPro, Input.mousePosition, Camera.main, true);
|
||||
if (charIndex != -1 && charIndex != m_lastCharIndex &&
|
||||
(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
||||
{
|
||||
//Debug.Log("[" + m_TextMeshPro.textInfo.characterInfo[charIndex].character + "] has been selected.");
|
||||
|
||||
m_lastCharIndex = charIndex;
|
||||
|
||||
var meshIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].materialReferenceIndex;
|
||||
|
||||
var vertexIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].vertexIndex;
|
||||
|
||||
var c = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255),
|
||||
(byte)Random.Range(0, 255), 255);
|
||||
|
||||
var vertexColors = m_TextMeshPro.textInfo.meshInfo[meshIndex].colors32;
|
||||
|
||||
vertexColors[vertexIndex + 0] = c;
|
||||
vertexColors[vertexIndex + 1] = c;
|
||||
vertexColors[vertexIndex + 2] = c;
|
||||
vertexColors[vertexIndex + 3] = c;
|
||||
|
||||
//m_TextMeshPro.mesh.colors32 = vertexColors;
|
||||
m_TextMeshPro.textInfo.meshInfo[meshIndex].mesh.colors32 = vertexColors;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Example of Link Handling
|
||||
|
||||
// Check if mouse intersects with any links.
|
||||
var linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);
|
||||
|
||||
// Clear previous link selection if one existed.
|
||||
if ((linkIndex == -1 && m_selectedLink != -1) || linkIndex != m_selectedLink)
|
||||
//m_TextPopup_RectTransform.gameObject.SetActive(false);
|
||||
m_selectedLink = -1;
|
||||
|
||||
// Handle new Link selection.
|
||||
if (linkIndex != -1 && linkIndex != m_selectedLink)
|
||||
{
|
||||
m_selectedLink = linkIndex;
|
||||
|
||||
var linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
|
||||
|
||||
// The following provides an example of how to access the link properties.
|
||||
//Debug.Log("Link ID: \"" + linkInfo.GetLinkID() + "\" Link Text: \"" + linkInfo.GetLinkText() + "\""); // Example of how to retrieve the Link ID and Link Text.
|
||||
|
||||
Vector3 worldPointInRectangle;
|
||||
|
||||
RectTransformUtility.ScreenPointToWorldPointInRectangle(m_TextMeshPro.rectTransform,
|
||||
Input.mousePosition, m_Camera, out worldPointInRectangle);
|
||||
|
||||
switch (linkInfo.GetLinkID())
|
||||
{
|
||||
case "id_01": // 100041637: // id_01
|
||||
//m_TextPopup_RectTransform.position = worldPointInRectangle;
|
||||
//m_TextPopup_RectTransform.gameObject.SetActive(true);
|
||||
//m_TextPopup_TMPComponent.text = k_LinkText + " ID 01";
|
||||
break;
|
||||
case "id_02": // 100041638: // id_02
|
||||
//m_TextPopup_RectTransform.position = worldPointInRectangle;
|
||||
//m_TextPopup_RectTransform.gameObject.SetActive(true);
|
||||
//m_TextPopup_TMPComponent.text = k_LinkText + " ID 02";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Example of Word Selection
|
||||
|
||||
// Check if Mouse intersects any words and if so assign a random color to that word.
|
||||
var wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextMeshPro, Input.mousePosition, Camera.main);
|
||||
if (wordIndex != -1 && wordIndex != m_lastWordIndex)
|
||||
{
|
||||
m_lastWordIndex = wordIndex;
|
||||
|
||||
var wInfo = m_TextMeshPro.textInfo.wordInfo[wordIndex];
|
||||
|
||||
var wordPOS = m_TextMeshPro.transform.TransformPoint(m_TextMeshPro.textInfo
|
||||
.characterInfo[wInfo.firstCharacterIndex].bottomLeft);
|
||||
wordPOS = Camera.main.WorldToScreenPoint(wordPOS);
|
||||
|
||||
//Debug.Log("Mouse Position: " + Input.mousePosition.ToString("f3") + " Word Position: " + wordPOS.ToString("f3"));
|
||||
|
||||
var vertexColors = m_TextMeshPro.textInfo.meshInfo[0].colors32;
|
||||
|
||||
var c = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255),
|
||||
(byte)Random.Range(0, 255), 255);
|
||||
for (var i = 0; i < wInfo.characterCount; i++)
|
||||
{
|
||||
var vertexIndex = m_TextMeshPro.textInfo.characterInfo[wInfo.firstCharacterIndex + i]
|
||||
.vertexIndex;
|
||||
|
||||
vertexColors[vertexIndex + 0] = c;
|
||||
vertexColors[vertexIndex + 1] = c;
|
||||
vertexColors[vertexIndex + 2] = c;
|
||||
vertexColors[vertexIndex + 3] = c;
|
||||
}
|
||||
|
||||
m_TextMeshPro.mesh.colors32 = vertexColors;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
Debug.Log("OnPointerEnter()");
|
||||
m_isHoveringObject = true;
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
Debug.Log("OnPointerExit()");
|
||||
m_isHoveringObject = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 103e0a6a1d404693b9fb1a5173e0e979
|
||||
timeCreated: 1452811039
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,557 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
#pragma warning disable 0618 // Disabled warning due to SetVertices being deprecated until new release with SetMesh() is available.
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TMP_TextSelector_B : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler,
|
||||
IPointerUpHandler
|
||||
{
|
||||
private const string k_LinkText = "You have selected link <#ffff00>";
|
||||
private const string k_WordText = "Word Index: <#ffff00>";
|
||||
public RectTransform TextPopup_Prefab_01;
|
||||
|
||||
// Flags
|
||||
private bool isHoveringObject;
|
||||
|
||||
private TMP_MeshInfo[] m_cachedMeshInfoVertexData;
|
||||
private Camera m_Camera;
|
||||
private Canvas m_Canvas;
|
||||
private int m_lastIndex = -1;
|
||||
|
||||
private Matrix4x4 m_matrix;
|
||||
private int m_selectedLink = -1;
|
||||
private int m_selectedWord = -1;
|
||||
|
||||
|
||||
private TextMeshProUGUI m_TextMeshPro;
|
||||
|
||||
private RectTransform m_TextPopup_RectTransform;
|
||||
private TextMeshProUGUI m_TextPopup_TMPComponent;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextMeshPro = gameObject.GetComponent<TextMeshProUGUI>();
|
||||
|
||||
|
||||
m_Canvas = gameObject.GetComponentInParent<Canvas>();
|
||||
|
||||
// Get a reference to the camera if Canvas Render Mode is not ScreenSpace Overlay.
|
||||
if (m_Canvas.renderMode == RenderMode.ScreenSpaceOverlay)
|
||||
m_Camera = null;
|
||||
else
|
||||
m_Camera = m_Canvas.worldCamera;
|
||||
|
||||
// Create pop-up text object which is used to show the link information.
|
||||
m_TextPopup_RectTransform = Instantiate(TextPopup_Prefab_01);
|
||||
m_TextPopup_RectTransform.SetParent(m_Canvas.transform, false);
|
||||
m_TextPopup_TMPComponent = m_TextPopup_RectTransform.GetComponentInChildren<TextMeshProUGUI>();
|
||||
m_TextPopup_RectTransform.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (isHoveringObject)
|
||||
{
|
||||
// Check if Mouse Intersects any of the characters. If so, assign a random color.
|
||||
|
||||
#region Handle Character Selection
|
||||
|
||||
var charIndex =
|
||||
TMP_TextUtilities.FindIntersectingCharacter(m_TextMeshPro, Input.mousePosition, m_Camera, true);
|
||||
|
||||
// Undo Swap and Vertex Attribute changes.
|
||||
if (charIndex == -1 || charIndex != m_lastIndex)
|
||||
{
|
||||
RestoreCachedVertexAttributes(m_lastIndex);
|
||||
m_lastIndex = -1;
|
||||
}
|
||||
|
||||
if (charIndex != -1 && charIndex != m_lastIndex &&
|
||||
(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
||||
{
|
||||
m_lastIndex = charIndex;
|
||||
|
||||
// Get the index of the material / sub text object used by this character.
|
||||
var materialIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].materialReferenceIndex;
|
||||
|
||||
// Get the index of the first vertex of the selected character.
|
||||
var vertexIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].vertexIndex;
|
||||
|
||||
// Get a reference to the vertices array.
|
||||
var vertices = m_TextMeshPro.textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
// Determine the center point of the character.
|
||||
Vector2 charMidBasline = (vertices[vertexIndex + 0] + vertices[vertexIndex + 2]) / 2;
|
||||
|
||||
// Need to translate all 4 vertices of the character to aligned with middle of character / baseline.
|
||||
// This is needed so the matrix TRS is applied at the origin for each character.
|
||||
Vector3 offset = charMidBasline;
|
||||
|
||||
// Translate the character to the middle baseline.
|
||||
vertices[vertexIndex + 0] = vertices[vertexIndex + 0] - offset;
|
||||
vertices[vertexIndex + 1] = vertices[vertexIndex + 1] - offset;
|
||||
vertices[vertexIndex + 2] = vertices[vertexIndex + 2] - offset;
|
||||
vertices[vertexIndex + 3] = vertices[vertexIndex + 3] - offset;
|
||||
|
||||
var zoomFactor = 1.5f;
|
||||
|
||||
// Setup the Matrix for the scale change.
|
||||
m_matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * zoomFactor);
|
||||
|
||||
// Apply Matrix operation on the given character.
|
||||
vertices[vertexIndex + 0] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
|
||||
vertices[vertexIndex + 1] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
|
||||
vertices[vertexIndex + 2] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
|
||||
vertices[vertexIndex + 3] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);
|
||||
|
||||
// Translate the character back to its original position.
|
||||
vertices[vertexIndex + 0] = vertices[vertexIndex + 0] + offset;
|
||||
vertices[vertexIndex + 1] = vertices[vertexIndex + 1] + offset;
|
||||
vertices[vertexIndex + 2] = vertices[vertexIndex + 2] + offset;
|
||||
vertices[vertexIndex + 3] = vertices[vertexIndex + 3] + offset;
|
||||
|
||||
// Change Vertex Colors of the highlighted character
|
||||
var c = new Color32(255, 255, 192, 255);
|
||||
|
||||
// Get a reference to the vertex color
|
||||
var vertexColors = m_TextMeshPro.textInfo.meshInfo[materialIndex].colors32;
|
||||
|
||||
vertexColors[vertexIndex + 0] = c;
|
||||
vertexColors[vertexIndex + 1] = c;
|
||||
vertexColors[vertexIndex + 2] = c;
|
||||
vertexColors[vertexIndex + 3] = c;
|
||||
|
||||
|
||||
// Get a reference to the meshInfo of the selected character.
|
||||
var meshInfo = m_TextMeshPro.textInfo.meshInfo[materialIndex];
|
||||
|
||||
// Get the index of the last character's vertex attributes.
|
||||
var lastVertexIndex = vertices.Length - 4;
|
||||
|
||||
// Swap the current character's vertex attributes with those of the last element in the vertex attribute arrays.
|
||||
// We do this to make sure this character is rendered last and over other characters.
|
||||
meshInfo.SwapVertexData(vertexIndex, lastVertexIndex);
|
||||
|
||||
// Need to update the appropriate
|
||||
m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Word Selection Handling
|
||||
|
||||
//Check if Mouse intersects any words and if so assign a random color to that word.
|
||||
var wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextMeshPro, Input.mousePosition, m_Camera);
|
||||
|
||||
// Clear previous word selection.
|
||||
if (m_TextPopup_RectTransform != null && m_selectedWord != -1 &&
|
||||
(wordIndex == -1 || wordIndex != m_selectedWord))
|
||||
{
|
||||
var wInfo = m_TextMeshPro.textInfo.wordInfo[m_selectedWord];
|
||||
|
||||
// Iterate through each of the characters of the word.
|
||||
for (var i = 0; i < wInfo.characterCount; i++)
|
||||
{
|
||||
var characterIndex = wInfo.firstCharacterIndex + i;
|
||||
|
||||
// Get the index of the material / sub text object used by this character.
|
||||
var meshIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].materialReferenceIndex;
|
||||
|
||||
// Get the index of the first vertex of this character.
|
||||
var vertexIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].vertexIndex;
|
||||
|
||||
// Get a reference to the vertex color
|
||||
var vertexColors = m_TextMeshPro.textInfo.meshInfo[meshIndex].colors32;
|
||||
|
||||
var c = vertexColors[vertexIndex + 0].Tint(1.33333f);
|
||||
|
||||
vertexColors[vertexIndex + 0] = c;
|
||||
vertexColors[vertexIndex + 1] = c;
|
||||
vertexColors[vertexIndex + 2] = c;
|
||||
vertexColors[vertexIndex + 3] = c;
|
||||
}
|
||||
|
||||
// Update Geometry
|
||||
m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
|
||||
|
||||
m_selectedWord = -1;
|
||||
}
|
||||
|
||||
|
||||
// Word Selection Handling
|
||||
if (wordIndex != -1 && wordIndex != m_selectedWord &&
|
||||
!(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)))
|
||||
{
|
||||
m_selectedWord = wordIndex;
|
||||
|
||||
var wInfo = m_TextMeshPro.textInfo.wordInfo[wordIndex];
|
||||
|
||||
// Iterate through each of the characters of the word.
|
||||
for (var i = 0; i < wInfo.characterCount; i++)
|
||||
{
|
||||
var characterIndex = wInfo.firstCharacterIndex + i;
|
||||
|
||||
// Get the index of the material / sub text object used by this character.
|
||||
var meshIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].materialReferenceIndex;
|
||||
|
||||
var vertexIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].vertexIndex;
|
||||
|
||||
// Get a reference to the vertex color
|
||||
var vertexColors = m_TextMeshPro.textInfo.meshInfo[meshIndex].colors32;
|
||||
|
||||
var c = vertexColors[vertexIndex + 0].Tint(0.75f);
|
||||
|
||||
vertexColors[vertexIndex + 0] = c;
|
||||
vertexColors[vertexIndex + 1] = c;
|
||||
vertexColors[vertexIndex + 2] = c;
|
||||
vertexColors[vertexIndex + 3] = c;
|
||||
}
|
||||
|
||||
// Update Geometry
|
||||
m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Example of Link Handling
|
||||
|
||||
// Check if mouse intersects with any links.
|
||||
var linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);
|
||||
|
||||
// Clear previous link selection if one existed.
|
||||
if ((linkIndex == -1 && m_selectedLink != -1) || linkIndex != m_selectedLink)
|
||||
{
|
||||
m_TextPopup_RectTransform.gameObject.SetActive(false);
|
||||
m_selectedLink = -1;
|
||||
}
|
||||
|
||||
// Handle new Link selection.
|
||||
if (linkIndex != -1 && linkIndex != m_selectedLink)
|
||||
{
|
||||
m_selectedLink = linkIndex;
|
||||
|
||||
var linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
|
||||
|
||||
// Debug.Log("Link ID: \"" + linkInfo.GetLinkID() + "\" Link Text: \"" + linkInfo.GetLinkText() + "\""); // Example of how to retrieve the Link ID and Link Text.
|
||||
|
||||
Vector3 worldPointInRectangle;
|
||||
RectTransformUtility.ScreenPointToWorldPointInRectangle(m_TextMeshPro.rectTransform,
|
||||
Input.mousePosition, m_Camera, out worldPointInRectangle);
|
||||
|
||||
switch (linkInfo.GetLinkID())
|
||||
{
|
||||
case "id_01": // 100041637: // id_01
|
||||
m_TextPopup_RectTransform.position = worldPointInRectangle;
|
||||
m_TextPopup_RectTransform.gameObject.SetActive(true);
|
||||
m_TextPopup_TMPComponent.text = k_LinkText + " ID 01";
|
||||
break;
|
||||
case "id_02": // 100041638: // id_02
|
||||
m_TextPopup_RectTransform.position = worldPointInRectangle;
|
||||
m_TextPopup_RectTransform.gameObject.SetActive(true);
|
||||
m_TextPopup_TMPComponent.text = k_LinkText + " ID 02";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore any character that may have been modified
|
||||
if (m_lastIndex != -1)
|
||||
{
|
||||
RestoreCachedVertexAttributes(m_lastIndex);
|
||||
m_lastIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Subscribe to event fired when text object has been regenerated.
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// UnSubscribe to event fired when text object has been regenerated.
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
//Debug.Log("Click at POS: " + eventData.position + " World POS: " + eventData.worldPosition);
|
||||
|
||||
// Check if Mouse Intersects any of the characters. If so, assign a random color.
|
||||
|
||||
#region Character Selection Handling
|
||||
|
||||
/*
|
||||
int charIndex = TMP_TextUtilities.FindIntersectingCharacter(m_TextMeshPro, Input.mousePosition, m_Camera, true);
|
||||
if (charIndex != -1 && charIndex != m_lastIndex)
|
||||
{
|
||||
//Debug.Log("Character [" + m_TextMeshPro.textInfo.characterInfo[index].character + "] was selected at POS: " + eventData.position);
|
||||
m_lastIndex = charIndex;
|
||||
|
||||
Color32 c = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 255);
|
||||
int vertexIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].vertexIndex;
|
||||
|
||||
UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
|
||||
|
||||
uiVertices[vertexIndex + 0].color = c;
|
||||
uiVertices[vertexIndex + 1].color = c;
|
||||
uiVertices[vertexIndex + 2].color = c;
|
||||
uiVertices[vertexIndex + 3].color = c;
|
||||
|
||||
m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
|
||||
}
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Word Selection Handling
|
||||
|
||||
//Check if Mouse intersects any words and if so assign a random color to that word.
|
||||
/*
|
||||
int wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextMeshPro, Input.mousePosition, m_Camera);
|
||||
|
||||
// Clear previous word selection.
|
||||
if (m_TextPopup_RectTransform != null && m_selectedWord != -1 && (wordIndex == -1 || wordIndex != m_selectedWord))
|
||||
{
|
||||
TMP_WordInfo wInfo = m_TextMeshPro.textInfo.wordInfo[m_selectedWord];
|
||||
|
||||
// Get a reference to the uiVertices array.
|
||||
UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
|
||||
|
||||
// Iterate through each of the characters of the word.
|
||||
for (int i = 0; i < wInfo.characterCount; i++)
|
||||
{
|
||||
int vertexIndex = m_TextMeshPro.textInfo.characterInfo[wInfo.firstCharacterIndex + i].vertexIndex;
|
||||
|
||||
Color32 c = uiVertices[vertexIndex + 0].color.Tint(1.33333f);
|
||||
|
||||
uiVertices[vertexIndex + 0].color = c;
|
||||
uiVertices[vertexIndex + 1].color = c;
|
||||
uiVertices[vertexIndex + 2].color = c;
|
||||
uiVertices[vertexIndex + 3].color = c;
|
||||
}
|
||||
|
||||
m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
|
||||
|
||||
m_selectedWord = -1;
|
||||
}
|
||||
|
||||
// Handle word selection
|
||||
if (wordIndex != -1 && wordIndex != m_selectedWord)
|
||||
{
|
||||
m_selectedWord = wordIndex;
|
||||
|
||||
TMP_WordInfo wInfo = m_TextMeshPro.textInfo.wordInfo[wordIndex];
|
||||
|
||||
// Get a reference to the uiVertices array.
|
||||
UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
|
||||
|
||||
// Iterate through each of the characters of the word.
|
||||
for (int i = 0; i < wInfo.characterCount; i++)
|
||||
{
|
||||
int vertexIndex = m_TextMeshPro.textInfo.characterInfo[wInfo.firstCharacterIndex + i].vertexIndex;
|
||||
|
||||
Color32 c = uiVertices[vertexIndex + 0].color.Tint(0.75f);
|
||||
|
||||
uiVertices[vertexIndex + 0].color = c;
|
||||
uiVertices[vertexIndex + 1].color = c;
|
||||
uiVertices[vertexIndex + 2].color = c;
|
||||
uiVertices[vertexIndex + 3].color = c;
|
||||
}
|
||||
|
||||
m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
|
||||
}
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Link Selection Handling
|
||||
|
||||
/*
|
||||
// Check if Mouse intersects any words and if so assign a random color to that word.
|
||||
int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);
|
||||
if (linkIndex != -1)
|
||||
{
|
||||
TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
|
||||
int linkHashCode = linkInfo.hashCode;
|
||||
|
||||
//Debug.Log(TMP_TextUtilities.GetSimpleHashCode("id_02"));
|
||||
|
||||
switch (linkHashCode)
|
||||
{
|
||||
case 291445: // id_01
|
||||
if (m_LinkObject01 == null)
|
||||
m_LinkObject01 = Instantiate(Link_01_Prefab);
|
||||
else
|
||||
{
|
||||
m_LinkObject01.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
break;
|
||||
case 291446: // id_02
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Example of how to modify vertex attributes like colors
|
||||
#region Vertex Attribute Modification Example
|
||||
UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
|
||||
|
||||
Color32 c = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 255);
|
||||
for (int i = 0; i < linkInfo.characterCount; i++)
|
||||
{
|
||||
TMP_CharacterInfo cInfo = m_TextMeshPro.textInfo.characterInfo[linkInfo.firstCharacterIndex + i];
|
||||
|
||||
if (!cInfo.isVisible) continue; // Skip invisible characters.
|
||||
|
||||
int vertexIndex = cInfo.vertexIndex;
|
||||
|
||||
uiVertices[vertexIndex + 0].color = c;
|
||||
uiVertices[vertexIndex + 1].color = c;
|
||||
uiVertices[vertexIndex + 2].color = c;
|
||||
uiVertices[vertexIndex + 3].color = c;
|
||||
}
|
||||
|
||||
m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
|
||||
#endregion
|
||||
}
|
||||
*/
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
//Debug.Log("OnPointerEnter()");
|
||||
isHoveringObject = true;
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
//Debug.Log("OnPointerExit()");
|
||||
isHoveringObject = false;
|
||||
}
|
||||
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
//Debug.Log("OnPointerUp()");
|
||||
}
|
||||
|
||||
|
||||
private void ON_TEXT_CHANGED(Object obj)
|
||||
{
|
||||
if (obj == m_TextMeshPro)
|
||||
// Update cached vertex data.
|
||||
m_cachedMeshInfoVertexData = m_TextMeshPro.textInfo.CopyMeshInfoVertexData();
|
||||
}
|
||||
|
||||
|
||||
private void RestoreCachedVertexAttributes(int index)
|
||||
{
|
||||
if (index == -1 || index > m_TextMeshPro.textInfo.characterCount - 1) return;
|
||||
|
||||
// Get the index of the material / sub text object used by this character.
|
||||
var materialIndex = m_TextMeshPro.textInfo.characterInfo[index].materialReferenceIndex;
|
||||
|
||||
// Get the index of the first vertex of the selected character.
|
||||
var vertexIndex = m_TextMeshPro.textInfo.characterInfo[index].vertexIndex;
|
||||
|
||||
// Restore Vertices
|
||||
// Get a reference to the cached / original vertices.
|
||||
var src_vertices = m_cachedMeshInfoVertexData[materialIndex].vertices;
|
||||
|
||||
// Get a reference to the vertices that we need to replace.
|
||||
var dst_vertices = m_TextMeshPro.textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
// Restore / Copy vertices from source to destination
|
||||
dst_vertices[vertexIndex + 0] = src_vertices[vertexIndex + 0];
|
||||
dst_vertices[vertexIndex + 1] = src_vertices[vertexIndex + 1];
|
||||
dst_vertices[vertexIndex + 2] = src_vertices[vertexIndex + 2];
|
||||
dst_vertices[vertexIndex + 3] = src_vertices[vertexIndex + 3];
|
||||
|
||||
// Restore Vertex Colors
|
||||
// Get a reference to the vertex colors we need to replace.
|
||||
var dst_colors = m_TextMeshPro.textInfo.meshInfo[materialIndex].colors32;
|
||||
|
||||
// Get a reference to the cached / original vertex colors.
|
||||
var src_colors = m_cachedMeshInfoVertexData[materialIndex].colors32;
|
||||
|
||||
// Copy the vertex colors from source to destination.
|
||||
dst_colors[vertexIndex + 0] = src_colors[vertexIndex + 0];
|
||||
dst_colors[vertexIndex + 1] = src_colors[vertexIndex + 1];
|
||||
dst_colors[vertexIndex + 2] = src_colors[vertexIndex + 2];
|
||||
dst_colors[vertexIndex + 3] = src_colors[vertexIndex + 3];
|
||||
|
||||
// Restore UV0S
|
||||
// UVS0
|
||||
var src_uv0s = m_cachedMeshInfoVertexData[materialIndex].uvs0;
|
||||
var dst_uv0s = m_TextMeshPro.textInfo.meshInfo[materialIndex].uvs0;
|
||||
dst_uv0s[vertexIndex + 0] = src_uv0s[vertexIndex + 0];
|
||||
dst_uv0s[vertexIndex + 1] = src_uv0s[vertexIndex + 1];
|
||||
dst_uv0s[vertexIndex + 2] = src_uv0s[vertexIndex + 2];
|
||||
dst_uv0s[vertexIndex + 3] = src_uv0s[vertexIndex + 3];
|
||||
|
||||
// UVS2
|
||||
var src_uv2s = m_cachedMeshInfoVertexData[materialIndex].uvs2;
|
||||
var dst_uv2s = m_TextMeshPro.textInfo.meshInfo[materialIndex].uvs2;
|
||||
dst_uv2s[vertexIndex + 0] = src_uv2s[vertexIndex + 0];
|
||||
dst_uv2s[vertexIndex + 1] = src_uv2s[vertexIndex + 1];
|
||||
dst_uv2s[vertexIndex + 2] = src_uv2s[vertexIndex + 2];
|
||||
dst_uv2s[vertexIndex + 3] = src_uv2s[vertexIndex + 3];
|
||||
|
||||
|
||||
// Restore last vertex attribute as we swapped it as well
|
||||
var lastIndex = (src_vertices.Length / 4 - 1) * 4;
|
||||
|
||||
// Vertices
|
||||
dst_vertices[lastIndex + 0] = src_vertices[lastIndex + 0];
|
||||
dst_vertices[lastIndex + 1] = src_vertices[lastIndex + 1];
|
||||
dst_vertices[lastIndex + 2] = src_vertices[lastIndex + 2];
|
||||
dst_vertices[lastIndex + 3] = src_vertices[lastIndex + 3];
|
||||
|
||||
// Vertex Colors
|
||||
src_colors = m_cachedMeshInfoVertexData[materialIndex].colors32;
|
||||
dst_colors = m_TextMeshPro.textInfo.meshInfo[materialIndex].colors32;
|
||||
dst_colors[lastIndex + 0] = src_colors[lastIndex + 0];
|
||||
dst_colors[lastIndex + 1] = src_colors[lastIndex + 1];
|
||||
dst_colors[lastIndex + 2] = src_colors[lastIndex + 2];
|
||||
dst_colors[lastIndex + 3] = src_colors[lastIndex + 3];
|
||||
|
||||
// UVS0
|
||||
src_uv0s = m_cachedMeshInfoVertexData[materialIndex].uvs0;
|
||||
dst_uv0s = m_TextMeshPro.textInfo.meshInfo[materialIndex].uvs0;
|
||||
dst_uv0s[lastIndex + 0] = src_uv0s[lastIndex + 0];
|
||||
dst_uv0s[lastIndex + 1] = src_uv0s[lastIndex + 1];
|
||||
dst_uv0s[lastIndex + 2] = src_uv0s[lastIndex + 2];
|
||||
dst_uv0s[lastIndex + 3] = src_uv0s[lastIndex + 3];
|
||||
|
||||
// UVS2
|
||||
src_uv2s = m_cachedMeshInfoVertexData[materialIndex].uvs2;
|
||||
dst_uv2s = m_TextMeshPro.textInfo.meshInfo[materialIndex].uvs2;
|
||||
dst_uv2s[lastIndex + 0] = src_uv2s[lastIndex + 0];
|
||||
dst_uv2s[lastIndex + 1] = src_uv2s[lastIndex + 1];
|
||||
dst_uv2s[lastIndex + 2] = src_uv2s[lastIndex + 2];
|
||||
dst_uv2s[lastIndex + 3] = src_uv2s[lastIndex + 3];
|
||||
|
||||
// Need to update the appropriate
|
||||
m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a05dcd8be7ec4ccbb35c26219884aa37
|
||||
timeCreated: 1435531209
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- TextPopup_Prefab_01: {fileID: 22450954, guid: b06f0e6c1dfa4356ac918da1bb32c603,
|
||||
type: 2}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,129 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TMP_UiFrameRateCounter : MonoBehaviour
|
||||
{
|
||||
public enum FpsCounterAnchorPositions
|
||||
{
|
||||
TopLeft,
|
||||
BottomLeft,
|
||||
TopRight,
|
||||
BottomRight
|
||||
}
|
||||
|
||||
private const string fpsLabel = "{0:2}</color> <#8080ff>FPS \n<#FF8000>{1:2} <#8080ff>MS";
|
||||
public float UpdateInterval = 5.0f;
|
||||
|
||||
public FpsCounterAnchorPositions AnchorPosition = FpsCounterAnchorPositions.TopRight;
|
||||
|
||||
private string htmlColorTag;
|
||||
|
||||
private FpsCounterAnchorPositions last_AnchorPosition;
|
||||
private RectTransform m_frameCounter_transform;
|
||||
private int m_Frames;
|
||||
private float m_LastInterval;
|
||||
|
||||
private TextMeshProUGUI m_TextMeshPro;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
Application.targetFrameRate = 1000;
|
||||
|
||||
var frameCounter = new GameObject("Frame Counter");
|
||||
m_frameCounter_transform = frameCounter.AddComponent<RectTransform>();
|
||||
|
||||
m_frameCounter_transform.SetParent(transform, false);
|
||||
|
||||
m_TextMeshPro = frameCounter.AddComponent<TextMeshProUGUI>();
|
||||
m_TextMeshPro.font = Resources.Load<TMP_FontAsset>("Fonts & Materials/LiberationSans SDF");
|
||||
m_TextMeshPro.fontSharedMaterial =
|
||||
Resources.Load<Material>("Fonts & Materials/LiberationSans SDF - Overlay");
|
||||
|
||||
m_TextMeshPro.enableWordWrapping = false;
|
||||
m_TextMeshPro.fontSize = 36;
|
||||
|
||||
m_TextMeshPro.isOverlay = true;
|
||||
|
||||
Set_FrameCounter_Position(AnchorPosition);
|
||||
last_AnchorPosition = AnchorPosition;
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
m_LastInterval = Time.realtimeSinceStartup;
|
||||
m_Frames = 0;
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (AnchorPosition != last_AnchorPosition)
|
||||
Set_FrameCounter_Position(AnchorPosition);
|
||||
|
||||
last_AnchorPosition = AnchorPosition;
|
||||
|
||||
m_Frames += 1;
|
||||
var timeNow = Time.realtimeSinceStartup;
|
||||
|
||||
if (timeNow > m_LastInterval + UpdateInterval)
|
||||
{
|
||||
// display two fractional digits (f2 format)
|
||||
var fps = m_Frames / (timeNow - m_LastInterval);
|
||||
var ms = 1000.0f / Mathf.Max(fps, 0.00001f);
|
||||
|
||||
if (fps < 30)
|
||||
htmlColorTag = "<color=yellow>";
|
||||
else if (fps < 10)
|
||||
htmlColorTag = "<color=red>";
|
||||
else
|
||||
htmlColorTag = "<color=green>";
|
||||
|
||||
m_TextMeshPro.SetText(htmlColorTag + fpsLabel, fps, ms);
|
||||
|
||||
m_Frames = 0;
|
||||
m_LastInterval = timeNow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Set_FrameCounter_Position(FpsCounterAnchorPositions anchor_position)
|
||||
{
|
||||
switch (anchor_position)
|
||||
{
|
||||
case FpsCounterAnchorPositions.TopLeft:
|
||||
m_TextMeshPro.alignment = TextAlignmentOptions.TopLeft;
|
||||
m_frameCounter_transform.pivot = new Vector2(0, 1);
|
||||
m_frameCounter_transform.anchorMin = new Vector2(0.01f, 0.99f);
|
||||
m_frameCounter_transform.anchorMax = new Vector2(0.01f, 0.99f);
|
||||
m_frameCounter_transform.anchoredPosition = new Vector2(0, 1);
|
||||
break;
|
||||
case FpsCounterAnchorPositions.BottomLeft:
|
||||
m_TextMeshPro.alignment = TextAlignmentOptions.BottomLeft;
|
||||
m_frameCounter_transform.pivot = new Vector2(0, 0);
|
||||
m_frameCounter_transform.anchorMin = new Vector2(0.01f, 0.01f);
|
||||
m_frameCounter_transform.anchorMax = new Vector2(0.01f, 0.01f);
|
||||
m_frameCounter_transform.anchoredPosition = new Vector2(0, 0);
|
||||
break;
|
||||
case FpsCounterAnchorPositions.TopRight:
|
||||
m_TextMeshPro.alignment = TextAlignmentOptions.TopRight;
|
||||
m_frameCounter_transform.pivot = new Vector2(1, 1);
|
||||
m_frameCounter_transform.anchorMin = new Vector2(0.99f, 0.99f);
|
||||
m_frameCounter_transform.anchorMax = new Vector2(0.99f, 0.99f);
|
||||
m_frameCounter_transform.anchoredPosition = new Vector2(1, 1);
|
||||
break;
|
||||
case FpsCounterAnchorPositions.BottomRight:
|
||||
m_TextMeshPro.alignment = TextAlignmentOptions.BottomRight;
|
||||
m_frameCounter_transform.pivot = new Vector2(1, 0);
|
||||
m_frameCounter_transform.anchorMin = new Vector2(0.99f, 0.01f);
|
||||
m_frameCounter_transform.anchorMax = new Vector2(0.99f, 0.01f);
|
||||
m_frameCounter_transform.anchoredPosition = new Vector2(1, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24b0dc2d1d494adbbec1f4db26b4cf83
|
||||
timeCreated: 1448607572
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,84 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TMPro_InstructionOverlay : MonoBehaviour
|
||||
{
|
||||
public enum FpsCounterAnchorPositions
|
||||
{
|
||||
TopLeft,
|
||||
BottomLeft,
|
||||
TopRight,
|
||||
BottomRight
|
||||
}
|
||||
|
||||
private const string instructions =
|
||||
"Camera Control - <#ffff00>Shift + RMB\n</color>Zoom - <#ffff00>Mouse wheel.";
|
||||
|
||||
public FpsCounterAnchorPositions AnchorPosition = FpsCounterAnchorPositions.BottomLeft;
|
||||
private Camera m_camera;
|
||||
private Transform m_frameCounter_transform;
|
||||
private TextContainer m_textContainer;
|
||||
|
||||
private TextMeshPro m_TextMeshPro;
|
||||
|
||||
//private FpsCounterAnchorPositions last_AnchorPosition;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
m_camera = Camera.main;
|
||||
|
||||
var frameCounter = new GameObject("Frame Counter");
|
||||
m_frameCounter_transform = frameCounter.transform;
|
||||
m_frameCounter_transform.parent = m_camera.transform;
|
||||
m_frameCounter_transform.localRotation = Quaternion.identity;
|
||||
|
||||
|
||||
m_TextMeshPro = frameCounter.AddComponent<TextMeshPro>();
|
||||
m_TextMeshPro.font = Resources.Load<TMP_FontAsset>("Fonts & Materials/LiberationSans SDF");
|
||||
m_TextMeshPro.fontSharedMaterial =
|
||||
Resources.Load<Material>("Fonts & Materials/LiberationSans SDF - Overlay");
|
||||
|
||||
m_TextMeshPro.fontSize = 30;
|
||||
|
||||
m_TextMeshPro.isOverlay = true;
|
||||
m_textContainer = frameCounter.GetComponent<TextContainer>();
|
||||
|
||||
Set_FrameCounter_Position(AnchorPosition);
|
||||
//last_AnchorPosition = AnchorPosition;
|
||||
|
||||
m_TextMeshPro.text = instructions;
|
||||
}
|
||||
|
||||
|
||||
private void Set_FrameCounter_Position(FpsCounterAnchorPositions anchor_position)
|
||||
{
|
||||
switch (anchor_position)
|
||||
{
|
||||
case FpsCounterAnchorPositions.TopLeft:
|
||||
//m_TextMeshPro.anchor = AnchorPositions.TopLeft;
|
||||
m_textContainer.anchorPosition = TextContainerAnchors.TopLeft;
|
||||
m_frameCounter_transform.position = m_camera.ViewportToWorldPoint(new Vector3(0, 1, 100.0f));
|
||||
break;
|
||||
case FpsCounterAnchorPositions.BottomLeft:
|
||||
//m_TextMeshPro.anchor = AnchorPositions.BottomLeft;
|
||||
m_textContainer.anchorPosition = TextContainerAnchors.BottomLeft;
|
||||
m_frameCounter_transform.position = m_camera.ViewportToWorldPoint(new Vector3(0, 0, 100.0f));
|
||||
break;
|
||||
case FpsCounterAnchorPositions.TopRight:
|
||||
//m_TextMeshPro.anchor = AnchorPositions.TopRight;
|
||||
m_textContainer.anchorPosition = TextContainerAnchors.TopRight;
|
||||
m_frameCounter_transform.position = m_camera.ViewportToWorldPoint(new Vector3(1, 1, 100.0f));
|
||||
break;
|
||||
case FpsCounterAnchorPositions.BottomRight:
|
||||
//m_TextMeshPro.anchor = AnchorPositions.BottomRight;
|
||||
m_textContainer.anchorPosition = TextContainerAnchors.BottomRight;
|
||||
m_frameCounter_transform.position = m_camera.ViewportToWorldPoint(new Vector3(1, 0, 100.0f));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3c1afeda5e545e0b19add5373896d2e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,78 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TeleType : MonoBehaviour
|
||||
{
|
||||
//[Range(0, 100)]
|
||||
//public int RevealSpeed = 50;
|
||||
|
||||
private readonly string label01 =
|
||||
"Example <sprite=2> of using <sprite=7> <#ffa000>Graphics Inline</color> <sprite=5> with Text in <font=\"Bangers SDF\" material=\"Bangers SDF - Drop Shadow\">TextMesh<#40a0ff>Pro</color></font><sprite=0> and Unity<sprite=1>";
|
||||
|
||||
private readonly string label02 =
|
||||
"Example <sprite=2> of using <sprite=7> <#ffa000>Graphics Inline</color> <sprite=5> with Text in <font=\"Bangers SDF\" material=\"Bangers SDF - Drop Shadow\">TextMesh<#40a0ff>Pro</color></font><sprite=0> and Unity<sprite=2>";
|
||||
|
||||
|
||||
private TMP_Text m_textMeshPro;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Get Reference to TextMeshPro Component
|
||||
m_textMeshPro = GetComponent<TMP_Text>();
|
||||
m_textMeshPro.text = label01;
|
||||
m_textMeshPro.enableWordWrapping = true;
|
||||
m_textMeshPro.alignment = TextAlignmentOptions.Top;
|
||||
|
||||
|
||||
//if (GetComponentInParent(typeof(Canvas)) as Canvas == null)
|
||||
//{
|
||||
// GameObject canvas = new GameObject("Canvas", typeof(Canvas));
|
||||
// gameObject.transform.SetParent(canvas.transform);
|
||||
// canvas.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
|
||||
// // Set RectTransform Size
|
||||
// gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(500, 300);
|
||||
// m_textMeshPro.fontSize = 48;
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
// Force and update of the mesh to get valid information.
|
||||
m_textMeshPro.ForceMeshUpdate();
|
||||
|
||||
|
||||
var totalVisibleCharacters =
|
||||
m_textMeshPro.textInfo.characterCount; // Get # of Visible Character in text object
|
||||
var counter = 0;
|
||||
var visibleCount = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
visibleCount = counter % (totalVisibleCharacters + 1);
|
||||
|
||||
m_textMeshPro.maxVisibleCharacters = visibleCount; // How many characters should TextMeshPro display?
|
||||
|
||||
// Once the last character has been revealed, wait 1.0 second and start over.
|
||||
if (visibleCount >= totalVisibleCharacters)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
m_textMeshPro.text = label02;
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
m_textMeshPro.text = label01;
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
}
|
||||
|
||||
counter += 1;
|
||||
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
}
|
||||
|
||||
//Debug.Log("Done revealing the text.");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e32c266ee6204b21a427753cb0694c81
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,117 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TextConsoleSimulator : MonoBehaviour
|
||||
{
|
||||
private bool hasTextChanged;
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextComponent = gameObject.GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(RevealCharacters(m_TextComponent));
|
||||
//StartCoroutine(RevealWords(m_TextComponent));
|
||||
}
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Subscribe to event fired when text object has been regenerated.
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
// Event received when the text object has changed.
|
||||
private void ON_TEXT_CHANGED(Object obj)
|
||||
{
|
||||
hasTextChanged = true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method revealing the text one character at a time.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerator RevealCharacters(TMP_Text textComponent)
|
||||
{
|
||||
textComponent.ForceMeshUpdate();
|
||||
|
||||
var textInfo = textComponent.textInfo;
|
||||
|
||||
var totalVisibleCharacters = textInfo.characterCount; // Get # of Visible Character in text object
|
||||
var visibleCount = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (hasTextChanged)
|
||||
{
|
||||
totalVisibleCharacters = textInfo.characterCount; // Update visible character count.
|
||||
hasTextChanged = false;
|
||||
}
|
||||
|
||||
if (visibleCount > totalVisibleCharacters)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
visibleCount = 0;
|
||||
}
|
||||
|
||||
textComponent.maxVisibleCharacters = visibleCount; // How many characters should TextMeshPro display?
|
||||
|
||||
visibleCount += 1;
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method revealing the text one word at a time.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerator RevealWords(TMP_Text textComponent)
|
||||
{
|
||||
textComponent.ForceMeshUpdate();
|
||||
|
||||
var totalWordCount = textComponent.textInfo.wordCount;
|
||||
var totalVisibleCharacters =
|
||||
textComponent.textInfo.characterCount; // Get # of Visible Character in text object
|
||||
var counter = 0;
|
||||
var currentWord = 0;
|
||||
var visibleCount = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
currentWord = counter % (totalWordCount + 1);
|
||||
|
||||
// Get last character index for the current word.
|
||||
if (currentWord == 0) // Display no words.
|
||||
visibleCount = 0;
|
||||
else if (currentWord < totalWordCount) // Display all other words with the exception of the last one.
|
||||
visibleCount = textComponent.textInfo.wordInfo[currentWord - 1].lastCharacterIndex + 1;
|
||||
else if (currentWord == totalWordCount) // Display last word and all remaining characters.
|
||||
visibleCount = totalVisibleCharacters;
|
||||
|
||||
textComponent.maxVisibleCharacters = visibleCount; // How many characters should TextMeshPro display?
|
||||
|
||||
// Once the last character has been revealed, wait 1.0 second and start over.
|
||||
if (visibleCount >= totalVisibleCharacters) yield return new WaitForSeconds(1.0f);
|
||||
|
||||
counter += 1;
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43bcd35a1c0c40ccb6d472893fe2093f
|
||||
timeCreated: 1435298333
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,220 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TextMeshProFloatingText : MonoBehaviour
|
||||
{
|
||||
//private int m_frame = 0;
|
||||
|
||||
private static readonly WaitForEndOfFrame k_WaitForEndOfFrame = new();
|
||||
|
||||
private static readonly WaitForSeconds[] k_WaitForSecondsRandom =
|
||||
{
|
||||
new(0.05f), new(0.1f), new(0.15f), new(0.2f), new(0.25f),
|
||||
new(0.3f), new(0.35f), new(0.4f), new(0.45f), new(0.5f),
|
||||
new(0.55f), new(0.6f), new(0.65f), new(0.7f), new(0.75f),
|
||||
new(0.8f), new(0.85f), new(0.9f), new(0.95f), new(1.0f)
|
||||
};
|
||||
|
||||
public Font TheFont;
|
||||
|
||||
public int SpawnType;
|
||||
public bool IsTextObjectScaleStatic;
|
||||
|
||||
private Vector3 lastPOS = Vector3.zero;
|
||||
private Quaternion lastRotation = Quaternion.identity;
|
||||
private Transform m_cameraTransform;
|
||||
|
||||
private GameObject m_floatingText;
|
||||
private Transform m_floatingText_Transform;
|
||||
private TextMesh m_textMesh;
|
||||
private TextMeshPro m_textMeshPro;
|
||||
|
||||
private Transform m_transform;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_transform = transform;
|
||||
m_floatingText = new GameObject(name + " floating text");
|
||||
|
||||
// Reference to Transform is lost when TMP component is added since it replaces it by a RectTransform.
|
||||
//m_floatingText_Transform = m_floatingText.transform;
|
||||
//m_floatingText_Transform.position = m_transform.position + new Vector3(0, 15f, 0);
|
||||
|
||||
m_cameraTransform = Camera.main.transform;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (SpawnType == 0)
|
||||
{
|
||||
// TextMesh Pro Implementation
|
||||
m_textMeshPro = m_floatingText.AddComponent<TextMeshPro>();
|
||||
m_textMeshPro.rectTransform.sizeDelta = new Vector2(3, 3);
|
||||
|
||||
m_floatingText_Transform = m_floatingText.transform;
|
||||
m_floatingText_Transform.position = m_transform.position + new Vector3(0, 15f, 0);
|
||||
|
||||
//m_textMeshPro.fontAsset = Resources.Load("Fonts & Materials/JOKERMAN SDF", typeof(TextMeshProFont)) as TextMeshProFont; // User should only provide a string to the resource.
|
||||
//m_textMeshPro.fontSharedMaterial = Resources.Load("Fonts & Materials/LiberationSans SDF", typeof(Material)) as Material;
|
||||
|
||||
m_textMeshPro.alignment = TextAlignmentOptions.Center;
|
||||
m_textMeshPro.color = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255),
|
||||
(byte)Random.Range(0, 255), 255);
|
||||
m_textMeshPro.fontSize = 24;
|
||||
//m_textMeshPro.enableExtraPadding = true;
|
||||
//m_textMeshPro.enableShadows = false;
|
||||
m_textMeshPro.enableKerning = false;
|
||||
m_textMeshPro.text = string.Empty;
|
||||
m_textMeshPro.isTextObjectScaleStatic = IsTextObjectScaleStatic;
|
||||
|
||||
StartCoroutine(DisplayTextMeshProFloatingText());
|
||||
}
|
||||
else if (SpawnType == 1)
|
||||
{
|
||||
//Debug.Log("Spawning TextMesh Objects.");
|
||||
|
||||
m_floatingText_Transform = m_floatingText.transform;
|
||||
m_floatingText_Transform.position = m_transform.position + new Vector3(0, 15f, 0);
|
||||
|
||||
m_textMesh = m_floatingText.AddComponent<TextMesh>();
|
||||
m_textMesh.font = Resources.Load<Font>("Fonts/ARIAL");
|
||||
m_textMesh.GetComponent<Renderer>().sharedMaterial = m_textMesh.font.material;
|
||||
m_textMesh.color = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255),
|
||||
(byte)Random.Range(0, 255), 255);
|
||||
m_textMesh.anchor = TextAnchor.LowerCenter;
|
||||
m_textMesh.fontSize = 24;
|
||||
|
||||
StartCoroutine(DisplayTextMeshFloatingText());
|
||||
}
|
||||
else if (SpawnType == 2)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void Update()
|
||||
//{
|
||||
// if (SpawnType == 0)
|
||||
// {
|
||||
// m_textMeshPro.SetText("{0}", m_frame);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_textMesh.text = m_frame.ToString();
|
||||
// }
|
||||
// m_frame = (m_frame + 1) % 1000;
|
||||
|
||||
//}
|
||||
|
||||
|
||||
public IEnumerator DisplayTextMeshProFloatingText()
|
||||
{
|
||||
var CountDuration = 2.0f; // How long is the countdown alive.
|
||||
var starting_Count = Random.Range(5f, 20f); // At what number is the counter starting at.
|
||||
var current_Count = starting_Count;
|
||||
|
||||
var start_pos = m_floatingText_Transform.position;
|
||||
Color32 start_color = m_textMeshPro.color;
|
||||
float alpha = 255;
|
||||
var int_counter = 0;
|
||||
|
||||
|
||||
var fadeDuration = 3 / starting_Count * CountDuration;
|
||||
|
||||
while (current_Count > 0)
|
||||
{
|
||||
current_Count -= Time.deltaTime / CountDuration * starting_Count;
|
||||
|
||||
if (current_Count <= 3)
|
||||
//Debug.Log("Fading Counter ... " + current_Count.ToString("f2"));
|
||||
alpha = Mathf.Clamp(alpha - Time.deltaTime / fadeDuration * 255, 0, 255);
|
||||
|
||||
int_counter = (int)current_Count;
|
||||
m_textMeshPro.text = int_counter.ToString();
|
||||
//m_textMeshPro.SetText("{0}", (int)current_Count);
|
||||
|
||||
m_textMeshPro.color = new Color32(start_color.r, start_color.g, start_color.b, (byte)alpha);
|
||||
|
||||
// Move the floating text upward each update
|
||||
m_floatingText_Transform.position += new Vector3(0, starting_Count * Time.deltaTime, 0);
|
||||
|
||||
// Align floating text perpendicular to Camera.
|
||||
if (!lastPOS.Compare(m_cameraTransform.position, 1000) ||
|
||||
!lastRotation.Compare(m_cameraTransform.rotation, 1000))
|
||||
{
|
||||
lastPOS = m_cameraTransform.position;
|
||||
lastRotation = m_cameraTransform.rotation;
|
||||
m_floatingText_Transform.rotation = lastRotation;
|
||||
var dir = m_transform.position - lastPOS;
|
||||
m_transform.forward = new Vector3(dir.x, 0, dir.z);
|
||||
}
|
||||
|
||||
yield return k_WaitForEndOfFrame;
|
||||
}
|
||||
|
||||
//Debug.Log("Done Counting down.");
|
||||
|
||||
yield return k_WaitForSecondsRandom[Random.Range(0, 19)];
|
||||
|
||||
m_floatingText_Transform.position = start_pos;
|
||||
|
||||
StartCoroutine(DisplayTextMeshProFloatingText());
|
||||
}
|
||||
|
||||
|
||||
public IEnumerator DisplayTextMeshFloatingText()
|
||||
{
|
||||
var CountDuration = 2.0f; // How long is the countdown alive.
|
||||
var starting_Count = Random.Range(5f, 20f); // At what number is the counter starting at.
|
||||
var current_Count = starting_Count;
|
||||
|
||||
var start_pos = m_floatingText_Transform.position;
|
||||
Color32 start_color = m_textMesh.color;
|
||||
float alpha = 255;
|
||||
var int_counter = 0;
|
||||
|
||||
var fadeDuration = 3 / starting_Count * CountDuration;
|
||||
|
||||
while (current_Count > 0)
|
||||
{
|
||||
current_Count -= Time.deltaTime / CountDuration * starting_Count;
|
||||
|
||||
if (current_Count <= 3)
|
||||
//Debug.Log("Fading Counter ... " + current_Count.ToString("f2"));
|
||||
alpha = Mathf.Clamp(alpha - Time.deltaTime / fadeDuration * 255, 0, 255);
|
||||
|
||||
int_counter = (int)current_Count;
|
||||
m_textMesh.text = int_counter.ToString();
|
||||
//Debug.Log("Current Count:" + current_Count.ToString("f2"));
|
||||
|
||||
m_textMesh.color = new Color32(start_color.r, start_color.g, start_color.b, (byte)alpha);
|
||||
|
||||
// Move the floating text upward each update
|
||||
m_floatingText_Transform.position += new Vector3(0, starting_Count * Time.deltaTime, 0);
|
||||
|
||||
// Align floating text perpendicular to Camera.
|
||||
if (!lastPOS.Compare(m_cameraTransform.position, 1000) ||
|
||||
!lastRotation.Compare(m_cameraTransform.rotation, 1000))
|
||||
{
|
||||
lastPOS = m_cameraTransform.position;
|
||||
lastRotation = m_cameraTransform.rotation;
|
||||
m_floatingText_Transform.rotation = lastRotation;
|
||||
var dir = m_transform.position - lastPOS;
|
||||
m_transform.forward = new Vector3(dir.x, 0, dir.z);
|
||||
}
|
||||
|
||||
yield return k_WaitForEndOfFrame;
|
||||
}
|
||||
|
||||
//Debug.Log("Done Counting down.");
|
||||
|
||||
yield return k_WaitForSecondsRandom[Random.Range(0, 20)];
|
||||
|
||||
m_floatingText_Transform.position = start_pos;
|
||||
|
||||
StartCoroutine(DisplayTextMeshFloatingText());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4d4c76e63944cba8c7d00f56334b98c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- TheFont: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,68 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class TextMeshSpawner : MonoBehaviour
|
||||
{
|
||||
public int SpawnType;
|
||||
public int NumberOfNPC = 12;
|
||||
|
||||
public Font TheFont;
|
||||
|
||||
private TextMeshProFloatingText floatingText_Script;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
for (var i = 0; i < NumberOfNPC; i++)
|
||||
if (SpawnType == 0)
|
||||
{
|
||||
// TextMesh Pro Implementation
|
||||
//go.transform.localScale = new Vector3(2, 2, 2);
|
||||
var go = new GameObject(); //"NPC " + i);
|
||||
go.transform.position = new Vector3(Random.Range(-95f, 95f), 0.5f, Random.Range(-95f, 95f));
|
||||
|
||||
//go.transform.position = new Vector3(0, 1.01f, 0);
|
||||
//go.renderer.castShadows = false;
|
||||
//go.renderer.receiveShadows = false;
|
||||
//go.transform.rotation = Quaternion.Euler(0, Random.Range(0, 360), 0);
|
||||
var textMeshPro = go.AddComponent<TextMeshPro>();
|
||||
//textMeshPro.FontAsset = Resources.Load("Fonts & Materials/LiberationSans SDF", typeof(TextMeshProFont)) as TextMeshProFont;
|
||||
//textMeshPro.anchor = AnchorPositions.Bottom;
|
||||
textMeshPro.fontSize = 96;
|
||||
|
||||
textMeshPro.text = "!";
|
||||
textMeshPro.color = new Color32(255, 255, 0, 255);
|
||||
|
||||
|
||||
//textMeshPro.Text = "!";
|
||||
// Spawn Floating Text
|
||||
floatingText_Script = go.AddComponent<TextMeshProFloatingText>();
|
||||
floatingText_Script.SpawnType = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TextMesh Implementation
|
||||
var go = new GameObject(); //"NPC " + i);
|
||||
go.transform.position = new Vector3(Random.Range(-95f, 95f), 0.5f, Random.Range(-95f, 95f));
|
||||
|
||||
//go.transform.position = new Vector3(0, 1.01f, 0);
|
||||
var textMesh = go.AddComponent<TextMesh>();
|
||||
textMesh.GetComponent<Renderer>().sharedMaterial = TheFont.material;
|
||||
textMesh.font = TheFont;
|
||||
textMesh.anchor = TextAnchor.LowerCenter;
|
||||
textMesh.fontSize = 96;
|
||||
|
||||
textMesh.color = new Color32(255, 255, 0, 255);
|
||||
textMesh.text = "!";
|
||||
|
||||
// Spawn Floating Text
|
||||
floatingText_Script = go.AddComponent<TextMeshProFloatingText>();
|
||||
floatingText_Script.SpawnType = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76c11bbcfddf44e0ba17d6c2751c8d84
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- TheFont: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,81 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class VertexColorCycler : MonoBehaviour
|
||||
{
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextComponent = GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(AnimateVertexColors());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to animate vertex colors of a TMP Text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerator AnimateVertexColors()
|
||||
{
|
||||
// Force the text object to update right away so we can have geometry to modify right from the start.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
var textInfo = m_TextComponent.textInfo;
|
||||
var currentCharacter = 0;
|
||||
|
||||
Color32[] newVertexColors;
|
||||
Color32 c0 = m_TextComponent.color;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var characterCount = textInfo.characterCount;
|
||||
|
||||
// If No Characters then just yield and wait for some text to be added
|
||||
if (characterCount == 0)
|
||||
{
|
||||
yield return new WaitForSeconds(0.25f);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the index of the material used by the current character.
|
||||
var materialIndex = textInfo.characterInfo[currentCharacter].materialReferenceIndex;
|
||||
|
||||
// Get the vertex colors of the mesh used by this text element (character or sprite).
|
||||
newVertexColors = textInfo.meshInfo[materialIndex].colors32;
|
||||
|
||||
// Get the index of the first vertex used by this text element.
|
||||
var vertexIndex = textInfo.characterInfo[currentCharacter].vertexIndex;
|
||||
|
||||
// Only change the vertex color if the text element is visible.
|
||||
if (textInfo.characterInfo[currentCharacter].isVisible)
|
||||
{
|
||||
c0 = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255),
|
||||
255);
|
||||
|
||||
newVertexColors[vertexIndex + 0] = c0;
|
||||
newVertexColors[vertexIndex + 1] = c0;
|
||||
newVertexColors[vertexIndex + 2] = c0;
|
||||
newVertexColors[vertexIndex + 3] = c0;
|
||||
|
||||
// New function which pushes (all) updated vertex data to the appropriate meshes when using either the Mesh Renderer or CanvasRenderer.
|
||||
m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
|
||||
|
||||
// This last process could be done to only update the vertex data that has changed as opposed to all of the vertex data but it would require extra steps and knowing what type of renderer is used.
|
||||
// These extra steps would be a performance optimization but it is unlikely that such optimization will be necessary.
|
||||
}
|
||||
|
||||
currentCharacter = (currentCharacter + 1) % characterCount;
|
||||
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91b8ba3d52e041fab2d0e0f169855539
|
||||
timeCreated: 1457047157
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,176 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class VertexJitter : MonoBehaviour
|
||||
{
|
||||
public float AngleMultiplier = 1.0f;
|
||||
public float SpeedMultiplier = 1.0f;
|
||||
public float CurveScale = 1.0f;
|
||||
private bool hasTextChanged;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextComponent = GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(AnimateVertexColors());
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Subscribe to event fired when text object has been regenerated.
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
private void ON_TEXT_CHANGED(Object obj)
|
||||
{
|
||||
if (obj == m_TextComponent)
|
||||
hasTextChanged = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to animate vertex colors of a TMP Text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerator AnimateVertexColors()
|
||||
{
|
||||
// We force an update of the text object since it would only be updated at the end of the frame. Ie. before this code is executed on the first frame.
|
||||
// Alternatively, we could yield and wait until the end of the frame when the text object will be generated.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
var textInfo = m_TextComponent.textInfo;
|
||||
|
||||
Matrix4x4 matrix;
|
||||
|
||||
var loopCount = 0;
|
||||
hasTextChanged = true;
|
||||
|
||||
// Create an Array which contains pre-computed Angle Ranges and Speeds for a bunch of characters.
|
||||
var vertexAnim = new VertexAnim[1024];
|
||||
for (var i = 0; i < 1024; i++)
|
||||
{
|
||||
vertexAnim[i].angleRange = Random.Range(10f, 25f);
|
||||
vertexAnim[i].speed = Random.Range(1f, 3f);
|
||||
}
|
||||
|
||||
// Cache the vertex data of the text object as the Jitter FX is applied to the original position of the characters.
|
||||
var cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Get new copy of vertex data if the text has changed.
|
||||
if (hasTextChanged)
|
||||
{
|
||||
// Update the copy of the vertex data for the text object.
|
||||
cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
|
||||
|
||||
hasTextChanged = false;
|
||||
}
|
||||
|
||||
var characterCount = textInfo.characterCount;
|
||||
|
||||
// If No Characters then just yield and wait for some text to be added
|
||||
if (characterCount == 0)
|
||||
{
|
||||
yield return new WaitForSeconds(0.25f);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i < characterCount; i++)
|
||||
{
|
||||
var charInfo = textInfo.characterInfo[i];
|
||||
|
||||
// Skip characters that are not visible and thus have no geometry to manipulate.
|
||||
if (!charInfo.isVisible)
|
||||
continue;
|
||||
|
||||
// Retrieve the pre-computed animation data for the given character.
|
||||
var vertAnim = vertexAnim[i];
|
||||
|
||||
// Get the index of the material used by the current character.
|
||||
var materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
|
||||
|
||||
// Get the index of the first vertex used by this text element.
|
||||
var vertexIndex = textInfo.characterInfo[i].vertexIndex;
|
||||
|
||||
// Get the cached vertices of the mesh used by this text element (character or sprite).
|
||||
var sourceVertices = cachedMeshInfo[materialIndex].vertices;
|
||||
|
||||
// Determine the center point of each character at the baseline.
|
||||
//Vector2 charMidBasline = new Vector2((sourceVertices[vertexIndex + 0].x + sourceVertices[vertexIndex + 2].x) / 2, charInfo.baseLine);
|
||||
// Determine the center point of each character.
|
||||
Vector2 charMidBasline = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;
|
||||
|
||||
// Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
|
||||
// This is needed so the matrix TRS is applied at the origin for each character.
|
||||
Vector3 offset = charMidBasline;
|
||||
|
||||
var destinationVertices = textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset;
|
||||
destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset;
|
||||
destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset;
|
||||
destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] - offset;
|
||||
|
||||
vertAnim.angle = Mathf.SmoothStep(-vertAnim.angleRange, vertAnim.angleRange,
|
||||
Mathf.PingPong(loopCount / 25f * vertAnim.speed, 1f));
|
||||
var jitterOffset = new Vector3(Random.Range(-.25f, .25f), Random.Range(-.25f, .25f), 0);
|
||||
|
||||
matrix = Matrix4x4.TRS(jitterOffset * CurveScale,
|
||||
Quaternion.Euler(0, 0, Random.Range(-5f, 5f) * AngleMultiplier), Vector3.one);
|
||||
|
||||
destinationVertices[vertexIndex + 0] =
|
||||
matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 0]);
|
||||
destinationVertices[vertexIndex + 1] =
|
||||
matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 1]);
|
||||
destinationVertices[vertexIndex + 2] =
|
||||
matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 2]);
|
||||
destinationVertices[vertexIndex + 3] =
|
||||
matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 3]);
|
||||
|
||||
destinationVertices[vertexIndex + 0] += offset;
|
||||
destinationVertices[vertexIndex + 1] += offset;
|
||||
destinationVertices[vertexIndex + 2] += offset;
|
||||
destinationVertices[vertexIndex + 3] += offset;
|
||||
|
||||
vertexAnim[i] = vertAnim;
|
||||
}
|
||||
|
||||
// Push changes into meshes
|
||||
for (var i = 0; i < textInfo.meshInfo.Length; i++)
|
||||
{
|
||||
textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
|
||||
m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
|
||||
}
|
||||
|
||||
loopCount += 1;
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Structure to hold pre-computed animation data.
|
||||
/// </summary>
|
||||
private struct VertexAnim
|
||||
{
|
||||
public float angleRange;
|
||||
public float angle;
|
||||
public float speed;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ed57967c52645d390a89dcf8f61ba73
|
||||
timeCreated: 1461286718
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,161 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class VertexShakeA : MonoBehaviour
|
||||
{
|
||||
public float AngleMultiplier = 1.0f;
|
||||
public float SpeedMultiplier = 1.0f;
|
||||
public float ScaleMultiplier = 1.0f;
|
||||
public float RotationMultiplier = 1.0f;
|
||||
private bool hasTextChanged;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextComponent = GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(AnimateVertexColors());
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Subscribe to event fired when text object has been regenerated.
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
private void ON_TEXT_CHANGED(Object obj)
|
||||
{
|
||||
if (obj = m_TextComponent)
|
||||
hasTextChanged = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to animate vertex colors of a TMP Text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerator AnimateVertexColors()
|
||||
{
|
||||
// We force an update of the text object since it would only be updated at the end of the frame. Ie. before this code is executed on the first frame.
|
||||
// Alternatively, we could yield and wait until the end of the frame when the text object will be generated.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
var textInfo = m_TextComponent.textInfo;
|
||||
|
||||
Matrix4x4 matrix;
|
||||
var copyOfVertices = new Vector3[0][];
|
||||
|
||||
hasTextChanged = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Allocate new vertices
|
||||
if (hasTextChanged)
|
||||
{
|
||||
if (copyOfVertices.Length < textInfo.meshInfo.Length)
|
||||
copyOfVertices = new Vector3[textInfo.meshInfo.Length][];
|
||||
|
||||
for (var i = 0; i < textInfo.meshInfo.Length; i++)
|
||||
{
|
||||
var length = textInfo.meshInfo[i].vertices.Length;
|
||||
copyOfVertices[i] = new Vector3[length];
|
||||
}
|
||||
|
||||
hasTextChanged = false;
|
||||
}
|
||||
|
||||
var characterCount = textInfo.characterCount;
|
||||
|
||||
// If No Characters then just yield and wait for some text to be added
|
||||
if (characterCount == 0)
|
||||
{
|
||||
yield return new WaitForSeconds(0.25f);
|
||||
continue;
|
||||
}
|
||||
|
||||
var lineCount = textInfo.lineCount;
|
||||
|
||||
// Iterate through each line of the text.
|
||||
for (var i = 0; i < lineCount; i++)
|
||||
{
|
||||
var first = textInfo.lineInfo[i].firstCharacterIndex;
|
||||
var last = textInfo.lineInfo[i].lastCharacterIndex;
|
||||
|
||||
// Determine the center of each line
|
||||
var centerOfLine =
|
||||
(textInfo.characterInfo[first].bottomLeft + textInfo.characterInfo[last].topRight) / 2;
|
||||
var rotation = Quaternion.Euler(0, 0, Random.Range(-0.25f, 0.25f) * RotationMultiplier);
|
||||
|
||||
// Iterate through each character of the line.
|
||||
for (var j = first; j <= last; j++)
|
||||
{
|
||||
// Skip characters that are not visible and thus have no geometry to manipulate.
|
||||
if (!textInfo.characterInfo[j].isVisible)
|
||||
continue;
|
||||
|
||||
// Get the index of the material used by the current character.
|
||||
var materialIndex = textInfo.characterInfo[j].materialReferenceIndex;
|
||||
|
||||
// Get the index of the first vertex used by this text element.
|
||||
var vertexIndex = textInfo.characterInfo[j].vertexIndex;
|
||||
|
||||
// Get the vertices of the mesh used by this text element (character or sprite).
|
||||
var sourceVertices = textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
// Need to translate all 4 vertices of each quad to aligned with center of character.
|
||||
// This is needed so the matrix TRS is applied at the origin for each character.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] = sourceVertices[vertexIndex + 0] - centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] = sourceVertices[vertexIndex + 1] - centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] = sourceVertices[vertexIndex + 2] - centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] = sourceVertices[vertexIndex + 3] - centerOfLine;
|
||||
|
||||
// Determine the random scale change for each character.
|
||||
var randomScale = Random.Range(0.995f - 0.001f * ScaleMultiplier,
|
||||
1.005f + 0.001f * ScaleMultiplier);
|
||||
|
||||
// Setup the matrix rotation.
|
||||
matrix = Matrix4x4.TRS(Vector3.one, rotation, Vector3.one * randomScale);
|
||||
|
||||
// Apply the matrix TRS to the individual characters relative to the center of the current line.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 0]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 1]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 2]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 3]);
|
||||
|
||||
// Revert the translation change.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] += centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] += centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] += centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] += centerOfLine;
|
||||
}
|
||||
}
|
||||
|
||||
// Push changes into meshes
|
||||
for (var i = 0; i < textInfo.meshInfo.Length; i++)
|
||||
{
|
||||
textInfo.meshInfo[i].mesh.vertices = copyOfVertices[i];
|
||||
m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7cfa58e417a46ea8889989684c2522e
|
||||
timeCreated: 1462089320
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,188 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class VertexShakeB : MonoBehaviour
|
||||
{
|
||||
public float AngleMultiplier = 1.0f;
|
||||
public float SpeedMultiplier = 1.0f;
|
||||
public float CurveScale = 1.0f;
|
||||
private bool hasTextChanged;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextComponent = GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(AnimateVertexColors());
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Subscribe to event fired when text object has been regenerated.
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
private void ON_TEXT_CHANGED(Object obj)
|
||||
{
|
||||
if (obj = m_TextComponent)
|
||||
hasTextChanged = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to animate vertex colors of a TMP Text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerator AnimateVertexColors()
|
||||
{
|
||||
// We force an update of the text object since it would only be updated at the end of the frame. Ie. before this code is executed on the first frame.
|
||||
// Alternatively, we could yield and wait until the end of the frame when the text object will be generated.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
var textInfo = m_TextComponent.textInfo;
|
||||
|
||||
Matrix4x4 matrix;
|
||||
var copyOfVertices = new Vector3[0][];
|
||||
|
||||
hasTextChanged = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Allocate new vertices
|
||||
if (hasTextChanged)
|
||||
{
|
||||
if (copyOfVertices.Length < textInfo.meshInfo.Length)
|
||||
copyOfVertices = new Vector3[textInfo.meshInfo.Length][];
|
||||
|
||||
for (var i = 0; i < textInfo.meshInfo.Length; i++)
|
||||
{
|
||||
var length = textInfo.meshInfo[i].vertices.Length;
|
||||
copyOfVertices[i] = new Vector3[length];
|
||||
}
|
||||
|
||||
hasTextChanged = false;
|
||||
}
|
||||
|
||||
var characterCount = textInfo.characterCount;
|
||||
|
||||
// If No Characters then just yield and wait for some text to be added
|
||||
if (characterCount == 0)
|
||||
{
|
||||
yield return new WaitForSeconds(0.25f);
|
||||
continue;
|
||||
}
|
||||
|
||||
var lineCount = textInfo.lineCount;
|
||||
|
||||
// Iterate through each line of the text.
|
||||
for (var i = 0; i < lineCount; i++)
|
||||
{
|
||||
var first = textInfo.lineInfo[i].firstCharacterIndex;
|
||||
var last = textInfo.lineInfo[i].lastCharacterIndex;
|
||||
|
||||
// Determine the center of each line
|
||||
var centerOfLine =
|
||||
(textInfo.characterInfo[first].bottomLeft + textInfo.characterInfo[last].topRight) / 2;
|
||||
var rotation = Quaternion.Euler(0, 0, Random.Range(-0.25f, 0.25f));
|
||||
|
||||
// Iterate through each character of the line.
|
||||
for (var j = first; j <= last; j++)
|
||||
{
|
||||
// Skip characters that are not visible and thus have no geometry to manipulate.
|
||||
if (!textInfo.characterInfo[j].isVisible)
|
||||
continue;
|
||||
|
||||
// Get the index of the material used by the current character.
|
||||
var materialIndex = textInfo.characterInfo[j].materialReferenceIndex;
|
||||
|
||||
// Get the index of the first vertex used by this text element.
|
||||
var vertexIndex = textInfo.characterInfo[j].vertexIndex;
|
||||
|
||||
// Get the vertices of the mesh used by this text element (character or sprite).
|
||||
var sourceVertices = textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
// Determine the center point of each character at the baseline.
|
||||
var charCenter = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;
|
||||
|
||||
// Need to translate all 4 vertices of each quad to aligned with center of character.
|
||||
// This is needed so the matrix TRS is applied at the origin for each character.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] = sourceVertices[vertexIndex + 0] - charCenter;
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] = sourceVertices[vertexIndex + 1] - charCenter;
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] = sourceVertices[vertexIndex + 2] - charCenter;
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] = sourceVertices[vertexIndex + 3] - charCenter;
|
||||
|
||||
// Determine the random scale change for each character.
|
||||
var randomScale = Random.Range(0.95f, 1.05f);
|
||||
|
||||
// Setup the matrix for the scale change.
|
||||
matrix = Matrix4x4.TRS(Vector3.one, Quaternion.identity, Vector3.one * randomScale);
|
||||
|
||||
// Apply the scale change relative to the center of each character.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 0]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 1]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 2]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 3]);
|
||||
|
||||
// Revert the translation change.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] += charCenter;
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] += charCenter;
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] += charCenter;
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] += charCenter;
|
||||
|
||||
// Need to translate all 4 vertices of each quad to aligned with the center of the line.
|
||||
// This is needed so the matrix TRS is applied from the center of the line.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] -= centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] -= centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] -= centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] -= centerOfLine;
|
||||
|
||||
// Setup the matrix rotation.
|
||||
matrix = Matrix4x4.TRS(Vector3.one, rotation, Vector3.one);
|
||||
|
||||
// Apply the matrix TRS to the individual characters relative to the center of the current line.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 0]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 1]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 2]);
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] =
|
||||
matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 3]);
|
||||
|
||||
// Revert the translation change.
|
||||
copyOfVertices[materialIndex][vertexIndex + 0] += centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 1] += centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 2] += centerOfLine;
|
||||
copyOfVertices[materialIndex][vertexIndex + 3] += centerOfLine;
|
||||
}
|
||||
}
|
||||
|
||||
// Push changes into meshes
|
||||
for (var i = 0; i < textInfo.meshInfo.Length; i++)
|
||||
{
|
||||
textInfo.meshInfo[i].mesh.vertices = copyOfVertices[i];
|
||||
m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4e0d9ccee5f4950be8979268c9014e0
|
||||
timeCreated: 1462093319
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,191 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class VertexZoom : MonoBehaviour
|
||||
{
|
||||
public float AngleMultiplier = 1.0f;
|
||||
public float SpeedMultiplier = 1.0f;
|
||||
public float CurveScale = 1.0f;
|
||||
private bool hasTextChanged;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextComponent = GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(AnimateVertexColors());
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// Subscribe to event fired when text object has been regenerated.
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// UnSubscribe to event fired when text object has been regenerated.
|
||||
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
private void ON_TEXT_CHANGED(Object obj)
|
||||
{
|
||||
if (obj == m_TextComponent)
|
||||
hasTextChanged = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to animate vertex colors of a TMP Text object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IEnumerator AnimateVertexColors()
|
||||
{
|
||||
// We force an update of the text object since it would only be updated at the end of the frame. Ie. before this code is executed on the first frame.
|
||||
// Alternatively, we could yield and wait until the end of the frame when the text object will be generated.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
var textInfo = m_TextComponent.textInfo;
|
||||
|
||||
Matrix4x4 matrix;
|
||||
var cachedMeshInfoVertexData = textInfo.CopyMeshInfoVertexData();
|
||||
|
||||
// Allocations for sorting of the modified scales
|
||||
var modifiedCharScale = new List<float>();
|
||||
var scaleSortingOrder = new List<int>();
|
||||
|
||||
hasTextChanged = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Allocate new vertices
|
||||
if (hasTextChanged)
|
||||
{
|
||||
// Get updated vertex data
|
||||
cachedMeshInfoVertexData = textInfo.CopyMeshInfoVertexData();
|
||||
|
||||
hasTextChanged = false;
|
||||
}
|
||||
|
||||
var characterCount = textInfo.characterCount;
|
||||
|
||||
// If No Characters then just yield and wait for some text to be added
|
||||
if (characterCount == 0)
|
||||
{
|
||||
yield return new WaitForSeconds(0.25f);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Clear list of character scales
|
||||
modifiedCharScale.Clear();
|
||||
scaleSortingOrder.Clear();
|
||||
|
||||
for (var i = 0; i < characterCount; i++)
|
||||
{
|
||||
var charInfo = textInfo.characterInfo[i];
|
||||
|
||||
// Skip characters that are not visible and thus have no geometry to manipulate.
|
||||
if (!charInfo.isVisible)
|
||||
continue;
|
||||
|
||||
// Get the index of the material used by the current character.
|
||||
var materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
|
||||
|
||||
// Get the index of the first vertex used by this text element.
|
||||
var vertexIndex = textInfo.characterInfo[i].vertexIndex;
|
||||
|
||||
// Get the cached vertices of the mesh used by this text element (character or sprite).
|
||||
var sourceVertices = cachedMeshInfoVertexData[materialIndex].vertices;
|
||||
|
||||
// Determine the center point of each character at the baseline.
|
||||
//Vector2 charMidBasline = new Vector2((sourceVertices[vertexIndex + 0].x + sourceVertices[vertexIndex + 2].x) / 2, charInfo.baseLine);
|
||||
// Determine the center point of each character.
|
||||
Vector2 charMidBasline = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;
|
||||
|
||||
// Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
|
||||
// This is needed so the matrix TRS is applied at the origin for each character.
|
||||
Vector3 offset = charMidBasline;
|
||||
|
||||
var destinationVertices = textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset;
|
||||
destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset;
|
||||
destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset;
|
||||
destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] - offset;
|
||||
|
||||
//Vector3 jitterOffset = new Vector3(Random.Range(-.25f, .25f), Random.Range(-.25f, .25f), 0);
|
||||
|
||||
// Determine the random scale change for each character.
|
||||
var randomScale = Random.Range(1f, 1.5f);
|
||||
|
||||
// Add modified scale and index
|
||||
modifiedCharScale.Add(randomScale);
|
||||
scaleSortingOrder.Add(modifiedCharScale.Count - 1);
|
||||
|
||||
// Setup the matrix for the scale change.
|
||||
//matrix = Matrix4x4.TRS(jitterOffset, Quaternion.Euler(0, 0, Random.Range(-5f, 5f)), Vector3.one * randomScale);
|
||||
matrix = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, Vector3.one * randomScale);
|
||||
|
||||
destinationVertices[vertexIndex + 0] =
|
||||
matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 0]);
|
||||
destinationVertices[vertexIndex + 1] =
|
||||
matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 1]);
|
||||
destinationVertices[vertexIndex + 2] =
|
||||
matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 2]);
|
||||
destinationVertices[vertexIndex + 3] =
|
||||
matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 3]);
|
||||
|
||||
destinationVertices[vertexIndex + 0] += offset;
|
||||
destinationVertices[vertexIndex + 1] += offset;
|
||||
destinationVertices[vertexIndex + 2] += offset;
|
||||
destinationVertices[vertexIndex + 3] += offset;
|
||||
|
||||
// Restore Source UVS which have been modified by the sorting
|
||||
var sourceUVs0 = cachedMeshInfoVertexData[materialIndex].uvs0;
|
||||
var destinationUVs0 = textInfo.meshInfo[materialIndex].uvs0;
|
||||
|
||||
destinationUVs0[vertexIndex + 0] = sourceUVs0[vertexIndex + 0];
|
||||
destinationUVs0[vertexIndex + 1] = sourceUVs0[vertexIndex + 1];
|
||||
destinationUVs0[vertexIndex + 2] = sourceUVs0[vertexIndex + 2];
|
||||
destinationUVs0[vertexIndex + 3] = sourceUVs0[vertexIndex + 3];
|
||||
|
||||
// Restore Source Vertex Colors
|
||||
var sourceColors32 = cachedMeshInfoVertexData[materialIndex].colors32;
|
||||
var destinationColors32 = textInfo.meshInfo[materialIndex].colors32;
|
||||
|
||||
destinationColors32[vertexIndex + 0] = sourceColors32[vertexIndex + 0];
|
||||
destinationColors32[vertexIndex + 1] = sourceColors32[vertexIndex + 1];
|
||||
destinationColors32[vertexIndex + 2] = sourceColors32[vertexIndex + 2];
|
||||
destinationColors32[vertexIndex + 3] = sourceColors32[vertexIndex + 3];
|
||||
}
|
||||
|
||||
// Push changes into meshes
|
||||
for (var i = 0; i < textInfo.meshInfo.Length; i++)
|
||||
{
|
||||
//// Sort Quads based modified scale
|
||||
scaleSortingOrder.Sort((a, b) => modifiedCharScale[a].CompareTo(modifiedCharScale[b]));
|
||||
|
||||
textInfo.meshInfo[i].SortGeometry(scaleSortingOrder);
|
||||
|
||||
// Updated modified vertex attributes
|
||||
textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
|
||||
textInfo.meshInfo[i].mesh.uv = textInfo.meshInfo[i].uvs0;
|
||||
textInfo.meshInfo[i].mesh.colors32 = textInfo.meshInfo[i].colors32;
|
||||
|
||||
m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52ec835d14bd486f900952b77698b7eb
|
||||
timeCreated: 1466280202
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,148 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TMPro.Examples
|
||||
{
|
||||
public class WarpTextExample : MonoBehaviour
|
||||
{
|
||||
public AnimationCurve VertexCurve = new(new Keyframe(0, 0), new Keyframe(0.25f, 2.0f), new Keyframe(0.5f, 0),
|
||||
new Keyframe(0.75f, 2.0f), new Keyframe(1, 0f));
|
||||
|
||||
public float AngleMultiplier = 1.0f;
|
||||
public float SpeedMultiplier = 1.0f;
|
||||
public float CurveScale = 1.0f;
|
||||
|
||||
private TMP_Text m_TextComponent;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_TextComponent = gameObject.GetComponent<TMP_Text>();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartCoroutine(WarpText());
|
||||
}
|
||||
|
||||
|
||||
private AnimationCurve CopyAnimationCurve(AnimationCurve curve)
|
||||
{
|
||||
var newCurve = new AnimationCurve();
|
||||
|
||||
newCurve.keys = curve.keys;
|
||||
|
||||
return newCurve;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method to curve text along a Unity animation curve.
|
||||
/// </summary>
|
||||
/// <param name="textComponent"></param>
|
||||
/// <returns></returns>
|
||||
private IEnumerator WarpText()
|
||||
{
|
||||
VertexCurve.preWrapMode = WrapMode.Clamp;
|
||||
VertexCurve.postWrapMode = WrapMode.Clamp;
|
||||
|
||||
//Mesh mesh = m_TextComponent.textInfo.meshInfo[0].mesh;
|
||||
|
||||
Vector3[] vertices;
|
||||
Matrix4x4 matrix;
|
||||
|
||||
m_TextComponent.havePropertiesChanged = true; // Need to force the TextMeshPro Object to be updated.
|
||||
CurveScale *= 10;
|
||||
var old_CurveScale = CurveScale;
|
||||
var old_curve = CopyAnimationCurve(VertexCurve);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!m_TextComponent.havePropertiesChanged && old_CurveScale == CurveScale &&
|
||||
old_curve.keys[1].value == VertexCurve.keys[1].value)
|
||||
{
|
||||
yield return null;
|
||||
continue;
|
||||
}
|
||||
|
||||
old_CurveScale = CurveScale;
|
||||
old_curve = CopyAnimationCurve(VertexCurve);
|
||||
|
||||
m_TextComponent
|
||||
.ForceMeshUpdate(); // Generate the mesh and populate the textInfo with data we can use and manipulate.
|
||||
|
||||
var textInfo = m_TextComponent.textInfo;
|
||||
var characterCount = textInfo.characterCount;
|
||||
|
||||
|
||||
if (characterCount == 0) continue;
|
||||
|
||||
//vertices = textInfo.meshInfo[0].vertices;
|
||||
//int lastVertexIndex = textInfo.characterInfo[characterCount - 1].vertexIndex;
|
||||
|
||||
var boundsMinX = m_TextComponent.bounds.min.x; //textInfo.meshInfo[0].mesh.bounds.min.x;
|
||||
var boundsMaxX = m_TextComponent.bounds.max.x; //textInfo.meshInfo[0].mesh.bounds.max.x;
|
||||
|
||||
|
||||
for (var i = 0; i < characterCount; i++)
|
||||
{
|
||||
if (!textInfo.characterInfo[i].isVisible)
|
||||
continue;
|
||||
|
||||
var vertexIndex = textInfo.characterInfo[i].vertexIndex;
|
||||
|
||||
// Get the index of the mesh used by this character.
|
||||
var materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
|
||||
|
||||
vertices = textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
// Compute the baseline mid point for each character
|
||||
Vector3 offsetToMidBaseline =
|
||||
new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2,
|
||||
textInfo.characterInfo[i].baseLine);
|
||||
//float offsetY = VertexCurve.Evaluate((float)i / characterCount + loopCount / 50f); // Random.Range(-0.25f, 0.25f);
|
||||
|
||||
// Apply offset to adjust our pivot point.
|
||||
vertices[vertexIndex + 0] += -offsetToMidBaseline;
|
||||
vertices[vertexIndex + 1] += -offsetToMidBaseline;
|
||||
vertices[vertexIndex + 2] += -offsetToMidBaseline;
|
||||
vertices[vertexIndex + 3] += -offsetToMidBaseline;
|
||||
|
||||
// Compute the angle of rotation for each character based on the animation curve
|
||||
var x0 = (offsetToMidBaseline.x - boundsMinX) /
|
||||
(boundsMaxX - boundsMinX); // Character's position relative to the bounds of the mesh.
|
||||
var x1 = x0 + 0.0001f;
|
||||
var y0 = VertexCurve.Evaluate(x0) * CurveScale;
|
||||
var y1 = VertexCurve.Evaluate(x1) * CurveScale;
|
||||
|
||||
var horizontal = new Vector3(1, 0, 0);
|
||||
//Vector3 normal = new Vector3(-(y1 - y0), (x1 * (boundsMaxX - boundsMinX) + boundsMinX) - offsetToMidBaseline.x, 0);
|
||||
var tangent = new Vector3(x1 * (boundsMaxX - boundsMinX) + boundsMinX, y1) -
|
||||
new Vector3(offsetToMidBaseline.x, y0);
|
||||
|
||||
var dot = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * 57.2957795f;
|
||||
var cross = Vector3.Cross(horizontal, tangent);
|
||||
var angle = cross.z > 0 ? dot : 360 - dot;
|
||||
|
||||
matrix = Matrix4x4.TRS(new Vector3(0, y0, 0), Quaternion.Euler(0, 0, angle), Vector3.one);
|
||||
|
||||
vertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
|
||||
vertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
|
||||
vertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
|
||||
vertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);
|
||||
|
||||
vertices[vertexIndex + 0] += offsetToMidBaseline;
|
||||
vertices[vertexIndex + 1] += offsetToMidBaseline;
|
||||
vertices[vertexIndex + 2] += offsetToMidBaseline;
|
||||
vertices[vertexIndex + 3] += offsetToMidBaseline;
|
||||
}
|
||||
|
||||
|
||||
// Upload the mesh with the revised information
|
||||
m_TextComponent.UpdateVertexData();
|
||||
|
||||
yield return new WaitForSeconds(0.025f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 790744c462254b7ba8038e6ed28b3db2
|
||||
timeCreated: 1458801336
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user