Amazonで商品を見るセール会場へ

Unityの手書き文字アニメーション:書き順マスクとCutoutの作り方

Unityでペンが文字を書いているように見せるには、書き順を表す階調をTextureのAlphaへ入れ、Cutoffを動かして表示領域を増やす方法があります。文字を1文字ずつ出すタイプライター表示とは別で、1文字の線の途中から現れる演出です。

この記事は書き順マスクの作り方、交差する線の制約、Unityでの確認、旧縁取りShaderの仕組みを扱います。CutoutのMaterial・Importの基本はAlpha Cutoutの記事にまとめています。現行仕様はUnity 6.3の資料を参照し、掲載する5画像は元記事の旧資料です。今回のUnity描画やAdobeソフトでの作業結果ではありません。

目次

書き順マスクの原理

Thresholdを高い値から低い値へ動かすと、高いAlphaの場所から順に現れます。書き始めを高い値、書き終わりを低い値にし、文字の外側は0にします。たとえば文字内側を0.2〜0.8に収める比較用素材なら、Threshold 0.9で非表示、0.1で文字全体を残すという確認ができます。これは素材を設計する例で、旧画像の階調を測った結果ではありません。

項目・症状選び方・確認先
書き始めAlphaを高くする。Thresholdを下げると先に現れる。
同じ線の途中書き順に沿ってAlphaを連続的に下げる。同じAlphaが広く続くと、その範囲が一度に現れる。
書き終わり0より大きい低いAlphaを使い、最後に現れる領域にする。外側の0と分ける。
文字の外側Alpha 0。Thresholdの最小値を0に固定せず、外側が残らない正の値で確認。
交差・重なり1画素には1つのAlphaしか持てない。別の筆順を同じ画素へ同時に記録できない。

文字を順に表示するだけならTextMeshProなどの文字表示の方法も候補ですが、これは輪郭を筆順に沿って描く方法とは異なります。フォント・文字表示の記事は文字を表示する設定の確認に使ってください。

素材を準備する:パスと文字形状を揃える

  1. 完成時の文字をRGB画像として用意します。表示位置と素材の縦横比を先に決め、マスクとカラーに同じキャンバス寸法・原点を使います。
  2. 書き順に沿うパスを用意し、線幅は最終的に表示したい文字の線を覆える幅にします。途中に細い部分や空白がないか、カラー画像と重ねて確認します。
  3. パスの始点から終点へ、Alphaの高い値から低い値に相当するグレースケールを割り当てます。単なる左→右のグラデーションでは、曲がる線の筆順と一致しません。
  4. 複数の筆画を同時に現したくない場合は、筆画ごとに使う値の範囲を分けます。各筆画が同じ白→黒を持つだけでは、同じThresholdで複数の線が一緒に進みます。
  5. マスクを文字の最終形状で切り抜き、形状の外は0、最後の筆画も0より大きい値にします。

旧Illustratorの資料と階調の条件

元記事はIllustratorのパスに沿うグラデーションを使って筆順の素材を用意しています。次の画面はその旧資料です。今回Adobeソフトの操作・現在の欄名は検証していません。

グラデーションパネルでパスに沿ってグラデーションを適用し、書き始めを白、書き終わりを黒に設定して階調を作る画面。

元記事にあったグラデーション範囲0〜50%は、すべての文字へそのまま使える必須値ではありません。始点・終点・外側のAlphaを分け、使用するThresholdで文字全体を出せるか確認してください。書き終わりを完全な0へすると、外側と同じ値になり、文字の終点だけを残す条件を作りにくくなります。

交差する線・複数の筆画で崩れる場合

1枚のマスクの交点を後の筆画の値で上書きすると、前の筆画を表示する途中で交点が欠ける場合があります。逆に早い筆画の値を残せば、交点部分だけは後の筆画より先に現れます。1画素1値の素材で、どちらの筆画も独立した時刻に描き直せるとは保証できません。

交差する部分の描き直しや、ペン先の動きまで必要なら、筆画を別Texture/別オブジェクトへ分ける、動くマスクや線描画を使うなど、表現を分ける方法を検討します。この本文の1枚マスクの手順で複数筆画の完全な筆運びまで実装済みとはしていません。

RGBAファイルに書き出し、Unity側でAlphaを見る

カラーと筆順マスクを同じ位置に重ね、RGBは文字色、Alphaは筆順の階調を持つ素材として書き出します。元記事はPhotoshopからTGA 32bit/pixelへ保存する例でした。追加Alphaチャンネルを作ったことだけで、PNGなどの出力へ必要なAlphaが含まれたとは判断しません。

フォトショップでグラデーション画像をアルファチャンネルとして設定し、ターガ形式で書き出し保存する手順を示す画面。
  1. 書き出したファイルを再び開き、筆順と外側のAlphaを確認します。形式名だけを根拠にせず、同じサイズ・座標で保存されたかも確認します。
  2. UnityではTexture Type=Default、Alpha Source=Input Texture Alphaを開始条件にし、プレビューのAlpha表示で階調が残っているか見ます。カラーの明るさをAlphaへ変換するFrom Gray Scaleとは分けます。
  3. 最初は圧縮・Mip Mapなどの条件を固定して境界を比較し、その後に実際の対象端末用設定へ戻します。Alpha is Transparencyは色の縁対策で、筆順マスクを生成する機能ではありません。

