- Home /
Alter Meshes in Editor by Script without warning
Hi
I want to vertex color some of my meshes instead of the textures to produce less texture copies. This requires me to call mesh.colors32 and therefore to access the mesh. Since I want to see what I am doing, I use [ExecuteInEditMode] to make this work when in Editor mode. And it does.
However, when I access MeshFilter.mesh, Unity will complain like this:
Instantiating mesh due to calling MeshFilter.mesh during edit mode. This will leak meshes. Please use MeshFilter.sharedMesh instead.
UnityEngine.MeshFilter:get_mesh()
So when I call MeshFilter.mesh, I actually produce a copy that will be used from there on. Which is fine I guess, because I want to color each instance individually and not all of them at the same time. If I use MeshFilter.sharedMesh, as proposed, I do actually end up changing the colors of all the meshes at the same time, which I do not want.
From searching, I know that questions like this one have been asked in the past. The answers boiled down to "yeah that sucks, but it is not severe so use #pragma warning disable xxxx". This seemed to work in the past, but when I look at my Console there are no warning numbers anymore that I could disable.
So my question is if there is now a better, error-free way to change individual mesh colors? And if not, how can I disable the associated error? It will become nearly impossible to work with the editor if it throws the same 100 errors every time the editor view loads after playtesting.
Since it is short and so you can see what I am doing, I am also posting the code. The error comes from the Awake method.
[ExecuteInEditMode]
public class vertexColorAdjustInEditor : MonoBehaviour
{
public Color32 color = new Color32 (255, 255, 255, 255);
private Color32 savedColor = new Color32 (255, 255, 255, 255);
private Mesh mesh;
void Awake ()
{
mesh = (GetComponent (typeof(MeshFilter))as MeshFilter).mesh;
}
// Update is called once per frame
void Update ()
{
if (!(color.Equals (savedColor))) {
savedColor = color;
Color32[] newColors = new Color32 [mesh.vertices.Length];
for (int i = 0; i < newColors.Length; i++) {
newColors [i] = savedColor;
}
mesh.colors32 = newColors;
}
}
}
Did you find an answer to this? I am having the same issue. shared$$anonymous$$esh, no errors, but wrong output. $$anonymous$$esh, errors, but correct output.
Answer by Robert-Castle · Aug 21, 2013 at 09:38 AM
Ok, had a lightbulb moment. Using your example, this should work:
#if UNITY_EDITOR
//Only do this in the editor
MeshFilter mf = GetComponent<MeshFilter>(); //a better way of getting the meshfilter using Generics
Mesh meshCopy = Mesh.Instantiate(mf.sharedMesh) as Mesh; //make a deep copy
mesh = mf.mesh = meshCopy; //Assign the copy to the meshes
#else
//do this in play mode
mesh = GetComponent<MeshFilter>().mesh;
#endif
it works! instantiating the mesh explicitly gave an end to those pesky warnings :)
I've tried many variations of this and the mesh leaking errors still show up. I will be honest, I thought I understood what I had to do differently based on the example above but looks like I really didn't... Why is it that the example by Robert should fix the issue and where would his code fit into $$anonymous$$ultiplayer's original code?
Answer by Devilwhale · Apr 25, 2017 at 05:07 AM
I have this working in 5.4 as the following.
-Works even after unity restart or scene is saved. -Objects track the original, and create a instance as needed from that org. -Works so far with out any errors.
Thanks
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
public class vertexColorAdjustInEditor : MonoBehaviour
{
public Color32 color = new Color32(255, 255, 255, 255);
private Mesh mesh;
public Mesh org;
private MeshFilter mf;
private bool isenabled = false;
void OnEnable()
{
if (org != null)
{
load();
}
}
void load()
{
mf = transform.GetComponent<MeshFilter>();
mesh = Mesh.Instantiate(org) as Mesh;
mf.sharedMesh = mesh;
updatecolor();
isenabled = true;
}
void OnValidate()
{
updatecolor();
}
void updatecolor()
{
if (isenabled)
{
Color32[] newColors = new Color32[mesh.vertices.Length];
for (int i = 0; i < newColors.Length; i++)
{
newColors[i] = color;
}
mesh.colors32 = newColors;
}
else if ( mesh == null)
{
load();
}
}
void OnDisable()
{
if (isenabled)
{
mf.sharedMesh = org;
mf.name = org.name;
}
}
}
Your answer
Follow this Question
Related Questions
Pressing play Causes Re-instancing of material (Editor) 1 Answer
Mesh memory leak error 0 Answers
Colored Voxel Meshs 2 Answers
Changing Mesh Vertex Colors in editor 0 Answers
Changing the color and transparency of a 3D model at runtime 1 Answer