- Home /
The question is answered, right answer was accepted
Generate a mesh around a LineRenderer
Hello, I was wondering if there is an easy way to generate a mesh for a LineRenderer
?
I followed this tutorial to make a spline and I was hoping I could attach unity's new navmesh surface component to it.
Sadly I didn't realize that the LineRenderer wasn't a mesh and so it won't work with the navigation system.
I have all the vertexes for the line. Is the only way to do it to generate mesh individually?
This is pretty doable. The big questions are: What shape do you want to generate around the line, What do you want to do about corners?
Well, what I'm trying to do is make it flat. I trying to make a path for NPC's to walk on at runtime.
I kinda want the path to look exactly like the line drawn in the image, where it bends at the corners. so the shape is rectangular and rounder edges.
If you have any ideas I would be more than glad to hear them. I can upload the scripts also if you want them.
Answer by BlakeSchreurs · Oct 18, 2017 at 06:39 PM
Here is some starter code. There are plenty of examples on how to dynamically create a mesh from points, so my answer here is going to focus on creating a group of points from a line. In this case, there will be a "left" side and a "right" side, and you can create a triangle strip using the two sets of points. The left side is one meter to the left of center, and the right side is one meter to the right of center, creating a path two meters wide.
This code is not a solve-all-cases piece of code. The sharper the angles of the turn, the more the weaknesses of this approach will show. That said, it's a fairly simple piece of code to understand, and you can build upon it to deal with the edge cases that you may encounter.
Also remember: You can run it in editor, and then prefab-out the generated result which you can then re-use without having to go through the process of generation.
This code finds & debug displays the left & right side of the line, but does not create the mesh.
using UnityEngine;
public class PathScript : MonoBehaviour {
public LineRenderer line;
// Use this for initialization
void Start () {
var caret = new GameObject();
Vector3 left, right; // A position to the left of the current line
// For all but the last point
for (var i = 0; i < line.positionCount - 1; i++)
{
caret.transform.position = line.GetPosition(i);
caret.transform.LookAt(line.GetPosition(i + 1));
right = caret.transform.position + caret.transform.right;
left = caret.transform.position - caret.transform.right;
Debug.DrawLine(line.GetPosition(i), line.GetPosition(i) + Vector3.up, Color.white, 60f); // Just to visualize what's going on
Debug.DrawLine(left, left + Vector3.up, Color.blue, 60f); // Just to visualize what's going on
Debug.DrawLine(right, right + Vector3.up, Color.red, 60f); // Just to visualize what's going on
}
// Last point looks backwards and reverses
caret.transform.position = line.GetPosition(line.positionCount - 1);
caret.transform.LookAt(line.GetPosition(line.positionCount - 2));
right = caret.transform.position - caret.transform.right;
left = caret.transform.position + caret.transform.right;
Debug.DrawLine(caret.transform.position, caret.transform.position + Vector3.up, Color.white, 60f); // Just to visualize what's going on
Debug.DrawLine(left, left + Vector3.up, Color.blue, 60f); // Just to visualize what's going on
Debug.DrawLine(right, right + Vector3.up, Color.red, 60f); // Just to visualize what's going on
}
}
Thank you, I think this is leading me in the right direction. I'm gonna try to implement a mesh builder for it. If I can do that I'll accept your answer.
Thank you :)
Here is the extra code that made it work:
using System.Collections.Generic;
using UnityEngine;
public class PathScript : $$anonymous$$onoBehaviour
{
public LineRenderer line;
private List<Vector3> points = new List<Vector3>();
// Use this for initialization
public void start(LineRenderer lines)
{
points.Clear();
line = lines;
GameObject caret = null;
caret = new GameObject("Lines");
Vector3 left, right; // A position to the left of the current line
// For all but the last point
for (var i = 0; i < line.positionCount - 1; i++)
{
caret.transform.position = line.GetPosition(i);
caret.transform.LookAt(line.GetPosition(i + 1));
right = caret.transform.position + transform.right * line.startWidth / 2;
left = caret.transform.position - transform.right * line.startWidth / 2;
points.Add(left);
points.Add(right);
}
// Last point looks backwards and reverses
caret.transform.position = line.GetPosition(line.positionCount - 1);
caret.transform.LookAt(line.GetPosition(line.positionCount - 2));
right = caret.transform.position + transform.right * line.startWidth / 2;
left = caret.transform.position - transform.right * line.startWidth / 2;
points.Add(left);
points.Add(right);
Destroy(caret);
Draw$$anonymous$$esh();
}
private void Draw$$anonymous$$esh()
{
Vector3[] verticies = new Vector3[points.Count];
for (int i = 0; i < verticies.Length; i++)
{
verticies[i] = points[i];
}
int[] triangles = new int[((points.Count / 2) - 1) * 6];
//Works on linear patterns tn = bn+c
int position = 6;
for (int i = 0; i < (triangles.Length / 6); i++)
{
triangles[i * position] = 2 * i;
triangles[i * position + 3] = 2 * i;
triangles[i * position + 1] = 2 * i + 3;
triangles[i * position + 4] = (2 * i + 3) - 1;
triangles[i * position + 2] = 2 * i + 1;
triangles[i * position + 5] = (2 * i + 1) + 2;
}
$$anonymous$$esh mesh = GetComponent<$$anonymous$$eshFilter>().mesh;
mesh.Clear();
mesh.vertices = verticies;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
This is good, but works only in some cases. I am using this to convert my points from a line renderer to a mesh, so a line is drawn horizontally does not get any kind of mesh. The rest of the cases that work fine have counter clockwise direction and are not visible in the direction of the camera. Is there a better algorithm than this to find out the triangles?
Answer by tonytopper · Mar 03 at 10:23 PM
I'd suggest giving the LineRenderer component's built-in BakeMesh method a try.
https://docs.unity3d.com/ScriptReference/LineRenderer.BakeMesh.html
Follow this Question
Related Questions
Procedural generated mesh problem 1 Answer
Filling area under linerenderer 2 Answers
LineRenderer BakeMesh is turning/rotating the line? 1 Answer
Procedural array of meshes problem / solved 1 Answer
Distribute terrain in zones 3 Answers