LiMMの溶解記録

脳を溶かすようなゲームを。

2Dゲーム空間に文字を出したい[その1]

痒いところに手が届かない

Unityのデバッグ機能は使っていますか?

Debug.Log()でコンソールに文字を出せます。

Debug.Line()でSceneビューに線が引けます。

ところでSceneビューやGameビューにデバッグ文字出したいですよね?

しかしそんな機能はありません。なので作りましょう。

[Unity 2017.3.0f3] 

完成予想図

f:id:littlemeltmachine:20180711225324p:plain

意外と簡単

調べたところ、3D空間上に文字を出せるものがありました。

このコンポーネントの名は『TextMesh』

空のオブジェクトにコンポーネントをアドしたところ、いい感じに出せました。

やった~

f:id:littlemeltmachine:20180711231311p:plain

が・・・駄目・・・! 罠っ・・・!!

f:id:littlemeltmachine:20180711231505p:plain

おわかりいただけるだろうか。

そう、スプライトより手前に描いてくれていません。

どうやらOrderInLayer=0で表示されているようです。というより、これは内部的には完全にスプライトですね。スプライトをカメラに合わせて変形させて、3D空間に置けますよ~というものみたいです。

スプライトなので、くっつけてるオブジェクトを他の3Dオブジェクト(球体)より奥にもっていっても文字が描画されます。

逆に言うと他の2D表示物をOrderInLayer=0より奥、つまりマイナスにすれば出るんじゃないかと思うのですが、そんなことやってられませんよね。

 

つまり2DゲームにおいてはTextMeshはスプライトと干渉してしまい、実力を発揮できないということですね。 ペッ!

2Dで出そう

ということでUIのTextで出すことにしました。

UI/TextをあらかじめPrefabにして……

ざっくりこんな感じのクラスを作って……(ちなみにinstanceIDを保持しているのは、Update()内でDrawTextを呼ばれる想定だからです)

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

public class Debug2DTextManager : MonoBehaviour {
    [SerializeField]
    GameObject m_canvas = null;

    [SerializeField]
    string m_prefabPath = "";

    class TextData {
        public GameObject textObject = null;
        public int instanceID = -1;
    }
    List<TextData> m_texts = new List<TextData>();

    public void DrawText(string text, Vector3 position, int instanceID)
    {
        // 3D座標をスクリーン座標に変換.
        position = Camera.main.WorldToScreenPoint(position);
        var data = m_texts.Find(a => a.instanceID == instanceID);
        if (data != null) {
                // 既存のテキストの情報を書き変える.
                data.textObject.transform.position = position;
                data.textObject.GetComponent<Text>().text = text;
        } else {
                // 新しいテキストオブジェクトを作る.
                TextData addData = new TextData();
                addData.textObject = (GameObject)Instantiate(Resources.Load(m_prefabPath), position, Quaternion.identity, m_canvas.transform);
                addData.textObject.GetComponent<Text>().text = text;
                addData.instanceID = instanceID;
                m_texts.Add(addData);
        }
    }
}

 うん、いい感じ!

f:id:littlemeltmachine:20180712002608p:plain

しかし当然、これはGameビューでしか見れません。デバッグで使いたいので、どちらかというとGameビューよりもSceneビューで見たい!

どうやって解決しようかなぁ。

現在模索中です。

[その2]へ続く。