Hi!
PuddlesTo create nice puddles we gonna use shaders. And fake cameras.

Red surface is our future puddle.
Let's provide to the puddle some information about what it should "reflect".
C# script creates invisible camera for plane reflective object which looks in the oppozite by z axis direction of main camera.
Fake camera renders that inverted image to RenderTexture and shares it with custom shader.

Show all layers
You can notice that there is no fog in reflected image. Rendering fog twice is untrivial task and it will costs us a lot of milliseconds.
So, let's add an emission to puddle. Let it a bit lighter.

Now we will show the closest objects to puddle only.
Just mark close object with custom layer and set Close Objects and Player layer to culling mask for other fake camera.

We removed the hill and useless objects, but now our reflection looks a bit shitty because of white borders around all objects. Let's just ignore that for a while

The puddle looks unrealistically flat, so we're going to add a ripple. I get a texture with blue noise and include it to reflection projection in shader.

fixed4 tex = tex2D(_BlueNoiseTex, i.uv);
fixed4 refl = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(i.refl + tex.x + tex.y));

Looks better.
Now we found out that the puddle border is too sharp. Let's paint some gradient texture like this:

Use it in our shader and reduce a brightness:
fixed4 tex = tex2D(_BlueNoiseTex, i.uv);
fixed4 refl = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(i.refl + tex.x + tex.y));
fixed4 gradient = tex2D(_GradientTex, i.uv);
fixed4 result = refl * _Brightness + _Emissive;
result.a = gradient.g;

Finally, let's make the ripple more active.
fixed4 tex = tex2D(_BlueNoiseTex, i.uv + _Time.x / 5);

Thank you!