FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム » Unity »【Unity】【C#】独自のギズモ(Gizmo)を表示する

【Unity】【C#】独自のギズモ(Gizmo)を表示する  


 特殊な当たり判定やオブジェクトに対しての当たり線などに、独自のギズモを利用すると見た目わかりやすい事がある。ギズモはあくまでエディタ上だけのものであり、実際のゲームでは表示されないので、開発を進める上では利用しない手はないだろう。ググッても思ったよりサンプルが少なかったので、簡単な例を書いてみることにした。アタッチするだけでいつでも使えるので非常に便利だ。

(※) Unity 5.4.3f1 / Windows10 で確認



反射レーザー(Wave51以降)の当たり判定は円形コライダを等間隔に置いて実装している(球状Gizmoで可視化)


Wave50のボスのミサイル発射位置と方向は同一線上に等間隔に配置した砲台を回転し翼に合わせている(線状Gizmoで可視化)


Unityチュートリアルの2Dシューティングにレーザーやらミサイルやらボス戦やらを付け加えてゲームとして楽しめるように超改造してみた



■球状 Gizmo
using UnityEngine;
using System.Collections;

/** 球状 Gizmo */
public class MyGizmoSphere : MonoBehaviour {

public bool visible = true; //可視状態
public Color color = Color.yellow; //色
public Vector3 center = Vector3.zero; //中心(相対座標)
public float radius = 1f; //半径

void OnDrawGizmos() {
if (!visible) {
return;
}

Gizmos.color = color;

//Gizmo はワールド座標指定なので、相対座標指定の場合はマトリクス変換で移動する
Gizmos.matrix = Matrix4x4.TRS(this.transform.position, this.transform.rotation,
this.transform.localScale);
Gizmos.DrawSphere(center, radius);
}
}


球状ギズモを縦長にしてみる

設定例

 使い方はギズモを付けたい GameObject にスクリプトを追加するだけだ。ギズモの形状やその他のメソッドなどはオンラインマニュアルに載っているので、色々試してみるといいだろう。

 注意点としては座標の指定などはワールド座標なので、そのままだと少し使いづらい点だ。階層化されているオブジェクトなどに設置するには相対座標の方がわかりやすいので、その場合は Gizmos.matrix(マトリクス変換)を使って移動すれば良い。Gizmos.DrawSphere() の中心座標(center)は this.transform.position でも良いが(この例が非常に多い)、マトリクス変換を使えばオブジェクトの回転やスケール、基準位置をずらすことなどにも対応させられるのでメリットが大きい。

 また、ギズモはエディタ上の機能なので、enabled のオン/オフで表示を切り替えられない(Start() や Update() を書くと、インスペクタにチェックボックスが表示される)。なので、visible (可視フラグ)を付けてある。一時的に消したいときに使うと良い。

 他の形状も設定パラメタが変わるだけなので、いくつか書いておこう。



■箱状 Gizmo
using UnityEngine;
using System.Collections;

/** 箱状 Gizmo */
public class MyGizmoCube : MonoBehaviour {

public bool visible = true; //可視状態
public Color color = Color.yellow; //色
public Vector3 center = Vector3.zero; //中心(相対座標)
public Vector3 size = Vector3.one; //x,y,z 方向の長さ

void OnDrawGizmos() {
if (!visible) {
return;
}

Gizmos.color = color;

//Gizmo はワールド座標指定なので、相対座標指定の場合はマトリクス変換で移動する
Gizmos.matrix = Matrix4x4.TRS(this.transform.position, this.transform.rotation,
this.transform.localScale);
Gizmos.DrawCube(center, size);
}
}


箱状ギズモを横長にし、45度回転してみる

設定例



■線状 Gizmo
using UnityEngine;
using System.Collections;

/** 線状 Gizmo */
public class MyGizmoLine : MonoBehaviour {

public bool visible = true; //可視状態
public Color color = Color.yellow; //色
public Vector3 from = Vector3.zero; //始点(相対座標)
public Vector3 to = Vector3.one; //終点(相対座標)

void OnDrawGizmos() {
if (!visible) {
return;
}

Gizmos.color = color;

//Gizmo はワールド座標指定なので、相対座標指定の場合はマトリクス変換で移動する
Gizmos.matrix = Matrix4x4.TRS(this.transform.position, this.transform.rotation,
this.transform.localScale);
Gizmos.DrawLine(from, to);
}
}


線状ギズモを中心を基準に45度回転してみる

設定例




■球/箱/線状のギズモ切り替え

 上記の//状のギズモの作り方がわかったら、形状を切り替えるようにしてみるのも良いだろう。今度はインスペクタで Shape を変更すると形状が変わるようにしてみた。各形状のパラメタは以下のように MySphere, MyCube, MyLine のように専用クラスでまとめるとスッキリする。また今回は、この形状パラメタのクラスは簡略のためコンストラクタを1つしか書いてないが、Vector3 でのコンストラクタも付け加えると便利かもしれない。

●球/箱/線状のギズモ切り替え版
using UnityEngine;
using System.Collections;

