For my current game project I decided to draw inspiration from the recent release of Octopath Traveler and aim for an artistic popup book style. I want to take it a step further though, adding in some action stealth elements like climbing and sneaking around.
Source code examples for the project are available here.
To start, I needed to utilize the Paper2D functionality in UE4 to help with rendering sprites inside of a 3D environment. I created an instance of APaperCharacter and dove on in.
Since my background is in C++ and software development in general, I wanted to implement as much as made sense in code. For the most part, all components that were added to the PaperPlayer were instantiated in the constructor. Then delegates were connected during the BeginPlay function override in the PaperPlayer class.
After adding simple directional movement using “wasd” and some controller input, it was time to implement ladder climbing. To do this I took the approach of using the falling physics state found in UCharacterMovementComponent and wrapping some custom “physics” around it.
Whenever the player is actively colliding with the ladder the effect of gravity is disabled. This prevents the player from falling while they are hanging on to the ladder, similar to the way you wouldn’t typically fall off a ladder in real life. The previously set value was cached for later so it could be returned to the previous state, before the player was on the ladder.
Now that the player has been determined to be on the ladder, it’s time to figure out what their intent is.
First, if the player is currently on the ground, they should be able to freely move away from the ladder. They also need to be able to start climbing the ladder in this case. To accomplish this, the player’s desired velocity in the XY-plane was left alone. The desired velocity along the Z-axis was calculated by determining the desired XY velocity along the direction opposite to the ladder’s face direction. This provides the amount that player is currently heading “toward” the ladder and translates that into a vertical motion
Second, if the player is not currently on the ground they should be stuck to the face of the ladder. They still need to be able to climb and descend, but they should also be able to move laterally along the face of the ladder. To accomplish this, the player’s velocity in the XY-plane was calculated by removing the portion of the desired velocity vector which ran perpendicular to the face of the ladder. This leaves only the portion of the vector along the face of the ladder and prevents the player from moving away from the ladder face while descending. The desired velocity in the Z-axis was calculated the same as in the first case. The only difference is that the bottom end of the velocity wasn’t clamped at 0, allowing the player to descend the ladder.
Now that everything is in place to control the player’s “falling” while on the ladder, the only thing left to do is add some actual movement.
Implementing movement while in the falling state proved to be mildly annoying. The proper way would be to add a custom physics state for climbing and handle all the physics in there. Since I haven’t done that yet I decided to work around the existing falling physics.
While on a ladder, the player is moved around using impulses determined from the ladder velocity calculation. Since these impulses are additive and the goal was to have movement similar to that of movement on the ground, on each tick the movement needed to be stopped to remove the player’s acceleration and make the controls feel tighter. This ended up working great and the controls feel how I wanted while climbing a ladder.
And finally, here is a sample of ladder climbing in action!
Overall I’m pleased with how the ladder climbing movement worked out. I would like to move the logic into a custom physics state implemented in a new MovementController. That way I can easily reuse the component to allow NPCs to also climb ladders.