- Home /
Problem drawing a mesh with Graphics.DrawMeshNow
Hello all. I'm making a block based building system for a mech fighting game but I seem to have hit a snag. You see I am trying to take all the blocks the player makes and assemble them into a single mesh to save memory, the problem is that when I try to draw this mesh I get an error that says "size
var VertexMasterArray = new Array();
var NormalMasterArray = new Array();
var TriangleMasterArray = new Array();
function Update(){
if (Input.GetKeyDown (KeyCode.V)) {
var BigMesh : Mesh = new Mesh();
var VBlocks = GameObject.FindGameObjectsWithTag("Block");
VertexMasterArray.Clear();
NormalMasterArray.Clear();
TriangleMasterArray.Clear();
BigMesh.Clear();
for (var i = 0; i < VBlocks.length; i++) {
var mesh : Mesh = VBlocks[i].GetComponent(MeshFilter).mesh;
var Vvertices : Vector3[] = mesh.vertices;
for(var i2=0; i2<Vvertices.length;i2++){
VertexMasterArray.Push(Vvertices[i2]+VBlocks[i].transform.position);
}
}
BigMesh.vertices = VertexMasterArray;
for (i = 0; i < VBlocks.length; i++) {
mesh = VBlocks[i].GetComponent(MeshFilter).mesh;
var Vnormals : Vector3[] = mesh.normals;
for(i2=0; i2<Vnormals.length;i2++){
NormalMasterArray.Push(Vnormals[i2]);
}
}
BigMesh.normals = NormalMasterArray;
for (i = 0; i< VBlocks.length; i++) {
mesh = VBlocks[i].GetComponent(MeshFilter).mesh;
var VTriangles : int[] = mesh.triangles;
for(i2=0; i2<VTriangles.length;i2++){
TriangleMasterArray.Push(VTriangles[i2]+24*i);
}
}
BigMesh.triangles = TriangleMasterArray;
BigMesh.RecalculateNormals();
BigMesh.RecalculateBounds();
BigMesh.Optimize();
VertexMasterArray.Clear();
VertexMasterArray = BigMesh.vertices;
NormalMasterArray.Clear();
NormalMasterArray = BigMesh.normals;
TriangleMasterArray.Clear();
TriangleMasterArray = BigMesh.triangles;
print("Mesh Built");
}
if (Input.GetKey(KeyCode.C)) {
var rotation = Quaternion.identity;
// Assign a rotation 30 degrees around the y axis
rotation.eulerAngles = Vector3(0, 0, 0);
var BigMesh2 : Mesh = new Mesh();
BigMesh2.vertices = VertexMasterArray;
BigMesh2.triangles = TriangleMasterArray;
BigMesh2.normals = NormalMasterArray;
BigMesh2.RecalculateNormals();
BigMesh2.RecalculateBounds();
BigMesh2.Optimize();
Graphics.DrawMeshNow(BigMesh2,Vector3(0,20,0),rotation);
}
}
I'm pretty much at a loss as how to proceed next.
Answer by Bunny83 · Jul 19, 2011 at 07:06 AM
To sum up some things that should kept in mind:
Vertices of a Mesh are in local space. To transform the vertices into world space you need to use Transform.TransformPoint so the position, rotation and scale is used to transform the point.
Same thing for normals but since they are directions you have to use Transform.TransformDirection so only the rotation (and scale i think) is (are) used.
Your whole thing will only work when each block-mesh have exactly 24 vertices (i guess you use unity cubes? ;) )
Not sure if you need them but you don't transfer the UVs so you can't use textures on your mesh
Your whole mesh creation should be a seperate function so you can call it once in start to make sure there is always something to render when you press C.
The 3 VBlock loops should be combined into one, that reduces the GetComponent accesses by factor 3.
Why are you re-creating the already built and optimised mesh each time you want to draw it? Just save your bigmesh outside instead of your 3 (slow)arrays.
Using DrawMeshNow in Update is pretty much useless since right after Update the camera will clear the buffers. You should use it in OnPostRender to draw it after all cameras has been drawn.
Finally just to have it mentioned: You need Unity pro to use the Graphics class
Thanks for answering my question, I will try and respond to your points now.
1) Oh that's nice to know. Doing that ins$$anonymous$$d of "Vvertices[i2]+VBlocks[i].transform.position" is way easier to keep track of. Especially considering all the blocks in the editor could be different sizes.
2)Silly me, I took one look at it and thought that when it said normals were a Vector3 that it was a point in space, not a direction. Thanks for pointing that out!
3)That is correct, I was only using unity cubes.
4)Yeah I probably would have noticed that if it actually drew. :P
5)This isn't really the final code, I was just throwing this together to see if I could make it work. If I got something to work then these two processes would actually take place in separate scenes by sending the mesh data to a control object that is consistent between levels.
6)Yeah optimization wasn't foremost in my $$anonymous$$d when I made this, I was mostly just trying to get it to RUN. But yeah, something so simple and easy to fix and it is kind of embarrassing I overlooked it. >.>
7)I didn't think Big$$anonymous$$esh would transfer between the functions so I made a second one...I guess I didn't even try it. :|
8)Oh wow, thanks. As I've probably made obvious I'm really new to Unity (I asked this question on my second day using it). I wasn't even aware PostUpdate existed. Perhaps I should read into the script reference even more then I already am. ;)
9)Well since I don't have fifteen-hundred dollars lying around...I guess I will have to resort to just using the mesh for a physics collider.
Thanks again for all your help!
Looking at what I have done so far though. $$anonymous$$esh.Combine$$anonymous$$eshes would serve the same purpose. Really wish I knew about that before writing the code. :\