I wanted to make note on how to do this because I purchased specializes VFX for the canvas which wasn’t needed at all after learning this little trick.

To have any Particle or sprite-based VFX show on your GUI Canvas in Unity you can simply create a special camera to do it. I though that having an extra camera was complicated, a waste of time, and would lead to more work to get things to look right in the long run…nope!

Here are the steps to getting this working..

  1. Create a new [Camera] and name it so you know what it’s doing, “Camera_UI_”.
  2. Change the cameras “Clear Flags” to “Depth Only”.
  3. Remove all layers except the “UI” layer from the “Culling Mask” are on the new camera you just made.
  4. Set the Cameras “Depth” to “100”.
  5. Remove all ‘Non-Camera’ components from the new camera. For example “flares’ and ‘audio listeners’.
  6. On the main Canvas, change the “Render Mode” to “Screen Space – Camera”.
  7. Assign the new “Camera_UI” camera to the “Render Camera” area of the Canvas.
  8. Remove the “UI” layer from the “Culling Mask” of the Main Camera.
  9. Finally, on any VFX you need to change the “Layer” to “UI”, so you may want to create a special prefab, so that it doesn’t mess with any of the VFX being used in 3D Space normally.
Example of Camera_UI
Main Canvas Example
VFX for UI Example

UPDATE: If you are finding that the effects are being clicked by the UI you can make a third camera for just the effects and Set it’s depth to 100 and then depth of the UI camera to 99. Now all of the VFX need to be put on the Effects Layer (Yes you need to create yet another layer, but the result is amazing and worth the effort.)

This has been used for an in-game notification icon that blinks when a new notification is available.

A Scene bool variable called “NewNotification” triggers this code to be run. During the code block we need to wait for the fading and unfading to complete before the “OnUpdate” tells the block of code to run again. If it tries to start it again before it’s done the blinking cycle, it makes the blink fail. To support this we have a Graph based bool variable called “Blinker”

If Blinker is true our block of code know that the blink hasn’t finished yet and waits until the bool is False again, meaning that it can initiate another blink.

Note: This code block must be set as a co-routine as we use Wait Timers.