My take on this course focused on designing an accessible, self-explaining puzzle.
Here’s my final build of the project for download: CryptRaider.zip - Google Drive
~
SPOILERS AHEAD if you want to play it first, and see how the puzzle design holds up.
The player is dropped in at the corner of the courtyard, implying our thief has just climbed in, over the perimeter wall. From this first perspective, the player has already received a clue. (not the glowing text)
The clue is the silhouette of the window grate on the wall in the distance.
This “silhouette” is faked, by the way. A rectangle light source has been placed here in the courtyard, outside the window… with a second window in front of it – set to be invisible, but to cast shadows, and to have no collisions.
Starting in the corner of the courtyard, the player is forced to walk passed the exterior of this room, which will not have an entrance on the interior. This unique window and its shadow-cast, seek to reinforce the awareness of this room; that the player will note its absence, once inside.
This is my secret entrance. I did a lot to build a custom blueprint for it from multiple static meshes, and framed it in with wood beams and stone arches. For a third and final reinforcement, gargoyle statue has been left in a place that appears to have fallen off the plinth.
Once opened, the secret room turns out to be the armory. I used another free asset pack from the UE marketplace to outfit it. In the lower right of this image, on the table, there is a small stone statue… The key for the real secret wall. Getting into this room was the tutorial. Now you know what to look for. And what’s that on the opposite side of the main hall? But the exact same wall recess and empty plinth.
After a lot of hair-pulling, I figured out a way to make it so that whatever the grabber grabs, will be spun to stand upright, and to face the player.
if (physHandle && physHandle->GetGrabbedComponent()) {
FVector targetLocation = GetComponentLocation() + GetForwardVector() * holdDistance;
FRotator targetRotation = GetComponentRotation();
targetRotation.Pitch = 0;
targetRotation.Yaw += 90;
physHandle->SetTargetLocationAndRotation(targetLocation, targetRotation);
}
This, in concert with heldComponent->GetComponentRotation()
for the FRotator in the PhysHandle->Grab… makes all the statues stand upright and face the player, when held.
Here’s another little trick I implemented, to keep the statues’ physics from going to sleep while they are being held. The Bump() function being called just adds a minor impulse on the Z axis.
// Nudge the held object once every half second to keep physics active.
GetWorld()->GetTimerManager().SetTimer(keepAliveTimer,this,&UGrabber::Bump,0.5,true);
The key for taking the final statue is at the end of the first hallway on the right. So, hopefully, the player goes into the mausoleum, tries to take the golden statue, gets locked in, and then goes hunting for something to replace it with… Which is the stone version of the same statue, by the way.
Yet another free asset pack was put to use in making the mausoleum into a treasure room. My head-canon is that some royal has the guards storing treasure down here. The guards aren’t happy about it, as they’re running out of room for the dead. And will soon need access to the side blocked by chests, jewels, and coins!
After the Indiana Jones trick, the player will hopefully return to the starting position, with the glowing text that commanded “Bring me the Golden Statue.” If they do, the moment they set it down on that tile of floor…
The tile descends 6000 units, over 20 seconds, to what I’ve named the “Winner’s Circle” in the project structure. Invisible planes are used to keep the player from jumping off the descending platform, or out of the winner’s circle.