top of page

Unity Portal

Introduction:

A personal project trying to build the portal mechanism of popular game Portal with Unity.

 

Engine:

Unity3D

 

Demo:

Download

 

Platform:

PC

 

Features:

Visual:
- Correct representation of portal images
- "Infinite portals" when portals are facing each other

- Animated texture of Portals

Functionality:
- Portal Gun being able to deploy portals with left and right click
- Pick up and throw objects
- Portal Alignment

- Seamless teleportation

    *Velocity, Angular Velocity, Relative Position, Relative Rotation Preservation

- Animated model for FPS Controller (Unity Chan)

Details:

When I was working on another project, I came to this idea of using a Portal as a level selection scene, where player are located in this laboratory with several portals connected to different levels.

After playing around with the render texture components in Unity for a while, I decided to take on the task of trying to recreate the Portal's mechanism in Unity.

 

My first thought is use RenderTexture and multiple cameras to recreate the visual of the portals.

RenderTexture is basically a texture where you project a camera's view on it, which is super easy to set-up in Unity.

And with it I was able to "see-through" the portals, and if the cameras' positions are updating corresponding to the player's camera's position, the visual should come out alright, which is not the case.

 

Since RenderTexture is render a camera's view on a plane, if a player is not viewing a portal from the center of the portal and without any angle, there will be a distortion and is obvious that it's a plane, which is not how a portal should look like, the portal's view should looks continuous, no matter to the player camera's position nor rotation.

The image above shows a portal with only RenderTexture setup, when viewing from narrow angle, it looks exactly like viewing a flat screen, the image is distorted and not natural.

 

In order to fix this, I have to alter the camera projection correspondingly to compensate the distortion.

And luckily, Unity allows user to change the camera's projection matrices, they even provided a pretty clear documentation on how to do it. So I was able to know which values to change without diving into all the mathematics.

The image above shows a portal with projection matrix correction, which shows a way better result with significantly less distortion and more immersive feel.

 

The next problem I face is the "Portal Inside Portal" problem.

With my current setting, the portals look fine when they are facing each other, but if they are of certain angle (e.g. 90 degree), the image does not look correct.

When you look at the projection inside a portal, the viewing angle is wrong, it looks like the camera is viewing from player's angle instead of another portal's angle. In this case, the player should not be able to see an "infinite projection", instead only 1 projection of the blue portal should be shown in the blue portal (as shown below).

In order to fix this, another portal camera and viewing plane is setup for each portal to handle the portal's camera. The detailed setup is shown on the diagram above.

 

And with that fixed, the visual part is almost done.

The only problem left is that when the player camera is extremely close up to a portal, the image will become blurry due to the way I implement the projection matrices causing the frustum angle to stretch out too much on close up. Which I still haven't found a perfect solution yet.

 

Okay, visual done (mostly), now let's move on to the functionality part.

How do we make an object "teleport" from 1 portal to another?

My first ghetto solution is when an object comes to contact with an portal, I will modify its position and rotation directly to snap it to another portal's position.

Which obvious is not ideal, if you played Portal, you will notice the transition between portals should be smooth with all the momentum preserved instead of snapping. 

But to achieve that, an object will have to exist in both portals' location when it's passing through, how do we make that happen?

My anwser? Hack it.

 

I simply make an clone of whatever object that comes to contact with a portal and update its transform corresponding to its origin. And when that object pass through the portal, I simply delete the clone and update the orign's transform to the clone's last known transform.

I also need to update the origin's physical properties like velocity, angular velocity, etc. to reflect the preservation of momentum.

 

And there you go, an imperfect (but good enough) Portal Clone in Unity.

 

Credtis:

Portal Gun Model

Portal SFX

bottom of page