top of page

Perspective Manipulation

Something I've always wanted to learn how to program and implement into my games are the mechanics that exist to mess with the player's sense of reality. So often we try to make our games as realistic as possible with the physics and the way the world behaves, but something I've always found fascinating is that because our games exist entirely within code, there's no reason they have to conform to or obey the laws of the real world. I love games that have mechanics that truly break our sense of reality, but do so in a way that feels fluid and well worked into the game world. In this project, I wanted to recreate a mechanic from the game Superliminal, which implements this sort of reality-breaking gameplay to create a mind-bending and fascinating puzzle game.

How I Did It

The core mechanic I sought to recreate was that of perspective manipulation. In Superliminal, when you pick up an item and move it around, it appears to the player to stay the same size. However, in the game, it is actually smoothly getting larger or smaller, while getting as far away from the player as possible. It does this in such a way that while the size changes drastically while being held, the player doesn't notice. This use of perspective and size is a core mechanic of the gameplay and puzzle-solving, and I wanted to know how it was done.

I started, naturally, with some research. I found some blogs and articles that explained the basic process behind the original mechanic, and I got to work. To start, I needed to find a way to find the player's perspective while holding an object, to find out how far back I could push the object. Then I would simply need to scale it with respect to the distance it moved. I started by using Unity's raycasting system. I sent a raycast from the camera to each of the vertices of the object as it was being held. Using these, I could find the point that I would need to move the cube to.

Raycast.png
VertexCode.JPG
Raycasts.JPG

Shown above is how I used raycast to outline the object being held from the player's perspective. I then find the raycast that has the shortest distance between the vertex and the wall, shown with the red line. I select this point as the point of reference for the transformation that the cube will need to undergo. The next step is to use some fairly simple 3D math to move the cube into position and then scale it accurately.

Translated.png
Math.JPG

Now that I have the object in position, all that's left to do is scale it up. Above is a clipping of my code that shows the full simple calculation. I start by getting the offset from the vertex I'm using to the center of the object. This is important because Unity calculates positions from the center of an object, so once I move it into place, I'll have to add the offset back so it's properly placed. Next, I calculate my scale factor. I do this by getting the current distance from the camera to the cube, and dividing it by the initial distance when the cube was first picked up. I multiply the initial scale by that factor, add the offset back, and then it's done.

small.png
large.png

The code doesn't work perfectly. It works best with a simple cube in a simple room, without many obstacles. Had I given myself more time on this project, I think I could have solved the bugs that it has, but I was successful in getting the base mechanic to work.

Conclusion

This project was a rough one for me. I prioritized other things for school and for my free time, and I falsely assumed I'd have enough time to fully implement this mechanic in the way that I wanted. I had a lot of trouble with Unity's built-in systems, and it took me longer than I had thought to find my way around some rather silly mistakes I had made early on in the development. Overall, I think I am happy with what I made, as it allowed me to gain some insight behind the scenes into the mechanics I enjoy in games. It also allowed me to refresh myself with some math skills that I haven't used in a while, and put them to good use. 

bottom of page