Created
October 20, 2017 01:23
-
-
Save iwashihead/83c881a6aff35ca5dbcbdb2af6a6e324 to your computer and use it in GitHub Desktop.
UnityEngine.UI.Textにアタッチして文字を個別に動かすアニメーションのサンプル。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//------------------------------------------------------- | |
// @file CommonTextAnimation.cs | |
// @brief IMeshModifierを利用したテキストアニメーション. | |
// | |
// @author haruki.tachihara | |
//------------------------------------------------------- | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.EventSystems; | |
//これは別UnityEngine名前空間を使ってはいるが自前のTweenライブラリ | |
using Method = UnityEngine.UI.TweenMain.Method; | |
namespace UnityEngine.UI | |
{ | |
[RequireComponent(typeof(Text))] | |
[DisallowMultipleComponent] | |
public class CommonTextAnimation : BaseMeshEffect | |
{ | |
// 1文字は6頂点. | |
const int CHAR_VERT_CNT = 6; | |
#region Animation Parameter | |
// OnEnableで自動開始するか. | |
public bool autoStartOnEnable = true; | |
// アニメーションにかける所用時間 [秒] | |
public float duration = 0.5f; | |
// X軸の動きの大きさ. | |
public float moveAmountX = 0f; | |
// Y軸の動きの大きさ. | |
public float moveAmountY = 0f; | |
// シェイクは有効か. | |
public bool enableShake = true; | |
// シェイク量. | |
public float shakeAmount = 1f; | |
#endregion | |
private bool isFinished; | |
private float time; | |
public void StartEffect() | |
{ | |
time = 0; | |
isFinished = false; | |
} | |
protected override void OnEnable() | |
{ | |
base.OnEnable(); | |
if (autoStartOnEnable) | |
{ | |
StartEffect(); | |
} | |
} | |
protected virtual void Update() | |
{ | |
if (isFinished) | |
return; | |
time += Time.deltaTime; | |
if (graphic != null) | |
{ | |
graphic.SetVerticesDirty(); | |
} | |
} | |
public override void ModifyMesh(VertexHelper vh) | |
{ | |
var vList = new List<UIVertex>(); | |
vh.GetUIVertexStream(vList); | |
Modify(ref vList); | |
vh.Clear(); | |
vh.AddUIVertexTriangleStream(vList); | |
} | |
void Modify(ref List<UIVertex> vList) | |
{ | |
if (isFinished || duration <= 0f || vList.Count < CHAR_VERT_CNT) | |
{ | |
return; | |
} | |
if (time >= duration && !enableShake) | |
{ | |
isFinished = true; | |
} | |
var vertexCount = vList.Count; | |
var charCount = vertexCount / CHAR_VERT_CNT; | |
var deltaTimeParChar = duration / charCount; | |
Vector3 shake = Vector3.zero; | |
if (enableShake) | |
{ | |
shake = Random.insideUnitCircle * shakeAmount; | |
} | |
for (int i = 0; i < vertexCount; i += CHAR_VERT_CNT) | |
{ | |
// 現在の文字のnormalizeTime[0-1]を計算. | |
var startTime = i / CHAR_VERT_CNT * deltaTimeParChar; | |
var elapsedTime = time - startTime; | |
var normalizeTime = Mathf.Clamp01(elapsedTime / deltaTimeParChar); | |
if (normalizeTime <= 0f) | |
{ | |
// 見えないように設定. | |
for (int vertexIndex = 0; vertexIndex < CHAR_VERT_CNT; vertexIndex++) | |
{ | |
var v = vList[i + vertexIndex]; | |
v.color = Color.clear; | |
vList[i + vertexIndex] = v; | |
} | |
} | |
else if (normalizeTime >= 1f) | |
{ | |
if (enableShake) | |
{ | |
for (int vertexIndex = 0; vertexIndex < CHAR_VERT_CNT; vertexIndex++) | |
{ | |
var v = vList[i + vertexIndex]; | |
v.position += shake; | |
vList[i + vertexIndex] = v; | |
} | |
} | |
} | |
else | |
{ | |
// アニメーションさせる. | |
var center = Vector2.Lerp(vList[i].position, vList[i + 3].position, 0.5f); | |
for (int vertexIndex = 0; vertexIndex < CHAR_VERT_CNT; vertexIndex++) | |
{ | |
var v = vList[i + vertexIndex]; | |
var sampled = Tweening.Sample(Method.EaseOut, normalizeTime); | |
// 移動量 | |
var moveX = moveAmountX * Tweening.Sample(Method.EaseIn, 1f - normalizeTime); | |
var moveY = moveAmountY * Mathf.Sin((1f - normalizeTime) * Mathf.PI);//上下にサインカーブ移動. | |
// スケール | |
var posX = Mathf.Lerp(center.x, v.position.x, sampled) + moveX; | |
var posY = Mathf.Lerp(center.y, v.position.y, sampled) + moveY; | |
v.position = new Vector2(posX + shake.x, posY + shake.y); | |
vList[i + vertexIndex] = v; | |
} | |
} | |
} | |
} | |
} | |
public static class Tweening | |
{ | |
public static float Sample(Method method, float normalizeTime) | |
{ | |
float val = Mathf.Clamp01(normalizeTime); | |
switch (method) | |
{ | |
case Method.Linear: | |
val = Easing.Linear(val); | |
break; | |
case Method.EaseIn: | |
val = Easing.Sinusoidal.In(val); | |
break; | |
case Method.EaseOut: | |
val = Easing.Sinusoidal.Out(val); | |
break; | |
case Method.EaseInOut: | |
val = Easing.Sinusoidal.InOut(val); | |
break; | |
case Method.BounceIn: | |
val = Easing.Bounce.In(val); | |
break; | |
case Method.BounceOut: | |
val = Easing.Bounce.Out(val); | |
break; | |
case Method.BounceInOut: | |
val = Easing.Bounce.InOut(val); | |
break; | |
} | |
return val; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment