- Home /
How to fix 'jumping' behavior with hinge joint 2D
I am trying to create a rope swinging mechanic for a 2D game. I am using a single hinge joint to act as my rope. I create the joint by script, allowing the user to aim the ropes. The problem is that when the hinge joint is created, the object it is attached to 'jumps'.
Here is a clip showing the problem:
The left square is the 'player' who is swinging from the rope. When I click, the hinge joint is created (as well as the pink line to help you see), and the player 'jumps' to a new position. Why is this jump happening?
Here is the relevant code from the script:
void Update () {
if (Input.GetMouseButtonDown (0)) {
// click location
Vector2 clickPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// player position
Vector2 playerPos = new Vector2(transform.position.x, transform.position.y);
// cast a ray from the player to the mouse click
RaycastHit2D hit = Physics2D.Raycast(playerPos, clickPos - playerPos, 100, layerMask);
if(hit.collider){
// add the hinge joint
GameObject go = hit.collider.gameObject;
HingeJoint2D hj = go.AddComponent<HingeJoint2D>();
hj.connectedBody = gameObject.GetComponent<Rigidbody2D>();
// adjust the player's anchor. This is the length of the rope
Vector2 playerAnchor = new Vector2(0, (hit.point - playerPos).magnitude);
hj.connectedAnchor = playerAnchor;
}
}
}
Answer by carsons · Jun 15, 2015 at 05:43 AM
For anyone that gets stuck on this problem, here is the answer:
It turns out that there is a Unity bug that prevents you from properly creating a hinge joint on mouse click. Talked about in answer here. (this says the bug is in Unity 4.6, but I have the same issues in Unity 5).
You must create the hinge joint earlier and enable it on click. Here is an example (this anchors the hinge to where you click, rather than to another GameObject like my original question, but is similar enough):
// Example from user "Dan" on gamedev.stackexchange.com
public class AddHingeOnClick : MonoBehaviour {
HingeJoint2D hingeJoint2D;
void Start () {
hingeJoint2D = gameObject.AddComponent<HingeJoint2D>();
hingeJoint2D.enabled = false;
}
void OnMouseDown() {
Vector3 mouseWorldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3 mouseLocalPosition = transform.InverseTransformPoint(mouseWorldPosition);
hingeJoint2D.enabled = true;
hingeJoint2D.connectedAnchor = mouseWorldPosition;
hingeJoint2D.anchor = mouseLocalPosition;
}
}