mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-01-02 19:38:24 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
191 lines
4.8 KiB
C#
191 lines
4.8 KiB
C#
|
|
namespace Sandbox.Movement;
|
|
|
|
/// <summary>
|
|
/// A move mode for this character
|
|
/// </summary>
|
|
public abstract partial class MoveMode : Component
|
|
{
|
|
public virtual bool AllowGrounding => false;
|
|
public virtual bool AllowFalling => false;
|
|
|
|
[RequireComponent]
|
|
public PlayerController Controller { get; set; }
|
|
|
|
/// <summary>
|
|
/// Highest number becomes the new control mode
|
|
/// </summary>
|
|
public virtual int Score( PlayerController controller ) => 0;
|
|
|
|
/// <summary>
|
|
/// Called before the physics step is run
|
|
/// </summary>
|
|
public virtual void PrePhysicsStep()
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called after the physics step is run
|
|
/// </summary>
|
|
public virtual void PostPhysicsStep()
|
|
{
|
|
|
|
}
|
|
|
|
public virtual void UpdateRigidBody( Rigidbody body )
|
|
{
|
|
bool wantsGravity = false;
|
|
|
|
// If we're standing still on a peice of ground, turn off gravity until
|
|
// we move again. This stops us slowly slipping down surfaces.
|
|
if ( !Controller.IsOnGround ) wantsGravity = true;
|
|
if ( Controller.Velocity.Length > 1 ) wantsGravity = true;
|
|
if ( Controller.GroundVelocity.Length > 1 ) wantsGravity = true;
|
|
if ( Controller.GroundIsDynamic ) wantsGravity = true;
|
|
|
|
body.Gravity = wantsGravity;
|
|
|
|
// when we're standing on the still ground and aren't wishing to move we apply a high linear damping to the body
|
|
// this stops whatever momentum it had from dragging it slowly down hills.
|
|
bool wantsbrakes = Controller.IsOnGround && Controller.WishVelocity.Length < 1 && Controller.GroundVelocity.Length < 1;
|
|
body.LinearDamping = wantsbrakes ? (10.0f * Controller.BrakePower) : Controller.AirFriction;
|
|
|
|
body.AngularDamping = 1f;
|
|
}
|
|
|
|
public virtual void AddVelocity()
|
|
{
|
|
var body = Controller.Body;
|
|
var wish = Controller.WishVelocity;
|
|
if ( wish.IsNearZeroLength ) return;
|
|
|
|
var groundFriction = 0.25f + Controller.GroundFriction * 10;
|
|
var groundVelocity = Controller.GroundVelocity;
|
|
|
|
var z = body.Velocity.z;
|
|
|
|
var velocity = (body.Velocity - Controller.GroundVelocity);
|
|
var speed = velocity.Length;
|
|
|
|
var maxSpeed = MathF.Max( wish.Length, speed );
|
|
|
|
if ( Controller.IsOnGround )
|
|
{
|
|
var amount = 1 * groundFriction;
|
|
velocity = velocity.AddClamped( wish * amount, wish.Length * amount );
|
|
}
|
|
else
|
|
{
|
|
var amount = 0.05f;
|
|
velocity = velocity.AddClamped( wish * amount, wish.Length );
|
|
}
|
|
|
|
if ( velocity.Length > maxSpeed )
|
|
velocity = velocity.Normal * maxSpeed;
|
|
|
|
velocity += groundVelocity;
|
|
|
|
if ( Controller.IsOnGround )
|
|
{
|
|
velocity.z = z;
|
|
}
|
|
|
|
body.Velocity = velocity;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This mode has just started
|
|
/// </summary>
|
|
public virtual void OnModeBegin()
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// This mode has stopped. We're swapping to another move mode.
|
|
/// </summary>
|
|
public virtual void OnModeEnd( MoveMode next )
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// If we're approaching a step, step up if possible
|
|
/// </summary>
|
|
protected void TrySteppingUp( float maxDistance )
|
|
{
|
|
Controller.TryStep( maxDistance );
|
|
}
|
|
|
|
/// <summary>
|
|
/// If we're on the ground, make sure we stay there by falling to the ground
|
|
/// </summary>
|
|
protected void StickToGround( float maxDistance )
|
|
{
|
|
Controller.Reground( maxDistance );
|
|
}
|
|
|
|
public virtual bool IsStandableSurace( in SceneTraceResult result )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public virtual bool IsStandableSurface( in SceneTraceResult result )
|
|
{
|
|
return IsStandableSurace( result );
|
|
}
|
|
|
|
Vector3.SmoothDamped smoothedMovement;
|
|
|
|
/// <summary>
|
|
/// Read inputs, return WishVelocity
|
|
/// </summary>
|
|
public virtual Vector3 UpdateMove( Rotation eyes, Vector3 input )
|
|
{
|
|
// don't normalize, because analog input might want to go slow
|
|
input = input.ClampLength( 1 );
|
|
|
|
var direction = eyes * input;
|
|
|
|
// Run if we're holding down alt move button
|
|
bool run = Input.Down( Controller.AltMoveButton );
|
|
|
|
// if Run is default, flip that logic
|
|
if ( Controller.RunByDefault ) run = !run;
|
|
|
|
// if we're running, use run speed, if not use walk speed
|
|
var velocity = run ? Controller.RunSpeed : Controller.WalkSpeed;
|
|
|
|
// if we're ducking, always use duck walk speed
|
|
if ( Controller.IsDucking ) velocity = Controller.DuckedSpeed;
|
|
|
|
if ( direction.IsNearlyZero( 0.1f ) )
|
|
{
|
|
direction = 0;
|
|
}
|
|
else
|
|
{
|
|
// Retain momentum, once we're moving, we're moving. Don't lerp between directions, only between speeds.
|
|
smoothedMovement.Current = direction.Normal * smoothedMovement.Current.Length;
|
|
}
|
|
|
|
//
|
|
// Smooth the wish velocity
|
|
//
|
|
smoothedMovement.Target = direction * velocity;
|
|
smoothedMovement.SmoothTime = smoothedMovement.Target.Length < smoothedMovement.Current.Length ? Controller.DeaccelerationTime : Controller.AccelerationTime;
|
|
smoothedMovement.Update( Time.Delta );
|
|
|
|
// If it's near zero, just stop
|
|
if ( smoothedMovement.Current.IsNearlyZero( 0.01f ) )
|
|
{
|
|
smoothedMovement.Current = 0;
|
|
}
|
|
|
|
//DebugOverlay.ScreenText( 200, $"{smoothedMovement.Current.Length}" );
|
|
|
|
return smoothedMovement.Current;
|
|
}
|
|
}
|