Physics Gravity In 3D
Understanding and making your first 3D physics enabled Quorum gameOverview
The Quorum 3D Physics Engine is meant to make basic forces and the interaction of objects in our games simpler to implement. In this tutorial, we will learn how to turn on physics and apply gravity. Note that this tutorial is quite similar to the Gravity In 2D tutorial. If you need a refresher on making 3D games, be sure to review the other Games and Media tutorials on the Reference page before beginning this tutorial. The code provided at the end of this tutorial will load a blue box onto the game screen which will be in the air above a green box representing the ground. Then the blue box will fall, increasing in speed as it approaches the ground. A lot of this code will be familiar to the 3D Drawing tutorial, because we still need to create shapes and add them to the screen.
Physics Flags
Our first step in using physics is to turn it on. We do this by setting the global physics flag in the CreateGame action.
EnablePhysics3D(true)
With the physics engine, there are additional properties that can be set for each item we add to the screen. Most importantly, when we want to use the Physics engine for an object, there is a flag that needs to be set to true: EnablePhysics. This is set in the same way that position or color is set, for example:
itemName:EnablePhysics(true)
After we turn physics on, we need to tell the engine more information about the item. There are two ways to do this part, but we will focus on only one for this tutorial. All Item3D objects now have physics properties stored in a PhysicsProperties3D object. We can access most of these properties through new actions in the Item3D class. The properties include friction, linear velocity, and others. We will cover more of these properties in further tutorials, but for this gravity game, we need responsiveness.
Responsiveness
Responsiveness describes how this item interacts with other items on the screen. There are three levels of responsiveness: Responsive, NonResponsive, and Unmovable.
Responsive
An object set to be responsive can be affected by forces like gravity or forces resulting from a collision. A player controlled character, for example, might be responsive. We can set an item to be responsive like this:
itemName:SetResponsive()
NonResponsive
A nonresponsive object will not respond to forces, but can be moved programmatically. A moving platform might be nonresponsive so that it can be moved in the program without responding to gravity or collisions. We can move the platform using "itemName:Move()", for example. Note that using Move() with responsive items will bypass collisions and gravity for them as well. We can set an item to be nonresponsive like this:
itemName:SetNonResponsive()
Unmovable
An unmovable object will not respond to forces and cannot be moved. This is the perfect option for the ground, as it should not fall from gravity, be pushed by collisions, or be moved in the program after being set in place. Note that if the position of an Unmovable object is changed in Update() or anytime after being set initially, the object will move on screen, but the physics will act as if the object remains in its original position. Unmovable is a physics property, so it only affects the physics of the object and not how it appears on screen. We can set an item to be unmovable like this:
itemName:SetUnmovable()
In this tutorial, we will use two of these levels of responsiveness: Unmovable and Responsive. The ground will be Unmovable. The box on the other hand, should be Responsive because we want gravity and collision forces to act on it: stopping it when it hits the ground. Finally, we need to tell the computer the impact of gravity.
Gravity
Like the global physics flag, we need to set gravity in the CreateGame() action. There are two ways to set gravity, both with the same handy action. Here, we will focus one of these ways. The next tutorial about forces will cover the other. The action to set gravity is:
number X = 0
number Y = -10
number Z = 0
SetGravity3D( X , Y , Z )
When we set gravity, the X, Y, and Z coordinates will correspond to the direction and amount of change per second. For gravity, we want a force pulling down vertically (set Y to a negative number), no pull horizontally (set X to 0) and no pull closer or farther from us (set Z to 0.) Because the engine has to convert pixels to metric measurements, sometimes we may need to try a few different force values for gravity to make sure it looks right.
Code
Here is a zip file containing a Quorum project using the code below. Read through, then use the following code to discover gravity.
use Libraries.Game.Game
use Libraries.Game.Graphics.Model
use Libraries.Game.Graphics.Color
use Libraries.Interface.Events.CollisionListener3D
use Libraries.Interface.Events.CollisionEvent3D
use Libraries.Sound.Audio
use Libraries.Game.Graphics.DirectionalLight
use Libraries.Game.Graphics.AmbientLight
class Main is Game, CollisionListener3D
Model ground
Model box
Audio fallSound
Audio boomSound
Color color
action Main
StartGame()
end
action CreateGame
DirectionalLight light
light:SetColor(0.8, 0.8, 0.8, 1)
light:SetDirection(GetCamera3D():GetDirection())
Add(light)
AmbientLight ambient
ambient:SetColor(0.4, 0.4, 0.4, 1)
SetAmbientLight(ambient)
/*
This flag enables 3 dimensional physics for the game. Make sure to set
this when you want to add physics.
*/
EnablePhysics3D(true)
ground:SetName("Ground")
ground:LoadBox(15, 1, 20, color:Green())
ground:SetPosition(0,-2,0)
Add(ground)
/*
We must enable physics for each Item3D object that will interact
with other Item3D objects.
*/
ground:EnablePhysics(true)
/*
Neither gravity, collision, nor any programmatic method should be able
to move the ground; its responsiveness needs to be set to unmovable.
*/
ground:SetUnmovable()
box:SetName("Box")
box:LoadBox(1,1,1, color:Blue())
box:SetPosition(0,1,0)
Add(box)
box:EnablePhysics(true)
/*
The box is responds to gravity and impact with the ground, so we will
set to be responsive.
*/
box:SetResponsive()
/*
Finally, we set gravity
(This is an approximation of actual gravity)
*/
SetGravity3D(0, -10, 0)
fallSound:Load("media/Fall.ogg")
boomSound:Load("media/Boom.ogg")
fallSound:Play()
AddCollisionListener(me)
end
action BeginCollision(CollisionEvent3D event)
fallSound:Pause()
boomSound:SetVolume(0.1)
boomSound:Play()
end
end
Try it Yourself!
Press the blue run button to execute the code in the code editor. Press the red stop button to end the program. Your program will work when the console outputs "Build Successful!"
If we run this gravity game, we should have a box load on the screen which falls to the ground like so:
Next Tutorial
In the next tutorial, we will discuss Force and Velocity In 3D, which describes how to add forces and velocity to a 3D game.