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度回転はあまり使わないので、機能的にはこれで十分でしょう。
エディタ拡張入門を読んだ感じでは、思った以上にあれこれできるようです。
また面白いネタがあったら挑戦してみようと思います。







