ホーム < ゲームつくろー! < Unity/カスタムエディタ編

カスタムエディタ編
その2 カスタムメニューを選択して世界に板ポリを置いてみる

 Unityのメニューに独自の項目を追加する事ができます。これにより、Unityエディタ上で色々な事を起こす事ができるようになります。いわば「マクロ」とか「プラグイン」を簡単に作れるわけです。

 ここではサンプルとして、メニューに独自の項目を追加し、それを選択したらヒエラルキーに板ポリが置かれるプラグインを作ってみましょう。



@ メニューに独自項目を追加する

 メニューに独自の項目を追加するのはとても簡単です。まずその項目でやりたい事をまとめるスクリプトを一つ新規で作ります。次にAssetsフォルダ以下のどこでも良いのですが「Editor」というフォルダを作り、そこにそのスクリプトを格納します。これはこうしないとUnityがカスタムエディタだと認識してくれないためです:

サンプルとして「MarupekeMenu」というスクリプトを作りました。

 次にスクリプトを次のように編集します:

using UnityEngine;
using UnityEditor;

public class MarupekeMenu {

    [MenuItem("Marupeke/Create New Something")]
    public static void CreateNewSomething() {

    }
}

 まず、カスタムエディタなので「using UnityEditor」で名前解決しておきます。次にクラスですが、これは特に何でも構いません。MonoBihaviourを継承してもしなくても良いです。

 一番のポイントはクラスにstaticでvoidなメソッドを追加し、それの属性を[MenuItem("path")]とする事です。上の例ではメインメニューに「Marupeke」というのが追加され、そのサブメニューに「Create New Something」という項目が出る事を想定しています。そして、それが選択された時の挙動がCreateNewSomethingメソッドに記述されるわけです。

 では実際にメニューを確認してみましょう:

…出ねぇ(^-^;。

 えーと、メニュー欄の適当な所をクリックしてみて下さい:

あ、出た(^-^;;;。どうも何らかのメニューイベントが発生しないと項目の更新が掛からないようです。ちょっと焦りました(^-^;。

 とりあえず、これでエディタ上で何かアクションを起こす準備ができました。



A メニュー選択からヒエラルキに板ポリを置く

 カスタムメニューの項目を選択した時の振る舞いはスクリプトに記述します。ちょっとだけ実用性を考えて、選択されたらヒエラルキ上に板ポリ1枚を新設する処理をさせてみます。ちょっとしたマクロ(プラグイン)ですね。

 [MenuItem]属性を付けたメソッド内でGameObjectを構成していきます:

[MenuItem("Marupeke/Create New Something")]
public static void CreateNewSomething() {
    // create new object
    GameObject obj = new GameObject("New 2D Plane");

    // attack MeshFilter
    MeshFilter filter = obj.AddComponent<MeshFilter>();

    // create -Z direction Billboard
    Mesh mesh = new Mesh();
    mesh.name = "Plane(-Z)";

    mesh.vertices = new Vector3[] {
        new Vector3( -0.5f, -0.5f, 0.0f ),
        new Vector3( -0.5f, 0.5f, 0.0f ),
        new Vector3( 0.5f, -0.5f, 0.0f ),
        new Vector3( 0.5f, 0.5f, 0.0f ),
    };

    mesh.triangles = new int[] {
        0, 1, 2, 1, 3, 2
    };

    mesh.uv = new Vector2[] {
        new Vector2( 0.0f, 1.0f ),
        new Vector2( 0.0f, 0.0f ),
        new Vector2( 1.0f, 1.0f ),
        new Vector2( 1.0f, 0.0f ),
    };

    mesh.RecalculateNormals();

    // attack mesh to filter
    filter.mesh = mesh;

    // attach renderer and replace material to 'Unlit/Transparent'
    MeshRenderer renderer = obj.AddComponent<MeshRenderer>();
    renderer.sharedMaterial = new Material( Shader.Find( "Unlit/Transparent" ) );
    renderer.sharedMaterial.mainTexture = new Texture2D( 8, 8 );
}

Unityで独自のメッシュを作るには、

○ GameObject
  ・ MeshFilter
  ・ Mesh
    - vertices
    - triangles
    - uv
  ・ MeshRenderer
    - sharedMaterial

の設定が必要です。上の例ではそれらをちまちまーっと作っています。マテリアルについて、MeshRenderer.shaderMaterialではなくmaterialにマテリアルを充てるとUnityさんに「EditorではMeshRenderer.materialにインスタンス入れるとリークするから駄目よ」と怒られます。

 上のコードをビルドし、[Marupeke]メニューの[Create New Something]を選択すると、ヒエラルキ上に辺の長さ1の板ポリゴンが一枚出現します:

後は煮るなり焼くなり好きに出来ます(^-^)。もちろん、何かプレハブを作ってそれをInstanciateしても構いません。むしろ、そういう使い方をUnityは推奨しています。

 ちょっとした便利なマクロやプラグインをこうして作る事で、Unityがどんどん便利になっていきます。それは同時にゲーム制作も楽になっていくわけです。積極的に使っていきたい機能ですね。