Importの各設定はUnity 6.3のTexture資料を参照します。画面上のグレースケールが正しくても、Shaderが読むチャンネルにその値が入っていなければ筆順は再現できません。

Unityで文字の表示をアニメーションさせる

  1. MeshRendererを持つQuadをCameraの前へ置き、文字素材用のMaterialを割り当てます。最初は他の文字やUIから分けて1枚だけで確認します。QuadとTextureの比率も揃えてください。
  2. URPならUniversal Render Pipeline/Unlit、Surface Type=Opaque、Alpha Clippingをオン、Base Mapへ文字のRGBA画像を指定します。Base Colorは白・Alpha 1から始めます。旧Built-inはUnlit/Transparent Cutoutという別のShader/欄です。
  3. Thresholdを手動で非表示側→途中→完成側へ動かします。書き始めが先に出るか、筆画が同時に動かないか、交点が欠けないか、外側の四角が出ないかを確認して値を記録します。
  4. 手動の結果が合ってからAnimationでQuadのMaterialのCutoff/Thresholdを記録します。0秒を確認した非表示値、たとえば1秒を完成値にします。カーブが使うShaderプロパティと一致するかも確認します。
  5. Loop Timeをオフ、Animator Controllerの既定状態へClipを設定しMotionを割り当てます。RecordとPreviewを解除してPlayし、始点・途中・終点を比較します。詳細な記録方法と端点の等値は基本のCutout記事で確認してください。
アニメーションウィンドウで、アルファカットオフの値を1から0へとキーフレーム設定する画面。

上のAnimation画面と次の文字GIFは旧例です。Threshold 1で完全非表示・0で文字の形だけ全表示という値は、すべてのShaderと素材で保証できません。clip(alpha−threshold)なら同じ値は残るため、Threshold 0で外側も残ることがあります。比較式と実際のAlpha範囲から端点を選んでください。

Unityで文字を描くようにアニメーションさせた表示例。

この例はClipを1回再生する構成です。Buttonで筆順を何度も再生する、途中から戻す、キャンセルする機能は別途状態制御が必要です。CanvasのImageで使う場合はStencil/RectMask2D/UI頂点色への対応も確認し、Mesh用MaterialをそのままUIの完成手順にしないでください。

文字の縁に色を付ける旧Shaderの条件

元記事はsetchi氏のCustomUnlitTransparentCutout.shaderを参照しています。2017年作成のGistで、取得ファイルはUnityCG.cginc、clip、Fogなどを使うBuilt-in系の旧コードです。URP/HDRPへの移植や現在の動作を確認した例ではありません。

取得したファイルのedgeHeightは0.015です。先にAlphaがCutoff未満の画素を除外し、残った画素のうちAlphaがCutoff+edgeHeight以下の帯を別の色へ変えます。したがってedgeHeightはAlpha値の幅で、縁の太さを画面上のピクセル数で指定する値ではありません。

項目・症状選び方・確認先
edgeHeightGist内の定数。Material Inspectorへ公開されたプロパティではない。0.05は元記事の調整例であり、取得したファイルの値ではない。
筆順マスクの傾き同じAlpha幅でも、階調の変化が緩い場所ほど画面上の帯が広くなり得る。一定ピクセル幅の輪郭線ではない。
色の指定旧ファイルはfixed4(0, 4, 2, 1)へ補間する。0〜1を超える値だけで画面上の発光を保証しない。
光がにじむ見た目使用Shaderの精度、描画先、HDRと後処理の条件を別に確認。Bloomや性能をこのコードで検証済みとはしない。

次の縁取りGIFは元記事の資料です。Gistを現在のUnityでコンパイルした結果ではありません。旧Forumの「Unlit cutout with shadows」参照先は今回の取得が403で、本文・添付ファイルの現状を追跡できていません。影付きShaderまで揃う手順としては採用していません。

文字が現れる先端の縁の幅や色を設定するシェーダーコードのパラメータ指定画面。

筆順や表示が崩れるときの確認

項目・症状選び方・確認先
逆方向から描かれる始点と終点のAlpha、Thresholdの移動方向を確認。高い値→低い値へ下げる例なら高いAlphaが先。
複数の筆画が同時に出る筆画ごとのAlpha範囲が重なっていないか。1枚で一つのThresholdを使う条件を確認。
交点が欠ける・先に出る1画素1Alphaの制約。交点の値と筆画の分割を検討。
最後の部分だけ出ない文字内側の最小Alphaと外側0、完成Threshold、Import後の値を確認。
境界がまだら・太さが一定でない圧縮・Filter・Mip Map・階調の傾き。縁取りのAlpha幅とピクセル幅を混同しない。
画面上のUIにするとMaskが効かないuGUI対応、Stencil/Clip、素材の比率を確認。Quadの手順とは分ける。

まず1筆画・1Quadの素材で、非表示→筆順→完成までを確認し、複数筆画や縁取りを後から加えると原因を分けやすくなります。基本のMaterialと比較条件はAlpha Cutoutの記事、透明・加算・深度の違いはアニメーション用Shaderの選び方で確認してください。

アニメーションと演出の記事は、ほかにもあります。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

Unityのおすすめ書籍

開発PCの選び方

周辺機器の優先度

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次