I have a series of contraptions in my maze/puzzle game that animate on set scripted paths when clicked. I wanted to add hazard balls in the game that can bounce and roll when these scripted objects bump into them. The problem is, these balls don’t react when my contraptions hit them, the balls just get pushed slightly out of the path of the contraptions. They should continue moving with inertia when hit.
Also, I already have 20 or so levels built with objects moving by scripts. The balls are just a last minute thing that would be fun to create as hazards to crush the player. I couldn’t possible change the contraptions to be moved by adding force at this point, so I’d need a solution that allows my objects to animate in the same way they’ve been animating via scripting.
Please see the video for details, thank you for your time.
The problem is that the object that you’re ‘moving’ doesn’t have any velocity (energy), it’s just ‘teleporting’ from position to position as you drag it. The reason the other object moves is because you’re causing the object to overlap (bad) the puck so the physics system solves the overlap by repositioning it out of the overlap but it doesn’t add velocity to do that.
A good way to drag a Rigidbody2D to a specific position is using the TargetJoint2D. This causes the body to move to a target position and you can keep updating the target position with the mouse position. This adds the appropriate forces to the body to move it to that position which gives it a velocity. This velocity therefore affects objects it touches. This is only really effective if the Rigidbody2Dbody-type is Kinematic so that the object you’re moving doesn’t receive a collision response from the collision.
Here’s an example of a Kinematic Rigidbody2D with an attached BoxCollider2D and TargetJoint2D having its Target set by the animation system in an up/down motion. Note that the Balls are Dynamic Rigidbody2D and that they move because they are hit by a moving object: Screen capture - aecc456f80f245c94dc0e88781b1e097 - Gyazo
Here’s an example script that would work:
using UnityEngine;
public class SetTargetToMouse : MonoBehaviour
{
TargetJoint2D target;
void Start ()
{
target = GetComponent<TargetJoint2D> ();
}
void FixedUpdate ()
{
if (!Input.GetKey (KeyCode.Mouse0))
return;
var position = Input.mousePosition;
position.z = 0.0f;
position = Camera.main.ScreenToWorldPoint(position);
target.target = position;
}
}
Note that you can also use Rigidbody2D.MovePosition but you’ll need to add the velocity to the puck yourself in a ‘OnCollisionEnter2D’ callback as the object that is being moved still doesn’t have any velocity (energy) to impart onto the puck.