In Unity I want to draw a line between 2 gameObjects on a UI canvas.
After seeing it work in the sample from the documentation I started to implement my own. After playing around with some values in the gizmos I ventured forward to the OnPopulateMesh method to see it for real, but eventhough the Gizmos show exactly what I want, I saw nothing.
I played around with the order of the vertex indexes in the AddTriangle method, but that did nothing.
[ExecuteInEditMode]
public class UILineRenderer : Graphic
{
public Vector3 BeginPoint;
public float BeginOffset;
public Vector3 EndPoint;
public float EndOffset;
public float Thickness;
protected override void OnPopulateMesh(VertexHelper vh)
{
var delta = EndPoint - BeginPoint;
var perpendicularToUI = Vector3.Cross(delta, Vector3.forward);
var thicknessVector = perpendicularToUI.normalized * (Thickness / 2f);
var beginOrigin = BeginPoint + (delta.normalized * BeginOffset);
var endOrigin = EndPoint - (delta.normalized * EndOffset);
vh.Clear();
UIVertex vertex = UIVertex.simpleVert;
vertex.color = color;
vertex.position = beginOrigin + thicknessVector;
vh.AddVert(vertex);
vertex.position = beginOrigin - thicknessVector;
vh.AddVert(vertex);
vertex.position = endOrigin + thicknessVector;
vh.AddVert(vertex);
vertex.position = endOrigin - thicknessVector;
vh.AddVert(vertex);
vh.AddTriangle(0, 1, 2);
vh.AddTriangle(2, 3, 0);
}
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawLine(BeginPoint, EndPoint);
var delta = EndPoint - BeginPoint;
var perpen = Vector3.Cross(delta, Vector3.forward);
var thicknessVector = perpen.normalized * (Thickness / 2f);
var beginOrigin = BeginPoint + (delta.normalized * BeginOffset);
var endOrigin = EndPoint - (delta.normalized * EndOffset);
var v0 = beginOrigin + thicknessVector;
var v1 = beginOrigin - thicknessVector;
var v2 = endOrigin + thicknessVector;
var v3 = endOrigin - thicknessVector;
Gizmos.color = color;
Gizmos.DrawLine(v0, v2);
Gizmos.DrawLine(v1, v3);
}
}
Also I tried referencing the child gameObject so I could make the RectTransform larger to enclose the total space the line would use.
Why won’t my line / triangles render?
1
You can use unity’s LineRenderer
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SetPosition_Line : MonoBehaviour
{
private LineRenderer line;
public GameObject TargetPoint;
// Start is called before the first frame update
void Start()
{
line = GetComponent<LineRenderer>();
// line.useWorldSpace = false;
// line.SetPosition(0, transform.position);
Vector3[] pathPoints = { new Vector3(0,0,0), new Vector3(10,10,10) };
line .positionCount = 2;
line .SetPositions(pathPoints);
}
// Update is called once per frame
void Update()
{
// in the start enough. not need to do it un the update to just draw the line
}
}
Or a more comeplex proposal is to use GL.LINES. Find adapted script from the documentation.
using UnityEngine;
public class Example : MonoBehaviour
{
// Draws a line from "startVertex" var to the curent mouse position.
public Material mat;
Vector3 startVertex;
Vector3 mousePos;
void Start()
{
startVertex = Vector3.zero;
}
void Update()
{
mousePos = Input.mousePosition;
// Press space to update startVertex
if (Input.GetKeyDown(KeyCode.Space))
{
startVertex = new Vector3(mousePos.x / Screen.width, mousePos.y / Screen.height, 0);
}
}
void OnPostRender()
{
if (!mat)
{
Debug.LogError("Please Assign a material on the inspector");
return;
}
GL.PushMatrix();
mat.SetPass(0);
GL.LoadOrtho();
GL.Begin(GL.LINES);
GL.Color(Color.red);
//GL.Vertex(startVertex);
//GL.Vertex(new Vector3(mousePos.x / Screen.width, mousePos.y / Screen.height, 0));
GL.Vertex(new Vector3(0, 0, 0));
GL.Vertex(new Vector3(0.3f, 0.3f, 0f));
GL.Vertex(new Vector3(0.3f, 0.3f, 0f));
GL.Vertex(new Vector3(0.3f, 0.5f, 0f));
GL.Vertex(new Vector3(0.3f, 0.5f, 0f));
GL.Vertex(new Vector3(0.7f, 0.5f, 0f));
GL.End();
GL.PopMatrix();
}
}
Output: