A mirror lays in the center of a room.
Look inside, everything is reflected, except you.
There were a few ways I considered accomplishing this:
- Build both sides of the mirror. Mirror Actor handles mirroring effect on each actor.
- Build one side of the mirror. Mirror Actor uses a second camera to draw the same room from projected location.
- Build one side of the mirror. Mirror Actor would create a duplicate room, the mirroring effect is handled by an actor. The camera for the duplicate room would be flipped on the x axis, and projected onto the mirror location in the room.
Choosing the method of the mirroring also depends on the end function of the mirror. Does the mirror just reflect beams and projectiles that hit it? Are there differences between the mirror worlds? Can the player pass through the mirror? Ultimately I chose the first option. For its more simple implementation in Unreal Engine 4, and alignment with target gameplay.
Now to the task of mirroring actors in the scene. Example explanation using the Cube:
- Spawn a Cube on each side of the mirror.
- Add the Cubes to a list of pairs managed by the mirror actor.
- Multiply the scale of one of the mirrored Cube by
(-1,1,1)
to flip the mesh. - Make sure to track which Cube should be the leader. In Daakorun, this is chosen by most recent time the Cube was touched by the player or player effect.
- On Tick, update the follower Cube’s position and rotation in the world. Mirroring positions and rotations was very simple to accomplish on a fixed axis, however was more complicated on a mirror set at an arbitrary angle.
- On Tick, update the lead Cube’s gravity vector based on which side of the mirror it is on.
Below is an early test of the mechanic. Though not apparent, this video was taken before the mirror supported arbitrary rotations and angles that altered gravity for a single side.
I was pleased to find the FVector
::
MirrorByPlane
function to calculate the mirrored position.
To get a mirrored FRotator
, I found this documentation extremely helpful, Reflection using Quaternions.
To get a mirrored gravity vector, the above mentioned methods can be used.
The culmination of these resources can be seen below in an excerpt of the c++ code I use to calculate positions and rotations for mirrored objects in Daakorun. There may be some shortcuts to take later in optimization, but for now the code falls back on being readable.
Code: