Categories
Basic Tutorials

Basic Coding 5: Physics

Preface

Once you understand the basic building blocks of coding, you can start to experiment with some of the resources that are available only to programmers. Game engines, like Crayta, have a way that programmers can interact with core functionality, which is called an API (Application Programmer Interface). 

Introduction

The Unit 2 Games developers have been hard at work to make sure that Crayta has some useful features you can interact with through code. One of these features is the physics engine.

The physics engine is an immensely powerful tool in Crayta. The physics engine controls the game physics including gravity and friction. It also means that you can apply forces to Entities within the game, and they behave in a simulated physical space. In this tutorial, you will find out about a couple of different ways that you can apply forces to Entities within Crayta. Let’s get going.

Create A Game

Create a new blank game and enter the advanced Editor.

Start a new blank game.

Add A Trigger 

A Trigger is an invisible Entity which knows if another Entity is within it, or has entered or exited it. Adding a Script to a Trigger allows us to access these functions, and to perform actions when they occur.

In the Primitives section of the Library you will find a Trigger

You can find the Trigger Primitive in the Primitives section of the Library.

Add a Trigger to your game. It will need some configuration before it can be useful.

Add a Trigger to your game.

Click on the Trigger and change the size of the box to 200.0, 200.0, 200.0. You can find the size Property in the Entity Editor for the Trigger Primitive.

Change the size to 200.0 200.0 200.0

This will make the box consist of a larger volume. You may need to reposition the Trigger once you have resized it.

Reposition your Trigger so that none of it is below the level of the ground.

Add a new Script to the Trigger. Call the Script “LaunchMe” and enter the Script editor by clicking on the pencil. You will need to know where the Trigger is when it comes to testing the game (as they are invisible during gameplay).

Add a new Script to the Trigger called LaunchMe. To help me find it, I’ve added some lovely tile Voxels under the Trigger.

Add A Trigger Function

The purpose of this LaunchMe Script is to launch the player into the air when they enter the Trigger.

There are two “hook” functions that specifically relate to a Trigger in Crayta. These are:

  1. OnTriggerEnter – which is called when an Entity intersects or enters the Trigger 
  2. OnTriggerExit – which is called when an Entity that did intersect the Trigger no longer does so

Both of these functions can take a parameter in the brackets which refers to the Entity that entered or exited the Trigger.

Within your Script, add the OnTriggerEnter function and include a Print statement, so that you can test that this is working. You can try to write this yourself, or you can copy the following:

function LaunchMe:OnTriggerEnter(other)
    Print("Something entered the Trigger")
end

Test your Script by playing your game. When you enter the Trigger volume you should be able to see the statement appear in the Console.

Launch The Character

In a previous tutorial you looked at using conditional (if) statements in order to check the value of a variable. You can use this same technique in the OnTriggerEnter function to check what type of Entity just entered the Trigger.

Tech Tips: Type-Checking

Sometimes it is not possible for you to be sure of exactly what type of data is contained in a variable. For example, a variable that is created whilst the game is running could contain a Character, or an Entity

Conditional statements can come to the rescue here, and ensure that the right type of data is being treated the correct way. You can write:

if aVariable:IsA(datatype) then

Which will ensure that the variable is the correct type of data before trying to run functions on it.

The Launch() function is a specific function that only exists on one type of Entity called a Character. You will need to check that the Entity that entered the Trigger is a Character before you can run the Launch() function. Add the following code to your OnTriggerEnter function:

function LaunchMe:OnTriggerEnter(other)
    if other:IsA(Character) then
        other:Launch( Vector.New( 0, 0, 2000 ) )
    end
end

This code is called automatically by Crayta when something enters the Trigger. The Script checks the type of Entity. If it is a Character, then the Script will call the Character’s Launch() function. 

Tech Tips: Vector.New(x, y, z)

Notice that we have also included a Vector.New… parameter in the Launch function. This value tells the Launch function which direction, and how powerfully, we need to launch the character. The Vector is the type of data, so here we are giving the three values, which relate to the positional axes in the 3D game. For example:

Vector.New( x, y, z)

Where:

X = left (-) / right (+)
Y = towards (-) / away (+)
Z = down (-) / up (+)

The launch code will fire the Character upwards with a force of 2000.

Save the Script. Return to the game and test your Trigger by running your character into it. You should find that it launches you into the air.

Walking into the Trigger should launch you into the air. Mmm, physicsy.

Adding A Thruster

Within Crayta’s physics engine is the ability to add a Thruster to an Entity. A Thruster does exactly what it sounds like, it applies a continuous thrust force to an Entity.

You can add a Thruster to any Entity to make it fly! 

In the game Editor, add a new Prop entity – pick the Bath Tub from the Library and place it somewhere in your scene.

Add a new Prop that you want to fly through the air. I am using a bathtub.

Tech Tip: Size = Weight

In Crayta physics, the larger an Entity, the heavier it is. This is the default setting because as a rule of thumb, it is similar to the real world. For example, a bathtub is much heavier than a banana.

