PcoWSkbVqDnWTu_dm2ix
We use cookies on this site to enhance your user experience

Collision Filtering: Make a Puzzle

Collision Filtering: Make a Puzzle

Jul 03 2018, 10:13 AM PST 5 min

In this tutorial, we will cover how to build a puzzle platformer mechanic using collision filters. Specifically, we will build a force field that allows players to pass through, but blocks the motion of crates.

In our example level, we have a ledge that the player has to jump on top of. In front of the ledge is a pit covered with a force field named “ForceField.” Next to the pit is a wooden crate (unanchored) named “Crate.”

In this case, we want the player to be able to fall through the force field. But if the crate is pushed onto the force field, it should rest on top of it and not fall through. To do this, we will need to set up collision groups for the objects involved.

First, we’ll insert a Script to manage the collision groups. Inside of the script we need to make variables for PhysicsService and the parts of our level.

local PhysicsService = game:GetService("PhysicsService")

local forceField = game.Workspace.ForceField
local crate = game.Workspace.Crate

Next, we need to create the collision groups. In this case, we will need two groups, one for force fields and one for crates. We can use the CreateCollisionGroup and SetPartCollisionGroup functions of PhysicsService to do this.

local PhysicsService = game:GetService("PhysicsService")

local forceField = game.Workspace.ForceField
local crate = game.Workspace.Crate

local forceFieldGroup = "ForceFieldGroup"
local crateGroup = "CrateGroup"

PhysicsService:CreateCollisionGroup(forceFieldGroup)
PhysicsService:CreateCollisionGroup(crateGroup)

PhysicsService:SetPartCollisionGroup(forceField, forceFieldGroup)
PhysicsService:SetPartCollisionGroup(crate, crateGroup)

Note that we also made variables for our collision group names. Collision groups aren’t instances (like parts) and can only be accessed through the PhysicsService by name. It is recommended to save this name in a variable. That way, we don’t have to write it over and over again later in the code (we can just use the variable), and if we ever had to rename the group we only would have to do that in one place.

Last, we need to set up the collision rules between the groups. The force field will collide with the crate group, but not with the default group (so that the player and other objects can fall through it). The crate group will collide with everything but the force field group. To configure whether two groups will collide, we can use the CollisionGroupSetCollidable function.

local PhysicsService = game:GetService("PhysicsService")

local forceField = game.Workspace.ForceField
local crate = game.Workspace.Crate

local forceFieldGroup = "ForceFieldGroup"
local crateGroup = "CrateGroup"

PhysicsService:CreateCollisionGroup(forceFieldGroup)
PhysicsService:CreateCollisionGroup(crateGroup)

PhysicsService:SetPartCollisionGroup(forceField, forceFieldGroup)
PhysicsService:SetPartCollisionGroup(crate, crateGroup)

PhysicsService:CollisionGroupSetCollidable(forceFieldGroup, "Default", false)

And this is all we need to do to set up our mechanic. Notice that we only had to specify that the force field group doesn’t collide with the default group. Groups always start off by colliding with each other, so there is no need to explicitly instruct the groups to collide (the only time one would have to do that is if the groups were previously set to not collide with each other).

Now when the player goes through our game they will fall through the force field, but will be able to push the crate and jump on top of it to progress.

CollisionGroupPuzzlePlatformer1.gif

CollisionGroupPuzzlePlatformer2.gif

Tags:
  • collision
  • filtering
  • puzzle
  • platformer
  • mechanic