[初心者向け]ギズモ描画用のプリミティブメッシュの取得方法

## 経緯
何かしらのサンプル作成や実体のないGameObjectの場所把握などにUnityのギズモ描画は利用することが多い。
デフォルトでは下記画像の通りのギズモ描画がサポートされている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212999/17963534-f71d-dc38-26e9-a4e691828ed6.png)
このほかシリンダーやカプセルも使いたい場合の簡単なサンプルを作成した

## 出来上がるもの
何はともあれ出来上がるものを見てみよう
サポートしているのは以下の通り( gif画像が荒いのは許して... )

**プリミティブのTransformとの連動**
![Sample_3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212999/b2eecf0e-1a2e-54d7-3d5d-c25a7b66c0ca.gif)


**プリミティブ形状の変更**
![Sample_0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212999/4c861f05-ff9d-7722-ce10-550a19ac1189.gif)

**描画方法をソリッド or ワイヤーフレーム切り替え**
![Sample_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212999/0c40115d-33b1-eb4e-cde1-f1cbed4c854b.gif)


**描画するプリミティブの色変更**
![Sample_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212999/d93f593e-8591-f1b0-1e05-b3f005254611.gif)


## スクリプト

今回のスクリプトはあくまでサンプルなのでエディタ拡張のコードも一つのファイルに収めています。
気になる人はエディタ用のコードとそうでないものとを分けると精神衛生上よろしいです。

``` csharp
using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace sample
{
    public class Sample : MonoBehaviour
    {

        // 描画モード.
        public enum DrawMode
        {
            Solid,
            Wire,
        }
        

        [SerializeField] Color gizmoColor;
        [SerializeField] DrawMode gizmoDrawMode;
        [SerializeField] PrimitiveType usePrimitiveType = PrimitiveType.Cube;
        [SerializeField] Mesh mesh = null;


        void OnDrawGizmos()
        {
            if (mesh == null) return;
 
             Gizmos.color = gizmoColor;
             switch (gizmoDrawMode)
             {
                 case DrawMode.Solid:
                     Gizmos.DrawMesh(mesh, transform.position, transform.rotation, transform.localScale);
                     break;
 
                 case DrawMode.Wire:
                     Gizmos.DrawWireMesh(mesh, transform.position, transform.rotation, transform.localScale);
                     break;
             }
        }


        
#if UNITY_EDITOR

        // エディタ拡張部分.
        [CustomEditor(typeof(Sample))]
        public class SampleEditor : Editor
        {

            public override void OnInspectorGUI()
            {
                var component = target as Sample;

                GUI.changed = false;
                component.gizmoColor = EditorGUILayout.ColorField("Gizmo Color", component.gizmoColor);
                component.gizmoDrawMode = (DrawMode)EditorGUILayout.EnumPopup("Draw Mode", component.gizmoDrawMode);
                if (GUI.changed) EditorUtility.SetDirty(component);
                
                // プリミティブタイプが変更された場合,メッシュを差し替える.
                GUI.changed = false;
                component.usePrimitiveType = (PrimitiveType)EditorGUILayout.EnumPopup(component.usePrimitiveType);
                if (GUI.changed)
                {
                    EditorUtility.SetDirty(component);
                    GameObject tempPrimitive = GameObject.CreatePrimitive(component.usePrimitiveType);
                    component.mesh = tempPrimitive.GetComponent<MeshFilter>().sharedMesh;
                    GameObject.DestroyImmediate(tempPrimitive);
                }

                // 取得したメッシュを確認できるようにしているだけ.
                EditorGUILayout.ObjectField(component.mesh, typeof(Mesh));
            }
        }
        
#endif
        
    }
}

```

肝となるのはエディタ拡張部分の↓この部分

``` csharp
                // プリミティブタイプが変更された場合,メッシュを差し替える.
                GUI.changed = false;
                component.usePrimitiveType = (PrimitiveType)EditorGUILayout.EnumPopup(component.usePrimitiveType);
                if (GUI.changed)
                {
                    EditorUtility.SetDirty(component);
                    GameObject tempPrimitive = GameObject.CreatePrimitive(component.usePrimitiveType);
                    component.mesh = tempPrimitive.GetComponent<MeshFilter>().sharedMesh;
                    GameObject.DestroyImmediate(tempPrimitive);
                }

```

GUI側のInspectorに変更があるか否かのチェックをとり変更がある場合、
- プリミティブオブジェクトの生成([参考ページ](http://kan-kikuchi.hatenablog.com/entry/CreatePrimitive))
- 生成したオブジェクトからsharedMeshの取り出し
- 生成したプリミティブオブジェクトの削除
の手順で差し替えています。