概要
スクリプトをアタッチして、インスペクタからVector3
型の値を操作する、というケースはままあるでしょう。
インスペクタから設定する場合、XYZそれぞれの値を手入力で入力して設定していくことになりますが、位置の調整だったり、回転だったり、といったものに利用する値の場合、どうしても細かい数値で調整する必要があります。
すると問題になるのが、「微調整のやりづらさ」。
しかも位置合わせの目的でVector3
を用いている場合は、いちいち実行したりして確認する必要があってとてもめんどくさい作業になりがちです。
今回はそんなケースで利用できるカスタムエディタの仕組みについて書きます。
↑左の小さいCubeに見えるものはカスタムエディタの機能で、位置を分かりやすく表示しているだけで、GameObjectではありません。
↑インスペクタの表記。PositionとRotationを設定する、という想定。
位置と回転を視覚的に表現する
カスタムエディタの中で、以下の機能を利用することで画像のような機能を提供することができるようになります。
- Handles.PositionHandle
- Handles.RotationHandle
利用するには以下のように記述します。
var newPos = Handles.PositionHandle(pos, rot); var posChanges = EditorGUI.EndChangeCheck();
ちなみに上記の処理はOnSceneGUI
メソッド内で実行します。
コード自体はシンプルなので、すべて見てもらったほうが分かりやすいと思います。
コード
using UnityEngine; using System.Collections; [ExecuteInEditMode] public class ViewTest : MonoBehaviour { [SerializeField] Vector3 _position; [SerializeField] Vector3 _rotation; public Vector3 Position{ get { return _position; } set { _position = value; } } public Quaternion Rotation { get { return Quaternion.Euler(_rotation); } set { _rotation = value.eulerAngles; } } }
using UnityEngine; using UnityEditor; using System.Collections; [CustomEditor(typeof(ViewTest))] public class ViewTestEditor : Editor { protected virtual void OnSceneGUI() { var script = target as ViewTest; var pos = script.Position; var rot = script.Rotation; EditorGUI.BeginChangeCheck(); var newPos = Handles.PositionHandle(pos, rot); var posChanges = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); var newRot = Handles.RotationHandle(rot, pos); var rotChanges = EditorGUI.EndChangeCheck(); Handles.CubeCap(0, pos, rot, 0.2f); if (posChanges || rotChanges) { if (posChanges) { script.Position = newPos; } if (rotChanges) { script.Rotation = newRot; } } } }