Tethering Two GameObjects Together By a Rope Through Code
21. Červen 2024 v 06:56
What I need assistance with:
I need to create a rope connecting two GameObjects together at runtime through code.
One end will be connected to
Transform
_pointA and the other will be connected toTransform
_pointB.I've divided the rope up into segments of GameObjects that have a
Hinge joint 2D
& aRigidbody 2D
.Each segment uses it's parent's
Rigidbody 2D
as the Connected Rigid Body.Then I set positions on the
LineRenderer
to match the segment positions so that I can later use rope material to make it looks nicer.
Issue:
- When the rope is initially created, it immediately falls straight down creating a vertical rope rather than a horizontal rope, even though the final rope segment is positioned at _pointB with the correct parent's
Rigidbody
connected. - After a few moments, the rope falls apart without moving any positions manually.
- Additionally, if the rope is manually moved, it immediately falls apart.
- To demonstrate the issue, I added a circle sprite to each segment
GameObject
in the rope.
- Which causes the line to look like this:
Here's an example of how I would like it to look when moving the two objects further/closer:
The Code I'm Using:
public class Rope: MonoBehaviour
{
[SerializeField] private LineRenderer _line;
[SerializeField, Range(2, 50)] int _segmentCount = 2;
[SerializeField] private Transform _pointA;
[SerializeField] private Transform _pointB;
[SerializeField] HingeJoint2D _hingeJoint;
public Transform[] segments;
private void Start()
{
GenerateRope();
}
// Update is called once per frame
void Update()
{
SetEndOfRopePositions();
SetLinePoints();
}
private void SetEndOfRopePositions()
{
segments[0].position = _pointA.position;
segments[segments.Length - 1].position = _pointB.position;
}
private void SetLinePoints()
{
_line.positionCount = segments.Length;
for (int i = 0; i < segments.Length; i++)
{
_line.SetPosition(i, segments[i].position);
}
}
private Vector2 GetSegmentPosition(int segmentIndex)
{
Vector2 posA = _pointA.position;
Vector2 posB = _pointB.position;
float fraction = 1f / (float)_segmentCount;
return Vector2.Lerp(posA, posB, fraction * segmentIndex);
}
void GenerateRope()
{
segments = new Transform[_segmentCount];
for (int i = 0; i < _segmentCount; i++)
{
var currJoint = Instantiate(_hingeJoint, GetSegmentPosition(i), Quaternion.identity, this.transform);
segments[i] = currJoint.transform;
if (i > 0) // Not first hinge
{
int prevIndex = i - 1;
currJoint.connectedBody = segments[prevIndex].GetComponent<Rigidbody2D>();
}
}
}
}
Inspector for Rope + Segment GameObjects before running the game: