I'm implementing magnet like behavior in unity3d.
the red object have a script that add force to it toward a blue object.
to do that i use this code:
void FixedUpdate()
{
float distance = Vector2.Distance(blue.transform.position, transform.position);
speed = MAX_DISTANCE - distance;
body2d.AddForce((blue.transform.position - transform.position).normalized * speed);
}
MAX_DISTANCE
is maximum distance that red and blue object can have.
with this code i got this behavior :
but i don't want red object gets this far after reaching blue object i want red object to decrease it's speed and after maybe some shaking around blue object and eventually stop on blue object, how can i implement this?
UPDATE
red and blue objects can't collide with each other they just know their location.
Answer
You really shouldn't redefine physics, you already have Physics2D. What you need is a PointEffector2D on the blue object and a Rigidbody2D on the red object. Your red object also needs to have its drag and angularDrag set to something other than zero for a realistic effect. You can skip the angularDrag and leave it at zero but you might need it later on.
Since the object will get to a point where the distance is almost zero, you'll have (almost) infinite force at that point. In the following gif, the "blue" object has a PointEffector2D
with the force -30 and a CircleCollider2D
for the effector to use. The "red" ball on the outside has a Rigidbody2D
with a mass of 1 and a drag of 0.25.
Here are the details of the objects (as I already had them at hand, I'm just putting them here for future reference). Be aware that you might or might not need a Collider2D on the "red" object, I'm not entirely sure.
So, when the object gets near enough to the point you want it to be (and when it's slow enough to stop), remove its Rigidbody2D, or just disable it, and set its position. You can also increase the drag your object has to a point where it'll stand still. This way you're ensuring that the object won't wobble. For example:
if(distanceBetweenObjects <= 0.1 && redObject.velocity < 1) {
redObject.Rigidbody2D.enabled = false;
redObject.transform.position = blueObject.transform.position;
}
You'll have to tweak the values and maybe the code but this is close enough.
No comments:
Post a Comment