Search Unity

Line Renderer Problem

Discussion in 'Scripting' started by liquidgraph, Apr 20, 2009.

  1. liquidgraph

    liquidgraph

    Joined:
    Feb 26, 2009
    Posts:
    324
    I can't figure out why the line renderer is misbehaving. I'm trying to draw a basic rectangle and here's the result:


    The rectangle is drawn in a clock-wise direction using 5 points. The first 3 lines end up twisted but the last line is fine. What am I missing? Here's my code for the line renderer object:

    Code (csharp):
    1. / the options
    2. var startWidth = 0.05;
    3. var endWidth = 0.05;
    4. var aMaterial : Material;
    5.  
    6.  
    7. // these are set in start
    8. private var line : LineRenderer;
    9.  
    10. private var point01 = Vector3(0,0,0);
    11. private var point02 = Vector3(0,0,0);
    12. private var point03 = Vector3(0,0,0);
    13. private var point04 = Vector3(0,0,0);
    14. private var point05 = Vector3(0,0,0);
    15.  
    16.  
    17.  
    18. function Start ()
    19. {
    20.    line = this.gameObject.AddComponent(LineRenderer);
    21.    line.SetWidth(startWidth, endWidth);
    22.    line.SetVertexCount(5);
    23.    line.material = aMaterial;
    24.    line.renderer.enabled = true;
    25. }
    26.  
    27. function Update ()
    28. {
    29.    line.SetPosition(0, point01);
    30.    line.SetPosition(1, point02);
    31.    line.SetPosition(2, point03);
    32.    line.SetPosition(3, point04);
    33.    line.SetPosition(4, point05);
    34. }
     
    luixodev likes this.
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That's just how the line renderer works; it's not really intended for that sort of drawing.

    --Eric
     
  3. liquidgraph

    liquidgraph

    Joined:
    Feb 26, 2009
    Posts:
    324
    :eek: I hope that's a joke.

    What is the technical reason for the lines being drawn in that way? What sort of drawing was it intended for?
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Not a joke. :) To quote the docs, "The Line Renderer does not render one pixel thin lines. It renders billboard lines that have width and can be textured. It uses the same algorithm for line rendering as the Trail Renderer." Also: "The lines may seem to rotate as you move the Camera. This is intentional."

    --Eric
     
  5. liquidgraph

    liquidgraph

    Joined:
    Feb 26, 2009
    Posts:
    324
    Yeah, I was just reading that part, but that's still no excuse for multiple points not rendering properly.

    I'm not trying to get a 1 pixel line; I need billboards that connect in an expected manner. I supposed it's possible to make use of 4 separate line renderers, but then why does the line render object support more than 2 points?
     
    Harinezumi likes this.
  6. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    TBH the LineRenderer could be smarter about this sort of thing without losing its functionality. Right now, to get the direction to offset the vertices relating to a particular point, it looks only at the line segment ahead of it. It could be improved by looking both behind and ahead of it and averaging those vectors, which would remove this sort of artifact.

    Maybe you could Wishlist it?
     
  7. Sbd

    Sbd

    Joined:
    Jun 16, 2008
    Posts:
    36
    This issue has bothered me as well. I don't see why anyone would want it to behave the way it does now.

    Fixed this issue by creating one line for each "part" of a larger twisting line.
     
  8. maxwelldoggums

    maxwelldoggums

    Joined:
    Sep 8, 2008
    Posts:
    157
    Check the settings. If the line renderer has a final or starting width of zero, it might look like that.
     
  9. liquidgraph

    liquidgraph

    Joined:
    Feb 26, 2009
    Posts:
    324
    The settings have been checked and re-checked. The line width properties are definitely equal, which should result in a flat, non-tapering line.

    I've worked around the issue by creating 4 separate line renderers, one for each side of the rectangle, but in more complicated applications I think that wouldn't fly. I assume this is a bug then that we should petition to get resolved in future releases. I see the line renderer as being a valuable tool when it works properly.
     
  10. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    We know the LineRenderer does not work perfectly for a lot of cases. If you consider it a priority that it should be improved, I would indeed suggest making a suggestion of it on the UserVoice Unity feedback forum:
    http://feedback.unity3d.com/

    Rune
     
  11. bumba

    bumba

    Joined:
    Oct 10, 2008
    Posts:
    358
    same problem here... why isnt that possible to draw several line correctly with the line renderer
     
  12. hogus

    hogus

    Joined:
    Jul 9, 2009
    Posts:
    145
    +1 on this... the way the line render behaves makes no sense at all. Where two segments connect you would expect them to connect smoothly, otherwise what is the point of allowing for multiple coordinates?
     
  13. Goody!

    Goody!

    Joined:
    Sep 11, 2009
    Posts:
    100
    I wanted to drop a little love for you for posting the best way that I could find to actually script the linerenderer. Your script is simple, understandable and works. :D

    After a day or so drowning in incomplete documentation and missing script examples, much like a baby learning to swim in an underwater invisible kelp forest, your simple post was all I needed to complete my own attempts at linerendering and see results on screen.

    Thank you very much! :D
     
  14. belias

    belias

    Joined:
    Nov 10, 2011
    Posts:
    35
    $laser_5.PNG here goes the solution
     
    luixodev likes this.
  15. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Let's not forget the ever-sexy vectrosity for lines for grown-ups :)
     
  16. Patrick234

    Patrick234

    Joined:
    Jun 25, 2014
    Posts:
    88
    Just want to revive this, as its no less irrelevant all these years later. Vectrosity is cool, but what would be cooler is if the line renderer would actualy render properly. Been twisting my neck as much as the line renderer recently...
     
    luixodev likes this.
  17. Patrick234

    Patrick234

    Joined:
    Jun 25, 2014
    Posts:
    88
    Annndd i fixed it!

    upload_2014-7-17_14-2-37.png

    So its actualy this easy.

    So in every joint, i add 2 points, instead of 1, and then i set my 1st new point to:

    laser.SetPosition(laserSize-1, Vector3.MoveTowards(hitInfo.point,lastLaserPoint,0.1f));

    And my seccond to:

    laser.SetPosition(laserSize-1, hitInfo.point);

    I hope you all are helped with this discover.

    Vector3.MoveTowards(hitInfo.point,lastLaserPoint,0.1f)); Is used to move the point 0.1 units backwards so that i have a " perfect" stroke. Basicaly by offsetting 0.1 units i create the space for the " twisted" part to reside. and at point 2 i start my new laser.

    So if this gives issues for you, you can add 3 points, effectively clearing the last lasers end, and the new lasers start. But for me 2 points where good enough., 3 gives an even more cleaner effect tho.

    -edit-
    heres the code:
    Code (CSharp):
    1.         lastDirection = direction;
    2.         if(Physics.Raycast(position, direction, out hitInfo)){
    3.             laserSize+=3;
    4.             if(laserSizeOld!=laserSize){
    5.                 laser.SetVertexCount(laserSize);
    6.             }
    7.             laser.SetPosition(laserSize-3, Vector3.MoveTowards(hitInfo.point,lastLaserPoint,0.01f));
    8.             laser.SetPosition(laserSize-2, hitInfo.point);
    9.             laser.SetPosition(laserSize-1, hitInfo.point); //Visualy Flips/Negates the last point
    10.             testObject.transform.position = hitInfo.point;
    11.             lastLaserPoint = hitInfo.point;
    12.             return true;
    13.         }else{
    14.             laserSize++;
    15.             if(laserSizeOld!=laserSize){
    16.                 laser.SetVertexCount(laserSize);
    17.             }
    18.             laser.SetPosition(laserSize-1, direction * 100);
    19.             return false;
    20.         }
     
    Last edited: Jul 17, 2014
    HamCha87 likes this.
  18. clydebink

    clydebink

    Joined:
    Feb 11, 2014
    Posts:
    2
    Patrick234 had the right idea. After reading their post, I think I got the basic concept; what you want to do is retrace the entire path of the line in reverse after drawing it. Here is a very simple depiction of me doing just that.

    Code (CSharp):
    1.  
    2.         _lineRenderer.SetPosition(0, pos_lineAnchor);
    3.         _lineRenderer.SetPosition(1, pos_lineTarget1);
    4.         //This is the final point in the line before retracing it backwards.
    5.         _lineRenderer.SetPosition(2, pos_lineTarget2);
    6.         //Now draw it in reverse to cover the tapers.
    7.         _lineRenderer.SetPosition(3, pos_lineTarget1);
    8.         _lineRenderer.SetPosition(4, pos_lineAnchor);
    9.  
    10.  
     
  19. aer0ace

    aer0ace

    Joined:
    May 11, 2012
    Posts:
    1,513
    Since even now I was having problems trying to find a good line renderer, I documented my trials with the above discussions in this blog post.
     
    Last edited: Feb 25, 2019
  20. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
  21. The-Knights-of-Unity

    The-Knights-of-Unity

    Joined:
    Aug 19, 2015
    Posts:
    45
  22. pRoFlT

    pRoFlT

    Joined:
    Dec 20, 2014
    Posts:
    27
    okay LineRenderer sucks! i did not try @patrick1234 way of doing it but rather i created a prefab with a LineRenderer on it with my material and scale settings. Then i created a script for the prefab that has a public function setpoints(start,end). then another GameObject (the one i should have had LineRenderer on) with a public prefab GameObject of my LineRenderer prefab. Then the script on the main GameObject has a list of points (transforms) that at start instantiates a prefab for each line i want and calls setpoints with the start and finish position......ugh what a pain.

    My problem was LineRenderer having more then 2 points would skew the texture from point 1-2 but 2-3 was okay. or if i had 5 points the last point 4-5 would be good but everything else skewed a little. why cant scale start and end be for each segment? and why not multiple LineRenderers on an object! What is it supposed to do when you set start and end scales?

    Anyways, an hour later it looks okay. but not the way it should have been implemented...

    p.s. see game shots of my new game on instagram @birdmaze or birdmaze dot com
     
  23. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Hi all.. a very old thread, but I wanted to let you know that we are investigating ways to improve the issues raised here about the Line and Trail Renderers.
     
  24. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    In case you haven't seen it - the 5.5 Beta contains an upgraded Line and Trail Renderer that should solve these problems. It's still in Beta, so we're still fixing a few issues, but hopefully you like it!
     
    aer0ace likes this.
  25. Bertlapp

    Bertlapp

    Joined:
    Sep 7, 2015
    Posts:
    44
    In order to fix this line width issue, I calculate a small new vector with the direction of the previous line and add it to the
    LineRenderer before adding the new point!

    Example of vector calculation:

    Code (CSharp):
    1.  
    2. points.Add (lastHitPoint + Vector3.Scale(Vector3.Normalize(lastHitPoint - secondLastPoint),new Vector3(0.01f,0.01f,0.01f)));
    3. points.Add (newHitPoint);
    4.  
    5.         line.SetVertexCount (points.Count);
    6.  
    7.         for (var j = 0; j < points.Count; j++) {
    8.              line.SetPosition (j, points [j]);
    9.         }
     
    Last edited: Sep 27, 2016
  26. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Looks good!

    FYI, it is *much* faster to use LineRenderer.SetPositions instead of setting each position individually in a loop.
     
  27. Bertlapp

    Bertlapp

    Joined:
    Sep 7, 2015
    Posts:
    44
    Thank for pointing that out. There's indeed a noticeable speed change and the code is much cleaner ;)
     
    richardkettlewell likes this.
  28. ProgBombo

    ProgBombo

    Joined:
    Oct 6, 2015
    Posts:
    21
  29. ProgBombo

    ProgBombo

    Joined:
    Oct 6, 2015
    Posts:
    21
    richardkettlewell likes this.
  30. nickg111

    nickg111

    Joined:
    Dec 3, 2016
    Posts:
    2
    Hi, just noticed this issue (Line twisting) on 2017.3.0b6 - did the fix for LineRenderer make it into this release? Is there an option I need to enable?
     
  31. Orr10c

    Orr10c

    Joined:
    Sep 11, 2016
    Posts:
    45
    I know it's not exactly the place to ask this question but it's the closest post I found to my issue:
    I declared a Behaviour type variable just so I can enable and disable whatever component I assign to the variable, the thing is, I'm not able to assign lone renderer component to it, isn't line renderer's base class behaviour?
    Why can't I assign it as a behaviour type?
     
    Last edited: Nov 5, 2017
  32. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
  33. Orr10c

    Orr10c

    Joined:
    Sep 11, 2016
    Posts:
    45
    Ah, I see, thank you very much :)
     
  34. Bamboy

    Bamboy

    Joined:
    Sep 4, 2012
    Posts:
    64
    I am having this problem still as well. Using 2017.3.1
     
  35. Bamboy

    Bamboy

    Joined:
    Sep 4, 2012
    Posts:
    64
    After much frustration, I came up with this solution for drawing local alignment circles. I really would like to see a fix for this. My script requires two LineRenderers, which isn't quite ideal but whatever.

    Code (CSharp):
    1.  
    2. public class RangeDrawer : MonoBehaviour
    3. {
    4.     public LineRenderer line1;
    5.     public LineRenderer line2;
    6.  
    7.     /// Draw a circle on the X/Z plane.
    8.     public void DrawRange( float radius, Vector3 center, int vertCount = 24 )
    9.     {
    10.         line1.transform.position = center; //For use when dealing with Local space line rendering - remove if needed
    11.         line2.transform.position = center;
    12.  
    13.         List<Vector3> pts1 = new List<Vector3>();
    14.         List<Vector3> pts2 = new List<Vector3>();
    15.  
    16.         float angle = 90f; //For whatever reason, using 90 prevents jaggy issues.
    17.         float stepSize = 360f / vertCount;
    18.  
    19.         for (int i = 0; i < (vertCount / 2); i++)
    20.         {
    21.             Vector3 pt1 = new Vector3(
    22.                 Mathf.Sin(Mathf.Deg2Rad * (angle)) * radius,
    23.                 0f,
    24.                 Mathf.Cos(Mathf.Deg2Rad * (angle)) * radius
    25.             );
    26.             pts1.Add( pt1 );
    27.  
    28.             Vector3 pt2 = new Vector3(
    29.                 Mathf.Sin(Mathf.Deg2Rad * (angle + 180f)) * radius,
    30.                 0f,
    31.                 Mathf.Cos(Mathf.Deg2Rad * (angle + 180f)) * radius
    32.             );
    33.             pts2.Add( pt2 );
    34.  
    35.             angle += stepSize;
    36.         }
    37.  
    38.         pts1.Add( pts2[0] ); //Join our half circles and finalize.
    39.         line1.positionCount = pts1.Count;
    40.         line1.SetPositions( pts1.ToArray() );
    41.  
    42.         pts2.Add( pts1[0] ); //Join our half circles and finalize.
    43.         line2.positionCount = pts2.Count;
    44.         line2.SetPositions( pts2.ToArray() );
    45.     }
    46.        
    47.     public void Clear()
    48.     {
    49.         line1.positionCount = 0;
    50.         line2.positionCount = 0;
    51.     }
    52. }
    53.  
    .
     
  36. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Please file a bug report for us.
     
    Bamboy likes this.
  37. DavidBVal

    DavidBVal

    Joined:
    Mar 13, 2017
    Posts:
    206
    Still weird things happening on 2018.2.13f1.

     
  38. SIRIUSTECHSOLUTIONS

    SIRIUSTECHSOLUTIONS

    Joined:
    Apr 14, 2016
    Posts:
    9
    Hey man I wish to Thank you for this amazing code. I making a coloring mechanic and when you drag the mouse around at start a line renderer is created and when you move it around, points are placed and then the line renderer adds that point to it, the thing was that when you changed direction of movement 180 degress the line would act wacky. And this solved it. This is the code I used maybe it clears the fog of how to use your idea in other situations for other people :)

    Code (CSharp):
    1.  
    2. private void AddPointToLineRenderer(LineRenderer line, int index, Vector2 position)
    3.     {
    4.         int positionCount = line.positionCount;
    5.         if (positionCount == 0)
    6.         {
    7.             line.positionCount++;
    8.             line.SetPosition(index, position);
    9.             currentPointIndex++;
    10.         }
    11.         else if(positionCount > 0)
    12.         {
    13.             line.positionCount += 4;
    14.             positionCount = line.positionCount;
    15.             line.SetPosition(positionCount - 4, Vector3.MoveTowards(position, line.GetPosition(positionCount - 5), 0.01f));
    16.             line.SetPosition(positionCount - 3, position);
    17.             line.SetPosition(positionCount - 2, position);
    18.             line.SetPosition(positionCount - 1, position);
    19.         }
    20.     }
     
    richardkettlewell likes this.