Appearance
第09回 UIエフェクト2
前回: 第08回 UIエフェクト1 / 次回: 第10回 シェーダー連携1
注意
この授業には提出課題があります
提出方法は 授業内で説明します
前回の振り返り
UI上の数字表示を作りました
- 第08回では、ダメージ数字、回復数字、コンボ数字などの UI エフェクトを扱いました
Canvasの表示モード、World Space表示、ビルボード、AnimationCurveや DOTween による簡易アニメーションを確認しました- UI は単なる表示ではなく、ゲームの状態を伝える演出として機能します
- 今回は、状態量の変化を可視化するゲージ系 UI を扱います
今回の授業の目的
状態量を視覚的に伝える

- HP
- スタミナ
- クールタイム
- 必殺技ゲージ
- 敵の体力表示
- 典型的なゲージ表示の方法を学びます
今回の授業内容
ゲージ表示の実装方法
Image.fillAmountによる横ゲージの実装- UI の
Maskによる横ゲージの応用 Image TypeのFilledによる円形ゲージWorld Space Canvasによる頭上 HP ゲージ- 3D 座標を
RectTransform座標へ変換する表示方法 - 授業内課題
ゲージの役割
変化量を直感的に伝える
- ゲージは、
現在値 / 最大値の割合を視覚化する UI です - HP やスタミナのように、プレイヤーが頻繁に確認する情報の視覚化に使われます
- 数字だけでは読み取りに時間がかかる場面でも、 ゲージなら一瞬で大まかな状態を把握できます
- 直感性と演出の両立が重要で、見た目の調整も大切な要素になります
ゲージの基本式
0 から 1 の割合に変換
csharp
// 比率の計算例
var rate = currentValue / maxValue;
rate = Mathf.Clamp01(rate);- こででの
currentValueは現在の HP やスタミナ、maxValueは最大 HP や最大スタミナです - UI 側では、この
rateを使って幅、マスク、fillAmountなどを更新します - ゲージの実装はまず割合を求め、UI の幅、色などに反映させるのが基本です
Image Type: Filled
画像の表示割合を変更する

割合変更の例
- uGUI の
Imageは、Image TypeをFilledに設定するとfillAmountで表示割合を制御できます - 横ゲージを作る場合は、
Fill MethodをHorizontalにします fillAmountは0で空、1で満タンです- シンプルな構成ですが、これだけで十分な 場合もあるかもしれません
横ゲージの基本設定
Inspector で確認する項目

Image コンポーネントの設定例
| 項目 | 設定例 |
|---|---|
| Image Type | Filled |
| Fill Method | Horizontal |
| Fill Origin | Left か Right |
| Fill Amount | 0 から 1 |
- 左から右へ増えるゲージなら
Fill OriginをLeftに 右から左へ増えるゲージならFill OriginをRightに設定しましょう
fillAmount を操作するコードの例
Image の表示割合を更新する
fillImageにはImage Type: Filledの Image を指定しますSetValueに現在値と最大値を渡すだけで ゲージの表示割合を更新できます- 最も簡単な横ゲージの実装方法です 何かと便利ですので覚えておきましょう
csharp
using UnityEngine;
using UnityEngine.UI;
public class FillAmountGauge : MonoBehaviour
{
[SerializeField] private Image fillImage;
public void SetValue(float current, float max)
{
if (max <= 0f)
return;
var rate = Mathf.Clamp01(current / max);
fillImage.fillAmount = rate;
}
}UI Mask の利用
親の画像で子の表示をくりぬく



最上段のImageにMaskを付与した例
Maskは、UI の子要素を親の形の内側だけに 表示するためのコンポーネントです- マスクを指定すれば、単に矩形だけではなく より自由な形状のゲージを作れます
- ※ 今回の目的とはあまり噛み合いませんが 単に範囲制限をするだけなら画像無しで使えて 軽量な
Rect Mask 2Dも便利です
Mask ゲージの実装例
親をマスク、子をバーにする

