terminalCode Example
Decal component — projecting bullet holes, scorch marks, and surface details
Decal Component — Projecting Surface Marks
Decal projects a texture onto surfaces in the world. Use it for bullet holes, blood splats, scorch marks, graffiti, and any surface detail that needs to conform to geometry.Basic Decal Placement
CSHARP
public sealed class BulletImpact : Component
{
[Property] public DecalDefinition ImpactDecal { get; set; }
public void PlaceAt( Vector3 position, Vector3 normal )
{
var go = Scene.CreateObject();
go.WorldPosition = position;
// Face the decal along the surface normal
go.WorldRotation = Rotation.LookAt( -normal, Vector3.Up );
var decal = go.Components.Create<Decal>();
decal.DecalDefinition = ImpactDecal;
decal.Width = 8f;
decal.Height = 8f;
decal.Depth = 16f; // projection depth into the surface
// Auto-remove after 30 seconds
go.DestroyAsync( 30f );
}
}DecalDefinition Asset
Create a DecalDefinition asset (Asset Browser → New Asset → Decal Definition) to define the material, size, and randomization:
- Set Rotation to a range (e.g. 0–360) for random orientation on spawn
- Define multiple definitions on one Decal component for random variety
- Set Lifetime on the definition for automatic fade-out
Transient Decals
Mark a decal as transient so it's automatically removed when the scene's decal limit is exceeded (oldest removed first):
CSHARP
decal.Transient = true;Tracing to Find Placement
Typical usage — trace a ray and place a decal at the hit point:
CSHARP
var tr = Scene.Trace
.Ray( WorldPosition, WorldPosition + WorldRotation.Forward * 1000f )
.WithoutTags( "player" )
.Run();
if ( tr.Hit )
{
var go = Scene.CreateObject();
go.WorldPosition = tr.HitPosition + tr.Normal * 0.5f; // slight offset
go.WorldRotation = Rotation.LookAt( -tr.Normal );
var decal = go.Components.Create<Decal>();
decal.DecalDefinition = BulletHoleDecal;
decal.Transient = true;
}
Was this helpful?