Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Vectrosity - Fast and Easy Line Drawing

Discussion in 'Assets and Asset Store' started by Eric5h5, Sep 26, 2014.

  1. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,046
    I was mistaken. The lines do not update even when I assigned a drawTransform.
    Like I mentioned before, when I move the camera I need the lines to update correctly to stay "attached" to the sprites on screen. (this is all 2D) See image .

    I am using render mode = Screen Space - Camera.

    I am calling line.Draw() during LateUpdate (after having detected the camera was moved). I also tried with the whole line making logic before calling Draw().

    [EDIT] Okaaay. .so I was supposed to use Draw3D()
    I was tying to stick to Vector2 and Draw() since I figured I am working with 2D here. I've changed everything to Vectro3 and use Draw3D() and it updates now. Now I do not have to detect camera moving and calling line.Draw either. It all updates correctly. I guess Vector2 and Draw is more for UI related stuff? Please let me know if I am suppose to do it differently.

    [EDIT2] I am quite confused now. drawTransform does not seem to be needed either now. Is there a 2D example I can look at to learn how to use lines properly in 2D? I liked the idea of using the VectorCanvas since I could control when lines appear in front or behind my sprites by placing them in different canvas.

    lines.jpg
     
    Last edited: Feb 24, 2017
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    DrawTransform will work for 2D. In this case, the units are pixels instead of world units. e.g., if you have an empty GO and you use that with DrawTransform, moving the GO over 5 units will move the associated VectorLine over by 5 pixels.

    --Eric
     
  3. GrumpyFour

    GrumpyFour

    Joined:
    Jan 12, 2016
    Posts:
    17
    Yes, they are using Draw3D, and the material is the DefaultLine3D material. I've tried changing the render queue value on that shader, but that doesn't fix the problem. The occluding object uses the standard shader, but not all objects in the scene that use the standard shader cause the problem. I don't know shaders well; is there something else I should be looking at besides the render queue value?
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    Try using a different shader entirely, such as the standard shader.

    --Eric
     
  5. Blightbuster

    Blightbuster

    Joined:
    Feb 14, 2017
    Posts:
    4
    Hey Eric, is there a way to render Sprites over a VectorLine in 2D space? I couldnt do it by just changing the z position.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    You need to set the vector canvas to be screen space overlay, then you can change the sorting layer of the canvas.

    --Eric
     
  7. GrumpyFour

    GrumpyFour

    Joined:
    Jan 12, 2016
    Posts:
    17
    OK, sorted. I created a new material using the Unlit/Color shader and assigned it to my VectorLines. That gets me the results I want. There is definitely something up with the way I have my scenes set up; I created a new material using the Particles Alpha Blended shader, and in some scenes objects with that material are opaque, but in others translucent. So I'm working around rather than resolving the underlying problem, but that problem has nothing to do with Vectrosity. Thanks again, Eric.
     
  8. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,046
    I am not moving the sprites (the GO). I am moving the camera (left/right/up/down) so obviously the sprites will appear in a different location on screen. The lines are supposed to follow. I guess I could move the sprites or parent object, rather than the camera, if I must.

     
    Last edited: Feb 26, 2017
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    I was explaining how .drawTransform works with 2D screen space lines. Sprites are world space, so lines that interact with them should also be world space.

    --Eric
     
  10. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,046
    ah.. so I was supposed to use Draw3D() . But now I am back at struggling to get the lines to draw in front of the sprites. The sprites are all on z=0. Changing the line.rectTransform.position or feeding line.MakeCurve() with points on a different z value (positive or negative) has no effect on this.
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    Sprite drawing order is done with Renderer.sortingLayerName and Renderer.sortingOrder.

    --Eric
     
  12. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,046
    I know. Can a Line be drawn in front of sprites or not and if so, how?
     
  13. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,046
    If anyone else is struggling with this.

    Code (CSharp):
    1.  
    2. ...
    3. line.Draw3D(); // after this else Renderer is not present.
    4. line.rectTransform.gameObject.GetComponent<Renderer>().sortingLayerID = WOTEVER;
    5.  
     
  14. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
    Hi Eric,

    I have a set of nodes plotted randomly, which you can check out here. I want to use Vectrosity to create a dynamic and infinite line through these points, as the camera moves along. Is this possible? Could you please assist me in doing this?Thanks.

    8Development
     
  15. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    It sounds like you basically want to do the SplineFollow demo?

    Screen Shot 2017-03-02 at 3.21.11 PM.png

    If so, have a look at that demo.

    --Eric
     
  16. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    271
    Hiya Eric!

    I don't believe there's a built in way to draw a rounded corner rectangle, but I don't suppose you've made one before? I'm hoping to come up with a method such as DrawFrame(width, height, cornerRadius), but can't seem to find a good starting point for doing this.
     
  17. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    VectorLine.MakeRoundedRect. ;)

    --Eric
     
  18. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    Your code has errors in it, so it won't run. For example, VectorLine must be made with a List, not an array.

    --Eric
     
  20. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    271
    That looks like it might work! :rolleyes: I searched for it, but evidently failed. Thank you!
     
  21. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    271
    Hi again!

    Is there a way to use the UI's anchor tools to draw things in place? I have tried adjusting anchored position and pivot, but it still draws in the same place. I'd like to specify how far from the right hand side to draw rather than calculating the screen width and subtracting its width.

    (As well as it automatically being positioned should the screen size change.)

    Thanks!
     
    Last edited: Mar 3, 2017
  22. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    No, sorry, using Screen.width and subtracting the amount you want from the right is the way to do it. You could also use viewport coords, where e.g. 0.9 for X is always 90% of the way across the screen.

    --Eric
     
  23. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
    Hello Eric,
    I've just updated the method to take in a List. I do get errors and the line doesn't show:
    Code (CSharp):
    1. VectorLine.MakeSpline: The length of the array for continuous lines needs to be at least the number of segments plus one for "Spline"
    2. UnityEngine.Debug:LogError(Object)
    3. Vectrosity.VectorLine:CheckArrayLength(FunctionName, Int32, Int32)
    4. Vectrosity.VectorLine:MakeSpline(Vector2[], Vector3[], Int32, Int32, Boolean)
    5. Vectrosity.VectorLine:MakeSpline(Vector3[], Int32)
    6. LevelGenerator:DrawCurve() (at Assets/Scripts/LevelGenerator.cs:45)
    7. LevelGenerator:SpawnChunkRoutine() (at Assets/Scripts/LevelGenerator.cs:40)
    8. LevelGenerator:Start() (at Assets/Scripts/LevelGenerator.cs:25)
    This is the method:
    Code (CSharp):
    1.  
    2. private void DrawCurve() {
    3.     var spline = new VectorLine("Spline", new List<Vector2>(new Vector2[segments+1]), lineMaterial, 2.0f, LineType.Continuous);
    4.     spline.MakeSpline (nodesList.ToArray(), segments+1, false);
    5.     spline.Draw();
    6. }
    7.     }
    Shouldn't this work, as I found the JavaScript alternative in MakeSpline.js:
    Code (CSharp):
    1. if (usePoints) {
    2.         var dotLine = new VectorPoints("Spline", new Vector3[segments+1], null, 2.0);
    3.         dotLine.MakeSpline (splinePoints.ToArray(), segments);
    4.         dotLine.Draw();
    5.     }
    Thanks,
    8Development
     
    Last edited: Mar 3, 2017
  24. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    You need to fix all errors before a script will run. You can't use the same number for the points in the line and the line segments, since those are different things (which depend on whether the line is Continuous or Discrete).

    --Eric
     
  25. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
    Alright, thanks.
    I'm not sure what happened here, but this isn't a curve:
    \
    There are six points in the nodes array, yet all the points aren't touched by the line, and this is definitely not a curve.

    Is there anything I have missed - what can I do to make it look curved and got through all the points in order?

    Thanks,
    8Development
     
  26. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    You need to use many points for a line that you want to be curved, since "curves" are made out of many short straight line segments.

    --Eric
     
  27. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
  28. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    More points in the line, not more points to connect. If the number of segments in the line is the same as the number of points you're connecting, you can only have straight lines. Curves are made out of many short straight line segments.

    --Eric
     
  29. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
    Eric,
    Thanks for your reply. Would it be possible for me to use these points (that are randomly generated) as control points, and instead find points on that line? If that is possible, does Vectrosity support this? Is there any appropriate place in the manual or reference guide which you can guide me to, or should I just use VectorLine.MakeSpline()?
    8Development
     
  30. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    MakeSpline already uses the points as control points, where the spline passes through those points. (Specifically, it's a centripetal Catmull-Rom spline.) I'm not sure what you mean by "find points on that line".

    --Eric
     
  31. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
    Alright, great! So how would I create points that are close together? Are there any algorithms or docs you could point me to perhaps?
    8Development
     
  32. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    I don't really understand that, sorry. What are you actually trying to do?

    --Eric
     
  33. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
    Hello Eric,
    I've followed up in a private conversation.
    8Development
     
  34. Netbandit

    Netbandit

    Joined:
    Feb 16, 2014
    Posts:
    18
    Hi

    I want to create a dashed line to indicate the path in a hex-map based strategy game.

    First of all I use quadratic bezier splines (custom implementation) to have a smooth curvy path when walking from one hex-field to another. This means in every hex field, there are 10 points for that line.
    However in the very first and very last hex-field, where the line is just straight forward, there is only one point (start-point or end-point).

    I use a texture that is 5x10 pixel, where only the rect (4,2) to (7,4) is filled with white pixels, the remaining pixels are transparent.

    This line looks like the first picture:
    AlmostRight.png

    This is almost right, except of some details, like the starting and ending line, where the texture is just lengthened to the whole line segment. And sometime there are very small white spots in the transparent gaps.

    Ok I thought this issue is due to a wrongly configured "textureScale", thus I set textureScale to 2f, since the width is two times the height. However this leads to a completely wrong line:
    TextureScale2.png

    It seems, that the texture starts from beginning at every new point. Furthermore the texture is continuous trough the whole line segment. Setting continuousTexture to true or false does not change anything.

    This is the code I'm using:

    Code (CSharp):
    1.         PathLine.active = true;
    2.         PathLine.material = PathLineMaterial;
    3.         PathLine.texture  = PathLineTexture;
    4.         PathLine.textureScale = 2f;
    5.         PathLine.continuousTexture = false;
    6.         PathLine.Draw3D();
    7.         PathLine.rectTransform.SetParent(transform);
    8.  
    Does anyone have a hint, what I need to change to get a nice dashed line from the very beginning to the very end?
     
  35. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    Hi, I'm not able to reproduce this. It looks from the screenshots that you have set textureScale after drawing the line and then did not call Draw3D again. If that's not the case, the only other thing I can think of is that you have duplicate points in the line. VectorLine.continuousTexture is for stretching a single texture along the entire length of a line and is not appropriate for this case (see illustrations in the docs). It also does not have any effect when set after drawing a line, unless you draw the line again.

    --Eric
     
  36. Netbandit

    Netbandit

    Joined:
    Feb 16, 2014
    Posts:
    18
    Hi Eric,

    thanks for your reply. I tried to reproduce it on a minimal project to send to it you. However I was also not able to reproduce the error in a new Unity environment. After checking everything, I saw my texture settings were wrong: I set the texture to clamp instead of repeat and this leads to the error.

    I'm very sorry for such a stupid error reporting, but maybe this helps other people to find a similar mistake earlier.

    Thanks for this very good asset, I like it!
     
  37. EndUser

    EndUser

    Joined:
    Aug 12, 2013
    Posts:
    51
    Hello!
    Interested in this package.
    Where can I learn how to turn on and turn off prepared lines on user demand {hotkey}?
    Where can I learn how to change line points {quantity and coordinates} on Update()?
    Or may be this is a simple pattern and someone can post these code fragments right here?
    Thank you!
     
  38. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    If it makes you feel better, you're not the only one to do this...I put it in the docs, but it sounds like it would be a good idea to put it in the troubleshooting section too.

    You can use VectorLine.active for turning lines on and off.

    Lines use a Vector2 list or a Vector3 list for the coords, so it's just a matter of changing what you want in the list and re-drawing the line.

    --Eric
     
    EndUser likes this.
  39. EndUser

    EndUser

    Joined:
    Aug 12, 2013
    Posts:
    51
    Hello, Eric5h5!
    Thank you!
    I don't quite understand
    Would you like to help me with Start() and Update() templates?
    I tried
    Code (csharp):
    1. void Start()
    2. {
    3.     listPoints.Add(new Vector2(0, Screen.height * 0.50f));
    4.     listPoints.Add(new Vector2(Screen.width, Screen.height * 0.50f));
    5.     vlineReticle = new VectorLine("Hud", listPoints, 1.0f, LineType.Discrete);
    6.     vlineReticle.color = Color.green;
    7.     //For some reason unknown I must finalize building of vlineReticle via Draw()
    8.     //which activates on-screen drawing, then turn off at once until a better moment.
    9.     vlineReticle.Draw();
    10.     vlineReticle.active = false;
    11. }
    12. void Update()
    13. {
    14.     //and I have a run-time error every frame "NullReferenceException:
    15.     //Object reference not set to an instance of an object" here:
    16.     if (!vlineReticle.active)
    17.     {
    18.          return;
    19.     }
    20.     //I haven't gone thus far, since I don't understand whether I can
    21.     //listPoints.Clear(), vlineReticle.points2.Clear(),
    22.     //then redefine and directly assign vlineReticle.points2 = listPointsUpdated
    23.     /*nothing yet*/
    24. }
    25.  
    What should I do exactly to rebuild vlineReticle.points2 without run-time exceptions?
    Head-up Display info should be dynamic.
    Earlier I did:
    Code (csharp):
    1.  
    2. void Update()
    3. {
    4.         listPoints.Clear();
    5.         VectorLine.Destroy(ref vlineReticle);
    6.         BuildDiscretePointList(ref listPoints);
    7.         vlineReticle = new VectorLine("Hud", listPoints, 1.0f, LineType.Discrete);
    8.         vlineReticle.color = Color.green;
    9.         vlineReticle.Draw();
    10. }
    11.  
    But I guess that destroying and recreating an object is a bad idea, despite it seemingly works.
    Thank you!
     
  40. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    Don't destroy and recreate lines, especially not in Update. Create a line once only, and change the list of points that you use when creating the line. It's just a standard List, use standard List functions like Add/Remove/etc., nothing special. Don't assign points2, just use the List you used to make the Line. I'm not sure what else you're doing with your code, since I don't have any of those issues you mention in the comments when using the code you posted (no null ref exceptions and so on).

    --Eric
     
    EndUser likes this.
  41. EndUser

    EndUser

    Joined:
    Aug 12, 2013
    Posts:
    51
    Ok, your hints helped me to form this template:
    Code (csharp):
    1. //Task: display position of a gun which follows player's look.
    2. //If you need to relocate gunsight reticles after screen resize,
    3. //  use distScreenWidthPrev != Screen.width in Update function
    4. //  to call UpdateImage() again
    5. void Awake()
    6. {
    7.     //listPoints is empty yet. Just needed for the constructor
    8.     vlineReticle = new VectorLine("Hud Gun", listPoints, 1.0f, LineType.Discrete, Joins.Weld);
    9.     vlineReticle.Resize(0);
    10.     UpdateImage();
    11. }
    12. void OnEnable()
    13. {
    14.     vlineReticle.active = true;
    15. }
    16. void OnDisable()
    17. {
    18.     vlineReticle.active = false; //the same command can be issued by player's desire
    19. }
    20. void Update()
    21. {
    22.     if (Camera.current == null)
    23.         //Sometimes when I switch between different cameras,
    24.         //there are some cycles with no cameras at all
    25.         //Using anything from Camera.current will cause an exception at this moment
    26.     {
    27.         return;
    28.     }
    29.     UpdatePosition();
    30.     UpdateChargedState();
    31.     UpdateImage();
    32. }
    33. void UpdatePosition()
    34. {
    35.     posScrAim = Camera.current.WorldToScreenPoint(posAim);
    36.     distRight = posScrAim.x;
    37.     distUp = posScrAim.y;
    38. }
    39. void UpdateImage()
    40. {
    41.     Color colorGunReticle = (coeffCharged == 1.0f) ? Color.green : Color.yellow;
    42.     int degStart = 0;
    43.     int degFinish = Mathf.RoundToInt(coeffCharged * 360);
    44.     int qtySegments = Mathf.Max(3, Mathf.FloorToInt(4 * distRadius * (degFinish - degStart) / 360));
    45.     vlineReticle.Resize(qtySegments * 2); //I guess that changing allocated memory is not too good.
    46.     vlineReticle.MakeArc(new Vector3(distRight, distUp, 0), distRadius, distRadius, degStart, degFinish, qtySegments);
    47.     vlineReticle.SetWidth(distThickness);
    48.     vlineReticle.SetColor(colorGunReticle);
    49.     vlineReticle.Draw();
    50. }
    Thank you very much!

    Is it... not too wrong? ;-)

    Two questions

    1) Obviously, circle segments quantity could be reduced for tiny circles and must be larger for big circles. I cannot find default quantity of segments in docs. Is there an optimal maximal capacity of points2 list to avoid resizing yet not overusing memory or CPU?

    2) How can I draw lines over
    GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), vignetteBinoculars, ScaleMode.ScaleAndCrop, true, 0);
    ?

    Thank you!
     
    Last edited: Mar 11, 2017
  42. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    It's not too wrong. ;) Take out the Resize() stuff though. Just add/remove points from the list as needed. For best results, make the list as big as it will ever need to be and change VectorLine.drawEnd when using fewer points.

    1) There's not an optimal capacity; it depends too much on what you're doing.
    2) You can't; nothing can draw on top of OnGUI. Switch to the other GUI system.

    --Eric
     
    EndUser likes this.
  43. EndUser

    EndUser

    Joined:
    Aug 12, 2013
    Posts:
    51
    Thank you!

    Do you have alternative ideas for drawing vignettes?
     
  44. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    I'm not sure what you mean by that.

    --Eric
     
  45. EndUser

    EndUser

    Joined:
    Aug 12, 2013
    Posts:
    51
    I mean:
    Game mode: sniper sight, which looks like black screen with transparent circle in centre. With reticles.
    Developer must draw additional information, like compass, ammo counter, minimap etc.
    I have drawn "black screen with transparent circle" vignette as a texture at OnGUI() moment.
    You say that OnGUI() is the very last event of the main cycle, so it overrides any images rendered before, including Vectrosity.
    (And recently Unity5.5 killed "simple" way to draw lines in GUI-class, that's why I run for Vectrosity).

    So, the question: do you know by chance any other method of drawing vignettes earlier than OnGUI(), so Vectrosity could draw lines over vignettes.

    Sorry, my question doesn't relate directly to Vectrosity library, but I hope Vectrosity people ;-) know relations of the lib to other graphics libraries to interact with to draw lines over images prepared earlier or later.

    Thank you!

    P.S. And, by the way, at which moment Vectorisy draws? At OnPostRender()?
     
  46. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    As I mentioned, use the other ("new") GUI system. (Sorry but it doesn't have an actual name...and for this reason people asked Unity to please call it something other than Unity GUI but they didn't listen. ;) ) Depending on whether you use Draw or Draw3D, Vectrosity uses the "new" GUI system or else it's just a standard mesh.

    --Eric
     
    EndUser likes this.
  47. flairzguru

    flairzguru

    Joined:
    Jan 29, 2017
    Posts:
    6
    Hello Eric,
    First of all thank you so much for your valuable time and quick responses as always.
    I am trying to figure out solution of my new problem through old posts but couldn't find any satisfactory solution. I want smoother and round joints for two lines, please be noted that collider is enabled for line so it will used as path for ball movement. "maxWeldDistance" property is not that useful in this case and also I am using "brick" texture provided in example.
    Please check attachment.

    SmoothJoints.png
     
  48. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    Hi, I'm not clear on what you're asking for. I can't see anything objectionable in the screenshot?

    --Eric
     
  49. flairzguru

    flairzguru

    Joined:
    Jan 29, 2017
    Posts:
    6
    I want smoother and round joints between two line section mentioned in red circle.
     
  50. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,149
    Oh, sorry, I thought the lines in question were the red circles, not the path. :) You'd need to add more points to the line.

    --Eric