• Control Room

  • Entrance

  • Exhausted

  • Lift

  • Start Menu


Trapped in a containment facility hidden beneath Abertay, you must figure out a way to escape. Don’t forget to take some incriminating evidence on your way out. This first person 3D puzzle game challenges you to find all the hidden clues to escape from the containment facility.

The game was created using Unreal Engine 4 with C++ classes for interaction and blueprints for easy iteration and recreation of many in-game elements.

Challenges encountered

​The main area of problems on this project were the limitations of mobile development on Unreal Engine at the time of this project. Mobile development has advanced greatly so many of the limitations of converting to mobile were no longer relevant.

The other area I researched was various different control schemes, as the traditional twin sticks on the screen is absolutely horrible, however due to time constraints this was not taken further. The control schemes developed were interesting but none were deemed suitable so mobile was dropped from the finale version, though there was a stable mobile version of the game.

This project was recently picked up and redesigned for Google Cardboard, as it felt like an interesting fit. However due to other projects it is still just a side project for more learning on VR systems.​


  • Occulsion depth rendering to highlight interactable models ( only available on desktop due to mobile limitations)
  • Collectable items hidden around the level
  • Usable switches
  • Lockable doors
  • Secret passage ways
  • Emissive lighting for monitors lights and warning signs
  • Mobile version, using reduced lighting and shading features

Cool Code

These are the functions available to the blueprint to allow the usable object be modified for any interaction in blueprints.

UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "Item: Used"))
bool OnUsed(ACharacter* character);
bool StartFocusItem();
bool EndFocusItem();

​This is the function used within the character class. It runs a ray trace to check if there are any usable actors in front of it and creates a pointer to them if there is. This pointer is then later used to call the “UsableActor” functions, which can be modified within blueprints. Allowing for easy visual scripting for the aesthetic aspects; text, colour, position, effects etc. of all interactable objects.

Performs raytrace to find closest looked-at UsableActor.
AUsableActor* ACPPEscapeCharacter::GetUsableInView() {
    FVector camLoc;
    FRotator camRot;
    if (Controller == NULL)
        return NULL;
    Controller->GetPlayerViewPoint(camLoc, camRot);
    const FVector start_trace = camLoc;
    const FVector direction = camRot.Vector();
    const FVector end_trace = start_trace + (direction * MaxUseDistance);
    FCollisionQueryParams TraceParams(FName(TEXT("")), true, this);
    TraceParams.bTraceAsyncScene = true;
    TraceParams.bReturnPhysicalMaterial = false;
    TraceParams.bTraceComplex = true;
    FHitResult Hit(ForceInit);
    GetWorld()->LineTraceSingle(Hit, start_trace, end_trace, COLLISION_PROJECTILE, TraceParams);
    return Cast(Hit.GetActor());

Products used

Stewart L. McCready
Code Monkey

Game programmer and code monkey, living in Inverkeithing, Scotland.