【Unity】オブジェクトの頭上に情報を表示する(2D)

Unityで2Dキャラクターの上にライフを表示させるには、UIのText要素を使用してキャラクターのライフ値を表示し、そのText要素をキャラクターに追従させる方法が一般的です。ここでは、Canvas内にライフを表示するUI Textを作成し、スクリプトを用いてキャラクターの動きに合わせてUIが追従する実装方法を紹介します

UI(Canvas)のTextMeshProで表示

TextMeshProを使用して2Dキャラクターの上にライフを表示させる場合も基本的な手順はUI Textを使用する場合と似ていますが、TextMeshProの機能を利用してより高品質なテキスト表示が可能です。以下にTextMeshProを使った実装手順を紹介します。

手順1: TextMeshProの準備

  1. Window -> TextMeshPro -> Import TMP Essential Resourcesを選択して、TextMeshProのリソースをプロジェクトにインポートします。このステップはTextMeshProを初めて使用する場合のみ必要です。
  2. UnityのHierarchyビューで右クリックし、UI -> Canvasを選択して新しいCanvasを作成します。
  3. Canvas内にTextMeshProのテキストを追加するため、Canvasを選択した状態で右クリックし、UI -> TextMeshPro - Textを選択します。これがキャラクターのライフを表示するTextMeshProテキストになります。


TextMeshProを使用して2Dキャラクターの上にライフを表示させる場合も基本的な手順はUI Textを使用する場合と似ていますが、TextMeshProの機能を利用してより高品質なテキスト表示が可能です。以下にTextMeshProを使った実装手順を紹介します。

手順2: TextMeshProテキストをキャラクターに追従させる

キャラクターの動きにTextMeshProテキストが追従するように、スクリプトを使用してキャラクターの位置にUIの位置を更新します。

using UnityEngine;
using TMPro; // TextMeshProの名前空間を追加

public class LifeDisplayTMP : MonoBehaviour
{
    public Transform character; // キャラクターのTransform
    public TextMeshProUGUI lifeTextTMP; // ライフを表示するTextMeshProUGUI
    public Vector3 offset = new Vector3(0, 2, 0); // キャラクターからのオフセット

    void Update()
    {
        // キャラクターの位置にオフセットを加えた位置にUIを移動させる
        lifeTextTMP.transform.position = Camera.main.WorldToScreenPoint(character.position + offset);

        // ここでlifeTextTMP.textをキャラクターのライフ値に応じて更新
        // 例: lifeTextTMP.text = "Life: " + character.GetComponent<Character>().life.ToString();
    }
}

実装のポイント

  • characterには、ライフを表示したいキャラクターのTransformコンポーネントをInspectorから割り当てます。
  • lifeTextTMPには、ライフ値を表示するTextMeshProUGUIコンポーネントをInspectorから割り当てます。
  • キャラクターのライフ値が変動する場合、その値に基づいてlifeTextTMP.textを適宜更新します。

TextMeshProを使用することで、さまざまなフォントスタイルや効果を活用し、ゲームの視覚的な魅力を高めることができます。

UI(3Dオブジェクト)のTextMeshProで表示

3D空間でTextMeshProを使用してテキストを表示することもできます。TextMeshProを利用することで、3Dシーン内のオブジェクト上に高品質なテキストを直接表示させることが可能です。3Dテキストを使用する場合、TextMeshPro - Textの代わりにTextMeshPro 3Dテキストオブジェクトを使用します。以下はその手順です。

手順1: TextMeshPro 3Dテキストの準備

  1. TextMeshProのリソースがプロジェクトにインポートされていない場合は、Window -> TextMeshPro -> Import TMP Essential Resourcesを選択してインポートします。
  2. Hierarchyビューで右クリックし、3D Object -> TextMeshPro - Textを選択して、3DシーンにTextMeshProテキストを追加します。

手順2: TextMeshPro 3Dテキストをキャラクターに追従させる

3Dキャラクターの動きにTextMeshProテキストが追従するように、スクリプトを使用してキャラクターの位置にテキストの位置を更新します。

using UnityEngine;
using TMPro; // TextMeshProの名前空間を追加

