Reference
Interfaces
The public runtime API of Easy FP Full Body Controller. Most code only needs PlayerController, which links to every subsystem. Everything is in the namespace Player unless noted.
On this page
- PlayerController
- State (read-only)
- Control methods
- PlayerSettings
- PlayerInputHandler
- Per-frame state
- Methods
- PlayerLocomotion
- Configurable fields
- State
- PlayerCameraController
- Configurable fields
- Public API
- Items
- HandItemSocket: the event source
- ItemContainer: the item list
- ItemHoldData: per-item configuration
- ItemDefinition
- ItemAttachmentData
- ItemIKPreset
- Event API
- Payloads
- Item events: HandItemSocket
- Locomotion events: PlayerLocomotion
- Footstep and vitals events
- Listener interfaces
- Subscribe in code
- FPCutter: FPCutterController
- PlayerAnimatorController
- Feet, hands, head and vitals
- PlayerFootPlanting
- PlayerFootsteps
- HandPoseController and FingerPose
- PlayerVitals and PlayerExertion
- PlayerHeadIK
- PlayerHandIK
- PlayerSpineStabilizer
- Multiplayer add-on bridges
- Demo classes
PlayerController#
The hub on the player root. In Awake it fills in any subsystem reference you left empty, so external code needs one reference.
| Property | Type | Subsystem |
|---|---|---|
Settings | PlayerSettings | tuning asset |
Input | PlayerInputHandler | input state |
Locomotion | PlayerLocomotion | movement and physics |
CameraController | PlayerCameraController | first-person camera |
AnimatorController | PlayerAnimatorController | animator parameters and item layers |
HeadIK, HandIK, SpineStabilizer | PlayerHeadIK, PlayerHandIK, PlayerSpineStabilizer | head, hand and spine IK |
FootPlanting | PlayerFootPlanting | ground-anchored feet |
HandItemSocket | HandItemSocket | item equip and unequip |
State (read-only)#
| Member | Type | Notes |
|---|---|---|
IsGrounded, IsSprinting | bool | from PlayerLocomotion |
MoveInput, LookInput | Vector2 | from PlayerInputHandler |
FlashlightTriggered | bool | true for the frame the flashlight key is pressed |
CurrentSpeed, MaxSpeed | float | horizontal speed, and the maximum for the current state |
Control methods#
Use these for menus, cutscenes and pausing.
| Method | Notes |
|---|---|
SetInputEnabled(bool) | Disabling also clears held input. |
SetMovementEnabled(bool), SetCameraEnabled(bool) | Toggle locomotion and the camera. |
SetHeadIKEnabled(bool), SetHandIKEnabled(bool), SetSpineStabilizationEnabled(bool) | Toggle one IK subsystem. |
SetFootIKEnabled(bool) | Toggles PlayerFootPlanting. |
SetExternalControlEnabled(bool) | For external drivers that move the player instead of local input. |
SetCursorLocked(bool) | Locks or frees the cursor. |
DisableAllControls(), EnableAllControls() | Stop or resume all gameplay controls. |
var player = GetComponent<PlayerController>();
player.DisableAllControls(); // enter cutscene or menu
// ...
player.EnableAllControls(); // resume gameplay
PlayerSettings#
A ScriptableObject, created with . Most components read their values from it, so it is the single place to tune the feel. When an asset is assigned, its values override the fields on the components. beginnerMode switches the Inspector to a simplified view.
walkSpeedfloat default 3- Walking speed in units per second.
sprintSpeedfloat default 6- Sprinting speed in units per second.
crouchSpeedfloat default 1.5- Speed while crouching.
crouchHeight,standHeightfloat default 1 and 2- Height of the
CharacterControllerwhile crouching and standing. crouchTransitionSpeedfloat default 8- Speed of the crouch and stand transition.
jumpHeightfloat default 1.2- Jump height in units.
gravityfloat default −15- Gravity. Keep it negative.
groundCheckDistancefloat default 0.2- Distance below the player that counts as ground.
groundedVelocityResetfloat default −2- Vertical velocity applied while grounded, to keep the player on slopes and stairs.
inputDeadzonefloat default 0.01- Smallest input magnitude that counts as movement.
animationSmoothTimefloat default 0.1- Smoothing of the animator's float parameters.
sprintAnimMultiplierfloat default 1.5- Animation speed multiplier while sprinting.
defaultHeadHeightfloat default 1.6- Head height when no head bone is assigned.
lookTargetDistancefloat default 2- Distance of the look target in front of the player.
cameraFallbackHeadHeightfloat default 1.7- Camera height when the head bone is not assigned.
verticalLookLimitfloat default 80- Maximum vertical look angle in degrees.
handVerticalLimitUpper,handVerticalLimitLowerfloat default 45- Look angle, up and down, beyond which the hand IK stops following the view.
enableSpineStabilizationbool default true- Turns spine stabilization on or off.
spineStiffness,spineDampingfloat default 1 and 10- Strength and smoothing of the spine correction.
lowerSpineWeight,middleSpineWeight,upperSpineWeightfloat default 0.3, 0.3, 0.4- Share of each spine segment in the correction.
PlayerInputHandler#
Reads the FBInputActions asset, using the action map named by actionMapName (default Player).
Per-frame state#
| Member | Type | Notes |
|---|---|---|
MoveInput | Vector2 | X is strafe, Y is forward, from −1 to 1 |
LookInput | Vector2 | X is horizontal, Y is vertical |
IsSprinting | bool | sprint is held |
IsCrouching | bool | toggled on each press of Crouch |
JumpTriggered | bool | true for the single frame of the press |
FlashlightTriggered | bool | true for the single frame of the press (uses the held item) |
InteractTriggered | bool | true for the single frame the Interact action is pressed |
Methods#
LockCursor() hides and locks the cursor for gameplay. UnlockCursor() frees it for UI.
The shipped Player map defines Move, Look, Sprint, Jump, Crouch, Flashlight, Interact, Attack, Previous and Next. Previous, Next and Attack are not read by the shipped code.
PlayerLocomotion#
Requires a CharacterController. It fires the locomotion events listed under Event API.
Configurable fields#
Speeds, heights and gravity mirror the values in PlayerSettings. When a settings asset is assigned, the asset wins. Other fields:
groundLayersLayerMask default all layers- Layers that count as ground.
State#
| Member | Type | Notes |
|---|---|---|
IsGrounded | bool | true while touching the ground |
IsCrouching | bool | true in the crouch state |
IsSprinting | bool | true only while grounded and sprinting |
CurrentSpeed, MaxSpeed | float | current horizontal speed, and the maximum for the current state (crouch, walk or sprint) |
CrouchFactor | float | crouch progress |
RegisterListener, UnregisterListener | ILocomotionEventListener | add or remove a listener at runtime |
PlayerCameraController#
Drives a Cinemachine camera. The camera target follows the head bone and does not inherit the head's animation sway.
Configurable fields#
eyeOffsetVector3 default (0, 0.05, 0.1)- Offset from the head bone while standing.
crouchEyeOffsetVector3 default (0, 0.05, 0.05)- Offset from the head bone while crouching.
lookSensitivityfloat default 0.1- Look sensitivity multiplier.
verticalLookLimitfloat default 80- Maximum vertical look angle in degrees, used when no settings asset is assigned.
Public API#
| Member | Signature | Notes |
|---|---|---|
CameraTarget | Transform | the transform the Cinemachine camera follows |
Pitch, Yaw | float | current look angles in degrees |
GetLookAngles | Vector2 GetLookAngles() | X is yaw, Y is pitch |
SetLookDirection | SetLookDirection(float yaw, float pitch) | sets the look direction, for example after a respawn |
SyncCameraTargetToHead | SyncCameraTargetToHead() | runs in LateUpdate; call it yourself after you change the head pose |
SetVerticalLimitOverride, ResetVerticalLimitOverride | SetVerticalLimitOverride(float upper, float lower) | asymmetric look limits, used by item IK data |
SetBodyYawOverride, ClearBodyYawOverride | SetBodyYawOverride(float targetYaw) | overrides the body yaw |
EnsureCameraTarget | EnsureCameraTarget() | creates or reassigns the camera target if it is missing |
SetLocalCameraActive, IsLocalCameraActive | SetLocalCameraActive(bool), bool | enables the local camera. The FishNet add-on disables it on remote players. |
Items#
How items are set up and used is explained in Items. This section lists the API.
HandItemSocket: the event source#
The single owner of equip and unequip events. A switch plays the holster animation: the current item is lowered out of view, then the new one is raised.
| Member | Type | Notes |
|---|---|---|
CurrentItem, HasItem | GameObject, bool | the logical current item, which changes at once when a switch starts |
StowingItem | GameObject | the old item still being lowered during a switch |
PendingItem | GameObject | the new item waiting to be drawn |
IsTransitioning | bool | true while a switch is in progress |
Socket, Locomotion | Transform, PlayerLocomotion | the socket transform, and the locomotion used for crouch offsets |
| Method | Signature | Notes |
|---|---|---|
AttachItem | AttachItem(GameObject, Vector3? positionOffset = null, Vector3? rotationOffset = null) or AttachItem(GameObject, ItemAttachmentData) | attaches an item to the socket |
DetachItem | GameObject DetachItem(bool destroy = false) | detaches the current item |
EquipFromContainer | EquipFromContainer(GameObject item, int slotIndex = -1) | equips an item from a container and applies its ItemHoldData |
UnequipToContainer | UnequipToContainer() or UnequipToContainer(bool hideImmediately) | returns the item to its container. The parameterless overload is kept for existing UnityEvent wiring. |
HideStowingItem, CompleteTransitionImmediately | void | hide the item being lowered, or finish a running switch at once |
UseCurrentItem | void | fires OnUse on the equipped item. It is ignored until the new item is drawn. |
RegisterListener, UnregisterListener | IItemEventListener | add or remove an item listener at runtime |
Inspector fields on HandItemSocket: Smooth Transitions (smoothTransitions, default on; off gives the previous instant switch) and Stow Timeout (stowTimeout, default 1 second).
ItemContainer: the item list#
Holds the items and equips them through the socket. It does not emit equip events itself.
| Member | Signature | Notes |
|---|---|---|
CurrentItem, HasEquippedItem, CurrentIndex | property | the equipped item, whether one is equipped, and its index (−1 for none) |
ItemCount, HandSocket | property | number of items, and the socket the items are equipped through |
EquipItem | EquipItem(int index), EquipItem(GameObject item) | equips by list index, or by a listed item |
EquipItemById | EquipItemById(string id) | equips by the item's id |
EquipNext, EquipPrevious | void EquipNext(), void EquipPrevious() | cycle through the items and wrap around |
UnequipCurrent | UnequipCurrent() or UnequipCurrent(bool hideImmediately) | puts the current item away |
GetItem, GetItemById | GetItem(int index), GetItem(ItemDefinition definition), GetItemById(string id) | gets an item without equipping it |
AddItem | AddItem(GameObject item) | adds an item, inactive until equipped, and fires OnContainerChanged |
RemoveItem | bool RemoveItem(GameObject item) | unequips the item first if it is equipped, and fires OnContainerChanged |
Event: OnContainerChanged (UnityEvent), fired when the item list changes.
ItemHoldData: per-item configuration#
Attached to the item GameObject. With an ItemDefinition assigned, the id, category and world prefab come from the definition.
| Member | Type | Notes |
|---|---|---|
ItemId | string | the effective id: the definition's id, or itemId (default NewItem) |
Definition | ItemDefinition | the assigned definition, or null |
Category | ItemCategory | the effective category |
Is(ItemCategory flags) | bool | true when all given flags are set |
AttachmentData | ItemAttachmentData | the hold and IK configuration |
WorldItemPrefab | GameObject | the prefab spawned when the item is dropped |
OnEquip, OnUnequip, OnUse | UnityEvent | item-local reactions. OnEquip and OnUnequip only fire for items that are shown. |
ItemDefinition#
A ScriptableObject, created with . It describes an item in one place.
| Member | Type | Notes |
|---|---|---|
Id | string | the locked id, or the id derived from the asset name |
IsIdLocked | bool | true once the id is locked |
DisplayName | string | name shown in UI. Falls back to the asset name. |
Category | ItemCategory | category flags |
HeldPrefab, WorldPrefab, NetworkPrefab | GameObject | prefabs for the hand, the world and the network |
Is(ItemCategory flags) | bool | true when all given flags are set |
ItemDefinition.ToId(string assetName) | static string | derives an id from an asset name |
ItemCategory is a flags enum: None, Tool, Electric, Consumable. An item can have several categories.
ItemAttachmentData#
The hold, grip and IK data of an item. Its fields are listed in Items: Grips and IK. The key members are holdStyle (OneHandedRight or TwoHanded), gripPositionOffset, gripRotationOffset, the override… switches with their hand and elbow offsets, fingerPoseRight and fingerPoseLeft, and the vertical limits.
ItemIKPreset#
A ScriptableObject, created with . It stores an ItemAttachmentData in its data field.
| Member | Signature | Notes |
|---|---|---|
ApplyTo | ApplyTo(ItemAttachmentData target) | copies the preset into an item's data |
CaptureFrom | CaptureFrom(ItemAttachmentData source) | copies an item's data into the preset |
CaptureFromScene, ApplyToScene | context menu | capture or apply the data of a scene object that the preset references |
Event API#
Every equip, unequip, locomotion change, footstep and vitals change is announced once, in three ways:
| Mechanism | For |
|---|---|
C# event | code subscribers. Struct payloads avoid allocations per call. |
UnityEvent | Inspector wiring without code |
| Listener interfaces | structured extension. Any component in the player hierarchy that implements one is found at startup. |
Payloads#
ItemEquipArgsItem(GameObject),SlotIndex(int, −1 if the item did not come from a container),HoldData(ItemHoldData),FromContainer(bool).LandArgsImpactVelocity(float, negative when falling),FallDistance(float).FootStepArgsIsLeft(bool),Point(Vector3, world position),IsReStep(bool,truefor a procedural re-step).
Item events: HandItemSocket#
| C# event | Type | UnityEvent |
|---|---|---|
ItemEquipped | Action<ItemEquipArgs> | OnItemEquipped (ItemEvent) |
ItemUnequipped | Action<ItemEquipArgs> | OnItemUnequipped (ItemEvent) |
With smooth transitions, ItemUnequipped fires while the old item is still visible. ItemEquipped can fire for an item that is still waiting to be drawn.
Locomotion events: PlayerLocomotion#
| C# event | Type | UnityEvent |
|---|---|---|
Jumped | Action | OnJumped |
Landed | Action<LandArgs> | OnLanded |
CrouchStarted, CrouchEnded | Action | OnCrouchStarted, OnCrouchEnded |
SprintStarted, SprintEnded | Action | OnSprintStarted, OnSprintEnded |
GroundedChanged | Action<bool> | OnGroundedChanged |
Footstep and vitals events#
| Source | C# event | UnityEvent |
|---|---|---|
PlayerFootsteps | FootPlanted (Action<FootStepArgs>) | OnFootPlanted |
PlayerFootPlanting | ReStepLanded (Action<FootStepArgs>) | none |
PlayerVitals | HealthChanged (Action<float>), Died, Revived | OnHealthChanged, OnDied, OnRevived |
Listener interfaces#
Implement only the methods you need. The others are no-ops. Use RegisterListener for objects that are added at runtime.
IItemEventListener:OnItemEquipped(ItemEquipArgs),OnItemUnequipped(ItemEquipArgs)ILocomotionEventListener:OnJumped(),OnLanded(LandArgs),OnCrouchStarted(),OnCrouchEnded(),OnSprintStarted(),OnSprintEnded(),OnGroundedChanged(bool)
using Player;
using UnityEngine;
public class MyListener : MonoBehaviour, IItemEventListener, ILocomotionEventListener
{
public void OnItemEquipped(ItemEquipArgs args) => Debug.Log($"equipped {args.Item.name}");
public void OnLanded(LandArgs args) => Debug.Log($"landed at {args.ImpactVelocity} m/s");
}
| Method | Notes |
|---|---|
locomotion.RegisterListener(ILocomotionEventListener) | adds a locomotion listener at runtime |
socket.RegisterListener(IItemEventListener) | adds an item listener at runtime |
UnregisterListener(...) | removes a listener from either source |
Subscribe in code#
player.Locomotion.Jumped += () => Debug.Log("jumped");
player.HandItemSocket.ItemEquipped += args =>
Debug.Log($"equipped {args.Item.name} from slot {args.SlotIndex}");
FPCutter: FPCutterController#
Namespace FPCutter. Hides body parts in first person and keeps their shadows. The FPCutter Wizard generates the controller on a complete copy of the character. See FPCutter.
| Member | Signature | Notes |
|---|---|---|
SetFirstPerson | SetFirstPerson() | hides the parts in Hide In First Person |
SetThirdPerson | SetThirdPerson() | shows all parts |
HidePart, ShowPart | HidePart(BodyPart part), ShowPart(BodyPart part) | control one part |
Hide In First PersonList<BodyPart> default Head- The parts that are hidden in first person.
Invisible MaterialMaterial- The material for hidden parts. It uses the
FPCutter/InvisibleShadowCastershader.
BodyPart (in the FPCutter namespace) has the values Body, Head, LeftArm, RightArm, LeftLeg and RightLeg.
PlayerAnimatorController#
Drives the animator parameters and the item animation layers.
| Member | Signature | Notes |
|---|---|---|
SetItemLayer | SetItemLayer(int layerIndex) | activates an item animation layer |
ToggleFlashlight, SetFlashlightActive | ToggleFlashlight(), SetFlashlightActive(bool) | the flashlight state |
IsFlashlightActive | bool (property) | true while the flashlight layer is active |
TriggerAnimation | TriggerAnimation(string triggerName) | sets an Animator trigger |
GetAnimator | Animator GetAnimator() | returns the Animator |
Feet, hands, head and vitals#
The Setup Wizard configures these components. Change them directly only for custom behaviour. The tuning of each is in its guide: Body IK and Vitals.
PlayerFootPlanting#
On the model. Runs at execution order -200, before the camera syncs to the head.
| Member | Signature or type | Notes |
|---|---|---|
SetEnabled | SetEnabled(bool) | turns planting on or off at runtime |
ResetPlanting | ResetPlanting() | resets the anchors. Call it after a teleport. |
SetExternalDriveState, ClearExternalDriveState | SetExternalDriveState(bool grounded, Vector2 moveDirection) | drives a remote player from a network add-on. The PurrNet bridge uses it. |
ReStepLanded | event Action<FootStepArgs> | fires when a re-step lands |
PlantMode | enum | Idle, Moving, Automatic |
StepSettings | nested class | re-step duration, path, arc, lift, rotation and catch-up curves |
PlayerFootsteps#
On the root. Detects steps from the animated feet, without animation events. It raises FootPlanted and OnFootPlanted, listed under Event API.
HandPoseController and FingerPose#
HandPoseController sits on the model and poses the fingers around the held item. It calibrates from the Humanoid muscle limits.
| Member | Signature | Notes |
|---|---|---|
CalibrateFromAvatar | bool CalibrateFromAvatar() | re-reads the finger limits from the avatar. |
Rebind | Rebind() | rebinds the finger bones |
RecaptureReference | RecaptureReference() | captures the reference pose |
Snap | Snap() | applies the current target at once, for example when an item is equipped at start |
ResolvedBoneCount | int (property) | number of finger bones found |
FingerPose is a ScriptableObject created with . Its fields are the five curls (thumbCurl, indexCurl, middleCurl, ringCurl, littleCurl), thumbOpposition and spread. ToValues() and FromValues(...) convert to and from FingerPoseValues.
PlayerVitals and PlayerExertion#
PlayerVitals is optional and sits on the root. Its health and stamina are described in Vitals and Stamina.
| Member | Signature or type | Notes |
|---|---|---|
Health, MaxHealth, NormalizedHealth | float (properties) | current and maximum health, and the 0 to 1 fraction |
IsDead | bool | true at zero health |
ApplyDamage, Heal | bool ApplyDamage(float amount), bool Heal(float amount) | false when ignored (dead player, or an amount that is zero, negative, NaN or infinite) |
Revive | bool Revive() | restores a dead player to full health. Returns false for a living player. |
SetHealth | void SetHealth(float value) | sets the value, clamped to 0 and MaxHealth. Use it to mirror a server value. |
Bpm, CanSprint | float, bool (properties) | heart rate, and whether sprinting is allowed |
Exertion | PlayerExertion (property) | the stamina model, with Bpm, Exhausted, NeedsSprintRelease and CanSprint |
PlayerHeadIK#
| Member | Signature | Notes |
|---|---|---|
Weight | float (property) | current IK weight |
SetWeight, SetWeightSmooth | SetWeight(float), SetWeightSmooth(float) | immediate or smoothed weight |
SetWeights | SetWeights(float body, float head, float eyes, float clamp) | body, head and eye weights, and the clamp |
SetEnabled | SetEnabled(bool) | turns head look-at on or off |
PlayerHandIK#
Hand and elbow IK for held items, including the holster animation. Runs at execution order 20, after head (10) and spine (15).
| Member | Signature | Notes |
|---|---|---|
HolsterProgress | float (property) | 0 is raised at the item pose, 1 is lowered out of view |
SetHolstered | SetHolstered(bool) | lowers or raises the hand |
BeginDraw | BeginDraw() | starts raising the hand |
SetIKWeight, SetIKWeightSmooth | SetIKWeight(float position, float rotation, float hint = 1) | right-hand weights. Partial weights stay as set. |
SetLeftIKWeight | SetLeftIKWeight(float position, float rotation, float hint = 1) | left-hand weights for two-handed items |
SetTwoHanded | SetTwoHanded(bool) | fades the left hand on or off |
SetEnabled | SetEnabled(bool) | turns hand IK on or off |
IKPositionWeight, IKRotationWeight | float (properties) | right-hand IK weights |
The holster timings are Inspector fields under Holster: holsterOffset, holsterTiltAngle, holsterDuration, drawDuration, drawStartWeight, leftHolsterOffset and twoHandedBlendDuration. They are described in Items.
PlayerSpineStabilizer#
Requires an Animator. Keeps the upper body steady while the head looks around. Runs at execution order 15. It is tuned through the spine fields of PlayerSettings.
Multiplayer add-on bridges#
Each optional add-on has one bridge per networking library. Both bridges expose the same item-state method and keep a list of networked world item prefabs.
| Class | Namespace | Public API |
|---|---|---|
FishNetPlayerBridge | FBSystem.FishNet | NotifyLocalItemStateChanged(ItemEquipArgs). Serialized list: networkWorldItemPrefabs. |
PurrNetPlayerBridge | FBSystem.PurrNet | NotifyLocalItemStateChanged(ItemEquipArgs). Serialized list: networkWorldItemPrefabs. |
The bridges are configured by their Setup Wizards. See Multiplayer (FishNet) and Multiplayer (PurrNet).
Demo classes#
These classes are demo code, not part of the core API. They are in the namespace Player.Demo.
PlayerEventLogger: implements both listener interfaces and logs every event. Use it as a template.PlayerInventory: the owned item ids and starter items.PlayerInteraction(E) andPlayerDropSystem(G): pickup and drop.WorldItem: the dropped item. ItsitemIdmust match the item in the container.DemoGuidePanel(F1) andDemoGripToggle(H).