- Home /
Make procedural mesh show in Scene Editor, not just in "Play" mode
Hi there,
I have a Mesh that I generate in code. It shows up properly when I'm in "play" mode, but nothing at all appears in the Scene when I'm trying to edit it. I'm assuming it's possible to show what the Mesh looks like after a Start() call in the Scene Editor? It's kind of frustrating to have to keep "running" the scene to see what it looks like.
I've checked out similar questions, but all the answers seem to involve Mesh Colliders, and I don't have one. I've got a MeshFilter, my script to generate the vertices, triangles, uvs, normals, etc., and then the MeshRenderer. Again, it shows up properly when I am in Play mode, but not in the Scene Editor.
Thanks for any help!
Answer by AlucardJay · Mar 14, 2013 at 06:12 AM
I don't use the evil ExecuteInEditMode, but instead have a ContextMenu function at the top of the script. With this you can call functions on the script in edit mode. While this is not a wysiwyg approach, by simply making changes then running the ContextMenu reassigns the values and the mesh is updated.
Just an alternative to think about : http://docs.unity3d.com/Documentation/ScriptReference/ContextMenu.html
#pragma strict
@script RequireComponent(MeshFilter, MeshRenderer)
#if UNITY_EDITOR
// instead of @script ExecuteInEditMode()
@ContextMenu("Construct sQuad")
function ConstructQuad()
{
Debug.Log("Constructing sQuad from ContextMenu");
ConstructMesh();
}
function ConstructMesh()
{
Startup();
}
#endif
public class SQuad extends MonoBehaviour
{
private var mesh : Mesh;
// other mesh variables here
function Start()
{
Startup();
}
function Startup()
{
if ( !mesh )
{
//GetComponent(MeshFilter).mesh = mesh = new Mesh();
mesh = new Mesh();
GetComponent(MeshFilter).mesh = mesh;
mesh.name = "sQuadMesh";
}
Construct();
}
function Construct()
{
mesh.Clear();
verts = new Vector3[8];
// all your mesh calculations here
mesh.vertices = verts;
mesh.uv = uvs;
mesh.triangles = tris;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
}
}
Interesting, but how do you call the "Startup" function that is inside the class?
Answer by rutter · May 03, 2012 at 05:53 AM
It won't behave exactly the same as during gameplay, but you might try giving your behavior script the ExecuteInEditMode attribute.
As an alternative, you could try writing a custom inspector that uses OnSceneGUI(). I find that's a little less intuitive, but might be easier to work with depending on what exactly you're trying to do.
@rutter Interesting -- so what is it about, say, a cylinder that allows it to appear in the scene editor whereas my procedural mesh does not? I could easily change both during runtime, but one of them shows up as expected and the other is a blank. Are cylinders, cubes, etc. all marked as ExecuteInEdit$$anonymous$$ode?
That's an insightful question, but unfortunately one I can't answer off the top of my head. ;) Probably something to do with some quirk of interaction between a mesh and its renderer?
Answer by GADoyle · Mar 14, 2013 at 05:40 AM
Having a similar problem. I have a procedurally generated mesh that I wish to display in the editor. I am using ExectueInEditMode, and the mesh is being passed correctly to the mesh filter. When run in the game, the mesh displays successfully.
However when Im in the editor it does not.
One thing I have noticed is that when previewing the mesh in the editor is says that it has the correct number of vertices, but NO TRIANGLES.
Both values are being assigned in the code in both play and editor mode. I am still trying to figure out the difference as well.
Have you found any answer?
and do you get the same issue when previewing the mesh?
Does anyone know why the triangles would not update the same way the vertices do in editor mode.
edit
Also worth noting, I do not use the triangles attribute to assign the triangle array. Instead I use the SetTriangles method to assign them to three separate submeshes. While in the editor, the submeshCount is still zero, after this assignment. I still can not figure out why though.
Answer by Yamin-Nather · Jan 10, 2016 at 07:23 AM
you could add the [ExecuteInEditMode] attribute but it doesnt work exactly same like in runtime. for example, update runs only when there is a particular change and not every frame. But there's a way around this. Make a OnEnable() function and OnDisable() function and type in the code below. void OnEnable() { EditorApplication.update += Update; } void OnDisable() { EditorApplication.update -= Update; }
Adding these lines makes the update function run every frame.
Answer by BorisOkunskiy · May 21, 2020 at 08:23 AM
Something along the lines of this, combined with [ExecuteInEditMode]
, works for me:
public Mesh mesh;
void Update() {
#if UNITY_EDITOR
if (!Application.isPlaying) {
bool needsUpdate = mesh == null ||
UnityEditor.Selection.activeGameObject == gameObject;
if (needsUpdate) {
GenerateMesh();
var mf = GetComponent<MeshFilter>();
mf.sharedMesh = mesh;
}
}
#endif
}