Files
sbox-public/engine/Sandbox.Engine/Scene/Components/Particles/Emitter/ParticleRingEmitter.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

75 lines
2.4 KiB
C#

namespace Sandbox;
/// <summary>
/// Emits particles in a ring. The ring can be flat or have a tube-like quality.
///
/// Velocity can either be added from the center of the ring, or from the ring itself.
/// </summary>
[Title( "Ring Emitter" )]
[Category( "Particles" )]
[Icon( "check_box_outline_blank" )]
public sealed class ParticleRingEmitter : ParticleEmitter
{
[Property] public ParticleFloat Radius { get; set; } = 50.0f;
[Property] public ParticleFloat Thickness { get; set; } = 10.0f;
[Property, Range( 0, 360 )] public ParticleFloat AngleStart { get; set; } = 0.0f;
[Property, Range( 0, 360 )] public ParticleFloat Angle { get; set; } = 360.0f;
[Property, Range( 0, 1 )] public ParticleFloat Flatness { get; set; } = 0.0f;
[Property, Range( -100, 100 )] public ParticleFloat VelocityFromCenter { get; set; } = 0.0f;
[Property, Range( -100, 100 )] public ParticleFloat VelocityFromRing { get; set; } = 0.0f;
protected override void DrawGizmos()
{
//using ( Gizmo.Scope( "ring", new Transform( 0, new Angles( 90, 0, 0 ) ) ) )
//{
// Gizmo.Draw.Color = Color.White.WithAlpha( 0.2f );
// Gizmo.Draw.SolidRing( 0, Radius.Evaluate( Delta, 0 ), Radius.Evaluate( Delta, 0 ) + 1 + Thickness.Evaluate( Delta, EmitRandom ), AngleStart.Evaluate( Delta, 0 ), AngleEnd.Evaluate( Delta, 0 ), 16 );
//}
}
public override bool Emit( ParticleEffect target )
{
var angle = Random.Shared.Float( 0, Angle.Evaluate( Delta, EmitRandom ).DegreeToRadian() );
angle += AngleStart.Evaluate( Delta, EmitRandom ).DegreeToRadian();
var x = MathF.Sin( angle );
var y = MathF.Cos( angle );
var size = new Vector3( x, y, 0 ) * Radius.Evaluate( Delta, EmitRandom );
var ringOffset = Vector3.Zero;
var thickness = Thickness.Evaluate( Delta, EmitRandom );
if ( thickness > 0 )
{
ringOffset = Vector3.Random * thickness;
ringOffset.z *= (1 - Flatness.Evaluate( Delta, EmitRandom ));
size += ringOffset;
}
size = (size * WorldScale) * WorldRotation;
var p = target.Emit( WorldPosition + size, Delta );
if ( p is not null )
{
var velFromCenter = VelocityFromCenter.Evaluate( Delta, EmitRandom );
if ( velFromCenter != 0 )
{
p.Velocity += (size.Normal * velFromCenter);
}
var velFromRing = VelocityFromRing.Evaluate( Delta, EmitRandom );
if ( velFromRing != 0 )
{
ringOffset = (ringOffset * WorldScale) * WorldRotation;
p.Velocity += (ringOffset.Normal * velFromRing);
}
}
return true;
}
}