This camera was developped for the game I made at my school to obtain my diploma, Wasabi.
The idea came from two games, PikuNiku and the Lego series, both have this kind of camera in their coop mode.
I first looked for some articles and documentation for that kind of system and found two of them.
One made by Matt Woelk on Unreal Engine.
And the other made by Marek Kost, this time on Unity.
One made by Matt Woelk on Unreal Engine.
And the other made by Marek Kost, this time on Unity.
Both of the systems I found were using a shader with voronoi but I don't know how to make a proper shader.
So, I picked some of their ideas and made my own system, without using any shader.
So, I picked some of their ideas and made my own system, without using any shader.
How it works
For my system to work, it needs a minimum of 2 Cameras, a Render Texture linked to one of those Cameras, two different targets, as well as a UI with a RawImage and a Mask as the parent.
It works as the following :
It works as the following :
- You configure the Mask in a way that the pivot point is at the center of the screen and it can cover every pixel of the screen. It can be way over the screen to avoid any problems.
- Then you set the Render Texture in the RawImage, and you make it so it takes the whole screen.
- After that you need to rotate the Mask accordingly to the angle between the two targets
- At the same time you need to rotate in the inverse direction the RawImage, because it is a child of the Mask you're rotating.
- And finally you have to place correctly the two Cameras in a way that they have an offset in the correct direction.
There are more things to consider, such as the merge moment when the targets are close enough, or the position of the Camera when there should be only one, or even the optimization needed.
Calculs
- First of all, you need to check if the distance between the targets isn't below the max distance parameter.
- If so, you need to merge back the cameras and disable the split.
- Then you can get the angle of the targets using their direction and the Mathf.Atan2() method mutliplied by Mathf.Rad2Deg.
- From that angle you can set the Mask and RawImage properly, but you will need to place the Cameras now.
- For that, you have to calculate the offset needed from the direction and add that to each camera target position.
- Then simply use a method to place your camera to that position.
- If so, you need to merge back the cameras and disable the split.
- Then you can get the angle of the targets using their direction and the Mathf.Atan2() method mutliplied by Mathf.Rad2Deg.
- From that angle you can set the Mask and RawImage properly, but you will need to place the Cameras now.
- For that, you have to calculate the offset needed from the direction and add that to each camera target position.
- Then simply use a method to place your camera to that position.
I had an issue with the resolution of the screen and the RenderTexture.
I didn't take in consideration the different format and sizes of the screens and there was a lot of distortion.
I didn't take in consideration the different format and sizes of the screens and there was a lot of distortion.
So I had to think and make something to correct that.
It actually simply clears the RenderTexture then recreates it with the correct width and height, then it is updated on the UI and finally the Cameras are set to their positions.
You should note that Unity doesn't have anything to detect the screen size or resolution changing, so I call that method at the start of the game, but it could be called anytime from a button for exemple.