The first part of our updatePlayerPhysics() function is an alignToVector() call which slowly re-orients our player back to the upright position. The parameters ( 0, 1, 0, 2, 0.05) dictate that our character will be aligned full upright along the Y-axis at a speed of 0.05, or very slowly. As the player tumbles through portals, the character's alignment gets constantly re-arranged.
Anyone who's played Portal should realize the developers' extra special attention to detail in this regard, as the player and camera are constantly being adjusted to keep the experience as intuitive as possible. In this demo, the player is slowly rotated back to the upright position, which is something to take notice of while tumbling through the puzzles in Portal.
The next part of the code is where the interesting bits lay. There is a check for portal collision. If it returns true, we will set our player collision type to static and search for the other end of our portal.
Afterwards, we reposition our player at the entrance of the opposing portal (or the exit of the portal we had previously collided with).
Then we calculate our player's total velocity and break it down into components relative to the portal we're coming out of -- by multiplying the player's total velocity by the surface normals of the exit portal.
This is what gives us the "waterslide" effect of entering in one direction and exiting at the same speed but in an entirely new direction.
The rest of the code within the first conditional helps create a smooth transition from one portal to the other. The first part sets the character's orientation with respect to its rotation upon entering the portal.
Afterward, the player is positioned out away from the exit portal an appropriate amount to avoid choppiness or repeated collision, once our player is returned to dynamic collision status.
Finally, a capture, update, and render are completed to avoid any choppiness in the visuals. Portal is especially slick in this regard, as it is virtually seamless when it teleports the player character about.
The final section of the updatePlayerPhysics() function is the flipside of the portal collision conditional. All it does is stop the player upon a static collision or otherwise pull the player down due to gravity.
The most interesting component of this is the collision normal conditional, which only stops the character from falling if they are on flat enough ground. Without that, the player can climb walls.
Portal is a landmark title. It's deceptively simple at a glance, but in truth is the implementation is a highly polished and complex system, which this article only begins to scratch the surface of. As stated above, the story was entertaining and the rendering was nothing short of pure eye candy.
However, without the mechanics Portal would not have been nearly as compelling. The title really conveys the feeling of partaking in the empirical process of groundbreaking science.
Just reading about something like this in a Michael Crichton novel or watching a sci-fi flick with great CG effects would not have had the same impact. Portal's mechanics distinguished it from other games this year, and more importantly, they distinguished games as a whole from the rest of contemporary media.
And now I'm going to grab a piece of cake from my rehearsal dinner and I'm not lying! Until next time... do not step into the... ... ... ... it may cause permanent malfunctions such as death.
[To download the associated demo and code sample for Portal Demystified, please click here.]