How can i get the LineRenderer.BakeMesh() method to use worldSpace?

Hello, i am using a line renderer to make a laser and i need a collider to detect collisions. I used LineRenderer.BakeMesh() method to generate collider for line renderer but i faced a problem. LineRenderer component is using worldSpace to follow a transform but the BakeMesh method is using localSpace and so the positions of collider and line are mismatching. How can i get the BakeMesh method to use worldSpace instead of localSpace?

Interesting question. I’ve never used that bake. The problem is that most uses of Mesh always treat the mesh as local space: MeshCollider, MeshRenderer, SkinnedMeshRenderer.

Therefore the final output for those above objects is always the mesh PLUS the Transform it is placed upon.

I suppose you could pick a point somewhere near the center of the baked mesh points, then go adjust all the points by that point, or else put the MeshCollider object at the same location where the LR was originally.

As above, meshes and what not live local to their transforms. You can probably use Transform.TransformPoint to convert it from local to world.

I fixed it with changing the all position values of transform to zero relative to worldSpace but i faced another problem now. LineRenderer’s mesh is missing some polygons, i mean it’s supposed to be a normal cylinder but it’s a half cylinder with missing polygons. How can i fix that? Renderer’s mesh is fine but the mesh collider’s not.

The mesh:
8427285--1115529--mesh.PNG

Although the mesh is wrong, it works. I’ll mark this post as resolved.

Is it? I’ve never seen LineRenderer make a cylinder… it would be a strip, plus it’s always a single-sided strip.

If you mean “how do I make it viewable from the other direction?” then the answer becomes one of:

1 use a two-sided Material / Shader
2 duplicate all the triangles and add them as flipped (eg, procedurally double-side the model)
3 something else?

I’ll leave #1 to you for googling.

#2 is fairly easy work, and this one might be all you need:

using UnityEngine;

// @kurtdekker - quick double-siding mechanism.
//
// Place or add this Component to things with at
// least a MeshFilter on them.
//
// Presently only for single-submesh geometry.

[RequireComponent( typeof( MeshFilter))]
public class MakeGeometryDoubleSided : MonoBehaviour
{
    void Awake()
    {
        // If this blows up you failed to meet the documented
        // requirement above that a MeshFilter be present.
        MeshFilter mf = GetComponent<MeshFilter>();

        int vertCount = mf.mesh.vertices.Length;
        Vector3[] verts = new Vector3[ vertCount * 2];

        for (int i = 0; i < vertCount; i++)
        {
            verts [i] = mf.mesh.vertices [i];
            verts [i + vertCount] = mf.mesh.vertices [i];
        }

        int triCount = mf.mesh.triangles.Length;
        int[] tris = new int[ triCount * 2];

        for (int i = 0; i < triCount; i += 3)
        {
            tris[i + 0] = mf.mesh.triangles[i + 0];
            tris[i + 1] = mf.mesh.triangles[i + 1];
            tris[i + 2] = mf.mesh.triangles[i + 2];

            tris[i + triCount + 0] = mf.mesh.triangles[i + 0] + vertCount;
            tris[i + triCount + 1] = mf.mesh.triangles[i + 2] + vertCount;
            tris[i + triCount + 2] = mf.mesh.triangles[i + 1] + vertCount;
        }

        mf.mesh.vertices = verts;

        mf.mesh.triangles = tris;

        mf.mesh.RecalculateNormals ();
    }
}

In case anyone is stuck on this threat as I was:

  • Use LineRenderer.Bake(yourMesh) or LineRenderer.Bake(yourMesh, yourCamera, useTransformBool) as you normally would. This will result in world space coordinates that seem offset at first.
  • Create a Vector3 Array with all the resulting vertices of the freshly created mesh.
  • Loop through all vertices and offset them by the offset value you need (for example the parents localPosition)
  • Feed the vertices back into the mesh
public void GeneratePathColliders()
    {
     
        // create mesh for this line renderer
        Mesh lrMesh = new Mesh();
       // create (add) a mesh collider for the resulting mesh
        MeshCollider lrMeshCollider = gameObject.AddComponent<MeshCollider>();

        // 'Bake' the line renderer mesh – which results in world space coordinates
        wpConnectionLineRenderer.BakeMesh(lrMesh, Camera.main, true);

        // Get the vertices of the freshly created mesh
        Vector3[] vertices = lrMesh.vertices;

        // Apply the offset by subtracting the offset (here:  parent's local position) from each vertex position
        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i] -= transform.parent.localPosition;
        }

        // Assign the adjusted vertices back to the mesh
        lrMesh.vertices = vertices;

        // Set the shared mesh of the mesh collider
        lrMeshCollider.sharedMesh = lrMesh;

    }

Hope this helps :slight_smile:

1 Like