読者です 読者をやめる 読者になる 読者になる

PaperSloth’s diary

Unity(C#)、UE4(Blueprint/C++)についての記事を書いたり日常のことをつぶやきます。

Unityの開発応用1(Gizmoのお話)

Unityの開発準備で幾つかの開発準備を行ってきましたが、今回はUnityの開発応用(Editorの拡張など)の話をしていこうと思います。

 

 

第一回で紹介するのがGizmoを使った機能です。

UnityのCameraObjectは選択時にしか、カメラの描画範囲が分かりません。

そこで、この機能を使うことでカメラの可視範囲を見えるようにしました。

 

具体的にはこういうことです。

 

Before

f:id:PaperSloth:20141112222537p:plain

 

 

 

After

f:id:PaperSloth:20141112222633p:plain

 

 

地味な違いではありますが、これで常に描画範囲の確認が行えるため

毎回カメラを選択したり実行したりして描画範囲内にObjectを配置できているか確認しないで済むと思います。

 

ひとつ問題を上げるとすれば、実際の描画範囲とは微妙に異なるという点です。

実際のカメラは4頂点でNear値を指定しているのに対し、

このScriptでは1頂点から4頂点に向けて線を描いているため、

若干の誤差が出ます。

 

また、こちらのソースコード

過去のSingletonを継承して制作しています。

(Singletonにする必要性はないような気もしますが。。。)

Unityの開発準備(Singletonのお話) - PaperSloth’s diary

 

 

 以下ソースコードです。

using UnityEngine;
using System.Collections;
// カメラの描画範囲を可視化する
public class DrawCameraRange : TemplateSingleton<DrawCameraRange> {
#if UNITY_EDITOR
// 描画フラグ
[SerializeField]
bool m_isdraw = true;
private Vector3 m_leftTop, m_rightDown, m_rightTop, m_leftDown; // 描画範囲を示す線のベクトル
private Vector3 m_forwardPosVec = new Vector3(0.0f, 0.0f, 0.0f); // ローカルのZ値とデプスを乗算して求める
// Gizmoを描画し,カメラの範囲を常に描画する
private void OnDrawGizmos()
{
if(!this.m_isdraw)
return; // カメラオブジェクトの取得
Camera targetCamera = this.camera;

// 描画範囲の更新
this.m_forwardPosVec = targetCamera.transform.forward *
-targetCamera.transform.localPosition.z;
this.UpdateRange(targetCamera);
// カメラの座標を取得
Vector3 cameraPosVec = targetCamera.transform.position; // 描画範囲を示すベクトルの描画
Gizmos.color = new Color(1.0f, 1.0f, 1.0f, 0.5f);
Gizmos.DrawLine(this.m_leftTop, this.m_rightTop);
Gizmos.DrawLine(this.m_leftTop, this.m_leftDown);
Gizmos.DrawLine(this.m_rightDown, this.m_rightTop);
Gizmos.DrawLine(this.m_rightDown, this.m_leftDown); // 拡縮率の調整
float CameraScale = targetCamera.farClipPlane /
-this.transform.localPosition.z; // Far値を示す4頂点の座標
Vector3 FarLeftTop = (this.m_leftTop - cameraPosVec) *
CameraScale + cameraPosVec;
Vector3 FarLeftDown = (this.m_leftDown - cameraPosVec) *
CameraScale + cameraPosVec;
Vector3 FarRightTop = (this.m_rightTop - cameraPosVec) *
CameraScale + cameraPosVec;
Vector3 FarRightDown = (this.m_rightDown - cameraPosVec) *
CameraScale + cameraPosVec;
// 本来の正確な値を計算する場合はZ軸にNear値を足す
cameraPosVec.z = targetCamera.transform.position.z +
targetCamera.nearClipPlane; // カメラのFar値に対する四角形の描画
Gizmos.DrawLine(FarLeftTop, FarRightTop);
Gizmos.DrawLine(FarRightTop, FarRightDown);
Gizmos.DrawLine(FarRightDown, FarLeftDown);
Gizmos.DrawLine(FarLeftDown, FarLeftTop); // カメラが遠近感をシミュレートするかを判定する
if(!targetCamera.orthographic)
{
Gizmos.DrawLine(cameraPosVec, FarLeftTop);
Gizmos.DrawLine(cameraPosVec, FarLeftDown);
Gizmos.DrawLine(cameraPosVec, FarRightTop);
Gizmos.DrawLine(cameraPosVec, FarRightDown);
} else {
Vector3 forward = targetCamera.transform.forward * CameraScale;
Vector3 back = targetCamera.transform.forward * -CameraScale;
Gizmos.DrawLine(this.m_leftTop + forward, this.m_leftTop + back);
Gizmos.DrawLine(this.m_leftDown + forward, this.m_leftDown + back);
Gizmos.DrawLine(this.m_rightTop + forward, this.m_rightTop + back);
Gizmos.DrawLine(this.m_rightDown+ forward, this.m_rightDown + back);
}
}

  // 描画する範囲の更新
private void UpdateRange(Camera targetCamera)
{
this.m_leftTop = targetCamera.ViewportToWorldPoint(
             new Vector3(1.035f, 0.0f, this.m_forwardPosVec.z));
this.m_rightDown= targetCamera.ViewportToWorldPoint(
             new Vector3(-0.035f, 1.0f, this.m_forwardPosVec.z));
this.m_rightTop = targetCamera.ViewportToWorldPoint(
             new Vector3(-0.035f, 0.0f, this.m_forwardPosVec.z));
this.m_leftDown = targetCamera.ViewportToWorldPoint(
             new Vector3(1.035f, 1.0f, this.m_forwardPosVec.z));
}
#endif

 

急ぎでコメントを付け足したため、間違ってる点があったらごめんなさい( ;∀;)

使い方はこのScriptをCameraObjectにAddすればOKです。

 

 


今回は地味な機能の紹介でしたが、今後の開発応用編では
・Sceneを合成する機能
C#が好きになる話
・2Dゲームを作る際のアイツ
などなど
もう少し役立つであろう内容を書くようにします。

 

次回に期待していてください!

ではでは