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 );
}
}