- Home /
Bounce back after spinning an object once it hits the angle limit.
I have this object where you spin in by touching and dragging it. It has a Hinge Joint 2D at the center so it would spin like a wheel.
The script I'm using is the one I got from this question: http://answers.unity3d.com/questions/679524/creating-draggable-hinge-joint.html
This works perfectly just the way I want it, except that I want it to bounce back once the angle hits a certain limit.
I tried checking the Angle Limit and set the min to 90 and the max to 270. It also works, but instead of bouncing back, it just completely stops at either 90 or 270.
How can I make it bounce back realistically?
Here's the exact code I have on my object right now (that I got from slek120). My object has a Hinge Joint 2D, a Box Collider 2D, and a Rigidbody 2D. The script also creates an object called "Rigidbody2D Dragger" with a Spring Joint 2D as you can see in the code:
using UnityEngine;
using System.Collections;
public class rotatingWall : MonoBehaviour
{
public float distance = 0.2f;
public float dampingRatio = 1;
public float frequency = 1.8f;
public float linearDrag = 1.0f;
public float angularDrag = 5.0f;
private SpringJoint2D springJoint;
GameObject go;
void Start ()
{
if (!springJoint) {
go = new GameObject ("Rigidbody2D Dragger");
go.transform.parent = this.transform.parent;
Rigidbody2D body = go.AddComponent <Rigidbody2D>() as Rigidbody2D;
springJoint = go.AddComponent <SpringJoint2D>() as SpringJoint2D;
body.isKinematic = true;
}
}
// Update
void Update ()
{
if (!Input.GetMouseButtonDown (0))
return;
Camera mainCamera = FindCamera ();
int mask = (1 << 8);
RaycastHit2D hit = Physics2D.Raycast (Camera.main.ScreenToWorldPoint (Input.mousePosition), Vector2.zero);
// I have proxy collider objects (empty gameobjects with a 2D Collider) as a child of a 3D rigidbody - simulating collisions between 2D and 3D objects
// I therefore set any 'touchable' object to layer 8 and use the layerMask above for all touchable items
if (hit.rigidbody != null && hit.rigidbody.isKinematic == true) {
return;
}
if (hit.rigidbody != null && hit.rigidbody.isKinematic == false) {
springJoint.transform.position = hit.point;
springJoint.dampingRatio = dampingRatio;
springJoint.frequency = frequency;
springJoint.distance = distance;
springJoint.connectedBody = hit.rigidbody;
springJoint.connectedAnchor = hit.transform.InverseTransformPoint (hit.point);
// maybe check if the 'fraction' is normalised. See http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit2D-fraction.html
StartCoroutine ("DragObject", hit.fraction);
} // end of hit true condition
} // end of update
IEnumerator DragObject (float distance)
{
float oldDrag = springJoint.connectedBody.drag;
float oldAngularDrag = springJoint.connectedBody.angularDrag;
springJoint.connectedBody.drag = linearDrag;
springJoint.connectedBody.angularDrag = angularDrag;
Camera mainCamera = FindCamera ();
while (Input.GetMouseButton (0)) {
Ray ray = mainCamera.ScreenPointToRay (Input.mousePosition);
springJoint.transform.position = ray.GetPoint (distance);
yield return null;
}
if (springJoint.connectedBody) {
springJoint.connectedBody.drag = oldDrag;
springJoint.connectedBody.angularDrag = oldAngularDrag;
springJoint.connectedBody = null;
}
}
Camera FindCamera ()
{
if (GetComponent<Camera>())
return GetComponent<Camera>();
else
return Camera.main;
}
}
Answer by dimaswift · Apr 04, 2015 at 04:23 PM
Try adding Torque multiplied by joint speed at the moment when it reaches needed angle:
public class NewBehaviourScript : MonoBehaviour
{
public float jumbBackForce = 4;
Rigidbody2D body;
HingeJoint2D hinge;
bool reachedMax, reachedMin;
void Start ()
{
hinge = GetComponent<HingeJoint2D>();
body = GetComponent<Rigidbody2D>();
}
void Update ()
{
JumpBack();
}
void JumpBack()
{
if (hinge.jointAngle >= hinge.limits.max)
{
if (!reachedMax)
{
body.AddTorque(jumbBackForce * Mathf.Abs(hinge.jointSpeed), ForceMode2D.Force);
reachedMax = true;
reachedMin = false;
}
}
else if (hinge.jointAngle <= hinge.limits.min)
{
if (!reachedMin)
{
body.AddTorque(-jumbBackForce * Mathf.Abs(hinge.jointSpeed), ForceMode2D.Force);
reachedMax = false;
reachedMin = true;
}
}
}
}