Contributions by Alex Ling
Currently I am maintaining a 2D Unity game (check it out here if you are interested). I was trying to implement a feature that when the user gives illegal input, the whole screen would shake (or vibrate if you would) for a while.
Here’s a GIF as a demo. When the user try to multiply of divide a variable with x, the whole screen will vibrate for 0.3 seconds.
I know what you would say, what’s the big deal here? We can simply randomly move the main camera for 0.3 seconds to achieve the effect. I don’t blame you, because that’s what I thought at first glance.
I attached a
CameraShaker.csscript to the main camera. The script looks like this
And in another script I call the
Then I ran the game and tried it… Oh wait! Why isn’t the screen shaking? I quickly found that it’s because the canvas’
renderModeproperty is at its default value
Screen Space - Overlay
When this property is set as
Screen Space - Overlayor
Screen Space - Camera, the canvas is always attached to the screen (and of course the camera), and so it’s vibrating with the camera. That’s why we can’t see any vibration happen.
So the solution is simply set the
World Spacein the inspector. In this way the canvas and the camera are decoupled and so the vibration can be seen. This should work in most cases, but for me, I found that when set to
World Space, the light blue operator when dragged (see the above GIF) will not be displayed. That’s because to position the blue operator at mouse position the coupling between canvas and camera(screen) is needed.
So my final solution is, set the
renderModeof the canvas to
World Spacewhen the vibration start, and set it back to
Screen Space - Overlayonce the vibration finish. Since the vibration time is short, this should not affect the display of the light blue operator. The final version of
CameraShaker.csis shown below:
Let’s take a closer look at what I did in
Before setting the
WorldSpace, I set it to
ScreenSpaceCamerafirst. That’s because by setting it to
ScreenSpaceCamera, the canvas will be automatically positioned and scaled to fit in the camera. If I jump from
WorldSpace, the canvas will be out of the sight of the camera, and we will need to manually reposition the canvas in that case.