codeAPI Reference
s&box IPlayerControllable: Player control interface
IPlayerControllable API Reference
IPlayerControllable is an interface for Components that can be controlled by seated players through the ControlSystem.
Type Signature
CSHARP
public interface IPlayerControllable
{
bool CanControl(Player player);
void OnStartControl();
void OnEndControl();
void OnControl();
}Methods
- bool CanControl(Player player) - Returns true if this component can be controlled by the specified player. Default implementation returns true.
- void OnStartControl() - Called when the player first gains control of this component.
- void OnEndControl() - Called when the player loses control of this component.
- void OnControl() - Called every frame while the player has control. Use this to read input and control the component.
Usage
Implement this interface on any Component that should respond to player input when seated in a vehicle or chair:
CSHARP
public class ThrusterEntity : Component, IPlayerControllable
{
public bool CanControl(Player player)
{
return true; // Allow any player to control
}
public void OnStartControl()
{
// Initialize control state
}
public void OnEndControl()
{
// Clean up control state
}
public void OnControl()
{
// Read input and apply thrust
var throttle = Input.Float("forward");
ApplyThrust(throttle);
}
}ControlSystem Integration
The ControlSystem automatically:
- Finds all occupied BaseChair components
- Sorts them by occupation time (earliest occupant has priority)
- Uses LinkedGameObjectBuilder to find all connected objects
- Calls OnControl() on all IPlayerControllable components in the connected hierarchy
- Uses ClientInput.PushScope to route input from the seated player
Notes
- ControlSystem runs in Stage.StartFixedUpdate for consistent physics timing
- Seats are sorted by occupation time to prevent conflicts
- Only components in the connected hierarchy (via LinkedGameObjectBuilder) receive control
- ClientInput.PushScope ensures input comes from the seated player, not the local player
- CanControl() is checked before OnControl() is called
Was this helpful?