Search Unity

Line renderers giving the illusion that they are not straight

Discussion in 'General Graphics' started by DroidifyDevs, Feb 3, 2017.

  1. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Hello!

    So I'm doing something really simple: The user taps on the screen and I draw a STRAIGHT line towards the point. I'm using a Line Renderer for this. Take note that the line is perfectly straight.

    In green is the line renderer, in yellow is a sprite that I manually placed:

    LineRendererUnity.PNG

    As you see, when viewed from the game camera, the line renderer gives the illusion that its left side is lower than the right. When viewed from the Editor's camera angle, it looks like it's tilted compared to the yellow sprite I manually placed.

    So I thought I'd set the Line Renderer's Alignment to Local. However, no matter how much I rotate it, I can't get it to be flat with the ground like I did with my sprite.

    So my question is, is there a way to rotate a line renderer so it looks like my manually-created sprite? If I can't, how can I draw a line between 2 points without a line renderer?

    Thank you!
     
    Mikael-H likes this.
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    The line is trying to face the camera. Though it still looks strange to me.. I guess some shadow rendering would clarify if this is an optical illusiuon.

    If you're using 5.5, you may want to try and set the line alignment to Local instead of View.
    This will make the line face its Transform component, instead of the camera. Set the line positions in XY only, and then rotate the Transform Component of the Line Renderer to make it face where ever you want.
     
  3. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Thanks for your reply!

    Here's another picture, this time with the line renderer set to local:
    LineREndererUnity2.PNG

    As you see, both the line renderer and sprites are straight, but the line renderer is still tilted. Now I rotated both the sprite and Line Renderer:
    LineRendererUnity3.PNG

    As you see by the transform arrows' rotation and the line renderer, it's not rotating as expected.

    Is this a bug or am I doing something wrong?

    Thanks!
     
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    It's best to use only X and Y for your line points, when using local space (we have some bugs that can occur when using Z)

    If that doesn't fix it, we'd probably need a bug report + repro project, to be able to figure out exactly what's going on here.
     
  5. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Yes, it does seem there are some bugs with the Line renderer. For instance, I can't rotate an instantiated line renderer properly, but one made in the Editor works fine. I really need Z as shown in the first picture. I guess I'll look into some other way of drawing a line between 2 points. I've seen massive improvement in the line renderer in 5.5, but it still doesn't work well enough for me to use for a relatively simple task :(
     
  6. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    But you weren't using Y, so I was suggesting to simply use Y instead of Z, and rotate your game object to compensate for the axis change. Might make other maths in your game confusing though, so fair enough if you can't reasonably do it.

    (You would also have to disable World Space, which again, I guess maybe you need) :)
     
  7. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Yeah I don't think it's a good idea to rotate my whole scene just to accommodate for a line renderer. Then physics would be really messed up. I think I need World Space too. What I'm doing is tapping on a battalion of soldiers. The center of the battalion is Point 0 in the Line renderer's point array. Then I tap on the screen and ensure the line is perfectly straight with this code:

    Code (CSharp):
    1. void SetupPointerLine(LineRenderer PointerLineObject)
    2.     {
    3.         //CurrentObject is the original object that will be moved
    4.         PointerLineObject.SetPosition(0, CurrentObject.transform.position);
    5.         float DiffX = SpawnLocation.position.x - CurrentObject.transform.position.x;
    6.         //make sure it's positive
    7.         if (DiffX < 0)
    8.         {
    9.             DiffX *= -1;
    10.         }
    11.  
    12.         float DiffZ = SpawnLocation.position.z - CurrentObject.transform.position.z;
    13.         //make sure it's positive
    14.         if (DiffZ < 0)
    15.         {
    16.             DiffZ *= -1;
    17.         }
    18.         //now make the line vertical or horizontal
    19.         if (DiffX < DiffZ)
    20.         {
    21.             //make the line vertical
    22.             PointerLineAdjustedPoint = new Vector3(CurrentObject.transform.position.x, SpawnLocation.position.y, SpawnLocation.position.z);
    23.         }
    24.         else
    25.         {
    26.             //make the line horizontal
    27.             PointerLineAdjustedPoint = new Vector3(SpawnLocation.transform.position.x, SpawnLocation.position.y, CurrentObject.transform.position.z);
    28.         }
    29.         PointerLineObject.SetPosition(1, PointerLineAdjustedPoint);
    30.         Debug.Log("DiffX is " + DiffX + " DiffZ is " + DiffZ);
    31.     }
    Where SpawnLocation is the place where the user tapped (shown as a red ball in the images below).

    So I could use Line Renderer and set its alignment to "View", but it gives a really sloppy look as it makes the line renderer point towards the camera, instead of being flat on the ground:

    LineRendererView1.PNG

    So then I could try setting the alignment to "local", but for some reason when they spawn, they aren't rotated correctly, even though the prefab line I'm spawning is rotated correctly. Once they are spawned, it's impossible to rotate properly. Here's what I mean:



    As you see, when I try to rotate it to the left (making the X rotation under 90 degrees), it shuts off. Is this a bug or is there something I don't understand properly?

    Thank you so much for your help.
     
  8. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    So I've created a script to achieve the result I need.

    Here are the results:

    1: Both line renderer AND sprite (green and yellow, respectively):
    LineRendererBothUnity1.PNG

    2: Just line renderer (set to "View" since I can't get the local rotation to work right as I stated in the previous post):
    LineRendererUnityLineOnly1.PNG

    3: Just sprite created with my script:
    LineRendererUnitySpriteOnly1.PNG

    Overall it isn't a giant difference, but the line renderer version doesn't look very straight and it takes away from the game.

    And here is my script for reference:

    Code (CSharp):
    1. void SetupSpritePointerLine(GameObject SpriteLine)
    2.     {
    3.         //CurrentObject is the original object that will be moved
    4.         //SpawnLocation is the point where the user tapped
    5.         //IMPORTANT: RESET BOOLS EVERY TIME. These tell where is SpawnLocation in relation to CurrentObject
    6.         IsBelow = false;
    7.         IsLeft = false;
    8.         SpriteLine.transform.position = CurrentObject.transform.position;
    9.         float DiffX = SpawnLocation.position.x - CurrentObject.transform.position.x;
    10.         //make sure it's positive
    11.         if (DiffX < 0)
    12.         {
    13.             DiffX *= -1;
    14.             IsLeft = true;
    15.         }
    16.  
    17.         float DiffZ = SpawnLocation.position.z - CurrentObject.transform.position.z;
    18.         //make sure it's positive
    19.         if (DiffZ < 0)
    20.         {
    21.             DiffZ *= -1;
    22.             IsBelow = true;
    23.         }
    24.         //now make the line vertical or horizontal
    25.         if (DiffX < DiffZ)
    26.         {
    27.             //make the line vertical
    28.             //if we clicked below the current object
    29.             if (IsBelow)
    30.             {
    31.                 PointerLineAdjustedPoint = new Vector3(CurrentObject.transform.position.x, -10.5f, CurrentObject.transform.position.z - (DiffZ / 2));
    32.                 Debug.Log("Sprite line done! - clicked below current object");
    33.             }
    34.             //if we clicked above the current object
    35.             if (!IsBelow)
    36.             {
    37.                 PointerLineAdjustedPoint = new Vector3(CurrentObject.transform.position.x, -10.5f, CurrentObject.transform.position.z + (DiffZ / 2));
    38.                 Debug.Log("Sprite line done! - clicked above current object");
    39.             }
    40.             //set proper scale
    41.             SpriteLine.transform.localScale = new Vector3(100, 100 *(DiffZ / 2), 1);
    42.         }
    43.         else
    44.         {
    45.             //make the line horizontal
    46.             if (IsLeft)
    47.             {
    48.                 PointerLineAdjustedPoint = new Vector3(SpawnLocation.transform.position.x + (DiffX / 2), -10.5f, CurrentObject.transform.position.z);
    49.                 Debug.Log("Sprite line done! - clicked left of current object");
    50.             }
    51.  
    52.             if (!IsLeft)
    53.             {
    54.                 PointerLineAdjustedPoint = new Vector3(SpawnLocation.transform.position.x - (DiffX / 2), -10.5f, CurrentObject.transform.position.z);
    55.                 Debug.Log("Sprite line done! - clicked right of current object");
    56.             }
    57.             SpriteLine.transform.localScale = new Vector3(100 * (DiffX / 2), 100, 1);
    58.         }
    59.         SpriteLine.transform.position = PointerLineAdjustedPoint;
    60.         Debug.Log("DiffX is " + DiffX + " DiffZ is " + DiffZ);
    61.     }
    However I'm still confused as to what's going on in the video I attached in my previous post. Hopefully UT will sort out the Z-axis and local rotation issues with the Line Renderers. Keep up the good work!
     
    richardkettlewell likes this.
  9. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    I'm on Unity 5.5.0f3 at the moment and working with linerenderer to mark the borders of minefields and other areas in the terrain. I am using local alignent, local space and I have rotated the transform as you suggested above. Unfortunately I have to edit the z coordinate a little bit in order to follow the terrain shape somewhat (I am also using a shader with offset) and this seems to result in a bug that can occur where the actual alignment of the lines can behave odd at times. It is most easily seen if you just move the whole transform up and down along global y axis a little bit. At certain places it looks like the line rotates along its axis. Is this one of the bugs you were talking about? If so, do they have a number so I could follow them and are they planned to be fixed in the near future?

    Fantastic stuff that has been done with the linerenderer in 5.5 though, all of a sudden it's a tool that is very competent even though there are a few hiccups...
     
  10. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    There's no doubt that there's massive improvement with the line renderers. In my case, when setting them to local, they just don't move and rotate like a regular sprite would. My most annoying bug was this:



    Probably different than yours, but it's still just a PITA to get around. However I did notice that even if the line is rotated to face straight, it sometimes will still look like it's angled. The video also shows a strange disappearing line bug where the line disappears if I rotate it past a point.

    I wrote my own script to find a position between 2 points, spawn a sprite and stretch it to fill a line between the 2 points. I had to do that instead of using the Line Renderer because its Z axis is bugged. Hopefully UT is working on this :)
     
    Mikael-H likes this.
  11. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    THIS I think is exactly what I am seeing as well. I haven't had any disappearing lines like in your video though. May I ask what unity version you are currently on?
     
  12. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Currently I'm on 5.5.2, but I made this thread when I was on 5.5.1.

    Also, I can't rotate its Z axis at all with it set to local.
     
  13. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    Ok, I'm on 5.5.0 currently and was sort of hoping it would be fixed in 5.5.2 :)
    As @richardkettlewell stated that there are know bugs I hope this is one of them and that it will be fixed by 5.6.
    Good luck with your game!
     
    DroidifyDevs likes this.
  14. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    The liner renderer bugs seems to have been fixed in 5.5.3 and 5.6!
     
    karl_jones and richardkettlewell like this.