NoclipMoveMode.cs

A MoveMode implementation named Simple Noclip for player movement. It disables gravity, sets noclip tags, provides a high-speed free-fly movement vector (with jump/duck and sprint), and resets animator parameters to idle when entering/exiting the mode.

using Sandbox.Movement;

[Title( "Simple Noclip" )]
[Category( "Movement" )]
[Icon( "flight" )]
public sealed class NoclipMoveMode : MoveMode
{
	[Property]
	public float Speed { get; set; } = 1200;

	public override int Score( PlayerController controller ) => 1000;

	public override void UpdateRigidBody( Rigidbody body )
	{
		body.Gravity = false;
		body.LinearDamping = 5.0f;
		body.AngularDamping = 1f;
		body.Tags.Set( "noclip", true );
	}

	public override void OnModeBegin()
	{
		Controller.Body.Gravity = false;
		ResetToIdle( Controller.Renderer );
	}

	public override void OnModeEnd( MoveMode next )
	{
		Controller.Body.Velocity = Controller.Body.Velocity.ClampLength( Controller.RunSpeed );
		Controller.Body.Tags.Set( "noclip", false );
		ResetToIdle( Controller.Renderer );
	}

	protected override void OnUpdateAnimatorState( SkinnedModelRenderer renderer )
	{
		ApplyIdleState( renderer );
	}

	protected override void OnUpdateAnimatorVelocity( SkinnedModelRenderer renderer )
	{
		ApplyIdleVelocity( renderer );
	}

	public override Vector3 UpdateMove( Rotation eyes, Vector3 input )
	{
		var direction = eyes * input.ClampLength( 1 );

		if ( Input.Down( "jump" ) ) direction += Vector3.Up;
		if ( Input.Down( "duck" ) ) direction += Vector3.Down;

		var speed = Speed;
		if ( Input.Keyboard.Down( "SHIFT" ) || Input.Keyboard.Down( "RSHIFT" ) )
			speed *= 2f;

		return direction * speed;
	}

	static void ResetToIdle( SkinnedModelRenderer renderer )
	{
		if ( renderer is null )
			return;

		renderer.ClearParameters();
		ApplyIdleState( renderer );
		ApplyIdleVelocity( renderer );
	}

	static void ApplyIdleState( SkinnedModelRenderer renderer )
	{
		renderer.Set( "b_grounded", true );
		renderer.Set( "duck", 0f );
		renderer.Set( "b_noclip", false );
	}

	static void ApplyIdleVelocity( SkinnedModelRenderer renderer )
	{
		renderer.Set( "move_x", 0f );
		renderer.Set( "move_y", 0f );
		renderer.Set( "move_z", 0f );
		renderer.Set( "wish_x", 0f );
		renderer.Set( "wish_y", 0f );
		renderer.Set( "wish_z", 0f );
	}
}