When you make something fly, you have to lift it off the ground using a force strong enough to take the Entity’s weight. The amount of force you give the bathtub will be much greater than what you would need to achieve the same effect with a banana, and much less than what you would need to make a bank vault fly.

You can change the density (and therefore the weight) of an Entity in the Entity Editor. This way, you could make a banana as dense as a house, and very hard to lift off the ground.

Select the Bath Tub Entity and make sure that the physicsEnabled checkbox is ticked.

Make sure that physicsEnabled is checked on the flying bathtub.

Add a new Script. Call the Script FlyMe. Enter the Script Editor.

Creating a Thruster is simple enough. Within the Init() function that is already prepared, add the following code:

self.thruster = self:GetEntity():CreateThruster()
self.thruster:SetForce( Vector.New( 0, 0, 150000 ) )

Notice that we are using Vector.New… again to set the force of the thrust here. We have to use a much higher value, because a Bath Tub is very heavy – Crayta simulates the weight of the objects based on their size.

Save the Script and check the Simulate checkbox on the bathtub. You should find that the Bath Tub takes off and flies into the air. You can use the simulate checkbox to test some of your coding without needing to playtest the game (although it’s still a good idea to playtest as often as possible).

Goodybe bathtub!

Uncheck the simulate checkbox to return the bathtub to it’s original position.

Triggering The Thruster

Now that you have made something fly, it’s time to learn how to control it somewhat. You are going to use another Trigger to do this. When a Character Entity enters the Trigger, it will turn on the Thruster on the Bath Tub. When a Character Entity exits the Trigger, it should turn off the Thruster.

To help your FlyMe code to know whether the Thruster should be on or off, you will need to add a boolean variable to the FlyMe Script. Open your FlyMe Script, and change your Init function to be like the following:

function FlyMe:Init()
    self.thruster = self:GetEntity():CreateThruster()
    self.thrustOn = false
end

You are no longer setting the force of the Thruster, and you have created a variable, thrustOn, and set it to false by default. This means that if we were to run the game the Bath Tub would no longer take off, because the Thruster has a thrust of 0.0 in all directions by default.

Create the following function in the FlyMe Script:

function FlyMe:ToggleThruster()
    if self.thrustOn then
        -- turn the thrust off
        self.thruster:SetForce( Vector.New( 0, 0, 0 ) )
        self.thrustOn = false
    else
        -- turn the thrust on
        self.thruster:SetForce( Vector.New( 0, 0, 150000 ) )
        self.thrustOn = true
    end
end

If you read through the code, you can see that it is “toggling” the Thruster on and off, by setting the amount of force that the Thruster has. The code uses the thrustOn variable to determine whether the Thruster is on or off (remember it is set to off in the Init function at the start). If the Thruster is on, then turn it off, and if it is off then turn it on. 

Tech Tips: Flags

thrustOn is a specific type of variable that programmers call “flags”. A flag is essentially a boolean value, which describes the state of something that can only have two states. Here it is the Thruster, and we are using a flag to tell whether the Thruster is on or off.

Now that we have made a function which can turn the Thruster on or off, we can call this from some of the inbuilt Events within Crayta. Return to the game Editor.

Create a new Trigger. Make sure to set the size, and reposition as required.

Add the Trigger to your Game World. Set the size and position accordingly. You can place another Prop or Voxels underneath it for testing purposes. This time I have selected a some beautiful Party Voxels.

Select the new Trigger that you just added (trigger2 in my case).

Use the Event boxes to add Event Listeners to the onTriggerEnter and onTriggerExit boxes. Make them both equal the following:

Entity: Bath Tub (or the Prop Entity you selected)
Script: FlyMe
Event: ToggleThruster

Add the bathtubs FlyMe:ToggleThruster function to the onTriggerEnter and onTriggerExit Events for the second Trigger.

Using the inbuilt Trigger Enter/Exit Events Listeners means you can very quickly link these Events to a function that you want to call. You can add more than one function to each Event, and they don’t have to be on the same Entity. Using the Packages and the tools that are available to you (like the physics engine) is all part of being an efficient programmer.

Test your game. When you enter the new Trigger, you should find that the Bath Tub levitates into the air. When you exit the Trigger, you should see it fall back to land.

Impress your friends by levitating a bath!

Recap

Success! You have now embarked into the world of physics within Crayta. Now that you have a basic understanding of Thrusters and launching the main character you can make lots of flying inventions to pilot or use as obstacles.

Adding Polish

Try creating a flying Bath Tub that you can easily operate:

  • Use trial and error to alter the amount of force that is suitable to make the Bath Tub more gradually fly into the air when you enter the Trigger
  • Use trial and error to select an amount of force that can make the Bath Tub hover when you leave the Trigger
  • Add another Trigger. Alter the FlyMe Script so that it is possible to have 3 different states for the Bath Tub: Rising, Hovering and Falling. Try using a number variable instead of the flag – when the number is 0 the Bath Tub is rising, when the number is 1 the Bath Tub is floating etc.
  • How could you add thrusters that move the Bath Tub in different directions?

Next steps

Congratulations. In the next tutorial in this series we put together everything you’ve learned so far to make a Highly Dangerous Football Game!