Search Unity

How to add collider to a Line Renderer

Discussion in '2D' started by MilanStosic, Nov 19, 2017.

  1. MilanStosic

    MilanStosic

    Joined:
    Apr 28, 2017
    Posts:
    3
    A while ago i asked for help to make incomplete rings, and i have succeeded. Since then i've been doing some work and now i have 1 more problem i can't add a collider to it. I've added edge collider to a ring but it's in the center and i can't figure out how to move it to the inner edge or even better a polygon collider around it whole. Here's what i ended up with
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. [RequireComponent(typeof(LineRenderer))]
    7. public class RingCreation : MonoBehaviour {
    8.  
    9.     public int segments;
    10.     public float xradius;
    11.     public float yradius;
    12.     public int gap;
    13.     LineRenderer line;
    14.    
    15.     EdgeCollider2D edge;
    16.     CapsuleCollider2D capsule;
    17.     List<Vector2> colliderPoints = new List<Vector2>();
    18.  
    19.     private void Awake()
    20.     {
    21.         line = GetComponent<LineRenderer>();
    22.         line.SetVertexCount(segments + 1 - (segments / gap));
    23.         line.useWorldSpace = false;
    24.         CreatePoints();
    25.         addCollider();
    26.     }
    27.  
    28.     void CreatePoints()
    29.     {
    30.         float x;
    31.         float y;
    32.         float z = 0f;
    33.  
    34.         float angle = 0f;
    35.  
    36.         for (int i = 0; i < (segments + 1) - (segments / gap); i++)
    37.         {
    38.             x = Mathf.Sin(Mathf.Deg2Rad * angle) * xradius;
    39.             y = Mathf.Cos(Mathf.Deg2Rad * angle) * yradius;
    40.  
    41.             line.SetPosition(i, new Vector3(x, y, z));
    42.  
    43.             Vector3 col = new Vector3(x, y, z);
    44.             colliderPoints.Add(col);
    45.  
    46.             angle += (360f / segments);
    47.         }
    48.     }
    49.  
    50.     void addCollider()
    51.     {
    52.         List<Vector2> colliderPoints2 = new List<Vector2>();
    53.  
    54.         for (int i = 0; i < colliderPoints.Count; i++)
    55.         {
    56.             colliderPoints2.Add(new Vector3(colliderPoints[i].x, colliderPoints[i].y, 0f));
    57.         }
    58.  
    59.         for (int i = colliderPoints.Count - 1; i > 0; i--)
    60.         {
    61.             colliderPoints2.Add(new Vector3(colliderPoints[i].x, colliderPoints[i].y, 0f));
    62.         }
    63.  
    64.         edge = line.gameObject.AddComponent<EdgeCollider2D>();
    65.         edge.points = colliderPoints2.ToArray();
    66.     }
    67. }
    68.  
     

    Attached Files:

    • ss.png
      ss.png
      File size:
      36.7 KB
      Views:
      1,591
  2. hasanbayat

    hasanbayat

    Joined:
    Oct 18, 2016
    Posts:
    630
    You can use PolygonCollider2D and use LineRenderer half width to add points.

    Here is an example:

    Code (CSharp):
    1. float halfWidth = line.startWidth / 2f;
    2. Vector2 rightPoint = colliderPoints[i];
    3. Vector2 leftPoint = colliderPoints[i];
    4. rightPoint.x -= halfWidth;
    5. leftPoint.x += halfWidth;
    6. colliderPoints2.Add(rightPoint);
    7. colliderPoints2.Add(leftPoint));
    Thanks.
     
    Fee1Good and HenryChinaski like this.
  3. bertrand_arnaud

    bertrand_arnaud

    Joined:
    Apr 11, 2019
    Posts:
    2
    Since Unity 2018.2, you can now use the public method BakeMesh of LineRenderer. This will give you the mesh along the LineRenderer with all the segments. You can then use this mesh with a mesh collider in order to detect Collisions and Raycasts.


    Code (CSharp):
    1.  LineRenderer lineRenderer = line.GetComponent<LineRenderer>();
    2. MeshCollider meshCollider = line.AddComponent<MeshCollider>();
    3.  
    4. Mesh mesh = new Mesh();
    5. lineRenderer.BakeMesh(mesh, true);
    6. meshCollider.sharedMesh = mesh;
    I tested it and it worked on my project. Let me know what you think about it and if it helps you !
     
    Last edited: Apr 15, 2019
  4. hangksgogo

    hangksgogo

    Joined:
    Aug 8, 2019
    Posts:
    1

    I tried the code that "bertrand_arnaud" provided, but unity gives error that says

    argumentnullexception: value cannot be null. parameter name: camera unityengine.linerenderer.bakemesh (unityengine.mesh mesh, system.boolean usetransform)

    How can I solve the error?
     
    _protagonist likes this.
  5. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Take a look at the documentation: https://docs.unity3d.com/ScriptReference/LineRenderer.BakeMesh.html

    One of the overloads takes a Camera parameter. That's what your error is talking about. Try passing in your main camera as a second parameter, or make sure you have a camera tagged MainCamera available in your scene.
     
    shenjiexiang1994 likes this.
  6. Lupinder

    Lupinder

    Joined:
    Oct 6, 2018
    Posts:
    85
    ı want to add collider to my line renderer but i did not understand your post. How ı will create mesh in line
     
  7. alekz1k

    alekz1k

    Joined:
    Dec 14, 2014
    Posts:
    16
    I do see the mesh from my Line Renderer using BakeMesh, but he's far away, living his dream in his own dimension lol. I guess I must fix something related to WorldSpace Vs LocalSpace (my LineRenderer uses WorldSpace). If anyone has any input on that one, I'm down! Peace out
     
    Last edited: May 30, 2022
  8. cyavictor88

    cyavictor88

    Joined:
    Feb 28, 2022
    Posts:
    3
    if you add
    Code (CSharp):
    1.        
    2.  //beware this makes lineRenderer using local space
    3.  myLineRenderer.useWorldSpace = false;
    4.  
    then it should work
     
  9. cyavictor88

    cyavictor88

    Joined:
    Feb 28, 2022
    Posts:
    3
    to be more complete, here is a script(Liner.cs) that should be able to quickly test out adding collider on lineRenderer:

    Code (CSharp):
    1.  
    2. /*
    3. Liner.cs
    4. for this to work, do the following steps:
    5. 1  Make sure "Main Camera" exists, and its position and rotation are 0s for all xyz directions
    6. 2. Create a scripts with filename "Liner.cs"
    7. 3. Copy this whole code into the Liner script  (the script is using the new input system, if you are on old one , rmb to change two lines( code below have details ))
    8. 4. Create an Empty GameObject in your scene, and add the Liner script as a component
    9. 5. click Play, you should be able to see a red line, click on it, will change color, then hooray, collider works
    10. */
    11.  
    12. using System.Collections;
    13. using System.Collections.Generic;
    14. using UnityEngine;
    15. using UnityEngine.InputSystem;
    16.  
    17. public class Liner : MonoBehaviour
    18. {
    19.     LineRenderer lr;
    20.     Color[] colors = { Color.red, Color.black };
    21.     int curColor = 0;
    22.     void Start()
    23.     {
    24.         lr = this.gameObject.AddComponent<LineRenderer>();
    25.         lr.material = new Material(Shader.Find("Sprites/Default"));
    26.         lr.material.color = colors[curColor];
    27.         lr.startWidth = 1f;
    28.         lr.endWidth = 1f;
    29.         lr.positionCount = 2;
    30.  
    31.         Vector3[] poses = new Vector3[2];
    32.         poses[0] = new Vector3(0, 10f, 100f);
    33.         poses[1] = new Vector3(5f, -3f, -4f);
    34.         lr.SetPositions(poses);
    35.  
    36.  
    37.         // making a meshcolllider and attach to the lineRenderer
    38.  
    39.         //beware this makes lineRenderer using local space
    40.         lr.useWorldSpace = false;
    41.  
    42.         MeshCollider meshCollider = this.gameObject.AddComponent<MeshCollider>();
    43.         Mesh mesh = new Mesh();
    44.         lr.BakeMesh(mesh, Camera.main, false);
    45.         meshCollider.sharedMesh = mesh;
    46.  
    47.  
    48.     }
    49.     void Update()
    50.     {
    51.         // when you click on the line, the line color should change between red and black
    52.  
    53.         // be aware that I am using the new input system
    54.         // if using the old input system, i think you replace the the next line with "if(Input.GetMouseButtonDown(0))"
    55.         if (Mouse.current.leftButton.wasPressedThisFrame)
    56.         {
    57.             // if using the old input system, i think you replace the the next line with "Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);"
    58.             Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
    59.             RaycastHit hitData_for_the_ray;
    60.             if (Physics.Raycast(ray, out hitData_for_the_ray))
    61.             {
    62.                 GameObject theGameObjectHitByRay = hitData_for_the_ray.collider.gameObject;
    63.                 {
    64.                     if (theGameObjectHitByRay == this.gameObject)
    65.                     {
    66.                         curColor = (curColor + 1) % 2;
    67.                         lr.material.color = colors[curColor];
    68.                     }
    69.                 }
    70.             }
    71.         }
    72.     }
    73. }
    74.  
     
    Last edited: Jun 23, 2022
    _protagonist likes this.