This game is an FPS(First-player-shooting) game, with a special setting that player can rotate the whole world in order to reach certain places, elude traps or kill particular enemies and achieve ultimate goal. Player aims to pass the level and eliminate enemies in the scene by their gun. At the same time, player should prevent to trigger environment traps or fall to deaths by world rotation.
I was responsible to design the level and the game mechanism. I implemented all functions in this game.
The FPS mechnism(User Interface, shoot, spawn enemies, enemies AI) were simple compare to the core mechanism.
The post processing effect and baked light makes the prototype world look much better.
The core mechanism that rotated the whole world confused my time but I finally made it. The rotation function in Quaternion confused me so I did a research about Quaternion.
Quaternion is represented by four numbers, whose values have a range from [-1 , 1]. The Quaternion.Identity representing no rotation is (0,0,0,1).
Although nearly nobody will convert directly from angle-axis, or Euler angle from Quaternion, there is a fomula to do it:
From Angle-Axis to Quaternion
(Given a normalized (length 1) axis representation (x, y, z) and an angle A. )
Q = [sin(A/2)*x, sin(A/2)*y, sin(A/2)*z, cos(A/2)] (corresponding to [x, y, z, w])
From Euler angle to Quaternion
(Given an Euler rotation (X, Y, Z) [using orthogonal axes])
x = sin(Y)sin(Z)cos(X)+cos(Y)cos(Z)sin(X);
y = sin(Y)cos(Z)cos(X)+cos(Y)sin(Z)sin(X);
z = cos(Y)sin(Z)cos(X)-sin(Y)cos(Z)sin(X);
w = cos(Y)cos(Z)cos(X)-sin(Y)sin(Z)sin(X);
Q = [x, y, z, w]
I tried to understand the maths inside it, and read some article, but it was too hard to totally comprehend it.
Euler to Quaternion,
Quaternion to Euler
My implementation of world rotation
To make it simple, Unity API has a lot of convinent function to help calcualte Quaternion. Some of them are calculating Quaternion, and others are doing rotation. What I did in this project is using Quaternion.AngleAxis(degree, direction), and Rotate(direction * speed, Space).
In Update(), if it is rotating, rotate to the direction that players want to go.
Calculate the Destination quaternion and start a new rotation. The desQuat is only for detecting when to stop rotation, the actual rotation happens in transform.Rotate().
dirForPlayer is setting player’s up direction according to the world rotation.