- Home /
Line renderer spring shape
Hi! I'm trying to connect two gameobjects using a linerenderer with a spring shape. I'm facing two issues: -The shape is created, but it doesn't connect the first object with the second one. -The first and last vertex of the linerenderer doesn't fit the first and last object center (see the screenshot)
This is the code I'm using:
public Transform object1;
public Transform object2;
private LineRenderer lineRenderer;
const int NUMBER_OF_POINTS = 100;
private void Awake()
{
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.positionCount = NUMBER_OF_POINTS;
}
private void Start()
{
CreateCurveShape();
}
private void CreateCurveShape()
{
float segmentWidth = Vector3.Distance(object1.position, object2.position) / NUMBER_OF_POINTS;
Vector3[] points = new Vector3[NUMBER_OF_POINTS];
for (int i = 0; i < NUMBER_OF_POINTS; i++)
{
float z = segmentWidth * i;
float x = Mathf.Sin(z);
float y = Mathf.Cos(z);
points[i] = new Vector3(x, y, z);
}
lineRenderer.SetPositions(points);
}
Answer by Shrimpey · Jul 29, 2020 at 10:09 AM
Not sure if you need 2D or 3D solution, so I just made the most universal one that applies to 3D space and can probably be somewhat used in 2D too.
There are a lot of ways to go about it (the beauty of algebra), I created a plane with normal pointing towards second object (from first one) and then created points on that plane moving it along the normal axis:
public Transform object1;
public Transform object2;
private LineRenderer lineRenderer;
const int NUMBER_OF_POINTS = 100;
const int NUMBER_OF_REVOLUTIONS = 5;
const float SPIRAL_WIDTH = 2.0f;
private void Awake() {
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.positionCount = NUMBER_OF_POINTS;
}
private void Start() {
CreateCurveShape();
}
private void CreateCurveShape() {
float objectDistance = Vector3.Distance(object1.position, object2.position);
Vector3[] points = new Vector3[NUMBER_OF_POINTS];
for (int i = 0; i < NUMBER_OF_POINTS; i++) {
// Define plane with normal pointing to second object
Vector3 planeForwardDirection = (object2.position - object1.position);
Vector3 planeRightDirection = Quaternion.Euler(90.0f, 0.0f, 0.0f) * planeForwardDirection;
Vector3 planeUpDirection = Vector3.Cross(planeForwardDirection, planeRightDirection);
// Some additional debug to visualize our plane
Debug.DrawLine(object1.position, planeForwardDirection, Color.red, 1000);
Debug.DrawLine(object1.position, planeUpDirection, Color.cyan, 1000);
Debug.DrawLine(object1.position, planeRightDirection, Color.green, 1000);
// Distance along the object to object axis
float currentDistanceNormalized = (float)i / (float)NUMBER_OF_POINTS;
float currentDistance = currentDistanceNormalized * objectDistance;
// New coords on our plane facing the second object
Vector3 spiralCoords = SPIRAL_WIDTH * planeUpDirection.normalized * Mathf.Sin(NUMBER_OF_REVOLUTIONS * currentDistanceNormalized * 2 *Mathf.PI) +
SPIRAL_WIDTH * planeRightDirection.normalized * (Mathf.Cos(NUMBER_OF_REVOLUTIONS * currentDistanceNormalized * 2 *Mathf.PI) - 1.0f) +
planeForwardDirection.normalized * currentDistance;
points[i] = spiralCoords;
}
lineRenderer.SetPositions(points);
}
It should work fine no matter how you position your objects in 3D space, maybe some minor modifications might be needed for your specific application. I also threw in number of revolutions and width variables.
Of course the debug lines can be removed. The -1.0f Mathf.Cos moves the starting/ending point to the object (cosine of 0 is 1, so we need to offset it to match our object's position).
It worked! Thank you so much. $$anonymous$$inor modifications are needed yes, but it's just a tweak depending on the project as you said (for example, if the scale between the objects is not the same)