FreeCam/FreeCamGameObjectSystem.cs
using Sandbox.Utility;
using static Sandbox.Component;

internal sealed class FreeCamGameObjectSystem : GameObjectSystem<FreeCamGameObjectSystem>, ISceneStage
{
	public bool IsActive { get; set; }

	Vector3 position;
	Vector3 smoothPosition;

	Angles angles;
	Angles smoothAngles;

	float fov = 80;
	float smoothFov = 80;

	GameObject _ui;

	public FreeCamGameObjectSystem( Scene scene ) : base( scene )
	{
	}

	void ISceneStage.Start()
	{
		if ( !IsActive )
			return;

		Input.Suppressed = true;
	}

	void StartFreeCamMode()
	{
		if ( !_ui.IsValid() )
		{
			_ui = new GameObject( true, "freecam_overlay" );
			_ui.Flags = GameObjectFlags.NotSaved | GameObjectFlags.NotNetworked;
			var fc = _ui.AddComponent<FreeCamOverlay>();
			var sp = _ui.AddComponent<ScreenPanel>();
		}

		if ( _ui.IsValid() )
		{
			_ui.Enabled = true;
		}

		smoothPosition = Scene.Camera.WorldPosition;
		position = smoothPosition + Scene.Camera.WorldRotation.Backward * 50;
		angles = smoothAngles = Scene.Camera.WorldRotation;
		smoothFov = fov = Scene.Camera.FieldOfView;

		Scene.Camera.RenderExcludeTags.Add( "firstperson" );
		Scene.Camera.RenderExcludeTags.Add( "ui" );
	}

	void EndFreeCamMode()
	{
		if ( _ui.IsValid() )
		{
			_ui.Enabled = false;
		}

		Scene.TimeScale = 1;
		Scene.Camera.RenderExcludeTags.Remove( "firstperson" );
		Scene.Camera.RenderExcludeTags.Remove( "ui" );
	}

	void ISceneStage.End()
	{
		if ( IsActive )
		{
			Input.Suppressed = false;
		}

		if ( Input.Keyboard.Pressed( "J" ) )
		{
			IsActive = !IsActive;

			if ( IsActive )
			{
				StartFreeCamMode();
			}
			else
			{
				EndFreeCamMode();
			}
		}

		if ( !IsActive )
			return;

		if ( _ui.IsValid() )
		{
			var fc = _ui.GetOrAddComponent<FreeCamOverlay>();
			fc.Update( Input.Down( "score" ) );

			UpdateCameraPosition( fc );
		}
	}

	void UpdateCameraPosition( FreeCamOverlay overlay )
	{
		var speed = 50;
		if ( Input.Down( "duck" ) ) speed = 5;
		if ( Input.Down( "run" ) ) speed = 300;

		if ( Input.Down( "attack2" ) )
		{
			fov += Input.MouseDelta.y * 0.1f;
			fov = fov.Clamp( 1, 120 );
		}
		else
		{
			angles += Input.AnalogLook * fov.Remap( 1, 100, 0.1f, 1 );
		}

		var velocity = angles.ToRotation() * Input.AnalogMove * speed;
		position += velocity * RealTime.SmoothDelta;

		smoothPosition = smoothPosition.LerpTo( position, MathF.Pow( RealTime.SmoothDelta * 16.0f, overlay.CameraSmoothing * 2.0f ) );
		Scene.Camera.WorldPosition = smoothPosition;

		smoothAngles = smoothAngles.LerpTo( angles, MathF.Pow( RealTime.SmoothDelta * 16.0f, overlay.CameraSmoothing * 2.0f ) );
		Scene.Camera.WorldRotation = smoothAngles + new Angles( Noise.Fbm( 2, Time.Now * 40, 1 ) * 2, Noise.Fbm( 2, Time.Now * 30, 60 ) * 2, 0 );

		smoothFov = smoothFov.LerpTo( fov, RealTime.SmoothDelta * 20.0f );
		Scene.Camera.FieldOfView = smoothFov;

		Scene.Camera.RenderExcludeTags.Remove( "viewer" );
	}
}