[Unity] スクリプトからMesh、GameObjectを作成しPrefabへ登録する
前回の記事でパズルゲームをリリースした事を書いたのですが、そのゲームに使用したメッシュはすべてスクリプトから作成しました。モデリングする能力ないしね!
特に難しいことは無く使用するメソッドさえ覚えれば使えました。メモしておきます。
Contents
MeshをAsset内に保存
// メッシュを作成 var mesh = new Mesh(); ... // 出力先ファイル名 var filename = "Assets/Resources/Mesh/" + mesh.name + ".asset"; // Assetへ保存 UnityEditor.AssetDatabase.CreateAsset (mesh, filename);
Meshの拡張子は「.asset」で良さそう。
Mesh付きGameObjectをAsset内に保存
// 空のオブジェクトを生成し、MeshFilter, MeshRendererを追加する GameObject obj = new GameObject(); obj.name = name; obj.AddComponent<MeshFilter> (); obj.AddComponent<MeshRenderer> (); obj.AddComponent<MeshCollider> (); obj.GetComponent<MeshFilter>().sharedMesh = mesh; obj.GetComponent<MeshFilter>().sharedMesh.name = name; obj.GetComponent<MeshCollider> ().sharedMesh = mesh; // Assetへ保存 UnityEditor.PrefabUtility.CreatePrefab ("Assets/Resources/PieceParts/" + name + ".prefab", obj); // これをしないとMeshが保存されない! UnityEditor.AssetDatabase.SaveAssets ();
GameObjectの拡張子は「.prefab」で良さそう。
最後行SaveAssetsは超重要らしい。
Asset内に保存したPrefab(GameObject)のインスタンスを取得
Resourcesフォルダ以下にあるPrefabのGameObjectを取得できます。
// 上で保存したGameObjectを取得(Prefabのインスタンス) var prefabObj = (GameObject)Resources.Load( "PieceParts/" + name );
Resourcesフォルダでないとダメなんだろうか。 → http://docs.unity3d.com/ScriptReference/Resources.Load.html
Prefabのインスタンスを取得出来たほうが都合が良い時があるはず。
フォルダを作成する
/// <summary> /// フルパスのファイルを名を指定し、フォルダが存在しなければ作成します。 /// </summary> /// <returns><c>true</c>, if without folder was created, <c>false</c> otherwise.</returns> /// <param name="filename">フルパスのファイル名.</param> public static bool CreateWithoutFolder( string filename ) { var directory = Path.GetDirectoryName(filename); var values = directory.Split( new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries ); var checkFolder = string.Empty; foreach( var folder in values ) { var baseFolder = checkFolder; checkFolder += folder; if (System.IO.Directory.Exists(checkFolder + "/") != true) { UnityEditor.AssetDatabase.CreateFolder( baseFolder, folder ); } checkFolder += "/"; } return true; }
UnityEditor.PrefabUtility.CreatePrefabはフォルダが無いとエラーを返してしまうので、事前にフォルダを作っておく必要があります。
Editor専用なので#ifで囲む
これらのコードは実行ファイルをビルドするときにエラーになるので#if #endifで囲む。
#if UNITY_EDITOR ... 上記のソースコード #endif
上記のコードはパズルのピースを作成するのに使用しました。
4角形1種類、3角形4種類の計5種類のGameObjectを生成した時。
ペイントツールでピースの絵を作成して、2Dゲームにしても良かったと思うですが3Dでやりたかったんだ。