Full Body Awareness Controller

Scripting

Read the view and held item state from code, make your own held item modifiers, change held items at runtime and add your own held item sources.

Scripting

Most things can be done with visual scripting. This page lists the parts you can use from your own C# code.

Awareness State

Every character with the Full Body Awareness rig has an AwarenessState. It holds the view, the held item state and the events.

csharp
AwarenessState state = AwarenessState.Get(character);

float yaw = state.Yaw;
float pitch = state.Pitch;

bool sprintLowered = state.IsSprintLowered;
bool wallRetracting = state.IsWallRetracting;
bool attacking = state.IsAttacking;
MemberWhat it does
AwarenessState.Get(character)Returns the state of a character.
AwarenessState.TryGet(character, out state)Returns the state if the character has one.
Yaw, PitchWhere the character looks, in degrees.
AddLookImmediate(yaw, pitch)Turns the view right away.
IsTraversingWhether the character is using Game Creator's Traversal module.
IsBodyReleased, SetBodyReleased(owner, released)Whether the body is given back to the animation, and turns it on or off for an owner object, like the Release Body instruction.
StartFollowHead(transition), StopFollowHead(transition)Makes the view follow the animated head, like the Follow Head Animation instruction.
AdsWeightHow far the item is raised to the eye, from 0 to 1.
IsSprintLoweredWhether Lower When Sprinting has lowered the item.
IsWallRetractingWhether Wall Retract has moved the item away from a wall.
IsAttacking, IsBlockingWhether the held weapon is attacking or blocking. Set by the Melee Integration.
EventLoweringRuns when an item starts to lower or raise.
EventRecoilRuns when a recoil kick plays.
AddRecoil(strength)Plays a recoil kick, like the Recoil Kick instruction.

Held Item Sources

The rig asks a list of sources which item a character holds. The Shooter and Melee integrations are sources. To feed another combat or item system, write your own source:

csharp
public class MyItemSource : IHeldItemSource
{
    public int Priority => 50;

    public bool TryGetWeapon(Character character, ref HeldItemInfo info)
    {
        Transform prop = FindMyWeapon(character);
        if (prop == null) return false;

        info.IsArmed = true;
        info.Weapon = prop;
        return true;
    }

    public void OnRelease(Character character)
    { }
}

Register it once, for example when the game starts:

csharp
HeldItemSources.Register(new MyItemSource());

Sources with a higher Priority are asked first. Shooter uses 100 and Melee uses 90.

Your Own Held Item Modifier

A Held Item Profile can hold your own modifiers next to the included ones. Make a class that inherits THeldItemModifier<TState>, and it shows up in the Add list of every Held Item Profile.

This example rolls the item a little while the view turns:

csharp
using System;
using Fullscreen.FullBodyAwarenessController.Runtime;
using GameCreator.Runtime.Common;
using UnityEngine;

[Title("Tilt When Turning")]
[Category("Tilt When Turning")]
[Description("Rolls the item while the view turns")]
[Serializable]
public class ModifierTiltWhenTurning : THeldItemModifier<ModifierTiltWhenTurning.State>
{
    public class State : HeldItemModifierState
    {
        public float Roll;
    }

    [SerializeField] private float m_Strength = 0.02f;
    [SerializeField] private float m_MaxRoll = 6f;
    [SerializeField] private float m_SmoothTime = 0.1f;
    [SerializeField] private PropertyGetDecimal m_WhileAiming = new PropertyGetDecimal(0.2f);

    public override string Title => "Tilt When Turning";

    protected override void Compute(in FeelContext context, State state, out Vector3 position, out Vector3 euler)
    {
        float turnSpeed = context.DeltaTime > 0f
            ? context.State.LookDelta.x / context.DeltaTime
            : 0f;

        float target = Mathf.Clamp(-turnSpeed * this.m_Strength, -this.m_MaxRoll, this.m_MaxRoll);
        target *= Mathf.Lerp(1f, GetRatio(this.m_WhileAiming, state), context.Ads);

        float blend = 1f - Mathf.Exp(-context.DeltaTime / Mathf.Max(0.001f, this.m_SmoothTime));
        state.Roll = Mathf.Lerp(state.Roll, target, blend);

        position = Vector3.zero;
        euler = new Vector3(0f, 0f, state.Roll);
    }

    protected override void OnClear(State state)
    {
        state.Roll = 0f;
    }
}

Compute runs every frame while the item is held. Return an offset in camera space: position in meters, where X is right, Y is up and Z is forward, and euler in degrees. The offsets of all modifiers in the profile are added together. Each one fades in and out when it is switched on or off, so you don't need to do that yourself.

MemberWhat it does
TStateYour own state class, made once per character. Keep values that change over time here, not in fields of the modifier, because one profile can be shared by many characters.
Compute(context, state, out position, out euler)Returns the offset for this frame.
OnActivate(state), OnDeactivate(state)Run when the modifier starts running for a character, and when it stops, for example when the item is put away or the profile changes.
OnClear(state)Resets the state after the modifier has faded out.
GetAimRelease(state)Return a value from 0 to 1 to lower the item out of the aim pose, like Lower When Sprinting does.
GetLiveInfo(state)Text shown for the modifier in the Live Preview.
PosePositionField, PoseRotationFieldNames of Vector3 fields the Live Preview nudge buttons can change.
Context valueWhat it holds
context.CharacterThe Character holding the item.
context.StateThe character's AwarenessState, with the view, speed, bob phase, sprint and lean.
context.CameraThe camera pose this frame.
context.AdsHow far the item is raised to the eye, from 0 to 1.
context.DeltaTime, context.TimeThe character's time.

Decimal fields can use PropertyGetDecimal, like the included modifiers, so their values can come from Game Creator variables. Read them with GetValue, GetPositive or GetRatio.

Change a Held Item From Code

Each held item can be changed at runtime through its Held Item component. The change applies on the next frame.

csharp
HeldItem item = weapon.GetComponent<HeldItem>();

item.Profile = heavyProfile;
item.LockHandToView = false;

item.SetRuntimePlacement(new HeldItemPlacementData(
    HeldItemPlacement.Animated,
    new Vector3(0f, -0.08f, 0f),
    new Vector3(20f, 0f, 0f)
));

item.ClearRuntimePlacement();
MemberWhat it does
ProfileSwaps the Held Item Profile, and with it every modifier.
LockHandToViewLocks the holding hand to the view, or lets it play its animation.
PointStrengthHow much the item turns towards the crosshair point.
SetRuntimePlacement(placement)Overrides where the item sits in view, like the Change Held Item Placement instruction. The profile is not changed.
ClearRuntimePlacement()Goes back to the placement of the profile.

HeldItem.Resolve(character.gameObject, true) returns the Held Item of what the character holds, and adds the component if the item doesn't have one yet.

Static Switches

MemberDefaultWhat it does
ShooterWeaponSource.OverrideShooterRigtrueSwitches the Shooter Human rig off while the Full Body Awareness rig is active.
MeleeWeaponSource.FollowAttackTurnstrueTurns the view with the body during Root Motion and Motion Warp skills.
MeleeWeaponSource.SyncStrikerstrueAdds Striker Sync to equipped Melee weapons that have a Striker.

Rig Settings From Code

csharp
RigFullBodyAwareness rig = character.IK.GetRig<RigFullBodyAwareness>();
rig.Shadow.ShadowBody = true;
rig.Items.AlignShotsToCrosshair = true;