I’m trying to make a grappling hook style game in Unity. When the rope collides with an object, I move the anchor point to that position and save a List<Vector2>
of positions.
I’m at the point now where I need to remove the last anchor based on the angle between the player and the last anchor and the last anchor and the second to last anchor.
Here’s a crude drawing to demonstrate:
- A is the original anchor Point.
- B is the recent anchor Point
- Green is the player
In this example, there should be no detaching. However, if the angle between the player and B is the same or less than the angle between B and A, it should detach:
I’m struggling to pin down the logic here, and I fear I’ve spent so long on this that I’m starting to overcomplicate things.
Here’s the current logic that I’m using, which works 80% of the time:
Vector2 playerPosition = player.transform.position;
Vector2 lastAnchor = anchorPositions[anchorPositions.Count - 1];
Vector2 secondToLastAnchor = anchorPositions[anchorPositions.Count - 2];
Vector2 directionToLastAnchor = lastAnchor - playerPosition;
Vector2 directionToSecondToLastAnchor = secondToLastAnchor - lastAnchor;
bool anchorToLeftOfPlayer = directionToLastAnchor.x < 0;
bool anchorToRightOfPlayer = directionToLastAnchor.x > 0;
float angleToLastAnchor = Vector2.SignedAngle(playerPosition, lastAnchor);
float angleToSecondToLastAnchor = Vector2.SignedAngle(secondToLastAnchor, lastAnchor);
if (anchorToLeftOfPlayer) {
if (angleToLastAnchor > angleToSecondToLastAnchor && directionToLastAnchor.x > directionToSecondToLastAnchor.x) {
Debug.Break();
DetachRopeAtIndex(anchorPositions.Count - 1);
}
} else if (anchorToRightOfPlayer) {
if (angleToLastAnchor < angleToSecondToLastAnchor && directionToLastAnchor.x < directionToSecondToLastAnchor.x) {
Debug.Log("Detached because anchor on right of player");
Debug.Break();
DetachRopeAtIndex(anchorPositions.Count - 1);
}
}
Here’s a human readable variation:
If anchor to the right of the player and angle B < angle A and direction B < direction A = DETACH
This breaks with the following scenario:
I’m not completely sure that I’m
- Calculating the angles correctly
- Applying the right logic
- Not overcomplicating things
- Not handing off this logic to Unity
The problem stems from the fact that the anchorPositions don’t have any reference as to which side of the wall they are attached to.
For example, the rope should detach in this state:
But not in this state:
Despite the fact that the positions of the anchors and the player are identical.
You can’t assume anything from the velocity of the player either, since they can be moving in either direction. The only thing that matters are the angles.
You can fix this by keeping track of the side of the rope that impacted the wall (either left or right), and using that instead of anchorToLeftOfPlayer
and anchorToRightOfPlayer
2