Day 83 — Pushing Objects to Complete Puzzles

Connor Fullarton
4 min readJun 6, 2021

--

Hey and welcome!

Here’s a fun one for you today, we’re going to look into allowing our player to be able to push an object so that it can sit on a pressure plate in order to open a door or complete a puzzle or whatever your imagination can think of.

First let’s get a box set up, go ahead and add in a cube object into your scene and give it a tag of Box. Next, add a rigidbody onto this box and make sure you freeze the rotation on the x, y and z in constraints otherwise you’re going to something like this when you push the box:

Now let’s look into how to move the box itself, we’re going to be using OnControllerColliderHit again in order to detect the collision so let’s update the code for that in our Player script to account for this:

private float _pushSpeed = 2.0f;private void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.transform.tag == "Box")
{
Rigidbody box = hit.collider.GetComponent<Rigidbody>();
if (box != null)
{
Vector3 pushDirection = new Vector3(hit.moveDirection.x, 0, 0);
box.velocity = pushDirection * _pushSpeed;
}
else
{
Debug.LogError("Box is null");
}
}
}

You’ll recognise the hit.transform.tag from the wall jumping code but we’re just using this to check that it’s the box being collided with. We then create a local variable to store the Rigidbody in as we need that to alter the velocity value of the rigidbody so that we can make the cube move.

Something a bit new we’re using here is moveDirection which is being assigned as the x value for the Vector3 we’re defining for pushDirection. It’s a pretty cool method that gets the direction the character controller was moving in when the collision occurred. So if our player is moving to the left when it hits the box then the box’s direction will also be set to the left.

With that direction we can then assign it to the velocity to the box to get this effect:

With that part done it’s time to give some functionality to the pressure plate I’ve added in here. To create a pressure pad for yourself you just need a cube object that you can flatten out and then create a second cube object that will be it’s parent but delete the mesh renderer and keep its collider so that you have something like this:

Next create a PressurePlate script and add in the following:

private void OnTriggerStay(Collider other)
{
if (other.tag == "Box")
{
float distance = Vector3.Distance(transform.position, other.transform.position);
if (distance < 0.05f)
{
Rigidbody box = other.GetComponent<Rigidbody>();
if (box != null)
{
box.isKinematic = true;
}
MeshRenderer renderer = GetComponentInChildren<MeshRenderer>(); if (renderer != null)
{
renderer.material.color = Color.green;
}
Destroy(this);
}
}
}

We’re using an old favourite method here which is Distance in order to figure out when the box is close enough to a certain area of the pressure plate. Once it gets to that area we set the isKinematic property in the rigidbody for the box to true which causes it to stop and become immovable.

Once stopped we then grab the Mesh Renderer component for the pressure plate in order to change its color from yellow to green.

Lastly we destroy the current script by using Destroy(this), the reason we’re doing this is because the OnTriggerStay method is being used which means that while the box is within the collider for the pressure plate this bit of code will keep running every frame which we don’t want it doing.

That’s not working too badly here, and it’s set up to add something extra on top of this, like say a door opening or an enemy spawning.

--

--

Connor Fullarton
Connor Fullarton

Written by Connor Fullarton

Hey and welcome! My name is Connor and my goal here is to put out a daily post for a full year about my game development journey.

No responses yet