/** 独自 Gizmo (球,箱,線 状) */
public class MyGizmo : MonoBehaviour {

/** 形状を表す定数 */
[System.Serializable]
public enum Shape {
Sphere = 0,
Cube,
Line,
}

public bool visible = true; //可視状態
public Color color = Color.yellow; //色
public Shape shape = Shape.Sphere; //形状

public MySphere sphereParam = new MySphere(0, 0, 0, 1); //球状のパラメタ
public MyCube cubeParam = new MyCube(0, 0, 0, 1, 1, 1); //箱状のパラメタ
public MyLine lineParam = new MyLine(0, 0, 0, 1, 1, 1); //線状のパラメタ

void OnDrawGizmos() {
if (!visible) {
return;
}

Gizmos.color = color;

//Gizmo はワールド座標指定なので、相対座標指定の場合はマトリクス変換で移動する
Gizmos.matrix = Matrix4x4.TRS(this.transform.position, this.transform.rotation,
this.transform.localScale);
switch (shape) {
case Shape.Sphere:
Gizmos.DrawSphere(sphereParam.center, sphereParam.radius);
break;

case Shape.Cube:
Gizmos.DrawCube(cubeParam.center, cubeParam.size);
break;

case Shape.Line:
Gizmos.DrawLine(lineParam.from, lineParam.to);
break;
}
}
}

/** 球状パラメタ */
[System.Serializable]
public class MySphere
{
public Vector3 center = Vector3.zero;
public float radius = 1f;

public MySphere(float x, float y, float z, float radius) {
this.center = new Vector3(x, y, z);
this.radius = radius;
}
}

/** 箱状パラメタ */
[System.Serializable]
public class MyCube
{
public Vector3 center = Vector3.zero;
public Vector3 size = Vector3.one;

public MyCube(float x, float y, float z, float scaleX, float scaleY, float scaleZ) {
this.center = new Vector3(x, y, z);
this.size = new Vector3(scaleX, scaleY, scaleZ);
}
}

/** 線状パラメタ */
[System.Serializable]
public class MyLine
{
public Vector3 from = Vector3.zero;
public Vector3 to = Vector3.one;

public MyLine(float x1, float y1, float z1, float x2, float y2, float z2) {
this.from = new Vector3(x1, y1, z1);
this.to = new Vector3(x2, y2, z2);
}
}


Shpae で形状を変更できる

 各形状クラスに [System.Serializable] を書いておくとインスペクタで階層的に表示され設定できるようになる。ただ、この方法だと、実際に選択した形状について対応するパラメタは1つなので、少しインスペクタの表示に無駄があり紛らわしいのが難点だ(球状を選択して、箱状のパラメタに値を設定しても意味がない等)。その場合は「インスペクタの設定項目を動的に変更する」方法で表示を切り替えることもできるので、そちらの記事も参照して欲しい。

 他にも「WireSphere」「WireCube」「Mesh」「WireMesh」なども描けるので、付け加えるとかなり便利になる。やってみると良いだろう。




■ギズモのアイコンを表示する

 もう1つ、カメラや太陽(ライト)のようなアイコンを表示することも覚えておくと良いかもしれない。やり方は簡単で「Gizmos」フォルダを作成し、そこにアイコン画像をインポートして「Gizmos.DrawIcon()」を使用すれば良いだけだ。試しに上記の「MyGizmoCube」に付けてみよう。

●箱状のギズモにアイコン表示を加えたもの
using UnityEngine;
using System.Collections;

/** 箱状 Gizmo */
public class MyGizmoCube : MonoBehaviour {

public bool visible = true; //可視状態
public Color color = Color.yellow; //色
public Vector3 center = Vector3.zero; //中心(相対座標)
public Vector3 size = Vector3.one; //x,y,z 方向の長さ

public string iconImage = ""; //※使用するアイコン画像は Gizmos という名前のフォルダを作成し、そこに格納しておく。

void OnDrawGizmos() {
if (!visible) {
return;
}

if (iconImage != "") {
Gizmos.DrawIcon(transform.position, iconImage, true);
}

Gizmos.color = color;

//Gizmo はワールド座標指定なので、相対座標指定の場合はマトリクス変換で移動する
Gizmos.matrix = Matrix4x4.TRS(this.transform.position, this.transform.rotation,
this.transform.localScale);
Gizmos.DrawCube(center, size);
}
}


Gizmos フォルダに画像を置く

アイコンを表示してみる

名前を指定する

 なお、アイコンには回転などは効かないようだ(ただの存在位置表現のため)。大きさなどはカメラ等デフォルトのアイコンの表示スライダーと共有となる。





(関連記事)
【Unity】タブ切り替えの UI をコードを書かないで作る
【Unity】【C#】インスペクタの表示項目を動的に変更する
【Unity】【C#】FPS(フレームレート)をリアルタイムに測定して表示するv2(4隅選択可能で、画面サイズの変更にも対応版)
 Unityチュートリアルの2Dシューティングにレーザーやらミサイルやらボス戦やらを付け加えてゲームとして楽しめるように超改造してみた


<素材提供>
[グラフィック]
ハムコロ様
ゲーム開発日記 DVDM様
Merry Party様
ぴぽや様

※著作権は各著作者に帰属します。


関連記事
スポンサーサイト



category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityリファレンス  エディタ拡張 
tb: 0   cm: --


トラックバック

トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/228-75efbda4
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR