====== Water Sampler ======
You can sample water to obtain exact wave height at given position in two ways:
* Using ''DragonWaterManager.Instance.SampleWater()'' function, or
* Via **WaterSampler** object.
In fact, first option is just exposed simplified version of WaterSampler usage and use it only occasionally for single, synchronous checks.
\\ Using WaterSampler manually is preferable solution, as it not only offers way more configurable options, but also asynchronous operation (via Job System) to provide best possible performance.
{{page>scripting-api#WaterSampler}}
===== Usage =====
==== Basic ====
With default ''SurfaceDetection'' set to ''Default'', sampler will tests only against water surface that has been set as default.
\\ If there is no default surface active, then it will fallback to ''AutoCull'' and will automatically detect nearby surfaces and tests against them all.
\\ **''AutoCull'' is medium-heavy operation, so if you need to check only against specific surface that is not default, set it to ''Custom'' and manually provide list of surfaces you want to check.**
With default ''CutoutDetection'' set to ''AutoCull'', sampler will scan for all nearby cutout volumes and check if given points are inside them or outside. Then, accordingly to the results, will properly respect cutout usage by each surface.
\\ **''AutoCull'' is heavy operation. If you do not need to test it (e.g. you know that your points will never be inside volumes or you simply don't need it) - turn it off by setting it to ''DontCutout''.**
\\ **You can also set it to ''Custom'' and manually provide list of cutouts you want to test against, what will also significantly improve performance comparing to ''AutoCull''.**
Default ''Precision'' is set to ''Constants.DefaultSamplerPrecision = 4'' and in most cases it's more than enough.
var sampler = new WaterSampler(1); // size of 1
sampler.SetPoint(0, Vector3.zero); // set first (the only one) point
sampler.Schedule(1); // schedule with this single point
// now, for best asyncrhonous performance
// you should wait for next frame and Complete() it then
sampler.Complete(); // always call Complete even if you've waited for N frames already
var result = sampler.Results[0];
sampler.Dispose(); // ALWAYS remember to to Dispose no longer needed sampler
==== Custom Detection Mode ====
This example shows how to use ''Custom'' modes.
var sampler = new WaterSampler();
sampler.SurfaceDetection = WaterSampler.SurfaceDetectionMode.Custom;
sampler.SurfaceDetectionCustom = new() { yourSurface1 };
sampler.CutoutDetection = WaterSampler.CutoutDetectionMode.Custom;
sampler.CutoutDetectionCustom = new() { cutout1, cutout2 };
//
//
//
sampler.Dispose();
==== Auto Cull Caching ====
As mentioned above, ''AutoCull'' modes are heavy. However, you can significantly improve performance by using built-in caching feature.
\\ After you set up your points, call ''CacheAutoCull()'', so sampler will temporarily act like with ''Custom'' modes and won't cull nearby surfaces and cutouts.
\\ If you constantly use sampler every frame with auto culling, you can re-cache auto cull like once (or few times) per second to have quite up-to-date results while maintaning good performance.
var sampler = new WaterSampler();
//
sampler.CacheAutoCull();
// now, all Schedule operation will be very perfomrant because
// sampler will no longer AutoCull surfaces and cutouts and used cached once instead
// so it acts like temporal Custom mode
sampler.ClearAutoCullCache(); // now it will come back to auto cull every next Schedule
// <...>
sampler.Dispose();
==== Bounding Box ====
If any of your modes is set to ''AutoCull'', sampler will need bounding box that covers all of your points for culling.
\\ By default sampler calculates it automatically which is pretty cheap operation for just a few points.
\\ However, this may become expensive for like hundreds of points. In this scenario, you will most likely want to assign ''CullingBox'' property manually.
\\ This property is a bounding box that must contains all of given points (it doesn't need to be exact, approximation is enough).
Also, try not to create sampler that covers your entire large world. Sampler is more effective for large amount of points, but these points should belong to relatively small, logically separated area (e.g. area of ship).