強火で進め

このブログではプログラム関連の記事を中心に書いてます。

自前作成した mesh は AssetDatabase に保存しないと Prefab 化した時に mesh データが失われる

こちらのエントリーで自前でPanelオブジェクトを作成するサンプルを紹介しました。

しかし、こちらのコメント欄にまささんよりプレハブ化するとmeshが無くなってしまうとのご指摘を頂きました。実際に試してみると確かに無くなってしまいました。

調査した所、本来はこちらのサイトに書かれてるコードの様に AssetDatabase への保存が必要な様です。

CreatePlane - Unify Community Wiki
http://wiki.unity3d.com/index.php?title=CreatePlane

こちらを参考に修正したコードがこちら。

【CreatePanel.cs】

using UnityEditor;
using UnityEngine;
using System.Collections;

public class CreatePanel : MonoBehaviour
{

	[MenuItem ("Create Object/Panel")]
	static void Create ()
	{
		GameObject newGameobject = new GameObject ("CustomPanel");
		
		MeshRenderer meshRenderer = newGameobject.AddComponent<MeshRenderer> ();
		meshRenderer.material = new Material (Shader.Find ("Diffuse"));
		//meshRenderer.sharedMaterial.mainTexture = 
		//	(Texture)AssetDatabase.LoadAssetAtPath("Assets/test.png", typeof(Texture2D));
			
		MeshFilter meshFilter = newGameobject.AddComponent<MeshFilter> ();
		
		meshFilter.mesh = new Mesh ();
		Mesh mesh = meshFilter.sharedMesh;
		mesh.name = "CustomPanel";
		
		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,
			2, 3, 0
		};
		mesh.uv = new Vector2[]{
			new Vector2 (0.0f, 1.0f),
			new Vector2 (1.0f, 1.0f),
			new Vector2 (1.0f, 0.0f),
			new Vector2 (0.0f, 0.0f)
		};
		
		mesh.RecalculateNormals ();	// 法線の再計算
		mesh.RecalculateBounds ();	// バウンディングボリュームの再計算
		mesh.Optimize ();
		
		AssetDatabase.CreateAsset (mesh, "Assets/" + mesh.name + ".asset");
		AssetDatabase.SaveAssets ();
	}
}

最後に追加した以下の記述で AssetDatabase に Asset の作成と保存を行なっています。

		AssetDatabase.CreateAsset (mesh, "Assets/" + mesh.name + ".asset");
		AssetDatabase.SaveAssets ();

後、こちらのエントリーも同様な問題を持っていたので修正版を書いて置きます。

Unityに三角ポリゴン2つのPanelを作成する機能を追加する - 強火で進め
http://d.hatena.ne.jp/nakamura001/20120818/1345304258

【WizardCreatePanel.cs】

using UnityEditor;
using UnityEngine;
using System.Collections;

public enum NormalDirction
{
	x_plus,
	x_minus,
	y_plus,
	y_minus,
	z_plus,
	z_minus,
};

public class WizardCreatePanel : ScriptableWizard
{
	
	public Texture2D texture;
	public NormalDirction normalDirction = NormalDirction.z_minus;

	[MenuItem ("Create Object/Panel")]
	static void Init ()
	{
		ScriptableWizard.DisplayWizard<WizardCreatePanel> ("Create Custom Panel", "Create");
	}
	
	void OnWizardCreate ()
	{
		CreatePanel ();
	}
	
	void CreatePanel ()
	{
		GameObject newGameobject = new GameObject ("CustomPanel");
		
		MeshRenderer meshRenderer = newGameobject.AddComponent<MeshRenderer> ();
		meshRenderer.material = new Material (Shader.Find ("Diffuse"));
		if (texture != null) {
			meshRenderer.sharedMaterial.mainTexture = texture;
		}
			
		MeshFilter meshFilter = newGameobject.AddComponent<MeshFilter> ();
		
		meshFilter.mesh = new Mesh ();
		Mesh mesh = meshFilter.sharedMesh;
		mesh.name = "CustomPanel";
		
		Vector3[] 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)
		};
		Quaternion quateRot = Quaternion.Euler (0.0f, 0.0f, 0.0f);
		switch (normalDirction) {
		case NormalDirction.x_plus:
			quateRot = Quaternion.Euler (0.0f, 270.0f, 0.0f);
			break;
		case NormalDirction.x_minus:
			quateRot = Quaternion.Euler (0.0f, 90.0f, 0.0f);
			break;
		case NormalDirction.y_plus:
			quateRot = Quaternion.Euler (90.0f, 0.0f, 0.0f);
			break;
		case NormalDirction.y_minus:
			quateRot = Quaternion.Euler (270.0f, 0.0f, 0.0f);
			break;
		case NormalDirction.z_plus:
			quateRot = Quaternion.Euler (0.0f, 180.0f, 0.0f);
			break;
		case NormalDirction.z_minus:
			quateRot = Quaternion.Euler (0.0f, 0.0f, 0.0f);
			break;
		}
		for (int v=0; v<vertices.Length; v++) {
			vertices [v] = quateRot * vertices [v];
		}
		mesh.vertices = vertices;
		mesh.triangles = new int[]{
			0, 1, 2,
			2, 3, 0
		};
		mesh.uv = new Vector2[]{
			new Vector2 (0.0f, 1.0f),
			new Vector2 (1.0f, 1.0f),
			new Vector2 (1.0f, 0.0f),
			new Vector2 (0.0f, 0.0f)
		};
		
		mesh.RecalculateNormals ();
		mesh.RecalculateBounds ();
		mesh.Optimize ();

		AssetDatabase.CreateAsset (mesh, "Assets/" + mesh.name + "_" + normalDirction.ToString() + ".asset");
		AssetDatabase.SaveAssets ();
	}
}