Typically I have a function to check whether an action can be done given current states.
For example, Fire input/event → Can I Fire (function) return: bool → Branch → (true) → fire action → set state
In the conditional function I’ll check if:
- Is equipped (actually has a weapon equipped)
- Current weapon obj is valid
- ammo > 0
- not falling
- not in swimming state
- and many other bools/states etc.
It can be a tedious process, but it has to be done. I always start out by determining “what should prevent this action from occurring”. I set up all the needed conditional vars. Then write my If statements.
Take a look at the Character Movement Component (CMC) Jump and Crouch/UnCrouch functions.
example: Jump line 877
bool UCharacterMovementComponent::DoJump(bool bReplayingMoves)
{
if ( CharacterOwner && CharacterOwner->CanJump() )
{
// Don't jump if we can't move up/down.
if (!bConstrainToPlane || FMath::Abs(PlaneConstraintNormal.Z) != 1.f)
{
Velocity.Z = FMath::Max(Velocity.Z, JumpZVelocity);
SetMovementMode(MOVE_Falling);
return true;
}
}
return false;
}
bool UCharacterMovementComponent::CanAttemptJump() const
{
return IsJumpAllowed() &&
!bWantsToCrouch &&
(IsMovingOnGround() || IsFalling()); // Falling included for double-jump and non-zero jump hold time, but validated by character.
}
UnCrouch starts on line 2703
void UCharacterMovementComponent::UnCrouch(bool bClientSimulation)