おもちゃラボ

Unityで遊びを作ってます

【Unity】コライダーを可視化する方法2選

f:id:nn_hokuson:20211210164008g:plain:w400

UnityでデバッグをするときColliderを可視化したいことってありますよね。
コライダーを見える化するには

  1. Physics Debuggerを使う
  2. 可視化スクリプトを使う

の2通りの方法があります

Physics Debuggerを使う

Physics Debuggerを使うとUnityエディタ上でコライダを可視化することができます。

Physics Debuggerを使うにはメニューバーから「Window」→「Analysis」→「Physics Debugger」を選択します。画面右下の「Collision Geometry」にチェックを入れるとコライダが表示されます。

f:id:nn_hokuson:20211209202916p:plain:w500

ただし、可視化できるのはUnityエディタの編集時のみです。Unityエディタで実行した場合や、iOS/Androidのアプリ、PCでの実行時にはコライダを可視化することはできません。

可視化スクリプトを使う

Unityエディタやアプリ実行時にもコライダを可視化したい場合は、スクリプトを使って可視化する必要があります。こちらのスクリプトを参考にさせて頂き、実行時にコライダのスケール等を変更した場合にもリアルタイムで変更が更新されるようにしました。

ColiiderVisualizer.csをダウンロードして、プロジェクトに追加してください。
ColliderVisualizer

次に、コライダを表示したいオブジェクトにColiiderVisualizer.csをアタッチしてください。
f:id:nn_hokuson:20211209203925p:plain:w250

ColliderVisualizerはスクリプトをアタッチしたオブジェクト(子要素を含む)の全コライダを検索して可視化を行います。実行すると、次のようにコライダが可視化されます。
f:id:nn_hokuson:20211210163358p:plain:w500

【DOTween】DoPunchScaleの拡大率を指定する方法がおかしい!

DOTweenには、一回モデルを拡大してから、ビヨンビヨ〜ンと拡縮しながらもとのサイズに戻す「DoPunchScale」というメソッドがあります。
f:id:nn_hokuson:20211102155826g:plain:w450
DoPunchScaleの第1引数にはVector3型のscale、第2引数にはfloat型のアニメーション時間を渡します。

transform.DoPunchScale(Vector3.one*3.0f,  1.0f); // サイズ「3」まで拡大して戻す?

DoScaleメソッドもDoMoveメソッドも「拡大後」「移動後」の値を渡すので、DoPunchScaleの第1引数にも「拡大後のサイズ」を指定すると思うじゃないですか。

でもでも、DoPunchScaleは違うんです、「現在のスケールからどれぐらい大きくしたいか」という差分を渡すんです。つまり元のサイズが1のオブジェクトにDoPunchScaleを使うと次のようになるんです。

transform.DoPunchScale(Vector3.one*3.0f,  1.0f); // サイズ「4」まで拡大して戻る
transform.DoPunchScale(Vector3.one*-1.0f,  1.0f); // サイズ「0」に縮小して戻る

これ、トラップな気がするぞ!

uGUI Textの文字の座標を取得してインライン画像を実現する

uGUI Textの文中に画像を配置したい場合、特定の文字の座標を取得する必要があります。この記事ではuGUI Textから特定文字の座標を取得し、そこに画像を配置することでインライン画像を実現する方法を紹介します。

f:id:nn_hokuson:20211029101035p:plain:w450

uGUI Textの特定文字の座標を取得

uGUIのTextから特定文字の座標を取得するにはcachedTextGeneratorを使います。cachedTextGeneratorを使うと、それぞれの文字を囲むボックスの4頂点の座標を取得することができます。

f:id:nn_hokuson:20211029092948p:plain:w500

各文字の4頂点の座標は左上から時計回りにListに格納されています。今回は文字の中心の座標がほしいので左上の座標と右下の座標の中間値を計算します。

f:id:nn_hokuson:20211029093403p:plain:w340

それでは実際にプログラムを作ってみましょう。インライン画像を実現する流れは次のとおりです

  1. Textから特定の文字を検索する
  2. その文字の座標を計算する
  3. 計算した座標に画像を移動する

Textから特定の文字を検索する

今回は「おもちゃ・ラボ」の「・」に「♥」の画像を配置してみます。そこで文字列中から「・」を検索します。文字列から特定の文字を検索するにはIndexOfメソッドを使います。

Text message = GetComponent<Text>();
int n = message.text.IndexOf("・");

IndexOfメソッドは引数に指定した文字のインデックスを返します。C#の文法についてはコチラも合わせて参考にしてくださいね。

n番目の文字の中央座標を計算する

上で紹介したcachedTextGeneratorを使ってn番目の文字の座標を計算します。

IList<UIVertex> vertexs = message.cachedTextGenerator.verts;
float unitsPerPixel = 1 / message.pixelsPerUnit;

int idx = n * 4;
UIVertex topLeft = vertexs[idx];
UIVertex bottomRight = vertexs[idx + 2];

topLeft.position /= message.pixelsPerUnit;
bottomRight.position /= message.pixelsPerUnit;

Vector3 center = (topLeft.position + bottomRight.position) / 2f;

cachedTextGeneratoで文字の頂点配列を取得し、n番目の文字の左上座標と右下座標を取り出します。今回の場合「・」は5文字目なのでn=4となり、16番目と18番目の座標を取り出しています。

f:id:nn_hokuson:20211029100545p:plain:w500

最後に、topLeftとbottomRightの2頂点の中間値を計算することで、文字の中央の座標を取得します。
f:id:nn_hokuson:20211029100715p:plain:w250

計算した座標に画像を移動する

最後に計算したcenter座標に画像を移動します。

this.img.GetComponent<RectTransform>().anchoredPosition = center;

得られたcenter座標はanchoredPositionで計算されています。したがって、これを画像のanchoredPositionに設定しています。

まとめ

上のプログラムをまとめると次のようになります。

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

public class InlineImage : MonoBehaviour
{
    [SerializeField] GameObject img;

    void Start()
    {
        Text message = GetComponent<Text>();
        int n = message.text.IndexOf("・");

        IList<UIVertex> vertexs = message.cachedTextGenerator.verts;
        float unitsPerPixel = 1 / message.pixelsPerUnit;

        int idx = n * 4;
        UIVertex topLeft = vertexs[idx];
        UIVertex bottomRight = vertexs[idx + 2];
        
        topLeft.position /= message.pixelsPerUnit;
        bottomRight.position /= message.pixelsPerUnit;

        Vector3 centerPosition = (topLeft.position + bottomRight.position) / 2f;
        this.img.GetComponent<RectTransform>().anchoredPosition = centerPosition;
    }
}

作成したInlineImageスクリプトをuGUI Textのオブジェクトにアタッチしてください。次に、インスペクタからimgに表示したい画像をドラッグ&ドロップしてください。

f:id:nn_hokuson:20211029101832p:plain

これで実行すれば、指定した文字の座標に画像が移動して、インライン画像が実現できます。

nn-hokuson.hatenablog.com