ECOPOINT

David and Goliath, Action-Adventure, UE Tech Showcase

Overview



Responsibilities



This is a showcase of what I made during the project

Developed with a team of 14 members (5 programmers, 2 designers, and 7 artists)

Unlike the past projects I wanted to showcase my knowledge deeper rather than working on something new, thus I decided to work on the character aspect of the game.

This was one of the most difficult tasks I did during PlaygroundSquad due to the sheer scale of the project, everything from making PCG (Procedural Content Generation) to work well to having lumen & nanite work hand in hand with the overall environment.

Though I have explained more in detail about technical more than gameplay, this is by design, due to the nature of this project, we wanted to focus more on what a group of students can do in 9 weeks in the sense of using Unreal Engine.

I hope you enjoy exploring this project, and look deeper at what I contributed to the game!

Character Controller

Grapple & Climbing

void UPlayerGrappleComponent::OnGrappleHit(TObjectPtr<AActor> HitActor, const FVector& HitLocation, const FHitResult& HitResult)

Uses a cable component to know what object to grapple towards

    GrappledComponent = HitResult.GetComponent();

    LocalHitLocation = GrappledComponent->GetComponentTransform().InverseTransformPosition(HitLocation);


    PlayerCharacter->CurrentPlayerState = Grappling;


    GetWorld()->GetTimerManager().SetTimer(PullWaitTimeHandle, this, &UPlayerGrappleComponent::StartPulling, PullWaitTime, false);

    PlayerCharacter->bIsInputAllowed = false;


    GrappleCable->AttachToComponent(PlayerCharacter->GetRootComponent(), FAttachmentTransformRules::SnapToTargetNotIncludingScale);

    GrappleCable->EndLocation = PlayerCharacter->GetActorTransform().InverseTransformPosition(TargetLocation);

void UPlayerGrappleComponent::PullTowardsTarget(float DeltaTime)

When pulling towards target that is moving, we used the local hit location of the grapple component to be able to move our player with it

    if (GrappledComponent)

    {

        TargetLocation = GrappledComponent->GetComponentTransform().TransformPosition(LocalHitLocation);

    }


    FVector CurrentLocation = PlayerCharacter->GetActorLocation();

    float DistanceToTarget = FVector::Dist(CurrentLocation, TargetLocation);


    FVector NewLocation = FMath::VInterpTo(CurrentLocation, TargetLocation, DeltaTime, PullingSpeed / DistanceToTarget);

    GrappleCable->EndLocation = PlayerCharacter->GetActorTransform().InverseTransformPosition(TargetLocation);


    PlayerCharacter->bIsInputAllowed = false;


    if (DistanceToTarget <= 60.0f)

    {

        CurrentGrappleState = Holding;

    }


    PlayerCharacter->SetActorLocation(NewLocation);

Challenges 

Optimization

GPU/CPU profiling is something I am glad I worked as much as I did during this project due to the nature of researching this topic gave me a lot of contrary solutions, knowing this the way we worked ensured fast iteration without losing performance or fidelity

Performance

We knew performance would be an issue even before starting, that is why I became the "Lead" Optimizer, this was mostly due to my own initiative but also because of my past work on Rocket Rider

Solutions & Outcome

Nanite

We had struggles getting nanite to work properly with our world, everything from artifacting to frame time issues, one of the solutions to this was changing the dicing rate (the rate of which nanite clusters are created)

Performance

As mentioned, we opted to go all out when talking about Unreal Engine tech, lumen and ray tracing being the 2 major problems we dealt with.

Due to the nature of the project we opted to use emissives as light sources instead of real light, which gave us an overall better boost to performance with quality still matching our intentions.