Web Analytics

こつこつエンジニア

現役アプリ開発者によるIT系特化ブログ

Unityでカメラがどの距離でもオブジェクト上に同じサイズのテキストを表示させてみる【オブジェクト表示2】

f:id:madai21:20210720210353j:plain

はじめに

Unityのオブジェクト表示2回目です。
前回はカメラに映っている特定のオブジェクトをクリックするとそのオブジェクト名の情報を表示させました。
madai21.hatenablog.com

近い場合はテキストの内容がわかりますが、遠く離れてしまうと見えなくなってしまうという課題がありました。
今回はカメラがどの距離でもオブジェクト上に一定サイズのテキストを表示させてみたいと思います。

  1. オブジェクトをクリックするとオブジェクト名の一部を表示する
  2. どの距離でも同じサイズのテキストを表示させる ※【今回】※
  3. カメラの範囲内にオブジェクトが写っている時のみ表示する

環境

Unity 2020.3.12f1を使います。
unity3d.com
この記事で作成したプロジェクトを元に作成していきます。
madai21.hatenablog.com

どの距離でも同じサイズのテキストを表示させる

カメラがどの位置でも一定サイズのテキスト表示するにはどう実現したらいいでしょうか?
それはCanvasで実現させます。
Hierarchy画面で右クリックからUI > Canvasを選択します。
f:id:madai21:20210809204512p:plain
Canvasを選択して右クリックからCreate Emptyを選択します。
f:id:madai21:20210809210952p:plain
オブジェクト名をRedSphereTextとしましょう。
Inspector画面でActiveをfalseにし、Rect Transformをtop&leftに、Pos X/Pos Y/Width/Height/Pivot X/Pivot Yをすべて0に変更します。
Add Componentを押して、検索窓にVerと入力してVertical Layout Groupを選択します。
f:id:madai21:20210809204636p:plain
さらにAdd Componentを押して、検索窓にContentと入力してContent Size Fitterを選択します。
f:id:madai21:20210809211403p:plain
Vertical Layout GroupのControl Child SizeのWidthとHeightのみにチェックします。
Content Size FitterのHorizontal FitとVertical Fitを共にPreferred Sizeを選択します。
f:id:madai21:20210809211723p:plain
Add Componentを押して、検索窓にNewと入力してスクリプトファイルを作成します。
スクリプトファイル名をSphereTextControllerとします。
f:id:madai21:20210809211910p:plain
Hierarchy画面に戻ります。
RedSphereTextを選択している状態で右クリックからUI > Textを選択します。
f:id:madai21:20210809212058p:plain
Inspector画面でWidthとHeightを0にします。
Pivot Xを0、Pivot Yを1にします。
f:id:madai21:20210809212300p:plain
Font Sizeを18、Colorをすべて255(白色)にします。
Add Componentを押して、検索窓にLayと入力してLayout Elementを選択します。
f:id:madai21:20210809212544p:plain
Hierarchy画面でRedSphereTextを選択し、SphereTextControllerのCamにMainCameraを、TargetにRedSphereをそれぞれHierarchy画面からドラッグ&ドロップしてアタッチしておきます。
f:id:madai21:20210809212703p:plain
BlueSphereとGreenSphereも同様の設定を行っておきます。

SphereTextController.csを開いて以下の内容に編集します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class SphereTextController : MonoBehaviour
{
    public Camera cam;
    public GameObject target;
 
    private RectTransform rect;
    // Start is called before the first frame update
    void Start()
    {
        rect = GetComponent<RectTransform>();
    }
 
    // Update is called once per frame
    void Update()
    {
        if (cam == null || target == null || rect == null)
        {
            return;
        }
 
        rect.position = cam.WorldToScreenPoint(target.transform.position) + new Vector3(0.0f, 10.0f, 0.0f);
    }
}


これでTargetオブジェクトのWorld座標をカメラのスクリーン平面上の座標に変換しています。

cam.WorldToScreenPoint(target.transform.position)


実行してみましょう。
ドリーインやドリーアウトしても一定サイズの表示になりましたね^^

おわりに

今回はカメラがどの距離でもオブジェクト上に一定サイズのテキストを表示させてみました。
実はこの対応ではオブジェクト表示でまだ問題があります。
この実行を見ていただくとわかると思いますが、カメラ範囲外でも情報を表示してしまっています。
これはまずいですね・・・^^;

次回はオブジェクトがカメラの範囲内か範囲外かを判定して範囲内の場合のみテキストを表示させるということをしてみようと思います。
madai21.hatenablog.com