- Home /
Modifying mesh vertices in an editor script
I'm wondering if it's possible to change the position of mesh vertices in the editor. Here's my current code:
function OnSceneGUI() { var mesh : Mesh = target.GetComponent(MeshFilter).mesh; var verts = mesh.vertices;
for (var v in verts)
v = v + Handles.PositionHandle( target.transform.position + v,
Quaternion.identity );
mesh.vertices = verts;
}
Unity complains: "Instantiating mesh due to calling MeshFilter.mesh during edit mode. This will leak meshes. Please use MeshFilter.sharedMesh instead." But using sharedMesh wouldn't make a lot of sense, either.
http://forum.unity3d.com/threads/226406-Dynamic-$$anonymous$$esh-Vertex-Selection-for-ingame-or-editor-modification Here is a more pro solution it makes it very easy and also makes u control the indices alone ins$$anonymous$$d of the vertices which u can find more than 3 in the same position but I can still move them
Answer by Eric5h5 · Apr 13, 2010 at 07:58 AM
Actually you do have to do what Unity says and use sharedMesh. Otherwise, as it says, you'd leak meshes since they would only exist in the scene and not the project. Here is an editor script that makes custom planes, which uses sharedMesh. If it needs to be unique you can make a new mesh.
do you know if a box collider can be used for a plane generated using that script? http://answers.unity3d.com/questions/33818/box-collider-on-a-default-plane
You can also give it a meshcollider and feed it the mesh you just created.
AddComponent($$anonymous$$eshCollider).shared$$anonymous$$esh = mesh;
that is the behavior i was trying to recreate. i am just generating mesh for tile map layers. i used to assign the new mesh to meshFilter.mesh and it would then persist in the scene so my changes to the map would last. now i get that error and when i uses shared$$anonymous$$esh my changes to not persist. how can i simulate the old behaviour? thank yousince they would only exist in the scene and not the project
$$anonymous$$eshes aren't serialized inside a scene. When you create a copy or new instance of a mesh it will be gone once you reload the scene or if you restart Unity. If you want a $$anonymous$$esh to persist, it need to be stored as asset in the project. The same holds true for most other assets like $$anonymous$$aterial, Texture2D, AudioClip. All those can be cloned or created from scratch, but if you don't create an actual asset using the AssetDatabase class the object just exists in memory and will leak as soon as you change playmode, load a different scene or if you restart Unity.
Just forget about .mesh / .material inside an editor script. Those can only be used at runtime. If you want to create a clone of an existing object you have to create it manually using Instantiate:
mf.shared$$anonymous$$esh = ($$anonymous$$esh)Instantiate(mf.shared$$anonymous$$esh);
This will create a temporary clone of the original $$anonymous$$esh and assign that to this mesh filter. Again, if that mesh isn't stored as asset in the project and not destroyed with DestroyImmediate when done, it will leak in the editor.
Thank you. I think i was mistaking some ExecuteInEdit$$anonymous$$ode code which rebuilds them for them being saved.
thanks. new url http://wiki.unity3d.com/index.php?title=CreatePlane
Answer by ianjosephfischer · May 05, 2013 at 06:32 AM
Here is my code for accessing/creating meshes at runtime or edit mode.
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public abstract class DynamicMesh : MonoBehaviour
{
#region Protected Abstract Properties
protected abstract Vector3[] vertices { get; }
protected abstract Vector2[] uv { get; }
protected abstract int[] triangles { get; }
#endregion
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#region Protected Properties
protected MeshFilter meshFilter
{
get
{
if(this._meshFilter == null)
{
this._meshFilter = gameObject.GetComponent();
}
return this._meshFilter;
}
}
protected Mesh mesh
{
get
{
if(_mesh != null)
{
return _mesh;
}
else
{
if(meshFilter.sharedMesh == null)
{
Mesh newMesh = new Mesh();
_mesh = meshFilter.sharedMesh = newMesh;
}
else
{
_mesh = meshFilter.sharedMesh;
}
return _mesh;
}
}
}
#endregion
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#region Protected Methods
protected virtual void OnEnable()
{
ReCalculateMesh(true);
}
#endregion
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#region Private Methods
private void ReCalculateMesh(bool allAttributes)
{
if(allAttributes)
{
if(mesh == null)
{
Debug.LogError("Could not access or create a mesh", this);
return;
}
mesh.Clear();
}
mesh.vertices = vertices;
if(allAttributes)
{
mesh.uv = uv;
mesh.triangles = triangles;
}
mesh.RecalculateNormals();
mesh.RecalculateBounds();
}
#endregion
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#region Private Members
private MeshFilter _meshFilter = null;
private Mesh _mesh = null;
#endregion
}
hi ianjosephfischer,please tell how to use your Dynamic$$anonymous$$esh class ? Dynamic$$anonymous$$esh class is abstract,all function is protected,how to use it modifying mesh???
The methods are the important part to focus on. I would not recommend a strait "copy-paste" of this code, but rather to see the methods called and learn the steps in procedurally generating and modifying meshes.