Procedurally created mesh appearing offset from it's vert locations.

Hey all.

I’m building a mesh procedurally at runtime and it works fine. but the visible mesh and the mesh collider are located offset from the location of the vertices.

To check this, I ran a for loop to grab all the vertices in the mesh and instantiated a small cube at each location.

Here’s a picture showing an example:
Image and video hosting by TinyPic

In this, the cube at the bottom right is being used as an indicator of where world origin is.

As you can see, the mesh is in one location, while the verts (represented by the smaller cubes) is in another.
The gameObject the mesh is a part of is created at the mouse position in world space using a ray (which works fine for placing primitives, so it doesn’t appear to be the culprit).

The further away the mesh is created from world origin, the larger the offset.
As you may have deduced from the image, the direction of the offset is also related to the world origin, always being in the opposite direction.

This here is the relevant bit of code for creating the mesh. New sets of points are added and calculated as you move the mouse around (with the button held down), creating a wall as you go.

    IEnumerator StartWall()
    {
        makeWall = true;
        oldMousePosition = Input.mousePosition;
        wallNumber += 1;
        bool startedMoving = false;
        List<Vector3> currentPoints = new List<Vector3>();
        List<Vector3> allPoints     = new List<Vector3>();
        List<int> currentTris   = new List<int>();
        List<int> allTris       = new List<int>();
        int segments = 0;

        ////INITILIZATION////
        #region Initializing The Wall Object

        mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(mouseRay, out mouseHit, 500f, floorMask))
        {
            startPoint = mouseHit.point;
        }

        Vector3 previousPoint           = startPoint;
        Vector3 nextPoint               = startPoint;

        Transform newWall               = new GameObject("Wall # " + wallNumber).transform;
        newWall.position = startPoint;
        newWall.parent = wallContainer;
        walls.Add(newWall);

        MeshFilter  newWallMeshFilter   = newWall.gameObject.AddComponent<MeshFilter>();
        MeshRenderer newWallRenderer    = newWall.gameObject.AddComponent<MeshRenderer>();
        MeshCollider newWallCollider    = newWall.gameObject.AddComponent<MeshCollider>();
        newWallRenderer.material = shinyWhite;
        Mesh newWallMesh         = new Mesh();
        newWallMesh.name 		 = "wall_mesh " + wallNumber;
        newWallMeshFilter.mesh   = newWallMesh;
        newWallCollider.sharedMesh = newWallMesh;

        #endregion

        while (makeWall)
        {
            if (mousePosition != oldMousePosition)
            {
                startedMoving = true;
                //Mesh Creation
                mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
                if(Physics.Raycast(mouseRay, out mouseHit, 500f, floorMask))
                {
                    if(Vector3.Distance(mouseHit.point, previousPoint) > smoothness)
                    {
                        nextPoint = mouseHit.point;

                        Instantiate(cubePrimitive, nextPoint, Quaternion.identity);

                        Vector3 direction = (nextPoint - previousPoint).normalized;
                        Vector3 up = new Vector3(0, 1, 0).normalized;
                        Vector3 right = Vector3.Cross(direction, up);

                        //Front
                        Vector3 point0 = previousPoint;
                        Vector3 point1 = nextPoint;
                        Vector3 point2 = new Vector3(nextPoint.x, nextPoint.y + wallHeight, nextPoint.z);
                        Vector3 point3 = new Vector3(previousPoint.x, previousPoint.y + wallHeight, previousPoint.z);
                        //Top
                        Vector3 point4 = new Vector3(previousPoint.x, previousPoint.y + wallHeight, previousPoint.z);
                        Vector3 point5 = new Vector3(nextPoint.x, nextPoint.y + wallHeight, nextPoint.z);
                        Vector3 point6 = new Vector3(nextPoint.x, nextPoint.y + wallHeight, nextPoint.z) + (right * wallWidth);
                        Vector3 point7;
                        if (allPoints.Count < 1)
                        {
                            point7 = new Vector3(previousPoint.x, previousPoint.y + wallHeight, previousPoint.z) + (right * wallWidth);
                        }
                        else
                        {
                            point7 = allPoints[allPoints.Count - 6];
                        }
                        //Back
                        Vector3 point8 = new Vector3(point6.x, point6.y - wallHeight, point6.z);
                        Vector3 point9 = new Vector3(point7.x, point7.y - wallHeight, point7.z);
                        Vector3 point10 = point7;
                        Vector3 point11 = point6;

						currentPoints = new List<Vector3>()
						{
							//Front
							point0, point1, point2, point3,
							//Top
							point4, point5, point6, point7,
							//Back
							point8, point9, point10, point11,
						};
                        allPoints.AddRange(currentPoints);
                        allPointsTest = allPoints;
                        newWallMesh.vertices = allPoints.ToArray();

                        segments++;

						currentTris = new List<int>()
						{
							0 + ((segments - 1) * 12), 2  + ((segments - 1) * 12), 1  + ((segments - 1) * 12),
							0 + ((segments - 1) * 12), 3  + ((segments - 1) * 12), 2  + ((segments - 1) * 12),
							4 + ((segments - 1) * 12), 6  + ((segments - 1) * 12), 5  + ((segments - 1) * 12),
							4 + ((segments - 1) * 12), 7  + ((segments - 1) * 12), 6  + ((segments - 1) * 12),
							8 + ((segments - 1) * 12), 10 + ((segments - 1) * 12), 9  + ((segments - 1) * 12),
							8 + ((segments - 1) * 12), 11 + ((segments - 1) * 12), 10 + ((segments - 1) * 12),
						};
							
                        allTris.AddRange(currentTris);
                        newWallMesh.triangles = allTris.ToArray();

                        newWallMesh.RecalculateNormals();
                        newWallMesh.RecalculateBounds();
                        newWallMesh.Optimize();
                        newWallCollider.sharedMesh = null;
                        newWallCollider.sharedMesh = newWallMesh;

                        previousPoint = nextPoint;  //Assigns the current point(nextPoint) to the previousPoint variable for use in the next iteration.
                    }
                }
                oldMousePosition = mousePosition;
            }

Are you taking the transform into account?

The mesh stores the position of each vertex in local space while the displayed position adds the transform information on top of it. So a simple case would be a vertex with coordinates (0, 0, 0) in a transform where the position is (1, 0, 0) would display the vertex at (1, 0, 0).

To make cubes where each vertex is displayed you’re going to have to line up their world coordinates. One way to do so would be to replace

Instantiate(cubePrimitive, nextPoint, Quaternion.identity);

with

Instantiate(cubePrimitive, transform.TransformPoint(nextPoint), Quaternion.identity)