In the previous post, we manage to display a ball each second at a random position. Our goal, if you accept it, will be to add some physical properties to the ball (mass, gravity, collision).

Balls are falling !

The first step is to define a mass for our balls. Without that, the physical engine can’t apply to the object because the mass is null. In the CreateBall method, you can add the code snippet below that adds a RigidBody component and sets his mass to 0.1. It’s important to note that we don’t create a new node to attach the RigidBody because the physical property must be apply to the entire object (=the root node).

// Add a rigidbody
var rigidbody = ballNode.CreateComponent<RigidBody>();
rigidbody.Mass = 0.1f;

You can use a RigidBody2D if your project is in 2D. That affects the physical engine because some axis are ignored during calculations.

Collision detected sir.

To handle the collision between objects, we need to add a CollisionShape that can be for example a sphere, a cube or a more complex shape. In our case, we will use a sphere that will fit our ball.

// Add a collision shape
var collision = ballNode.CreateComponent<CollisionShape>();
collision.SetSphere(1, Vector3.Zero, Quaternion.Identity);

In term of pure performances, it’s better to use a simple shape (or an addition of them) than a complex shape that represents exactly the model. An approximation is often used in real scenario : a cube can be a simple solution to handle a head for exemple.

So, our balls can collide so let’s add a fake floor to show what happens.

private void CreateFloor()
{
    var floorNode = Scene.CreateChild();
    floorNode.Position = new Vector3(0, -1, 0);
    floorNode.SetScale(20);

    var floorModelNode = floorNode.CreateChild();
    var plane = floorModelNode.CreateComponent<Urho.Shapes.Plane>();
    plane.Color = Color.White;

    var rigidbody = floorNode.CreateComponent<RigidBody>();
    rigidbody.Kinematic = true;

    var collision = floorNode.CreateComponent<CollisionShape>();
    collision.SetBox(new Vector3(20, 0.1f, 20), new Vector3(0, -0.05f, 0), Quaternion.Identity);
}

That method seems pretty similar to CreateBall except the use of the property Kinematic for the RigidBody. The physical engine will not apply the gravity to this object, and it’s right what we need for a floor. Don’t forget to invoke the method at the beginning of the application, inside the Start method.

protected override void Start()
{
    base.Start();

    CreateFloor();
}

urhosharp_balls_on_the_floor

In the next episode, we will use the spatial mapping to detect the floor automatically.