public class LifeDisplayTMP3D : MonoBehaviour
{
    public Transform character; // キャラクターのTransform
    public TextMeshPro lifeTextTMP3D; // ライフを表示するTextMeshPro
    public Vector3 offset = new Vector3(0, 2, 0); // キャラクターからのオフセット

    void Update()
    {
        // キャラクターの位置にオフセットを加えた位置にテキストを移動させる
        lifeTextTMP3D.transform.position = character.position + offset;

        // ここでlifeTextTMP3D.textをキャラクターのライフ値に応じて更新
        // 例: lifeTextTMP3D.text = "Life: " + character.GetComponent<Character>().life.ToString();
    }
}

実装のポイント

  • characterには、ライフを表示したいキャラクターのTransformコンポーネントをInspectorから割り当てます。
  • lifeTextTMP3Dには、ライフ値を表示するTextMeshProコンポーネントをInspectorから割り当てます。
  • キャラクターのライフ値が変動する場合、その値に基づいてlifeTextTMP3D.textを適宜更新します。
  • このスクリプトは3Dテキストを3Dキャラクターに追従させるため、Camera.main.WorldToScreenPointメソッドは使用しません。

TextMeshPro 3Dテキストを使うことで、3D環境内で直接的に高品質なテキストを表示させることができ、ゲームの没入感を高めることが可能です。

2つの実装パターンの使い分け

2D UI(TextやTextMeshProUGUI)と3D TextMeshProの実装方法の選択は、使用するシーンや必要とする機能、表示するテキストの種類によって異なります。以下では、これらの選択肢の棲み分けについて解説します。

2D UI(TextやTextMeshProUGUI)を使用する場合

  • ユーザーインターフェース(UI)要素が主な用途:ヘルスバー、スコア表示、メニュー項目など、画面に常時表示される情報に適しています。
  • 画面サイズの変更に対応しやすい:Canvas内で管理されるため、画面サイズや解像度が変更されても自動でサイズや位置の調整が可能です。
  • キャンバスのレイヤリング:複数のUI要素を重ねて表示する場合、Canvas内でのレイヤー制御が簡単にできます。

3D TextMeshProを使用する場合

  • 3D環境内でのテキスト表示が必要な場合:3Dモデルの近くに情報を表示したい場合や、テキスト自体を3D空間内で動かしたい場合に適しています。
  • 視覚的なインパクトが求められるシーンでの使用:TextMeshProは高品質なレンダリングが可能であり、カスタムフォント、アウトライン、シャドウ、グラデーションなど、高度なテキスト装飾を実現できます。
  • 3Dオブジェクトとの相互作用:3Dテキストをオブジェクトとして扱えるため、3Dオブジェクトと同様に回転、移動、スケーリングが可能です。また、物理演算の影響を受けさせることもできます。

使用シナリオに基づいた選択

  • ゲームUIやHUDの表示:プレイヤーのステータスやゲームメニューなど、画面に固定された情報を表示する場合は、2D UI(TextMeshProUGUI)を使用するのが一般的です。
  • ゲーム世界内でのダイナミックなテキスト表示:プレイヤーやオブジェクトの名前、3D空間内でのインタラクティブなメッセージ表示には、3D TextMeshProを使用します。これにより、テキストが3D環境の一部として自然に溶け込みます。

結局のところ、2D UI(TextMeshProUGUI)と3D TextMeshProの選択は、アプリケーションの設計と目的によって異なります。静的なUI要素には2D UIを、3D環境内でのインタラクティブなテキスト表示には3D TextMeshProを選択することが多いです。

サンプル実装

Prefabを使って汎用性を持たせています

同じ動きに見えますが、左側が3D TextMeshProを使用する場合、右側がUI(Canvas)のTextMeshProで表示になります

2つのゲームオブジェクト

cat_0(右側): UI(Canvas)のTextMeshProで表示
cat_0(1)(左側):3D TextMeshProを使用する場合

追加の実装をまとめるためのフォルダを作成

テストのため、フォルダを作成し、そこに素材を保存しています

UI(Canvas)のTextMeshProで表示

cat_0(右側): UI(Canvas)のTextMeshProで表示

UIでTextを作成します

作成されたTextのプロパティを調整します

調整値は次のようにします
下記キャプチャーは、Prefab後のものになります
上記、ヒエラルキーの状態で調整してもいいです

