In The Chamber

Contributions

Project Overview

Personal Notes

The team size was a warm welcome, enabling me to work on the things I really wanted to work on, getting able to know how one would approach an ability system was a unique insight into a genre I deeply love.

Knowing this was my first time ever doing a project in Unreal Engine, I was able to make a system for abilities in the game. Being able to implement them in both c++ and blueprints, while also making the player controller, empowering an understanding of Unreal Engine 5 in a way I wouldn't have otherwise.

Development Process

Ability System

We knew the ability system was important, so I started work on it as fast as possible, I started by looking up documentation for GAS, a system we consciously did not choose owing to the fact it would be beyond the scope of the project. I started with making an example ability that activated from blueprints. Then I branched out to make the code more blueprint friendly by making helper functions, both for c++ and blueprints, validating a more agile workflow for designers and other programmers.

I thought the most effective way of making an ability system would be to let any entity that would end up using an ability would end up as part of the "ability user" class. The ability system component would automatically make the associated ability from blueprints, and if necessary, bind it to an input.

const TObjectPtr<AAbility> NewAbility = NewObject<AAbility>( this, Class );


Abilities.Add( NewAbility );


if ( !IsValid( InputAction ) )

    return;


NewAbility->BoundTo = InputAction;


if ( FAbilityStruct* Binding = BoundAbilities.Find( InputAction ) )

    Binding->Abilities.Add( NewAbility );

else

{

    FAbilityStruct BindingInfo( { NewAbility } );

    BindingInfo.Handle = InputComponent->BindAction( InputAction, ETriggerEvent::Started, this,

    &UAbilitySystemComponent::TryActivateAbilityWithInput, InputAction ).GetHandle();

    BoundAbilities.Add( InputAction, BindingInfo );

}

An example of two ability users using an ability, the player and the spike trap on the ground

Player Controller

We wanted the camera to work in a specific way, meaning we would have to make custom camera functionality in c++. Likewise, the player control scheme had to be agnostic to the platforms we were planning to use. I also made the camera rotation, speed and distance from the player when moving modular.

void APlayerCharacter::RotateMesh() const

{

    FVector  DesiredDirection = LookInput.IsZero()

        ? FVector( MovementInput.X, -MovementInput.Y, 0.f ).GetSafeNormal() : 

        FVector( LookInput.X, LookInput.Y, 0.f ).GetSafeNormal();


    FRotator TargetRotation = FRotationMatrix::MakeFromX( DesiredDirection ).Rotator();


    TargetRotation = FMath::RInterpTo( GetMesh()->GetRelativeRotation(), TargetRotation,

                                       GetWorld()->GetDeltaSeconds(), RotationSpeed );


    GetMesh()->SetRelativeRotation( TargetRotation );

    SetCameraRelative( CameraSpeed );

}


void APlayerCharacter::SetCameraRelative( float _CameraSpeed ) const

{

    FVector DesiredDirection = LookInput.IsZero() 

? CharacterMovementComponent->GetCurrentAcceleration().GetSafeNormal() * FVector( UE_SQRT_2 ) : 

GetMesh()->GetRightVector();


    FVector TargetLocation = FMath::VInterpTo( SpringArmComponent->GetComponentLocation(),

                        GetActorLocation() + DesiredDirection * FVector( CameraDistance ),

                                            GetWorld()->GetDeltaSeconds(), _CameraSpeed );


    SpringArmComponent->SetRelativeLocation( TargetLocation );

}

Using the assigned inputs, the camera will move appropirately