Puzzle 3

The third puzzle room will be a mix of quaternions, rotations, and vectors. The main new concept will be using a quaternion to find a specific rotation by applying a vector to another vector.

Puzzle Overview

The third puzzle riddle is as follows:

Karl is too distracted in his hobbies
if only his love life could align

This means the player must move the soccer ball so Karl is looking at Kate.

Create a Server Script

In the Hierarchy, add a new script named Puzzle3Logic to the Server Context within the Scripts folder.

Add Custom Properties

This puzzle is a bit different because the player does not necessarily matter. It only cares if the soccer ball is in the correct alignment so the two statues face each other.

Expand the Escape The Room Template and find the Puzzle 3 group. This will contain the objects required by the script. Then open the Properties window with the Puzzle3Logic script selected.

Add the following custom properties:

  • From the Project Content window, drag and drop the PuzzleAPI script as a custom property.
  • Drag and drop the Statue 1 object as a custom property.
  • Drag and drop the Statue 2 object as a custom property.
  • Drag and drop the Ball object as a custom property.

Using the Dot Product

The Dot Product was introduced in the second puzzle room and can be used to check if an object is facing a certain direction. This will be useful to check if the Karl statue is currently facing the ball or Kate statue. Our API script has a function GetFacingDotProduct that takes in two objects and returns a value between -1 (facing opposite direction) and 1 (facing exact direction) to represent how much the first object is facing the second object. The script will make Karl rotate to face the ball until it is looking at the Kate statue.

Open the Puzzle3Logic script. Add this code:

local API = require(script:GetCustomProperty("PuzzleAPI"))

local STATUE_1 = script:GetCustomProperty("Statue1"):WaitForObject()
local STATUE_2 = script:GetCustomProperty("Statue2"):WaitForObject()
local BALL = script:GetCustomProperty("Ball"):WaitForObject()

local rotateSpeed = 0.5
local stopDP = 0.999

local function RotateStatue()
	local ballDP = API.GetFacingDotProduct(STATUE_1, BALL)
	local targetDP = API.GetFacingDotProduct(STATUE_1, STATUE_2)
	
	if targetDP > stopDP then
		STATUE_1:StopRotate()
		Events.Broadcast("OpenPuzzleDoor", "3")
	elseif ballDP <= stopDP then
		STATUE_1:LookAtContinuous(BALL, true, rotateSpeed)
	else
		STATUE_1:StopRotate()
	end
end

function Tick()
	RotateStatue()
endCode language: JavaScript (javascript)

Preview the Project

Moving the ball should make Karl rotate to follow. Once Karl is looking at Kate, the puzzle door should open.

One Slight Issue

The puzzle room is functioning but there is a slight issue. Karl is not looking exactly at Kate and is off by a small degree amount. This can be seen in the properties values of the rotation.

The rotation Z property should be an even 90 since the statues are lined up.

Using Quaternions

There are many ways to find the exact rotation required for an object to face another object. The following logic will be projecting the two object’s offset vector onto a forward vector by creating a Quaternion.

Open the Puzzle3Logic script. Add this code:

local API = require(script:GetCustomProperty("PuzzleAPI"))

local STATUE_1 = script:GetCustomProperty("Statue1"):WaitForObject()
local STATUE_2 = script:GetCustomProperty("Statue2"):WaitForObject()
local BALL = script:GetCustomProperty("Ball"):WaitForObject()

local rotateSpeed = 0.5
local stopDP = 0.999

local function RotateStatue()
	local ballDP = API.GetFacingDotProduct(STATUE_1, BALL)
	local targetDP = API.GetFacingDotProduct(STATUE_1, STATUE_2)
	
	local offset = API.GetOffsetVector(STATUE_1, STATUE_2)
	local targetQuat = Quaternion.New(Vector3.FORWARD, Vector3.New(offset, 0))
	local targetRot = targetQuat:GetRotation()
	
	if targetDP > stopDP then
		STATUE_1:StopRotate()
		STATUE_1:SetWorldRotation(targetRot)
		Events.Broadcast("OpenPuzzleDoor", "3")
	elseif ballDP <= stopDP then
		STATUE_1:LookAtContinuous(BALL, true, rotateSpeed)
	else
		STATUE_1:StopRotate()
	end
end

function Tick()
	RotateStatue()
end


Code language: PHP (php)

Preview the Project

The Karl statue should now snap to the exact rotation to face Kate head on.

Summary

The Escape the Room project is now complete! There are many different applications for Vectors, Rotations, and Quaternions. This project highlighted just a few of them.

Post a comment

Leave a Comment

Scroll to Top