top of page
  • 執筆者の写真BTA(Kelorin Jo)

Unityのアセットにセットアップのエディタ拡張をつけたい

更新日:2021年6月18日

スクールシミュレーターでモデルや自作スクリプトが充実してきたし、

FANBOXやPatreon支援者向けコンテンツとしてミニゲームとか作りたいなー

と思って、過去購入したテンプレートにマリンスクールシミュレーターの自作モデル(デザイン:柏ユツカ様)を差し替えて作ってみるかなーと思ったら、

目当てのアセットが配布終了してたのでした。

それがこちらですが。


ThirdPerson CoverSystem



ギアーズまんまのカバーアクション銃撃戦ができる、敵AIも視界がありちゃんとしてる、

とても完成度が高く見えたし、手持ちのモデルが充実したらぜひこれでなにか作ろうと思ってたんですが、

唯一最大の欠点が、キャラのセットアップが手動という点でした。

大量のコンポーネントと値を、サンプルシーンのプレイヤーやNPCからコピーで移植しろという。


リリースから何年経ってもそこは頑として改善せず、しかも解説マニュアルが動画のみで、それも非英語字幕なしで音声解説なんてことしてるし、一方で見下ろしビューや味方AIの実装とか手のこんだ(ずれた)アップデートを続けていたようで。

(この作者もしや天然なのでは…)


販売終了した理由が売り上げやクレームだとしたら、セットアップが手動という点がでかいマイナス要素であり、セットアップウィザードが充実してるInvectorなんかと大きく明暗分けたのではと思えました。


実際、セットアップが苦行すぎてモデル差し替えは諦めました。


比較として、Invectorのセットアップがこんな感じのウィンドウが出ます。↓


1-2ステップの手間で、ものすごい量のコンポーネントとオブジェクトが追加されます。

カメラ、武器の持ち手マーカー、UIカメラつきアイテムインベントリまでセットアップされる豪華さ。




…実際セットアップウィザードって自分のゲームづくりでも欲しいと思う時が多々あるし、「キャラ追加するたびにこの手間ってなあ」ってなってるし、

これを自作できない限りは、仮にゲームシステムのテンプレートのアセットを作って販売しても受け入れられることはない、他をいくら強化しても埋め合わせは効かないのでは?

と思うにいたりました。


しかしUnityのエディタ拡張は、普通のゲームスクリプト作るより数倍難しいです。

カスタムインスペクタ用とカスタムウィンドウ用でコードが変わり、UIElementsだのIMGUIだの規格が後付けされてるせいでかネットの情報が分散して、

見た目のデザイン変えるだけで心が折れる難易度です。

しかし自作ゲームでも今後出番が多そうなことを考えると、作る価値はあるかも。

ゲーム作りの気分転換に挑戦しようと思います。


・自作ウィンドウの見た目を変える

機能に直接関係ないけど、視認性とやる気を向上させる効果があるので、見た目は大事。

プロジェクトからCreate-GUISkinで自作のUIスキン設定を作れますが、項目が多すぎて簡単に手が出ません。

一番効果でかくて簡単に改造できそうなのは、ButtonやWindowのBackGroundでしょうか?


InvectorのGUIスキンをいじったらこうです↓オレンジのウィンドウ超目立つ

自作のスクリプトに自作の背景を差し替えれたら視認性抜群ですが、 どうやって実装できるというのか。

(苦しむこと10時間)


Resourcesフォルダ作って(Assetフォルダ下ならどこでもいい)に自作GUISkinを入れ、

Editorフォルダを作って(Assetフォルダ下ならどこでもいい)、

以下のようなスクリプトGUITest .CSを作って、Editorに入れると…

using System;

using UnityEditor;

using UnityEngine;


public class GUITest : EditorWindow

