Cluster Creator Kit と Unity Editor拡張 入門
この記事は Cluster Creator Kit Advent Calendar 2020 2020/12/04 に投稿する記事です。
概要
何を書こうか迷ったけれど、 clusterゲームワールド杯
2020 に応募したワールドで利用した Unity Editor拡張 が便利だったので 一部を 入門
として記事にしてみました。
ClusterCreatorKit
Clusterワールド制作ではスクリプトは使えないのですが Editor拡張 を使うと複雑なトリガー,ギミックを組み合わせたアイテムもコードで作る事ができて楽につくれるようになるので便利そうです。
内容
入門なので メニューから実行することで ワールドに必須のコンポーネント を配置するだけ
のシンプルな Editor拡張 を作ってみたいと思います。
- ClusterCreatorKit 導入
- ワールドに必須のコンポーネント の用意
- Editor拡張 スクリプトを作ってみる
- 初期ワールド作る スクリプトを作って実行してみる
- ClusterCreatorKitのコンポーネントをGameObjectに追加してみる
- まとめ
1. ClusterCreatorKit 導入
Unity 2019.4.1f1
動作確認済バージョン 2019.4.1f1
を Unity ダウンロード アーカイブ
からインストールする。
新規プロジェクトを作成
CreatorKitEditorSample
でプロジェクト を 新規作成。
ClusterCreatorKit を プロジェクトに導入する
- ClusterCreatorKit をダウンロードして解凍する。
https://github.com/ClusterVR/ClusterCreatorKit/releases - Unityのメニュー Window > Package Manager から「Packages」ウィンドウを開いてダウンロードしたzipを解凍したファイルを選択する
- Project Settingsの設定
Edit > Project Settings
項目 | 値 |
---|---|
Player > Other Settings > Rendering > Color Space | Linear |
2. ワールドに必須のコンポーネント の用意
ワールドに必須のコンポーネント を参考に 3つのオブジェクトを作って Prefab にする。
Spawn Point
リスポーンした際の位置となるオブジェクト
- GameObject を作り 名前を SpawnPoint
に設定する
- 子オブジェクト に GameObject を追加して PointObject
に設定
- PointObject
に Spawn Point
を設定する
- Transform Position Y を 2 に設定
Despawn Height
プレイヤーやMovable Itemをリスポーンする高さを決めるコンポーネント
- GameObject を作り 名前を Despawn Height
に設定する
- 子オブジェクト に GameObject を追加して DespawnObject
に設定
- DespawnObject
に Despawn Height
を設定する
- Transform Position Y を -10 に設定
Floor
キャラクターが立つ為の床になるオブジェクト
- GameObject を作り 名前を Floor
に設定する
- 子オブジェクト に Plane を追加
- Plane に Mesh Collider を設定する。
3つのコンポーネントを Prefab にする。
- `Asset/Editor/Items` フォルダを作成する
- Items へ 3つのコンポーネントを ドラッグ&ドロップ する
- Prefab になれば 青いアイコンに変わる
3. Editor拡張 を作ってみる
必須オブジェクトが準備できたので Editor拡張 を書いてみる。
ClusterCreatorEditorScript.cs を作成
Asset/Editor
フォルダに C# スクリプト を作成 ファイル名は ClusterCreatorEditorScript
にする。
ClusterCreatorEditorScript.cs を編集
- Unity のメニューに項目を追加して 実行 できるとこまで確認してみるコード
ClusterCreatorEditorScript.cs
内容をコードに書き換えて Unity 画面に戻ると
メニューにCreatorKitEditor
が追加される。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 1. UnityEditor を追加
using UnityEditor;
// 2. namespace ClusterCreatorEditorScript を追加
namespace ClusterCreatorEditorScript
{
// 3. class を EditorScript に名変更
public class EditorScript
{
// 4. Start(), Update() は不要なので削除する
// 5. メニューに "ClusterCreatorEditor/ワールド初期設定" を追加するコードを追加
[MenuItem ("ClusterCreatorEditor/ワールド初期設定")]
private static void InitWorld()
{
// メニューで選択されたら シーンに必須コンポーネントを配置 するメソッドを実行する
InitScene();
}
// 6. シーンに必須コンポーネントを配置 するコードを追加する
private static void InitScene() {
Debug.Log("InitScene()");
}
}
}
- Unity のメニュー CreatorKitEditor -> ワールド初期配置 を実行してみる
Console にInitScene()
が出力される。
4. 初期ワールド作る スクリプトを作って、実行してみる
InitScene()
を書き換えて ワールド初期設定 をしてみましょう。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 1. UnityEditor を追加
using UnityEditor;
using UnityEditor.SceneManagement;
// 2. namespace ClusterCreatorEditorScript を追加
namespace ClusterCreatorEditorScript
{
// 3. class を EditorScript に名変更
class EditorScript: EditorWindow
{
// 8. シーンに必須コンポーネントを配置 する実際のコードで利用するメンバ変数
// プレハブフォルダ名 Assets/Prefab
private static string PATH_DIST_REFAB_FOLDER_NAME = "Prefab";
private static string PATH_SRC_DESPAWN_HEIGHTP_REFAB = "Assets/Editor/Items/DespawnHeight.prefab";
private static string PATH_DIST_DESPAWN_HEIGHTP_REFAB = "Assets/Prefab/DespawnHeight.prefab";
// private static Vector3[] PATH_DIST_DESPAWN_HEIGHTP_REFAB_TRANSFORM = {new Vector3(0,-10,0), Vector3.zero, new Vector3(1,1,1)};
private static string PATH_SRC_SPAWNPOINT_REFAB = "Assets/Editor/Items/SpawnPoint.prefab";
private static string PATH_DIST_SPAWNPOINT_REFAB = "Assets/Prefab/SpawnPoint.prefab";
// private static Vector3[] PATH_DIST_SPAWNPOINT_TRANSFORM = {new Vector3(0,2,-4), Vector3.zero, new Vector3(1,1,1)};
private static string PATH_SRC_FLOOR_REFAB = "Assets/Editor/Items/Floor.prefab";
private static string PATH_DIST_FLOOR_REFAB = "Assets/Prefab/Ground.prefab";
// private static Vector3[] PATH_DIST_FLOOR_TRANSFORM = {new Vector3(0,0,0), Vector3.zero, new Vector3(1,1,1)};
// 4. Start(), Update() は不要なので削除する
// 5. メニューに "ClusterCreatorEditor/ワールド初期設定" を追加するコードを追加
[MenuItem ("ClusterCreatorEditor/ワールド初期設定")]
private static void InitWorld()
{
// メニューで選択されたら シーンに必須コンポーネントを配置 するメソッドを実行する
InitScene();
}
// 6. シーンに必須コンポーネントを配置 するコードを追加する
private static void InitScene() {
Debug.Log("InitScene()");
// 9. シーンに必須コンポーネントを配置 する実際のコード
// Prefab ディレクトリを作成
Debug.Log(PATH_DIST_REFAB_FOLDER_NAME);
if (AssetDatabase.IsValidFolder("Assets/" + PATH_DIST_REFAB_FOLDER_NAME) == false){
Debug.Log("Create REFAB_FOLDER");
AssetDatabase.CreateFolder("Assets", PATH_DIST_REFAB_FOLDER_NAME);
}
// Cluster 必須コンポーネントを Prefabから生成 する
CreatePrefab(PATH_SRC_FLOOR_REFAB, PATH_DIST_FLOOR_REFAB /*, PATH_DIST_FLOOR_TRANSFORM */);
CreatePrefab(PATH_SRC_SPAWNPOINT_REFAB, PATH_DIST_SPAWNPOINT_REFAB /*, PATH_DIST_SPAWNPOINT_TRANSFORM */);
CreatePrefab(PATH_SRC_DESPAWN_HEIGHTP_REFAB, PATH_DIST_DESPAWN_HEIGHTP_REFAB /*, PATH_DIST_DESPAWN_HEIGHTP_REFAB_TRANSFORM */);
// シーンを保存する
EditorSceneManager.SaveOpenScenes();
}
// 10. Cluster 必須コンポーネントを Prefab から生成 する
private static void CreatePrefab(string pathSrc, string pashDist/*, Vector3[] transform*/) {
// すでにあった場合は処理をしない
GameObject dist = AssetDatabase.LoadAssetAtPath<GameObject>(pashDist);
if (dist == null) {
// Prefabから生成 する
var src = PrefabUtility.LoadPrefabContents(pathSrc);
dist = PrefabUtility.SaveAsPrefabAsset(src, pashDist);
PrefabUtility.UnloadPrefabContents(src);
}
// シーンに Prefab を配置する
// dist.transform.position = transform[0];
// dist.transform.rotation = Quaternion.Euler(transform[1]);
// dist.transform.localScale = transform[2];
PrefabUtility.InstantiatePrefab(dist);
}
}
}
実行
hierarchy
に配置されている3つのprefabを削除してから、メニュー ClusterCreatorEditor/ワールド初期設定
を実行する。
コードが正しければワールドに必須の要素が配置されるはず。
5. ClusterCreatorKitのコンポーネントをGameObjectに追加してみる
エディター上のウインドウで GameObjectを指定して ClusterCreatorKitのコンポーネント を設定できるようにしてみましょう。
// 11. ClusterCreatorKit を利用する設定の追加
using ClusterVR.CreatorKit.Item;
using ClusterVR.CreatorKit.Item.Implements;
using ClusterVR.CreatorKit.Gimmick;
using ClusterVR.CreatorKit.Gimmick.Implements;
using ClusterVR.CreatorKit.Trigger.Implements;
public class EditorScript : EditorWindow
{
// 12. エディターの GUI で使う メンバ変数を定義する
private static GameObject selectGrabbableObject = null;
// 13. メニューの追加 ClusterCreatorEditor/ユーティリティ
[MenuItem ("ClusterCreatorEditor/ユーティリティ")]
private static void OpenUtility()
{
// メニューで選択されたら ウインドウを開く
EditorWindow.GetWindow<EditorScript>("ClusterCreatorEditor");
}
// 14. エディターの GUI を実装
void OnGUI () {
using (new GUILayout.VerticalScope())
{
EditorGUILayout.LabelField("Grabbable Item", EditorStyles.boldLabel);
using (new GUILayout.HorizontalScope())
{
EditorGUILayout.LabelField("GameObject", GUILayout.Width (100));
selectGrabbableObject = EditorGUILayout.ObjectField(selectGrabbableObject, typeof(Object), true) as GameObject;
}
if (GUILayout.Button("addGrabbable"))
{
// selectGrabbableObject に Grabbable Item を設定する
addGrabbableObject();
}
}
}
// 15. selectGrabbableObject に Grabbable Item を設定する
private static void addGrabbableObject(){
if (selectGrabbableObject == null) {
Debug.Log(string.Format("<color=#ff0000>{0}</color>", "GameObject を指定してください"));
return;
}
// CreatorKit で定義されているコンポーネントを AddComponent する
selectGrabbableObject.AddComponent<GrabbableItem>();
}
}
実行
- 手にもてるアイテムを作る為 Hierarchyに 新規で
GameObject
を配置。名前をGrabbableObject
に変更 - 子オブジェクトに
Cube
を配置 position Y 1 scale 0.5,0.5,0.5 にする - メニュー ClusterCreatorEditor -> ユーティリティ を選択して ウインドウを開く
- GameObject 欄に
GrabbableObject
をドラッグ&ドロップする -
addGrabbable
ボタンを押す。 -
GrabbableObject
の Inspector に GrabbableItemに 必要コンポーネントが自動で追加される。
まとめ
4. 初期ワールド作る スクリプトを作って実行してみる
や 5. ClusterCreatorKitのコンポーネントをGameObjectに追加してみる
ができるようになると、Unity Editor 上では見た目複雑なアイテムも、コードから生成できるようになってすっきりしそうです。 Editor拡張 使いこなせるとワールド作成の幅ひろがるかなーと思います!
12/5 は #clusterゲームワールド杯で クイズ・正解にタッチ!
ワールドを作った vin さんです。
logicつかったワールドの記事との事 気になります!
コード一式
参考
Cluster Creator Kit ドキュメント
ワールドに必須のコンポーネント
【cluster用アイテム】ハトソード
ClusterCreatorKitのプロパティをGameObjectに追加する方法は 【cluster用アイテム】ハトソード のコードも参考になりそうです。コンポーネントのクラス名などは ClusterCreatorKit 自体のコードを参考に。Cluster-World-Creator-Support
自分で作っている 1ボタンでワールドに必要な要素を配置したり、ゲーム作成に便利な機能をUnityに追加する Unityエディタ拡張スクリプト です。
Discussion