Creating Mesh like Line Render Unity3d

Viewed 486

I want to create mesh the same to User input. User draw line by linerender. This is my code that generate mesh by points base of LineRender point Array, but Mesh isn't continious, have some space between mesh if you draw line fast, due to big distance of two points in array(, so how create mesh of same shape and continiously. Mesh need to looks like line.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

[RequireComponent(typeof(MeshFilter))]
public class MeshGenerator : MonoBehaviour
{
    public Vector3[] _point;
    private Vector3[] _vertices;
    private int[] _triengels;
    private Mesh _mesh;
    private Draw draw;
    private float _verticesOffSetX;
    private float _verticesOffSetY;


    void Start()
    {
        draw = GameObject.FindGameObjectWithTag("GameController").GetComponent<Draw>();
        _mesh = GetComponent<MeshFilter>().mesh;

    }

    void Update()
    {
        if(Input.GetKeyUp(KeyCode.Mouse0))
        {
            CreateShapeDraw();
            UpdateMesh();
        }        
    }

    private void CreateShapeDraw()
    {


        _point = new Vector3[draw.pointCounter];
        draw.currentLineRender.GetPositions(_point);

        _vertices = new Vector3[draw.pointCounter * 4];
        _triengels = new int[draw.pointCounter * 6];

        int v = 0;
        int t = 0;
        for (int i = 1; i < draw.pointCounter-1; i++)
        {

            _verticesOffSetX = _point[0].x - _point[i].x ;
            _verticesOffSetY = _point[0].y - _point[i].y;
            Vector3 offSet = new Vector3(_verticesOffSetY, 0, _verticesOffSetX);

            _vertices[v] =   new Vector3(-0.1f, 0, -0.1f) + offSet;
            _vertices[v+1] = new Vector3(0.1f, 0, -0.1f) + offSet;
            _vertices[v+2] = new Vector3(-0.1f, 0, 0.1f) + offSet;
            _vertices[v+3] = new Vector3(0.1f, 0, 0.1f) + offSet;

            _triengels[t]   = v;
            _triengels[t+1] = _triengels[t+4] = v+1;
            _triengels[t+2] = _triengels[t+3] = v+2;
            _triengels[t+5] = v+3;

            v += 4;
            t += 6;



        }

    }

    private void UpdateMesh()
    {
        this.gameObject.RemoveComponent<MeshCollider>();
        _mesh.Clear();
        _mesh.vertices = _vertices;
        _mesh.triangles = _triengels;
        MeshCollider mesh =  gameObject.AddComponent(typeof(MeshCollider)) as MeshCollider;
        mesh.convex = true;
    }   
}

The way I'm drawing line

public class Draw : MonoBehaviour
{
    public Camera mainCamera;
    public GameObject brush;

    public LineRenderer currentLineRender { get; set; }
    public int pointCounter { get; set; }

    private Vector3 _previousPointDistance = Vector3.zero;
    private float _minDistance = 0.01f;
    private CheckArea checkArea;
    private int i;
    public List<Vector3> extenciveArray;
    private Vector3[] _point;

    private void Start()
    {
        i = 0;
        checkArea = GameObject.FindGameObjectWithTag("Desk").GetComponent<CheckArea>();
    }
    private void Update()
    {
        Shapeding();
        currentLineRender.GetPositions(_point);
    }
    private void Shapeding()
    {
        if (!checkArea.canDrow) return;
        
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
           CreateBrush();
        }
        else if (Input.GetKey(KeyCode.Mouse0))
        {
            Vector3 mousePos = mainCamera.ScreenToWorldPoint(Input.mousePosition);   
            AddPoint(mousePos);
            pointCounter = currentLineRender.positionCount;
            _point = new Vector3[pointCounter];
        }
        else
        {
            currentLineRender = null;
             Destroy(GameObject.FindGameObjectWithTag("Brush"));
             i = 0;
        }
        
        
    }
    private void CreateBrush()
    {
        GameObject brushInctance = Instantiate(brush);
        currentLineRender = brushInctance.GetComponent<LineRenderer>();

        Vector3 mousePos = mainCamera.ScreenToWorldPoint(Input.mousePosition);

        currentLineRender.SetPosition(0, new Vector3(mousePos.x, mousePos.y, mousePos.z + 10));
        currentLineRender.SetPosition(1, new Vector3(mousePos.x, mousePos.y, mousePos.z + 10));
    }
    private void AddPoint(Vector3 pointPos)
    {
        if(_previousPointDistance == null)
        {
            _previousPointDistance = pointPos;
        }
        if (_previousPointDistance != null && Mathf.Abs(Vector3.Distance(_previousPointDistance, pointPos)) >= _minDistance)
        {
            i++;
            _previousPointDistance = pointPos;
            currentLineRender.positionCount = i;
            currentLineRender.SetPosition(i - 1, new Vector3(pointPos.x, pointPos.y, pointPos.z + 10));

        }
    }
}
1 Answers

Defining the collider you are after is a very fun but quite an epic task. The unity's LineRenderer.BakeMesh method of the lineRenderer can do that for you.

You can do:

public yourLineRendererComponent;
public meshColliderComponentReferenceAddedToYourLineRendererGameObject;
private Mesh mesh = new Mesh();

void setLrCollider() {
    LineRenderer lineRenderer = yourLineRendererComponent;
    lineRenderer.startWidth = 1; //optional
    lineRenderer.endWidth = 1; //optional
    MeshCollider meshCollider = 
    meshColliderComponentReferenceAddedToYourLineRendererGameObject;
    lineRenderer.positionCount = lineRendererPathVector3Array.Length;
    lineRenderer.SetPositions(lineRendererPathVector3Array);
    lineRenderer.BakeMesh(mesh, Camera.main);
    meshCollider.sharedMesh = mesh;
}

Obviously not debuggued code. Naming the variables so as descriptive as possible so as you know what to do if you would like to try it out.

Related