Prefabを作成します

スクリプトを作成しcat_0にアタッチします
2つのオブジェクトをアウトレット接続します

using UnityEngine;
using TMPro; // TextMeshProの名前空間を追加

public class LifeDisplayTMP : MonoBehaviour
{
    public Transform character; // キャラクターのTransform
    public TextMeshProUGUI lifeTextTMPPrefab; // ライフを表示するTextMeshProUGUIのPrefab
    private TextMeshProUGUI lifeTextTMPInstance; // Prefabから生成されたインスタンス
    public Vector3 offset = new Vector3(0, 2, 0); // キャラクターからのオフセット

    void Start()
    {
        // PrefabからTextMeshProUGUIインスタンスを生成し、Canvasの子として設定
        lifeTextTMPInstance = Instantiate(lifeTextTMPPrefab, FindAnyObjectByType<Canvas>().transform);
    }

    void Update()
    {
        // キャラクターの位置にオフセットを加えた位置にUIを移動させる
        lifeTextTMPInstance.transform.position = Camera.main.WorldToScreenPoint(character.position + offset);

        // ここでlifeTextTMPInstance.textをキャラクターのライフ値に応じて更新
        // 例: lifeTextTMPInstance.text = "Life: " + character.GetComponent<Character>().life.ToString();
    }
}

3D TextMeshProを使用する場合

cat_0(1)(左側):3D TextMeshProを使用する場合

ヒエラルキービューでグローバル座標に配置するため、3Dオブジェクトメニューから作成します

作成されたTextのプロパティを調整します

調整値は次のようにします
下記キャプチャーは、Prefab後のものになります
上記、ヒエラルキーの状態で調整してもいいです

Prefabを作成します

スクリプトを作成しcat_0(1)にアタッチします
2つのオブジェクトをアウトレット接続します

using UnityEngine;
using TMPro; // TextMeshProの名前空間を追加

public class LifeDisplayTMP3D : MonoBehaviour
{
    public Transform character; // キャラクターのTransform
    public TextMeshPro lifeTextTMP3DPrefab; // ライフを表示するTextMeshPro
    TextMeshPro lifeTextTMP3D;
    public Vector3 offset = new Vector3(0, 2, 0); // キャラクターからのオフセット

    private void Start()
    {
        lifeTextTMP3D = Instantiate(lifeTextTMP3DPrefab);
    }
    void Update()
    {
        // キャラクターの位置にオフセットを加えた位置にテキストを移動させる
        lifeTextTMP3D.transform.position = character.position + offset;

        // ここでlifeTextTMP3D.textをキャラクターのライフ値に応じて更新
        // 例: lifeTextTMP3D.text = "Life: " + character.GetComponent<Character>().life.ToString();
    }
}

おまけ

スクリプト命名サンプル

キャラクターの頭上に情報(例えば、名前、ライフバー、ステータスなど)を表示させるスクリプトの命名には、そのスクリプトが何をするのかを直感的に理解できるような名前を選ぶことが重要です。このようなスクリプトには、「AboveCharacterDisplay」、「HeadTopInfoDisplay」、「OverheadDisplay」などが考えられます。表示する内容によって、さらに具体的な名前をつけることも有効です。以下にいくつか例を示します。

1. ライフバーを表示する場合

  • HealthBarOverhead
  • HeadTopHealthDisplay

2. 名前を表示する場合

  • NameTagOverhead
  • CharacterNameDisplay

3. ステータスやチャットメッセージを表示する場合

  • StatusOverheadDisplay
  • OverheadChatDisplay

命名のポイント

  • 目的を明確に: スクリプトが何をするのかが一目でわかる名前を選びます。
  • 一貫性を保つ: プロジェクト内の他のスクリプト名とスタイルを合わせ、一貫性を保ちます。
  • 簡潔さと明瞭さ: 長すぎず、かつ、内容が明確に伝わる名前を選びます。

スクリプト名を選ぶ際は、プロジェクト内で他のスクリプトとどのように区別されるか、また、他の開発者がこのスクリプトの機能をすぐに理解できるかを考慮すると良いでしょう。これにより、チーム内でのコミュニケーションがスムーズになり、プロジェクトの管理とメンテナンスが容易になります。

Particle,Unity

Posted by hidepon