マスク兼BG
FillImageに画像を設定
フレームを重ねて完成
text
HP Gauge
├─ FillMask
│ └─ FillImage
└─ FrameImageFillMaskにMaskコンポーネントを追加しますFillImageは塗りつぶし用ですMaskの子にして、マスクの形で表示しますFrameImageはマスクの外側に置いて 枠や背景を表現します
マスク方式の使いどころ
矩形以外の形状でゲージを作りたいはず
- マスクを使えば、円形や波形など、様々な形のゲージを作ることができます
- いまのゲームで、単なる矩形でゲージが表示されることはあまりありません マスクの利用は、ゲージ表示の定番テクニックの一つです
- 一方で階層が増え、
Maskによる描画負荷の増加もあるため、 大量に表示する場合は実装方法を検討する必要があります
円形ゲージの作り方
Image の塗りつぶし機能を利用する


Image Type:Filled と Fill Method: Radial 360 の設定例
ImageコンポーネントのImage TypeをFilledに設定すれば 画像の表示割合をfillAmountで制御できる ようになりますFill MethodをRadial 360に設定するだけで 円形のゲージを作ることができますFill OriginとClockwiseで開始位置と 回転方向を変更できます
円形ゲージの設定
Inspector で確認する項目

Photoshop での作成例 図形で円を作成し、線の太さでリング化している
| 項目 | 設定例 |
|---|---|
| Image Type | Filled |
| Fill Method | Radial 360 |
| Fill Origin | 基点を上下左右のいずれかに設定 |
| Clockwise | 時計回り / 反時計回り |
| Fill Amount | 0 から 1 |
- 扇形のゲージには円形のスプライトを使います 中央を透明に抜けばリング状のゲージを作れます
円形ゲージの用途
横ゲージとの使い分け
- クールタイムやチャージ量のように、オンタイムでの増減を表現するのには 円形ゲージが向いています
- 円形ゲージは面積が大きく目立ちます 重要度の低い情報に使いすぎると画面がうるさくなるので注意が必要です
- HP のように残量を常に表示したい情報には横ゲージの方が向いています 用途ごとに使い分けましょう
頭上表示の目的
移動するキャラクターの状態表示

HP ゲージを頭上に表示した例
World Space Canvasは 3D 空間上の オブジェクトとして配置できる Canvas です- 3D キャラクターの子にするだけで UI を一緒に 表示することができます
- キャラクターの頭上に HP ゲージなどを 表示する場合などに便利ですが、 距離によって画面上のサイズが変わるため 常に最適な選択肢とは限りません
World Space Canvas の作り方
キャラクターの子に配置する

