update sample
This commit is contained in:
14
Assets/Scenes/SampleCurvedText/Scripts/Rotator.cs
Normal file
14
Assets/Scenes/SampleCurvedText/Scripts/Rotator.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace space.chikalin.textdecal
|
||||
{
|
||||
public class Rotator : MonoBehaviour
|
||||
{
|
||||
[Range(1f, 100f)] public float speed = 30f;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
transform.Rotate(Vector3.up, Time.deltaTime * speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scenes/SampleCurvedText/Scripts/Rotator.cs.meta
Normal file
2
Assets/Scenes/SampleCurvedText/Scripts/Rotator.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86d5f4391de14e74aa3dc0b7649c414c
|
||||
156
Assets/Scenes/SampleCurvedText/Scripts/TextMeshProSpline.cs
Normal file
156
Assets/Scenes/SampleCurvedText/Scripts/TextMeshProSpline.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Splines;
|
||||
|
||||
namespace space.chikalin.textdecal
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Should execute after <c>space.chikalin.textdecal.TextMeshProDecal</c> script
|
||||
/// </summary>
|
||||
[ExecuteAlways]
|
||||
[DisallowMultipleComponent]
|
||||
[DefaultExecutionOrder(-90)]
|
||||
[AddComponentMenu("Mesh/TextMeshPro - Spline")]
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
[Icon("Packages/com.unity.splines/Editor/Resources/Icons/SplineComponent.png")]
|
||||
#endif
|
||||
[RequireComponent(typeof(SplineContainer), typeof(TMP_Text))]
|
||||
public class TextMeshProSpline : MonoBehaviour
|
||||
{
|
||||
private TMP_Text _text;
|
||||
private SplineContainer _spline;
|
||||
|
||||
private Spline DefaultSpline(float3 start, float3 end)
|
||||
{
|
||||
var spline = new Spline
|
||||
{
|
||||
{ start, TangentMode.Linear },
|
||||
{ end, TangentMode.Linear }
|
||||
};
|
||||
return spline;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_text = GetComponent<TMP_Text>();
|
||||
_spline = GetComponent<SplineContainer>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_text.OnPreRenderText += OnPreRenderText;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_text.OnPreRenderText -= OnPreRenderText;
|
||||
_text.ClearMesh();
|
||||
_text.mesh.RecalculateBounds();
|
||||
_text.ForceMeshUpdate();
|
||||
}
|
||||
|
||||
private void OnPreRenderText(TMP_TextInfo textInfo)
|
||||
{
|
||||
FitSpline(textInfo);
|
||||
}
|
||||
|
||||
private void FitSpline(TMP_TextInfo textInfo)
|
||||
{
|
||||
FixSpline();
|
||||
|
||||
var splineLength = _spline.CalculateLength();
|
||||
if (splineLength <= 0) return;
|
||||
|
||||
for (var i = 0; i < textInfo.characterCount; i++)
|
||||
{
|
||||
if (!textInfo.characterInfo[i].isVisible)
|
||||
continue;
|
||||
|
||||
var vertexIndex = textInfo.characterInfo[i].vertexIndex;
|
||||
var materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
|
||||
var vertices = textInfo.meshInfo[materialIndex].vertices;
|
||||
var bl = vertices[vertexIndex + 0];
|
||||
var tr = vertices[vertexIndex + 2];
|
||||
var charCenter = bl + (tr - bl) / 2;
|
||||
Evaluate(splineLength, charCenter.x, out var position, out var xAxis, out var yAxis);
|
||||
xAxis = transform.InverseTransformDirection(math.normalize(xAxis));
|
||||
yAxis = transform.InverseTransformDirection(math.normalize(yAxis));
|
||||
position = transform.InverseTransformPoint(position);
|
||||
var newCenter = position + yAxis * charCenter.y;
|
||||
for (var v = 0; v < 4; v++)
|
||||
{
|
||||
var d = vertices[vertexIndex + v] - charCenter;
|
||||
vertices[vertexIndex + v] = newCenter + xAxis * d.x + yAxis * d.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FixSpline()
|
||||
{
|
||||
var textRectTransform = _text.rectTransform;
|
||||
if (_spline.Spline.Count >= 2) return;
|
||||
var rect = textRectTransform.rect;
|
||||
var position = textRectTransform.position;
|
||||
var start = new float3(rect.xMin, rect.yMin, position.z);
|
||||
var end = new float3(rect.xMax, rect.yMax, position.z);
|
||||
_spline.Spline = DefaultSpline(start, end);
|
||||
}
|
||||
|
||||
private void Evaluate(float length, float xPos, out float3 position, out float3 xAxis, out float3 yAxis)
|
||||
{
|
||||
var s = (xPos / length) * transform.localScale.x + .5f; // centered
|
||||
_spline.Evaluate(math.clamp(s, 0.01f, .99f), out position, out xAxis, out yAxis);
|
||||
}
|
||||
|
||||
private Quaternion ReflectRotation(Quaternion source, Vector3 normal)
|
||||
{
|
||||
return Quaternion.LookRotation(Vector3.Reflect(source * Vector3.forward, normal),
|
||||
Vector3.Reflect(source * Vector3.up, normal));
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[ExecuteAlways]
|
||||
[ContextMenu("Mirror")]
|
||||
public void Mirror()
|
||||
{
|
||||
var rectTransform = _text.rectTransform;
|
||||
rectTransform.GetPositionAndRotation(out var position, out var rotation);
|
||||
var max = position + _text.transform.right * rectTransform.rect.width * rectTransform.localScale.x;
|
||||
max.x = -max.x;
|
||||
var angles = rotation.eulerAngles;
|
||||
rotation = Quaternion.Euler(angles.x, 180 - (angles.y - 180), -angles.z);
|
||||
rectTransform.SetPositionAndRotation(max, rotation);
|
||||
|
||||
var spline = _spline.Splines[0];
|
||||
var array = spline.Knots.ToArray();
|
||||
var lastX = array[^1].Position.x;
|
||||
var r = array.Length - 1;
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
var knot = array[i];
|
||||
knot.Position.x = -knot.Position.x + lastX;
|
||||
spline.SetKnot(r - i, knot);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
ForceUpdate();
|
||||
}
|
||||
#endif
|
||||
|
||||
[ExecuteAlways]
|
||||
public void ForceUpdate()
|
||||
{
|
||||
if (_text != null)
|
||||
{
|
||||
_text.ForceMeshUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05798bd8f0b876340941273f09bab577
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "space.chikalin.textdecal.SampleCurvedText",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||
"GUID:21d1eb854b91ade49bc69a263d12bee2",
|
||||
"GUID:d8b63aba1907145bea998dd612889d6b"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd71501f22a1b524ab1b3b104b75b75e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user