Devlog 4 - Moving Platforms and Elevators!
Moving Platforms are a staple of the platforming genre of games. At first glance, they might seem pretty simple but there's a bit more than meets the eye!
The Player
I bet you thought I was going to start talking about the platforms! Before we can even think about making a moving platform, we have to first understand how the player character moves throughout the world, or rather what moves the player?
This is a concept in games that is universal, but is almost always handled completely differently! Player movement can be a very complex problem to tackle in games, as there are many different ways the player can move throughout the game-world. Many player characters can walk, run, jump, crouch, dash, wall-run, double jump, etc.
However what many people forget to take into account is that the user isn't the only thing that can move the character, and the moving platform is a perfect example! Without taking this into account, the player won't follow the platform and will simply fall right off!
Moving the player character with a platform can usually be tackled in two different ways, but both essentially doing the same thing.
1. The Parental Paradox
In many game engines, objects in the game can have a parent-child relationship. Essentially what this means is that if you set an object to be a child of another, any movement, rotations, and scaling will be applied to the parent object will also be applied to all child objects. This sounds great right? Just make the player's parent the platform when he's standing on it, and de-parent the player when he leaves the platform! In theory this could work, depending on how your player object is set up. This also takes away a lot of control from the developer using this method, as there's no way to control or limit how exactly the parent movement is effecting the child. One other problem you could run into is knowing when exactly the player should be a child of the platform, which could be done by collision, raycast, etc. This may very well work perfectly for your game, but for this project I had to get a little more creative given the very complicated movement system developed for our character.
2. The Momentary Manual Movements
Another way that we could make our player move with the ground they're standing on is done completely via code. This is handy for developers who want more control over all the movement applied to their character, as well as developers who can't simply make their player a child of another object. For this approach, we need to find out how much the platform has moved recently, and then apply that exact movement to our player so that it matches up!
The way I went about it for our game has a few dependencies:
- Knowing whether or not the player is on the ground, instead of in the air
- Knowing when we should be applying the movement of the platform
- Knowing exactly how much the platform has moved since the last check
- A way to move our player in combination with other forms of movement!
If you know all those things, then we can get cooking! The logic is actually fairly simple to follow, so don't be nervous!
1. First things First
Before we can start moving the player, we need to know whether or not we should move the player with the platform. In my case, all we need to do is check if the player is on the ground, and if so, get a reference to the Transform of the ground we're standing on.
2. Setting things Up
Now that we know the player is on the ground and we know what ground we're standing on, we can begin to move our player according to the movement of the ground! To do this, we need to start in our Update(), FixedUpdate(), or any other kind of loop function that we can run repeatedly and know exactly how much time has passed since the code was last run. Now we can start by creating a variable that stores the previous position of the platform. Initialize it at the top of your class, we'll be setting it later. We also need a variable that stores the current position of the platform. If you're using Unity or a similar game engine, we can already access this by Transform.position so you can skip this. Finally, we need to simply make sure only to run this code inside of an if statement that looks something like this:
if(isGrounded && platform.transform != null)
This is simply to make sure that we only move the player with the ground when we're on the ground and we know exactly what we're standing on! Let's move forwards...
3. Moving things Along
Now that we know those things above, we can begin to do some fun math! This is some really simple vector math, so don't panic! What we need to do is calculate how much to move the player, so we can do that by subtracting the previous position of the platform from the current position of the platform. This should look something like:
Vector3 moveDelta = platform.position - platformPreviousPosition;
Now that we have this variable, we almost know exactly how much to move the player. If you remember, we still need to find out where the platform's previous position is! After we declare that variable, we'll want to set the previous position to the current position. This ensures each time we run this code both the previous and current positions are accurate. We'll also want to set the previous position to the current position in the Start() function or similar place where code runs only once at the start of play. To ensure that the previous position is never zero.
Depending on how your player is set up, this might be tricky as to not have other parts of your movement code override this movement! If you're using Unity and a Character Controller, you can use characterController.Move(moveDelta) or if you're using a Rigidbody, you can use rigidBody.MovePosition(moveDelta). These two methods are a sure-fire way to ensure that the player actually moves the amount that we're looking for, rather than moving too much or too little.
The Platforms
Now that we have set up our player to move with whatever it's standing on, it's time to make what we're standing on, move! There's many ways that you can do this, but I'm going to make a simple platform that moves back and forth from points A to B and it begins moving only when you start standing on it, and it stops when it reaches it's destination. This part is a little more Game Engine specific, so I'm going to explain how I made it specifically for Unity.
To start, we'll want to find a way to know when the player is standing on the platform. One easy way is by using Trigger Colliders. These can trigger code exactly when something enters inside the collider and exits it. These run the OnTriggerEnter(Collider other) and OnTriggerExit(Collider other) functions on any scripts that are attached to the same GameObject as the trigger collider. Once we declare our OnTriggerEnter function, we can check if what entered the trigger is the player by this neat little if statement:
if(other.CompareTag("Player))
You just want to make sure that your Player character has the "Player" tag.
Great! Now that we know when the player steps on the platform, it's time to move the platform! An easy way to do this is simply interpolate it's position based on how much time is passed out of how long we want the platform to take to get from point A to B. Before we can do that though, we need to know where we're going and where we're coming from! To do this, we'll want to make two Empty GameObjects and name them Start Position and End Position. We can then move these around and refer to them in our code to know where to go! We'll also want to define in a float variable the travel time from point A to B. I usually use 3 seconds for medium to short distances, but change it around to see what feels good in your game!
Now when we tell the platform to start moving, we can simply find out where to make the platform move to by finding out where it isn't. If the platform's position is equal to the start position, then we know to move it to the end position. Otherwise, we'll move the platform to the start position. We'll also want to make some Vector3 variables local to this function to store where we currently started from, and where we're currently going to. This so we don't have to re-write code, as we're not always going to be starting from the start position and ending at the end position, sometimes we'll be ending at the start position and vice-versa.
From there it's just a matter of tracking how much time has passed, dividing that by the travel time, and plopping it into a Vector3.Lerp function that can look like this:
Vector3.Lerp(currentStartPosition, currentEndPosition, elapsedTime/travelTime);
We can then repeat this code until the elapsed time is greater than or equal to our travel time. Once we do that, we know that the platform should be at the end position, but Lerps aren't always 100% accurate due to the nature of lerping, so we'll go ahead and set the position of the platform exactly to the currentEndPosition. Now that we're done, our function should look something like this:
IEnumerator MovePlatform()
{
float elapsedTime = 0;
Vector3 currentStartPosition = platform.position;
Vector3 currentEndPosition = platform.position == startPosition ? endPosition : startPosition;
while(elapsedTime < travelTime)
{
platform.position = Vector3.Lerp(currentStartPosition, currentEndPosition, elapsedTime/travelTime);
yield return new WaitForEndOfFrame();
elapsedTime += Time.deltaTime;
}
platform.position = currentEndPosition;
}
End Result
Now that we have all of this, you should have some really great moving platforms!
Script Scrapper
Status | In development |
Author | trweening |
Genre | Adventure |
More posts
- Creating the Final Boss: The Dev!1 day ago
- Devlog 5 - Enemies!2 days ago
- Devlog 3 - Level Design2 days ago
- Devlog 2 - Cloaks and Capes!9 days ago
- Devlog 1 - Environment Art16 days ago
Leave a comment
Log in with itch.io to leave a comment.