Support Me on Patreon

Tuesday, November 19, 2019

The Rain in the Game Falls Mainly on Nothing?!

There are many ways to do rain and other weather effects. Some games use particles, which can clip through objects. A few just add/remove objects, but the physics needed and constant object flow causes lag. In 2D it can just be a screen effect. A few use shaders or have dedicated weather systems. For newer developers, that don't have the resources or experience, rain systems can seem awkward.

Either you have particles or objects, but those either clip through objects, or cause lag. I've found another way. First, a little advice and an example. Everyone seems to think the rain needs to fall, preposterous. Take two coins, fairly new ones, and stack them between your thumb and pointer finger. Now rub the coins together, slowly getting faster. If done correctly, three coins should be visible. It's an optical illusion, the same as an after-image that some anime characters can create.

How does this help us create a rain system? By taking several rain meshes and shuffling them around the player, we can cause an illusion of rain. I'll walk you through the steps.

First, make two rain objects, a drop and a splash. We'll add them to a parent object/node as meshes with a basic water or blue texture, no colliders or transparency needed, just meshes. I like to add each to a different group or have some other way to grab them from code. Don't try to grab them directly or through paths, we're going to copy them. The scene should be a parent node with a few dozen drop/splash children.

Make a few dozen copies of the drops and splashes. Add the scene to a scene, preferably as a child of something positioned at (0,0,0). Now let's create a new scene with any positional node. Since I'm doing 3D I'll use a spatial node. This can also work in 2D with minor adjustments. Add a raycast and make sure it is casting down (-y) by about 300.  Move it up to +y 200/250, make sure it is active as well. Create copies and change their x/z to whatever you feel like. Keep them relatively close to the center, but not on the center.

About 12-32 raycasts should be good. Add a script to the top (parent) node. The scene should be a parent node with a few dozen raycast children. On ready you should get the splashes and drops from the scene tree using groups. If you've added the raycast scene to the same parent you added the drops scene to, you can just get the parent and then the drops scene's children. Either way is good.

Get the raycasts as well, you can just add the children to a variable. Get the player node/character as well. You should have two main functions, shuffle_rain and unshuffle_rain. The unshuffle_rain function should just get all the drops/splashes and place them somewhere hidden. I suggest changing their translation to (0,-200,0).

The shuffle_rain function is a bit more complex. Grab a random raycast, drop, and splash. Check that the raycast is colliding and get the collision position. Place the splash at the collision position, and the drop at a higher position. You can add a random number to the position's Y axis.  You would do this several times a frame, feel free to experiment.

The final things to do is to get the raycast parent to rotate and change it's X/Z translation to that of the player. Randomizing the Y rotation can help make the rain move more randomly. Now all you need is signals/Boolean to start/stop the rain.

No odd clipping, no lag, no physics, easily editable. It's a good rain system if you want something easy to implement.















No comments:

Post a Comment