Creating an FPS in UE4: Devlog 1 : Analysis and Setup
Creating an FPS in UE4: Devlog 1 : Analysis and Setup
I have forever been interested in developing a “Nazi Zombies” styled game based off of the Call of Duty Franchise, specifically targeting Black Ops as my source inspiration. I explored creating an FPS when I was trying to start learning the Unreal Engine, you can find that exploration here. My main issue with that exploration, was that I didn’t know what I was doing. Granted, I still don’t, but I have a much better handle on Unreal now than I did back then, and I think I might have a slightly better idea about how I want to setup and structure my FPS. So for this post, I’ll just be talking about how I started doing some analysis on the types of movement and the things I want to support, as well as how I started setting up and configuring my project, what’s going well for me currently, and what is going poorly
Movement Analysis:
As I mentioned above, my main inspiration for this game is Black Ops 1. So, naturally I went ahead and downloaded it on Steam so that I could really get a feel for the movement. During the first part of development, I am going to primarily focus on getting the movement feeling good. Even if there is nothing to shoot at, and nowhere to run, I want it to feel responsive, fast and fluid to do all the actions in the game. Before getting bogged down in networking, damage, AI, scoring, and rounds, I want the player controller to feel good.
So, In picking up Black ops, I made note of the primary actions available to you: walking, turning, running, jumping, aiming, shooting, swap weapons, interact, reload, melee, grenade, special grenade, crouch, prone, crouch-walk, prone crawl, dolphin diving. Quite a few more commands than one would initially think! And of course this doesn’t really include things like repairing windows, picking up environment objects, or buying weapons, etc.
So obviously, I want to start with the basic movement, which for me means, walking, turning, sprinting, crouching, crouch-walking, prone, prone crawling, and dolphin diving. Although personally, I’m not considering implementing dolphin diving too strongly, if anything I would probably make a slide instead, but if that is something I develop, it may be in the late stages, as I don’t really deem that to be too important for my purposes. Here are some of the things that I make note of while playing that I want to replicate when creating my version. It’s worth noting, that currently, I will not be focusing on the audio portion of the game, or much of the combat, or interactions, moreso how the player moves and feels within the environment.
When moving, there is a slight head bob motion, this is amplified when sprinting. When looking around, the characters hands sway slightly to keep up with the head. To go prone, you may hold the crouch button longer to automatically transition. When crouched or prone, if you press the sprint button, it will automatically transition to standing, and start moving into a sprint. When clicking the sprint button, if you stop clicking in, but keep holding forwards, you continue sprinting until you lower your movement analog stick closer to centered. When aiming down sights, your head does not move at all, your arms move up to the camera’s center for you, a slight blur occurs around the edges of the screen. When swinging your knife, your head moves with the blade. If a zombie is slightly out of range, and you are moving forward, you will jump forwards to stab the zombie. When swinging your knife, the camera aims towards the center of the zombie, where your knife will hit. When jumping, upon landing, there is a sway of the camera, as if your knees are bending to resist the fall. When you empty out your clip, your character automatically reloads. If you are in the middle of reloading, and swap weapons, you immediately snap out of the reload and go to swap weapons. If in the middle of swapping weapons, you may swap back and the animation continues in reverse, but at a slower rate. When firing a weapon, there are different recoil animations depending on how close the fire was to the last fire, as well as how long you have been consecutively firing. When firing, the accuracy of your weapon is reliant on how stable your arms are when firing, as well as if you are aiming down sights. When not aiming down sights, you have UI that shows the general area in which you can guarantee to fire within; This UI is adjustable and grows/shrinks as you move, crouch, prone, are moving, or are ADS. The environment includes a handful of objects that you may interact with, however most of the environment is static. You can hold the grenade or special grenade buttons and are shown cross hairs that “tick” down as the grenade comes closer to blowing. When shooting, you get points that show up dynamically in the lower-right score UI.
Movement Improvement:
This was a great list of observations, most of these things I noted above I like and would like to replicate in some fashion. However, that is not the case for all of the player movement abilities. As I mentioned earlier, I would like to swap out the dolphin dive for a slide mechanic. I also don’t like how static the environment is, I would like majority be static, such as the architecture, however, I would prefer if most items in the environment were destructible, movable, intractable, or otherwise dynamic. I also don’t particularly like the lack of feedback upon shooting and hitting a zombie. I think a hit-marker and sound effect could be really helpful with this aspect. I also would potentially like to play around with using IK and dynamic recoil as opposed to a candid recoil animation, although I played with this before and ran into issues with this. However, I think that it could really make each gun give a feeling as to how it’s accuracy is going to be. This partnered with a minor animation could do lot’s!
Choosing A Game Engine:
So, naturally I want to learn Unreal better and work in Unreal, the main trouble is which version to pick? With 5 on the verge of release I see many people opting to work in UE5 and making new projects there. However, I have downloaded the engine, and I noticed a couple things. First, the existing project that we had in 4.27 DID work in 5, however, it was quite broke visually, including UI. I also noticed many errors where I couldn’t open a project more than once without having to delete all my changes. I couldn’t open up two instances of the editor at once, which is sometimes nice when I’m trying to reference another project. And honestly, the UE5 functionality looks completely unnecessary for my purposes. I think it is incredibly greedy to expect developers and users to have the amount of RAM required for applications. I can’t even run the UE5 demo project because I lack the RAM required. In general, I don’t completely agree with the engine architecture of Unreal and think that in general engines need to start using less managed architecture styles. So, the overhead in complexity added in UE5 really doesn’t appeal to me. Anyway, I chose UE 4.27 as that’s the newest version of 4.
Setting Up A UE4.27 Project:
One of the main goals of this development is to learn (myself without a team) a way to structure, develop, and maintain a high-production value game. Meaning just that I can have a nice setup, in something that seems like a AA or AAA production in terms of where I can juice, and push polish, especially in regards to the UX, and animations. I also want to really learn UE4 from the inside as much as I can, which means I want to work in C++ as much as possible. Obviously BP is there for a reason, but I want to keep that reason limited to setting up the visual representation of the assets, I want to use little to no BP code.
All that being said, I set up this project for UE4 C++, and got started with a blank level, just a floor, some lighting. Then I wanted to get cracking on the player controller. The main thing I wanted to do was implement basic movement on-top-of the already existing UE4 Character. One thing I have never spent enough time doing is figuring out what functionality already exists in the Acharacter cpp file. The main things I saw and wanted to make use of were the Skeletal Mesh, the Character Movement component, the Jump, Crouch, and Uncrouch functions, and bPressedJump.
In setting up the initial variables and inputs for the character, I really wanted to try and change up my game flow architecture where I don’t map inputs directly to actions. In this game I am truing to take the approach of mapping inputs directly to setting boolean input flags in the player object, then using the current state of how long they have been held, what the crouch/standing/movement input state is in Tick to try and determine the best output that the player should see on screen. This realization mostly came about when trying to develop a simple method to replicate the functionality that allows you to sprint and maintain full speed until you start trying to sprint in a direction that does not match the player’s look direction by some angle. To implement this functionality, the best I could imagine was caching a dot product value of the angle that the movement direction has to be under in relation to the look angle. Then, if sprinting and you leave this range, you slow to a walking speed, and then if you push the stick back forwards you regain sprinting speed. To achieve all of this, I break up sprinting into: Setting the sprintingPressed, in Tick checking if sprintingPressed and !isSprinting and CanSprint(checks velocity angle vs look angle). If that’s the case StartSprint is called. And then alternatively, if you are sprinting and no-longer can sprint, it calls StopSprinting().
The next thing I really wanted to figure out was crouching, and this was actually something I was having a hard time testing, as I later realized that Crouch() and Uncrouch() simply set the Character capsule collider’s half-height to whatever the crouch height is, and I realized that I don’t believe that it’s affecting the character’s camera! This led me onto a whole process of setting up the character’s camera. In past, I had setup the camera, and under the camera is the player’s arm skeletal mesh. However, I was thinking that this would be more limited and harder to work with for head movement in animations. What I would really like is a character arm skeletal mesh that includes bones for the spine. And at the head, the camera would be parented to the head socket. This way, instead of the camera being the parent of the arms, the arms (and theoretically body) are the parent of the camera. In order to do this, I really need to get up on my blender skills, start modeling some arms, make a whole rigged body, and then try and parent the camera to the head! I was trying to set this up with some temporary mesh, and setting up the component in the constructor. However, I was running into many issues. Here is the process I am using: I have an arm skeletal mesh in my project, and in the FPSCharacter constructor, I am creating a UskeletalMeshComponent and attaching it to the Actor root. Then I’m using the ConstructorHelpers::FobjectFinder to load up the FPS arm skeletal mesh and then I am setting the skeletal mesh to the loaded asset. When this is found, I’m also setting an Fname that is equal to the socket name I want to attach to. Then I am using CreateDefualtSubobject<UcameraComponent> and using SetupAttachment to attach it to the FPSMesh at the socket that I have supplied. This is where it seems to go wrong, nomatter the bone name I supply it seems that the camera will never attach to the socket I want. The issue is also that if I define the camera component in the cpp, I am not allowed to set the attach socket within the editor. And I would like the camera component inside of the cpp so that I may use it in code when needed. Maybe there is some way to link a cpp variable to an Actor component, similar to the UPROPERTY( meta = (BindWidget)) to bind a Widget component to a cpp variable. I’ll have to look more into the meta specifiers, as I don’t know what practically any of them are!
Next Goals:
I think my next goals for the project would be to create some arms with some armature and a head socket and try looking into some meta tags to link them, or learn how to attach it to the socket. I want to then start working on trying to get in some basic crouching and then focus on some animations and make a gun for the character to hold!
Anyway, if anyone has any tips for success. Please let me know what I could be doing better! Thanks so much for reading and stay tuned for future updates!