Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Vectrosity - Fast and Easy Line Drawing

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

  1. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That shouldn't be necessary; the points would be the same for both lines, they just need to be oriented to different cameras separately.

    I did this as a quick test with two cameras and it works as expected:

    Code (javascript):
    1. var lines : VectorLine[];
    2. var cameras : Camera[];
    3.  
    4. function Start () {
    5.     lines = new VectorLine[2];
    6.     lines[0] = new VectorLine("Line1a", [Vector3.zero, Vector3(2, 0, 2)], null, 2.0);
    7.     lines[1] = new VectorLine("Line1b", [Vector3.zero, Vector3(2, 0, 2)], null, 2.0);
    8. }
    9.  
    10. function Update () {
    11.     for (var i = 0; i < 2; i++) {
    12.         VectorLine.SetCamera3D (cameras[i]);
    13.         lines[i].Draw3D();
    14.     }
    15. }
    The only thing is, I'd recommend having the lines use different layers, along with appropriate culling layers for the cameras, so the cameras only see "their" lines.

    You can use VectorLine.drawTransform to associate a line with a transform, and use transform.Translate with that transform.

    --Eric
     
  2. matias-e

    matias-e

    Joined:
    Sep 29, 2014
    Posts:
    106
    Is it possible to link the collider attached to the VectorLine to OnTriggerEnter's collider?
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You'd need to use AddComponent to attach a script to the line object.

    --Eric
     
  4. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    Hi Eric5h5,

    I bought vectrosity about 1.5 years ago and I think it is "The tool" for any line rendering needs.

    These days I'm building a little drawing tool into unity and I'm using Vectrosity for the line drawing but I need to delete parts of it too. I mean, the user moves his finger over the screen and a line is drawn following the finger movement but then the user can select the eraser tool and again move his finger over the screen and he must be able to delete parts of the line as he moves his finger over it.

    Would you mind suggesting a way to do this?

    Cheers.
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You can use Selected(), which has an index of the line segment that was selected, so you can use that to delete the appropriate points.

    --Eric
     
  6. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    Hi,

    Thanks for the answer. Anyway I don't know if you understood my question (or I did not explain the problem the correct way).

    The main problem is, I have a line and I can pass my finger over it and erase a part of it. I think the segments you suggest is not a solution because I need to split the line in two parts (I think), because now after deletin a bit of the line it is not a continuos line.

    Cheers.
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I was assuming you were using a discrete line. If you weren't, you should.

    --Eric
     
  8. Game-Whiz

    Game-Whiz

    Joined:
    Nov 10, 2011
    Posts:
    122
    I'd like to be able to move the camera in the DrawLinesTouch example (to zoom in/out). I've set Line3D to true but if I move the camera the line disappears. How can I correct this?
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Redraw the line after moving the camera.

    --Eric
     
  10. Dazzid

    Dazzid

    Joined:
    Apr 15, 2014
    Posts:
    61
    HI Eric,
    One question. I have a VectorLine that reads an array of 2 vectors. One point is a fixed position in the 3D space, but the other point is moving, how can update only this vector to make the line move only in one of the sides?
    Thaaanks for the help
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Update the point that's moving, either with VectorLine.points2/points3, or in the list used to create the line.

    --Eric
     
  12. Dazzid

    Dazzid

    Joined:
    Apr 15, 2014
    Posts:
    61
    Ah ok! I'm new in Vectrosity, it rocks thanks!
     
  13. sharksharkshark

    sharksharkshark

    Joined:
    Apr 27, 2015
    Posts:
    13
    Eric,

    I'm using the Oblique Projection script found here: https://github.com/keijiro/unity-oblique-projection on my MainCamera.

    I'm having problems with Vectrosity not showing the line unless the "Z Scale" property of the Oblique Projection script is set to 0. Does this have something to do with the camera's projection matrix changing?

    I've attached a simple sample of my test code, which assumes you have the Oblique Projection script attached to your MainCamera, with Angle: 0, Z Scale: 1, and Z Offset: 0.

    Is there a way to make this render in 3D space with this type of projection?
     

    Attached Files:

  14. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Hi, I'm not sure if that can work, sorry. I'm not able to test it right now since I'm not at my computer with Unity.

    --Eric
     
  15. Dazzid

    Dazzid

    Joined:
    Apr 15, 2014
    Posts:
    61
    Hi,
    One question about best way to program something.
    I have a visualization with 1000 nodes. Each node has multiple connections to other nodes. I think I should add Vectrosity to the node class to draw this connections in a 3D space.
    My point is, the array of connections is made with a List<Edge>(); and Edge is a struct with information about the weight of the connection and some other things. My question is, what is the best way to do it with Vectrosity? Just with VectorLine? and then translate the List to an fixed array of points?
    I do this question because also, the array Edges has the other nodes ID's, so that means I have to translate this List to an array[] with the original position and then other node position, and then again, the original position and the second node position etc... it is clear the question?

    My other problem is that I have "Canvas element contains more than 65535 vertices. This is not supported"

    I'm trying something like this:
    Code (CSharp):
    1. public void RecalculateEdges ()
    2.     {
    3.         Material material = new Material (Shader.Find ("Particles/Alpha Blended"));
    4.         Color lineColor = new Color (0.0f, 0.5f, 1.0f, 0.1f);
    5.         material.SetColor ("_TintColor", lineColor);
    6.  
    7.         for (int i = 1; i <= gm.nodeCount; i++) {
    8.             int switching = 0;
    9.             Vector3[] nodeArray = new Vector3[gm.Nodes [i].EdgesTo.Count];
    10.             //Debug.Log ("array: " + gm.Nodes [i].EdgesTo.Count);
    11.             for (int j = 1; j < gm.Nodes [i].EdgesTo.Count; j++) {
    12.                 if (switching == 0){
    13.                     nodeArray [j-1] = gm.Nodes [i].currentCoordinates;
    14.                     Debug.Log ("counter: " + (j-1));
    15.                 }
    16.                 if (switching == 1)
    17.                     nodeArray [j] = gm.Nodes [gm.Nodes [i].EdgesTo [j].NodeTo].currentCoordinates;
    18.                 switching++;
    19.                 switching = switching % 2;
    20.             }
    21.             myLine.Add (new VectorLine ("name" + i, nodeArray, material, 1.0f, LineType.Continuous, Joins.Weld));
    22.         }
    23.     }

    Thanks a lot for the hep
     
    Last edited: Jun 15, 2015
  16. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Use a List of points, rather than a fixed array. You have to use multiple canvases if you exceed 65K verts.

    --Eric
     
  17. Dazzid

    Dazzid

    Joined:
    Apr 15, 2014
    Posts:
    61
    Hi!
    Ok cool! Actually I'm drawing all the lines with the fixed array. Like this code: But I can't find the way to draw behind the spheres (nodes) where the connections happens. I'm trying to use SetLine or SetRay3D but I get this error.
    Static member `Vectrosity.VectorLine.SetLine3D(UnityEngine.Color, params UnityEngine.Vector3[])' cannot be accessed with an instance reference, qualify it with a type name instead

    Code (CSharp):
    1. public void RecalculateEdges ()
    2.     {
    3.         for (int i = 1; i <= gm.nodeCount; i++) {
    4.             Material material = new Material (Shader.Find ("BlackLine"));
    5.             Color lineColor = new Color (gm.Nodes [i].myColor.r, gm.Nodes [i].myColor.g, gm.Nodes [i].myColor.b, 0.1f);
    6.             material.SetColor ("_Color", lineColor);
    7.  
    8.             int switching = 0;
    9.             Vector3[] nodeArray = new Vector3[gm.Nodes [i].EdgesTo.Count/2];
    10.             //Debug.Log ("array: " + gm.Nodes [i].EdgesTo.Count);
    11.             for (int j = 0; j < gm.Nodes [i].EdgesTo.Count/2; j++) {
    12.                 if (switching == 0){
    13.                     nodeArray [j] = new Vector3(gm.Nodes [i].currentCoordinates.x, gm.Nodes [i].currentCoordinates.y+0.5f, gm.Nodes [i].currentCoordinates.z);
    14.                     //Debug.Log ("counter: " + (j-1));
    15.                 }
    16.                 if (switching == 1){
    17.                     Vector3 nodePos = gm.Nodes [gm.Nodes [i].EdgesTo [j].NodeTo].currentCoordinates;
    18.                     nodeArray [j] = new Vector3( nodePos.x, nodePos.y+0.25f, nodePos.z) ;
    19.                 }
    20.                 switching++;
    21.                 switching = switching % 2;
    22.             }
    23.  
    24.             myLine.Add (new VectorLine ("name_" + i.ToString (), nodeArray, material, 1.0f, LineType.Continuous, Joins.Weld));
    25.             //myLine[i].SetLine3D(lineColor, nodeArray);
    26.         }
    27.     }
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I'd suggest using a List instead of an array, so it doesn't have to copy the values, and use Draw3D.

    --Eric
     
  19. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,816
    I've just purchased Vectrosity and I must say after looking through the demos and playing around a bit, it is indeed a very powerful package, nice work!

    I've had a Google around but can only find old posts, but is it possible to fill a set of drawn lines in with a mesh or colour? For instance I want a user to make a selection by defining a set of points, and once they have at least 3 points, I want the inner area to be filled to highlight the selected area.

    Is there is an easy way to do this? I couldn't find anything in the docs.

    Thanks
     
  20. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Thank you! Vectrosity is for line-drawing only though; there's no functionality for making filled shapes.

    --Eric
     
  21. UCh

    UCh

    Joined:
    Nov 18, 2012
    Posts:
    29
    Hi,

    I just brought Vectrosity on the asset store. The library is fantastic! But I got an issue and I'm sure I'm doing something wrong. I searched on the forums but I don't see anyone with that problem. So... I created a 3D grid using the 2D one on the demos as a reference, but in C#. So far so good. The issue is that when I'm moving the camera, some lines randomly disappear/reappear for no reason. I'm redrawing the line each update (I tried with auto and manually).

    Here's my code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Vectrosity;
    4.  
    5. public class ReferenceGridView : MonoBehaviour {
    6.  
    7.     public float cellSize = 10.0f;
    8.     public int columns = 20;
    9.     public int rows = 20;
    10.     public Material lineMaterial;
    11.     public float lineWidth = 2;
    12.  
    13.     private VectorLine gridLines;
    14.  
    15.     void Start () {
    16.         gridLines = new VectorLine ("Grid", new Vector3[0], lineMaterial, lineWidth);
    17.         gridLines.drawTransform = transform;
    18.         MakeGrid ();
    19.     }
    20.  
    21.     void Update () {
    22.         gridLines.Draw3D();
    23.     }
    24.  
    25.     void MakeGrid()
    26.     {
    27.         gridLines.Resize ((rows + columns) * 2);
    28.  
    29.         float halfWidth = (columns-1) * cellSize * 0.5f;
    30.         float halfHeight = (rows-1) * cellSize * 0.5f;
    31.  
    32.         int index = 0;
    33.         for (int col = 0; col < columns; col ++) {
    34.  
    35.             float x = (col*cellSize)-halfWidth;
    36.  
    37.             gridLines.points3[index++] = new Vector3(x, 0, -halfWidth);
    38.             gridLines.points3[index++] = new Vector3(x, 0, halfWidth);
    39.         }
    40.  
    41.         for (int row = 0; row < rows; row ++) {
    42.  
    43.             float z = (row*cellSize)-halfHeight;
    44.  
    45.             gridLines.points3[index++] = new Vector3(-halfHeight, 0, z);
    46.             gridLines.points3[index++] = new Vector3(halfHeight, 0, z);
    47.         }
    48.     }
    49. }
    50.  
    The camera that I'm using is a regular perspective camera with an orbit script to rotate and zoom around a game object. I uploaded a package with a simple scene with the issue, just add Vectrosity dll, run the scene and move the mouse around zooming in and out with the wheel.

    Do you see anything obviously wrong here?
     

    Attached Files:

  22. UCh

    UCh

    Joined:
    Nov 18, 2012
    Posts:
    29
    Just for the record. I changed to version 3 and now the grid behaves as expected without any change on my code, so maybe is a canvas related issue.
     
  23. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It's probably code changes to prevent lines from rendering when they should be behind the camera and therefore invisible. You can fix this by subdividing the grid lines into more segments. Perhaps a "always render all line segments no matter what I don't care just do it" mode would be useful?

    --Eric
     
  24. UCh

    UCh

    Joined:
    Nov 18, 2012
    Posts:
    29
    Well... each line of the grid is a single segment, so a single quad? I don't see why one line that is crossing from the back of the camera to the other end should be removed. Can be a side effect of using canvas and rectTransform for 3D lines?
     
  25. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, it's the Vectrosity line segment culling code. It tries to remove segments that cause rendering artifacts, but in some cases this errs on the side of removing segments that would be OK. Typically this is for lines where one point is far in front of the camera and the other point is far behind, which is why subdividing the segment fixes the issue.

    --Eric
     
  26. wbl1

    wbl1

    Joined:
    Apr 22, 2009
    Posts:
    159
    Sorry if this is an idiotic question (I am good at those), but I am getting more and more comfortable with the new Canvas system and overall RectTransform concept for positioning UI items relative to their parent and the screen,etc.

    Here's the question ... let's say I want to create some sort of graph using Vectrocity and I want the graph to be displayed over a Panel. Is there some clever way to define the vectrocity lines/points etc. such that if I use the RectTransform tools to move the panel around that the vectrocity elements will stay with it ...?

    Hopefully this makes some sense ...
     
  27. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You can use VectorLine.rectTransform for that, yes.

    --Eric
     
  28. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Hi Eric,

    I'm trying to update a list of points for a VectorLine. According to your docs:
    "If you supply a generic List instead of an array, the points2 or points3 list will be a reference to the list you supplied, so making changes in either your list or VectorLine.points2/points3 will have the same effect."

    In the following code, DrawMovementVectors is called by another script every frame. The first Debug.Log outputs two vectors, so I know the list that the VectorLine was constructed with is updated, but the second Debug.Log shows an ArgumentOutOfRangeException. Unless I'm messing something up, shouldn't VectorLine.points3 be pointing to the list it was created with?

    Code (CSharp):
    1. private VectorLine movementLine;
    2. private List<Vector3> waypointsList = new List<Vector3>();
    3.  
    4. public void Initialize()
    5. {
    6.     movementLine = new VectorLine("MovementLine", waypointsList, null, 10.0f, LineType.Continuous);
    7. }
    8.  
    9. public void DrawMovementVectors(List<Vector3> waypoints)
    10. {
    11.     waypointsList = waypoints;
    12.     Debug.Log(waypointsList[0] + " " + waypointsList[1]);
    13.     Debug.Log(movementLine.points3[0]);
    14.     movementLine.Draw3D();
    15. }
    According to your SelectLine example, I see that you loop through the VectorLine.points2 list and set the values accordingly. It works if I do the same, but since the waypoints argument being passed into the DrawMovementVectors method can change size, I have to clear the VectorLine.points3 list every frame and then add the elements, which is fine, but I think I'm missing something here and would appreciate some help.
    Thanks.
     
  29. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Try using the ref keyword to pass by reference explicitly. Also make sure you're using the latest version of Vectrosity.

    --Eric
     
  30. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Hi Eric, thanks for the prompt response.

    I'm using Vectrosity 4.2 which I just downloaded from the Asset Store two days ago.

    I tried DrawMovementVectors(ref List<Vector3> waypoints) and adjusted the calling method accordingly, but am still getting the same exception.

    It seems like if I try to set the waypointsList (which the VectorLine was constructed with) to either a different list, or a new list, then I get the ArgumentOutOfRangeException. If I modify the waypointsList using Clear() then iterate through the arguments list and add the elements one by one, or set the elements directly, there is no exception thrown.

    Is this intended behavior? Does it have something to do with points3 not being settable?
     
  31. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Possibly...stuff like this definitely works though:

    Code (csharp):
    1. var points = new List<Vector3>();
    2. points.Add (Vector3.zero);
    3. points.Add (Vector3.one);
    4. line = new VectorLine("Line", points, null, 2.0f, LineType.Continuous);
    5. line.Draw();
    6. points.Add (new Vector3(2, 2, 2));
    7. line.Draw();
    --Eric
     
  32. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,614
    When using SetEndCap, is there a way to first check if a style (with a matching name) has already been created?
     
  33. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Not currently, but that's a good idea for the next version. (Really just a matter of checking if the name is in the end cap dictionary.)

    --Eric
     
    angrypenguin likes this.
  34. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    I was trying to setup a 3D scene where the user can draw on a 3D object's surface with the mouse. For a specific example, my scene has a 3D whiteboard that the user can draw on with the mouse.

    I was wondering what might be the best approach to achieving this with Vecrosity? I looked at the sample scene with the DrawLinesMouse example scene, so I understand how to draw with Vecrosity, but I can't quite get it to work in a scenario like I described.
     
  35. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Probably raycasting to get the points that you'd add to a Vector3 list.

    --Eric
     
  36. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Looks like that did the trick. Thanks.
     
  37. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    The requirements from my client have changed, and now they are requiring that the 3D whiteboard I draw on shows up as a UI element, so the UI element shows the drawing in real-time as the drawing happens in the 3D scene.

    I'm using the Raycast to draw on the specific whiteboard surface in the 3D world with your drawing example code, but I'm not sure how to update the UI element with the drawing on it as well. My issue seems to be with converting the drawing coordinates on the 3D world's mesh to the 2D UI's image.
     
  38. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I'm not sure I understand; Vectrosity lines are already UI elements.

    --Eric
     
  39. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    I made a photo to better visualize it. I hope it makes more sense.
    VectrosityLineDrawing.png
     
  40. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Sounds like using a rendertexture is the way to go.

    --Eric
     
  41. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    So currently, I'm using Vecrosity and Raycasting to draw the Vectrosity line on the mesh collider by setting the RaycastHit world coordinates as the Vectorsity line points.

    Do you know how a rendertexture would help with this? I thought rendertexture was for directly modifying the texture itself?

    If that is what I have to do, is there a way to draw a Vectrosity line directly to a texture?
     
  42. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    A rendertexture renders a camera to a texture.

    --Eric
     
  43. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Wouldn't the rendertexture capture everything in the camera, not just the whiteboard? I'm not sure that would work for my case. There are scenarios where the whiteboard can be on a 3D corner between two walls.
     
    Last edited: Jun 24, 2015
  44. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Use layers to determine what a camera can see.

    --Eric
     
  45. Rikrok

    Rikrok

    Joined:
    Apr 11, 2013
    Posts:
    50
    If I'm manipulating the points in a vector 3 array is this the best way to update the line? I'm using vector manager.
     
  46. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It would be best not to clear the points3 list unless you really need to. Preferably you'd update the points in-place. You can add/remove/etc. with points3 directly.

    --Eric
     
  47. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,614
    I'm trying to render lines on multiple cameras. My approach is that when the camera changes I use VectorLine.SetCamera3D or VectorLine.SetCanvasCamera to set the new camera. I then call Render on that camera (which renders to a texture). Then SetCamera3D is called again back to my main camera. This is currently for once-off renders to texture when the user presses a button.

    The lines aren't showing up in my second camera. From this page I see that the approach is confirmed as not working for Vectrosity 4. So then, what is the recommended approach for viewing lines from multiple cameras in Vectrosity 4?
     
  48. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You'd need to use two sets of lines, as discussed here.

    --Eric
     
  49. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    Is there going to be support for the Unity UI? Like say, adding some VectorLine object to a Canvas, which I could then edit in editor mode?
     
  50. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Vectrosity already uses the Unity UI. There isn't currently any support for manual editing in editor mode.

    --Eric