Skip to main content

Demigod - CSGO - Update 1


The 'player' with a cylinder to identify its front face

As part of this teaching blocks assignment for my Coding & Scripting for Games module (nicknamed CSGO...we don't talk about the O) I have to make a simple game or game system inside Unreal Engine 5. This is a solo project that everyone has to do individually but as the focus is on the code, things such as appearance and presentation are not important, lightening the workload.

My idea for this project is simple: I intend to make a 3D platformer wherein the player has a dash and double jump ability which can be stringed together for impressive world traversal. At first, you may think that's too easy, UE5 already has most of that built-in...until I say that I intend to program it all myself.

Why am I doing that? Because of how the built-in versions work. Jumping, for instance, uses the advanced physics engine which makes it momentum based. You need to run/sprint before you jump or else you will go nowhere. Not only is this not desired for a cartoony platformer, but it also makes the character feel rather 'floaty', which is not useful for precise platforming. The "Character" blueprint that this is all tied to is also a bit restrictive in that it requires humanoid models in order to properly work. So even though I intend to have the player be humanoid, I want to do the movement and physics in a better way for this kind of project.

And so, that's what I've done (mostly).


Movement

Movement was really simple. First, I looked for the inputs of W, A, S, & D and flipped a boolean for each if true (returning to false when the button was released). Currently, each of the 4 keys has their own boolean so that they can be pressed together and the character move diagonally, but I believe I can keep that functionality and shrink it to 2 (horizontal and vertical) - Look at the next update to see how that goes.

Movement Input Detection

Then, I added a function ran each tick that checks for the 4 booleans, and calls the actual Move Function with the appropriate parameters.

Direction Function

Finally, the Movement Function is called. This takes a float called 'multiplier' and a boolean called 'X/Y'. The 'X/Y' boolean determines which axis the movement is applied to (X for forward/backward, Y for left/right). The multiplier variable is the speed & direction that the player moves by adding it to their position along the selected axis (using negative or positive to determine forward/backward and left/right). In unreal, the function can be called seemingly simultaneously with different parameters to allow diagonal movement. In reality, it's just calling them separately each tick, which is so fast it gives the perception of parallel processing.

(Movement with some simple rotation)

 

Rotation

Fluid Rotation was much more challenging, and had me face my old nemesis: the concept of 'forward' on axes. 

The first thing I did to achieve this was to add custom input axis mappings to the keys. W and S were mapped to "Forward-Backward", returning 1 and -1 respectively, and A and D were mapped to "Left-Right" in the same way. The way input axis mappings work is that when neither inputs are pressed, 0 is returned. They're designed for analogue inputs such as joysticks on controllers, where you can move to any degree between -1 and 1, and through this implementation that would be accepted if using another input device. But for keyboards, it's binary - you either press it or you don't. So -1, 0 and 1 are the only possible outputs.

When an input on one of the two axes is registered, a boolean called "No input" is set to false and the Rotation function is called. Otherwise, it is set to true and the function is called (this will make sense why in a bit).

Checks for movement before calling Rotation

Then, a float timeline is played, this goes from 0 to 1 in the span of a second. The two axis mappings are combined into a vector together and then converted into a rotator. The calculated z axis rotation is then used to determine the 'forward' facing direction. This is plugged into a node called 'Rinterp To' which takes a current and target rotation values to slowly transition between (rather than just snapping to the new direction). This is where the timeline comes in, as the 'Rinterp To' node uses it to animate the transition, with 0 being the current rotation and 1 being the target rotation. Points are then plotted between them to calculate the amount of rotation per tick for a smooth animation of sorts.

Rotation function (is an event because timelines can't be used in functions)

At first, this had a bug that when the player stopped moving, it would always snap back to facing up along the X axis, rather than remaining in whatever direction it was just facing. 

 


To fix this, I called the function even when not moving and added the branch that checked for 'No Input'. If it is true, it sets the current rotation directly, without any other modifications. This kept it facing the direction it had previously been moved towards until it is moved again.

And with that, the basic movement was done! It will probably get refined underneath some more, but functionally it's all there.


Next thing to tackle is jumping and gravity, since (for the player atleast) I don't intend to use the built-in physics engine at all.

Until then, though, goodbye!

- JDM

Comments

Popular posts from this blog

Game Jam #2 - Van Helsing (PART 2) - The Bullets

  (Bullet sprite by Nicolas Katsis) This part is solely on how I implemented the bullets shown in the video in Part 1. There are two parts to this split across two scripts. The first is its behaviour and the second is the spawning of the bullet. First of all, it's behaviour.   The first thing that occurs on spawn is that the bullet assigns itself to a group of objects known as "P_Bullet". You will notice in all the snippets of code that many of the variables and groups for this object are listed as "P_ something ". This is because we initially considered the idea of giving the player two different guns that they could swap between: A pistol with a higher ammo count and longer range but weaker damage, and a shotgun with a much higher damage but fewer bullets and shorter range. The P_ was a reference to 'Pistol' bullets and S_ was a reference to 'Shotgun' bullets. Unfortunately, due to time constraints, the Shotgun was never introduced. For those u...

Game Jam #2 - Van Helsing (PART 1) - The Beginning

  Game Jam #2 began on 13th October and lasted 3 weeks. The goal this time was "Shoot-em up" and the teams had been both expanded to average 4 per group and randomly assorted as opposed to being grouped based on those around you. My team consisted of the following: - Programmer (me) - Programmer - Artist - Designer  Off the bat, we were able to come up with a very solid idea for our game: A side-scrolling platformer where the player can shoot 360 degrees to kill zombies. The player can only see inside a small aura of light around them and must rely on lampposts and other light sources as well as directional audio cues to navigate the level. The other programmer, just like my last partner, had never used a game engine prior to this course. As such, we settled on using Godot for this project. The reason we chose Godot is because its proprietary scripting language, known as GDscript, is pythonic. This means it is eerily similar to python, but enhanced and integrated enough that ...