Last active
May 31, 2016 16:51
-
-
Save anzfactory/74b9b902638951c0258d7283c7f34423 to your computer and use it in GitHub Desktop.
数字テキストを良い感じにアニメーションさせて表示するやつ http://anz-note.tumblr.com/post/145157295266
This file contains hidden or 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
/********************************* | |
* 数字テキストを良い感じにアニメーションして | |
* 表示するやーつ | |
*********************************/ | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using DG.Tweening; | |
public class Number : MonoBehaviour | |
{ | |
/// <summary> | |
/// 表示する値 | |
/// </summary> | |
[SerializeField] private int value; | |
/// <summary> | |
/// 文字色 | |
/// </summary> | |
[SerializeField] private Color textColor = Color.white; | |
/// <summary> | |
/// フォント | |
/// </summary> | |
[SerializeField] private Font textFont; | |
/// <summary> | |
/// 表示したときのアニメーションタイプ | |
/// </summary> | |
[SerializeField] private DisplayAnimation currentAnimation = DisplayAnimation.None; | |
/// <summary> | |
/// 開始時にアニメーションするかどうか | |
/// 開始時は表示するだけで、更新した時だけアニメーションしたい場合はfalse | |
/// </summary> | |
[SerializeField] private bool animateWhenStart = false; | |
public enum DisplayAnimation { | |
None, Wave, Scale, Rotate | |
} | |
private RectTransform rectTransform; | |
private List<NumberText> list; | |
private GameObject template; | |
private List<Vector2> sizeList; | |
private float startX = 0; | |
public int Value { | |
get { return this.value; } | |
set { | |
this.value = value; | |
UpdateValue(this.currentAnimation); | |
} | |
} | |
public DisplayAnimation CurrentAnimation { | |
get { return this.currentAnimation; } | |
set { this.currentAnimation = value; } | |
} | |
private void Awake() | |
{ | |
this.rectTransform = this.gameObject.GetComponent<RectTransform>(); | |
this.list = new List<NumberText>(); | |
this.sizeList = new List<Vector2>(); | |
} | |
private void Start() | |
{ | |
this.template = CreateTemplateText(); | |
PreLoadSize(); | |
UpdateValue(this.animateWhenStart ? this.currentAnimation : DisplayAnimation.None); | |
} | |
/// <summary> | |
/// 値を更新して表示(アニメーション指定があれば実行する) | |
/// </summary> | |
private void UpdateValue(DisplayAnimation animation) | |
{ | |
var str = this.value.ToString(); | |
this.startX = this.rectTransform.rect.width * -0.5f; | |
for (int i = 0; i < str.Length; i++) { | |
var s = str[i]; | |
NumberText text; | |
if (this.list.Count > i) { | |
// 既存Text再利用 | |
text = this.list[i]; | |
} else { | |
// Text作って表示して保持 | |
text = CreateText(); | |
this.list.Add(text); | |
} | |
text.text = s.ToString(); | |
AdjustRect(text.gameObject, int.Parse(s.ToString()), i); | |
switch (animation) { | |
case DisplayAnimation.Wave: | |
text.AnimateWave(0.1f * i); | |
break; | |
case DisplayAnimation.Scale: | |
text.AnimateScale(0.1f * i); | |
break; | |
case DisplayAnimation.Rotate: | |
text.AnimateRotate(0.2f * i); | |
break; | |
case DisplayAnimation.None: | |
default: | |
// なにもなし | |
break; | |
} | |
} | |
// 余分なやつを消す | |
for (int i = str.Length; i < this.list.Count; i++) { | |
this.list[i].gameObject.SetActive(false); | |
} | |
} | |
/// <summary> | |
/// 新たにText入れ物をつくる | |
/// </summary> | |
/// <returns>The text.</returns> | |
private NumberText CreateText() | |
{ | |
var gameObject = Instantiate(this.template) as GameObject; | |
gameObject.SetActive(true); | |
gameObject.transform.SetParent(this.gameObject.transform); | |
return gameObject.GetComponent<NumberText>(); | |
} | |
/// <summary> | |
/// テンプレートテキストをつくる | |
/// </summary> | |
/// <returns>The template text.</returns> | |
private GameObject CreateTemplateText() | |
{ | |
int fontSize = (int)(this.rectTransform.rect.height * 0.8); | |
var gameObject = new GameObject(); | |
gameObject.name = "Template"; | |
var text = gameObject.AddComponent<NumberText>(); | |
text.color = this.textColor; | |
text.font = this.textFont; | |
text.fontSize = fontSize; | |
text.alignment = TextAnchor.MiddleCenter; | |
gameObject.SetActive(false); | |
gameObject.transform.SetParent(this.gameObject.transform); | |
return gameObject; | |
} | |
/// <summary> | |
/// 位置調整 | |
/// </summary> | |
/// <param name="text">Text.</param> | |
/// <param name="value">Value.</param> | |
/// <param name="position">Position.</param> | |
private void AdjustRect(GameObject text, int value, int position) | |
{ | |
var size = this.sizeList[value]; | |
var rectTransform = text.gameObject.GetComponent<RectTransform>(); | |
rectTransform.sizeDelta = size; | |
this.startX += (size.x * (position == 0 ? 0.5f : 1f)); | |
rectTransform.localPosition = new Vector2(this.startX, 0); | |
} | |
/// <summary> | |
/// 各数字の横幅を一気に取得しておく | |
/// </summary> | |
private void PreLoadSize() | |
{ | |
var generator = new TextGenerator(); | |
var settings = this.template.GetComponent<Text>().GetGenerationSettings(Vector2.zero); | |
for (int i = 0; i < 10; i++) { | |
var width = generator.GetPreferredWidth(i.ToString(), settings); | |
this.sizeList.Add(new Vector2(width, this.rectTransform.rect.height)); | |
} | |
} | |
} | |
class NumberText: Text | |
{ | |
public void AnimateWave(float delay) | |
{ | |
var rectTransform = this.gameObject.GetComponent<RectTransform>(); | |
var seq = DOTween.Sequence(); | |
seq.Append(rectTransform.DOLocalMoveY(5f, 0.2f).SetDelay(delay)); | |
seq.Append(rectTransform.DOLocalMoveY(0f, 0.1f)); | |
} | |
public void AnimateScale(float delay) | |
{ | |
var rectTransform = this.gameObject.GetComponent<RectTransform>(); | |
var seq = DOTween.Sequence(); | |
seq.Append(rectTransform.DOScale(1.4f, 0.2f).SetDelay(delay)); | |
seq.Append(rectTransform.DOScale(1f, 0.1f)); | |
} | |
public void AnimateRotate(float delay) | |
{ | |
var rectTransform = this.gameObject.GetComponent<RectTransform>(); | |
rectTransform.DOLocalRotate(new Vector3(0, 360, 0), 0.4f, RotateMode.FastBeyond360) | |
.SetDelay(delay) | |
.OnComplete(() => { | |
rectTransform.localRotation = Quaternion.Euler(0, 0, 0); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment