- Home /
Question is off-topic or not relevant
How do you have a line renderer render multiple lines from 1 mouse click?
So essentially, I have 2 lines with vertices attached to each ends as "sprites", the point of the script is that you click on the middle vertex and drag with your mouse a line from that vertex to the white vertex. When you connect the dots, you get a "good job" message and the level resets on another script.
However, what I want to do is also create 2 lines from the top and bottom vertices to also link to the mouse when dragging the line:
So essentially here is the current design:
And here is what I want it to do:
This way, it creates a "parallelogram" of the 4 vertices.
This is the script I have attached to the middle vertex:
public class DrawLine : MonoBehaviour
{
public Material _lineMaterial;
public float _lineWidth;
private LineRenderer _lineRenderer;
bool _overVertex = false;
void OnMouseOver()
{
_overVertex = true;
}
void OnMouseExit()
{
_overVertex = false;
}
public void Start()
{
_lineRenderer = gameObject.AddComponent<LineRenderer>();
_lineRenderer.SetWidth(0.1f, 0.1f);
_lineRenderer.enabled = false;
}
private Vector3 _initialPosition;
private Vector3 _currentPosition;
public void Update()
{
if (Input.GetMouseButtonDown(0) && _overVertex == true)
{
_initialPosition = GetCurrentMousePosition().GetValueOrDefault();
_lineRenderer.SetPosition(0, _initialPosition);
_lineRenderer.SetVertexCount(1);
_lineRenderer.enabled = true;
_lineRenderer.material = _lineMaterial;
_lineRenderer.startWidth = _lineWidth;
}
else if (Input.GetMouseButton(0))
{
_currentPosition = GetCurrentMousePosition().GetValueOrDefault();
_lineRenderer.SetVertexCount(2);
_lineRenderer.SetPosition(1, _currentPosition);
}
else if (Input.GetMouseButtonUp(0) && _overVertex == true)
{
_lineRenderer.enabled = false;
var releasePosition = GetCurrentMousePosition().GetValueOrDefault();
var direction = releasePosition - _initialPosition;
Debug.Log("Process direction " + direction);
}
}
private Vector3? GetCurrentMousePosition()
{
bool vertexHit = false;
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var plane = new Plane(Vector3.forward, Vector3.zero);
float rayDistance;
if (plane.Raycast(ray, out rayDistance))
{
return ray.GetPoint(rayDistance);
}
return null;
}
}
Answer by Horschty · Jun 09, 2018 at 08:58 AM
I would say all that's missing from your code to do what you want is some reference to the actual vertices. So maybe add a public reference to your owner of the vertices, like public MyVertexArrayOwner mvao
so you can access them through mvao.vertices or something. Of course you then need to drag that object which has your vertices into the field in the inspector. Then at if (Input.GetMouseButtonDown(0) && _overVertex == true)
you could get a reference to your currently hovered vertex and the 2 neighboring ones by looping over them and checking which one is closest to the mouse position to get the one that you clicked on. Like so:
private int FindClosestVertexIndex(Vector3[] vertices, Vector3 closestToWhat) {
int closest = 0;
float shortestDistance = float.PositiveInfinity;
for(int i = 0; i < vertices.Length; i++) {
var vertex = vertices[i];
var distanceSquared = (vertex - closestToWhat).sqrMagnitude;
if(distanceSquared < shortestDistance) {
closest = i;
}
}
return closest;
}
if (Input.GetMouseButtonDown(0) && _overVertex == true) {
Vector3 mousePos = GetCurrentMousePosition().GetValueOrDefault();
int vertCenterIndex = FindClosestVertexIndex(mvao.vertices, mousePos);
int vertPreviousIndex = vertCenterIndex - 1;
int vertNextIndex = vertCenterIndex + 1;
/* Now you can get your vertices and do your line drawing.
Don't forget to do bounds checking,
in case it's the first vertex which doesn't have a previous neighbor,
then don't draw that line etc. I'll leave that tedious work to you :) */
Vector3 previous = mvao.vertices[vertPreviousIndex];
Vector3 current = mvao.vertices[vertCenterIndex];
Vector3 next = mvao.vertices[vertNextIndex];
// Add lines from previous to mousePos, current to mousePos etc etc
}
Wait, I am confused about what you stated here:
"So maybe add a public reference to your owner of the vertices, like public $$anonymous$$yVertexArrayOwner mvao so you can access them through mvao.vertices or something."
Are you saying that I should create a mesh called: mvao, then have a get-component to the mesh-filter? Like so:
$$anonymous$$esh mvao = new $$anonymous$$esh();
GetComponent<$$anonymous$$eshFilter>().mesh = mvao;
What I mean is that the code that I posted needs to access your List/Array/Whatever where you store are your vertices, so it can loop over them and find the one the user clicked on (by finding the one which is closest to the mouse position) and the ones next to it (now that I think about it the ones that are connected might not even be next to each other... in which case my code fails :P). By public $$anonymous$$yVertexArrayOwner mvao
I mean a public field (a variable on your class/script that you can assign to from outside) where $$anonymous$$yVertexArrayOwner is another script on a gameObject which you can then drag into the inspector into the mvao field of the gameObject where your DrawLine script is attached. What that is in your case I cannot know since I don't know all of your code.
Follow this Question
Related Questions
Create a sine wave(using line renderer) and reflect it from colliders 0 Answers
How To Sync Scale in UNET 2 Answers
How can I make my 2D sprite move in the direction of the most recent key pressed? 1 Answer
SphereCast doesn't work when I increase the radius. 1 Answer
How to get pixel coordinates when mouse click on Sprite Renderer 0 Answers