Unity
Unity2D
uGUI
GIF画像を差し替えるんだよ

Unity uGUIのTextをα値で1文字ずつ表示

More than 3 years have passed since last update.


初めに

当たり前の方法なのかもしれませんが自分で思いついた方法が上手く動かせたのと

文章の書き方の練習もかねて記事にしておこうかと思います。


概要

ss00-compressor.gif

こんな感じのメッセージ表示をUnityで実装してみました。


やり方

BaseMeshEffectを継承したクラスを用意しModifyMeshをオーバーライド

そのメソッド内で頂点のアルファを書き換えます。

ソースはこのようになります。

using UnityEngine;

using UnityEngine.UI;
using System;
using System.Collections;
using System.Collections.Generic;

public class TextAlphaSending : BaseMeshEffect
{
private const int OneSpriteVertex = 6;
private bool _isEnd = false;
private float _alpha = 0f;
private int _charaCount = 0;
private Text _text;
public Text Text
{
get{return _text ?? (_text = GetComponent<Text>()); }
}

/// <summary>
/// 文字表示終了判定
/// </summary>
/// <returns></returns>
public bool IsEnd()
{
return _isEnd;
}

/// <summary>
/// 文字数カウント初期化
/// </summary>
public void Initialize()
{
_charaCount = 0;
_isEnd = false;
}

/// <summary>
///
/// </summary>
/// <param name="vh"></param>
public override void ModifyMesh(VertexHelper vh)
{
var input = new List<UIVertex>();
var output = new List<UIVertex>();
var text = Text;

vh.GetUIVertexStream(input);
var vertexTop = _charaCount * OneSpriteVertex;

if (vertexTop >= input.Count) {
_isEnd = true;
return;
}

for (int i=0; i<vertexTop; ++i) {
output.Add(input[i]);
}

for (int i=vertexTop; i<vertexTop + OneSpriteVertex; ++i) {
var uiVertex = input[i];
uiVertex.color.a = (byte)(255f * _alpha);
output.Add(uiVertex);
}

_alpha += 0.1f;
if (_alpha >= 1f) {
_charaCount++;
_alpha = 0f;
}

vh.Clear();
vh.AddUIVertexTriangleStream(output);
}
}

using UnityEngine;

using UnityEngine.UI;
using System.Collections;

public class TextSenging : MonoBehaviour
{
private Text _text;
public Text Text
{
get
{
return _text ?? (_text = GetComponent<Text>());
}
}
private TextAlphaSending _textAlphaSending;
public TextAlphaSending TextAlphaSending
{
get
{
return _textAlphaSending ?? (_textAlphaSending = GetComponent<TextAlphaSending>());
}
}

// Use this for initialization
void Start ()
{
TextAlphaSending.Initialize();
Text.text = "【王様】\nおお勇者よ,よくぞ参った";
}

// Update is called once per frame
void Update ()
{
if (!TextAlphaSending.IsEnd()) {
Text.SetAllDirty();
}
}
}

TextSengingのUpdateで表示される文字が残っている場合

Text.SetAllDirtyでModifyMeshが呼び出されるようにしています。

以上のような感じで1文字ずつα値を変化させて文字を表示することが出来ます。

問題点としてはα値の更新を行わないとならないため毎フレームSetAllDirtyで

頂点を更新しなければならないということです。

実際処理負荷を検証したわけではありませんがあくまでPC環境でちょっとした会話シーンなら問題にならないでしょう

モバイル環境だとさすがに厳しいかもしれません

uGUIの頂点は意外と簡単に編集できる一例として考えてください