How can I move a ball to a clicked location using physics forces?

I have a ball as a sphere in my game and I'm viewing it from top down view. The ball is a rigid body.

When I click somewhere on the screen, I want the ball to be moved towards that direction using physics forces.

The ball needs to move only on the X and Y axes, the Z axis can be ignored.

Here is what I tried, but gives me some weird results. The script is attached to the ball:

// Use this for initialization
void Start () {
rb = gameObject.GetComponent<Rigidbody> ();
}

void Update () {

//
Vector3 v3 = gameObject.transform.position;
Vector3 v3Mouse = Input.mousePosition;

//
Vector2 pointA = new Vector2(v3.x, v3.y);
Vector2 pointB = new Vector2(v3Mouse.x, v3Mouse.y);

//
float Angle = Vector2.Angle(pointA, pointB);
float angleRad = Angle * (Mathf.PI / 180);

Debug.Log ("Angle: " + Angle);
//
float dx = Mathf.Cos (angleRad) * 10;
float dy = Mathf.Sin (angleRad) * 10;

//
if (Input.GetMouseButtonDown (0)) {

rb.velocity = new Vector3(dx, dy, 0);

}

}

What should I do here? When I click on the top of the screen, the ball should move up toward the mouse, and in all the other directions.

Any ideas?

1 Answer

Vector mathematics! Assuming you're using Unity, you could use the inbuilt functions of Vector2:

transform.position = Vector3.MoveTowards(transform.position, target, speed);

Otherwise, here's how it's done - first, calculate the direction from point A to point B:

public static float Length(float x, float y) {
return Math.Sqrt(x * x + y * y);
}

public static Vector2 Direction(Vector2 position) {
return new Vector2(position.X / Length(position.X, position.Y), position.Y / Length(position.X, position.Y);
}

Direction will return a Vector2 representing the direction towards the position as values from -1 and 1 on both the X and Y axis. This is a Normalized Vector. In the case of finding the direction towards a target, you need to pass it the target's position subtracted by the current position:

Vector2 direction = Vector2.Direction(target - position);

You can use this to move your ball to the desired position:

position += direction * speed;

And you can also use it to make the object rotate towards (face) the desired position, although with it being a ball, it doesn't seem necessary, but regardless:

float angleInRadians = Math.Atan2(direction.Y, direction.X);
float angleInDegrees = angleInRadians * 180 / Math.PI;
• Thanks for the comment, but I need to use it on a rigitbody, I tried like: rb.velocity = new Vector3(direction.x * 5, direction.y * 5, 0); but it does not work....what to do? Jul 19, 2015 at 16:27