Map/OutOfBounds.cs
using Sandbox.UI.Player;

/// <summary>
/// Trigger volume that detects when the local player flies out of bounds.
/// Place in the scene as a large trigger box surrounding the playable area.
/// </summary>
[Title( "Out Of Bounds Trigger" ), Icon( "sports_gymnastics" )]
public sealed class OutOfBounds : Component, Component.ITriggerListener
{
	protected override void OnStart()
	{
		// Ensure a TriggerComponent exists
		if ( !Components.TryGet<BoxCollider>( out _ ) )
		{
			var col = Components.Create<BoxCollider>();
			col.IsTrigger = true;
		}
	}

	void ITriggerListener.OnTriggerEnter( Collider other )
	{
		var pawn = other.GameObject.Components.Get<PlayerPawn>( FindMode.EnabledInSelfAndDescendants );
		if ( pawn == null ) return;

		// Bots are host-driven, so kill immediately when they enter OOB.
		if ( pawn.IsBot && Networking.IsHost )
		{
			pawn.TakeDamage( 1000f, null );
			return;
		}

		if ( pawn != PlayerPawn.Local ) return;

		var ui = OutOfBoundsUI.Current;
		if ( ui == null ) return;

		ui.Open = true;
		ui.StartTimer();
	}

	void ITriggerListener.OnTriggerExit( Collider other )
	{
		var pawn = other.GameObject.Components.Get<PlayerPawn>( FindMode.EnabledInSelfAndDescendants );
		if ( pawn == null || pawn.IsBot || pawn != PlayerPawn.Local ) return;

		var ui = OutOfBoundsUI.Current;
		if ( ui == null ) return;

		ui.Open = false;
		pawn.SetOutOfBounds( false );
		ui.ResetTimer();
	}
}