{

[MenuItem("Tools/TestWindow")]

private static void ShowWindow()

{

var window = GetWindow<GUITest>(); // ←クラス名を記入します

window.titleContent = new GUIContent("自作ウィンドウテスト");

}


GUISkin customSkin;


private void OnEnable()

{ customSkin = Resources.Load("Vustom GUISkin") as GUISkin;} //←GUISkin名を記入します


void OnGUI()

{

GUI.skin = customSkin; //←これでGUISkinの設定が反映されるはず

EditorGUILayout.BeginVertical("Box");

EditorGUILayout.LabelField("テスト");

EditorGUILayout.LabelField("縦並びテキストテスト");

EditorGUILayout.BeginHorizontal();

EditorGUILayout.LabelField("横並びテキストテスト");

EditorGUILayout.LabelField("横並びテキストテスト");

EditorGUILayout.EndHorizontal();

EditorGUILayout.EndVertical();


if (GUILayout.Button("ボタンテスト"))

{Debug.Log("ボタン押した");}

}


}

上メニューにTools/TestWindowが追加され、自作ウィンドウが表示できますが



成功!

見た目変わりました。少なくともこのスクリプトはUnity2020.3.4の自作ウィンドウに対しては有効です。(ウィンドウ表示するだけでも機能がかぶってるコードがいくつもあるようです…)


※インスペクターのカスタムの場合はさらに複雑です。もとからあるインスペクターのデザインを継承を使って上書き、という手順してるから、こっちはうまくいかずエラーでまくったので見送りました。


まあWindowとかなぜか反映されない項目も多数あるのですが。Resourcesフォルダを使わされるのも不安の種。


ともあれこの自作ウィンドウに、セットアップウィザードに必要なコードを入れていけばいいでしょう。

幸い、通常のインスペクタ的なコードに関しては情報は多いので


1・ツールの説明文と、対象となるキャラモデル(GameObject)をセットする項目を作成

2・キャラモデルにAnimatorとかSkinMeshとか入ってるかチェック(自分で使う分には要らない)

3・すでに重複するコンポーネントが入ってないかチェック(自分で使う分には要らない)

4・全て大丈夫だったら確認ボタンが押せるようにする

5・AddComponentとかで必要なコンポーネントやプロップをもりもり追加

6・各コンポーネントに必要な値を入力


こんな流れかな。

上の自作ウィンドウにコードを書きたして作るとすると、こんな感じ?(長くなるのでプログラムわかる人向けに多少はしょってます。)

GameObject TargetChara;

void OnGUI()

{

GUI.skin = customSkin;


EditorGUILayout.BeginVertical("Box");

EditorGUILayout.LabelField("Humanoidでスキンメッシュのあるオブジェクトをセット");

TargetChara = (GameObject)EditorGUILayout.ObjectField("キャラモデル", TargetChara, typeof(GameObject),true);

EditorGUILayout.EndVertical();


if((TargetChara!=null)&&(GUILayout.Button("SETUP"))) { SetupChara(TargetChara); }

}


void SetupChara(GameObject ChaO)

{

var BoxC = ChaO.AddComponent<BoxCollider>();

var Rd= ChaO.AddComponent<Rigidbody>();

var CharaCo = ChaO.AddComponent<CharacterController>();

}

TargetCharaにキャラモデルを割り当ててからSETUPボタンを押すと、コンポーネントをアタッチするメソッドSetupCharaを実行します。

結果がこうです↓


みごとコライダーやRigidbodyやキャラコンがアタッチできました。

こんな感じで、他のコンポーネントやコライダーの寸法とか設定してけばいいのかな!


つまづきポイントは、変数TargetChara を割り当てるコードでしょう。

インスペクタならpublicにすれば済むことが、自作ウィンドウではかなりの長さです。

TargetChara = (GameObject)EditorGUILayout.ObjectField("キャラモデル", TargetChara, typeof(GameObject),true);

アドリブじゃ絶対思いつかない

配列やリストだとさらに困難ですが。過去に作ったエディタ拡張で使った時は何日も探して苦しんだっけ…

閲覧数:576回0件のコメント

最新記事

すべて表示
bottom of page