2020/11/09
というわけで、近頃のゲーム業界はE3の件でにぎわっていますね!
特に気になるのはやはりPS4のモンハンでしょうか。久々のPSハードなので尚更ですね。
今回の内容ですが、珍しくUnityのエディタ拡張に関するお話です。
シーンビューであれこれ物を配置する際、「Blenderのようにテンキーで視点変えれたらな~」なんて思うことがあります。「シーンギズモ使えよ」という話ではありますが、やはりマウスカーソルはそのままで、パパっと回したいのが願望です。
エディタ拡張系はほとんど触ったことがなく、ちょうどいい機会なので「それっぽい動作」を作ってみました!
ちなみに「シーンギズモ」って↓のことらしいです。
これに名前があることを知ったのはかなり最近だったりします。Unity自体勢いで始めたので、各機能の名称が分からないことも多いです。普段は問題ありませんが、エディタ拡張関連であれこれ調べるときに面倒なことになります。
サンプルクラス
先に作ったクラスを記載します。
これをAsset以下のEditorフォルダに入れると機能します。
面倒が嫌いな方はこれをコピペすればBlenderっぽくなるはずです。
using UnityEngine; using UnityEditor; [InitializeOnLoad] public class SwitchViewPoint { // 各キー名の定義 private const string FRONT = "Keypad1"; private const string TOP = "Keypad7"; private const string RIGHT = "Keypad3"; private const string PROJECTION_METHOD = "Keypad5"; static SwitchViewPoint() { SceneView.onSceneGUIDelegate += onSceneView; } static void onSceneView(SceneView sceneView) { if (Event.current.isKey && Event.current.type == EventType.keyDown) { string current_key = Event.current.keyCode.ToString(); if (current_key != "None") { // シーンビューの情報を取得 Vector3 forward = sceneView.camera.transform.forward; // Ctrlキーが押されているか判定 bool onControlKey = Event.current.modifiers.ToString() == "Control" ? true : false; // フロントビュー if (current_key == FRONT) { forward = onControlKey ? Vector3.forward : -Vector3.forward; } // トップビュー if (current_key == TOP) { forward = onControlKey ? Vector3.up : -Vector3.up; } // サイドビュー if (current_key == RIGHT) { forward = onControlKey ? Vector3.right : -Vector3.right; } sceneView.LookAt(sceneView.pivot, Quaternion.LookRotation(forward)); // 投影方法 if (current_key == PROJECTION_METHOD) { sceneView.orthographic = !sceneView.orthographic; } } } } }
以下、各部分について少しずつ紹介していきます!
シーンビューのイベントへ追加
SceneView.onSceneGUIDelegate
に作った関数を追加します。
static SwitchViewPoint() { SceneView.onSceneGUIDelegate += onSceneView; }
実はデリゲートって概念がよく分かっていなかったりするので、詳しいことは説明できません。「関数を変数っぽく使える」みたいな雰囲気でしょうか。
気になる方はぐぐってみてください。
入力キーの取得
Event.current.keyCode
で入力されたキーのKeyCode
が取得できます。
また、修飾キーが押されている場合はEvent.current.modifiers
で取れるので、Ctrlキーが押されているかの判定に使います。
if (Event.current.isKey && Event.current.type == EventType.keyDown) { string current_key = Event.current.keyCode.ToString(); bool onControlKey = Event.current.modifiers.ToString() == "Control" ? true : false; if (current_key != "None") { /* 各処理 */ } }
キーによっては何故か2回実行され、2回目はNone
が返ってくるので、こちらも弾くようにしています。
公式フォーラムにそれっぽい話はありましたが、分かるような分からないような・・・という感じです。
http://answers.unity3d.com/questions/666996/why-does-pressing-a-key-generate-a-keydown-event-w.html
各操作の実装
各キーは何れも「テンキーの」数字・記号です。当然ですが、NumLockがオンの状態でないと動作しません。
視点移動
1
でフロント、3
でサイド(右側)、7
でトップビューへの移動を実装します。
公式フォーラムにバックビューのやり方が載っていたので、参考にさせていただきました。
// シーンビューの情報を取得 Vector3 forward = sceneView.camera.transform.forward; // フロントビュー if (current_key == FRONT) { forward = -Vector3.forward; } // トップビュー if (current_key == TOP) { forward = -Vector3.up; } // サイドビュー if (current_key == RIGHT) { forward = -Vector3.right; } sceneView.LookAt(sceneView.pivot, Quaternion.LookRotation(forward));
カメラ方向を指定する際、Vector3
のup
、forward
、right
を逆数にする必要があります。「その方向を向けるために移動すべき場所」を考えると分かりやすいかも。逆に分かりにくいという方は忘れてください。
視点移動 (逆側)
BlenderではCtrl
を押しながら入力することで逆側に視点移動するので、そのあたりも考慮してみます。
先程のコードを少し修正します。
// シーンビューの情報を取得 Vector3 forward = sceneView.camera.transform.forward; // Ctrlキーが押されているか判定 bool onControlKey = Event.current.modifiers.ToString() == "Control" ? true : false; // フロントビュー if (current_key == FRONT) { forward = onControlKey ? Vector3.forward : -Vector3.forward; } // トップビュー if (current_key == TOP) { forward = onControlKey ? Vector3.up : -Vector3.up; } // サイドビュー if (current_key == RIGHT) { forward = onControlKey ? Vector3.right : -Vector3.right; } sceneView.LookAt(sceneView.pivot, Quaternion.LookRotation(forward));
Ctrlが押されている場合は各ベクトルの符号を逆にすればOKです。
ここは三項演算子でスマートに設定しちゃいましょう。
投影方法の切り替え
5
で透視投影と平行投影の切り替えを行います。Unityで言えば、シーンギズモの真ん中を押したときのアレですね。
あまり使わないとは思いますが、一応実装しておきます。
if (current_key == PROJECTION_METHOD) { sceneView.orthographic = !sceneView.orthographic; }
SceneView
自体にorthographic
があるので、こちらのtrue/falseを切り替えます。
SceneView.camera
にもorthographic
がありますが、こちらを切り替えても反映されないようです。
動作
シーンビューで動作を確認してみます。
テンキーの操作だけでぐるぐる動きます!
gifアニメーションでは微妙ですが、実際の動きはシーンギズモ操作時とほとんど変わらないのでもっとなめらかです。
あとがき
ということで、Unityのエディタ拡張でBlenderっぽい視点変更を実現してみました!
本当は「15度ずつ回転」もやりたかったのですが、思った以上に厳しかったので固定での移動だけに限定しました。
15度回転はあまり使わないので、機能的にはこれで十分でしょう。
エディタ拡張入門を読んだ感じでは、思った以上にあれこれできるようです。
また面白いネタがあったら挑戦してみようと思います。