Code/Water/WaterController.Buoyancy.cs

Part of a WaterController component that exposes buoyancy-related properties and creates/configures a WaterVolume child component. It defines fluid density, velocity, drag, surface and wave settings, ignore tags, and a CreateWaterBuoyancy method that finds or creates a Sandbox.WaterVolume and applies these properties.

Native Interop
namespace AtmokineticAssets;

public sealed partial class WaterController : Component, Component.ExecuteInEditor
{
    
   	/// <summary>
	/// How heavy the fluid is. Higher values make things float more.
	/// Water is 1000, oil is around 900, something very heavy like mercury is 13600.
	/// </summary>
	[Property, Feature("Buoyancy"), Group( "Fluid" ), Title("Fluid Density"), Range( 0, 15000 )]
	[Sync]
	public float WaterBuoyancyFluidDensity { get; set; } = 1000.0f;

	/// <summary>
	/// Direction and speed of the water current.
	/// </summary>
	[Property, Feature("Buoyancy"), Group( "Fluid" ), Title("Fluid Velocity")]
	[Sync]
	public Vector3 WaterBuoyancyFluidVelocity { get; set; } = Vector3.Zero;

	/// <summary>
	/// How much the fluid slows down movement.
	/// </summary>
	[Property, Feature("Buoyancy"), Group( "Fluid" ), Title("Linear Drag"),Range( 0, 1 )]
	[Sync]
	public float WaterBuoyancyLinearDrag { get; set; } = 0.1f;

	/// <summary>
	/// How much the fluid slows down spinning.
	/// </summary>
	[Property, Feature("Buoyancy"), Group( "Fluid" ), Title("Angular Drag"), Range( 0, 2 )]
	[Sync]
	public float WaterBuoyancyAngularDrag { get; set; } = 0.5f;

	/// <summary>
	/// Moves the water surface up or down.
	/// </summary>
	[Property, Feature("Buoyancy"), Group( "Surface" ), Title("Surface Offset")]
	[Sync]
	public float WaterBuoyancySurfaceOffset { get; set; } = 0.0f;

	/// <summary>
	/// How tall the waves are. Set to 0 for calm water.
	/// </summary>
	[Property, Feature("Buoyancy"), Group( "Surface" ), Title("Wave Amplitude"), Range( 0, 100 )]
	[Sync]
	public float WaterBuoyancyWaveAmplitude { get; set; } = 0.1f;

	/// <summary>
	/// How fast the waves move.
	/// </summary>
	[Property, Feature("Buoyancy"), Group( "Surface" ), Title("Wave Frequency"), Range( 0, 5 )]
	[Sync]
	public float WaterBuoyancyWaveFrequency { get; set; } = 0.5f;

	/// <summary>
	/// Objects with any of these tags won't be affected.
	/// </summary>
	[Property, Feature("Buoyancy"), Group( "Filtering" ), Title("Ignore Tags")]
	[Sync]
	public TagSet WaterBuoyancyIgnoreTags { get; set; } = [];

	private WaterVolume _waterBuoyancy;

	public void CreateWaterBuoyancy()
	{
		_waterBuoyancy ??= Components.Get<Sandbox.WaterVolume>( FindMode.InSelf ) ?? Components.Create<Sandbox.WaterVolume>();
		_waterBuoyancy.Flags |= ComponentFlags.Hidden;

		_waterBuoyancy.FluidDensity = WaterBuoyancyFluidDensity;
		_waterBuoyancy.FluidVelocity = WaterBuoyancyFluidVelocity;
		_waterBuoyancy.LinearDrag = WaterBuoyancyLinearDrag;
		_waterBuoyancy.AngularDrag = WaterBuoyancyAngularDrag;
		_waterBuoyancy.SurfaceOffset = _waterZ - WorldPosition.z + WaterBuoyancySurfaceOffset;
		_waterBuoyancy.WaveAmplitude = WaterBuoyancyWaveAmplitude;
		_waterBuoyancy.WaveFrequency = WaterBuoyancyWaveFrequency;
		_waterBuoyancy.IgnoreTags = WaterBuoyancyIgnoreTags;
	}
}