Player/Player.Control.cs

Player movement component. Defines movement settings (speed, jump height, ground friction), computes desired velocity from input and camera, applies acceleration, friction, gravity, and handles jumping when on ground.

Native Interop
using Sandbox;

namespace SnowSandbox;

public sealed partial class Player : Component
{
	[Property, Feature( "Control", Icon = "keyboard" )]
	public float Speed { get; set; } = 100f;

	[Property, Feature( "Control" )]
	public float JumpHeight { get; set; } = 25f;

	[Property, Range(0, 10), Feature( "Control" )]
	public float GroundFriction { get; set; } = 4f;

	public bool OnGround => Controller.IsOnGround;

	Vector3 WishVelocity;

	private void BuildWishVelocity()
	{
		WishVelocity = Input.AnalogMove * Camera.WorldRotation.Angles().WithPitch( 0 );

		WishVelocity = WishVelocity.WithZ( 0 ).Normal * Speed;
	}

	private void MoveBody()
	{
		BuildWishVelocity();

		if ( OnGround )
		{
			Controller.Velocity = Controller.Velocity.WithZ( 0 );
			Controller.Accelerate( WishVelocity );
			Controller.ApplyFriction( GroundFriction );

			UpdateJump();
		}
		else
		{
			Controller.Accelerate( WishVelocity.ClampLength( 4f ) );
		}

		if ( !OnGround )
		{
			Controller.Velocity += Scene.PhysicsWorld.Gravity * Time.Delta;
		}

		Controller.Move();
	}

	private void UpdateJump()
	{
		if ( Input.Pressed( "Jump" ) )
			Controller.Punch( Vector3.Up * JumpHeight );
	}
}