World Space Canvas の設定例 Face Camera はビルボード制御用のスクリプト(後述)
- キャラクターの子に
Canvasを作成する Render ModeをWorld Spaceにする- Canvas のサイズを小さく調整する
- 頭上に来るように
localPositionを設定する - HP ゲージ用の Image や Text を配置する
- カメラを向くようにビルボード制御を入れる
World Space Canvas のサイズ
そのままでは巨大に表示される
World Space Canvasは、UI の 1 ピクセルがワールド上の1ユニットに対応します 通常の UI の感覚で使用すると、非常に大きなサイズになってしまいます- Canvas の
Width、Heightを 3D 空間上のサイズに合わせるのがおすすめですが、 2D のサイズを流用したままScaleで縮小しても問題ありません - 3D キャラクターの子として運用する場合は、親のスケールに影響されることになります サイズ調整には注意が必要です
World Space Canvas をカメラ正面に向ける
LateUpdate でビルボード化
- 第08回で扱ったビルボード処理で、 UI 表示をカメラ方向に向けられます
LateUpdateで 回転をカメラと揃えるだけの シンプルな処理ですが、これで UI を常に 正面に向けることができます
csharp
using UnityEngine;
public class FaceCamera : MonoBehaviour
{
[SerializeField] private Camera targetCamera;
private void LateUpdate()
{
if (targetCamera == null)
targetCamera = Camera.main;
if (targetCamera == null)
return;
transform.rotation = targetCamera.transform.rotation;
}
}World Space Canvas の注意点
距離で見た目の大きさが変わる
- 遠くのキャラクターほどゲージは小さく見えます
- 近いキャラクターほどゲージは大きく見えます
- 遠距離の敵まで常に同じ大きさで表示したい場合は、
World Space Canvasではなく、画面上の Canvas に表示する方法もあります - ゲーム内の距離感を加味したいなら
World Space Canvasで問題ありませんが 読みやすい固定サイズにしたいなら画面座標変換が必要です
3D 座標を UI 座標に変換する
あくまで 2D で UI を表示するには
World Space Canvasは、3D 空間上のオブジェクトとして配置されるため、 距離によって見た目の大きさが変わってしまいます- 表示サイズを一定に保ちたい場合は、2D の Canvas に表示する方法が適しています
- 3D 空間の座標を画面上の Canvas 座標に変換するユーティリティ関数で 2D 表示に必要な座標変換を行います
- 若干複雑ですが、ゲーム内の二次元情報表示には必須のテクニックです
3D座標 → スクリーン座標 → Canvas座標
変換手順
- キャラクターの頭上のワールド座標を取得
- カメラ経由でワールド座標を画面に映った際の座標(スクリーン座標)に変換
- 得られたスクリーン座標を Canvas 内の
RectTransform座標に変換 - 変換後の座標に UI 部品を配置
- UI は画面上の Canvas にあるため、距離が変わってもサイズは変わりません
座標変換に使うメソッド
2段階で変換する
| 処理 | メソッド |
|---|---|
| 3D座標から画面座標 | Camera.WorldToScreenPoint |
| 画面座標からUI座標 | RectTransformUtility.ScreenPointToLocalPointInRectangle |
WorldToScreenPointの戻り値のzが 0 以下なら 対象はカメラの後ろに回っていることになります 画面外やカメラ後方にいる対象の UI は非表示にして処理を終えますScreenPointToLocalPointInRectangleは、 Canvas のRectTransformを基準にしたローカル座標を返します
3D 座標に 2D の UI を追従させる実装例
csharp
using UnityEngine;
public class WorldToCanvasFollower : MonoBehaviour
{
[SerializeField] private Transform target;
[SerializeField] private Vector3 worldOffset;
[SerializeField] private Camera worldCamera;
[SerializeField] private Camera uiCamera;
[SerializeField] private RectTransform canvasRect;
[SerializeField] private RectTransform uiRect;
private void LateUpdate()
{
if (target == null)
return;
if (worldCamera == null)
worldCamera = Camera.main;
if (worldCamera == null)
return;csharp
var worldPosition = target.position + worldOffset;
var screenPoint =
worldCamera.WorldToScreenPoint(worldPosition);
var visible = screenPoint.z > 0f;
uiRect.gameObject.SetActive(visible);
if (!visible)
return;
RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvasRect,
screenPoint,
uiCamera,
out Vector2 localPoint);
uiRect.anchoredPosition = localPoint;
}
}座標変換方式の注意点
奥行きとの関係は自分で処理する
- 3D 空間の座標を2Dに変換しただけでは ゲーム内の距離感や見え方を阻害したり、矛盾した表現になる場合があります
- ゲーム内容によっては、表示の有無や表示サイズの調整も必要です
- 特に敵の HP 表示などはゲーム体験に直結します ただ実装しただけで終わらせず、ゲームの質を高めるための調整を行いましょう
3D → 2D 変換の基本的な対応
距離や奥行きに応じて表示を調整する
- カメラの後ろにいる対象を非表示にする
- 画面外の対象を非表示にする、または画面端に固定する
- 手前の壁に隠れている対象を表示するかどうか決める
- 対象が多い場合は、表示距離や重要度で間引く
即時ゲージと遅延ゲージ
ダメージの量を見せる
- HP が減った瞬間、前景ゲージはすぐに減らします
- 背後に置いた別色のゲージを少し遅れて減らすと、 どれだけダメージを受けたか分かりやすくなります
- 回復の場合は、増える方向の遅延表現にすることもできます
- ゲージの変化が速すぎると読めないため、 UI では少しだけ余韻を入れると見やすくなります
ゲージのアニメーション例
DOTween でのアニメーション
- コードはダメージを受けたときに前景ゲージが 即時に減り、遅れて背後のゲージも減る例です
- UI アニメーションには細かな時間管理が 必要で、直接コーディングするのは大変です
- DOTween などのライブラリで大幅に省力化 できますので、積極的に活用しましょう
csharp
// ダメージを受ける
public void TakeDamage(float damage)
{
_hp = Mathf.Clamp(_hp - damage, 0f, 1f);
var sequence = DOTween.Sequence();
sequence.
Append(front.DOFillAmount(_hp, 0.2f)).
Join(_rectTransform.DOShakePosition(0.5f, 10f, 20)).
SetDelay(0.1f).
Append(back.DOFillAmount(_hp, 0.5f));
}
// 回復する
public void Heal(float heal)
{
_hp = Mathf.Clamp(_hp + heal, 0f, 1f);
var sequence = DOTween.Sequence();
sequence.Append(front.DOFillAmount(_hp, 0.5f));
sequence.Join(back.DOFillAmount(_hp, 0.5f));
}実習
各種ゲージを 実装してみよう
ひとつ作ると つぶしがきくよ
実習1:横ゲージを作る
fillAmount で残量を表示する
- Canvas に HP ゲージ用の UI を作成する
- 背景、
FillImage、枠を配置する FillImageのImage TypeをFilledにするFill MethodをHorizontalにする- スクリプトから
fillAmountを変更して HP の残量を表示する
実習1-2:Mask ゲージを試す
画像を潰さずに残量を表示する
FillImageを子に持つFillMaskを作成するFillMaskにRect Mask 2Dを追加するFillMaskの Pivot と Anchor を左寄せにする- スクリプトから
FillMaskの幅を変更する fillAmount方式との見た目の違いを確認する
実習2:円形ゲージを作る
Image Type を Filled にする
- 円形の Image を配置する
Image TypeをFilledにするFill MethodをRadial 360にするfillAmountを変更して残量が変わることを確認する- クールタイムやチャージ量として使える見た目に調整する
実習3:頭上 HP ゲージを作る
World Space Canvas を使う
- キャラクターの子に Canvas を作成する
Render ModeをWorld Spaceにする- Transform の Scale を小さくする
- 頭上に来るように位置を調整する
- ビルボード処理でカメラの方を向かせる
実習4:固定サイズの頭上 UI を作る
3D座標をUI座標へ変換する
- 画面上の Canvas に HP ゲージ Prefab を配置する
- キャラクターの頭上位置を取得する
WorldToScreenPointでスクリーン座標に変換するScreenPointToLocalPointInRectangleで Canvas 座標に変換するanchoredPositionに反映して追従させる
授業内課題
ゲージ UI を一つ作成して 提出してください
HP、スタミナ、 クールタイムなど
課題の条件
以下を満たしてください
現在値 / 最大値を割合に変換して表示している- 横ゲージ、円形ゲージ、頭上ゲージのいずれかを実装している
- 値を変更すると見た目が変化する
- 背景や枠などでゲージの範囲が分かる
- 色や形で用途が伝わるように調整している
- スクリーンショットまたは動画で提出する
余裕があれば挑戦
以下のような調整もしてみましょう
- ダメージ時の遅延ゲージを入れる
- 値の変化をなめらかに補間する
- 危険域で色を変える
- キャラクターの頭上に追従させる
- 3D 座標変換でサイズ固定の UI として表示する
提出時の説明
調整の意図を添えてください
- 何を表すゲージか
- どの方式で実装したか
- 値の変化をどのように見せたか
- 色や形をどう決めたか
- 読みやすくするために調整した点
- 改善したい点
今回のまとめ
ゲージは状態量を見せる UI エフェクト
Image.fillAmountを使うと、横ゲージをシンプルに実装できますMaskを使うと、画像を潰さずに横ゲージを表現できますImage Type: FilledとRadial 360で円形ゲージを作れますWorld Space Canvasは、キャラクターに紐づく UI 表示に向いています- 3D 座標を Canvas 座標へ変換すると、サイズ固定の頭上 UI を表示できます
- ゲージは派手さより、変化の読みやすさを優先して設計しましょう