- Home /
Creating new GameObject for Procedural Mesh has wrong Transform.position
Hey all, So Ive read that the anchor point of an object's transform cannot be directly changed, but Im looking for a workaround for a project of mine.
Basically Im creating a new empty game object called "Tile" in a loop. I then assign the mesh vertices and triangles etc and end up with exactly what I wanted, except for the fact that each one of the created Tile objects has its transform.position at the origin. I tried setting the position directly after creating the new GameObject before assigning the mesh vertices and tris but this distorted my result. I have the center points of each tile mesh already stored in a list and I use that point to generate the mesh. Is there any way of telling this new gameobject that its transform's position should be at this center point without translating the mesh away from its desired position?
Heres some of my code and some screen shots.
The Vector3 vertices[i] represents the desired center point of the game objects transform.position.
Result when I DO NOT set the GameObject's transform.position to vertices[i]
Result when I DO set the GameObject's transform.position to vertices[i]
private void generateSubMeshes(List<Vector3> centers, List<Vector3> vertices){
//Generate the hex/pent mesh for each vertex in the main mesh by associating it to its surrounding triangle centers
for(int i = 0; i < vertices.Count; i++){
GameObject tile = new GameObject ("Tile");
Mesh submesh = new Mesh ();
//tile.transform.position = vertices[i];
List<Vector3> submeshVs = new List<Vector3>();
//Some stuff happens here to generate the mesh
tile.AddComponent<MeshFilter> ();
tile.AddComponent<MeshRenderer>().material.color = Color.white;
tile.GetComponent<MeshFilter>().mesh = submesh;
submesh.RecalculateBounds();
submesh.RecalculateNormals();
tile.AddComponent<Tile>();
Answer by Ozy51 · Apr 23, 2015 at 09:08 PM
Hope it's not to late for an answer but if you give each vertice a position it will be assigned as if you are on the origin. And if you apply a transformation to that Tile(in your case) you are transforming that origin, and the vertices have a position according to that as i said before, that will make that separation that you see in the second screenshot. So as a solution you may have to do the math and take from the vertices position what you are adding on the transform. It's actually confusing to explain without code, but hope it helps.
Answer by GDiSalvo · May 22, 2020 at 12:34 AM
Hi @Ozy51 (and @ZAxisTechnology )! It's waaaay too late for a reply to your answer, but this is the only post I've found with the same problem I have and with an answer that helped me! I was thinking on making a new post for this topic but first I will try to find if you have more information about this issue.
I have an example simpler than the one from the OP. I'm making a procedural grid of quads (so, it's a plane with square tiles, not a sphere of hexagons). I post my code below to create a single tile: I create a quad and assign it to a GO, this is simple and works fine with all the tiles in the right position but all the GOs transform.position are at the zero position. The problem is that I need to add a dynamic destroy of this objects when they are far from the player, and I don't have a tile transform.position to compare!
I've added a vertices' repositioning as you mentioned and now I have the correct positioning and the transform.position correct values, but it's an ugly solution! ?? Maybe you or anyone know about a better option. Thank you!
public void CreateQuadMesh(GameObject segmentPrefab, Vector3 pointX0Z0, Vector3 pointX1Z0, Vector3 pointX0Z1, Vector3 pointX1Z1)
{
Vector3[] vertices = new Vector3[4] { pointX0Z0, pointX1Z0, pointX0Z1, pointX1Z1 };
mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = tris;
mesh.RecalculateNormals();
mesh.uv = uv;
tempQuad = Instantiate(segmentPrefab, Vector3.zero, Quaternion.identity);
tempQuad.GetComponent<MeshFilter>().mesh = mesh;
// Required added steps to keep position in transform:
// - doing nothing = right position but transform.position zero
// - assign transform.position only = GO with right transform.position but mesh moves position
tempQuad.transform.position = pointX0Z0;
vertices[0] = pointX0Z0 - pointX0Z0;
vertices[1] = pointX1Z0 - pointX0Z0;
vertices[2] = pointX0Z1 - pointX0Z0;
vertices[3] = pointX1Z1 - pointX0Z0;
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = tris;
mesh.RecalculateNormals();
mesh.uv = uv; // this maybe is the only one not required
//
tempQuad.GetComponent<MeshCollider>().sharedMesh = mesh;
}