SCharacter class overview - whoisEllie/Project-Isolation GitHub Wiki
SCharacter
Overview
SCharacter
is the foundational class for project isolation. As the name suggests, this is the class which holds all the data and functions that the player will use to interact with the world. If we imagine all of project isolation as a flow chart, the SCharacter
class is the centre of it all, with other classes (and indeed, mechanics implemented in these classes), branching out from SCharacter
in various directions. This is where we implement the player's inputs, and potentially pass them through to other classes, such as the weapon.
Variables
-
FWeaponDataStruct
- Contains the details for the currently spawned weapon, such as how much ammo it has, its health and its array of attachments. -
USkeletalMeshComponent* meshComp;
-meshComp
is the mesh used for the player's hands. AsSCharacter
is built off of UE4's baseCharacter
class, it already comes with a mesh slot, which could in theory be used for a hands mesh. However, this slot is not set up to receive input from the mouse, and is best reserved for use with a full mesh in a third person setting. If you'd like to use a dual mesh system, it's recommended to use theCharacter
mesh for the Third-person mesh, and to usemeshComp
for your First-person arms. Mesh can be adjusted in Blueprint. -
UCameraComponent* cameraComp;
-cameraComp
is the component for the First-person camera. It's position and additional details are editable in Blueprint. -
USpringArmComponent* springArmComp;
-springArmComp
is theRootComponent
of theSCharacter
class. It receives the input from the mouse that we need to rotate the camera. It's length is set to0.0f
in Blueprint, as we're using it for a First-person camera rather an a Third-person one. Details adjusted in Blueprints. -
TSubclassOf<ASWeaponBase> primaryWeapon;
-primaryWeapon
keeps track of the player's, well, primary weapon. This variable needs to be updated if the player picks up a new weapon that you want to be 'permanent', i.e. stay in the player's inventory if they switch to another weapon, such as a pistol. If this variable is not updated, the player will be returned to their previous weapon when they hit '1', or whatever input you have set to callSwapToPrimary
. Currently set in Blueprints. -
TSubclassOf<ASWeaponBase> secondaryWeapon;
-secondaryWeapon
keeps track of the player's, well, secondary weapon. This variable needs to be updated if the player picks up a new weapon that you want to be 'permanent', i.e. stay in the player's inventory if they switch to another weapon, such as a rifle. If this variable is not updated, the player will be returned to their previous weapon when they hit '2', or whatever input you have set to callSwapToSecondary
. Currently set in Blueprints. -
ASWeaponBase* currentWeapon;
-currentWeapon
is a reference to the weapon the player is currently holding in their hands. It is used to call functions such asStartFire
andReload
within the currently equipped weapon, and is updated with theUpdateWeapon
function. -
bool bWantsToAim
- Keeps track of whether the player wants to aim or not. When we transition from states where the player is not allowed to aim to states where the player can aim, we can use this to let the player ADS without having to re-click the ADS button. -
bool bIsAiming
- Keeps track of whether the player is actually aiming or not -
bool bHoldingCrouch
- Keeps track of whether the player is holding the crouch button -
bool bPerformedSlide;
- Have we performed a slide yet? -
bool bHoldingSprint;
- Keeps track of whether the player is holding down the sprint button -
bool isCrouching;
- keeps track of whether we're crouching (for animations) -
bool isSprinting;
- keeps track of whether we're sprinting (for animations) -
float finalCapsuleHalfHeight;
-finalCapsuleHalfHeight
is the target half-height for the capsule which the player will move to. Set in Blueprints. -
float defaultCapsuleHalfHeight;
-defaultCapsuleHalfHeight
is the default height of the player. This is determined by the height of theCapsuleComponent
in Blueprints, and set onEventContruct
. -
float crouchSpeed;
-crouchSpeed
is the speed at which the player should crouch (i.e. the interpolation speed betweendefaultCapsuleHalfHeight
andfinalCapsuleHalfHeight
). Set in Blueprints. -
float sprintSpeed;
-sprintSpeed
is the movement speed of the player while in the sprinting state. Set in Blueprints. -
float walkSpeed;
-walkSpeed
is the movement speed of the player while in the walking state. Set in Blueprints. -
float crouchMovementSpeed;
-crouchMovementSpeed
is the movement speed of the player while in the crouching state. Set in Blueprints.
Functions
-
void MoveForward(float value);
-MoveForward
is one of unreal's default functions, included withCharacterMovementComponent.h
. We call it to allow the player to move forward/backwards (asvalue
can be both positive and negative, with a negative value being backwards movement). UE4 documentation here) -
void MoveRight(float value);
-MoveRight
is one of unreal's default functions, included withCharacterMovementComponent.h
. We call it to allow the player to move right/left (asvalue
can be both positive and negative, with a negative value being movement to the left). UE4 documentation here) -
void LookUp(float value);
-LookUp
is one of unreal's default functions. We call it to pass through the respective mouse axis (Y in this case) as an input with which to move a component. In Project Isolation, we move a Spring Arm Component, as Cameras don't support receiving this type of input. -
void LookRight(float value);
-LookRight
is one of unreal's default functions. We call it to pass through the respective mouse axis (X in this case) as an input with which to move a component. In Project Isolation, we move a Spring Arm Component, as Cameras don't support receiving this type of input. -
void ExecCrouch();
-ExecCrouch
is an alternative to UE4's built inCrouch
function. Said crouch function is essentially a switch between two different capsule component heights, and as such instantly switches between a standing and a crouched state.ExecCrouch
takes an alternative approach, where based on the player's current state, we either set the player to be crouched or standing. Following that, a chunk of code located in theTick
function switches atargetHalfHeight
between thedefaultCapsuleHalfHeight
(or the half height of the player's capsule when the player is standing) and thefinalCapsuleHalfHeight
which is the half height of the capsule while the player is crouching. AnFMath::FInterpTo
function then smoothly transitions between the player's current capsule half height, and the desired value oftargetHalfHeight
. -
void StartSprint();
- As we use two inputs for the sprinting implementation (AnIE_Pressed
and anIE_Released
), we need to map this to two functions.StartSprint
is called when the player presses down the chosen sprint key, and does exactly what it says on the tin, it puts the player into the sprinting state and updates any relevant variables. -
void StopSprint();
-StopSprint
is the opposite ofStartSprint
, and is called when the player releases the chosen sprint key. Note that it is only executed if the player stops sprinting by releasing the sprint key, not if the player crouches while they are sprinting. It does the same thing asStartSprint
, but in reverse, putting the player into the walking state (if and only if the player is in the sprinting state at the time of execution) and updates any relevant variables. -
void UpdateMovementSpeed();
-UpdateMovementSpeed
exists in order to avoid cluttering functions such asStartSprint
with numerous updates to the player's movement speed (GetCharacterMovement()->MaxWalkSpeed
). It's called inExecCrouch
,StartSprint
andStopSprint
after they finish executing any required code, and updates the maximum movement speed based on the current movement state of the player. The movement speeds get updated based on the variablessprintSpeed
,walkSpeed
andcrouchMovementSpeed
, with each applying to their respective movement state. -
void UpdateWeapon(TSubclassOf<ASWeaponBase> newWeapon);
-UpdateWeapon
is called every time we need to give the player a weapon. This does not assign a weapon to either the primary or secondary weapon slot, rather, it puts the weapon in the player's hands. The reference to this weapon is stored in thecurrentWeapon
variable. The function takes aTSubClassOf<ASWeaponBase>
as an input. It first destroys the current weapon the player has equipped, spawns the weapon that was passed through and then attaches it to the player character's skeletal mesh. Note that weapons will always be spawned regardless of collision overlaps, so make sure that any weapons you attempt to spawn have their collision response set toIgnore
on all channels. -
void SwapToPrimary();
- A function that exists because I don't know how to get UE to pass arguments through when usingPlayerInputComponent->BindAction()
. All it does is callUpdateWeapon(primaryWeapon)
-
void SwapToSecondary();
- A function that exists because I don't know how to get UE to pass arguments through when usingPlayerInputComponent->BindAction()
. All it does is callUpdateWeapon(secondaryWeapon)
-
void StartFire();
-StartFire
passes the player's input through to thecurrentWeapon
function of the same name. -
void StopFire();
-StopFire
passes the player's input through to thecurrentWeapon
function of the same name. -
void Reload();
-Reload
passes the player's input through to thecurrentWeapon
function of the same name.
Uses
The use for SCharacter
is pretty clear - it's the foundation upon which we build our entire game. Within it, we handle all of our inputs, passing them through to various sub-classes, such as SWeaponBase
. It also logically follows that this is where all of our movement and camera control code is stored and executed. If you wish to modify movement, I would recommend implementing your changes here. Anything else though, such as modifications to how weapons work, or any additional functionality such as a shield system akin to Halo should preferably be implemented in a separate actor and then attached to SCharacter
.