A player Component for the SnowSandbox game. It holds body dimensions, references a CharacterController and Camera, handles input for use and reload, does ray traces to call IPlayerInteract on hit objects, and updates controller size and camera each tick.
using Sandbox;
namespace SnowSandbox;
[Icon("person")]
public sealed partial class Player : Component
{
[Property]
public float BodyRadius { get; set; } = 9;
[Property]
public float BodyHeight { get; set; } = 40;
[RequireComponent]
public CharacterController Controller { get; private set; }
public bool IsLocalPlayer => !IsProxy;
private CameraComponent Camera;
protected override void OnStart()
{
Camera = Scene.Camera;
if ( IsLocalPlayer )
LocalPlayer = this;
base.OnStart();
}
protected override void OnValidate()
{
UpdateBody();
base.OnValidate();
}
protected override void OnUpdate()
{
var ray = new Ray(EyePosition, EyeAngle.Forward);
var trace = Scene.Trace.Ray( ray, 512 );
if ( !Input.Pressed( "use" ) )
return;
var traceRunned = trace
.IgnoreGameObjectHierarchy( GameObject.Root )
.Run();
if ( traceRunned.Hit )
{
var interact = traceRunned.GameObject.Components.Get<IPlayerInteract>();
interact?.IPress();
}
base.OnUpdate();
}
protected override void OnFixedUpdate()
{
MoveBody();
CameraUpdate();
if ( Input.Pressed( "Reload" ) )
WorldPosition = WorldPosition.WithZ( 1000 );
}
void UpdateBody()
{
Controller.Radius = BodyRadius;
Controller.Height = BodyHeight;
}
}
public interface IPlayerInteract
{
void IPress() { }
}