Movement Examples
Various movement patterns and player controllers.
WASD Movement
public class PlayerMovement : Component
{
public float Speed = 5f;
protected override void OnUpdate()
{
var move = Vector3.Zero;
if (RaylibInput.IsKeyDown(KeyCode.W)) move.Z += 1;
if (RaylibInput.IsKeyDown(KeyCode.S)) move.Z -= 1;
if (RaylibInput.IsKeyDown(KeyCode.A)) move.X -= 1;
if (RaylibInput.IsKeyDown(KeyCode.D)) move.X += 1;
if (move.LengthSquared > 0)
Transform!.Position += move.Normalized * Speed * Time.Delta;
}
protected override void OnRender(RaylibRenderer r)
{
r.DrawCube(Transform!.Position, Vector3.One, Color.Blue);
}
}
Velocity with Friction
public class VelocityMovement : Component
{
public float Acceleration = 20f;
public float Friction = 8f;
public float MaxSpeed = 10f;
private Vector3 _velocity;
protected override void OnUpdate()
{
var input = Vector3.Zero;
if (RaylibInput.IsKeyDown(KeyCode.W)) input.Z += 1;
if (RaylibInput.IsKeyDown(KeyCode.S)) input.Z -= 1;
if (RaylibInput.IsKeyDown(KeyCode.A)) input.X -= 1;
if (RaylibInput.IsKeyDown(KeyCode.D)) input.X += 1;
if (input.LengthSquared > 0)
_velocity += input.Normalized * Acceleration * Time.Delta;
else
_velocity = _velocity.LerpTo(Vector3.Zero, Friction * Time.Delta);
_velocity = _velocity.ClampLength(MaxSpeed);
Transform!.Position += _velocity * Time.Delta;
}
}
Jump Mechanic
public class JumpingPlayer : Component
{
public float MoveSpeed = 5f;
public float JumpForce = 10f;
public float Gravity = 25f;
private float _velocityY;
private bool _grounded = true;
protected override void OnUpdate()
{
var pos = Transform!.Position;
// Horizontal movement
var move = Vector3.Zero;
if (RaylibInput.IsKeyDown(KeyCode.W)) move.Z += 1;
if (RaylibInput.IsKeyDown(KeyCode.S)) move.Z -= 1;
if (RaylibInput.IsKeyDown(KeyCode.A)) move.X -= 1;
if (RaylibInput.IsKeyDown(KeyCode.D)) move.X += 1;
pos += move.Normalized * MoveSpeed * Time.Delta;
// Jump
if (_grounded && RaylibInput.IsKeyPressed(KeyCode.Space))
{
_velocityY = JumpForce;
_grounded = false;
}
// Gravity
_velocityY -= Gravity * Time.Delta;
pos.Y += _velocityY * Time.Delta;
// Ground check
if (pos.Y <= 0.5f)
{
pos.Y = 0.5f;
_velocityY = 0;
_grounded = true;
}
Transform.Position = pos;
}
}
Dash Ability
public class DashMovement : Component
{
public float MoveSpeed = 5f;
public float DashSpeed = 25f;
public float DashDuration = 0.15f;
public float DashCooldown = 0.5f;
private Vector3 _dashDir;
private float _dashTimer;
private float _cooldownTimer;
protected override void OnUpdate()
{
_cooldownTimer -= Time.Delta;
var input = Vector3.Zero;
if (RaylibInput.IsKeyDown(KeyCode.W)) input.Z += 1;
if (RaylibInput.IsKeyDown(KeyCode.S)) input.Z -= 1;
if (RaylibInput.IsKeyDown(KeyCode.A)) input.X -= 1;
if (RaylibInput.IsKeyDown(KeyCode.D)) input.X += 1;
// Start dash
if (RaylibInput.IsKeyPressed(KeyCode.LeftShift) && _cooldownTimer <= 0 && input.LengthSquared > 0)
{
_dashTimer = DashDuration;
_dashDir = input.Normalized;
_cooldownTimer = DashCooldown;
}
// Apply movement
if (_dashTimer > 0)
{
_dashTimer -= Time.Delta;
Transform!.Position += _dashDir * DashSpeed * Time.Delta;
}
else if (input.LengthSquared > 0)
{
Transform!.Position += input.Normalized * MoveSpeed * Time.Delta;
}
}
}
Smooth Follow
public class SmoothFollower : Component
{
public string TargetName = "Player";
public float FollowSpeed = 5f;
public float MinDistance = 2f;
protected override void OnUpdate()
{
var target = Scene?.FindByName(TargetName);
if (target == null) return;
float dist = Transform!.Position.DistanceTo(target.Transform.Position);
if (dist > MinDistance)
{
Transform.Position = Vector3.Lerp(
Transform.Position,
target.Transform.Position,
FollowSpeed * Time.Delta
);
}
}
}
Orbit Motion
public class OrbitMotion : Component
{
public Vector3 Center = Vector3.Zero;
public float Radius = 5f;
public float Speed = 1f;
private float _angle;
protected override void OnUpdate()
{
_angle += Speed * Time.Delta;
Transform!.Position = Center + new Vector3(
MathF.Cos(_angle) * Radius,
0.5f,
MathF.Sin(_angle) * Radius
);
}
}
Waypoint Patrol
public class WaypointPatrol : Component
{
public float Speed = 3f;
public float ArriveThreshold = 0.2f;
private Vector3[] _waypoints = new[]
{
new Vector3(-5, 0.5f, -5),
new Vector3(5, 0.5f, -5),
new Vector3(5, 0.5f, 5),
new Vector3(-5, 0.5f, 5)
};
private int _currentIndex;
protected override void OnUpdate()
{
var target = _waypoints[_currentIndex];
var dir = (target - Transform!.Position).Normalized;
Transform.Position += dir * Speed * Time.Delta;
if (Transform.Position.DistanceTo(target) < ArriveThreshold)
_currentIndex = (_currentIndex + 1) % _waypoints.Length;
}
}
Bounded Movement
public class BoundedMovement : Component
{
public float Speed = 5f;
public float BoundarySize = 10f;
protected override void OnUpdate()
{
var move = Vector3.Zero;
if (RaylibInput.IsKeyDown(KeyCode.W)) move.Z += 1;
if (RaylibInput.IsKeyDown(KeyCode.S)) move.Z -= 1;
if (RaylibInput.IsKeyDown(KeyCode.A)) move.X -= 1;
if (RaylibInput.IsKeyDown(KeyCode.D)) move.X += 1;
var pos = Transform!.Position + move.Normalized * Speed * Time.Delta;
pos.X = MathHelper.Clamp(pos.X, -BoundarySize, BoundarySize);
pos.Z = MathHelper.Clamp(pos.Z, -BoundarySize, BoundarySize);
Transform.Position = pos;
}
}