I’m using floats because it will need to be in the final version, as it is only moved up something around 0.125, that is just so I can see the change. And Unity won’t let me just use +5f.
Err… no? The typical “i++” used in for loops is actually shorthand for “i += 1;” or “i = i + 1;”. There must be an assignment. If you just use “i + 5” the calculated value won’t be assigned to anything, which would create an infinite loop.
Also, using floats is fine as long as your code logic takes floating point imprecision into account. It’ unclear if this code does or not, but that’s unlikely to cause the crash based on what’s shown.
Tyler, does “mesh2.vertices = mesh.vertices;” assign a copy of the array from the original mesh, or does it assign a reference to the original? I expect it does the latter, and based on that I think there’s a logic error in your code. Assuming that the latter case is correct, it could potentially be causing your crash in one of two ways:
CombineMeshes(…) might be dereferencing the arrays from the meshes in the given array, finding that they’re actually references to the same array, and hitting an internal error as a result. The fix should be pretty simple, just copy the contents of the array instead of the reference to the array. If this turns out to be the case I’d suggest filing a bug report, as it’d be useful for Unity to give an error in that case rather than charging forward and committing suicide.
Something related similar happening in your own following code, because you think you’re playing with multiple arrays where you’re actually playing with multiple references to the same array. The fix here would be based on what you’re trying to do.
This is of course all based on the assumption that mesh.vertices gives you a reference rather than a copy, and that assigning to it assigns a reference rather than making a copy. Without having checked, though, that’s the behaviour I would expect in both cases.
Why don’t you just start with the lines and uncomment everything else. If it works, go on, uncomment the next. Like the you can say, this line causes the crash, but I don’t know why…
I expect that the mesh combines doesn’t like mesh2, because it has only vertices, no triangles, uvs, … .
“creates a copy of the vertex data”. You should probably change your code to look like that example; you need to create a temp variable “vertices”, and then modify all of them there, and then do mesh2.vertices = vertices. Currently I don’t think your loop will work, because each time you do mesh2.vertices.y += i, it's creating a brand new copy of mesh2.vertices, changing only that copy, and then not assigning that back to the original. So at the end of your loop, you haven't actually changed any of the vertices in the original array. I think in your code currently, mesh and mesh2 are going to be identical at the point they're combined because the array is never set again in mesh2.
My whole point with the float thing is that none of the code written relied on i being a float because the increment was a whole number and adding an int to a float works just fine.
That’s because you changed the increment from 5f to 0.5f. It does look weird to see a float used in the increment of a for loop but that’s legal.
Also:
for(float i = -10f; i < 20f; i += 0.5f)
{
mesh2 = new Mesh();
…
}// for
should mean that mesh2 is destroyed when the for loop completes.
combine[1].mesh = mesh2; // mesh2 destroyed after for loop means points to null after loop is done
I can’t remember the C# API rules with regard to operator overloading of = and using for class assignment and without knowing the class API I’d copy the contents of mesh2 into combine[1].mesh rather than do an address assignment (which I know is the behavior you’d get in C). Oh, how I like memcpy and all the straightforward rules and API of C.
That’d be the case if mesh2 was declared within the loop, but it is not, it’s assigned. It’s declared outside of the loop, so it’s still in scope after the loop is complete.
Sorry, thanks. That’s correct. One of the disadvantages of knowing several languages and using them all from time to time is that implicit declaration is allowed in some languages but not others but had I looked a bit further up the page I would have seen the declaration.
Please do me the favor of clarifying this in C# specifically:
Does C# overload ‘=’ on those two assignments do a ‘new’ so the assignment works or is combine[ ] just an array of addresses that the compiler/runtime engine extends with each new indexed address reference (e.g. [1]) and is then used to look up mesh and mesh2 indirectly?
e.g.
combineInstance[2 ] combine;
works in C#
but
combineInstance combine;
doesn’t as that almost looks like a JavaScript/UnityScript style declaration. In C# that would work at array position 0 but not array position 1.
If this is true the C# compiler needs to be stricter to catch that with a warning. Of combineInstance combine; combineInstance[0] combine; and combineInstance combine; → combineInstance combine; should generate a warning. When would that be needed? When reading in array size at runtime I guess.
C# almost certainly does not, but it’s quite possible that Unity overloads the operator. As someone linked above, the documentation makes it sound like it does, but Tyler’s experience implies the opposite since changes applied to the new variable still show up when accessing values from the original.
The docs are a tad ambiguous there, though. For instance, they may return a copy as they say, but when called multiple times it may return references to the same copy, which could potentially lead to the issue we’re seeing here. However, the issue is still there even now that Tyler is using a cloned array…
@Tyler: What are you trying to achieve here? It seems like you’re trying to make a mesh which is a copy of multiple instances of an existing mesh in a row. Is that the case? No promises (I’m a busy guy with a job and just now releasing a game on the side) but I might try and whip something up, purely because this is really strange and I’m interested in figuring out what’s up.
OK, sorry. I actually carefully read every post and your problem I think can be solved if you initialize
combine = new combineInstance[2];
on original declaration or in the Update function if you were to change the definition to be global or class wide. At least I’ve had a similar experience in the past. It may be enough to move the declaration before both of the for loops begin which is where you declared it anyway. I do know that moving a new before both my for loops and at the beginning of my function rather than between for loops (in this case in an Update function ) stopped a crash similar to what you might be experiencing.
In my experience it was almost like you need a lag to give objects a chance to finish initializing with new.