15 / 18
Packages/2D Water Reflection Pro/Runtime C# examples
DEVELOPER REFERENCE
15 / 18

Runtime C# examples

Four complete scripts for setup, effects, selection and lifecycle events.

English guideSource: Unity 6000.3.13f1 · URP 17.3.011 October 2026

Four complete scripts from the supplied guide. Save each file with its matching class name and assign explicit scene references in the Inspector.

1. Connect your gameplay script#

Save as GuideWaterControls.cs. Attach it to an empty GameObject, assign a Reflection Surface, Source Camera and optional preset. Keep one active WaterReflectionManager. Your custom asmdef needs an ERAGANX.WaterReflection2D reference.

C#
using UnityEngine;
using ERAGANX.WaterReflection2D;
public sealed class GuideWaterControls : MonoBehaviour
{
    [SerializeField] WaterReflectionSurface water = null;
    [SerializeField] Camera sourceCamera = null;
    [SerializeField] ReflectionPreset calmPreset = null;
    void Start()
    {
        if (!water || !sourceCamera) return;
        water.SetSourceCamera(sourceCamera);
        water.SetSurfaceSize(new Vector2(10f, 3f));
        water.Settings.Capture.Region =
            new Rect(-5f, 0f, 10f, 3f);
        water.NotifySettingsChanged();
        if (calmPreset)
            water.ApplyReflectionPreset(calmPreset);
        water.SetReflectionEnabled(true);
    }
    public void UseLowQuality()
    {
        if (water)
            water.SetReflectionQuality(ReflectionQuality.Low);
    }
    public void Refresh()
    {
        if (water) water.RefreshCachedReflection();
    }
}

Download GuideWaterControls.cs

Public Button methods can connect to UI events or gameplay components. No API key or network service is required. Keep a reference to the particular surface rather than finding/creating a manager every frame.

2. Change visual effects#

Save as GuideWaterEffects.cs and assign the surface. Effect setters sanitize values and enable Visual Effects where required. Strength/Opacity alone do not force optional effects on. These methods change displayed reflection appearance, rather than source scene geometry or water physics.

C#
using UnityEngine;
using ERAGANX.WaterReflection2D;
public sealed class GuideWaterEffects : MonoBehaviour
{
    [SerializeField] WaterReflectionSurface water = null;
    public void UseGentleWater()
    {
        if (!water) return;
        water.SetReflectionMode(ReflectionMode.Planar);
        water.SetReflectionStrength(1f);
        water.SetReflectionOpacity(0.85f);
        water.SetWaves(true, 0.025f, 0.55f, 10f,
                       Vector2.right);
        water.SetSecondaryWave(true, 0.01f, 0.3f, 5f,
                               Vector2.up);
        water.SetRipples(false, 0.01f, 12f, 1f, 1f);
        water.SetReflectionTint(
            new Color(0.65f, 0.85f, 1f, 1f), 0.18f);
        water.SetReflectionBrightness(1f);
        water.SetReflectionSaturation(1f);
        water.SetReflectionFade(true, false,
                                0.15f, 1f, 0.65f);
        water.SetReflectionBlur(false, 1f);
    }
    public void UseCleanMirror()
    {
        if (!water) return;
        water.SetReflectionMode(ReflectionMode.Mirror);
        water.SetMirrorOrientation(
            ReflectionMirrorOrientation.Vertical);
        water.SetReflectionStrength(1f);
        water.SetReflectionOpacity(1f);
        water.SetVisualEffectsEnabled(false);
    }
}

Download GuideWaterEffects.cs

SetWaves takes amplitude, speed, frequency, then direction. SetRipples takes amplitude, frequency, speed, then scale. Check their different argument order.

3. Filter content and set a shape#

Save as GuideWaterSelection.cs. Assign masks in your script Inspector rather than hardcoding demo layer numbers. Object-layer masks and sorting-layer IDs are different. Direct capture/optimization edits need NotifySettingsChanged() after the batch.

C#
using UnityEngine;
using ERAGANX.WaterReflection2D;
public sealed class GuideWaterSelection : MonoBehaviour
{
    [SerializeField] WaterReflectionSurface water = null;
    [SerializeField] LayerMask included = 0;
    [SerializeField] LayerMask excluded = 0;
    [SerializeField] LayerMask movingActors = 0;
    [SerializeField] Sprite puddleShape = null;
    [SerializeField] Renderer[] selectedRenderers = null;
    public void UseHybridLayers()
    {
        if (!water) return;
        var settings = water.Settings;
        settings.Capture.IncludedLayers = included;
        settings.Capture.ExcludedLayers = excluded;
        settings.Capture.ObjectFilter =
            ReflectionObjectFilter.Layers;
        settings.Optimization.DynamicLayers = movingActors;
        water.SetReflectionMode(ReflectionMode.Hybrid);
        water.NotifySettingsChanged();
        water.SetSurfaceShape(puddleShape, 0.001f);
        water.RefreshCachedReflection();
    }
    public void UseSelectedSprites()
    {
        if (!water) return;
        water.Settings.Capture.ObjectFilter =
            ReflectionObjectFilter.IncludeSelected;
        water.Settings.Capture.SelectedRenderers =
            selectedRenderers;
        water.SetReflectionMode(ReflectionMode.LightweightSprite);
        water.NotifySettingsChanged();
    }
}

Download GuideWaterSelection.cs

The Hybrid static and dynamic effective groups must both be nonempty. Exact Renderer selection remains subject to layer/sorting filters, and Lightweight needs compatible source sprites. SetSurfaceShape(null) restores a rectangle; assigning a mask does not automatically match its aspect ratio.

4. Events and cache refresh#

Save as GuideWaterEvents.cs. Pair event subscriptions/unsubscriptions and refresh static captures when scenery or lights change.

C#
using UnityEngine;
using ERAGANX.WaterReflection2D;
public sealed class GuideWaterEvents : MonoBehaviour
{
    [SerializeField] WaterReflectionSurface water = null;
    void OnEnable()
    {
        if (!water) return;
        water.DiagnosticChanged += OnDiagnostic;
        water.ReflectionUpdated += OnReflectionUpdated;
    }
    void OnDisable()
    {
        if (!water) return;
        water.DiagnosticChanged -= OnDiagnostic;
        water.ReflectionUpdated -= OnReflectionUpdated;
    }
    void OnDiagnostic(ReflectionDiagnostic info)
    {
        Debug.Log(info.Status + ": " + info.Message, this);
    }
    void OnReflectionUpdated(WaterReflectionSurface source)
    {
        // Optional UI/status work. Do not start nested renders.
    }
    public void StaticSceneryChanged()
    {
        if (water) water.RefreshCachedReflection();
    }
}

Download GuideWaterEvents.cs

Direct changeRequired action
Capture/quality settingsBatch changes, then NotifySettingsChanged(); structural changes invalidate capture resources/state as needed.
Effects onlyChange Settings.Effects, then NotifyVisualEffectsChanged() to sanitize display settings without refreshing stored scene content.
ShapeUse SetSurfaceShape. Existing capture can be reused; resize separately with SetSurfaceSize for a new aspect.

ReflectionUpdated reports a completed displayed capture update, not proof of a correct image. Avoid mutating renderers/lights or starting unrelated nested render calls inside capture callbacks. These scripts are copied from the supplied guide; no new runtime/device test is claimed by this website.

Adapted from the supplied guide · PDF pages 34–37.View source guide ↗
Keep creating.ERAGAN STUDIO.

Search a topic, setting or method across all package guides.