# Ultimate Character Controller - Opsive Documentation

> Complete Ultimate Character Controller documentation, generated from the Opsive documentation source on 2026-08-14.

Documentation home: https://opsive.com/support/documentation/ultimate-character-controller/

## Contents

- [Ultimate Character Controller](#page-ultimate-character-controller)
  - [Getting Started](#page-ultimate-character-controller-getting-started)
    - [Requirements and First Decisions](#page-ultimate-character-controller-getting-started-requirements-and-first-decisions)
    - [Importing](#page-ultimate-character-controller-getting-started-importing)
    - [First Playable Character](#page-ultimate-character-controller-getting-started-first-playable-character)
    - [Quick Setup](#page-ultimate-character-controller-getting-started-quick-setup)
    - [Your First Hour with UCC](#page-ultimate-character-controller-getting-started-first-hour)
    - [How UCC Fits Together](#page-ultimate-character-controller-getting-started-how-ucc-fits-together)
    - [Demo Scene](#page-ultimate-character-controller-getting-started-demo-scene)
    - [Getting Started Troubleshooting](#page-ultimate-character-controller-getting-started-troubleshooting)
    - [Editor Options by Feature](#page-ultimate-character-controller-getting-started-editor-reference)
    - [Version 3 Migration Guide](#page-ultimate-character-controller-getting-started-version-3-migration-guide)
  - [Organization](#page-ultimate-character-controller-organization)
  - [Component Overview](#page-ultimate-character-controller-component-overview)
  - [Character](#page-ultimate-character-controller-character)
    - [Character Creation](#page-ultimate-character-controller-character-character-creation)
      - [Common Setups](#page-ultimate-character-controller-character-character-creation-common-setups)
      - [Item Support](#page-ultimate-character-controller-character-character-creation-item-support)
      - [Templates](#page-ultimate-character-controller-character-character-creation-templates)
    - [Movement Types](#page-ultimate-character-controller-character-movement-types)
      - [Included Movement Types](#page-ultimate-character-controller-character-movement-types-included-movement-types)
        - [First Person Combat](#page-ultimate-character-controller-character-movement-types-included-movement-types-first-person-combat)
        - [First Person Free Look](#page-ultimate-character-controller-character-movement-types-included-movement-types-first-person-free-look)
        - [Third Person Adventure](#page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-adventure)
        - [Third Person Combat](#page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-combat)
        - [Third Person Four Legged](#page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-four-legged)
        - [Third Person Point & Click](#page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-point-click)
        - [Third Person Pseudo3D (2.5D)](#page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-pseudo3d-2-5d)
        - [Third Person RPG](#page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-rpg)
        - [Third Person Top Down](#page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-top-down)
    - [Abilities](#page-ultimate-character-controller-character-abilities)
      - [Included Abilities](#page-ultimate-character-controller-character-abilities-included-abilities)
        - [Align To Ground](#page-ultimate-character-controller-character-abilities-included-abilities-align-to-ground)
        - [Align To Gravity Zone](#page-ultimate-character-controller-character-abilities-included-abilities-align-to-gravity-zone)
        - [Assist Aim](#page-ultimate-character-controller-character-abilities-included-abilities-assist-aim)
        - [Damage Visualization](#page-ultimate-character-controller-character-abilities-included-abilities-damage-visualization)
        - [Detect Ground Ability Base](#page-ultimate-character-controller-character-abilities-included-abilities-detect-ground-ability-base)
        - [Detect Object Ability Base](#page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base)
          - [Drive](#page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-drive)
          - [Interact](#page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-interact)
          - [Look At](#page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-look-at)
          - [Pickup](#page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-pickup)
          - [Ride](#page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-ride)
        - [Die](#page-ultimate-character-controller-character-abilities-included-abilities-die)
        - [Fall](#page-ultimate-character-controller-character-abilities-included-abilities-fall)
        - [First Person Lean](#page-ultimate-character-controller-character-abilities-included-abilities-first-person-lean)
        - [Follow Pseudo3D Path](#page-ultimate-character-controller-character-abilities-included-abilities-follow-pseudo3d-2-5d-path)
        - [Generic](#page-ultimate-character-controller-character-abilities-included-abilities-generic)
        - [Height Change](#page-ultimate-character-controller-character-abilities-included-abilities-height-change)
        - [Idle](#page-ultimate-character-controller-character-abilities-included-abilities-idle)
        - [Rotate Towards](#page-ultimate-character-controller-character-abilities-included-abilities-rotate-towards)
        - [Impact Knock Back](#page-ultimate-character-controller-character-abilities-included-abilities-impact-knock-back)
        - [Item Equip Verifier](#page-ultimate-character-controller-character-abilities-included-abilities-item-equip-verifier)
        - [Jump](#page-ultimate-character-controller-character-abilities-included-abilities-jump)
        - [Move Towards](#page-ultimate-character-controller-character-abilities-included-abilities-move-towards)
        - [Move With Object](#page-ultimate-character-controller-character-abilities-included-abilities-move-with-object)
        - [NavMeshAgent Movement](#page-ultimate-character-controller-character-abilities-included-abilities-navmeshagent-movement)
        - [Quick Start](#page-ultimate-character-controller-character-abilities-included-abilities-quick-start)
        - [Quick Stop](#page-ultimate-character-controller-character-abilities-included-abilities-quick-stop)
        - [Quick Turn](#page-ultimate-character-controller-character-abilities-included-abilities-quick-turn)
        - [Ragdoll](#page-ultimate-character-controller-character-abilities-included-abilities-ragdoll)
        - [Restrict Position](#page-ultimate-character-controller-character-abilities-included-abilities-restrict-position)
        - [Restrict Rotation](#page-ultimate-character-controller-character-abilities-included-abilities-restrict-rotation)
        - [Revive](#page-ultimate-character-controller-character-abilities-included-abilities-revive)
        - [Rideable](#page-ultimate-character-controller-character-abilities-included-abilities-rideable)
        - [Stop Movement Animation](#page-ultimate-character-controller-character-abilities-included-abilities-stop-movement-animation)
        - [Slide](#page-ultimate-character-controller-character-abilities-included-abilities-slide)
        - [Speed Change](#page-ultimate-character-controller-character-abilities-included-abilities-speed-change)
        - [Target Orbit](#page-ultimate-character-controller-character-abilities-included-abilities-target-orbit)
      - [Item Abilities](#page-ultimate-character-controller-character-abilities-item-abilities)
        - [Aim](#page-ultimate-character-controller-character-abilities-item-abilities-aim)
        - [Block](#page-ultimate-character-controller-character-abilities-item-abilities-block)
        - [Drop](#page-ultimate-character-controller-character-abilities-item-abilities-drop)
        - [Item Set](#page-ultimate-character-controller-character-abilities-item-abilities-item-set)
          - [Equip Next](#page-ultimate-character-controller-character-abilities-item-abilities-item-set-equip-next)
          - [Equip Previous](#page-ultimate-character-controller-character-abilities-item-abilities-item-set-equip-previous)
          - [Equip Scroll](#page-ultimate-character-controller-character-abilities-item-abilities-item-set-equip-scroll)
          - [Equip Unequip](#page-ultimate-character-controller-character-abilities-item-abilities-item-set-equip-unequip)
          - [Toggle Equip](#page-ultimate-character-controller-character-abilities-item-abilities-item-set-toggle-equip)
        - [Reload](#page-ultimate-character-controller-character-abilities-item-abilities-reload)
        - [Third Person Item Pullback](#page-ultimate-character-controller-character-abilities-item-abilities-third-person-item-pullback)
        - [Use](#page-ultimate-character-controller-character-abilities-item-abilities-use)
          - [In Air Melee Use](#page-ultimate-character-controller-character-abilities-item-abilities-use-in-air-melee-use)
          - [Melee Counter Attack](#page-ultimate-character-controller-character-abilities-item-abilities-use-melee-counter-attack)
      - [Ability Starter](#page-ultimate-character-controller-character-abilities-ability-starter)
      - [Move Towards Location](#page-ultimate-character-controller-character-abilities-move-towards-location)
      - [Animator Motion](#page-ultimate-character-controller-character-abilities-animator-motion)
      - [New Ability](#page-ultimate-character-controller-character-abilities-new-ability)
    - [Effects](#page-ultimate-character-controller-character-effects)
      - [Included Effects](#page-ultimate-character-controller-character-effects-included-effects)
        - [Boss Stomp](#page-ultimate-character-controller-character-effects-included-effects-boss-stomp)
        - [Play Audio Clip](#page-ultimate-character-controller-character-effects-included-effects-play-audio-clip)
        - [Shake](#page-ultimate-character-controller-character-effects-included-effects-earthquake)
    - [Generic Character](#page-ultimate-character-controller-character-generic-character)
    - [Time](#page-ultimate-character-controller-character-time)
    - [Model Switch](#page-ultimate-character-controller-character-model-switch)
    - [Minimum Component Setup](#page-ultimate-character-controller-character-minimum-component-setup)
  - [Camera](#page-ultimate-character-controller-camera)
    - [View Types](#page-ultimate-character-controller-camera-view-types)
      - [Included View Types](#page-ultimate-character-controller-camera-view-types-included-view-types)
        - [First Person](#page-ultimate-character-controller-camera-view-types-included-view-types-first-person)
          - [Combat](#page-ultimate-character-controller-camera-view-types-included-view-types-first-person-combat)
          - [Free Look](#page-ultimate-character-controller-camera-view-types-included-view-types-first-person-free-look)
        - [First Person Transform Look](#page-ultimate-character-controller-camera-view-types-included-view-types-first-person-transform-look)
        - [Third Person](#page-ultimate-character-controller-camera-view-types-included-view-types-third-person)
          - [Adventure](#page-ultimate-character-controller-camera-view-types-included-view-types-third-person-adventure)
          - [Combat](#page-ultimate-character-controller-camera-view-types-included-view-types-third-person-combat)
          - [RPG](#page-ultimate-character-controller-camera-view-types-included-view-types-third-person-rpg)
        - [Third Person Look At](#page-ultimate-character-controller-camera-view-types-included-view-types-third-person-look-at)
        - [Third Person Pseudo3D (2.5D)](#page-ultimate-character-controller-camera-view-types-included-view-types-third-person-pseudo3d-2-5d)
        - [Third Person Top Down](#page-ultimate-character-controller-camera-view-types-included-view-types-third-person-top-down)
        - [Transition](#page-ultimate-character-controller-camera-view-types-included-view-types-transition)
    - [Object Fader](#page-ultimate-character-controller-camera-object-fader)
    - [Post Processing](#page-ultimate-character-controller-camera-post-processing)
    - [Split Screen](#page-ultimate-character-controller-camera-split-screen)
  - [Items & Inventory](#page-ultimate-character-controller-items-inventory)
    - [Item Type Creation](#page-ultimate-character-controller-items-inventory-item-types)
    - [Item Creation](#page-ultimate-character-controller-items-inventory-item-creation)
      - [Dual Wielding](#page-ultimate-character-controller-items-inventory-item-creation-dual-wielding)
      - [Common Setups](#page-ultimate-character-controller-items-inventory-item-creation-common-setups)
      - [Item Tips](#page-ultimate-character-controller-items-inventory-item-creation-item-tips)
      - [Templates](#page-ultimate-character-controller-items-inventory-item-creation-templates)
      - [Item Troubleshooting](#page-ultimate-character-controller-items-inventory-item-creation-item-troubleshooting)
    - [Item Type, Definition & Category](#page-ultimate-character-controller-items-inventory-item-type-definition-category)
    - [Item Set & Rules](#page-ultimate-character-controller-items-inventory-item-set-rules)
    - [Character Item](#page-ultimate-character-controller-items-inventory-character-item)
      - [First Person Perspective](#page-ultimate-character-controller-items-inventory-character-item-first-person-perspective)
      - [Third Person Perspective](#page-ultimate-character-controller-items-inventory-character-item-third-person-perspective)
      - [Item Actions](#page-ultimate-character-controller-items-inventory-character-item-item-actions)
        - [Usable](#page-ultimate-character-controller-items-inventory-character-item-item-actions-usable)
          - [Shootable](#page-ultimate-character-controller-items-inventory-character-item-item-actions-usable-shootable)
          - [Melee](#page-ultimate-character-controller-items-inventory-character-item-item-actions-usable-melee)
          - [Throwable](#page-ultimate-character-controller-items-inventory-character-item-item-actions-usable-throwable)
          - [Magic](#page-ultimate-character-controller-items-inventory-character-item-item-actions-usable-magic)
        - [Shield](#page-ultimate-character-controller-items-inventory-character-item-item-actions-shield)
        - [Action Modules & Groups](#page-ultimate-character-controller-items-inventory-character-item-item-actions-action-modules-groups)
          - [Impact Actions](#page-ultimate-character-controller-items-inventory-character-item-item-actions-action-modules-groups-impact-actions)
          - [Impact Action Conditions](#page-ultimate-character-controller-items-inventory-character-item-item-actions-action-modules-groups-impact-action-conditions)
          - [Item Effects](#page-ultimate-character-controller-items-inventory-character-item-item-actions-action-modules-groups-item-effects)
    - [Inventory](#page-ultimate-character-controller-items-inventory-inventory)
    - [Item Slots](#page-ultimate-character-controller-items-inventory-item-slots)
    - [Animator Audio State Set](#page-ultimate-character-controller-items-inventory-animator-audio-state-set)
    - [Item Pickup](#page-ultimate-character-controller-items-inventory-item-pickup)
  - [Animation](#page-ultimate-character-controller-animation)
    - [Springs](#page-ultimate-character-controller-animation-springs)
    - [Animator](#page-ultimate-character-controller-animation-animator)
      - [Animator Controller](#page-ultimate-character-controller-animation-animator-animator-controller)
      - [Animator Parameters](#page-ultimate-character-controller-animation-animator-animator-parameters)
      - [Default Animator Values](#page-ultimate-character-controller-animation-animator-default-animator-values)
      - [First Person Arms](#page-ultimate-character-controller-animation-animator-first-person-arms)
      - [Replacing Animations](#page-ultimate-character-controller-animation-animator-replacing-animations)
    - [Animation Event Trigger](#page-ultimate-character-controller-animation-animation-event-trigger)
      - [Animation Slot Event Trigger](#page-ultimate-character-controller-animation-animation-event-trigger-animation-slot-event-trigger)
  - [Input](#page-ultimate-character-controller-input)
    - [Virtual Controls](#page-ultimate-character-controller-input-virtual-controls)
  - [State System](#page-ultimate-character-controller-state-system)
    - [Presets](#page-ultimate-character-controller-state-system-presets)
  - [Attributes](#page-ultimate-character-controller-attributes)
    - [Health](#page-ultimate-character-controller-attributes-health)
  - [Inverse Kinematics (IK)](#page-ultimate-character-controller-inverse-kinematics)
  - [Objects](#page-ultimate-character-controller-objects)
    - [Explosions](#page-ultimate-character-controller-objects-explosions)
    - [Damage Processor](#page-ultimate-character-controller-objects-damage-processor)
    - [Magic Particle](#page-ultimate-character-controller-objects-magic-particle)
    - [Object Identifier](#page-ultimate-character-controller-objects-object-identifier)
    - [Object Pickup](#page-ultimate-character-controller-objects-object-pickup)
      - [Health Pickup](#page-ultimate-character-controller-objects-object-pickup-health-pickup)
      - [Item Pickup](#page-ultimate-character-controller-objects-object-pickup-item-pickup)
    - [Trajectory Object](#page-ultimate-character-controller-objects-trajectory-object)
      - [Grenade](#page-ultimate-character-controller-objects-trajectory-object-grenade)
      - [Magic Projectile](#page-ultimate-character-controller-objects-trajectory-object-magic-projectile)
      - [Projectile](#page-ultimate-character-controller-objects-trajectory-object-projectile)
      - [Shell](#page-ultimate-character-controller-objects-trajectory-object-shell)
  - [Moving Platforms](#page-ultimate-character-controller-moving-platforms)
  - [Layer Manager](#page-ultimate-character-controller-layer-manager)
  - [Surface System](#page-ultimate-character-controller-surface-system)
    - [Surface Manager](#page-ultimate-character-controller-surface-system-surface-manager)
    - [Surface Impacts](#page-ultimate-character-controller-surface-system-surface-impacts)
    - [Surface Types](#page-ultimate-character-controller-surface-system-surface-types)
    - [Surface Effects](#page-ultimate-character-controller-surface-system-surface-effects)
    - [Surface Identifiers](#page-ultimate-character-controller-surface-system-surface-identifiers)
    - [Decal Manager](#page-ultimate-character-controller-surface-system-decal-manager)
    - [Character Foot Effects](#page-ultimate-character-controller-surface-system-character-foot-effects)
    - [Advanced Surface System Topics](#page-ultimate-character-controller-surface-system-advanced-surface-system-topics)
  - [Spawn System](#page-ultimate-character-controller-spawn-system)
    - [Respawner](#page-ultimate-character-controller-spawn-system-respawner)
    - [Spawn Points](#page-ultimate-character-controller-spawn-system-spawn-points)
  - [Audio](#page-ultimate-character-controller-audio)
  - [Programming Concepts](#page-ultimate-character-controller-programming-concepts)
    - [Events](#page-ultimate-character-controller-programming-concepts-events)
      - [Event Names](#page-ultimate-character-controller-programming-concepts-events-event-names)
    - [Scheduler](#page-ultimate-character-controller-programming-concepts-scheduler)
    - [Object Pool](#page-ultimate-character-controller-programming-concepts-object-pool)
  - [Artificial Intelligence (AI)](#page-ultimate-character-controller-artificial-intelligence)
  - [Integrations](#page-ultimate-character-controller-integrations)
    - [A* Pathfinding Project](#page-ultimate-character-controller-integrations-astar-pathfinding-project)
    - [Adventure Creator](#page-ultimate-character-controller-integrations-adventure-creator)
    - [Atlas](#page-ultimate-character-controller-integrations-atlas)
    - [Behavior Designer Pro](#page-ultimate-character-controller-integrations-behavior-designer)
    - [Cinemachine](#page-ultimate-character-controller-integrations-cinemachine)
    - [Control Freak](#page-ultimate-character-controller-integrations-control-freak)
    - [Dialogue System](#page-ultimate-character-controller-integrations-dialogue-system)
    - [Easy Build System](#page-ultimate-character-controller-integrations-easy-build-system)
    - [Edy's Vehicle Physics](#page-ultimate-character-controller-integrations-edys-vehicle-physics)
    - [Feel](#page-ultimate-character-controller-integrations-feel)
    - [Final IK](#page-ultimate-character-controller-integrations-final-ik)
    - [FMOD](#page-ultimate-character-controller-integrations-fmod)
    - [FPS Mesh Tool](#page-ultimate-character-controller-integrations-fps-mesh-tool)
    - [High Definition Render Pipeline](#page-ultimate-character-controller-integrations-high-definition-render-pipeline)
    - [Horse Animset Pro](#page-ultimate-character-controller-integrations-horse-animset-pro)
    - [InControl](#page-ultimate-character-controller-integrations-incontrol)
    - [Juicy Actions](#page-ultimate-character-controller-integrations-juicy-actions)
    - [Master Audio](#page-ultimate-character-controller-integrations-master-audio)
    - [NWH Vehicle Physics](#page-ultimate-character-controller-integrations-nwh-vehicle-physics)
    - [Omni Animation Packs](#page-ultimate-character-controller-integrations-omni-animation-packs)
    - [PlayMaker](#page-ultimate-character-controller-integrations-playmaker)
    - [Quest Machine](#page-ultimate-character-controller-integrations-quest-machine)
    - [RayFire](#page-ultimate-character-controller-integrations-rayfire)
    - [Realistic Car Controller](#page-ultimate-character-controller-integrations-realistic-car-controller)
    - [Realistic Car Controller Pro](#page-ultimate-character-controller-integrations-realistic-car-controller-pro)
    - [Rewired](#page-ultimate-character-controller-integrations-rewired)
    - [State Designer](#page-ultimate-character-controller-integrations-state-designer)
    - [Ultimate Inventory System](#page-ultimate-character-controller-integrations-ultimate-inventory-system)
    - [UMA](#page-ultimate-character-controller-integrations-uma)
    - [Universal Render Pipeline](#page-ultimate-character-controller-integrations-universal-render-pipeline)
  - [Videos](#page-ultimate-character-controller-videos)

---

<a id="page-ultimate-character-controller"></a>

# Ultimate Character Controller

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/)

Ultimate Character Controller provides character locomotion, camera, item, animation, and world-interaction tools for first- and third-person games. This documentation applies to Ultimate Character Controller and the related Opsive controllers that share its structure, including UFPS and Third Person Controller.

Workflow pages lead with the Unity editor setup and finish with the behavior you should observe in Play Mode. Complete the focused Manager or Inspector steps first, then verify the runtime result before adding another system.

## Start here

1. Open [Getting Started](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/), then use [Requirements and First Decisions](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/requirements-and-first-decisions/) to choose the controller edition, perspective, input, render pipeline, and first-scene route.
2. Follow [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) to add the controller and optional sample to the project.
3. Build the [First Playable Character](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-playable-character/) with the sample CharacterContainer before configuring a project model.
4. Use [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) and [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) for the project's own scene.
5. Follow the [First Hour](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-hour/) route to add one feature at a time.

Customer-visible controls are documented with the feature that owns them. For example, [Item Types](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-types/) explains its row icons, [State Presets](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/) explains the States add menu, and [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) explains the mapped ID picker.

Use the [Videos](https://opsive.com/support/documentation/ultimate-character-controller/videos/) alongside these steps when a visual walkthrough is helpful. Existing projects can follow the [Version 3 Migration Guide](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/version-3-migration-guide/); the older version 2 documentation remains available as a [PDF](https://opsive.com/wp-content/uploads/2022/11/Documentation.pdf).

[How UCC Fits Together](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/how-ucc-fits-together/) provides the beginner mental model for scene managers, camera, character locomotion, abilities, animation, items, and world systems. Use [Getting Started Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/troubleshooting/) when the first character does not move, the camera does not attach, rendering is incorrect, animation does not respond, or an item cannot equip.

## Character

- [Character](https://opsive.com/support/documentation/ultimate-character-controller/character/) covers locomotion, movement types, abilities, and the character setup workflows.

## Camera

- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/) covers Camera Controller setup, view types, perspective changes, and character attachment.

## Items and inventory

- [Items & Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/) covers equipping, using, dropping, and managing character items.

## Animation and presentation

- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/) explains Animator integration, parameters, events, and item animation.
- [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) covers post-animation positioning for hands, feet, look direction, and item alignment.
- [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/) covers shared audio playback, Audio Sources, and character or item sounds.

## Objects and world interaction

- [Objects](https://opsive.com/support/documentation/ultimate-character-controller/objects/) routes to damage processing, explosions, pickups, trajectory objects, and object identification.
- [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) explains reliable character movement on elevators, vehicles, and other moving surfaces.
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) covers impact sounds, decals, particles, and surface-specific responses.

## Gameplay systems

- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/) covers values such as health or stamina and how they change over time.
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) covers keyboard, mouse, controller, mobile, and input-system setup.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains presets that change component properties for gameplay states.
- [Spawn System](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/) covers spawn locations, respawning, and scene placement.

## Integrations

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/) routes to supported Opsive and third-party connections.
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/) explains how external AI systems can drive a UCC character.

## Developer topics

- [Component Overview](https://opsive.com/support/documentation/ultimate-character-controller/component-overview/) identifies the main runtime components and their responsibilities.
- [Organization](https://opsive.com/support/documentation/ultimate-character-controller/organization/) explains the shared framework, assembly layout, and controller variants.
- [Programming Concepts](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/) routes to events, object pooling, scheduling, and other code-facing concepts.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) documents the collision and visibility layers required by controller systems.

---

<a id="page-ultimate-character-controller-getting-started"></a>

# Getting Started

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/)

The Getting Started guides take a new project from importing Ultimate Character Controller to running a playable character and camera in a prepared scene. Use this section for a first installation, a sample-based evaluation, or a project-specific first scene.

## Start here

1. Use [Requirements and First Decisions](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/requirements-and-first-decisions/) to choose the controller edition, perspective, render pipeline, input route, and sample or custom-scene path.
2. Read [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) to complete the package and sample import and resolve compiler or package problems before character setup.
3. Build the [First Playable Character](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-playable-character/) with CharacterContainer and verify movement and camera control.
4. Follow [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) when the project's own scene, model, camera, and managers are ready.
5. Read [How UCC Fits Together](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/how-ucc-fits-together/), then follow the [First Hour](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-hour/) path to add one feature at a time.
6. Open the [Demo Scene](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/demo-scene/) when you want to compare a finished ability, item, interaction, surface, or state workflow.

[Editor Options by Feature](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/editor-reference/) is a compact route to those owning guides; it does not duplicate their option descriptions.

## Open managers and optional packages

**Tools > Opsive > Ultimate Character Controller > Main Manager** hosts the same managers exposed by the direct Setup, Character, Item Type, Item, Object, Animation Replacer, Migration, Integrations, and Add-Ons commands. A direct command selects that page in the shared window; it does not create another copy of the project data.

The **Welcome** page opens documentation, videos, support, release, and sample routes without changing gameplay data. **Add-Ons Manager** separates **Installed Add-Ons** from **Available Add-Ons**. An available card's **Overview** and **Asset Store** actions open its information or store route; an installed add-on can expose its own character or Animator setup. Follow the documentation supplied with that add-on before applying its setup to a production prefab. **Atlas** opens the companion Atlas authoring surface and does not add UCC character components by itself.

## Choose a first-scene route

- **Fast evaluation:** Import the sample, then use the Demo Scene or add CharacterContainer to an empty scene. This route provides a configured character, camera, and managers.
- **Project-specific setup:** Use Quick Setup, then continue to [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) for the project's own model, perspective, view type, and scene.

## Verify the first setup

Before entering Play Mode, the scene should have its manager services, a configured Camera Controller, and a character with Ultimate Character Locomotion. In Play Mode, the configured movement and look inputs should control the character and camera without missing-manager errors in the Console.

If that result is not available, return to Quick Setup and verify the selected input route, manager setup, camera perspective, and character build before adding items or other gameplay systems.

Use [Getting Started Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/troubleshooting/) for one ordered diagnostic path across importing, input, managers, camera, character, animation, and items.

## Upgrading from version 2

The [Version 3 Migration Guide](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/version-3-migration-guide/) is only for projects upgrading existing version 2 characters, cameras, and items. New installations should follow Importing and Quick Setup instead of the migration removal and conversion steps.

---

<a id="page-ultimate-character-controller-getting-started-requirements-and-first-decisions"></a>

# Requirements and First Decisions

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/requirements-and-first-decisions/)

Choose the installed controller, perspective, input, render pipeline, and first-scene route before running a manager. These decisions determine which Setup Manager and Character Manager options are available.

## Requirements

- **Unity:** Use Unity 2021.3 or newer for the released Version 3 installer.
- **Clean compilation:** Finish package import and resolve all compiler errors before opening Setup Manager.
- **Sample:** The optional demo requires TextMesh Pro, Universal Render Pipeline 14.0.11 or newer, and the Input System.
- **Project backup:** Back up or commit an existing project before changing layers, input mappings, render-pipeline integrations, Animator Controllers, or generated character hierarchies.

The Installer and [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) provide the authoritative checks for the downloaded package.

## Choose the controller edition

| Installed product | Available perspective | Choose it when |
| --- | --- | --- |
| Ultimate Character Controller | First, Third, or Both | The project may use either perspective or switch between them. |
| Ultimate First Person Shooter | First | The game requires only the first-person controller content. |
| Third Person Controller | Third | The game requires only the third-person controller content. |

Setup Manager cannot offer a perspective that the installed product does not include. Install the matching controller before building the camera or character.

## Choose the first route

| Question | Recommended first choice |
| --- | --- |
| Do you only want to verify that UCC works? | Import the sample and follow [First Playable Character](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-playable-character/). |
| Do you need to explore complete systems? | Open the [Demo Scene](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/demo-scene/). |
| Do you have the final project model and camera requirements? | Follow [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/), then Character Manager. |
| Are you upgrading Version 2 content? | Stop and use the [Version 3 Migration Guide](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/version-3-migration-guide/). |

Do not begin with item creation, Animator customization, integrations, or multiplayer. First prove that one character and camera move together in an otherwise simple scene.

## Choose the character route

| Choice | Beginner guidance |
| --- | --- |
| **Humanoid** | Recommended for the first visible character. It supports the included Animator Controller, Unity IK, and automatic ragdoll setup. |
| **Generic** | Use when the model cannot use Humanoid retargeting and the project already has a compatible Animator Controller. |
| **Bodyless first person** | Use when the game needs no full character model. Disable Animator when no rig is assigned. |
| **Player** | Uses a Player Input implementation and character handlers. Recommended for the first test. |
| **AI Agent** | Removes the player-input route and requires external decision-making. Add it after player locomotion works. |

## Choose input

- Use **Input System** when the project already uses Unity's Input System actions.
- Use the legacy Input Manager only when the project deliberately uses that backend.
- Use Rewired, InControl, or another integration only after importing and configuring its matching UCC integration.
- Do not apply **Update Buttons** to a project that should not receive the default legacy mappings.

## Choose rendering

The active Built-in, URP, or HDRP pipeline must match the imported UCC integration and materials. The sample is a URP reference. A custom Built-in or HDRP project should follow its own project setup instead of copying sample pipeline assets indiscriminately.

![The Setup Manager Project tab exposes the project update action for input mappings, layers, and the active render pipeline.](https://opsive.com/wp-content/uploads/2022/11/CharacterManagerProjectUpdateSetup-1024x816.png)

## Decision checkpoint

Before importing the sample or running a manager, write down:

- installed controller edition;
- First, Third, or Both perspective;
- sample or custom-scene route;
- Input System, legacy, or integration input;
- Built-in, URP, or HDRP;
- humanoid, generic, or bodyless character; and
- player or AI ownership.

Use the same choices in Setup Manager, Character Manager, Camera Controller, and input setup. If those surfaces disagree, return here before troubleshooting individual components.

## Next step

Continue with [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/), then [First Playable Character](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-playable-character/).

---

<a id="page-ultimate-character-controller-getting-started-importing"></a>

# Importing

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/)

Import the controller package and confirm that Unity compiles it cleanly before configuring a character, camera, or scene in Setup Manager. The runtime package is stored under **Packages**; the demo is an optional, separate sample import.

## Before you begin

- Use Unity 2021.3 or newer, as required by the included Version 3 Installer.
- Back up the project before replacing an older controller installation. A project upgrading from version 2 requires the [Version 3 Migration Guide](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/version-3-migration-guide/) and a clean import.
- Close Play Mode and allow Unity to finish any existing compilation before importing.

## Choose the controller package

- **Ultimate Character Controller** supports **First**, **Third**, and **Both** perspectives.
- **Ultimate First Person Shooter** supports the **First** perspective.
- **Third Person Controller** supports the **Third** perspective.

Setup Manager only offers perspectives supplied by the installed package. Choose **Both** later only when both first- and third-person controller content is installed.

## Import the controller package

1. Import the downloaded Opsive asset into the Unity project and wait for its Installer scripts to compile. The **Installer** window should open automatically.
2. If it does not open, select **Tools > Opsive > Ultimate Character Controller > Installer**.
3. Confirm that the Installer marks **Located Install Package** and **Unity 2021.3 or Newer** as satisfied. If **Clean Install** is shown for an older installation, confirm that requirement as well.
4. If a package dropdown is shown, select **Ultimate Character Controller**, **Ultimate First Person Shooter**, or **Third Person Controller** to match the purchased product and required perspective.
5. Select **Install**.
6. In Unity's Import Package window, keep the supplied controller files selected and select **Import**.
7. Wait for Unity to finish importing and compiling before changing project settings.

For an upgrade from version 2, move custom work out of the old **Opsive/UltimateCharacterController** and **Opsive/Shared** folders, make a backup, then remove those old folders before using **Install**.

## Verify the package import

Before opening Setup Manager, confirm that:

- The Project window shows **Opsive Ultimate Character Controller** and **Opsive Shared** under **Packages**.
- The Console contains no compiler errors.
- **Tools > Opsive > Ultimate Character Controller** contains **Setup Manager** and the other controller managers.

If any check fails, resolve it before continuing to [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/). This prevents package or compiler problems from being mistaken for character-setup problems.

## Import the optional sample

The sample provides a configured scene for learning and testing. It is not required for a custom project.

1. Select **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Sample** tab.
3. Select **Import Sample** and wait for the import to finish.

![The Setup Manager Sample tab with the Import Sample control for the Ultimate Character Controller demo.](https://opsive.com/wp-content/uploads/2025/01/UltimateCharacterControllerSampleSceneSetup.png?v=aa9eebddba84)

## Configure the sample requirements

The imported sample requires TextMesh Pro, Universal Render Pipeline 14.0.11 or later, and the Unity Input System.

1. In **Window > Package Manager**, confirm that **TextMesh Pro**, **Universal RP**, and **Input System** are installed.
2. The **Import Sample** action imports the UCC Universal Render Pipeline integration automatically. If it is missing, open **Setup Manager > Project**, select **URP** under **Render Pipeline**, and select **Import**.

![The Setup Manager Project tab showing the Universal Render Pipeline integration ready to import.](https://opsive.com/wp-content/uploads/2022/11/UniversalRenderPipelineImport.png?v=c3bc832acf5e)

3. Assign **DemoUniversalRenderPipelineAsset** as the active render pipeline asset:
   - Before Unity 6, use **Edit > Project Settings > Graphics**.

![The Graphics Project Settings with DemoUniversalRenderPipelineAsset assigned as the Scriptable Render Pipeline asset.](https://opsive.com/wp-content/uploads/2022/11/DemoScriptableRenderPipeline-1024x86.png)

   - In Unity 6, use **Edit > Project Settings > Quality**.

![The Unity 6 Quality Project Settings with DemoUniversalRenderPipelineAsset assigned as the Render Pipeline asset.](https://opsive.com/wp-content/uploads/2022/11/QualityRenderPipelineRenderer-1024x237.png)

4. In **Edit > Project Settings > Player**, set **Active Input Handling** to **Both** or **Input System (New)**.

![The Player Settings with Active Input Handling set to Both for the controller sample.](https://opsive.com/wp-content/uploads/2022/11/BothInputHandlingPlayerSettings-1024x439.png)

## Verify the sample in Play Mode

Open the imported Demo scene after all requirements are satisfied. Enter Play Mode and confirm that the scene renders with the demo materials, responds to its configured movement and look input, and produces no missing-package or render-pipeline errors in the Console.

If the sample works, return to [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) to configure the project's own managers, camera perspective, and character.

## Troubleshoot import problems

- **The Installer cannot locate its install package:** Check that the downloaded **.unitypackage** still exists in **Assets/Opsive/Installer/UltimateCharacterController**. Reimport the purchased asset if that file is missing, then reopen **Tools > Opsive > Ultimate Character Controller > Installer**.
- **The required perspective is unavailable:** Check whether the First Person, Third Person, or combined Ultimate Character Controller package was installed. Install or reimport the product that supplies the required perspective.
- **The sample has incorrect materials or shaders:** Check the active pipeline, the UCC URP integration, and the assigned **DemoUniversalRenderPipelineAsset**. Import or assign the missing requirement, then reopen the Demo scene.
- **The sample does not respond to input:** Check **Active Input Handling** and the Input System package. Set the handling mode to **Both** or **Input System (New)** and restart Unity when prompted.
- **A script in a custom Assembly Definition cannot resolve UCC types:** Check **Assembly Definition References** and add **Opsive.UltimateCharacterController**.
- **Unity reports one-time animation import warnings:** Warnings such as **File 'AimWalkFwd' has animation import warnings** come from the Blender-authored source animations and do not affect playback.

### Namespace collision example

An existing project class in the global namespace can hide a controller type with the same name. For example, this project-defined **Health** class is in the global namespace:

```csharp
using UnityEngine;

public class Health : MonoBehaviour
{
    /// <summary>
    /// Damages the object.
    /// </summary>
    public void Damage()
    {
        // My implementation.
    }
}
```

After importing UCC, that collision can produce an error such as:

> Assets/Opsive/UltimateCharacterController/Demo/Scripts/DamageZone.cs(68,22): error CS1501: No overload for method Damage takes 4 arguments

Check whether the project defines **Health** or another reported type without a namespace. Move the project class into its own namespace:

```csharp
using UnityEngine;

namespace MyProject
{
    public class Health : MonoBehaviour
    {
        /// <summary>
        /// Damages the object.
        /// </summary>
        public void Damage()
        {
            // My implementation.
        }
    }
}
```

Use the same fix for other project classes that collide with controller type names.

## Related tasks

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Demo Scene](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/demo-scene/)
- [Version 3 Migration Guide](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/version-3-migration-guide/)
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)

## Developer reference: Assembly Definitions

Scripts compiled by a custom Assembly Definition must reference **Opsive.UltimateCharacterController** before they can use controller runtime types. Select the project's Assembly Definition, add **Opsive.UltimateCharacterController** to **Assembly Definition References**, and apply the change.

![An Assembly Definition Inspector with Opsive.UltimateCharacterController added to Assembly Definition References.](https://opsive.com/wp-content/uploads/2018/09/UltimateCharacterControllerAssemblyDefinition.png?v=9cf551cc05a2)

---

<a id="page-ultimate-character-controller-getting-started-first-playable-character"></a>

# First Playable Character

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-playable-character/)

Place the sample CharacterContainer in a new scene and verify one working character, camera, input route, and manager set before building a project-specific character.

## Before you begin

- Complete [Requirements and First Decisions](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/requirements-and-first-decisions/) and [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/).
- Import the optional sample and satisfy its TextMesh Pro, URP, and Input System requirements.
- Resolve every Console compiler error.
- Use a new saved scene so the result is easy to isolate.

## Import the sample

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select **Sample**.
3. Select **Import Sample** and wait for Unity to finish importing and compiling.
4. Confirm that the Console has no new package, shader, or compiler errors.

![The Setup Manager Sample tab provides the Import Sample control for the Ultimate Character Controller demo content.](https://opsive.com/wp-content/uploads/2025/01/UltimateCharacterControllerSampleSceneSetup.png?v=aa9eebddba84)

## Add CharacterContainer

1. Create and save an empty scene.
2. Search the Project window for `CharacterContainer` inside the imported sample.
3. Drag the prefab into the scene at the origin.
4. Confirm that the prefab supplies a character, Camera Controller, and scene-level manager objects.
5. Save the scene again.

Do not add a second camera, movement script, Rigidbody controller, or manager set. CharacterContainer is intentionally complete enough for the first test.

## Verify in Play Mode

1. Enter Play Mode.
2. Use the configured movement input and confirm that the character changes position.
3. Use the configured look input and confirm that the camera follows or rotates with the character.
4. Start one standard ability such as Jump when it is available in the imported configuration.
5. Stop input and confirm that the character remains stable rather than drifting, jittering, or falling through the floor.
6. Confirm that the Console contains no missing-manager, Look Source, input, or movement-type errors.

This is the first-success checkpoint. Do not continue to custom models, item creation, or Animator edits until this scene works.

## Recognize the working ownership

- The **Game** or equivalent manager object supplies scene services.
- **Camera Controller** owns camera position and rotation through its active View Type.
- **Ultimate Character Locomotion** owns character movement, collision, Movement Types, Abilities, and Effects.
- The Player Input implementation and locomotion handler translate device input into character commands.
- **Animator Monitor** coordinates UCC runtime values with the model's Animator.

Read [How UCC Fits Together](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/how-ucc-fits-together/) before replacing any of those owners.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| CharacterContainer cannot be found. | Sample import and search scope. | Reimport the sample and search all project assets for the prefab. |
| Materials are pink. | Active render pipeline, URP integration, and sample pipeline asset. | Complete the render-pipeline steps on [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/). |
| The character does not move. | Active Input Handling, Input System package, focused Game view, and Console. | Configure the sample input requirement and restart Unity when requested. |
| The camera does not follow. | Extra camera, disabled Camera Controller, or incorrect character assignment. | Remove the competing camera and restore the prefab's configured controller. |
| The scene reports missing managers. | Duplicate or incomplete prefab contents. | Revert/reimport CharacterContainer in a clean scene. |

Use [Getting Started Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/troubleshooting/) when the first failing owner is not obvious.

## Continue to a project character

Keep this working scene as a comparison. Create another scene, follow [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/), and build the project model with [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/). Compare the custom scene with CharacterContainer whenever movement, camera, or managers diverge.

---

<a id="page-ultimate-character-controller-getting-started-quick-setup"></a>

# Quick Setup

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)

Use this quick setup to prepare a Unity project and scene, then get a controllable Ultimate Character Controller character running in Play Mode.

For the shortest evaluation route, complete [First Playable Character](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-playable-character/) before this project-specific setup. Use [Requirements and First Decisions](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/requirements-and-first-decisions/) when the perspective, input backend, render pipeline, or model route is still undecided.

## Before you begin

- Import the Ultimate Character Controller and wait for Unity to finish compiling without errors.
- Decide whether to prototype with the sample **CharacterContainer** prefab or build a character in your own scene.
- The CharacterContainer route requires the sample package; see [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) for its package requirements.

## Use CharacterContainer for the fastest prototype

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Sample** tab.
3. Select **Import Sample** and wait for the import to finish.
4. In the Project window, search for the **CharacterContainer** prefab and drag it into an empty scene.
5. Save the scene.

CharacterContainer includes a configured character, camera, and scene-level managers, so it is the quickest route for testing the controller before building a project-specific setup. The [CharacterContainer walkthrough](https://www.youtube.com/watch?v=f0CbKm3GC1g) shows this route in use.

## Set up the project settings

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and select the **Project** tab.
2. For a new project that uses the default Input Manager mappings, select the combined setup action shown in the warning:
   - **Update Buttons and Layers** when using the Built-in Render Pipeline.
   - **Update Buttons, Layers, and Render Pipeline** when URP or HDRP is active.
3. For a project that already uses the Input System, custom mappings, or another input integration, use the individual controls instead:
   - Select **Update Layers** under **Layers** if the required layer slots are available.
   - Under **Render Pipeline**, select **URP** or **HDRP** and then select **Import** when that integration is needed.
   - Do not select **Update Buttons** unless the project should receive the default legacy Input Manager mappings.

![The Setup Manager Project tab showing the project update action for button mappings, layers, and the active render pipeline.](https://opsive.com/wp-content/uploads/2022/11/CharacterManagerProjectUpdateSetup-1024x816.png)

The layer update adds the controller's default layer names. Review the [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) first when an existing project already uses those layer indices.

## Set up a custom scene

1. In **Tools > Opsive > Ultimate Character Controller > Setup Manager**, select the **Scene** tab.
2. Under **Manager Setup**, select **Add Managers**. This creates the **Game** GameObject with the required scene-level services, including the Surface Manager and Object Pool.
3. Under **Camera Setup**, choose **Perspective**:
   - **First** for a first-person camera.
   - **Third** for a third-person camera.
   - **Both** when the game can switch perspectives.
4. Choose the corresponding **First Person View Type** or **Third Person View Type**. When Perspective is Both, also choose **Start Perspective**.
5. Select **Setup Camera**.
6. Open **Tools > Opsive > Ultimate Character Controller > Character Manager** and follow [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) to build the playable character.

![The Setup Manager Scene tab showing Manager Setup, Camera Setup, UI Setup, and Virtual Controls Setup.](https://opsive.com/wp-content/uploads/2022/11/CharacterManagerSceneSetup.png?v=7969dfe2d830)

## Key choices

- **Sample or custom scene:** Use CharacterContainer to evaluate or prototype quickly. Use the custom route when the scene, camera, and character must match the project's own assets.
- **Input:** The **Update Buttons** action targets the legacy Input Manager. Skip it when the project already uses the Input System or another integration, and follow the project's [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) setup instead.
- **Perspective:** The selected first- or third-person controller must be imported before that Perspective and View Type can be configured. Use Both only when both perspectives are installed.
- **UI and virtual controls:** **Add UI** and **Add Virtual Controls** are optional. Add them only when the scene needs the supplied monitors or on-screen controls. For virtual controls, choose the matching **Input Type** before adding them.
- **Items:** Finish the character and movement setup before creating item data and prefabs. Items are not required for the first movement test.

## Verify in Play Mode

Before entering Play Mode, confirm that the Hierarchy contains a **Game** GameObject, the camera has a **Camera Controller** component, and the character has an **Ultimate Character Locomotion** component.

Enter Play Mode and use the configured movement and look inputs. The character should move, the camera should follow or rotate using the selected View Type, and the Console should not report missing scene managers. A CharacterContainer instance should provide the same result without additional scene setup.

## Troubleshoot setup problems

- **CharacterContainer is not available:** Check whether the sample was imported. Open **Setup Manager > Sample** and select **Import Sample**, then search for the prefab again.
- **The camera setup reports that a perspective is unavailable:** Check which first- or third-person controller is installed. Import the required controller or choose an installed Perspective, then select **Setup Camera** again.
- **The character does not respond to input:** Check whether the project uses the Input System, legacy Input Manager, or another integration. Configure the matching Player Input implementation and mappings instead of applying settings for a different input route.
- **The scene reports missing manager components:** Check for the **Game** GameObject. Open **Setup Manager > Scene** and select **Add Managers** to create or complete it.
- **URP or HDRP materials or shaders are incorrect:** Check the active render pipeline and its controller integration. On **Setup Manager > Project**, select the matching **Render Pipeline** and select **Import**.

## Related tasks

- [Requirements and First Decisions](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/requirements-and-first-decisions/)
- [First Playable Character](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-playable-character/)
- [How UCC Fits Together](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/how-ucc-fits-together/)
- [First Hour](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-hour/)
- [Getting Started Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/troubleshooting/)
- [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) covers the sample package and its requirements.
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) builds or updates a project-specific character.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) explains the controller layer assignments.
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) explains player-input implementations and common controls.
- [Item Type Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-types/) creates the item data used by the inventory.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds a character item after the character is working.

---

<a id="page-ultimate-character-controller-getting-started-first-hour"></a>

# Your First Hour with UCC

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-hour/)

Add one UCC capability at a time and keep a known working checkpoint after each step. This route prevents camera, locomotion, animation, health, and item problems from becoming one combined failure.

## 1. Prove movement and camera

Complete [First Playable Character](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/first-playable-character/). The character must move, look, and remain stable with a clean Console before continuing.

For a project model, complete [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) and [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) with only the systems required for movement. Disable Items for the first custom-character test when its data and slots are not ready.

## 2. Test one standard Ability

Use Jump or another standard Ability already added by Character Manager. Confirm its start input, active state, animation, movement, and completion before adding a custom Ability.

![The current UCC Abilities list shows Interact above Die, giving Interact the higher priority.](https://opsive.com/wp-content/uploads/2018/03/AbilityInteractPriority.webp?v=a8d79a8016e3)

If the character moves but the Ability does not start, inspect the active Ability list, input name/start type, blocking Ability, and required ground/object condition.

## 3. Apply health and respawn

Enable Health through Character Manager or confirm the generated Character Attribute Manager, Character Health, and Character Respawner group. Apply a controlled amount of damage, observe the Health Attribute decrease, then test death and respawn separately.

Do not add combat items merely to test health. A simple damage source or project diagnostic is easier to isolate.

## 4. Create one item

After movement, camera, animation, and health work:

1. Create or select one Item Type.
2. Confirm the character has item support, a valid Item Collection, Item Set Rule, and matching slot.
3. Build one simple Character Item through Item Manager.
4. Add it to the starting inventory or collect it through one pickup route.
5. Equip it, use it once, and unequip it.

![The Item Set Manager shows active, enabled, disabled, and invalid runtime Item Sets.](https://opsive.com/wp-content/uploads/2022/10/ItemSetManagerInspectorRuntime.png?v=1c0fa0a829a7)

Use [Item Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-troubleshooting/) before creating a second item when the first does not equip or use.

## 5. Add one world interaction

Add one Interact target, pickup, or moving platform. Verify its trigger/layer setup, Ability start, visible response, and completion. Then add Surface effects or States only when the core interaction works without them.

## First-hour checkpoint

At the end of this route, one scene should prove:

- movement and camera ownership;
- one standard Ability;
- health decrease and recovery or respawn;
- one equipped and usable item; and
- one world interaction.

Keep this scene or prefab version as a regression checkpoint. Add AI, multiple perspectives, inventory integrations, saving, multiplayer, and advanced animation only after the corresponding simple owner is stable.

## Next paths

- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [Items & Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/)
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Multiplayer](https://opsive.com/support/documentation/ultimate-character-controller/multiplayer/)

---

<a id="page-ultimate-character-controller-getting-started-how-ucc-fits-together"></a>

# How UCC Fits Together

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/how-ucc-fits-together/)

Use this mental model to identify which UCC system owns a result before changing components. Managers create the relationships; the runtime components then own distinct responsibilities.

## The beginner model

| Layer | Main owner | Question it answers |
| --- | --- | --- |
| Scene services | Setup Manager and the **Game** manager object | Which shared services exist in this scene? |
| Camera | **Camera Controller** and active View Type | Where should the player see from? |
| Character motor | **Ultimate Character Locomotion** | How does the character move and collide? |
| Temporary behavior | Movement Types, Abilities, Item Abilities, and Effects | Which movement model or temporary action is active? |
| Presentation | Animator, **Animator Monitor**, IK, audio, and surfaces | How is the runtime state presented? |
| Items | Inventory, Item Set Manager, Character Items, Actions, and modules | What is owned, equipped, and used? |
| World response | Objects, impacts, Attributes, Health, spawning, and States | How do characters and objects affect one another? |

Configure the owning layer instead of adding a second system that competes with it.

## Scene services

**Setup Manager > Scene > Add Managers** creates the scene-level services used for surfaces, pooling, scheduling, spawning, audio, states, and simulation. Features can fail even when their character component is correct if the matching scene service is absent.

![The Setup Manager Scene tab exposes Manager Setup, Camera Setup, UI Setup, and Virtual Controls Setup.](https://opsive.com/wp-content/uploads/2022/11/CharacterManagerSceneSetup.png?v=7969dfe2d830)

## Camera and character

The camera does not move the character, and Character Manager does not create the camera. Camera Controller follows the assigned character and uses a View Type for framing and rotation. Ultimate Character Locomotion owns the character motor, colliders, Movement Types, Abilities, and Effects.

![The Camera Controller Inspector lists the available View Types and the active View Type settings.](https://opsive.com/wp-content/uploads/2018/03/CameraControllerViewType.png?v=aa00a146a75e)

The visible model is normally a child of the character root. Animator Monitor bridges runtime values into the Animator Controller. Avoid putting the main movement component on the model child or moving the model separately from the root.

## Abilities and items

Use a Movement Type for the persistent movement model. Use an Ability for temporary character behavior such as jumping, interacting, falling, or changing height. Use an Effect for presentation that can run alongside locomotion.

![The current UCC Abilities list shows Die above Interact so death has the higher priority.](https://opsive.com/wp-content/uploads/2018/03/AbilityDiePriority.webp?v=897de8276547)

Items add another ownership chain: Inventory owns counts, Item Set Manager chooses equipped sets, Character Item is the character-side object, an Item Ability receives input, and the selected Character Item Action modules perform use, impact, reload, or other behavior.

![The Inventory and Item Set Manager Inspectors show a configured loadout and Item Set groups.](https://opsive.com/wp-content/uploads/2022/10/InventoryAndItemSetManagerInspector.png?v=7b4b4b8c12de)

## Configure through managers first

Use Setup Manager for project, scene, camera, and sample setup. Use Character Manager for character structure and optional component groups. Use Item Type and Item Managers for item data and prefabs. Use Object Manager for world objects.

Inspect individual components after the manager has created a valid baseline. Hand-adding one component rarely creates its required companion objects, abilities, lists, layers, or references.

## Verify ownership in Play Mode

1. Select the character root and confirm the intended Movement Type is active.
2. Select the camera and confirm the intended View Type and Character.
3. Start one Ability and watch its active state and animation.
4. Equip one item and trace Inventory → Item Set → Character Item → Action.
5. Trigger one world response and identify the Attribute, impact, surface, or state owner.

Use the full [Component Overview](https://opsive.com/support/documentation/ultimate-character-controller/component-overview/) when you need exact component names and developer APIs.

## Related pages

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Component Overview](https://opsive.com/support/documentation/ultimate-character-controller/component-overview/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Items & Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

---

<a id="page-ultimate-character-controller-getting-started-demo-scene"></a>

# Demo Scene

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/demo-scene/)

The Demo Scene is a playable tour of Ultimate Character Controller's movement, abilities, items, interactions, surfaces, and state-driven changes. Use it to study a working setup in Play Mode before recreating a feature in your own scene.

The demo uses the Universal Render Pipeline and is imported separately from the main package. Complete [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/), including the sample requirements, before opening it.

## Open the demo

1. From Unity's main menu, select **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Sample** tab, then select **Import Sample**.
3. In the Project window, locate the imported **Demo** sample and open the **Demo** scene.
4. Enter Play Mode. On the opening menu, choose a starting perspective when that choice is available, then select a demo zone.

The selected zone displays a description and the relevant keyboard or controller mapping. Use that information as the source of truth for the controls while exploring.

## Follow a learning route

1. Start with **Locomotion**, then visit the first-person or third-person movement-type zone available to your controller. Compare how the same character responds as the movement style changes.
2. Continue to **Interact** to try the door, chest, and button examples. Then visit **Shooter**, **Melee**, or **Throwable** to see how character abilities and the modular item system work together.
3. Visit **Dynamic Gravity** and **Moving Platforms** to observe how the controller stays oriented and grounded when the environment changes.
4. Finish with **Effects**, **Die & Revive**, and **States**. Watch for visible changes caused by effects, death and recovery, and runtime state presets.

This route moves from the core motor to abilities and items, then to environmental and state-driven behavior. You can return to the zone menu at any time by pressing **Escape**.

## Start directly in free roam

Use Free Roam when you want to begin at a fixed point instead of choosing a zone from the opening menu.

1. Exit Play Mode and select the GameObject with the **Demo Manager** component in the Hierarchy.
2. In the Inspector, expand **Free Roam** and enable **Free Roam**.
3. Assign **Free Roam Spawn Location** to the Transform where the character should begin.
4. Enter Play Mode again. The character should spawn at that Transform and the surrounding demo zone should become active.

![Demo Manager Inspector with Free Roam enabled and a Free Roam Spawn Location assigned](https://opsive.com/wp-content/uploads/2018/09/FreeRoamDemoManager.png?v=922ba7c889f5)

## Verify in Play Mode

With Free Roam disabled, the zone-selection menu should appear before the character begins exploring. After you select a zone, the character and camera should become active, and the zone's title, description, and control mapping should match the feature in front of the character.

Move into another zone and confirm that its guidance replaces the previous zone's guidance. Press **Escape** and confirm that the zone menu opens again. With Free Roam enabled, confirm instead that the menu is skipped and the character starts at **Free Roam Spawn Location**.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The scene has pink materials or incorrect rendering. | The demo's Universal Render Pipeline requirements are incomplete. | Follow the render-pipeline integration and pipeline-asset steps on [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/). |
| The demo sample is missing or the project has compile errors. | The sample import or one of its required packages did not complete. | Return to **Setup Manager > Sample**, import the sample, and resolve the Console errors before entering Play Mode. |
| The opening zone menu does not appear. | **Free Roam** may be enabled on the Demo Manager. | Disable **Free Roam** when you want to choose a zone at startup. |
| The character does not respond to the displayed controls. | The project's **Active Input Handling** setting may not meet the sample requirement. | Use the input setting listed on [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/), restart the editor if Unity requests it, and enter Play Mode again. |

## Related tasks

- [Import the package and demo sample](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/)
- [Build a first playable scene](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Create a project character](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)

---

<a id="page-ultimate-character-controller-getting-started-troubleshooting"></a>

# Getting Started Troubleshooting

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/troubleshooting/)

Diagnose a first UCC scene in ownership order: package, project settings, scene services, camera, character motor, animation, then items. Stop at the first failed layer instead of changing later systems.

## 1. Package and Console

Confirm that the UCC and Shared packages appear under Packages, Unity finished compiling, and the Console has no compiler errors. A missing type, namespace collision, or Assembly Definition reference can prevent managers and runtime components from loading correctly.

Return to [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) for Installer, package, sample, namespace, and Assembly Definition problems.

## 2. Project settings

Confirm the intended UCC layers, input backend, active render pipeline, and matching integration. Do not apply legacy button mappings to a project that is intended to use only the Input System or another integration.

![The Setup Manager Project tab shows the combined project update and render-pipeline controls.](https://opsive.com/wp-content/uploads/2022/11/CharacterManagerProjectUpdateSetup-1024x816.png)

## 3. Scene services

Confirm that the scene contains the **Game** manager object produced by **Setup Manager > Scene > Add Managers**. Remove duplicate manager sets created by combining complete prefabs or additive scenes without a single ownership plan.

## 4. Camera

Confirm that Camera Controller is enabled, references the intended Character, and has an active View Type supplied by the installed perspective. Remove any competing camera movement script from the same camera.

## 5. Character motor and input

On the character root, confirm:

- Ultimate Character Locomotion is enabled;
- a compatible Movement Type is active;
- the generated Rigidbody is kinematic and does not use Unity gravity;
- the collider hierarchy exists;
- a player character has the intended Player Input implementation and locomotion handler; and
- an AI character is not expected to respond to player input.

## 6. Animation

Confirm that the visible model has a valid Avatar, Animator Controller, and Animator Monitor. Inspect Animator parameters while moving. A generic rig needs its project-specific controller; humanoid-only IK, retargeting, and automatic ragdoll steps do not apply to it.

## 7. Items

Trace the first item through:

1. Inventory amount.
2. Item Set Manager group and generated Item Set status.
3. Matching slot ID and Character Item.
4. Equip/Unequip and Use Item Abilities.
5. Character Item Action and its active modules.

![The runtime Inventory shows an active Character Item and owned ammunition counts.](https://opsive.com/wp-content/uploads/2022/10/InventoryAtRuntime_edited.png?v=e099815b708f)

![The runtime Item Set Manager shows active, enabled, and invalid sets for diagnosis.](https://opsive.com/wp-content/uploads/2022/10/ItemSetManagerAtRuntime.png?v=f3f02215df7f)

## Symptom guide

| Symptom | Check | Fix |
| --- | --- | --- |
| UCC menus are missing. | Package compilation and Installer completion. | Resolve Console errors and reinstall the matching package. |
| Character does not move. | Input backend, focused Game view, player/AI route, active Movement Type, and handlers. | Configure one matching input route and rebuild/update the character through Character Manager. |
| Character jitters or moves twice. | Competing motor, dynamic Rigidbody, Unity gravity, or root-motion ownership. | Keep Ultimate Character Locomotion as the motor and remove the competing path. |
| Camera does not follow. | Camera Controller Character, Init Character On Awake, Player tag, View Type, and extra camera scripts. | Assign the character or rerun Camera Setup with the correct perspective. |
| Character falls through the scene. | Generated collider, ground collider, layers, and collision matrix. | Restore the UCC collider/layer setup and a supported ground collider. |
| Model stays in a T-pose. | Avatar, Model Type, Animator Controller, and Animator Monitor. | Correct the rig and update the character through Character Manager. |
| Jump or another Ability does not start. | Ability enabled state, input/start type, priority, blockers, and required conditions. | Inspect the Ability list and correct the first failed start condition. |
| Item is owned but not equipped. | Item Set group/rule, slot ID, active/valid set status, and Equip/Unequip. | Fix the first invalid Item Set or slot mismatch before editing animations. |
| Item equips but does not use. | Use Item Ability Slot/Action ID and the Character Item Action modules. | Match the ability to the equipped action and verify its start/completion events. |
| Materials are pink. | Active pipeline, UCC integration, and material conversion. | Import/configure the matching render-pipeline integration. |

## Compare with a known working scene

Open the untouched CharacterContainer or Demo scene and reproduce the same input or feature. Compare one ownership layer at a time—managers, camera, character, animation, then item—rather than copying the complete hierarchy into the broken scene.

## Related pages

- [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [How UCC Fits Together](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/how-ucc-fits-together/)
- [Component Overview](https://opsive.com/support/documentation/ultimate-character-controller/component-overview/)
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Item Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-troubleshooting/)

---

<a id="page-ultimate-character-controller-getting-started-editor-reference"></a>

# Editor Options by Feature

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/editor-reference/)

Ultimate Character Controller documents each customer-visible editor option with the feature that owns it. Use this page only to find the correct guide.

## Find the owning page

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) covers every Setup Manager tab and project, scene, camera, UI, virtual-control, and sample action.
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) covers Character Manager build, update, template, perspective, model, and optional-system choices.
- [Item Type Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-types/) covers Item Collection creation and Category or Item Type row controls.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) covers Item Manager build/update choices, action types, and Action Templates.
- [Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/) covers module add menus, rows, IDs, ordering, States, and bindings.
- [Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) covers its module diagnostics and Debug foldout.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) and [State Presets](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/) cover State-name mapping, State rows, preset creation, priority, activation, and persistence.
- [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) covers NameIDMap creation, mapped ID pickers, sorting, model roles, and lookup behavior.
- [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/), [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/), [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/), and [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) cover their respective managers and project assets.

Component-specific Inspector fields remain on the owning component or workflow page.

---

<a id="page-ultimate-character-controller-getting-started-version-3-migration-guide"></a>

# Version 3 Migration Guide

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/version-3-migration-guide/)

This guide is for projects migrating Ultimate Character Controller version 2 characters, cameras, items, scenes, or custom code to version 3. It is not needed for a new version 3 installation or a version 3 point update. Version 3 requires Unity 2021.3.0 or later.

Version 3 cannot be imported over version 2. Work on a recoverable copy of the project and complete the steps in order.

## Prepare the project

1. Create a full project backup or source-control checkpoint and confirm that you can restore it.
2. Check `Assets/Opsive` for project-owned scripts, presets, materials, animations, or other unique files. Move copies of those files outside `Assets/Opsive` before removing the folder.
3. Record the version 2 **Motor Acceleration** and **Motor Damping** values for each character, plus the behavior of every item action that must be rebuilt.
4. Note which scenes and prefabs contain version 2 characters, cameras, and items so each one can be verified after migration.

Do not continue until the backup contains both the project and any unique content that was stored under `Assets/Opsive`.

## Choose the relevant migration path

- **Characters and cameras using standard version 2 components:** The Migration Manager can replace the legacy components after the project compiles.
- **Custom abilities or impact listeners:** Update the changed APIs before opening the Migration Manager.
- **Items or custom item-action subclasses:** Expect manual work. Version 3's modular item system cannot reproduce the old action behavior automatically.
- **Prefab-based characters:** The Migration Manager accepts a scene object, not a prefab asset. Migrate a scene instance; character migration may unpack that instance, so create a new version 3 prefab deliberately after verification.
- **Projects with add-ons or integrations:** Migrate and verify the core controller first, then install versions of each add-on or integration that support your installed version 3 package.

## Migration order

1. Remove the version 2 `Assets/Opsive` folder.
2. Remove the version 2 character-controller scripting defines.
3. Import and install version 3.
4. Resolve all compiler errors in project code.
5. Migrate each character, camera, and item scene object.
6. Rebuild modular item behavior and retune character movement.
7. Update the scene managers and remove only the expected missing scripts.
8. Verify the migrated scene in Play Mode before replacing the version 2 project or prefabs.

## Remove version 2

After preserving any unique content, remove the version 2 `Assets/Opsive` folder. The package has too many file changes for version 3 to be imported on top of it.

In **Edit > Project Settings > Player**, open **Other Settings** and remove these values from **Scripting Define Symbols** for every build target that contains them:

```text
FIRST_PERSON_CONTROLLER
THIRD_PERSON_CONTROLLER
FIRST_PERSON_MELEE
FIRST_PERSON_SHOOTER
THIRD_PERSON_MELEE
THIRD_PERSON_SHOOTER
ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
ULTIMATE_CHARACTER_CONTROLLER_VR
```

![Player Settings with the version 2 character-controller scripting define symbols selected for removal](https://opsive.com/wp-content/uploads/2022/10/Version2PlatformDefines.png?v=13f51096c1e1)

Version 3 adds the appropriate controller defines after installation. Leaving the old symbols in place can make removed version 2 code paths compile before the new package is ready.

## Install version 3

Import version 3 from the same source used for the purchased package and allow Unity to finish compiling. Follow the current [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) requirements when the package or sample needs additional Unity packages.

Some version 3 distributions open the **Version 3 Installer** after import. When that window appears, satisfy its listed requirements and select **Install**. Older distributions also expose it at **Tools > Opsive > Ultimate Character Controller > Installer**. If the installed package does not include that menu, continue when compilation finishes and **Tools > Opsive > Ultimate Character Controller > Main Manager** is available.

![Version 3 Installer ready to install Ultimate Character Controller](https://opsive.com/wp-content/uploads/2022/10/Version3Installer.png?v=c9e2e2ed435f)

Do not migrate scene objects while the Console still contains compiler errors.

## Update custom code

Resolve project-code errors before using the Migration Manager. The following version 2 extension points require the most common changes.

### Ability movement and rotation

Version 2 abilities could move the character with **Motor Throttle**, **Move Direction**, or **Ability Motor**. In version 3, set `DesiredMovement` instead:

```csharp
m_CharacterLocomotion.DesiredMovement = m_Rigidbody.TransformDirection(moveDirection);
```

Set `DesiredRotation` when an ability controls rotation:

```csharp
m_CharacterLocomotion.DesiredRotation = targetRotation * Quaternion.Inverse(m_Rigidbody.rotation);
```

These examples use the Rigidbody position and rotation rather than the Transform values because version 3 moves the character with `Rigidbody.MovePosition` and `Rigidbody.MoveRotation`. Transform values may not be current when `Physics.autoSyncTransforms` is disabled.

### Ability animator updates

`Ability.UpdateAnimator` is deprecated in version 3. Move custom animator-parameter changes into `Ability.Update`.

### Modular items

Version 3 replaces the version 2 Shootable Weapon, Melee Weapon, and other item-action implementations with modular item actions. A migrated item receives equivalent version 3 components where possible, but its previous action behavior must be recreated with [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) and [Action Modules and Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/).

### OnObjectImpact listeners

`OnObjectImpact` now sends one `ImpactCallbackContext` instead of a separate argument for each value. A version 3 listener can register and unregister like this:

```csharp
using UnityEngine;
using Opsive.Shared.Events;
using Opsive.UltimateCharacterController.Items.Actions.Impact;

public class MyObject : MonoBehaviour
{
    /// <summary>
    /// Initialize the default values.
    /// </summary>
    public void Awake()
    {
        EventHandler.RegisterEvent<ImpactCallbackContext>(gameObject, "OnObjectImpact", OnImpact);
    }

    /// <summary>
    /// The object has been impacted by another object.
    /// </summary>
    /// <param name="ctx">The context of the impact.</param>
    private void OnImpact(ImpactCallbackContext ctx)
    {
        Debug.Log("Event received " + name + " impacted by " + ctx.ImpactCollisionData.SourceGameObject + " on collider " + ctx.ImpactCollisionData.ImpactCollider + ".");
    }

    /// <summary>
    /// The GameObject has been destroyed.
    /// </summary>
    public void OnDestroy()
    {
        EventHandler.UnregisterEvent<ImpactCallbackContext>(gameObject, "OnObjectImpact", OnImpact);
    }
}
```

## Migrate characters, cameras, and items

1. Open a scene containing one version 2 object to migrate.
2. Select **Tools > Opsive > Ultimate Character Controller > Main Manager**.
3. Select the **Migration** manager.
4. In **Object Migration**, assign the scene object to **Object**.
5. Select **Migrate Object** and wait for the Console confirmation.
6. Repeat for every version 2 character, camera, and item in the project.

![Migration Manager Object Migration section with a version 2 object ready to migrate](https://opsive.com/wp-content/uploads/2022/10/MigrationManager.png?v=f93cb0b76b63)

The **Migrate Object** button remains disabled when **Object** is empty, points to a prefab asset, or does not contain a recognized version 2 character, camera, or item component. Items still require their version 2 action behavior to be rebuilt with modules after the component migration.

## Retune the migrated content

The version 3 locomotion algorithm changed. Use these conversions only as starting points for a similar response:

- Multiply the version 2 **Motor Acceleration** value by `17.7`.
- Multiply the version 2 **Motor Damping** value by `20`.

Test acceleration, stopping distance, airborne movement, and each movement type, then tune the results for the project rather than treating the converted values as final.

For every item, recreate its action modules and confirm its equip, use, impact, ammo, and unequip behavior as applicable. Custom version 2 item-action subclasses do not migrate automatically.

## Update the scene

Open each migrated scene and inspect missing components before removing them. The expected version 2 leftovers are:

- One missing **Kinematic Object Manager** script on the **Game** GameObject because that manager was removed in version 3.
- Missing version 2 **Aim Assist** components on the camera because those camera components were removed.

Investigate any other missing script instead of assuming it is safe to delete. Then open **Tools > Opsive > Ultimate Character Controller > Setup Manager**, select the **Scene** tab, and use **Add Managers** as described in [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/).

Save the migrated scene under a temporary name until its Play Mode checks pass.

## Verify in Play Mode

1. Confirm that the Console has no compiler errors and no unexpected missing-script messages.
2. Confirm that each migrated character has **Ultimate Character Locomotion**, each migrated camera has **Camera Controller**, and the scene contains the required managers.
3. Enter Play Mode and test movement, look input, perspective changes, jumps, abilities, animation parameters, death and respawn, and any project-specific interactions.
4. Equip and use every migrated item. Confirm each manually rebuilt action and impact response rather than checking only that the item appears.
5. Test add-ons and integrations only after the core character, camera, and items work.
6. Create replacement version 3 prefabs from verified migrated scene objects, then repeat the Play Mode check in a clean scene.

The migration is complete only when the version 3 scene reproduces the required project behavior without relying on a missing component or a version 2 package file.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Version 3 produces compiler errors immediately after import. | A version 2 scripting define or custom script may still reference a removed API. | Remove the listed version 2 defines, update the custom-code areas above, and do not run object migration until the Console compiles cleanly. |
| **Migrate Object** is disabled. | **Object** may be empty, a prefab asset, or an object without a supported legacy component. | Put the version 2 character, camera, or item in a scene and assign its root GameObject to **Object**. |
| A migrated item appears but no longer performs its action. | Component migration does not rebuild version 2 item-action behavior. | Recreate the behavior with Item Actions and Action Modules, then verify every use path in Play Mode. |
| Character acceleration or stopping feels different. | The version 3 locomotion algorithm uses different tuning. | Start with the conversion factors above, then tune against the project's expected movement and stopping distance. |
| A migrated character prefab instance is unpacked. | Character migration reorganizes the model and related child objects. | Keep the original version 2 prefab in the backup and create a new version 3 prefab from the verified migrated scene object. |
| Unexpected missing scripts remain. | They may belong to project code, an add-on, or an integration rather than the removed version 2 managers. | Restore or install the compatible dependency and investigate the component before removing it. |

## Related documentation

- [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Create a new ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)
- [Action Modules and Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)

---

<a id="page-ultimate-character-controller-organization"></a>

# Organization

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/organization/)

Organize Ultimate Character Controller content so package updates can replace Opsive-owned files without replacing the characters, items, controllers, presets, or scripts owned by the game. Treat the installed packages and imported sample as sources; keep production customization in a project-owned folder under `Assets`.

## Know who owns each location

| Location | Owner and purpose | Editing guidance |
| --- | --- | --- |
| `Packages/com.opsive.ultimatecharactercontroller` | The released Version 3 runtime, editor tools, integrations, materials, shaders, and sample source. | Treat as Opsive-owned even when the embedded package is editable. A package update can replace direct changes. |
| `Packages/com.opsive.shared` | The required Opsive Shared runtime and editor dependency. | Keep its version compatible with the installed controller and do not store game code here. |
| `Assets/Samples/Opsive Ultimate Character Controller/<version>/Demo` | The optional demo imported through Setup Manager. | Use it as a working reference. Reimporting the sample uses an overwrite operation, so copy anything that will become production content. |
| `Assets/Opsive/UltimateCharacterController/Integrations/...` | Files imported by a render-pipeline or other packaged integration. | Treat these as integration-owned. Put modified materials, shaders, or derived assets in the game folder. |
| `Assets/Opsive/ImportStatus.asset` | A generated record used to remember whether Opsive startup and project-settings windows have been shown. | It is not gameplay data. Choose one version-control policy for the team; deleting it lets the tools recreate it and may show setup again. |
| `Assets/<ProjectName>/...` | Characters, items, object prefabs, Animator Controllers, data assets, presets, scenes, and scripts created for the game. | This is the normal location for editable, version-controlled work. |

The installed package can safely remain a dependency of project-owned assets. Separation does not require copying every runtime script, animation, material, or icon; it means that files you intend to edit have a project-owned location.

## Create a project-owned layout

Use names that fit the game and team. A compact starting layout is:

```text
Assets/<ProjectName>/
  Characters/
    Animators/
    Prefabs/
  Items/
    Data/
    Animators/
    Prefabs/
  Objects/
    Prefabs/
  Presets/
  Scenes/
  Scripts/
    Runtime/
    Editor/
```

Keep an asset with the system that owns its behavior. For example, a character Animator Controller belongs with character animation, an Item Collection belongs with item data, and an explosion prefab belongs with gameplay objects. A project does not need to copy the package's internal `Runtime` and `Editor` folder structure.

## Save each asset with the correct owner

### Characters and character prefabs

1. Put the character model in a scene.
2. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
3. Assign the scene object to **Character**, configure it, and select **Build Character** or **Update Character**.
4. Verify the scene instance in Play Mode.
5. Save the verified result as a prefab under `Assets/<ProjectName>/Characters/Prefabs`, or deliberately apply the verified changes to an existing project-owned character prefab.

Character Manager cannot add components directly to a prefab asset. It works on a scene object and may modify the connected prefab when structural updates are applied, so create a version-control checkpoint before a substantial **Update Character** operation and review the resulting prefab changes.

### Item data and prefabs

1. Open **Tools > Opsive > Ultimate Character Controller > Item Type Manager**.
2. Beside **Item Collection**, select **Create** and save the new collection in the project's item-data folder. This also creates an Individual Item Set Rule beside the collection.
3. Use that project Item Collection instead of adding production definitions to `DemoItemCollection`.
4. Open **Tools > Opsive > Ultimate Character Controller > Item Manager** to build a Character Item.
5. When building an item prefab, save it under the project's item-prefab folder. When building directly on a character, the character scene or prefab owns that item hierarchy.

Use prefab variants for project-owned visual models when changes to the source model should flow into several pickup or equipped-item prefabs. Avoid making production prefabs variants of disposable demo prefabs unless receiving future demo changes is an intentional choice.

### Gameplay object prefabs

Open **Tools > Opsive > Ultimate Character Controller > Object Manager**, choose the supported **Object Type**, and select **Build Object**. The **Save Object** dialog starts under `Assets`; choose the project's object-prefab folder. Continue with the [Objects](https://opsive.com/support/documentation/ultimate-character-controller/objects/) documentation because the generated prefab is a configured starting point, not a complete project-specific behavior.

### Animator Controllers and animation replacements

The supplied `Demo.controller` is a working reference and the default humanoid controller found by Character Manager. Duplicate it into the project's character Animator folder before changing states, transitions, clips, layers, masks, or parameters.

Assign the project copy in Character Manager's **Animator Controller** field. **Tools > Opsive > Ultimate Character Controller > Animation Replacer** changes the selected controller in place, so confirm that **Animator Controller** points to the project copy before selecting **Replace**. Follow [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) for the clip and animation-event workflow.

### Presets and other ScriptableObjects

Store State System presets, audio configurations, damage processors, surface data, item rules, and other project-authored ScriptableObjects under the relevant project folder. A reference to a package type is expected; the editable `.asset` file itself should not be saved inside an Opsive package or imported sample.

## Use an upgrade-safe workflow

1. Commit or back up the entire working project before changing the controller version.
2. Confirm that no unique game asset exists only under `Packages/com.opsive.*`, `Assets/Samples/.../Demo`, or an imported Opsive integration folder.
3. Record the currently installed Ultimate Character Controller and Opsive Shared versions.
4. Update both packages through the team's licensed installation process and let Unity finish compiling.
5. Reimport only the sample or integrations the project actually uses.
6. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and review the **Project** tab before applying layer, input, or render-pipeline changes.
7. Inspect the version-control diff before saving unrelated scenes or prefabs.
8. Verify one representative character, camera, item, pickup, projectile, and project-specific extension in Play Mode before accepting the update.

For a version 2 project, follow the [Version 3 Migration Guide](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/version-3-migration-guide/) instead of treating the change as a normal package update.

## Coordinate work in a team

- Commit project-owned assets together with their `.meta` files so Unity GUID references remain stable.
- Commit the relevant `ProjectSettings`, `Packages/manifest.json`, and `Packages/packages-lock.json` changes. Ensure every workstation obtains the same licensed embedded Opsive package versions; do not rely on one developer's `Library` cache.
- An embedded install is recorded as a local `file:com.opsive...` package; the manifest and lock file do not download that folder for another workstation. Use one private, license-compliant process to supply both Opsive package directories to every checkout.
- Commit imported sample or integration files only when production assets reference them. Otherwise, make their import a documented setup step.
- Keep `Library`, `Temp`, and generated IDE solution/project files out of source control.
- Assign one person at a time to edit large shared assets such as an Animator Controller, Item Collection, Item Set Rule, character prefab, or primary scene. These serialized assets are harder to merge safely than separate prefabs or data assets.
- Review manager operations as asset changes. **Build Item**, **Build Object**, **Update Character**, **Replace**, and project setup actions can change more than the currently visible Inspector.

## Verify the organization

1. In the Project window, confirm that `Packages` contains the controller code and the game's editable content is under its own `Assets` folder.
2. Select each production character and item. Confirm that its prefab, Animator Controller, Item Collection, Item Set Rule, presets, and custom scripts point to the intended project-owned assets.
3. Search the project-owned folder for missing scripts and broken object references.
4. Open a clean test scene, instantiate the project-owned character and a representative item or object, and verify them in Play Mode.
5. Test a clean checkout on another workstation or build agent. It should restore the same package versions, compile without manual file copying, and load the required assets with stable references.
6. Before an upgrade is merged, confirm that expected changes are limited to package, integration, project-settings, and intentional project-asset diffs.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| A customization disappeared after a package update or sample import. | The edited file was under `Packages`, the imported demo, or an integration folder. | Restore the change from version control, copy or recreate it under the project folder, and point production references to that project-owned asset. |
| Character Manager rejects the selected character. | **Character** references a prefab asset instead of a scene instance. | Place the model or prefab in a scene, build or update that instance, verify it, then save or apply the project prefab deliberately. |
| Animation Replacer changed the demo controller. | **Animator Controller** pointed to the supplied controller instead of a project copy. | Revert or reimport the demo asset, duplicate the controller into the project folder, assign the copy, and repeat the replacement. |
| Item Type Manager or Character Manager selects demo item data. | The last-used or scene Item Collection was not the project's collection, so the manager found the demo fallback. | Select the project Item Collection and matching Item Set Rule before building or updating the character's item support. |
| A teammate sees missing scripts or package types. | Their project does not contain the same Ultimate Character Controller and Opsive Shared versions, or a custom Assembly Definition lacks its UCC reference. | Restore the agreed package versions and add **Opsive.UltimateCharacterController** under **Assembly Definition References**. |
| A teammate sees the startup setup window on every clean checkout. | `Assets/Opsive/ImportStatus.asset` is absent or recreated locally. | Either commit the shared import-status asset and its `.meta` file or accept the prompt as part of the team's documented setup policy. |
| A prefab, Item Collection, or controller has a difficult merge conflict. | Multiple branches edited the same serialized asset. | Restore each branch from source control, choose an owner for the shared asset, reapply the second change in Unity, and split future work into smaller owned assets where practical. |

## Related tasks

- [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Items & Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Objects](https://opsive.com/support/documentation/ultimate-character-controller/objects/)
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/)
- [Version 3 Migration Guide](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/version-3-migration-guide/)

## Developer reference

Custom runtime scripts compiled by an Assembly Definition should reference **Opsive.UltimateCharacterController**. Put custom editor-only scripts in an Editor folder or editor assembly and keep both assemblies under the project-owned script folder. Prefer subclasses, components, modules, and documented events over direct edits to package source. When a vendor-source patch is unavoidable, keep it as an explicit, reviewable patch or private fork that can be reapplied and tested against each update.

If package source is missing from the IDE project, open **Edit > Preferences > External Tools**. Under **Generate .csproj files for**, enable **Embedded packages** and **Local packages** as appropriate, then select **Regenerate project files**.

![Unity External Tools preferences with Embedded packages and Local packages enabled and Regenerate project files highlighted.](https://opsive.com/wp-content/uploads/2018/03/RegenerateProjectFiles.png?v=8063be781cf2)

Version 3's managers use different ownership models: Item Type Manager creates the Item Collection and its initial Individual Item Set Rule at the chosen `Assets` location; Item Manager and Object Manager save new prefabs at a chosen `Assets` location; Character Manager modifies a scene instance; and Animation Replacer modifies the selected Animator Controller asset in place. Check the selected source and destination before running each action.

---

<a id="page-ultimate-character-controller-component-overview"></a>

# Component Overview

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/component-overview/)

Use this overview to identify which Ultimate Character Controller component owns a behavior before changing the Inspector or writing custom code.

UCC separates the character motor, control source, camera, animation, items, traits, and scene services. Most projects should let the supplied managers build these relationships instead of adding individual components by hand.

## Build the component structure

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. On the **Project** tab, configure the required layers and the input or render-pipeline settings used by the project.
3. On the **Scene** tab, select **Add Managers** under **Manager Setup**.
4. Under **Camera Setup**, choose the **Perspective** and matching View Type, then select **Setup Camera**.
5. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
6. Assign the **Character**, choose its **Perspective** and movement type, and assign an Animator Controller when the character uses animation.
7. Enable only the optional groups the character needs: **Standard Abilities**, **AI Agent**, **NavMeshAgent**, **Items**, **Health**, **Unity IK**, **Foot Effects**, and **Ragdoll**.
8. Select **Build Character** for a new character or **Update Character** for an existing one.

The Character Manager configures component dependencies, the kinematic Rigidbody, collider hierarchy, layers, input route, abilities, and model-level components together. Use the Inspector afterward to tune the generated setup.

## Understand the component groups

| Area | Main components | Responsibility and relationship |
| --- | --- | --- |
| Scene services | **Surface Manager**, **Decal Manager**, **Simulation Manager**, **Object Pool**, **Scheduler**, **Audio Manager**, **Spawn Point Manager**, **State Manager**, and **Layer Manager** | **Add Managers** places these services on the scene's **Game** object. Features use them for simulation, pooling, delayed work, audio, spawning, states, surfaces, and layer setup. |
| Character motor | **Ultimate Character Locomotion**, **Character Layer Manager**, a kinematic **Rigidbody**, and supported colliders | Ultimate Character Locomotion handles movement, collision detection, slopes, stairs, gravity direction, root motion, variable time scale, and moving platforms. It also owns the configured Movement Types, Abilities, Item Abilities, and Effects. |
| Player control | A Player Input implementation, **Ultimate Character Locomotion Handler**, and, when items are enabled, **Item Handler** | The input implementation reads the device. The character handlers translate that input into movement, ability input, and equipped-item movement. |
| AI control | **Local Look Source** plus the chosen AI or navigation integration | An AI character does not use the player input components or Ultimate Character Locomotion Handler. The **NavMeshAgent** option adds the NavMesh Agent Movement ability for Unity navigation; it does not create decision-making AI. |
| Models and animation | Unity **Animator** and **Animator Monitor**; optionally **Model Manager** and **Perspective Monitor** | Animator Monitor is the bridge between UCC runtime values and Animator parameters. Model Manager coordinates multiple character models. Perspective Monitor supports a character that switches between first and third person presentation. |
| Camera | **Camera Controller**, **Camera Controller Handler**, and one or more View Types; optionally **Object Fader** | Camera Controller follows the assigned **Character** and delegates framing and rotation to the active View Type. Camera Controller Handler reads player camera input. Setup Camera adds Object Fader for a third-person-capable camera. |
| Character items | **Inventory**, **Item Set Manager**, **Item Handler**, **Item Placement**, and Item Abilities on Ultimate Character Locomotion | Inventory tracks item identifier amounts. Item Set Manager decides which Character Items can occupy the configured slots and categories. Item Handler is omitted for AI characters. |
| Item behavior | **Character Item**, perspective-item components, and one or more **Character Item Action** components | Character Item identifies and coordinates an equippable object. Shootable Action, Melee Action, Shield Action, and other actions divide their behavior into replaceable module groups. A single Character Item can contain multiple actions. |
| Attributes and health | **Character Attribute Manager**, **Character Health**, and **Character Respawner** | Character Attribute Manager stores values such as Health, Shield, or Stamina. Character Health reads the named health and shield attributes and adds character-specific damage behavior. Character Respawner handles the character lifecycle after death. |
| Character presentation | **Character IK**, **Character Foot Effects**, the Surface System, and the **Ragdoll** ability | Character IK adjusts humanoid limbs and look direction. Character Foot Effects detects steps and asks the Surface System to play the matching audio, decal, or spawned effect. Ragdoll adds its ability and humanoid ragdoll colliders. These features are optional. |

## Choose the right extension point

- To change how directional input becomes motion and rotation, configure or create a **Movement Type**.
- To add a temporary character behavior such as jumping, climbing, interacting, or changing height, configure or create an **Ability**.
- To add lightweight presentation that runs alongside locomotion, use an **Effect**.
- To change camera placement or rotation, use a **View Type** rather than moving the camera directly each frame.
- To change how an equipped weapon or tool works, configure its **Character Item Action** modules.
- To add health, shield, stamina, hunger, or another changing value, use the **Character Attribute Manager** and add Character Health only when damage and death behavior are required.
- To respond to impacts or footsteps, configure the **Surface System** instead of placing one-off audio, decal, and particle logic on every object.

### Example: a player-controlled third-person character

Build the character with a third-person Movement Type, Animator, Standard Abilities, and the player input route. The character root owns Ultimate Character Locomotion, Character Layer Manager, the Rigidbody and colliders, the input handlers, and any optional gameplay groups. The model owns the Animator and Animator Monitor. The scene camera owns Camera Controller, Camera Controller Handler, a third-person View Type, and Object Fader.

### Example: an AI character with a weapon

Enable **AI Agent** and **Items**. The character uses Local Look Source instead of player input and Ultimate Character Locomotion Handler. Inventory and Item Set Manager still determine what the agent owns and can equip, while the AI solution starts movement, abilities, and item actions. Enable **NavMeshAgent** only when Unity navigation should supply locomotion.

## Verify in Play Mode

1. Select the character root. In **Ultimate Character Locomotion**, confirm that the intended **First Person Movement Type** or **Third Person Movement Type** is active and that the configured **Abilities** can start.
2. Move or drive the character. The kinematic Rigidbody should remain controlled by Ultimate Character Locomotion, and the colliders should resolve stairs, slopes, and obstacles without a second movement component competing with it.
3. Select the camera and confirm that **Camera Controller** follows the expected **Character** with the intended View Type.
4. Watch the model's Animator parameters while moving or starting an ability. Animator Monitor should update them and the expected animation should play.
5. Exercise each optional group that was enabled: equip an item, apply damage, trigger a footstep, or switch perspective. Only the corresponding component group should own that behavior.

The Console should remain free of missing component, unassigned Item Collection, missing Look Source, and invalid movement or View Type errors.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character does not move from player input | Check for a Player Input implementation, **Ultimate Character Locomotion Handler**, and an active Movement Type. Also check whether the character was built as **AI Agent**. | Update the character through Character Manager using the correct player or AI route, then configure the matching input system. |
| The character moves twice, jitters, or fights physics | Check for another movement script, a dynamic Rigidbody, or Unity gravity acting alongside Ultimate Character Locomotion. | Remove the competing motor and restore the UCC Rigidbody to **Is Kinematic** with **Use Gravity** disabled. |
| The camera does not follow the character | Check **Camera Controller > Character**, **Init Character On Awake**, and the configured View Types. | Assign the character or rerun **Setup Manager > Scene > Camera Setup** with the correct Perspective. |
| Animations do not respond to movement | Check that the active model has both an Animator with the intended controller and an **Animator Monitor**. | Update the character through Character Manager and correct the model's Animator Controller. |
| An item is owned but cannot equip | Check **Inventory**, **Item Set Manager**, its **Item Collection**, Item Set Group category and rules, Item Handler for a player, and the Item Abilities. | Re-enable **Items** in Character Manager and configure a valid Item Collection and Item Set Rule. |
| Health or respawning is incomplete | Check for the complete **Character Attribute Manager**, **Character Health**, and **Character Respawner** group and the named Health attribute. | Enable **Health** in Character Manager, then configure the attributes and respawn behavior. |
| An AI character responds to player input | Check for player input components, Ultimate Character Locomotion Handler, or Item Handler left on the AI character. | Update it with **AI Agent** enabled. Drive it through the AI integration and Local Look Source instead. |
| The character collides with its own model or misses expected layers | Check the Character, SubCharacter, Overlay, and other UCC layers plus the generated collider hierarchy. | Run the Setup Manager's Project layer setup and update the character through Character Manager. |

## Related pages

- [Quick setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) prepares the project, scene services, camera, and first character.
- [Character creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) explains every Character Manager choice.
- [Minimum component setup](https://opsive.com/support/documentation/ultimate-character-controller/character/minimum-component-setup/) lists the smallest valid player, AI, and animated-character configurations.
- [Character](https://opsive.com/support/documentation/ultimate-character-controller/character/) leads to Movement Types, Abilities, Effects, time, and model switching.
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/) covers Camera Controller and View Type workflows.
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/) covers Animator Monitor, parameters, events, and controller customization.
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/) covers Item Types, Character Items, Inventory, Item Sets, actions, and modules.
- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/) covers changing values, Health, damage, death, and respawning.
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/) explains the AI control route.
- [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/), [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/), and [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/) cover optional presentation systems.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains how presets change component values while named states are active.

## Developer reference

The main runtime types are grouped by responsibility:

- `Opsive.UltimateCharacterController.Character` contains UltimateCharacterLocomotion, handlers, AnimatorMonitor, Movement Types, Abilities, and Effects.
- `Opsive.UltimateCharacterController.Camera` contains CameraController and View Types.
- `Opsive.UltimateCharacterController.Inventory` contains InventoryBase, Inventory, ItemSetManager, ItemCollection, and the built-in ItemType.
- `Opsive.UltimateCharacterController.Items` and `.Items.Actions` contain CharacterItem, perspective items, actions, and modules.
- `Opsive.UltimateCharacterController.Traits` contains AttributeManager, CharacterAttributeManager, Health, CharacterHealth, and CharacterRespawner.
- `Opsive.Shared.Events.EventHandler` connects these systems without requiring direct component references for every notification.

Common entry points include:

| Goal | API |
| --- | --- |
| Change the movement model | `UltimateCharacterLocomotion.SetMovementType(Type)` or `SetMovementType(string)` |
| Find and control an ability | `GetAbility<T>()`, `GetAbilities<T>()`, `TryStartAbility(Ability, ...)`, and `TryStopAbility(Ability, ...)` |
| Find an item ability or effect | `GetItemAbility<T>()` and `GetEffect<T>()` |
| Change the camera model | `CameraController.SetViewType(Type, bool)` and `GetViewType<T>()` |
| Read or change an item amount | `InventoryBase.GetItemIdentifierAmount`, `AddItemIdentifierAmount`, and `RemoveItemIdentifierAmount` |
| Find a changing value | `AttributeManager.GetAttribute(string)` |

For example, custom gameplay code can ask the locomotion component for the configured Jump ability instead of constructing a second movement system:

```csharp
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using UnityEngine;

public class StartConfiguredJump : MonoBehaviour
{
    public void TryJump()
    {
        var locomotion = GetComponent<UltimateCharacterLocomotion>();
        var jump = locomotion.GetAbility<Jump>();
        if (jump != null) {
            locomotion.TryStartAbility(jump);
        }
    }
}
```

Use the [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) page when custom code should observe UCC state changes rather than poll components each frame.

---

<a id="page-ultimate-character-controller-character"></a>

# Character

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/)

The Character system controls how an Ultimate Character Controller character moves, collides with the world, responds to gravity and external forces, plays animation-driven motion, and runs gameplay abilities. Its kinematic, deterministic locomotion can be predicted and replayed, which is useful for consistent simulation and networking.

**Ultimate Character Locomotion** is the main component on a configured character. It builds on the core Character Locomotion behavior with Movement Types, Abilities, Effects, and Animator integration. Create or update this component through the Character Manager instead of assembling a new character by hand.

## Recommended route

1. Start with [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) to build a new character or update an existing one with **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Use [Minimum Component Setup](https://opsive.com/support/documentation/ultimate-character-controller/character/minimum-component-setup/) and [Component Overview](https://opsive.com/support/documentation/ultimate-character-controller/component-overview/) to understand the locomotion, collision, input, animation, and manager components that the chosen setup needs.
3. Learn [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) to add actions such as jumping, falling, interacting, or changing locomotion state without modifying the core controller.
4. Choose [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) to decide how input drives movement and which direction the character faces.
5. Configure the camera perspective and framing through [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/).
6. Add [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) when hands, feet, look direction, or held items need post-animation alignment.
7. Finish with the physics behavior relevant to the scene, including [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) and the terrain choices below.

## Additional character choices

- [Generic Character](https://opsive.com/support/documentation/ultimate-character-controller/character/generic-character/) explains when a non-humanoid rig is appropriate and which retargeting and IK features it cannot use.
- [Model Switch](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/) covers changing the visible character model at runtime.
- [Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/) covers lightweight camera, item, and character motion layered on top of locomotion.
- [Time](https://opsive.com/support/documentation/ultimate-character-controller/character/time/) explains global and per-character time-scale choices.

## Work from the editor to Play Mode

Use the Character Manager for the structural setup, then select the character and make focused changes in the **Ultimate Character Locomotion** Inspector. After each change, enter Play Mode and verify the visible result before adding another system.

A basic character should:

- Move and rotate according to its active Movement Type.
- Remain grounded on supported slopes and steps while respecting its colliders.
- Enter airborne behavior when it leaves the ground.
- Start and stop configured Abilities under their expected conditions.
- Stay aligned with the selected camera perspective and, when enabled, IK targets.

Testing one decision at a time makes it easier to distinguish a character setup problem from an input, camera, animation, or scene-physics problem.

## Core locomotion and physics choices

- **Animation or motor movement:** Enable root-motion position or rotation when animation should supply that delta. Motor acceleration, damping, and rotation settings control non-root-motion movement.
- **Steps and slopes:** Keep **Max Step Height** lower than the radius of every character collider to avoid a large vertical step in one frame. For taller stairs, place a sloped transparent quad collider across the step tops and assign it to **TransparentFX**. Locomotion follows the slope while foot IK continues to use the visible steps.

![A sloped transparent quad collider bridging stair tops so the character can traverse the staircase smoothly.](https://opsive.com/wp-content/uploads/2020/11/TransparentStairsCollider.png?v=94d6294a2aa4)

- **Air control:** Use the **Airborne** state to apply different **Motor Acceleration** and **Motor Damping** values while the character is off the ground.
- **Gravity and collision:** Configure gravity direction, collision layers, slope limits, and horizontal or vertical collision detection for the world the character must traverse.
- **Moving surfaces:** Choose whether the character sticks to a moving platform or inherits its momentum after separation; the [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) page covers the complete setup.

## Related topics

- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/)
- [Items & Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/)

## Developer reference

Ultimate Character Locomotion works with the Simulation Manager. For teleports or other authoritative position changes, use its movement API instead of setting the Transform directly:

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;

public class MyComponent : MonoBehaviour
{
    [Tooltip("A reference to the Ultimate Character Controller character.")]
    [SerializeField] private GameObject m_Character;

    /// <summary>
    /// Set the position and deactivate the character.
    /// </summary>
    private void Start()
    {
        var characterLocomotion = m_Character.GetComponent<UltimateCharacterLocomotion>();
        if (characterLocomotion != null) {
            characterLocomotion.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
        }
    }
}
```

Apply external forces through Character Locomotion rather than its Rigidbody:

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;

public class MyComponent : MonoBehaviour
{
    [Tooltip("A reference to the Ultimate Character Controller character.")]
    [SerializeField] private GameObject m_Character;

    /// <summary>
    /// Set the position and deactivate the character.
    /// </summary>
    private void Start()
    {
        var characterLocomotion = m_Character.GetComponent<UltimateCharacterLocomotion>();
        if (characterLocomotion != null) {
            characterLocomotion.AddForce(Vector3.up * 5);
        }
    }
}
```

When a character must persist between scenes, keep the character, camera, and UI together so their references remain valid:

```csharp
private void Start()
{
    // Find the character. If the character does not exist then instantiate a new character with DontDestroyOnLoad.
    var character = FindObjectOfType<Character.UltimateCharacterLocomotion>();
    if (character == null) {
        character = Instantiate(m_Character).GetComponent<Character.UltimateCharacterLocomotion>();
        DontDestroyOnLoad(character.gameObject);
    }
    // Find the camera. If the camera does not exist then instantiate a new camera with DontDestroyOnLoad.
    var camera = FindObjectOfType<Camera.CameraController>();
    if (camera == null) {
        camera = Instantiate(m_Camera).GetComponent<Camera.CameraController>();
        // The camera needs to be aware of the instantiated character.
        camera.Character = character.gameObject;
        DontDestroyOnLoad(camera.gameObject);
    }
    // Find the active canvas. If the canvas does not exist then instantiate a new canvas with DontDestroyOnLoad.
    var canvasScaler = FindObjectOfType<UnityEngine.UI.CanvasScaler>();
    if (canvasScaler == null) {
        DontDestroyOnLoad(Instantiate(m_Canvas));
    }
}
```

The persistent camera must reference the persistent character, as shown above. Keep only one instance of each persistent object when a new scene loads.

---

<a id="page-ultimate-character-controller-character-character-creation"></a>

# Character Creation

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)

Use the Character Manager to turn a scene model into a playable Ultimate Character Controller character, or to create a bodyless first-person character. It builds the controller hierarchy, movement, animation, input or AI bridge, and the optional item, health, IK, foot-effect, and ragdoll systems selected for that character.

## Before you begin

- Complete the project and scene steps in [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/). The Character Manager does not create the scene managers or camera.
- Import the first-person, third-person, or combined controller required by the intended **Perspective**.
- For a visible character, place a model instance in the scene. The manager cannot build or update a prefab asset directly and cannot run in Play Mode.
- Configure the model's Avatar before building. A humanoid needs a valid Humanoid Avatar with a Head bone; a [generic character](https://opsive.com/support/documentation/ultimate-character-controller/character/generic-character/) needs its own Animator Controller.
- If **Items** will remain enabled, create or select an **Item Collection** and **Item Set Rule** before building.

For representative first-person, third-person, combined, and multi-model layouts, start with [Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/).

## Build a new character

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Drag the scene model into **Character**. For a bodyless first-person character, leave **Character** empty and disable **Animator**.
3. Choose **Perspective**: **First**, **Third**, or **Both**.
4. Choose **First Person Movement** and/or **Third Person Movement** for the selected perspective. Additional movement types can be added later; see [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/).
5. For a visible model, confirm **Animator**, **Character Model 1**, **Model Type**, and **Animator Controller**.
6. Configure first-person objects, item slots, and optional additional models as described below.
7. Review the functionality toggles. Turn off systems the character does not need; a movement-only prototype can turn off **Items**, for example.
8. Resolve every error shown by the manager, then select **Build Character**.

The initial manager view below shows a bodyless first-person configuration while **Animator** is still enabled. Either assign a rigged model or disable **Animator** to clear that error.

![Character Manager with First perspective selected and a validation error requesting a rigged character for the enabled Animator](https://opsive.com/wp-content/uploads/2022/10/CharacterSetup.png)

## Choose the perspective and rig

| Choice | Use it when | Manager result |
| --- | --- | --- |
| **First** | The game uses a first-person View Type. A model is optional. | Shows **First Person Movement**, first-person object fields, and allows a bodyless setup when **Character** is empty and **Animator** is disabled. |
| **Third** | The player or AI is seen through a third-person View Type. | Requires a scene model and Animator, and shows **Third Person Movement**. |
| **Both** | The character can switch between installed first- and third-person controllers. | Adds both movement types and a Perspective Monitor. The released Version 3 Character Manager does not show a **Start Perspective** field; a new character is built with its first-person movement type as the initial default. Verify the camera's separately configured start perspective in Play Mode. |

The Character Manager does not create or configure a Camera Controller. Use **Setup Manager > Scene > Camera Setup**, choose the same perspective, and follow [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/). A player character receives the **Player** tag, so a camera with **Init Character On Awake** can find it automatically.

| Model choice | What to configure |
| --- | --- |
| **Humanoid** | The manager detects a valid Humanoid Avatar and can supply the included Animator Controller when the model has none. Humanoid models support **Unity IK**, automatic hand slots, and **Ragdoll**. |
| **Generic** | Select **Generic**, assign the model's project-specific **Animator Controller**, and leave **Unity IK** and **Ragdoll** off. Unity's humanoid retargeting, IK, and ragdoll builder do not apply. |
| Multiple models | Add **Character Model 2** and later rows. Configure **Model Type**, **Animator Controller**, first-person objects, and item slots for every model. The build adds a Model Manager so the character can switch models at runtime. |

The selected scene model is automatically inspected. Humanoid models default to **Humanoid** and an available included controller; other models default to **Generic** and retain their existing controller when one is assigned.

![Character Manager configured for the Atlas humanoid with Both perspectives, first- and third-person movement types, item data, and the default optional systems](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupAtlas.png?v=080151ec9998)

## Configure first-person visibility and item slots

For **First** or **Both**, use these model-specific fields:

1. Add optional separate arm rigs to **First Person Arms** and assign the corresponding Animator Controller in the field beside each arm object.
2. Add the full-body renderers that should be hidden in first person to **Third Person Objects**. Head and body-arm renderers are common choices.
3. When **Items** is enabled, select **Adjust Slots** beside **Item Slots**.
4. Assign each full-body and first-person-arm parent, then give matching locations the same slot ID in every perspective. The humanoid defaults are right hand ID `0` and left hand ID `1`.
5. Close **Character Item Slots** only after it reports a valid configuration.

The first-person View Type handles the separate arms and hidden full-body objects. See the [first-person View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/) for the rendering behavior.

![Character Item Slots window mapping left and right hand IDs across the Atlas model and its first-person arms](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupItemSlots.png?v=6733ff832e52)

The completed combined-perspective example assigns an arm rig and controller, hides the full-body arms and head, and lists the matching slots for both rigs.

![Character Manager completed for Atlas with first-person arms, hidden third-person objects, matching hand slots, and all optional systems enabled](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupAtlasBoth.png?v=20fd1acadbf4)

For the complete item component, ability, and slot flow, continue with [Item Support](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/).

## Choose the optional systems

The following are the initial values for a new valid humanoid character. Selecting a generic model automatically turns off **Unity IK** and **Ragdoll**.

| Option | Initial value | What Build Character adds |
| --- | --- | --- |
| **Standard Abilities** | On | Jump, Fall, Move Towards, Speed Change, and Height Change. Item Equip Verifier comes from **Items**, not this toggle. |
| **AI Agent** | Off | When on, adds a Local Look Source and omits player input, Ultimate Character Locomotion Handler, and Item Handler. It prepares the controller for AI but does not add decision-making behavior. |
| **NavMeshAgent** | Off | Adds NavMeshAgent Movement with a Unity NavMeshAgent and a stopping distance of `0.1`. It does not build or bake a NavMesh. |
| **Input System** | On when the Input System is installed | Uses the project's Input Actions for a player character. Turn it off to use the legacy Input Manager implementation. The field is hidden for an AI agent. |
| **Items** | On | Requires **Item Collection** and **Item Set Rule**. Adds inventory, item-set, placement, handler, standard item abilities, and Item Equip Verifier support. |
| **Health** | On | Adds Character Attribute Manager, Character Health, and Character Respawner. |
| **Unity IK** | On for a valid humanoid | Adds Character IK to each humanoid model. |
| **Foot Effects** | On | Adds Character Foot Effects to animated models and initializes humanoid feet when available. |
| **Ragdoll** | On for a valid humanoid | Adds the Ragdoll ability and automatically creates the humanoid ragdoll colliders. |

Use [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/) after enabling **AI Agent**, [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) for IK choices, and [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) for foot effects.

## Use a template character

Assign an existing Ultimate Character Controller character to **Template Character** when the new character should reuse an established setup. The template must be different from the target and cannot be a legacy controller character.

With a template selected, the normal functionality toggles are replaced by **Copy Components**, **Copy Abilities**, **Copy Item Abilities**, **Copy Effects**, and **Copy Items**. They initially appear enabled. Model-specific fields such as **First Person Arms**, **Third Person Objects**, and **Item Slots** still belong to the new character and must be configured separately.

After the build, the Reference Resolver maps copied object references to the new hierarchy and opens a resolution window for ambiguous references. Follow [Templates](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/templates/) for that workflow.

> **Released Version 3 limitation:** **Copy Items** is wired to the **Copy Abilities** value in the current Character Manager, while the internal item-copy setting remains enabled. Do not rely on that toggle to exclude Character Items. Use a template without those items or remove the copied items from the new character after resolving references.

## What Build Character creates

When a scene model is assigned, the manager creates a new controller root at the model's position and rotation, then reparents the model beneath it. With no model, it creates a root named `FirstPersonCharacter`.

The core build adds the Character and SubCharacter layer assignments, a Character Layer Manager, a kinematic Rigidbody, Ultimate Character Locomotion, the selected movement types, and a `Colliders/CapsuleCollider` hierarchy. A player build also adds its input object, Player Input Proxy, and Ultimate Character Locomotion Handler. Animated models receive Animator Monitor, and their Animator Controllers receive the required UCC parameters. Both-perspective and multi-model choices add their corresponding monitor or manager components.

The optional systems add scene components and hierarchy objects; they do not create a Camera Controller, Item Collection, Item Set Rule, or other project data asset. The manager references the assets selected in its fields and may modify an assigned Animator Controller by adding required parameters.

![Built Atlas character selected in the Scene view with the generated capsule and humanoid ragdoll colliders visible](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupAtlasBuilt.png?v=7b26c6c3e035)

## Update an existing character

1. Save the scene and any prefab changes before an update that removes models, arms, item support, slots, IK, or ragdoll colliders.
2. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
3. Assign the existing controller root to **Character**. The manager recognizes it by the Ultimate Character Locomotion component and loads the detected setup.
4. Change the supported perspective, movement, Animator Controller, model, first-person, slot, input/AI, NavMeshAgent, item, health, IK, foot-effect, or ragdoll options.
5. Select **Update Character** and inspect the hierarchy and components before saving.

The update path can add and remove generated components and objects. Removing a model or first-person arm can destroy that scene object; removing item support deletes the generated Items hierarchy, slots, inventory components, item abilities, and Item Equip Verifier. Keep a recoverable scene or prefab version before subtractive changes.

### Released Version 3 update boundaries

- **Standard Abilities** is read and displayed for an existing character, but **Update Character** does not add or remove that set. Edit the **Abilities** list directly when changing it after the initial build.
- If item support already exists, changing **Item Collection** clears the Item Set groups and assigns the new collection. Changing only **Item Set Rule** is not applied by **Update Character**; edit **Item Set Manager > Starting Item Set Rules** on the character instead.
- The Character Manager updates the character only. Create or update its camera separately and retest the connection after changing **Perspective**.

## Verify in Play Mode

Before entering Play Mode, confirm that the selected root has **Ultimate Character Locomotion**, the generated collider hierarchy exists, each visible model has the expected Animator Controller, the scene has its managers, and a Camera Controller is configured for a player character.

1. Enter Play Mode and move the player with the configured input. The selected movement type should become active and the camera should follow the character.
2. For **Both**, switch perspectives in both directions. The camera View Type and character movement type should agree, separate arms should appear only in first person, and the configured full-body objects should hide correctly.
3. Equip one item in every configured slot. First- and third-person objects should use matching hands or attachment points.
4. Exercise each enabled optional system: apply damage for **Health**, inspect foot contacts for **Foot Effects**, and test IK or Ragdoll only on the intended humanoid models.
5. For an **AI Agent**, confirm player input does not drive the character. If **NavMeshAgent** is enabled, test it on a baked NavMesh through the project's AI logic.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Character** or **Update Character** is disabled. | Look for a prefab asset instead of a scene instance, Play Mode, an unavailable perspective package, an invalid Humanoid Avatar or Head bone, missing item assets, or an error in **Character Item Slots**. | Use a scene instance, exit Play Mode, import the required controller, correct the rig, assign the required item assets, and resolve every displayed error. |
| The model remains in a T-pose or does not animate. | Check **Model Type**, Avatar validity, and **Animator Controller** for every model. | Use the included controller with a valid humanoid or assign the project-specific controller required by a generic rig. |
| The camera does not follow the new player. | The Character Manager does not create a camera; also check the **Player** tag and Camera Controller **Character** assignment. | Complete **Setup Manager > Scene > Camera Setup**, then assign the character or enable automatic Player-tag lookup. |
| The head or body arms appear in first person. | Check **Third Person Objects** and the selected first-person View Type. | Add the unwanted renderers to **Third Person Objects**, update the character, and test the view again. |
| First-person items appear in the wrong hand. | Compare slot parents and IDs across the full-body model and every arm rig. | Open **Adjust Slots** and use the same ID for corresponding attachment points. |
| Items do not equip after the build. | Check **Item Collection**, **Item Set Rule**, Item Set Manager groups, and slot IDs. | Follow [Item Support](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/) and correct the data or slot mapping before creating more items. |
| An AI character does not respond to player input. | **AI Agent** intentionally removes the player input and locomotion-handler path. | Drive it through the AI integration, or turn off **AI Agent** and select **Update Character** to restore the player input path. |

## Developer details

The editor workflow delegates the core build to `CharacterBuilder.BuildCharacter` and the optional systems to `CharacterBuilder.BuildCharacterComponents`. The builder also exposes focused operations such as `AddMovementType`, `AddItemSupport`, `AddHealth`, `AddUnityIK`, `AddFootEffects`, and `AddAIAgent` for controlled setup code. These methods build character-side objects and components; camera creation remains a Setup Manager or Camera Controller responsibility.

When a template is used, the manager copies Opsive components and serializable ability, item-ability, and effect objects, then resolves hierarchy references. Review unresolved references instead of assuming a copied component still points to the intended model, collider, arm rig, or item on the new character.

## Related tasks

- [Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/)
- [Item Support](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/)
- [Templates](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/templates/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)

---

<a id="page-ultimate-character-controller-character-character-creation-common-setups"></a>

# Common Setups

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/)

Use these Character Manager patterns to build the smallest controller layout that supports the camera perspective, visible body, separate first-person arms, items, and model switching needed by the game.

## Before you begin

- Complete [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/), including the project layers and scene managers.
- Import the first-person, third-person, or combined controller required by the intended **Perspective**.
- Place every visible full-body model in the scene. A bodyless first-person character can leave **Character** empty, but Character Manager cannot build directly onto a prefab asset.
- Prepare an Animator Controller for every generic model and every separate arm rig that needs animation. Humanoid models can use the included controller when their Avatar is valid and has a Head bone.
- If the character will carry items, create an **Item Collection** and **Item Set Rule** before building.

See [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) for the complete explanation of the manager and its optional systems.

## Choose a layout

| Player presentation | Character Manager choice | Generated result |
| --- | --- | --- |
| First person with arms but no full body | **Character** is empty, **Perspective** is **First**, and **Animator** is off. | Creates a `FirstPersonCharacter` controller root and parents any configured **First Person Arms** beneath its first-person objects. |
| First person with a visible body | Assign one model, choose **First**, keep **Animator** on, and configure **Third Person Objects**. | Builds the full controller around the model while hiding selected head or body meshes from the first-person camera. |
| Third person only | Assign one model and choose **Third**. | Builds a model-driven controller with a third-person movement type and no first-person arm hierarchy. |
| Switchable first and third person | Assign one model and choose **Both**. | Adds both movement types and a Perspective Monitor so character visibility follows the camera perspective. |
| One controller with interchangeable models | Assign two or more **Character Model** rows and configure each model separately. | Adds a Model Manager; the first listed model is active initially and the others can be selected at runtime. |

## Build the selected layout

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Assign **Character** when the layout uses a full-body model, then choose **Perspective**.
3. Choose the visible **First Person Movement** and/or **Third Person Movement** fields. The available names depend on the installed controller packages.
4. For each visible model, confirm **Character Model**, **Model Type**, and **Animator Controller**.
5. For a first-person-capable layout, assign optional **First Person Arms** and their Animator Controllers. Add the model's head, body arms, or other unwanted first-person renderers to **Third Person Objects**.
6. If **Items** is enabled, assign **Item Collection** and **Item Set Rule**, then use **Adjust Slots** as described below.
7. Select only the optional systems the character needs, resolve every displayed error, and select **Build Character**.
8. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**. On **Scene**, open **Camera Setup**, choose the matching **Perspective** and View Type fields, then select **Setup Camera**. For **Both**, also choose the camera's **Start Perspective**.

If exactly one character exists when **Setup Camera** runs, the new Camera Controller is assigned to it automatically. Otherwise, assign the controller root to the Camera Controller's **Character** field.

The following screenshots focus on the fields that define each layout. **Health**, **Unity IK**, **Foot Effects**, **Ragdoll**, and other optional systems can be selected independently. **Input System** appears between **NavMeshAgent** and **Items** only when Unity's Input System is installed, so that row is not present in every valid configuration.

## First person without a full body

Use this layout when only separate arms and held items should be visible.

1. Leave **Character** empty, choose **First**, and select a **First Person Movement** type.
2. Turn off **Animator**. A bodyless character cannot keep that option enabled.
3. Assign the arm rig to **First Person Arms** and its controller in the adjacent Animator Controller field.
4. If items are enabled, map the arm rig's attachment points with **Adjust Slots**.
5. Configure the camera with **Perspective: First** and the intended **First Person View Type**.

![Character Manager for a bodyless First perspective character with First Person Combat movement, separate Atlas arms, items enabled, and Animator disabled](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupFirstPersonBasic.png?v=e33e5dd2c6c1)

After the build, the controller has no full-body model. In Play Mode, only the separate arms and their first-person items should render from the player camera.

## First person with a full body

Use this layout for first-person body awareness while retaining a separate arm rig for weapons or interactions.

1. Assign the scene model to **Character**, choose **First**, and keep **Animator** enabled.
2. Confirm **Character Model 1**, **Model Type**, and **Animator Controller**.
3. Assign the separate rig to **First Person Arms**.
4. Add the full-body head and body arms to **Third Person Objects** so they do not obstruct the first-person camera. Add only the renderers that should disappear; the remaining body stays visible.
5. Map equivalent hand or attachment points to the same item slot IDs.

![Character Manager for an Atlas full-body First perspective character with a humanoid Animator, separate arms, Arms and Head hidden in first person, and matching item slots](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupFirstPersonFullBody.png?v=b3066df564d1)

This is a first-person-only controller: the full body provides awareness, but it does not add a third-person movement type or View Type.

## Third person only

Use this layout when the camera always shows the character and no first-person arms are needed.

1. Assign the model, choose **Third**, and select **Third Person Movement**.
2. Keep **Animator** enabled and confirm the model type and Animator Controller.
3. Configure the full-body **Item Slots** if items are enabled. **First Person Arms** and **Third Person Objects** are not shown for this perspective.
4. Configure the camera with **Perspective: Third** and the intended **Third Person View Type**.

![Character Manager for an Atlas Third perspective character using Third Person Adventure movement with humanoid animation and left and right hand item slots](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupThirdPerson.png?v=25b9823391cd)

The built character contains only the selected third-person movement path. Adding a first-person camera later also requires updating the character to **Both** or **First**.

## Switchable first and third person

Use this layout when the player can change perspective during play.

1. Assign the full-body model and choose **Both**.
2. Choose both **First Person Movement** and **Third Person Movement**.
3. Configure **First Person Arms**, **Third Person Objects**, and matching **Item Slots** just as for the full-body first-person layout.
4. In **Setup Manager > Scene > Camera Setup**, choose **Both**, select both View Types, choose **Start Perspective**, and select **Setup Camera**.

![Character Manager for an Atlas Both-perspective character with First Person Combat and Third Person Adventure movement, separate arms, hidden Arms and Head, and four item-slot entries](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupFirstThirdPerson.png?v=b07e01e392d4)

> **Released Version 3 limitation:** Character Manager does not expose a **Start Perspective** field and builds a new **Both** character with its first-person movement type selected first. The camera's **Start Perspective** is configured separately in Setup Manager. Always verify that the active camera View Type and movement type agree after entering Play Mode.

## Multiple interchangeable models

Use this layout for skins, forms, or characters that share one controller but need different rigs or first-person representations.

1. Configure the first scene model normally.
2. Assign another scene model in the empty **Character Model 2** row. Additional empty model rows appear as each model is added.
3. For every model, choose its own **Model Type** and **Animator Controller**.
4. Configure that model's **First Person Arms**, **Third Person Objects**, and **Item Slots**. Do not assume one model's hand bones or hidden meshes apply to another.
5. Build the character once. The generated Model Manager lists the available models and uses the first model initially.

![Character Manager for a Both-perspective controller with Atlas and Rhea models, each configured with its own arms, hidden objects, Animator Controller, and item slots](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupFirstThirdPersonMultiModel.png?v=4c8cca5f3a8b)

Changing the active model is a separate runtime action; adding models in Character Manager does not create a player-facing selection menu. See [Model Switch](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/) for the switching workflow.

## Match item slots across views and models

The slot ID identifies an attachment role, not a particular transform. A right-hand slot should therefore use the same ID on the full-body model, each first-person arm rig, and every interchangeable model.

1. Enable **Items**, assign the data assets, and select **Adjust Slots**.
2. Under **Model**, assign the full-body attachment points. A valid humanoid is initially populated with right hand ID `0` and left hand ID `1`.
3. Under each **First Person Arms** group, assign the equivalent transforms and reuse those IDs.
4. Keep every ID unique within one model or arm group. Resolve any duplicate parent or duplicate ID error before closing **Character Item Slots**.

![Character Item Slots window matching right-hand ID 0 and left-hand ID 1 between the Atlas model and its first-person arm rig](https://opsive.com/wp-content/uploads/2022/10/CharacterSetupItemSlots.png?v=6733ff832e52)

Continue with [Item Support](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/) before creating perspective-specific Character Items.

## Verify in Play Mode

1. Enter Play Mode and confirm that the camera follows the controller and the chosen movement type responds to input.
2. In first person, confirm that separate arms render, configured **Third Person Objects** disappear, and the remaining full body does not block the camera.
3. For **Both**, switch perspectives in both directions. The camera View Type, movement type, arm visibility, and hidden full-body objects should change together.
4. Equip an item in every configured slot. Its full-body and first-person versions should attach to the equivalent location.
5. For a multi-model character, switch to every available model. Only one model should remain active, animation should continue, and items should stay on the intended slots.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Character** is disabled. | Check for a prefab in **Character**, an enabled **Animator** with no model, a missing perspective package, missing item assets, or an error in **Character Item Slots**. | Use a scene model, disable **Animator** for a bodyless setup, import the required controller, assign the item assets, and resolve every slot-window error. |
| The head or body arms cover the first-person camera. | Check **Third Person Objects** for the affected model. | Add only the unwanted head or arm renderers, select **Update Character**, and retest the first-person View Type. |
| Separate arms do not animate. | Check the Animator Controller field beside each **First Person Arms** entry. | Assign the controller made for that arm rig and update the character. |
| An item appears in the wrong hand or jumps when perspectives change. | Compare the slot parent and ID for the model, arm rig, and active interchangeable model. | Open **Adjust Slots** and reuse the same ID for equivalent attachment points. |
| A **Both** character starts in the wrong perspective or uses the wrong movement. | Check the camera's **Start Perspective**, View Types, and **Character** assignment. | Correct **Setup Manager > Scene > Camera Setup**, then enter Play Mode again and verify the camera and locomotion synchronize. |
| Switching models leaves the wrong mesh or item visible. | Check the Model Manager's available models and each model's first-person objects, hidden objects, and slots. | Return to Character Manager, configure every model-specific row, select **Update Character**, and test every model again. |

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Item Support](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Model Switch](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [First Person View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [Templates](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/templates/)

## Developer details

The generated Model Manager exposes `ActiveModel` and `ChangeModels(GameObject)` for model selection. It activates the selected model, deactivates the previous model, transfers animation parameters, updates model states, and sends `OnCharacterSwitchModels`.

For a custom perspective control, the Camera Controller owns the runtime camera change through `SetPerspective(bool)` or `TogglePerspective()`. Keep that camera state synchronized with the character rather than trying to set a start perspective in Character Manager.

---

<a id="page-ultimate-character-controller-character-character-creation-item-support"></a>

# Item Support

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/)

Enable item support when a character must collect, equip, switch, aim, use, or reload Character Items. Character Manager creates the receiving hierarchy, inventory, equip rules, slots, and abilities; it does not create the actual items or a default loadout.

## Before you begin

- Create or choose an **Item Collection** containing the categories and definitions used by the character.
- Create an **Item Set Rule** that can form the intended equipment combinations. See [Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) for the available rule types.
- Decide which full-body, first-person-arm, and alternate-model transforms represent each equipment slot.
- Save the scene or prefab before changing item support on an existing character. Removing support deletes generated item objects, slots, abilities, and first-person object hierarchies.

This field-based workflow applies when **Template Character** is empty. A template build uses its copy options instead; see [Templates](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/templates/).

## Add item support with Character Manager

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Configure a new character, or assign an existing Ultimate Character Controller root to **Character**.
3. Enable **Items**. It is enabled initially for a new character.
4. Assign **Item Collection** and **Item Set Rule**. **Build Character** or **Update Character** remains unavailable when either required asset is missing.
5. Select **Adjust Slots** beside **Item Slots**. Assign the full-body attachment transforms and, for first-person or **Both** layouts, the equivalent transforms beneath each **First Person Arms** group.
6. Give corresponding attachment points the same ID in every perspective and model. Keep IDs unique within each individual model or arm group.
7. Resolve every error in **Character Item Slots**, close the window, then select **Build Character** or **Update Character**.

A valid humanoid is initially populated with right hand ID `0` and left hand ID `1`. Custom slots can use higher IDs; Inventory uses the highest ID plus one as its slot count, so an ID gap still creates an unused slot index.

## Check the generated setup

After the build or update, inspect the controller before creating items:

| Location | Generated result |
| --- | --- |
| Character root | **Inventory** and **Item Set Manager**. A player also receives **Item Handler**; an **AI Agent** does not. |
| Character root or animated model | **Animator Monitor** is added only when none exists, allowing item animation parameters to be forwarded even on a bodyless first-person character. |
| `Items` child of the controller | **Item Placement**, which identifies where [Character Items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) are stored or spawned. |
| Selected attachment transforms | A child named `Items` with **Character Item Slot** and the configured ID. This is separate from the controller's `Items` object with Item Placement. |
| Ultimate Character Locomotion > Item Abilities | **Reload**, **Use**, **Equip Unequip**, **Toggle Equip**, **Equip Next**, **Equip Previous**, **Equip Scroll**, and **Aim**. |
| Ultimate Character Locomotion > Abilities | **Item Equip Verifier**, added after the item abilities so other abilities can request temporary equip changes safely. |
| First-person-capable models and arm rigs | **First Person Objects** containers used by perspective-specific item visuals. |

The configured demo below shows a populated Inventory and three Item Set groups. Character Manager does not create that loadout or those extra groups: a new build starts with an empty Inventory and one base group.

![Inventory and Item Set Manager Inspectors on Atlas showing a configured demo loadout, Immediately update mode, one Items group, and two grenade groups with their rule assets](https://opsive.com/wp-content/uploads/2022/10/InventoryAndItemSetManagerInspector.png?v=7b4b4b8c12de)

The controller-level `Items` object is the storage parent for Character Items. Their first- and third-person visible objects attach to the matching Character Item Slots when initialized.

![Atlas hierarchy with the generated Items child selected and its Item Placement component visible in the Inspector](https://opsive.com/wp-content/uploads/2022/10/ItemPlacementInspector.png?v=09f3edf4b374)

## Match slots across perspectives and models

Treat the slot ID as the equipment role and the selected transform as that role's location for one representation:

- ID `0` can be the right hand on the full-body model, first-person arms, and every interchangeable model.
- ID `1` can be the corresponding left hand locations.
- An additional ID such as `2` can represent a magic, shoulder, or utility attachment that may equip independently when its Item Set Rule permits it.

The Character Item's **Slot ID** must match one of these generated slots. If a first-person and third-person visual use different IDs, the item can initialize under the wrong transform or fail to find a spawn parent. Continue with [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) for the slot component behavior.

## Configure Item Set groups and rules

On a new item-enabled character, Character Manager:

1. assigns the selected **Item Collection** to Item Set Manager;
2. creates one **Item Set Group** when none exists;
3. assigns the collection's first category as that group's **Item Category** when no category is already set; and
4. places the selected **Item Set Rule** in the edit-time **Item Set Rules** list when that list is empty.

The chosen rule determines which Character Items may form an equip set:

| Rule | Useful starting point |
| --- | --- |
| **Individual Item Set Rule** | One item per set, with other slots allowed to remain empty. |
| **Category Item Set Rule** | Slot combinations based on item categories. |
| **Item Type Item Set Rule** | Fixed slot combinations based on specific item types. |
| **Multi Item Set Rule** | Several rule assets treated as alternative valid patterns. |

**On Add Item Update Item Sets Option** defaults to **Immediately**. Keep it for straightforward pickup flows. **Schedule To Late Update** can combine several additions into one end-of-frame refresh, while **Manual** requires project code to call `UpdateItemSets()`.

Add more groups when equipment categories should operate independently. Each group needs a unique **Item Category**, and each item-set ability that operates on that group needs the matching **Item Category**. An unassigned generated ability falls back to the first group at runtime.

## Understand the generated item abilities

- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs the actual transition between Item Sets.
- **Toggle Equip**, **Equip Next**, **Equip Previous**, and **Equip Scroll** choose a target set, then hand the work to the matching Equip Unequip ability.
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) coordinates aiming state and perspective item behavior.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) runs the selected action on the equipped Character Item; several Use abilities can target different slots or action IDs.
- [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) coordinates reload-capable item actions and their timing.

For an **AI Agent**, Character Manager keeps the item abilities but changes their input-driven start and stop types to **Manual**. The AI logic must decide when to equip and use an item.

## Update an existing character

Use **Update Character** to add item support to a character that does not already have it or to change slot mappings. For an existing item-enabled character, edit Item Set Manager directly when changing groups and rules.

> **Released Version 3 limitations:**
>
> - Changing only **Item Set Rule** in Character Manager does not update the edit-time **Item Set Rules** list when item support already exists. The field is loaded from the first group's first rule for display, but the update path does not write it back.
> - Changing **Item Collection** clears the existing Item Set groups before assigning the new collection. Item Set Manager recreates a base group for the new collection, but Character Manager does not reapply the selected rule. Rebuild the intended groups, categories, and **Item Set Rules** in Item Set Manager after the update.
> - Turning **Items** off removes the `Items`/Item Placement hierarchy, all generated Character Item Slot objects, Inventory, Item Set Manager, every item ability, Item Equip Verifier, and all **First Person Objects** hierarchies. On a first-person or **Both** character, this also removes the separate arm instances beneath those hierarchies. Keep a recoverable copy and reassign the arms in a later update if the character must retain them without item support.

## Verify in Play Mode

1. Enter Play Mode and inspect **Inventory**. Pick up one known Character Item, or add it through the default loadout, and confirm it appears in the current inventory.
2. Inspect **Item Set Manager**. The matching group should generate a set containing that item in its configured slot; the set should be valid before an equip ability can select it.
3. Trigger **Equip Unequip** or one of the switcher abilities. The expected Character Item should become active in Inventory.
4. Confirm the visible item attaches to the matching full-body slot. For **First** or **Both**, switch perspective and verify that the first-person visual uses the same slot role.
5. Trigger **Aim**, **Use**, and **Reload** only where the Character Item provides the matching actions. Their animation and visible-object state should complete without changing to an unintended Item Set.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Character** or **Update Character** is disabled with **Items** enabled. | Check **Item Collection**, **Item Set Rule**, and the open **Character Item Slots** window. | Assign both assets and resolve duplicate parents, duplicate IDs, or empty slot entries. |
| Inventory and Item Set Manager exist, but no items appear. | Check whether any Character Item prefab or default loadout was created. Character Manager does not generate either. | Follow [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/), then add the item through a pickup or Inventory default loadout. |
| The character owns an item but cannot equip it. | In Play Mode, check the Item Set group's **Item Category**, generated sets, rule validity, and the Equip Unequip ability's **Item Category**. | Make the definition, group, rule, and ability refer to the same category, then refresh the Item Sets. |
| A visible item is missing or attached to the wrong hand. | Compare the Character Item **Slot ID** with every perspective and model slot ID. | Use **Adjust Slots** and assign the same ID to equivalent transforms; update the character and recreate the item only if its own Slot ID is wrong. |
| Toggle, next, previous, or scroll input does nothing. | Check for a matching Equip Unequip ability and Item Category. | Add or correct Equip Unequip for that group; the switcher abilities do not perform the equip transition themselves. |
| A changed rule is ignored after **Update Character**. | Check **Item Set Manager > Item Set Groups > Item Set Rules**. | Edit the group directly; changing Character Manager's **Item Set Rule** field alone does not update an existing setup. |
| First-person arms disappear after item support is removed. | Check whether the arms were children of a generated **First Person Objects** hierarchy. | Restore or reassign the arm rig from the recoverable source, then run a second update with **Items** left off. |

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/)
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/)
- [Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/)
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/)
- [Character Items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/)
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/)

## Developer details

`CharacterBuilder.AddItemSupport` is the editor workflow's component-level entry point. At runtime, Item Set Manager exposes `SetItemCollection`, `UpdateItemSets`, and `TryEquipItemSet` for controlled collection changes, rule refreshes, and set selection.

Inventory determines its slot count from all Character Item Slot IDs and spawns runtime Character Item prefabs beneath Item Placement. Perspective Item initialization then resolves the active model and matching slot, including after `OnCharacterSwitchModels`.

---

<a id="page-ultimate-character-controller-character-character-creation-templates"></a>

# Templates

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/templates/)

Use a template character to transfer a working Ultimate Character Controller configuration to a new or existing character. A template is an ordinary configured character, not a separate asset type.

## Before you begin

- Finish and test the source character before using it as a template.
- Save the scene or prefab containing an existing target. Applying a template changes matching component, ability, item ability, and effect settings in place.
- Decide the target's **Perspective**, movement types, models, Animator Controllers, **First Person Arms**, **Third Person Objects**, and **Item Slots**. Those target-specific choices are not taken from the template.
- Configure the camera separately. Character templates do not create or copy a camera.

## Apply a template

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. For a new character, assign its model and complete the perspective, movement, Animator, arms, third-person-object, and item-slot fields. For an existing character, assign its controller root to **Character**.
3. Assign the configured source character to **Template Character**. It must already contain **Ultimate Character Locomotion**, cannot be the target itself, and cannot be a legacy character.
4. Choose the copy options described below.
5. Select **Build Character** for a new target or **Update Character** for an existing target.
6. If **Reference Resolver** opens, replace or clear every field that still points into the template hierarchy before selecting **Close**.

The screenshot shows Nolan remaining as the target model while Atlas supplies the reusable controller configuration.

![Character Manager configured with Nolan as the target, Atlas as the Template Character, and all five copy options enabled](https://opsive.com/wp-content/uploads/2022/10/TemplateCharacter.png?v=f534e2b41240)

## Choose what to copy

All five options are enabled initially. Their merge behavior is different:

| Option | Result on the target |
| --- | --- |
| **Copy Components** | Copies settings from Opsive components on the template root. A component of the same type is reused; otherwise it is added. Unity components, custom components, child components, and **Model Manager** are not copied. |
| **Copy Abilities** | Reconfigures matching ability types and adds missing types. Additional target abilities remain, and existing entries are not reordered to match the template. |
| **Copy Item Abilities** | Reconfigures matching item-ability types and adds missing types. Extra occurrences of a type used by the template are removed, unrelated types remain, and existing entries are not reordered. |
| **Copy Effects** | Reconfigures matching effect types and adds missing types. Additional target effects remain, and existing entries are not reordered. |
| **Copy Items** | Clones each active **Character Item** beneath the template into the target's **Item Placement** hierarchy. It does not merge or deduplicate items. |

> **Released Version 3 limitation:** the visible **Copy Items** toggle reads and changes the **Copy Abilities** setting instead of the stored item-copy setting. The item-copy setting normally remains at its enabled default, so selecting a template can still copy items when **Copy Items** appears disabled. Changing that toggle can also change whether abilities copy. If the target must not receive items, use a temporary template with no Character Item beneath an active GameObject, then verify **Copy Abilities** before building or updating.

When a template is selected, Character Manager replaces its normal functionality choices with these copy options. For a new target, it does not run the normal component-support or ragdoll-builder steps. **Copy Components** transfers only root-level Opsive components, so create any required child hierarchy, ragdoll colliders, or other model-specific setup separately.

## Keep target-specific setup on the target

The target keeps the model rows configured above **Template Character**, including its model type, Animator Controller, first-person arms, third-person objects, and item-slot transforms. **Model Manager** is deliberately excluded from component copying. This lets two characters share controller behavior without replacing their visual hierarchy.

| Target | What happens |
| --- | --- |
| New character | Character Manager builds the target's core locomotion and model setup first, then applies the selected template data. |
| Existing character | Character Manager updates the target's core setup first, then overwrites matching copied settings and adds missing copied entries. |

Applying the same template repeatedly is not idempotent for items: each run clones the active template Character Items again. Inspect the target hierarchy after every application and remove unintended duplicates before entering Play Mode.

## Resolve object references

The copy operation tries to replace references into the template with equivalent objects on the target. It can match the target root, corresponding Animator hierarchies, relative child paths, and Humanoid bones. When a corresponding object is missing or ambiguous, **Reference Resolver** lists the unresolved field.

![Reference Resolver listing unresolved Collider, Lean collider, and Item Pullback collider fields that still point to the template character](https://opsive.com/wp-content/uploads/2022/10/ReferenceResolver.png?v=3036f68997af)

For each warning:

1. Select the corresponding object on the target, or set the field to **None** when the target does not use that object.
2. Confirm that the warning stating that the destination is a child of the template character disappears.
3. Select **Close**, then inspect the affected component on the target.

The **Close** button does not require every warning to be resolved. Leaving a template object selected creates an unwanted cross-character reference. Also inspect cloned Character Items manually: their fields are not included in the Reference Resolver pass.

## Check the generated result

Before Play Mode, select the target and confirm:

- **Ultimate Character Locomotion** contains the intended ability, item-ability, and effect order;
- each copied root component refers to the target's models, colliders, item slots, and child objects rather than the template;
- model-specific arms and third-person objects are still the ones selected for the target;
- **Item Placement** contains the intended Character Items exactly once; and
- any required child components or ragdoll colliders that were not copied have been created separately.

## Verify in Play Mode

1. Move the target with its selected movement type and switch perspective when the character supports both views.
2. Start one copied ability and one copied effect. Confirm that they use the target's Animator, colliders, and child objects.
3. If items were copied, equip and use one item in every supported perspective. Confirm that the expected Character Item and Item Set are selected and that no duplicate item appears.
4. Exercise any model switch or alternate-model flow. Confirm that references resolve within the active target model and never activate or move an object on the template character.
5. Check the Console for missing references or exceptions before saving the result as a prefab.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Character** or **Update Character** is disabled after choosing a template. | Check whether the template has Ultimate Character Locomotion, is the same object as the target, or contains Legacy Character Locomotion. | Choose a different, already configured Version 3 character. |
| Items copy even though **Copy Items** appears disabled. | Check whether a released Version 3 template build was used. | Use a temporary template with no Character Item beneath an active GameObject and remove any unwanted target clones. Recheck **Copy Abilities**, because the two visible controls are miswired. |
| Applying the template a second time creates duplicate items. | Inspect the target's **Item Placement** children. | Remove unintended Character Item clones, or reapply from a template with no Character Item beneath an active GameObject. |
| A warning remains in Reference Resolver. | Check whether the field still selects an object beneath the template character. | Assign the corresponding target object, set the field to **None** when it is not needed, and then inspect the component again after closing. |
| References for a second model cannot be resolved. | Check whether that model and its equivalent child hierarchy exist on the target. | Add and configure the target model first, or clear references that are not valid for the target. |
| A new character is missing health, item, ragdoll, or other supporting objects. | Check whether those dependencies existed only as child objects on the template. | Build the missing target-specific hierarchy with the appropriate setup workflow; template component copying covers only root-level Opsive components. |
| The target camera does not follow or switch perspective correctly. | Check whether a camera was configured for the target. | Set up the camera separately; it is outside the Character Manager template copy. |

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/)
- [Item Support](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Model Switching](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)

## Developer details

`CharacterManager.CopyTemplateCharacter` copies root Opsive components unless their type uses `IgnoreTemplateCopy`; `ModelManager` is excluded this way. It matches abilities, item abilities, and effects by exact type and occurrence before `ReferenceResolverWindow.ResolveFields` copies their values and maps compatible hierarchy references.

The released Version 3 item path calls `GetComponentsInChildren<CharacterItem>()` without including inactive objects and instantiates every returned item beneath Item Placement. Those clones are not added to the resolver's component, ability, or effect pairs. The visible **Copy Items** control is wired to `m_CopyAbilities`, while the actual clone path reads `m_CopyItems`.

---

<a id="page-ultimate-character-controller-character-movement-types"></a>

# Movement Types

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)

A Movement Type decides how directional input is interpreted and which way the character tries to face. Choose one that matches the intended control style, then pair it with a compatible camera View Type.

Movement Types do not move the Rigidbody directly. The active Movement Type supplies an input vector and a yaw change; **Ultimate Character Locomotion** still applies acceleration, root motion, gravity, collision, slopes, and ability restrictions.

## Before you begin

- Create or update the character through [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/). A player character normally receives its look source from the Camera Controller. An AI agent uses **Local Look Source**, while a networking integration supplies the appropriate remote look source.
- Configure the camera separately through [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/). The character's Movement Type and the camera's View Type are independent selections, so the controller cannot prevent an unsuitable pairing.
- Configure movement and look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) before judging a Movement Type.

## Choose a Movement Type

The [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/) section contains all supplied options.

### First person

- [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/) keeps movement relative to the camera and allows strafing and backward movement. Pair it with the [First Person Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/).
- [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/) lets the character move and rotate independently while the camera looks around. Pair it with the [First Person Free Look View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/).

### General third person

- [Third Person Adventure](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-adventure/) turns the character into the camera-relative travel direction and uses forward movement instead of strafing. Pair it with the [Adventure View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/).
- [Third Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/) keeps the character aligned for camera-relative strafing and backward movement. Pair it with the [Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/).
- [Third Person Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/) turns while moving left or right instead of strafing and is intended for generic or quadruped characters.
- [Third Person RPG](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/) provides RPG-style turning, strafing, and automatic forward movement. Pair it with the [RPG View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/).

### Specialized third person

- [Third Person Point & Click](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/) turns a click into a destination for the **Move Towards** and a pathfinding movement ability.
- [Third Person Pseudo3D (2.5D)](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/) constrains movement to a side-on composition and can follow a path. Pair it with the [Pseudo3D View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/).
- [Third Person Top Down](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-top-down/) supports camera-relative or world-relative movement and can face either the movement direction or the pointer. Pair it with the [Top Down View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/).

## Configure the character

For a new character:

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Choose **First**, **Third**, or **Both** from **Perspective**.
3. Choose **First Person Movement** and/or **Third Person Movement** for the perspectives in the build.
4. Finish the remaining character options, then select **Build Character**. Use **Update Character** when changing an existing character through the manager.

For an existing character that needs more than its original choice:

1. Select the character root and find **Ultimate Character Locomotion** in the Inspector.
2. Expand **Movement Types** and use the add control to add each required concrete type. Select a row to configure that type's own settings.
3. Use the row's **Active** control to choose the type that should start active.
4. Set **First Person Movement Type** and/or **Third Person Movement Type** to the types that should activate for those perspectives. These dropdowns appear only when a type for that perspective is available.
5. On the Camera Controller, choose the corresponding **First Person View Type** and/or **Third Person View Type**. Enable perspective switching only after both sides of the character-camera pairing exist.

There is no universal serialized Movement Type default on **Ultimate Character Locomotion**. The Character Manager populates the selections from the chosen setup, and the Inspector fills an empty perspective selection from the types already in the list.

### Editor checkpoint

Before entering Play Mode, confirm that:

- **Movement Types** contains one instance of every required concrete type and no unknown entries.
- exactly one row is selected as **Active**;
- each installed perspective has a **First Person Movement Type** or **Third Person Movement Type** selection;
- the Camera Controller has the corresponding View Type and is attached as the player's look source; and
- an AI agent has **Local Look Source** instead of relying on a player camera.

## How it runs

At runtime, the active Movement Type transforms the allowed directional input and calculates the requested yaw change. Character Locomotion then resolves that request against animation root motion, acceleration, gravity, colliders, slopes, moving platforms, and active abilities. A wall can therefore stop a valid forward request, and an ability can suppress input before the Movement Type is applied.

When the camera changes perspective, **Ultimate Character Locomotion** activates the configured first-person or third-person Movement Type and enables the default `FirstPerson` or `ThirdPerson` character State. The Camera Controller changes its View Type independently. Configure both defaults so that character facing and camera behavior change together.

### AI, networking, and root motion

- A Movement Type does not choose an AI destination. Navigation or an ability supplies the movement intent; the Movement Type still shapes any input passed through Character Locomotion. Use [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/) for the agent and pathfinding workflow.
- Core `SetMovementType` calls are local. In a multiplayer project, change the type on the authoritative character and replicate that choice through the supported networking integration when remote characters must use the same selection.
- Root-motion position and rotation belong to Character Locomotion and can also be changed by abilities or [States](https://opsive.com/support/documentation/ultimate-character-controller/state-system/). Switching Movement Type alone does not enable or disable root motion.

## Verify in Play Mode

1. Start with the intended row active and confirm that movement input produces the expected facing behavior.
2. Compare **Third Person Adventure** with **Third Person Combat** in otherwise equivalent setups. Adventure should turn into the travel direction; Combat should preserve camera-relative facing while strafing or moving backward.
3. Move into a wall and across a slope. The character should respect collision and locomotion settings even though the Movement Type continues to request movement.
4. Aim and use any equipped items. Their direction should agree with the chosen Movement Type, View Type, and look source.
5. If the character supports both perspectives, switch in both directions. The configured first-person and third-person Movement Types and View Types should activate together, and the `FirstPerson` and `ThirdPerson` States should follow the new perspective.
6. For an AI character, remove dependence on the player camera and verify that **Local Look Source** supplies the required look direction.
7. In a networked test, observe the owning and remote instances separately and confirm that any project-specific movement-type synchronization changes both.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Movement input causes a null-reference error or no valid type is active. | **Movement Types** may be empty, contain an unknown entry, or have no valid **Active** selection. | Add a compiled concrete type, select it as **Active**, and set the relevant perspective dropdown. |
| The Console reports that no look source is attached. | A camera-relative Movement Type has no `ILookSource`. | Attach the Camera Controller to a player character, add **Local Look Source** for an AI agent, or use the remote look source supplied by the networking integration. |
| The character moves, but faces differently from the camera design. | The Movement Type and View Type may not be a recommended pair. | Select the matching pair from the lists above, then retest movement, aim, and backward input. |
| Perspective switching activates the wrong control style. | **First Person Movement Type**, **Third Person Movement Type**, or the camera's corresponding View Type default is incorrect. | Set both character defaults and both camera defaults explicitly. |
| `SetMovementType` reports that it cannot find a type. | The requested concrete type is not present in **Movement Types**, or its script does not compile. | Resolve compiler errors and add the type to the list before requesting it from code. |
| The character fails during Movement Type initialization. | The same concrete class may have been added more than once. Released Version 3 indexes the list by the type's full name. | Keep only one instance of each concrete Movement Type. Use States to vary one type's settings instead of duplicating it. |
| The **Active** radio appears stale after a runtime/API switch. | The released Version 3 Inspector binds that radio to an obsolete serialized field name. | Treat `ActiveMovementType` and the movement-type change event as authoritative; reselect or reopen the component when inspecting the serialized start choice. |
| A custom type is grouped under the wrong perspective or does not update the expected default. | The released Version 3 Inspector classifies custom types from `FirstPerson` or `ThirdPerson` in the type's full name. | Include the appropriate token in the custom type name or namespace and keep `FirstPersonPerspective` consistent with it. |
| A remote character keeps a different Movement Type. | The core switch was performed only on one instance. | Replicate the type choice through the networking integration or project authority layer. |
| Root motion changes unexpectedly after a setup change. | Character Locomotion, an ability, or a State may be changing root-motion settings. | Inspect **Use Root Motion Position**, **Use Root Motion Rotation**, active abilities, and active States; do not use Movement Type selection as a root-motion toggle. |

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Camera View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)

## Developer reference

Call `SetMovementType` with a type already present in **Movement Types**. Do not assign `ActiveMovementType` directly: that property bypasses the outgoing and incoming lifecycle callbacks, stored perspective default, and change events.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;
using Adventure = Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.Adventure;
using Combat = Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.Combat;

public class MovementStyleSelector : MonoBehaviour
{
    private UltimateCharacterLocomotion m_CharacterLocomotion;

    private void Awake()
    {
        m_CharacterLocomotion = GetComponent<UltimateCharacterLocomotion>();
    }

    public void UseAdventureMovement()
    {
        m_CharacterLocomotion.SetMovementType(typeof(Adventure));
    }

    public void UseCombatMovement()
    {
        m_CharacterLocomotion.SetMovementType(typeof(Combat));
    }
}
```

`OnMovementTypeActiveEvent` and the `OnCharacterChangeMovementType` event both supply the Movement Type and an activation boolean. A switch first reports the outgoing type with `false`, then the incoming type with `true`.

### Create a custom Movement Type

Create a custom type only when the included options and their States cannot produce the required input and facing behavior. A concrete `MovementType` must identify its perspective, return the yaw change, and return the input vector passed to Character Locomotion.

This third-person example preserves the current yaw and passes directional input through unchanged. Its namespace contains `ThirdPerson` so the released Version 3 Inspector classifies it consistently.

```csharp
namespace MyGame.ThirdPerson.MovementTypes
{
    using Opsive.UltimateCharacterController.Character.MovementTypes;
    using UnityEngine;

    [System.Serializable]
    public class FixedForward : MovementType
    {
        public override bool FirstPersonPerspective => false;

        public override float GetDeltaYawRotation(
            float characterHorizontalMovement,
            float characterForwardMovement,
            float cameraHorizontalMovement,
            float cameraVerticalMovement)
        {
            return 0;
        }

        public override Vector2 GetInputVector(Vector2 inputVector)
        {
            return inputVector;
        }
    }
}
```

After the script compiles, add **Fixed Forward** to **Movement Types**, choose it in the appropriate perspective dropdown, and repeat the same Play Mode checks used for an included type.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types"></a>

# Included Movement Types

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)

Ultimate Character Controller includes two first-person and seven third-person Movement Types. Choose one by how the character should interpret input and face, then use a recommended camera View Type to make the controls and framing agree.

Start with **First Person Combat** for conventional first-person controls, **Third Person Adventure** for camera-relative travel, or **Third Person Combat** for strafing. Add a specialized type only when the game needs its particular control model.

## Choose a first-person Movement Type

| Movement Type | Choose it when | Character response | Recommended View Type |
| --- | --- | --- | --- |
| [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/) | The player should move relative to the camera with familiar first-person controls. | Forward and backward input move along the facing direction; horizontal input strafes without turning the character away from the camera. | [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) |
| [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/) | The camera should look around without always turning the character. | The character can keep its own movement direction while the camera rotates independently. Aiming can be configured to bring them back into alignment. | [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/) |

Both types use the standard directional input passed to Character Locomotion. Their important difference is whether camera yaw and character yaw remain coupled.

## Choose a third-person Movement Type

| Movement Type | Choose it when | Character response | Recommended View Type or dependency |
| --- | --- | --- | --- |
| [Third Person Adventure](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-adventure/) | Movement should feel like an exploration or action-adventure game. | The character turns into the camera-relative travel direction and uses forward movement rather than strafing. | [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) |
| [Third Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/) | The character should keep facing with the camera while moving in any direction. | Horizontal input strafes, and backward input moves backward without turning the character around. | [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) |
| [Third Person Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/) | A generic or quadruped character should turn through horizontal movement instead of strafing. | Left and right input turn the character while it moves; forward and backward input retain the current facing direction. | Adventure, Combat, RPG, Pseudo3D, and Top Down View Types all explicitly support this Movement Type; choose the framing that matches the scene. |
| [Third Person Point & Click](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/) | The player should click a world location and let navigation move the character there. | Direct movement input is replaced by a screen-point raycast and a destination request. | [Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/), plus **Move Towards** and a pathfinding movement ability |
| [Third Person Pseudo3D (2.5D)](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/) | Movement should follow a side-on composition, optionally along a curved path. | Horizontal input follows the view or assigned path; depth movement can be allowed or blocked. | [Pseudo3D (2.5D)](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/) |
| [Third Person RPG](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/) | The game needs RPG-style turning, strafing, camera rotation, or automatic forward movement. | It adds rotate, turn, and auto-move input events to the usual directional input. | [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) |
| [Third Person Top Down](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-top-down/) | The character is viewed from above and should move relative to the camera or world axes. | The character can face its movement direction or the pointer while moving across the camera plane. | [Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/) |

The package's recommendation metadata also permits **Four Legged** with the Adventure, Combat, RPG, Pseudo3D, or Top Down View Type. That flexibility changes the camera framing, not the Four Legged rule that horizontal movement turns rather than strafes.

## Configure a comparison

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Choose **First**, **Third**, or **Both** from **Perspective**. Choose **First Person Movement** and/or **Third Person Movement**, then use **Build Character** for a new character or **Update Character** for an existing one.
3. To compare more than one type on an existing character, select the character root, find **Ultimate Character Locomotion**, expand **Movement Types**, and add each different concrete type.
4. Select a row to configure its settings. Choose its **Active** control for the next test, and set **First Person Movement Type** or **Third Person Movement Type** to the default that should activate for that perspective.
5. On the Camera Controller, add and select the corresponding View Type. The camera and character selections are stored independently.
6. Confirm the required input and dependencies. In particular, Point & Click requires [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) and a [pathfinding movement ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/); RPG requires its additional input mappings.

### Editor checkpoint

Before Play Mode, verify that:

- every type being compared appears once in **Movement Types** and exactly one row is **Active**;
- **First Person Movement Type** and/or **Third Person Movement Type** names a type already in the list;
- the Camera Controller uses a recommended View Type and is attached to the player character as its look source;
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) contains the mappings required by the chosen type; and
- an AI agent has **Local Look Source** and the ability or navigation system that supplies its movement intent.

## What the Movement Type does not choose

- **Root motion:** **Use Root Motion Position**, **Use Root Motion Rotation**, abilities, and [States](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) control whether animation deltas are applied. A Movement Type only shapes input and requested yaw.
- **Camera position and rotation:** the active View Type owns the view. A recommendation is a compatible pairing, not an automatic link between the two selections.
- **Collision and gravity:** Character Locomotion still resolves walls, slopes, steps, platforms, gravity, and acceleration after the Movement Type requests motion.
- **AI decisions:** a Movement Type is not a patrol, destination, or pathfinding system. [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/) and abilities supply that intent.
- **Network authority:** changing a Movement Type through the core character API is local. A multiplayer integration or project authority layer must replicate the selected type when remote characters need the same result.

## Verify in Play Mode

1. Compare **Third Person Adventure** and **Third Person Combat** with their matching View Types. Press left, right, and backward: Adventure should turn into the travel direction, while Combat should strafe or move backward without reversing its facing.
2. Compare **First Person Combat** and **First Person Free Look**. Rotate the camera while stationary and while moving; only Free Look should preserve independent character and camera directions.
3. For **Four Legged**, press left and right and confirm that the character turns instead of strafing. Repeat with the chosen View Type to confirm that the framing still suits the character.
4. For **Point & Click**, click a valid floor point away from UI. The character should request the destination through Move Towards and the configured pathfinding movement ability.
5. For **Pseudo3D** or **Top Down**, test every allowed input direction at the camera's actual gameplay angle. Confirm that blocked depth input, path orientation, camera-relative movement, and facing choices behave as configured.
6. For **RPG**, test turn, rotate, and auto-move separately so a missing mapping is easy to identify.
7. If the character supports both perspectives, switch in both directions and confirm that the selected Movement Type and View Type change together.
8. Test a wall, slope, root-motion animation, and any active movement ability. Those systems should still constrain or modify the request after the Movement Type processes input.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character strafes when it should turn, or turns when it should strafe. | The wrong Movement Type is active. | Use Adventure for turn-into-travel movement, Combat for strafing, or Four Legged for turn-through-horizontal-input movement. |
| The character and camera disagree about forward. | The Movement Type and View Type are not a recommended pair, or the look source is missing. | Select the pairing in the tables above and attach the Camera Controller to the player character. |
| Point & Click logs a missing-ability error or never starts moving. | **Move Towards**, a `PathfindingMovement` ability, the click mapping, the camera look source, or a valid floor hit may be missing. | Add both required abilities, verify the pointer input, and test a solid floor point outside the UI. |
| RPG turn, rotate, or auto-move does nothing. | Its extra input mapping name is absent from the active input implementation. | Configure the mapping named by the RPG Movement Type and verify its value independently. |
| Perspective switching activates the wrong type. | **First Person Movement Type**, **Third Person Movement Type**, or the camera defaults are unset or mismatched. | Set both character defaults and the corresponding camera View Type defaults explicitly. |
| The same type causes an initialization failure after being added twice. | Released Version 3 indexes configured Movement Types by each class's full name. | Keep only one instance of each concrete type; use States to vary that instance's settings. |
| The **Active** radio looks unchanged after a switch from code. | The released Version 3 Inspector binds its refresh to an obsolete serialized field name. | Treat `ActiveMovementType` and the movement-type change event as authoritative; reselect or reopen the component to inspect the serialized start choice. |
| Root-motion distance or turning differs from the comparison. | Character Locomotion, an ability, or a State is applying animation motion in addition to the Movement Type's request. | Check root-motion settings and active States before changing the Movement Type. |
| A remote character keeps a different type. | The type selection changed only on the local instance. | Replicate the selection through the networking integration or authority layer. |

## Related tasks

- [Movement Types overview and custom types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Camera View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)

## Developer note

At runtime, call `UltimateCharacterLocomotion.SetMovementType` only for a concrete type already present in **Movement Types**. The switch deactivates the outgoing type, activates the incoming type, updates the stored default for that perspective, and invokes `OnMovementTypeActiveEvent` and `OnCharacterChangeMovementType`. Do not assign `ActiveMovementType` directly because that bypasses this lifecycle. The [Movement Types overview](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) contains the code and custom-type contract.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-first-person-combat"></a>

# First Person Combat

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/)

Choose First Person Combat for a conventional first-person controller where camera yaw turns the character and directional input supports forward movement, backward movement, and strafing. It suits shooters, melee combat, and interactions where body facing, item use, and the view should agree.

Use [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/) instead when the player should look around without turning the character or redirecting its forward movement.

## Set up the character and camera

For a new or manager-owned character:

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Assign the scene **Character** and set **Perspective** to **First** or **Both**.
3. Set **First Person Movement** to **First Person Combat**.
4. Complete the remaining character choices, then select **Build Character** or **Update Character**.
5. Select the character root and expand **Ultimate Character Locomotion > Movement Types**. Confirm **First Person Combat** is present and selected in **First Person Movement Type**.

For an existing character that is configured directly:

1. Select the character root and expand **Movement Types** on **Ultimate Character Locomotion**.
2. Use the add control to add **First Person Combat**. Keep only one instance of that concrete type.
3. Select its radio button in the **Active** column when the character should start in first person.
4. Select **First Person Combat** in **First Person Movement Type** when the character contains more than one perspective or first-person option.

Pair the character with the matching camera:

1. Select the Camera Controller, assign its **Character**, and expand **View Types**.
2. Add and activate [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/).
3. When the camera supports both perspectives, select it in **First Person View Type**.
4. Configure movement and look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/), then verify that the Camera Controller is attached as the player's look source.

## Editor checkpoint

Before entering Play Mode, confirm that:

- **Movement Types** contains one **First Person Combat** entry;
- **First Person Movement Type** points to that entry and its radio is active for a first-person start;
- the Camera Controller uses the First Person Combat View Type and its **Character** is assigned;
- horizontal, forward, and look input all respond in the Input setup; and
- root-motion and motor settings are configured on **Ultimate Character Locomotion**, not on the selected Movement Type.

Selecting First Person Combat shows no option-specific fields. The released class declares no serialized settings of its own; an empty detail area is expected.

## How it moves and faces

First Person Combat leaves the two-axis movement input unchanged:

| Input | Runtime result |
| --- | --- |
| Forward | The character moves along its forward direction. |
| Backward | The character moves backward without turning around. |
| Left or right | The character strafes while preserving its view-facing orientation. |
| Diagonal | Ultimate Character Locomotion combines and limits both axes before applying its movement settings. |

The Movement Type obtains the attached look source's gameplay direction and requests the shortest yaw change from the current character rotation to that direction. Camera pitch therefore aims the view up or down while the body remains upright around its configured **Up** direction.

With normal motor rotation, **Motor Rotation Speed** controls how quickly the character closes a yaw difference. The camera can lead briefly when that value is deliberately low. Movement still passes through Ultimate Character Locomotion, so acceleration, damping, backward speed, collisions, slopes, abilities, and States can change the final motion even though the Movement Type preserves the input vector.

## Choose movement and rotation ownership

First Person Combat does not enable root motion or choose input settings. Make those decisions on the systems that own them:

| Goal | Configure | Expected result |
| --- | --- | --- |
| Responsive first-person strafing driven by the controller motor | Keep **Use Root Motion Position** and **Use Root Motion Rotation** disabled, then tune **Motor Acceleration**, **Motor Damping**, **Motor Backwards Multiplier**, and **Motor Rotation Speed**. | Input produces direct motor movement while the character turns toward camera yaw. |
| Animation-authored movement with Combat facing | Enable **Use Root Motion Position** only when the locomotion clips contain suitable forward, backward, and strafe displacement. | The same directional input drives Animator parameters, while animation supplies position. |
| Animation- or ability-authored turns | Enable **Use Root Motion Rotation**, or let a specific ability override it, only when the active animation supplies the intended yaw. | Character Locomotion uses animation rotation instead of the Combat yaw request, and the Combat camera follows the character rotation. |
| A reticle and equipped item must agree with movement | Use the paired Combat View Type, the correct look source, and the item's first-person aim setup. | Body facing, view direction, and item use communicate the same target. |
| The camera should look aside without turning the body | Change both character and camera to the Free Look pair. | Camera yaw becomes independent; movement stays relative to character facing unless **Rotate With Camera On Aim** is enabled on Free Look. |

Do not use a Movement Type switch as a root-motion toggle. Abilities and States can override root-motion position or rotation at runtime, so test the actual combat, interaction, jump, and positioning animations that the character will use.

## Compare with First Person Free Look

The quickest comparison is to stand still and rotate the camera horizontally:

| Option | Character while looking | Movement direction | Aim choice |
| --- | --- | --- | --- |
| **First Person Combat** | Turns toward the Camera Controller's gameplay look direction. | Forward, backward, and strafe remain aligned with the view-facing body. | Body and camera remain coordinated without an additional setting. |
| [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/) | Normally keeps its existing yaw while the camera looks independently. | Input remains relative to the character, so forward can differ from the camera view. | **Rotate With Camera On Aim** can turn the body toward the camera during an input-started Aim. |

Changing only the camera or only the Movement Type produces a mixed control scheme. Switch the recommended pair together.

## Verify in Play Mode

1. Stand still and rotate the camera through a full horizontal turn. The character should turn toward camera yaw while vertical look changes pitch without tilting the body.
2. Hold forward, backward, left, and right separately. Backward input should not turn the character around, and left and right should strafe.
3. Hold a diagonal input. The character should move diagonally without gaining unintended speed or changing away from camera-facing yaw.
4. Aim or use each relevant item. Reticle or view direction, character facing, and the item's hit or projectile direction should identify the same target.
5. Lower **Motor Rotation Speed** temporarily. Confirm that the body follows the view more slowly, then restore the intended value.
6. Test one clip with **Use Root Motion Position** and one with **Use Root Motion Rotation**. Confirm position and yaw are authored by the expected source instead of fighting the motor.
7. If both perspectives are installed, switch away and back. First Person Combat should become active on both Ultimate Character Locomotion and Camera Controller.
8. Replace both sides temporarily with the Free Look pair. Looking sideways while standing or moving should now leave body yaw independent, making the distinction visible.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console reports that the character has no look source. | Camera Controller is not attached to the character, or an AI character has no Local Look Source. | Assign **Character** on Camera Controller for the player. Configure the appropriate local or integration-owned look source for a nonplayer character. |
| The camera turns but the character keeps its old yaw. | First Person Combat may not be the active Movement Type, or root-motion rotation is overriding its yaw request. | Select First Person Combat in **First Person Movement Type** and the active row; then disable or correct the root-motion rotation source for the test. |
| Left or right input turns into the travel direction instead of strafing. | A different Movement Type is active. | Activate First Person Combat and retest all four cardinal inputs. |
| The body follows the camera with a noticeable delay. | **Motor Rotation Speed** is low, the character's local **Time Scale** is reduced, or an ability is controlling rotation. | Test without the ability or State, restore normal time scale, and tune Motor Rotation Speed for the intended response. |
| Movement looks correct but animations face or travel incorrectly. | The Animator may not contain matching backward and strafe motion, especially with root-motion position. | Verify horizontal and forward Animator parameters, then use clips whose root motion matches all supported directions or disable root-motion position. |
| The reticle or item fires away from the camera-facing target. | Movement Type, View Type, look source, or item aim configuration is mismatched. | Activate the Combat pair, confirm the camera is the look source, and test the item with procedural recoil or spread removed before restoring it. |
| Perspective switching returns to another first-person style. | **First Person Movement Type** or **First Person View Type** names another option. | Set both defaults explicitly, then switch perspectives twice and verify both active rows. |

## Related pages

- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/)
- [First Person Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/)
- [First Person Free Look View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)

## Developer details

The released class is `Opsive.UltimateCharacterController.FirstPersonController.Character.MovementTypes.Combat`. It is a serializable `MovementType`, reports `FirstPersonPerspective` as `true`, declares no serialized fields, and returns the supplied `Vector2` unchanged from `GetInputVector`.

`GetDeltaYawRotation` reads `m_LookSource.LookDirection(true)`, builds a rotation around the character's **Up** direction, and returns the clamped relative yaw. In editor builds, a missing look source logs an error and returns zero. Combat inherits the normal non-independent-look result from `MovementType`; Free Look overrides that result and normally returns zero yaw unless its aim option is active.

There is no `RecommendedViewType` attribute on the Movement Type. The pairing is declared in the opposite direction: `Opsive.UltimateCharacterController.FirstPersonController.Camera.ViewTypes.Combat` has `RecommendedMovementType(typeof(Character.MovementTypes.Combat))`. Camera Controller checks that attribute when it initially attaches the character and warns in the editor if the active Movement Type is not the recommended type.

The base `CharacterLocomotion` source defaults **Use Root Motion Position** and **Use Root Motion Rotation** to disabled, **Motor Rotation Speed** to `0.15`, and **Motor Backwards Multiplier** to `0.7`. Character Manager choices, templates, abilities, and States can replace those serialized or runtime values; treat the configured character as authoritative.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-first-person-free-look"></a>

# First Person Free Look

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/)

Choose First Person Free Look when the player should look around without automatically turning the character or redirecting its forward movement. It suits observation, mounted movement, body-aware interaction, and any control scheme where camera direction and character facing intentionally differ.

Use [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/) instead when camera yaw, character facing, movement, reticle, and item-use direction should remain coordinated like a conventional first-person game.

## Set up the character and camera

For a new or manager-owned character:

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Assign the scene **Character** and set **Perspective** to **First** or **Both**.
3. Set **First Person Movement** to **First Person Free Look**.
4. Complete the remaining character choices, then select **Build Character** or **Update Character**.
5. Select the character root and expand **Ultimate Character Locomotion > Movement Types**. Confirm **First Person Free Look** is present and selected in **First Person Movement Type**.

For an existing character that is configured directly:

1. Select the character root and expand **Movement Types** on **Ultimate Character Locomotion**.
2. Use the add control to add **First Person Free Look**. Keep only one instance of that concrete type.
3. Select its radio button in the **Active** column when the character should start in first person.
4. Select **First Person Free Look** in **First Person Movement Type** when the character contains more than one perspective or first-person option.
5. Select the Free Look row and decide whether to enable **Rotate With Camera On Aim**. It is disabled by default.

Pair the character with the matching camera:

1. Select the Camera Controller, assign its **Character**, and expand **View Types**.
2. Add and activate [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/).
3. When the camera supports both perspectives, select it in **First Person View Type**.
4. Configure the camera's **Yaw Limit**, **Yaw Limit Lerp Speed**, and **Base Rotation Type** for the intended look arc.
5. Configure movement, look, and Aim mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/), then verify that the Camera Controller is attached as the player's look source.

## Editor checkpoint

Before entering Play Mode, confirm that:

- **Movement Types** contains one **First Person Free Look** entry;
- **First Person Movement Type** points to that entry and its radio is active for a first-person start;
- **Rotate With Camera On Aim** matches the intended aim behavior;
- Camera Controller uses the First Person Free Look View Type and its **Character** is assigned;
- the View Type's yaw range and base rotation have an intentional owner; and
- root-motion and motor settings are configured on **Ultimate Character Locomotion**, not mistaken for Free Look camera settings.

## How independent look runs

During ordinary look input, First Person Free Look requests no character yaw change. Its matching View Type can rotate the camera within its configured yaw limits while the body retains its existing forward direction.

The Movement Type also reports independent look for character look-direction queries. This allows the view and body orientation to differ, but it does not guarantee that an item fires through the center of the visible camera. The paired View Type derives gameplay look from the first-person objects when present, or from the Camera Controller anchor otherwise. Test the actual item, reticle, and animation together.

Free Look leaves the two-axis movement input unchanged:

| Input | Runtime result |
| --- | --- |
| Forward | The character moves along its own forward direction, even when the camera is looking aside. |
| Backward | The character moves backward without turning around. |
| Left or right | The character strafes relative to its current body orientation. |
| Diagonal | Ultimate Character Locomotion combines and limits both axes before applying its movement settings. |

Ultimate Character Locomotion still owns acceleration, damping, backward speed, collisions, slopes, abilities, root motion, and States. Free Look changes the facing relationship; it is not a separate movement motor.

## Choose aim, camera, and rotation ownership

| Goal | Configure | Expected result |
| --- | --- | --- |
| Look around without ever turning the body automatically | Leave **Rotate With Camera On Aim** disabled. | Ordinary look and Aim preserve independent character yaw. |
| Turn the body toward the view only while the player aims | Enable **Rotate With Camera On Aim**, keep a usable **Motor Rotation Speed**, and start Aim from player input. | While that Aim is active, the character requests the shortest yaw toward the Camera Controller's gameplay look direction. |
| Keep a glance relative to a turning character | On the Free Look View Type, set **Base Rotation Type** to **Rotate With Character**. | Character rotation moves the camera's yaw baseline while preserving the relative look offset. |
| Keep the look arc relative to a rotating platform | Set **Base Rotation Type** to **Rotate With Moving Platform**. | The platform rotates the camera baseline while the character stands on it. |
| Let animation author character turns | Enable **Use Root Motion Rotation**, or let an ability override it, only when the active clip supplies the intended yaw. | Animation rotation takes ownership; the Free Look aim-yaw request is not applied while root-motion rotation is active. |
| Let animation author displacement | Enable **Use Root Motion Position** only with suitable forward, backward, and strafe clips. | The unchanged directional input drives Animator parameters while animation supplies position. |

**Rotate With Camera On Aim** responds only to the `Aim` ability event whose `inputStart` value is true. A programmatically started Aim does not change the Free Look Movement Type's alignment state. This keeps scripted item or camera states from unexpectedly turning the body.

The Movement Type's aim option and the View Type's **Base Rotation Type** solve different problems. The first can rotate the character toward the camera; the second decides whether character or platform rotation moves the camera's yaw baseline.

## Compare with First Person Combat

The clearest comparison is to look 60 degrees to one side, then press forward:

| Option | Character while looking | Forward movement | Aim behavior |
| --- | --- | --- | --- |
| **First Person Free Look** | Normally keeps its existing yaw while the camera looks independently. | Continues along character forward, not visible camera forward. | Optional **Rotate With Camera On Aim** aligns only during input-started Aim. |
| [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/) | Turns toward the Camera Controller's gameplay look direction. | Follows the view-facing body direction. | Camera and body remain coordinated without the Free Look aim option. |

Changing only the camera or only the Movement Type creates a mixed control scheme. Switch the recommended character and camera pair together.

## Verify in Play Mode

1. Stand still and rotate the camera to both yaw limits. The camera should stop or ease toward each boundary without turning the character.
2. Look to one side and press forward, backward, left, and right. Movement should remain relative to character facing rather than the visible camera direction.
3. Set the View Type's **Base Rotation Type** to each mode the project uses. Turn the body or its moving platform and confirm that only the selected source moves the yaw baseline.
4. Start Aim from player input with **Rotate With Camera On Aim** disabled. Character yaw should remain independent.
5. Enable the option and repeat. The character should rotate toward the gameplay look direction during Aim and stop requesting that alignment when Aim ends.
6. Start the same Aim programmatically. The Movement Type should not change its aiming state from that non-input event.
7. Equip and use each relevant item while looking away from body forward. Confirm the reticle or feedback communicates the actual item-use direction.
8. Test **Use Root Motion Position** and **Use Root Motion Rotation** separately. Confirm animation and motor ownership do not fight the intended independent-look behavior.
9. Replace both sides temporarily with the Combat pair. Standing look and forward movement should now follow camera-facing yaw, making the difference visible.
10. If both perspectives are installed, switch away and back. First Person Free Look should become active on both Ultimate Character Locomotion and Camera Controller.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character turns whenever the camera turns. | First Person Combat may still be active on the character, or root motion, an ability, or a State owns rotation. | Activate Free Look in **First Person Movement Type**, then test with root-motion rotation and rotation-changing abilities disabled. |
| The camera turns independently, but forward follows an unexpected direction. | Free Look deliberately preserves body-relative input; the character may already be facing away from the camera. | Show character facing through the body or reticle, or use the Combat pair when forward must follow camera yaw. |
| **Rotate With Camera On Aim** does nothing. | Aim may have started programmatically, no Aim ability may be active, root-motion rotation may own yaw, or the character lacks a look source. | Test an input-started Aim with the Camera Controller attached and root-motion rotation disabled. Then restore the intended ownership one piece at a time. |
| The body aligns for Aim but turns too slowly. | **Motor Rotation Speed**, character **Time Scale**, or an active State affects non-root motor rotation. | Test at normal time scale without the State, then tune Motor Rotation Speed for the desired aim response. |
| The camera's look arc follows the wrong object. | **Base Rotation Type** does not match character-, platform-, or world-relative behavior. | Select **None**, **Rotate With Character**, or **Rotate With Moving Platform** deliberately and retest both yaw limits. |
| An item fires somewhere other than camera center. | Free Look intentionally allows camera, body, and first-person object directions to differ. | Use the Combat pair when camera-centered firing is required, or make the reticle and item pose show the true gameplay direction. |
| Movement looks correct but root-motion clips travel or turn incorrectly. | The animation does not provide matching backward/strafe displacement or an intended rotation. | Use compatible clips, disable the affected root-motion channel, or override it only in the ability or State that owns that animation. |
| Perspective switching returns to another first-person style. | **First Person Movement Type** or **First Person View Type** names another option. | Set both defaults explicitly, then switch perspectives twice and verify both active rows. |

## Related pages

- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/)
- [First Person Free Look View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/)
- [First Person Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)

## Developer details

The released class is `Opsive.UltimateCharacterController.FirstPersonController.Character.MovementTypes.FreeLook`. It is a serializable `MovementType`, reports `FirstPersonPerspective` as `true`, returns the supplied `Vector2` unchanged from `GetInputVector`, and always returns `true` from `UseIndependentLook`.

Its only serialized field is `RotateWithCameraOnAim`, which defaults to `false`. During `Awake`, the type registers for `OnAimAbilityStart(bool aim, bool inputStart)`. It ignores events whose `inputStart` value is false. While the option and input-started Aim state are both true, `GetDeltaYawRotation` reads `m_LookSource.LookDirection(true)` and returns the clamped relative yaw around the character's **Up** direction; otherwise it returns zero. `OnDestroy` unregisters the same event.

There is no `RecommendedViewType` attribute on the Movement Type. The pairing is declared in the opposite direction: `Opsive.UltimateCharacterController.FirstPersonController.Camera.ViewTypes.FreeLook` has `RecommendedMovementType(typeof(Character.MovementTypes.FreeLook))`. Camera Controller checks that attribute when it initially attaches the character and warns in the editor if the active Movement Type is not the recommended type.

The paired View Type source defaults **Yaw Limit** to `-60` through `60`, **Yaw Limit Lerp Speed** to `0.7`, and **Base Rotation Type** to **None**. Character Manager, templates, and States can replace those serialized values; treat the configured Camera Controller as authoritative.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-adventure"></a>

# Third Person Adventure

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-adventure/)

Third Person Adventure gives an exploration character camera-relative travel without a permanent strafe stance: orbit the camera independently, then press a direction to turn the character toward it and move forward. Choose it when free exploration matters more than always facing the camera, and pair it with the [Third Person Adventure View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/).

Use [Third Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/) for a character that should continually face the camera's gameplay look direction, or [Third Person RPG](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/) for separate strafe, turn, rotate, and automatic-movement controls.

## Before you begin

- Start with a working third-person character, player input, and a Camera Controller assigned to that character.
- Prepare forward locomotion and turning animation. Adventure normally removes lateral and negative processed movement, so ordinary left, right, and backward commands should still look like forward travel after the character turns.
- If Aim or item use should allow strafing and backing away, also prepare those animations and test their Animator states separately.
- Decide whether locomotion uses the motor or root motion before tuning turn response. Adventure supplies a travel direction and yaw request; Character Locomotion and the Animator still determine the final motion.

## Set up the Adventure pair

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the new or existing character, choose **Third** from **Perspective**, and choose **Adventure** from **Third Person Movement**.
3. Complete the character's model, Animator, input, item, and ability choices. Select **Build Character** for a new character or **Update Character** for an existing one.
4. Select the character root and expand **Ultimate Character Locomotion > Movement Types**. Confirm **Third Person Adventure** is present and selected in the **Active** column. When both perspectives are installed, also choose **Adventure** in **Third Person Movement Type**.
5. Select the camera, assign the character on **Camera Controller**, and expand **View Types**. Add **Third Person Adventure** if needed and select it in the **Active** column. When both perspectives are installed, also choose **Adventure** in **Third Person View Type**.
6. Verify that the active input setup supplies the character's horizontal and forward axes and the camera's horizontal and vertical look input.
7. Enter Play Mode and test ordinary travel before enabling Aim, Use, root-motion overrides, or state-driven changes.

The released Adventure View Type explicitly recommends the Adventure Movement Type. Keeping both rows active makes camera orbit, movement-facing, and the Inspector's perspective selections agree.

## Understand ordinary movement

Adventure turns the character toward the requested movement direction after rotating that direction by the camera's Transform. It then converts the processed two-axis movement into forward magnitude. The result is camera-relative travel using forward locomotion instead of a standing strafe or backward pose.

| Input | Observable result |
| --- | --- |
| Forward | The character travels in the camera's forward direction. It does not need to change yaw when it already faces that direction. |
| Left | The character turns toward camera-left and travels forward in that direction. |
| Right | The character turns toward camera-right and travels forward in that direction. |
| Backward | The character turns toward the camera and travels forward toward it. It does not use ordinary backward locomotion. |
| Diagonal | The character turns toward the camera-relative diagonal and travels forward at the requested magnitude. |
| No movement | Adventure requests no movement-driven yaw, so orbiting the camera alone does not turn the character. |

Adventure does not force a sprint-scaled component above `1` back to unit input. Its processed forward value is capped at the largest absolute input component, so final speed still depends on active abilities, Animator motion, motor settings, states, slopes, and collisions.

## Choose Aim and Use behavior

Adventure deliberately stops converting the processed movement vector in two target-facing situations:

- An **Aim** ability that started from player input preserves the original horizontal and forward values until that same input-started Aim stops. The character can therefore strafe or move backward while the aiming system controls its target-facing behavior.
- An active **Use** ability also preserves the original values when one of its usable actions is currently rotating a Character Item toward the target. On a **Usable Action**, the controlling option is **Face Target**, which is enabled by default in the released source.

These are temporary exceptions, not a second Adventure mode. Once input-started Aim and every target-facing Use have stopped, Adventure resumes forward-only conversion. A programmatically started Aim reports that it did not start from input, so Adventure does not enable its Aim exception for that start. Test scripted aiming explicitly if it should have the same locomotion result.

The controller stores **Raw Input Vector** before the Movement Type converts anything. During ordinary Adventure travel, the raw vector can still contain left, right, or negative forward input even though the processed **Input Vector** becomes forward-only. Abilities that read raw input can therefore react to the player's original command. Do not assume both values will show the same direction while diagnosing an ability.

## Choose motor or root-motion movement

Third Person Adventure has no option-specific serialized fields and does not force either root-motion setting. Make the choice on **Ultimate Character Locomotion**:

- Leave **Use Root Motion Position** disabled when the motor should supply displacement. Tune the shared acceleration, damping, and speed-related states for the intended travel response.
- Enable **Use Root Motion Position** when the locomotion clips should supply displacement. Forward and turning clips must cover Adventure's travel relationship without sliding.
- Leave **Use Root Motion Rotation** disabled when the controller should apply Adventure's yaw request directly through the motor.
- Enable **Use Root Motion Rotation** only when the animation set supplies compatible turning. Test sharp camera-relative direction changes rather than assuming a forward clip can also turn cleanly.
- A **Usable Action** can temporarily request **Force Root Motion Position** or **Force Root Motion Rotation** during item use. Treat those as action-specific overrides and verify the transition into and out of each action.

The underlying released fields initialize with both root-motion choices disabled, but the Character Manager, templates, presets, states, or an existing prefab can configure different values. The selected character's runtime Inspector is the authoritative configuration.

## How it runs

1. **Ultimate Character Locomotion Handler** reads the character movement axes and asks the active Adventure Movement Type for a yaw change using the attached look source.
2. With nonzero movement, Adventure rotates the input direction by the camera Transform and requests the shortest yaw change from the character's current rotation to that direction.
3. **Ultimate Character Locomotion** stores the unmodified movement as **Raw Input Vector**. If positional input is allowed, Adventure then converts the processed vector to forward magnitude unless an applicable Aim or target-facing Use exception is active.
4. Abilities, effects, Character Locomotion, and the Animator apply the resulting request through their normal priority, root-motion, gravity, slope, collision, and state rules.
5. In its default configuration, the matching Adventure View Type retains its independent camera yaw. Beginning movement changes the character's travel-facing, not the camera's stored orbit.

Adventure requires a look source for its camera-relative yaw calculation. A player character normally receives it from the attached Camera Controller; an AI character needs a suitable local look source. In the Unity Editor, movement with no look source logs an error instead of producing a useful yaw result.

### Editor checkpoint

Before Play Mode, confirm that:

- **Third Person Adventure** is active on both the character and camera;
- both-perspective characters select Adventure in **Third Person Movement Type** and **Third Person View Type**;
- the Camera Controller's **Character** reference points to this character and provides its look source;
- horizontal, forward, and camera-look inputs resolve in the active input implementation;
- the Animator has forward movement and turning coverage, plus strafe/backward coverage for any Aim or Use exception;
- **Use Root Motion Position** and **Use Root Motion Rotation** match the animation set; and
- each usable action's **Face Target**, **Force Root Motion Position**, and **Force Root Motion Rotation** choices are intentional.

## Compare Adventure, Combat, and RPG

| Movement Type | Facing and processed movement | Choose it when |
| --- | --- | --- |
| **Adventure** | Nonzero input turns the character toward a camera-relative direction, then normally becomes forward-only movement. Input-started Aim and target-facing Use can temporarily preserve strafe/backward input. | Exploration should allow free camera orbit and natural turn-to-travel movement. |
| [Third Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/) | The character continually turns toward the look source and always preserves forward, backward, and strafe input. | Camera-facing combat and over-the-shoulder strafing are the default relationship. |
| [Third Person RPG](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/) | Ordinary movement preserves facing; separate mappings control turn, camera-aligned rotation, and automatic forward movement. | The project needs classic RPG-style independent movement and turn controls. |

Compare the three with the same character, scene route, camera offset, input device, and root-motion configuration. Otherwise animation or camera differences can hide the Movement Type behavior you are evaluating.

## Verify in Play Mode

1. Stand still and orbit the camera through several angles. The camera should move while the character keeps its current facing.
2. At each orbit angle, press forward, left, right, backward, and diagonals. The character should turn toward the camera-relative command and travel using forward locomotion.
3. Alternate quickly between opposite directions. Confirm the turn response is controlled and the character does not slide, snap unexpectedly, or play an ordinary backward pose.
4. Start Aim through its mapped player input. Move sideways and backward; the processed movement should retain those directions. Stop Aim and confirm the next ordinary movement returns to turn-and-travel behavior.
5. If the project starts Aim from code, test that path separately. Released Adventure only enables the Aim exception for an input-started Aim.
6. Use one item with **Face Target** enabled and one with it disabled. The target-facing use should allow the original strafe/backward input while active; ordinary use should keep Adventure's normal conversion unless another exception is active.
7. Test locomotion and item actions with the configured root-motion settings. Verify direction changes, action entry, action exit, slopes, moving platforms, and collision rather than checking only an idle animation.
8. Switch to Third Person Combat and RPG, then back to Adventure. Confirm each pair restores the expected View Type, Movement Type, input behavior, and facing.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Left/right input always strafes instead of turning into forward travel. | Aim, a target-facing Use, or a different Movement Type may be active. | Stop Aim and Use, then activate Third Person Adventure on the character and retest ordinary movement. |
| The character faces the camera even while no input is held. | Third Person Combat or an item/ability rotation may own facing. | Activate the complete Adventure pair and disable other facing overrides while isolating the movement test. |
| Orbiting the camera does not change the next travel direction. | The Adventure Movement Type may have no look source, or the camera may be attached to another character. | Assign the correct **Character** on Camera Controller and confirm the Adventure Movement Type is active before moving. |
| The Console reports that the character has no look source. | The Camera Controller or an AI local look source was not attached. | Attach the intended look source before sending movement input. |
| Aim still uses forward-only movement. | Aim may have started from code, may no longer be active, or the wrong Adventure row may be selected. | Test with the mapped Aim input first. If scripted Aim must preserve input, own that policy in project-specific code instead of assuming released Adventure will do so. |
| Item use never allows strafing or backward movement. | The active usable action may have **Face Target** disabled or may not currently be using its Character Item as the face target. | Enable **Face Target** on the intended action and verify that action starts through the Use ability. |
| After one item stops, Adventure still preserves strafe input. | Another target-facing Use may still be active. | Inspect all active Use abilities and stop the remaining target-facing action; Adventure tracks more than one active Use. |
| An ability reacts to left/back input although the character moves forward. | The ability may read **Raw Input Vector**, which is captured before Adventure converts the processed input. | Decide whether that ability should use raw player intent or processed locomotion, then configure or extend it accordingly. |
| Turning slides, double-moves, or feels delayed. | Root-motion position/rotation may not match the Animator clips, or both animation and motor tuning may contribute an unsuitable result. | Test with root motion disabled, then enable position and rotation one at a time and retune the matching clips and shared locomotion values. |
| The camera recenters behind the character when free orbit should remain. | A different View Type or a state may be changing the camera relationship. | Activate Third Person Adventure on the camera and inspect active camera states; use RPG only when follow-behind behavior is wanted. |

## Related tasks

- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Third Person Adventure View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/)
- [Third Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/)
- [Third Person RPG](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/)
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/)
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/)

## Developer details

The released Version 3.2.0 type is `Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.Adventure`. It is serializable, reports `FirstPersonPerspective` as `false`, and declares no serialized Adventure-specific settings.

`GetDeltaYawRotation` uses the look source Transform rotation to convert the normalized horizontal/forward input into world-relative travel, projects that result against the character's up direction, and returns the clamped local yaw difference. It returns zero when both movement axes are zero.

`GetInputVector` normally sets horizontal input to zero and replaces forward input with the vector magnitude. Its clamp preserves a component magnitude above `1`. While an input-started Aim is active, or while at least one active Use exposes a non-null `FaceTargetCharacterItem`, it returns the original processed vector instead. The Use exceptions are stored in a set, so normal conversion resumes only after every tracked target-facing Use stops.

Adventure registers `OnAimAbilityStart` as `EventHandler.RegisterEvent<bool, bool>` and `OnUseAbilityStart` as `EventHandler.RegisterEvent<bool, Use>`, then unregisters both in `OnDestroy`. The first Aim boolean is the start state and the second identifies an input start. The camera-side Adventure View Type carries recommendation attributes for this Movement Type and Four Legged; the Movement Type itself does not select or switch the camera.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-combat"></a>

# Third Person Combat

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/)

Third Person Combat keeps a character facing the camera's gameplay look direction while forward, backward, and sideways input remains available. Choose it for an over-the-shoulder or action setup built around strafing, aiming, and camera-facing item use, and pair it with the [Third Person Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/).

Use [Third Person Adventure](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-adventure/) when directional input should turn the character into forward travel, or [Third Person RPG](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/) when movement, turning, camera alignment, and automatic travel need separate controls.

## Before you begin

- Start with a working third-person character, player input, and a Camera Controller assigned to that character.
- Prepare forward, backward, and strafe animations. Combat preserves both movement axes, so its Animator needs more directional coverage than an ordinary Adventure setup.
- Establish the reticle and item firing or use direction before tuning movement animation. The character, camera, and equipped item should agree on the gameplay look target.
- Decide whether the character uses motor movement or root motion. Combat supplies facing and input; Character Locomotion, abilities, and the Animator still determine the final displacement and rotation.

## Set up the Combat pair

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the new or existing character, choose **Third** from **Perspective**, and choose **Combat** from **Third Person Movement**.
3. Complete the character's model, Animator, input, item, and ability choices. Select **Build Character** for a new character or **Update Character** for an existing one.
4. Select the character root and expand **Ultimate Character Locomotion > Movement Types**. Confirm **Third Person Combat** is present and selected in the **Active** column. When both perspectives are installed, also choose **Combat** in **Third Person Movement Type**.
5. Select the camera, assign the character on **Camera Controller**, and expand **View Types**. Add **Third Person Combat** if needed and select it in the **Active** column. When both perspectives are installed, also choose **Combat** in **Third Person View Type**.
6. Verify that the active input setup supplies horizontal and forward character movement plus horizontal and vertical camera look input.
7. Enter Play Mode and test facing and all four movement directions before changing root motion, Aim settings, camera offsets, springs, or item actions.

The released Combat View Type explicitly recommends the Combat Movement Type. Keeping both selected makes camera yaw, character facing, perspective defaults, and Inspector warnings agree.

## Understand Combat movement and facing

Combat returns the movement input vector unchanged. At the same time, it requests character yaw from the attached look source's character look direction rather than from the travel direction. With the matching camera, this produces a stable camera-facing stance:

| Input | Observable result |
| --- | --- |
| Forward | The character moves forward while facing the gameplay look direction. |
| Left | The character strafes left without turning toward the travel direction. |
| Right | The character strafes right without turning toward the travel direction. |
| Backward | The character moves backward while continuing to face the gameplay look direction. |
| Diagonal | The character blends the original horizontal and forward values while maintaining camera-facing yaw. |
| No movement | Look input can still turn the character because Combat facing does not require positional input. |

The Movement Type does not normalize, remap, or clamp the vector. In ordinary movement, **Raw Input Vector** and the Combat-processed **Input Vector** begin with the same values. Abilities may still block or replace processed input later in the update.

Combat uses `LookDirection(true)`, not the character's travel vector and not simply the camera GameObject's unadjusted forward axis. With the supplied Third Person camera, the character-facing direction follows camera rotation while excluding the crosshair offset and compensating for moving-platform rotation. Item and Aim systems can perform a more detailed target raycast afterward.

## Configure movement input

On **Ultimate Character Locomotion Handler**, **Horizontal Input Name** defaults to `Horizontal` and **Forward Input Name** defaults to `Vertical`. Keep those names when the active input implementation supplies the matching axes, or replace them with names that exist in the project's current input map.

- Horizontal sign and magnitude pass through to left or right strafe.
- Forward sign and magnitude pass through to forward or backward travel.
- Diagonal input remains two-axis input; Combat does not collapse it into a forward value.
- Camera look input controls the look source separately. The character's alignment to that look source is what makes the unchanged movement feel camera-relative.

Verify movement and look actions independently before tuning animation. A missing horizontal action can look like an Animator problem, while a missing look action can leave movement working even though the character never changes facing.

## Choose Aim behavior

Combat already supports strafing and backward movement, so starting **Aim** does not need to unlock another input mode. Aim instead controls the item pose, Aim State, optional zoom presets, and target-facing refinement.

- Keep **Rotate Towards Look Source Target** enabled on Aim when the character should face the projected gameplay target. This setting is enabled by default in released Version 3. Aim projects the detailed look direction onto the character's up plane and can refine the final yaw after the Movement Type's ordinary camera-facing request.
- Disable **Rotate Towards Look Source Target** when another ability or gameplay system owns final facing.
- When **Assist Aim** is active with **Rotate Character Towards Target**, Aim leaves rotation to Assist Aim instead of applying both corrections.
- Aim's **Stop Speed Change** choice affects sprinting, not Combat's ability to strafe. It is enabled by default and stops an input-started Speed Change while aiming.

Test the reticle, camera offset, character pose, and item result together. An over-the-shoulder camera can point forward while a near target ray from the character requires a slightly different horizontal rotation.

## Handle Move Towards

[Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) deliberately takes control from the normal Combat relationship while it places a character for an interaction or another ability:

1. Move Towards blocks ordinary positional and rotational input by default and raises the independent-look event so it can own final alignment.
2. It supplies its own movement toward the selected location and rotates toward that location using **Motor Rotation Speed** when final alignment is still needed.
3. The Combat View Type detects the active Move Towards ability, clears its local yaw, and follows the character's rotation instead of making the character follow camera yaw.
4. When Move Towards stops, it releases independent look and the Combat camera returns to ordinary player yaw input.

Keep **Move Towards** above the ability it prepares. Use its State to increase **Motor Rotation Speed** when final alignment is too slow; the supplied demo uses a high temporary value for this purpose. Test both the approach and the handoff, because the camera should not snap when control changes in either direction.

## Choose motor or root-motion movement

Third Person Combat has no option-specific serialized fields and does not force root-motion settings. Make the locomotion choice on **Ultimate Character Locomotion**:

- Leave **Use Root Motion Position** disabled when the motor should supply displacement. Tune the shared acceleration, damping, backward multiplier, and movement states for the desired strafe response.
- Enable **Use Root Motion Position** when the clips should supply displacement. The animation set needs matching forward, backward, strafe, and diagonal motion or the character can slide.
- Leave **Use Root Motion Rotation** disabled when the controller should apply Combat's look-facing yaw through the motor.
- Enable **Use Root Motion Rotation** only when the clips can follow camera yaw without delayed or doubled turning.
- Abilities and item actions can temporarily force root-motion position or rotation. Verify Aim, Use, Move Towards, interaction, and reload animations instead of testing locomotion alone.

The released root-motion fields initialize disabled, but the Character Manager, templates, presets, States, or an existing prefab may configure different values. Inspect the selected character in Play Mode to determine the effective setup.

## How it runs

1. **Ultimate Character Locomotion Handler** reads the movement and look controls.
2. The active Combat Movement Type requests the shortest yaw change from the current character rotation to the attached look source's character look direction.
3. **Ultimate Character Locomotion** stores the unmodified movement as **Raw Input Vector**. When positional input is allowed, Combat returns that vector unchanged as processed input.
4. Active abilities can suppress, replace, or add movement and rotation. Aim may refine rotation toward the projected target; Move Towards replaces normal input and alignment while it is active.
5. Character Locomotion and the Animator apply motor or root-motion position, rotation, gravity, slopes, moving platforms, collision, and active States.
6. In ordinary play, the Combat View Type accepts camera yaw while maintaining its local relationship to the character. During Move Towards, it temporarily follows character rotation instead.

Combat requires a look source even when no movement input is held. A player normally receives it from the attached Camera Controller; an AI character needs a suitable local look source. In the Unity Editor, a missing look source logs an error instead of producing a valid yaw request.

### Editor checkpoint

Before Play Mode, confirm that:

- **Third Person Combat** is active on both the character and camera;
- both-perspective characters select Combat in **Third Person Movement Type** and **Third Person View Type**;
- the Camera Controller's **Character** reference points to this character and provides its look source;
- horizontal, forward, and camera-look inputs exist in the active input implementation;
- the Animator covers forward, backward, left strafe, right strafe, and the relevant diagonals;
- Aim's **Rotate Towards Look Source Target** and **Stop Speed Change** values match the intended combat design;
- Move Towards is correctly ordered and has an appropriate alignment State when used; and
- **Use Root Motion Position** and **Use Root Motion Rotation** match the animation set.

## Compare Combat, Adventure, and RPG

| Movement Type | Facing and processed movement | Choose it when |
| --- | --- | --- |
| **Combat** | The character faces the look source while horizontal and forward input passes through unchanged. | Camera-facing strafing, aiming, and item use are the default relationship. |
| [Third Person Adventure](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-adventure/) | Input normally turns the character into a camera-relative travel direction and becomes forward-only movement. Aim and target-facing Use can temporarily preserve strafing. | Exploration should allow free orbit without a permanent combat stance. |
| [Third Person RPG](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/) | Ordinary movement preserves facing; separate controls handle turn, look-source alignment, and automatic forward travel. | The game needs classic RPG controls rather than continuous camera-facing yaw. |

Compare the three with the same character, scene route, input device, Animator, root-motion settings, and camera offset. Changing those at the same time can hide the Movement Type difference.

## Verify in Play Mode

1. Stand still and rotate the camera. The character should turn with the gameplay look direction even without positional input.
2. Hold forward, backward, left, right, and each diagonal. The character should keep the same camera-facing relationship while the original movement direction is preserved.
3. Watch the Animator parameters and pose during every direction. Backward and strafe input should not be converted into forward-only motion.
4. Aim from idle and while moving. Confirm the item pose, reticle, character facing, camera State, and resulting item direction agree. Toggle **Rotate Towards Look Source Target** only to isolate who owns final yaw.
5. Test with Assist Aim if present. Confirm only the intended system rotates the character toward the selected target.
6. Trigger Move Towards from every interaction that uses it. The camera should follow the character's positioning rotation without a yaw snap, then restore ordinary Combat yaw after arrival or cancellation.
7. Repeat locomotion, Aim, and Move Towards with the configured root-motion settings. Test sharp yaw changes, slopes, moving platforms, walls, and action transitions for sliding or double rotation.
8. Switch to Adventure and RPG, then back to Combat. Confirm the matching View Type, Movement Type, facing, and input behavior return together.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Left or right input turns into forward travel instead of strafing. | Adventure or another Movement Type may be active. | Select Third Person Combat under **Movement Types** and retest with Aim and Move Towards inactive. |
| The camera turns but the character does not follow it. | The character may have no look source, a different Movement Type may be active, or another ability may own rotation. | Attach the Camera Controller, activate Combat, and isolate active abilities before changing camera tuning. |
| The Console reports that the character has no look source. | The Camera Controller or an AI local look source was not attached. | Attach the intended look source before sending look or movement input. |
| The character faces beside the reticle while aiming. | Aim's **Rotate Towards Look Source Target**, Assist Aim ownership, or the item look settings may not match the design. | Enable one intended rotation owner, then test the detailed target direction and each item separately. |
| Starting Aim does not change strafing. | Combat already preserves horizontal and backward input at all times. | Treat Aim as pose, State, zoom, and target-facing control; use Adventure if strafing should be limited to Aim. |
| Sprint stops as soon as Aim starts. | Aim's **Stop Speed Change** is enabled by default for input aiming. | Keep the combat restriction or disable the setting when sprint-while-aiming is intentional and animated. |
| The camera stops accepting yaw and follows the character. | Move Towards may be active. | Let it finish or inspect why it remains active; this temporary camera ownership is intentional during positioning. |
| Move Towards reaches the point but rotates too slowly. | Its final alignment uses **Motor Rotation Speed**, potentially while root motion or a low shared value limits the visible turn. | Apply a Move Towards State with a suitable rotation speed and verify the approach animation and root-motion choices. |
| Move Towards causes a camera snap at start or stop. | The Combat View Type may be mismatched, or another camera system may also change yaw. | Restore the complete Combat pair and disable competing camera rotation while testing the ability handoff. |
| Backward or strafe movement slides. | The Animator lacks matching directional motion, or root-motion displacement does not match the preserved input. | Add or retune directional clips, then test motor and root-motion position separately. |
| Character yaw lags, snaps, or doubles. | Root-motion rotation, motor rotation, Aim, and another active ability may all influence the final result. | Disable root-motion rotation and optional facing systems, then restore one rotation owner at a time. |

## Related tasks

- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Third Person Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/)
- [Third Person Adventure](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-adventure/)
- [Third Person RPG](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/)
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/)

## Developer details

The released Version 3.2.0 type is `Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.Combat`. It is serializable, reports `FirstPersonPerspective` as `false`, and declares no Combat-specific serialized settings.

`GetDeltaYawRotation` builds a rotation from `m_LookSource.LookDirection(true)` and the character's current up direction, converts it relative to `UltimateCharacterLocomotion.Rotation`, and returns the clamped local yaw. Unlike Adventure, this calculation does not depend on horizontal or forward movement values. `GetInputVector` returns its argument unchanged.

The matching camera type is `Opsive.UltimateCharacterController.ThirdPersonController.Camera.ViewTypes.Combat`. It declares recommendation attributes for the Combat and Four Legged Movement Types, includes the default `Zoom` State, and adds no serialized Combat-specific fields. Its private rotate-with-character flag is reset to `false` when a character attaches, becomes `true` only while a `MoveTowards` ability is active, and resets local yaw to zero when that ability starts.

Aim is not a Combat Movement Type event listener. Its later `UpdateRotation` step may replace the desired yaw when **Rotate Towards Look Source Target** is enabled and neither independent look nor Assist Aim owns rotation. Move Towards uses `OnCharacterForceIndependentLook` and ability rotation instead; the Combat camera responds to `OnCharacterAbilityActive` so that positioning can lead the camera temporarily.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-four-legged"></a>

# Third Person Four Legged

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/)

Third Person Four Legged turns horizontal input into steering instead of a humanoid strafe stance. Choose it for a quadruped, vehicle-like creature, or generic character whose body should turn through movement, while using animation, colliders, and optional IK to provide the actual gait and ground contact.

Four Legged is a Movement Type, not a quadruped animation or leg-placement system. It shapes input and requested yaw; Character Locomotion and the rig still own displacement, gravity, slopes, collision, and visible limb motion.

## Before you begin

- Build or prepare a third-person character with **Ultimate Character Locomotion** and a look source. A player character also needs **Ultimate Character Locomotion Handler** and a player-input component; an AI character normally uses **Local Look Source** plus its navigation or movement ability instead of the handler.
- Use a rig and Animator with forward, backward, left-turn, and right-turn coverage. Add transition or diagonal clips when the creature should turn while moving at speed.
- Fit the character colliders to the body. The Movement Type does not create a four-legged collision shape or adjust feet to terrain.
- Choose a compatible camera based on framing. Released Version 3 explicitly recommends Adventure, Combat, RPG, Pseudo3D, and Top Down View Types with Four Legged.
- Decide whether motor motion or root motion owns travel and turning before tuning the clips.

## Set up the character and camera

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the new or existing character, choose **Third** from **Perspective**, and choose **Third Person Four Legged** from **Third Person Movement**.
3. Complete the model, Animator, input, collider, item, and ability choices. Select **Build Character** for a new character or **Update Character** for an existing one.
4. Select the character root and expand **Ultimate Character Locomotion > Movement Types**. Confirm **Third Person Four Legged** is present and selected in the **Active** column. When both perspectives are installed, also choose **Four Legged** in **Third Person Movement Type**.
5. Select the Four Legged row and decide whether to enable **Rotate To Face Input Direction**. It is disabled by default and materially changes steering and backward input.
6. Select the camera, assign this character on **Camera Controller**, and expand **View Types**. Add and activate one of the compatible View Types described below. When both perspectives are installed, select it in **Third Person View Type**.
7. Verify the character's horizontal and forward input plus the camera controls required by the chosen View Type, then test the default steering mode before changing slope, gravity, or root-motion settings.

There is no dedicated Four Legged View Type. Camera and Movement Type selections are stored independently, so a compatible recommendation does not automatically configure either side of the pair.

## Choose the steering mode

**Rotate To Face Input Direction** selects between two distinct control models.

### Steering mode: disabled by default

The horizontal input remains in the processed movement vector and also adds a turn request. This creates a turning or arcing response instead of a stationary humanoid strafe. Forward and backward input retain their sign.

| Input | Observable result |
| --- | --- |
| Forward | The creature moves forward. With no horizontal input, it can turn gradually toward the camera when their yaw differs. |
| Backward | The creature moves backward. With no horizontal input, it can also correct gradually toward the camera. |
| Left or right | Horizontal input adds a turn while the same input remains available to locomotion and animation. |
| Turn while moving forward | Steering follows the horizontal sign. |
| Turn while moving backward | Steering reverses the horizontal sign so backing behaves like reverse steering. |
| No movement | On a settled character aligned to its current up direction, Four Legged adds no horizontal or look-source steering. |

When horizontal input is zero and forward or backward input is nonzero, Four Legged compares the creature with the look source Transform and adds a yaw correction clamped between `-1` and `1` per movement calculation. Straight travel therefore does not guarantee a permanently unchanged rotation when the camera points elsewhere.

### Face-input mode: enabled

Four Legged calculates the full camera-relative direction represented by horizontal and forward input. It requests yaw toward that direction, changes processed horizontal input to zero, and changes processed forward input to the input magnitude.

The result resembles Adventure's turn-to-travel relationship: left and right commands turn into forward travel, and backward input turns the creature toward the camera-relative backward direction before moving forward. It no longer behaves as reverse travel. A scaled component above `1` is retained up to the largest absolute input component.

Although the setting's source tooltip says "instantly," the Movement Type supplies a full target-yaw request; Character Locomotion, motor rotation, root motion, active abilities, and States can still affect the visible turn.

Use the default steering mode for an animal that can reverse and arc through turns. Enable face-input mode when every directional command should become forward-facing travel.

## Configure movement input

On **Ultimate Character Locomotion Handler**, **Horizontal Input Name** defaults to `Horizontal` and **Forward Input Name** defaults to `Vertical`. Keep them when those axes exist in the active input implementation, or assign names from the project's current input map.

- Test analog sticks at small and full deflection. Default steering scales yaw from horizontal input; dead zones and response curves therefore change how quickly the creature begins turning.
- Test horizontal input both with and without forward input. The default mode retains the horizontal component, so the Animator and motor must be authored for a turning response rather than a sidestep.
- Test reverse steering deliberately. The released default mode flips the yaw contribution when forward input is negative.
- In face-input mode, input direction selects facing while input magnitude selects processed forward movement. The original values remain available as **Raw Input Vector** before conversion.

AI navigation can supply the same movement intent, but the agent still needs a **Local Look Source** or another attached look source. Four Legged does not choose destinations or paths.

## Choose a compatible View Type

All five options below carry released recommendation metadata for Four Legged. The choice changes camera behavior, not the creature's steering rules.

| View Type | Camera result with Four Legged | Important boundary |
| --- | --- | --- |
| [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) | The player can orbit the camera independently for exploration framing. Default straight travel gradually corrects toward the camera; face-input mode turns directly into the camera-relative command. | Adventure's Aim/Use input exceptions belong to the Adventure Movement Type and are not added to Four Legged. |
| [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) | An over-the-shoulder camera can frame action while the creature continues to steer rather than strafe. | The Combat camera does not turn Four Legged into the Combat Movement Type. Verify reticle, item direction, and creature yaw together. |
| [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) | The camera follows the creature and can optionally allow camera-only free movement. | RPG auto-move, turn mappings, and forced character rotation belong to the RPG Movement Type. Four Legged does not gain them from the camera pairing. |
| [Pseudo3D](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/) | A side-on or 2.5D camera can frame a creature that still uses Four Legged steering. | Path and depth constraints belong to the Pseudo3D Movement Type. Add project-specific constraints if Four Legged must remain on a path. |
| [Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/) | Overhead framing exposes turns and reversing clearly. | Cursor/right-stick facing and camera-relative movement fields belong to the Top Down Movement Type. Four Legged continues using its own steering mode. |

Compare View Types with the same creature, input, rig, collider, and root-motion configuration. Otherwise camera smoothing or animation changes can look like a Movement Type difference.

## Coordinate slopes and gravity

Four Legged calculates yaw around **Ultimate Character Locomotion**'s current **Up** direction. Character Locomotion then resolves grounding, slopes, gravity, and collision after the Movement Type supplies input and yaw.

- **Use Gravity** is enabled by default, **Gravity Direction** starts as world down, and **Up** starts as world up in released source. Gravity zones, abilities, States, or project code can change the runtime frame.
- Keep **Adjust Motor Force On Slope** enabled when a motor-driven creature should use the shared uphill and downhill force adjustment. In released 3.2.0 it defaults to enabled, with **Motor Slope Force Up** at `1` and **Motor Slope Force Down** at `1.25`; tune them only after confirming the ground and collider setup.
- A look source whose orientation disagrees with the character's gravity frame can produce unintuitive camera correction or face-input yaw. Test custom gravity at walls, ceilings, and transitions rather than only on a flat floor.
- Terrain alignment of the body and individual feet is outside this Movement Type. Use animation, IK, or project-specific alignment while keeping the root and colliders consistent with Character Locomotion's up direction.

Slope force settings affect motor movement; root-motion displacement remains authored in the animation clips. In either case, steep-slope limits, grounding, and collision can reject or alter a valid movement request.

## Choose motor or root-motion movement

Four Legged does not force root-motion position or rotation.

- Leave **Use Root Motion Position** disabled when the motor should supply displacement. Tune **Motor Acceleration**, **Motor Damping**, **Motor Backwards Multiplier**, and slope force for the desired gait response.
- Enable **Use Root Motion Position** when the clips contain the intended travel distance. Forward, reverse, and turning animations must match the input mode to avoid sliding; begin with **Root Motion Speed Multiplier** at its released default of `1`.
- Leave **Use Root Motion Rotation** disabled when Character Locomotion should apply Four Legged's yaw request through **Motor Rotation Speed**. The released default is `0.15`.
- Enable **Use Root Motion Rotation** only when the turn clips own the complete visible yaw. Begin with **Root Motion Rotation Multiplier** at its released default of `1`, then test both forward and reverse steering and the full face-input direction range.
- Abilities and States may override root-motion settings temporarily. Verify attacks, interactions, jumps, knockback, and Move Towards as well as ordinary locomotion.

The released root-motion fields initialize disabled, but Character Manager choices, templates, presets, States, or an existing prefab can change them. The runtime Inspector on the selected character is authoritative.

## How it runs

1. **Ultimate Character Locomotion Handler** reads horizontal, forward, and camera input from the active input implementation.
2. Four Legged calculates yaw from the original movement values. Default mode adds reverse-aware horizontal steering and a limited look-source correction during straight travel; face-input mode requests the full camera-relative input direction.
3. **Ultimate Character Locomotion** stores the original values as **Raw Input Vector**. Default mode returns the processed vector unchanged; face-input mode converts it to forward magnitude.
4. Abilities and States can suppress, replace, or add movement and rotation.
5. Character Locomotion and the Animator apply motor or root-motion movement, motor or root-motion rotation, gravity, slope handling, platforms, collision, and grounding.
6. The selected compatible View Type frames the result independently and continues to provide the look-source Transform used by Four Legged.

### Editor checkpoint

Before Play Mode, confirm that:

- **Third Person Four Legged** is active and selected as **Third Person Movement Type** when both perspectives are installed;
- exactly one compatible camera View Type is active and selected as **Third Person View Type**;
- the Camera Controller's **Character** reference points to this character, or an AI uses an appropriate local look source;
- **Rotate To Face Input Direction** matches reverse-steering versus turn-to-travel intent;
- the input map supplies deliberate horizontal, forward, and camera controls with suitable dead zones;
- the Animator and root-motion settings cover the selected steering mode;
- colliders fit the body and behave on the project's steepest supported slopes; and
- custom gravity keeps Character Locomotion, the look source, animation, and optional IK in the same up frame.

## Verify in Play Mode

1. With **Rotate To Face Input Direction** disabled, press forward and backward while the camera matches the creature's yaw. Confirm signed forward and reverse travel.
2. Orbit the camera away from the creature, then hold straight forward and straight backward. Confirm the released limited yaw correction instead of assuming rotation remains fixed.
3. Hold left and right from rest, while moving forward, and while reversing. The creature should turn rather than present a humanoid strafe, and the steering sign should reverse while backing.
4. Enable **Rotate To Face Input Direction** and repeat every cardinal and diagonal command. The creature should face the camera-relative command and use forward-only processed travel, including for backward input.
5. Compare low and full analog-stick values. Steering should enter predictably without a dead-zone jump or an unintended sidestep animation.
6. Compare the compatible Adventure, Combat, RPG, and Top Down View Types without changing the Movement Type. In each supported pairing, confirm that camera framing changes while Four Legged steering remains active; RPG auto-move and turn inputs, Combat strafing, and Top Down cursor-facing must not appear unless you actually switch to those Movement Types. Test Pseudo3D too when the project uses side-on framing.
7. Walk and turn across flat ground, side slopes, uphill and downhill grades, moving platforms, and the steep-slope boundary. Grounding and collision should remain stable.
8. If the project uses custom gravity, repeat steering on every supported surface and through gravity transitions. Creature up, camera frame, and yaw should remain coherent.
9. Test motor position, root-motion position, motor rotation, and root-motion rotation in isolation before combining them. Confirm there is no sliding, double turn, or animation mismatch.
10. Trigger every movement-changing ability used by the character and confirm it returns control to Four Legged cleanly.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The creature strafes or slides sideways instead of presenting a turn. | Default mode retains horizontal processed input, so the Animator or motor response may still look like a sidestep. | Author a turn-in-motion blend for the horizontal parameter, reduce unsuitable lateral animation, or use face-input mode for forward-only travel. |
| Forward or backward movement slowly changes yaw. | With horizontal input at zero, default Four Legged corrects toward a misaligned look-source Transform by up to one degree of request per calculation. | Align the camera, accept the follow behavior, or enable **Rotate To Face Input Direction** for direct camera-relative facing. |
| Left/right steering feels reversed only while backing. | Released default mode deliberately flips the yaw contribution for negative forward input. | Keep reverse steering, remap the control for the game's convention, or implement a custom type when the sign should remain unchanged. |
| Backward input turns the creature around and moves forward. | **Rotate To Face Input Direction** is enabled. | Disable it when true reverse travel is required. |
| The creature turns too slowly or too quickly. | Input response, **Motor Rotation Speed**, root-motion rotation, and active States can all affect visible yaw. | Test with motor rotation and neutral States first, then tune input and rotation one owner at a time. |
| The Console reports that the character has no look source. | No Camera Controller or AI local look source was attached. | Attach the intended look source before sending movement input. |
| The camera works but RPG turn, auto-move, cursor aim, or Pseudo3D path behavior does not. | Those features belong to the corresponding Movement Type, not to the compatible View Type. | Keep Four Legged steering or switch to the Movement Type that owns the required control feature. |
| The body tilts or feet penetrate uneven ground. | Four Legged does not implement body alignment or leg IK. | Configure the rig, animation, colliders, and a supported IK/alignment solution independently. |
| Uphill and downhill speed is inconsistent. | Motor slope force, root-motion distance, friction, or grounding may not match the animation. | Test motor and root-motion position separately, then tune shared slope values and clips on the actual terrain. |
| Custom gravity produces an unexpected turn plane. | Character **Up**, gravity, and look-source orientation may disagree. | Align the runtime frames and retest each gravity transition with both steering modes. |
| Turning slides, doubles, or snaps. | Motor rotation and root-motion rotation may both conflict with the clip or an ability. | Disable root-motion rotation, verify motor yaw, then enable the authored rotation path only if the animation owns it completely. |

## Related tasks

- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Adventure Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-adventure/)
- [Combat Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/)
- [RPG Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/)
- [Top Down Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-top-down/)
- [Adventure View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/)
- [Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/)
- [RPG View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/)
- [Pseudo3D View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/)
- [Top Down View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)

## Developer details

The released Version 3.2.0 type is `Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.FourLegged`. It is serializable, reports `FirstPersonPerspective` as `false`, and declares one serialized option: `RotateToFaceInputDirection`, which defaults to `false`.

In default mode, `GetDeltaYawRotation` first resolves current forward against the Character Locomotion up direction. It adds horizontal input, reversing that contribution when forward input is negative. When horizontal input is zero and forward input is nonzero, it adds the look-source Transform's local yaw difference clamped to `-1` through `1`. `GetInputVector` returns the input unchanged.

With `RotateToFaceInputDirection` enabled, yaw uses the normalized movement direction transformed by the look source and the Character Locomotion up direction. `GetInputVector` sets horizontal input to zero and forward input to the vector magnitude, capped by the largest absolute component when that component exceeds `1`.

The Adventure, Combat, RPG, Pseudo3D, and Top Down View Type classes each declare a recommendation attribute for Four Legged. That metadata is camera compatibility guidance only; Four Legged does not inherit those other Movement Types' fields, events, input mappings, or runtime behavior.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-point-click"></a>

# Third Person Point & Click

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/)

The Point & Click Movement Type turns a pointer click on solid world geometry into a destination, then lets Move Towards and a Pathfinding Movement ability guide the character there. Use it for click-to-move RPG, strategy, or top-down controls rather than direct keyboard or stick locomotion.

The [Top Down View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/) is the released Version 3 recommended camera pairing. Other camera framing can work, but the camera must still be attached as the character's look source because Point & Click casts the destination ray from that camera.

## Before you begin

- Bake a NavMesh that covers the character's starting point and every intended destination.
- Create a third-person character with player input, a Camera Controller, and **Ultimate Character Locomotion**.
- Keep the active cursor available for screen pointing. The supplied **Unity Input** and **Unity Input System** components default **Disable Cursor** to enabled, so turn it off for this workflow.
- Decide whether movement and item use share a pointer button. Both Point & Click and the built-in Use item ability default to `Fire1`; give one of them a separate mapping when one click should not do both.

## Build the point-and-click character

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Choose **Third** from **Perspective** and choose **Point Click** from **Third Person Movement**.
3. Enable **Standard Abilities** so the character receives **Move Towards**, or plan to add Move Towards manually.
4. Enable **NavMeshAgent**. This adds **NavMeshAgent Movement** and its required **NavMeshAgent** component.
5. Complete the remaining model, Animator, input, and item choices, then select **Build Character**. Use **Update Character** for an existing character.
6. Configure the Camera Controller with the **Top Down** View Type and attach it to the character.
7. On the active player-input component, disable **Disable Cursor**. Confirm that the mapping used by **Click Button Name** exists and reports the intended pointer button.

For a character assembled outside the manager, add **Point Click** under **Movement Types**, make it **Active**, and set **Third Person Movement Type** to it. Under **Abilities**, add **Move Towards** and a concrete `PathfindingMovement` ability such as **NavMeshAgent Movement**.

## Order the abilities

Ability order controls which system writes the final movement input. Use this order from top to bottom:

1. **Speed Change**, when used.
2. **NavMeshAgent Movement** or another Pathfinding Movement ability.
3. **Move Towards**.
4. Lower-priority locomotion abilities that should wait during automatic travel.

Pathfinding must be above Move Towards so Move Towards can hand it the destination. In the released Version 3 implementation, Pathfinding Movement already applies an active Speed Change multiplier; keep Speed Change above pathfinding so that multiplier is not applied again after pathfinding writes its input.

Move Towards is concurrent but defaults to blocking positional and rotational player input while active. It also blocks lower-priority locomotion abilities and stored-input abilities. **Item Equip Verifier** and **Equip Unequip** are explicitly allowed, while item abilities use their own list; test item use separately, especially when it shares `Fire1` with the movement click.

## Configure the important settings

### Point Click Movement Type

| Setting | Released Version 3 default | Use it for |
| --- | --- | --- |
| **Click Button Name** | `Fire1` | The button checked every frame while held. Use a dedicated mapping when `Fire1` also uses an equipped item. |
| **Min Point Click Distance** | `1` | Ignore hits whose straight-line world distance from the character is less than this value. This is not NavMesh path distance. |
| **Run Max Squared Distance** | `140` | The field remains visible and serialized, but released Version 3 does not read it at runtime. It does not automatically start running. |

Point & Click ignores a click while the pointer is over UI. Otherwise, it raycasts from the attached camera through the pointer position, ignores trigger colliders, and accepts the first hit on **Character Layer Manager > Solid Object Layers**. Holding the button updates the destination every frame, which supports drag-to-retarget behavior but can also make a held attack button continually replace the path.

### NavMeshAgent Movement

- **Auto Enable** defaults to enabled, allowing a destination request to activate the ability and NavMeshAgent.
- **Rotation Override** defaults to **No Override**. Use **NavMesh** to force facing along the path, or **Character** when another system should preserve character rotation.
- **Arrived Distance** defaults to `0.2`. Increase it when the agent oscillates near the target; reduce it only when the character and baked path can reliably reach the tighter tolerance.
- **Allow Movement In Air** defaults to enabled. Disable it when airborne abilities should own movement and rotation.

The NavMeshAgent calculates the path, but Ultimate Character Locomotion moves the character and resolves collision. Changing NavMeshAgent speed alone does not change visible root-motion speed.

### Move Towards

- **Input Multiplier** defaults to `1` and scales direct approach input when pathfinding is not active.
- **Inactive Timeout** defaults to `1` second.
- **Teleport On Early Stop** defaults to enabled. For visible click-to-move navigation, consider disabling it so a blocked or invalid destination stops instead of snapping the character to the clicked point.
- **Disable Gameplay Input** defaults to disabled. Enable it when all other gameplay input, not just positional and rotational movement, should be suspended during travel.

Point & Click supplies a position-only Move Towards request. The generated destination accepts any final rotation, so pathfinding controls facing while traveling and no particular facing is required after arrival.

## How a click runs

1. Point & Click checks **Click Button Name** and ignores the frame when the pointer is over UI.
2. The camera casts a ray through the current pointer position against **Solid Object Layers**. Trigger colliders are ignored.
3. A hit at least **Min Point Click Distance** from the character is passed to `MoveTowardsLocation`.
4. Move Towards starts and asks the higher-priority Pathfinding Movement ability to set the destination.
5. NavMeshAgent Movement converts the path's desired velocity and rotation into Ultimate Character Locomotion input. Character Locomotion applies animation, root motion, acceleration, gravity, collision, and other active abilities.
6. At **Arrived Distance**, pathfinding reports arrival. Move Towards completes its position check, releases independent look control, and stops its active pathfinding ability.

The built-in click does not project the hit onto the NavMesh or confirm that a complete path exists. If the pathfinding ability rejects the destination, Move Towards can fall back to direct movement toward the hit. A blocked character can then reach **Inactive Timeout** and, with **Teleport On Early Stop** enabled, teleport to the target. Keep clickable geometry aligned with the baked NavMesh, disable the teleport fallback for player-visible navigation, or validate destinations in a project-specific click handler before starting Move Towards.

## Scenario choices

- **Movement-only pointer:** keep `Fire1` when the character has no conflicting item or UI action.
- **Move and attack with the pointer:** give **Click Button Name** a dedicated mapping, or route the click through game logic that decides whether the pointer selected an enemy, an interactable, or the ground.
- **Click and hold to steer:** keep the built-in held-button behavior and ensure frequent destination replacement is acceptable to the pathfinding implementation.
- **Click once to travel:** use an input mapping that produces the intended short press and avoid holding it while using another action.
- **Walking and running:** add Speed Change above NavMeshAgent Movement and select matching walk/run animations. **Run Max Squared Distance** cannot choose the speed in released Version 3.
- **Root-motion travel:** use locomotion animations whose embedded displacement matches the intended path input. The NavMeshAgent supplies direction, not final Transform movement.
- **Fixed facing:** choose **Character** for **Rotation Override** and let an aiming or facing system own rotation. Use **NavMesh** when the character should follow path turns.

### Editor checkpoint

Before Play Mode, confirm that:

- **Point Click** is the active third-person Movement Type;
- the Camera Controller is attached and uses **Top Down** or another deliberate third-person View Type;
- the cursor is visible and unlocked, and **Click Button Name** resolves to the intended input;
- the abilities are ordered **Speed Change**, **NavMeshAgent Movement**, **Move Towards** when all three exist;
- the character starts on the baked NavMesh and the destination floor is in **Solid Object Layers**; and
- **Teleport On Early Stop** matches the desired failure behavior.

## Verify in Play Mode

1. Click a reachable floor point farther than `1` world unit away. Confirm **Move Towards** and **NavMeshAgent Movement** become active, a path appears, and the character travels around obstacles.
2. Click inside **Min Point Click Distance**. The current destination should not be replaced.
3. Click over a UI control and on a trigger-only collider. Neither should create a destination.
4. Hold the click while moving the pointer across valid floor. Confirm the destination updates continuously and decide whether that matches the game design.
5. Test **No Override**, **NavMesh**, and **Character** rotation behavior used by the game. Confirm facing follows the chosen owner during turns and remains acceptable at arrival.
6. With items equipped, verify that the movement click does not also fire or use an item unless that shared action is intentional.
7. Activate Speed Change with it above NavMeshAgent Movement. Confirm the movement input is scaled once and the matching walk or run animation plays.
8. Test with root motion enabled. The character should follow the path without the NavMeshAgent moving the Transform independently or the animation visibly sliding.
9. Disable **Teleport On Early Stop**, then click solid geometry outside the baked NavMesh or behind an unreachable obstruction. Confirm the character stops safely instead of snapping to the hit.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console reports a missing Pathfinding Movement or Move Towards ability. | Point & Click requires both abilities before Movement Types initialize. | Add a concrete Pathfinding Movement ability and **Move Towards**, then keep pathfinding above Move Towards. |
| Clicking throws an error or creates no ray. | The character may have no player input, no camera look source, or no Camera component on that look source. | Build the character with player input and attach the Camera Controller before testing Point & Click. |
| Clicking does nothing. | The pointer may be over UI, the mapping may not exist, the cursor may be locked, the hit may be too close, or the floor may not be in **Solid Object Layers**. | Verify **Click Button Name**, disable **Disable Cursor**, test away from UI, and inspect the floor layer and distance. |
| A path is not created. | The character or destination is off the NavMesh, **Auto Enable** is off while the ability is disabled, or the destination is unreachable. | Place both endpoints on a baked NavMesh, enable **Auto Enable**, and test the destination through NavMeshAgent Movement. |
| The character moves directly into an obstacle instead of following a path. | Pathfinding rejected the click, so Move Towards fell back to direct input. | Align clickable surfaces with the NavMesh or validate the hit before starting movement. Disable **Teleport On Early Stop** while diagnosing. |
| The character teleports after becoming stuck. | Move Towards reached its default `1`-second **Inactive Timeout** with **Teleport On Early Stop** enabled. | Correct the path or animation, increase the timeout only when a real pause is expected, or disable the teleport fallback. |
| The click also fires or uses an item. | Point & Click and Use both default to `Fire1`. | Assign a dedicated movement mapping or resolve move-versus-use intent in project input logic. |
| The character does not run on distant clicks. | **Run Max Squared Distance** has no runtime use in released Version 3. | Use Speed Change, an Animator/state decision, or project logic to choose walking and running. |
| Speed is multiplied twice. | Speed Change is below NavMeshAgent Movement, so it processes input that pathfinding already scaled. | Move Speed Change above NavMeshAgent Movement. |
| A root-motion character follows the path too slowly or slides. | The animation's embedded speed does not match the path input and movement thresholds. | Use matching walk/run clips and blend-tree thresholds; do not tune only NavMeshAgent speed. |
| The character faces the wrong direction. | **Rotation Override**, NavMeshAgent `updateRotation`, or another aiming ability owns facing. | Choose **NavMesh** for path facing or **Character** for external facing, then retest items and arrival. |

## Related tasks

- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [Top Down View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)
- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Item Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)

## Developer reference

Point & Click checks `IPlayerInput.GetButton` every frame and calls `UltimateCharacterLocomotion.MoveTowardsAbility.MoveTowardsLocation(hit.point)` after a valid raycast. Its public settings are `ClickButtonName`, `MinPointClickDistance`, and `RunMaxSquaredDistance`; the last property remains unused by the released Version 3 runtime.

For projects that need NavMesh projection, complete-path validation, target selection, or separate move/attack intent, handle the pointer in project code and call `MoveTowardsLocation` only after accepting a safe destination. The position-only overload accepts any final rotation; use the position-and-rotation overload when arrival facing matters.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-pseudo3d-2-5d"></a>

# Third Person Pseudo3D (2.5D)

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/)

The Pseudo3D Movement Type creates side-view controls for a straight 2.5D stage or a curved route through 3D space. Pair it with the [Pseudo3D View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/), then add a Path and Follow Pseudo3D Path only when the playable plane must bend.

The Movement Type interprets input and facing, the View Type frames and aims the camera, and [Follow Pseudo3D Path](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/follow-pseudo3d-2-5d-path/) keeps the character at a stable offset from an optional curve. One does not replace the others.

## Before you begin

- Create a working third-person character with player input and a Camera Controller.
- Decide whether the game is a fixed side-scroller, supports depth lanes, or follows a curved route. That choice determines whether **Allow Depth Movement**, **Path**, and Follow Pseudo3D Path are needed.
- Keep the complete camera corridor clear. The Pseudo3D View Type does not perform the ordinary third-person obstruction sweep.
- Prepare movement and aiming animations for both travel directions. When root motion is enabled, the animation supplies visible displacement even though Pseudo3D supplies the input direction.

## Build the character and camera

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Choose **Third** from **Perspective** and choose **Pseudo3D** from **Third Person Movement**.
3. Complete the model, Animator, input, item, and ability choices, then select **Build Character**. Use **Update Character** for an existing character.
4. Select the character root. Under **Ultimate Character Locomotion > Movement Types**, confirm **Third Person Pseudo3D** is present and selected as **Active**. When both perspectives are installed, also select it as **Third Person Movement Type**.
5. Select the camera, expand **Camera Controller > View Types**, add and activate **Third Person Pseudo3D**, and select it as **Third Person View Type** when both perspectives exist.
6. Start with **Path** empty. Set the camera's **Forward Axis** and **View Distance**, then verify a straight side view before adding depth or a curved route.

The View Type starts with **Forward Axis** `(0, 0, -1)`, **View Distance** `10`, **Vertical Dead Zone** `1`, **Move Smoothing** `0.1`, **Rotation Smoothing** `0.1`, and **Depth Look Direction** disabled. Treat these as a baseline and tune the final aspect ratio, jump height, path bends, and aiming behavior in Play Mode.

## Configure movement and facing

| Setting | Released Version 3 default | Choose it by scenario |
| --- | --- | --- |
| **Allow Depth Movement** | disabled | Leave it disabled for a single gameplay plane. Enable it when forward and backward input should move toward or away from the camera. |
| **Look In Move Direction** | disabled | Enable it when the character should face travel input. Leave it disabled when visible-cursor or look-axis input should control facing. |
| **Look Rotate Buffer** | `0.2` | Increase it when cursor-facing changes rapidly near the character; reduce it when close pointer movement must rotate sooner. The runtime threshold also grows with character velocity. |
| **Path** | unassigned | Leave it empty for a straight stage. Assign a valid Path before Play Mode for a curved route. |

With **Allow Depth Movement** disabled, forward and backward input are removed and horizontal input moves across the side-view plane. When enabled, both axes are transformed relative to the look source and normalized so diagonal input is not inherently faster.

With **Look In Move Direction** enabled, the character faces the current travel input. A Path makes that direction local to the curve tangent. When it is disabled, a visible cursor rotates the character toward a plane through the character; a hidden cursor uses the configured horizontal and vertical look axes instead.

## Choose a Pseudo3D scenario

| Scenario | Movement Type | Camera and path | Expected result |
| --- | --- | --- | --- |
| Straight side-scroller | Disable depth movement; choose movement-facing or pointer-facing | Leave **Path** empty and use the View Type's **Forward Axis** | Horizontal input stays on one fixed plane and the camera remains on the chosen side. |
| Depth lanes | Enable depth movement | Leave **Path** empty or assign one; constrain lane width with level collision | Forward and backward input change the character's depth without losing the side-view composition. |
| Curved single lane | Disable depth movement and assign a Path | Add Follow Pseudo3D Path | The camera rotates with the tangent while the character preserves its initial offset through bends. |
| Curved route with lane changes | Enable depth movement and assign a Path | Add Follow Pseudo3D Path and provide lane boundaries | Depth input changes the stored path offset; the new lane remains stable around later bends. |

## Create a curved Path

Skip this section for a straight stage.

1. Create an empty scene GameObject and add the **Path** component.
2. Select **Add Curve Segment**. The Scene view creates the first cubic Bezier segment with four control points.
3. Move the green start point and red end point to the route endpoints. White points mark internal endpoints, and smaller handles control the tangent.
4. Select a point or handle and use the Scene tool. Use the Inspector's **Position** field when an exact local coordinate is required.
5. Select **Add Curve Segment** for each additional bend. A later segment shares the previous endpoint, and moving an internal tangent keeps its opposite tangent aligned for a continuous direction.
6. Follow the curve from green to red and remove sharp tangent reversals. The path direction and tangent determine movement-facing and camera rotation.
7. Assign the Path GameObject to **Ultimate Character Locomotion > Movement Types > Third Person Pseudo3D > Path** before entering Play Mode.

![Scene view showing a white Pseudo3D curve from its green start through white control points to its red end](https://opsive.com/wp-content/uploads/2018/04/2.5DCameraPath.png?v=2340a333acdd)

The full curve establishes the route direction and the camera-facing tangent used at each position.

![Selected middle point on a Pseudo3D path with aligned tangent handles shaping the white curve](https://opsive.com/wp-content/uploads/2018/04/MidControlPointPath.png?v=e0368456c6af)

Selecting an internal point exposes both tangent directions; keep them smooth when the camera and character should turn continuously through the bend.

The Path must contain at least one curve segment. An assigned but empty Path is not a valid route and will fail when the Movement Type, View Type, or follow ability requests a tangent.

## Add Follow Pseudo3D Path

1. On the character's **Ultimate Character Locomotion** component, expand **Abilities**.
2. Add **Follow Pseudo3D Path**.
3. Keep **Enabled** selected and leave **Start Type** and **Stop Type** set to **Manual**. The ability listens for the Movement Type change event and starts itself when Pseudo3D activates with a Path assigned.
4. Keep the ability near the bottom of the list so its position correction runs after ordinary movement abilities that produce the frame's desired movement.
5. Place the character at the intended lane offset before Pseudo3D activates. The ability preserves that starting offset; it does not snap the character to the curve centerline.

Assign the Path before Pseudo3D becomes active. Assigning a Path after the Movement Type is already active does not emit the change event that starts Follow Pseudo3D Path. Switch to another Movement Type and back, or deliberately start the ability through project code after the reference is valid.

## How it runs

On each movement update, Pseudo3D transforms the allowed input axes into the character's local movement vector. Character Locomotion then applies acceleration, root motion, gravity, collision, and ability restrictions.

For a curved route, the Movement Type uses the nearest Path tangent to calculate movement-facing. The matching View Type reads the same active Movement Type and rotates its side view from that tangent. Follow Pseudo3D Path separately examines the character's requested **Desired Movement** and corrects it enough to preserve the stored horizontal offset from the curve.

When depth movement is enabled, forward or backward raw input changes that stored offset, allowing lane changes. Removing the Path while the follow ability is active stops the ability. Switching away from Pseudo3D stops it; switching back starts it again when the Path is already assigned.

## Aiming, items, and root motion

- With a visible cursor, Pseudo3D character-facing uses a plane through the character when **Look In Move Direction** is disabled. With the cursor hidden, the look axes supply the direction.
- The Pseudo3D View Type's **Depth Look Direction** is disabled by default. Leave it disabled for plane-constrained pointer aiming; enable it when item or aim direction should use a physics hit at another depth. This option affects the visible-cursor path, not controller or virtual look axes.
- Pseudo3D reports independent-look behavior differently for character and item queries. Test [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/), [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/), projectiles, and throwables with the actual mouse and controller paths instead of assuming the character transform and item direction are identical.
- Root-motion position and rotation remain Character Locomotion settings. Pseudo3D chooses direction and input magnitude; the animation clip still determines root-motion displacement. Follow Pseudo3D Path corrects the requested movement to maintain the route offset, so test it after every position-changing ability.

### Editor checkpoint

Before Play Mode, confirm that:

- **Third Person Pseudo3D** is active on both character and camera;
- **Allow Depth Movement** matches the level design and lane collision exists when depth is enabled;
- **Look In Move Direction**, **Look Rotate Buffer**, cursor behavior, and look-axis mappings match the intended facing control;
- a curved route has a nonempty **Path** assigned before Pseudo3D activates;
- **Follow Pseudo3D Path** exists, is enabled, and is placed after ordinary movement modifiers; and
- the character begins at the intended offset and the camera corridor is clear through every bend.

## Verify in Play Mode

1. On a straight section, move left and right in both directions. Confirm the character remains on the side-view plane and the camera stays on its intended side.
2. With depth movement disabled, press forward and backward and confirm they do not move the character. Enable it and confirm those inputs change lanes without diagonal speed gain.
3. Compare **Look In Move Direction** enabled and disabled. Test movement-facing, visible-cursor facing, and controller/look-axis facing separately.
4. For a curved route, confirm Follow Pseudo3D Path becomes active without an input press. Traverse every segment in both directions and confirm the camera turns smoothly while the character preserves its lane offset.
5. Start the character away from the curve centerline and repeat the route. It should preserve that deliberate offset rather than snapping to the line.
6. Enable depth movement, change lanes, release the depth input, and continue around a bend. The new offset should remain stable.
7. Aim and use each relevant item with a visible cursor and with controller input. Test **Depth Look Direction** off and on against targets on and away from the gameplay plane.
8. Test jumps, knockback, root-motion actions, and other position-changing abilities. Vertical motion should remain available while the intended horizontal route offset is restored.
9. Switch away from Pseudo3D and back. The follow ability should stop and restart, and the camera and Movement Type should return to their configured defaults.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Forward and backward input do nothing. | **Allow Depth Movement** is disabled. | Enable it only when the stage supports depth lanes; otherwise this is the expected single-plane behavior. |
| The character faces the wrong direction. | **Look In Move Direction**, cursor visibility, look-axis mappings, Path direction, or **Look Rotate Buffer** may not match the control scheme. | Choose one facing owner, verify the green-to-red route direction, and test pointer and controller input separately. |
| The Console reports no look source or cursor-facing throws an error. | The player character has no attached Camera Controller, player input, or usable Camera on its look source. | Attach the camera and verify the active input component before using cursor-facing Pseudo3D controls. |
| The camera rotates around a bend but the character drifts away. | Assigning a Path or using the Pseudo3D View Type does not constrain position by itself. | Add and enable Follow Pseudo3D Path, confirm it is active, and place it after ordinary movement abilities. |
| Follow Pseudo3D Path never becomes active. | The Path was empty or assigned after Pseudo3D had already activated. | Add at least one segment, assign the Path first, then switch away from and back to Pseudo3D. |
| The character stays offset instead of snapping to the curve. | The follow ability captured the character's starting lane offset. | Position the character on the intended lane before activation; preserving the offset is expected. |
| The camera or character flips at a bend. | The path direction or tangent handles reverse abruptly. | Smooth the internal tangents and test travel through the exact segment in both directions. |
| A Path moved or edited during Play Mode keeps its old shape. | Released Version 3 caches world-space curve data during `Path.Awake`. | Finish the Transform and control points before Play Mode, or use a custom runtime path implementation. |
| Swapping directly to another Path produces a wrong segment or offset. | The Movement Type, View Type, and follow ability retain their current path index and stored offset. | Use a designed transition that reactivates the systems and establishes the new route instead of replacing the reference in place. |
| Item aim works with the mouse but not the controller, or points at the wrong depth. | Visible-cursor and cursor-hidden look paths differ, and **Depth Look Direction** applies only to the visible cursor. | Configure the look axes for controllers and test the View Type's depth option with the target colliders and layers. |
| Root-motion movement slides or leaves the route. | The clip speed does not match the input, or another ability changes movement after the follow correction. | Use matching root-motion clips and keep Follow Pseudo3D Path late enough in the ability list to correct the final request. |
| The Pseudo3D camera never rotates after smoothing changes. | **Rotation Smoothing** set to `0` applies none of the target rotation during normal updates. | Use a positive value; use `1` for the immediate target rotation. |

## Related tasks

- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [Pseudo3D View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/)
- [Follow Pseudo3D Path](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/follow-pseudo3d-2-5d-path/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/)
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

The Movement Type exposes `AllowDepthMovement`, `LookInMoveDirection`, `LookRotateBuffer`, and `Path`. `GetInputVector` removes disallowed depth input, transforms the remaining axes relative to the look source, and normalizes the result. `GetDeltaYawRotation` uses movement input, cursor position, or look axes and uses the Path tangent when one is assigned.

The Version 3 `Path` component creates its cubic Bezier data during `Awake`. The first segment uses four control points; every later segment adds three because it shares the previous endpoint. `GetTangent` and `GetClosestPoint` retain a segment index for neighboring-segment searches, so an empty curve or an uncoordinated runtime Path replacement is not supported safely.

`FollowPseudo3DPath` is a concurrent manual ability that listens for `OnCharacterChangeMovementType`. It starts when Pseudo3D activates with a Path, stores the character's local offset, and adjusts `UltimateCharacterLocomotion.DesiredMovement` in `UpdatePosition`. It supplies no speed, destination, vertical motion, Animator index, or automatic centering.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-rpg"></a>

# Third Person RPG

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/)

Third Person RPG provides separate controls for forward movement, strafing, turning, camera-aligned rotation, and automatic forward movement. Use it for a follow-behind RPG scheme where the character can move without always facing the camera, and pair it with the [RPG View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/).

## Before you begin

- Create a working third-person character with player input, **Ultimate Character Locomotion**, **Ultimate Character Locomotion Handler**, and an attached Camera Controller.
- Choose the input route before assigning names. The supplied Input Manager and Input System configurations separate strafing and turning differently.
- Prepare forward, backward, strafe, and turning animation coverage. The Movement Type chooses the input and facing request; Character Locomotion still applies animation, root motion, acceleration, gravity, collision, and active abilities.
- Decide whether the mouse buttons should control the RPG camera or equipped items. The RPG View Type's supplied free-movement inputs overlap common Aim and Use inputs when enabled.

## Build the RPG character and camera

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Choose **Third** from **Perspective** and choose **RPG** from **Third Person Movement**.
3. Complete the model, Animator, input, item, and ability choices, then select **Build Character**. Use **Update Character** for an existing character.
4. Select the character root. Under **Ultimate Character Locomotion > Movement Types**, confirm **Third Person RPG** is present and selected as **Active**. When both perspectives are installed, also select it as **Third Person Movement Type**.
5. On **Ultimate Character Locomotion Handler**, configure **Horizontal Input Name** for the chosen input route using the table below.
6. Select the camera, expand **Camera Controller > View Types**, add and activate **Third Person RPG**, and select it as **Third Person View Type** when both perspectives are installed.
7. Select the RPG Movement Type row and confirm **Rotate Input Name**, **Turn Input Name**, **Turn Multiplier**, and **Auto Move Input Name**. Test each referenced mapping independently before tuning animation or camera smoothing.

## Separate strafe and turn input

Do not give **Horizontal Input Name** and **Turn Input Name** the same axis. One name feeds the character's left/right movement and the other rotates the character.

| Supplied input route | **Horizontal Input Name** on the handler | **Turn Input Name** on RPG | Supplied keyboard result |
| --- | --- | --- | --- |
| Legacy Input Manager | `Alt Horizontal` | `Horizontal` | Q/E strafe; A/D turn. |
| Unity Input System | `Horizontal` | `Turn` | A/D strafe; Q/E turn. |

The legacy **Update Buttons** workflow creates `Alt Horizontal` with Q/E. The released Input System `CharacterInput` asset does not contain an `Alt Horizontal` action; it supplies `Horizontal` on A/D and a separate `Turn` action on Q/E. The released demo character uses that Input System arrangement. For a custom action asset, the exact keys can differ, but the two UCC fields must request distinct action names.

The supplied Q/E bindings also overlap **Equip Previous Item** and **Equip Next Item**. Rebind either turning/strafe or item cycling when the character uses both workflows.

## Understand the controls

| Control | Released Version 3 default | Runtime result |
| --- | --- | --- |
| Forward/backward movement | Handler **Forward Input Name** is `Vertical` | The character moves along its current forward axis without changing yaw by movement alone. The supplied keyboard mapping is W/S. |
| Strafe | Handler **Horizontal Input Name** is `Horizontal` until changed | The character moves left or right without turning. Use the input-route table above so this is not also the turn axis. |
| **Rotate Input Name** | `Fire3` | While held, the character turns to the attached look source and the paired RPG camera accepts yaw and pitch input. The supplied mouse mapping is the middle button. |
| **Turn Input Name** | `Horizontal` on a newly created RPG type | The axis rotates the character. The demo overrides this to `Turn` for its Input System action asset. |
| **Turn Multiplier** | `1.5` | Scales the turn-axis value before it is applied to yaw. |
| **Auto Move Input Name** | `Action` | Each button press toggles automatic forward movement. The supplied keyboard mapping is F. |

Auto move is a toggle, not a hold. While enabled, it forces processed and raw forward input to `1`, so pressing backward does not cancel it. Press the mapped button again to stop. Strafing, turning, collision, and ability restrictions still apply during auto move.

## Choose the camera behavior

The matching RPG View Type normally follows character rotation. It can also expose two temporary camera modes:

- **Allow Free Movement** is disabled by default. When enabled, holding **Camera Free Movement Input Name** (`Fire1` by default) orbits and pitches the camera without turning the character. After release, the yaw offset recenters only when the character moves.
- Holding **Character Forced Rotation Input Name** (`Fire2` by default) clears the camera's yaw offset and tells the active RPG Movement Type to turn with the look source. This mode also requires **Allow Free Movement**.
- Holding the Movement Type's **Rotate Input Name** turns the character with the look source and lets the paired camera accept yaw and pitch. Keep it distinct from the View Type's two camera inputs so each held mode has one clear purpose.

`Fire1` and `Fire2` are also common Use and Aim mappings. Rebind the camera modes or the item abilities when a click should not both orbit the camera and use an item.

## Scenario choices

| Scenario | Configuration | Expected result |
| --- | --- | --- |
| Keyboard RPG controls | Use one axis for strafe and another for turn; leave **Turn Multiplier** near its starting value | Forward/back and strafe preserve facing, while the turn axis changes yaw. |
| Controller movement | Create separate strafe and turn actions or composites instead of assigning the same stick axis to both fields | Movement and character yaw can be tuned independently without double input. |
| Mouse-driven character rotation | Keep **Rotate Input Name** on a held button and attach the RPG View Type as the look source | The character follows camera look while held, then returns to ordinary RPG turning after release. |
| Independent camera inspection | Enable **Allow Free Movement** and assign a camera-only button | The camera orbits without turning the character, then recenters behind it after movement resumes. |
| Continuous travel | Keep a dedicated **Auto Move Input Name** that does not overlap an interaction | One press begins forward travel and the next press stops it; strafe and turn remain available. |
| Item-heavy combat | Move free camera, forced rotation, turn/strafe, and item cycling onto non-overlapping actions | Aim, Use, and equipment changes occur without an unintended camera or movement command. |

## How it runs

1. **Ultimate Character Locomotion Handler** reads the configured horizontal and forward axes into the character's raw movement input.
2. The RPG input events track the rotate button, turn axis, and auto-move toggle. The turn value is multiplied by **Turn Multiplier**.
3. When auto move is active, RPG replaces both processed and raw forward input with `1`. Updating the raw value allows movement abilities to observe the automatic travel request.
4. RPG preserves the current facing during ordinary forward/back and strafe input. The turn axis adds yaw; held rotate or forced camera rotation also adds the yaw difference between the character and look source.
5. Character Locomotion applies the resulting request through acceleration, root motion, gravity, collision, slopes, and active abilities. The Movement Type does not move the Transform directly.
6. The paired RPG View Type follows the resulting character rotation. A stored free-camera offset recenters while the character is moving, according to the View Type's **Yaw Snap Damping**.

RPG reports independent look for both character and item queries. Aim and Use therefore do not automatically turn the character in the same way as a camera-facing Combat Movement Type. Item modules may still use the camera ray or their own fire/throw Transform according to their settings, so verify character facing, animation, crosshair, projectile, and hit direction together.

The RPG View Type watches **Move Towards** separately and follows character rotation while that ability positions the character. Other abilities can block, replace, or scale movement in their normal list order. Root-motion position and rotation remain Character Locomotion choices; RPG supplies direction and yaw, while the animation clip supplies root-motion displacement.

### Editor checkpoint

Before Play Mode, confirm that:

- **Third Person RPG** is active on both the character and camera;
- **Horizontal Input Name** and **Turn Input Name** are different and both exist in the active input map;
- **Rotate Input Name** and **Auto Move Input Name** resolve to intentional buttons;
- the Q/E and mouse-button bindings do not collide with item cycling, Aim, or Use unless that overlap is deliberate;
- **Allow Free Movement** matches the intended camera design; and
- forward, backward, strafe, turn, and root-motion animations cover the complete control set.

## Verify in Play Mode

1. Press forward and backward without turn input. Confirm the character keeps its yaw and moves along its current forward axis.
2. Test strafe and turn separately. Strafe should translate without changing yaw; turn should rotate without also adding sideways input.
3. Hold **Rotate Input Name** and move the look input. Confirm the character follows the camera yaw and the camera accepts pitch, then release it and confirm ordinary turn controls return.
4. Press **Auto Move Input Name** once. Confirm the character travels forward, can still strafe and turn, and respects walls and active abilities. Press backward to confirm it does not cancel the toggle, then press auto move again to stop.
5. If free camera movement is enabled, orbit while stationary, release the button, and wait. The offset should remain. Begin moving and confirm the camera recenters behind the character.
6. Hold **Character Forced Rotation Input Name** and confirm the camera aligns immediately and the character turns with its look source. Release it and confirm the temporary alignment mode ends.
7. Equip each relevant item and test Aim, Use, reload, and item cycling. Confirm no shared Q/E, `Fire1`, or `Fire2` binding triggers an unintended movement or camera command.
8. Compare in-place and root-motion locomotion at walk and run speeds. The character should keep the same RPG control relationship without sliding or double movement.
9. Trigger **Move Towards** and other movement-changing abilities. Confirm their positioning, stopping, and camera behavior remain intentional.
10. If the game switches Movement Types or perspectives, test the switch with auto move both off and on. Returning to RPG should not surprise the player with resumed travel.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Left/right input both strafes and turns. | **Horizontal Input Name** and **Turn Input Name** request the same axis. | Use the matching pair from the input-route table or create two distinct actions. |
| `Alt Horizontal` does nothing with the Unity Input System. | The released `CharacterInput` action asset has no action with that name. | Keep the handler on `Horizontal` and set RPG **Turn Input Name** to `Turn`, or add a deliberate custom action and binding. |
| Q/E changes equipment while strafing or turning. | The supplied input configurations also bind Q/E to previous/next item. | Rebind item cycling or the RPG axis so each key has one gameplay purpose. |
| Rotate, turn, or auto move never responds. | RPG may not be active, the character may have no Ultimate Character Locomotion Handler, or the requested mapping may be absent. | Activate the RPG row, verify the handler and Player Input Proxy, and make every input name exist in the active map. |
| Pressing backward does not stop automatic travel. | Auto move is a toggle and replaces forward input with `1`. | Press **Auto Move Input Name** again; use a project-specific movement mode if manual backward should cancel it. |
| The character starts moving when returning to RPG. | Released Version 3 keeps the private auto-move toggle when RPG is deactivated. | Turn auto move off before switching, or replace this behavior in a project-specific Movement Type when switches must reset it. |
| Free camera movement or forced rotation does nothing. | **Allow Free Movement** is disabled by default, the mapping is missing, or the RPG View Type is not active. | Enable the option on the View Type, verify both camera input names, and activate the complete RPG pair. |
| The camera does not recenter after free movement. | The character may still be stationary. | Begin moving; the RPG View Type recenters its yaw offset only during movement. |
| Clicking aims or uses an item and also moves the camera. | RPG camera inputs share `Fire1` or `Fire2` with item abilities. | Assign separate camera and item actions, then retest all equipped items. |
| Aim does not rotate the character toward the crosshair. | RPG uses independent look rather than camera-facing Combat rotation. | Use the forced-rotation mode where appropriate, author matching independent-look animation, or choose a camera-facing Movement Type for that design. |
| Root-motion movement slides or moves at the wrong speed. | The animation displacement does not match the requested input or another ability changes the final movement. | Tune the locomotion clips and blend thresholds, then inspect active abilities; do not use **Turn Multiplier** as a movement-speed control. |

## Related tasks

- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [RPG View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/)
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

The released Version 3 `RPG` Movement Type defaults to `RotateInputName = "Fire3"`, `TurnInputName = "Horizontal"`, a serialized turn multiplier of `1.5`, and `AutoMoveInputName = "Action"`. It registers button-down/button-up events for rotate, an axis event for turn, and a button-down event for the auto-move toggle. `GetInputVector` forces processed and raw forward input while auto move is active; `GetDeltaYawRotation` combines the current turn-axis value with look-source alignment during rotate or forced-rotation modes.

The public `TurnMultiplier` property is incorrectly wired to the current turn value in the released Version 3 source instead of the serialized multiplier field. The Inspector's **Turn Multiplier** field is read correctly by runtime turning, but code that gets or sets the public property does not read or change that field. Configure the multiplier in the Inspector, or expose the protected multiplier from a project-specific subclass when it must change through code.

Auto move has no public state or explicit reset API, and `ChangeMovementType` does not clear its private toggle. Projects that require deterministic reset-on-switch behavior should own that policy in a custom Movement Type rather than assuming deactivation stops the stored toggle.

---

<a id="page-ultimate-character-controller-character-movement-types-included-movement-types-third-person-top-down"></a>

# Third Person Top Down

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-top-down/)

Third Person Top Down turns direct movement input into overhead, screen-relative travel and can face either the movement direction or an independent cursor/right-stick aim direction. Pair it with the [Top Down View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/) for action games, twin-stick controls, or movement-facing overhead characters.

Top Down is one of three Movement Types recommended by that View Type. Use [Point & Click](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/) for destination-driven navigation or [Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/) for a creature that turns instead of strafing; neither is a mode of the direct Top Down Movement Type.

## Before you begin

- Create a working third-person player character with **Ultimate Character Locomotion**, **Ultimate Character Locomotion Handler**, player input, and an attached Camera Controller.
- Configure the movement and look actions through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/). Direct Top Down normally reads `Horizontal` and `Vertical` for movement, then uses the pointer or the configured horizontal/vertical look axes for facing.
- Decide who owns character facing: movement, cursor, controller look axes, root-motion animation, or an ability. Two owners can fight each other even when the camera framing looks correct.
- For a generic or non-humanoid character, identify a stable head or upper-body Transform. Humanoids can obtain the head from the Animator automatically.

## Build the direct Top Down pair

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Choose **Third** from **Perspective** and choose **Top Down** from **Third Person Movement**.
3. Complete the model, Animator, input, item, and ability choices, then select **Build Character**. Use **Update Character** for an existing character.
4. Select the character root. Under **Ultimate Character Locomotion > Movement Types**, confirm **Third Person Top Down** is present and selected as **Active**. When both perspectives are installed, also select it as **Third Person Movement Type**.
5. Select the Top Down row and configure **Relative Camera Movement**, **Look In Move Direction**, and **Head**.
6. Select the camera, expand **Camera Controller > View Types**, add and activate **Third Person Top Down**, and select it as **Third Person View Type** when both perspectives are installed.
7. Set the camera's **Forward Axis**, **Up Axis**, **Pitch Limit**, and **View Distance**, then test movement and aim before adding camera state transitions or springs.

## Configure movement and facing

| Setting | Released Version 3 default | Choose it by scenario |
| --- | --- | --- |
| **Relative Camera Movement** | enabled | Keep it enabled for screen-relative controls. Input is rotated from the camera orientation into the character's local input and diagonal magnitude is clamped to `1`. |
| **Look In Move Direction** | disabled | Enable it when travel input should control facing. Leave it disabled for cursor or right-stick aiming independent of movement. |
| **Head** | unassigned | Leave it empty for a valid humanoid Animator so Top Down can find the humanoid head. Assign a stable Transform for a generic rig; otherwise the character root is used. |

With **Relative Camera Movement** enabled, forward means toward the top of the camera composition, backward means toward the bottom, and horizontal input moves left or right across the view. Rotating the camera changes those world directions while preserving the same screen directions.

Disabling **Relative Camera Movement** does not create fixed world-axis movement in the released Version 3 implementation. It passes the input vector through unchanged, so Character Locomotion interprets it in the character's current local axes. Use a custom Movement Type when a cursor-facing character must move along fixed world axes regardless of both camera and character rotation.

When **Look In Move Direction** is enabled, nonzero movement input rotates the character toward the input direction relative to the top-down camera. With no movement input, the current yaw is retained. When it is disabled, the Movement Type asks the attached View Type for a look direction from **Head** and rotates toward that result.

## Choose cursor or controller aim

The Top Down View Type selects one of these facing paths when **Look In Move Direction** is disabled:

| Input state | Facing source | What to verify |
| --- | --- | --- |
| Cursor visible | A camera ray through the pointer, projected onto a plane through **Head** | The character faces the pointer without jitter when it crosses near the character. |
| No controller connected | The same pointer path, even if the cursor is hidden | The stored mouse position still determines facing. A hidden cursor alone does not select look-axis aiming. |
| Controller connected and cursor hidden | **Horizontal Look Input Name** and **Vertical Look Input Name**, transformed relative to the camera | The right stick aims independently of movement and retains the last direction inside the input dead zone. |
| **Look In Move Direction** enabled | Character forward from movement-facing logic | Cursor and look axes no longer choose character yaw. |

The View Type's **Vertical Look Direction** can use a physics hit to aim items above or below the horizontal plane. It does not change the character's yaw calculation into a pitch rotation. Configure target colliders, layers, **Look Direction Distance**, and an anchor above head height when items need vertical aiming.

## Choose the correct Top Down variant

| Goal | Movement Type | Setup consequence |
| --- | --- | --- |
| Direct keyboard/stick movement with cursor or twin-stick aim | **Third Person Top Down** | Use the workflow on this page and keep **Look In Move Direction** disabled. |
| Direct movement where the character faces travel | **Third Person Top Down** | Enable **Look In Move Direction**; cursor and right-stick aim do not control yaw. |
| Click a destination and navigate around obstacles | [Third Person Point & Click](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/) | Add a Pathfinding Movement ability and [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/), bake the navigation data, and keep the cursor available. |
| Overhead animal or creature without strafing | [Third Person Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/) | Horizontal input turns the creature, or **Rotate To Face Input Direction** converts the input into forward travel after facing. |

All three are recommended pairings for the Top Down View Type, but they do not share movement rules. Point & Click returns no direct movement or yaw request of its own; its pathfinding and Move Towards abilities drive travel. Four Legged deliberately removes strafing. Do not diagnose either behavior using the direct Top Down fields on this page.

## Coordinate root motion, items, and abilities

- **Use Root Motion Position** lets the animation supply displacement after Top Down chooses input direction. Use clips whose forward, backward, and strafe motion match the Top Down blend tree.
- **Use Root Motion Rotation** replaces the Movement Type's yaw request with the animation's rotation delta. Leave it disabled when the cursor, right stick, or movement input must rotate the character directly; enable it only when the turn clips own the complete visible rotation.
- **Previous Acceleration Influence** has a released default of `1` and is used only when root-motion position is off. If rapid cursor-facing changes rotate carried acceleration and create drift, set it to `0`. Do not treat `0` as a universal Top Down requirement when root-motion position is active or retained momentum is intentional.
- Top Down's independent-look result changes by facing mode and input device. With movement-facing or a connected controller, Aim and Use normally leave character yaw to the Movement Type. With mouse-facing and no connected controller, those abilities may also request the same look direction. Test animation, muzzle/throw direction, crosshair, and hit result together.
- Movement and item abilities can block or replace positional and rotational input. Confirm ability priority and concurrency when Aim, Use, Move Towards, knockback, or another ability changes the same frame's movement.

## How it runs

1. **Ultimate Character Locomotion Handler** reads horizontal, forward, and look input from the active player-input implementation.
2. Top Down calculates yaw from raw movement input when **Look In Move Direction** is enabled. Otherwise it requests a look direction from **Head** through the attached Top Down View Type.
3. The View Type uses its cached movement-facing state, a cursor ray and projection plane, or camera-relative controller look axes to produce that direction.
4. Top Down transforms the movement vector relative to the camera when **Relative Camera Movement** is enabled and clamps diagonal magnitude. When disabled, it returns the input unchanged.
5. Character Locomotion applies ability input restrictions, animation/root motion, acceleration, gravity, collision, slopes, and the requested yaw or root-motion rotation.
6. The Top Down View Type positions itself from its anchor, pitch, axes, and distance while continuing to provide character and item look directions.

### Editor checkpoint

Before Play Mode, confirm that:

- **Third Person Top Down** is active on both character and camera;
- **Relative Camera Movement** matches screen-relative versus character-local movement intent;
- exactly one facing design is intentional: movement, pointer, controller look axes, root motion, or an ability;
- a generic rig has **Head** assigned and a humanoid resolves the expected head bone;
- cursor visibility and connected-controller state select the intended look path;
- **Use Root Motion Rotation** is off when Top Down should own yaw; and
- non-root-motion characters use a deliberate **Previous Acceleration Influence** after drift testing.

## Verify in Play Mode

1. Hold each movement direction with **Relative Camera Movement** enabled. Confirm it follows the screen axes, then rotate or state-change the camera and repeat.
2. Disable **Relative Camera Movement** and turn the character. Confirm input now follows the character's local axes rather than an assumed fixed world axis.
3. Enable **Look In Move Direction**. Move in every cardinal and diagonal direction, stop, and confirm the character faces travel without rotating after input returns to zero.
4. Disable **Look In Move Direction**, show the cursor, and move it around the character and across the screen edges. The character should face the pointer without jitter near **Head**.
5. Hide the cursor with a controller connected and sweep both look axes. Aim should remain camera-relative and preserve its last direction inside the dead zone.
6. Disconnect the controller while the cursor is hidden. Confirm the built-in path returns to the stored mouse position; decide whether the game should reveal the cursor or provide a custom keyboard aim path.
7. Test **Vertical Look Direction** off and on against targets below, level with, and above **Head**. Character yaw should remain planar while item aim uses the intended height.
8. For a non-root-motion character, rotate aim sharply while moving and compare **Previous Acceleration Influence** at `1` and `0`. Choose the value that produces the intended momentum without drift.
9. Test **Use Root Motion Position** and **Use Root Motion Rotation** separately. Position clips should travel in the intended direction; rotation clips should not fight cursor or movement-facing yaw.
10. Equip every relevant item and test Aim, Use, projectiles, throwables, and IK with mouse and controller input. Visible direction and hit direction should agree.
11. Start every movement-changing ability used by the game. Confirm it blocks or combines with direct input and character rotation as designed.
12. If the character also contains Point Click or Four Legged, activate each in turn and confirm the camera remains Top Down while movement follows that type's own rules.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Movement does not follow the screen after the camera rotates. | **Relative Camera Movement** may be disabled or a different Movement Type may be active. | Enable it on the active Top Down row and confirm the matching camera is attached as the look source. |
| Disabling Relative Camera Movement does not produce fixed world directions. | Released Version 3 returns unchanged character-local input in this mode. | Keep camera-relative movement enabled or implement a custom world-relative transform. |
| The character faces travel instead of the pointer or right stick. | **Look In Move Direction** is enabled. | Disable it and verify the intended cursor/controller look path. |
| The character jitters or turns unpredictably near the pointer. | **Head** may resolve to the character root or an unstable Transform. | Assign a stable head/upper-body Transform and test the pointer crossing close to that position. |
| The right stick does not aim. | The controller may not be reported as connected, the cursor may still be visible, or the look-axis names may be missing. | Verify the input implementation, hide the cursor, and test **Horizontal Look Input Name** and **Vertical Look Input Name** directly. |
| A hidden-cursor keyboard setup still aims at the old mouse position. | The built-in controller-axis branch requires a connected controller as well as a hidden cursor. | Keep the pointer available or implement a custom View Type/input route for keyboard-only directional aim. |
| The character drifts when aim changes quickly. | A non-root-motion character may carry prior acceleration through the new rotation. | Reduce **Previous Acceleration Influence**, using `0` when no carry is desired; the field does not affect root-motion position. |
| The character ignores cursor or movement-facing yaw. | **Use Root Motion Rotation** or an active ability may own rotation. | Disable root-motion rotation for direct Top Down yaw, or author the complete turn in animation and remove the competing owner. |
| The item points at a different height than the cursor. | **Vertical Look Direction**, target layers/colliders, **Look Direction Distance**, or the camera anchor may be unsuitable. | Configure the View Type and test the actual item impact layers with the anchor above head height. |
| Aim or Use rotates differently between mouse and controller. | `UseIndependentLook` changes with **Look In Move Direction** and controller connection. | Test both devices, keep one facing owner per mode, and align the item animation and module direction with that owner. |
| Point & Click does not move. | Point Click needs a Pathfinding Movement ability and Move Towards; it does not use the direct Top Down input. | Follow the [Point & Click setup](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/) and verify navigation, cursor, layers, and ability order. |
| Four Legged will not strafe. | That Movement Type converts horizontal input into turning by design. | Use direct Top Down for strafing or configure Four Legged for the intended creature controls. |
| Point Click or Four Legged aim always returns character forward. | The Top Down View Type caches the first installed Top Down Movement Type and reads its **Look In Move Direction** value even when another type is active. | Disable **Look In Move Direction** on the installed Top Down type, or remove that unused type when the other pairing needs cursor/controller look. |

## Related tasks

- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Included Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/)
- [Top Down View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/)
- [Point & Click](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/)
- [Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/)
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

The released Version 3 `TopDown` Movement Type defaults **Relative Camera Movement** to `true`, **Look In Move Direction** to `false`, and **Head** to no explicit reference. `Initialize` resolves the humanoid head from the Animator when possible and otherwise falls back to the character Transform.

`GetDeltaYawRotation` uses raw movement input and the look source's up direction for movement-facing yaw. In independent-aim mode, it requests a character look direction from the resolved head position. `GetInputVector` performs the camera-relative conversion only when **Relative Camera Movement** is enabled and clamps the result with `Vector2.ClampMagnitude`.

`UseIndependentLook` always returns true for non-character look queries. For character look queries, it returns true when **Look In Move Direction** is enabled, the base force-independent setting is active, or a controller is connected; otherwise mouse-facing Aim and Use may also request character rotation.

The Top Down View Type's `AttachCharacter` method caches the first installed `TopDown` Movement Type, not necessarily the active one. Its detailed look-direction method reads that cached instance's **Look In Move Direction** value before choosing cursor or controller aim. This is why an inactive Top Down row can affect Point Click or Four Legged when all types are installed on one character.

---

<a id="page-ultimate-character-controller-character-abilities"></a>

# Abilities

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)

Abilities add self-contained character behaviors such as jumping, interacting, dying, changing speed, and using items without changing the core locomotion system. Each ability decides when it may start, what it changes while active, and when it stops. Unlike [effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/), abilities can drive the Animator and are synchronized across the network.

## How abilities run

An ability begins with a start request. The request can come from player input, an automatic check, another script, or a custom starter. The Ultimate Character Locomotion component then checks that the ability is enabled, that its own start conditions pass, and that active abilities do not block it.

For non-concurrent abilities, the order of the **Abilities** list establishes priority: an ability nearer the top has a higher priority. A higher-priority ability can prevent a lower-priority ability from starting, while a newly starting ability can interrupt active abilities when its rules require it. Concurrent abilities can remain active together, but their blocking and interruption rules are still evaluated.

After an ability starts, it can apply its state, Animator values, audio, attribute modifier, movement controls, gravity, root motion, and collision overrides. Its **Stop Type** or a manual stop request ends it and restores those temporary changes.

![Ability lifecycle from the start request and eligibility checks through active updates and stop conditions](https://opsive.com/wp-content/uploads/2018/03/AbilityLifeCycle.png?v=698758e8ad75)

## Add and configure an ability

1. Select the character and locate the **Ultimate Character Locomotion** component in the Inspector.
2. Expand **Abilities**, select the plus button, and choose the ability type. For equipping, aiming, using, reloading, and other item actions, use the separate **Item Abilities** list instead.
3. Select the new row to show its settings below the list, then leave **Enabled** selected.
4. Choose a **Start Type** and **Stop Type**. Add the required **Input Names** for an input-driven type.
5. Drag the row to the required position in the list. Put behavior that must take control, such as **Die**, above behavior it needs to interrupt.
6. Configure the fields specific to that ability. Set shared animation, state, input, gravity, root-motion, or collision options only when the ability needs to override the character defaults.

## Set priority and interruption

In this first arrangement, **Interact** is above **Die**, so Interact has the higher priority. A character killed while interacting may therefore be unable to start the Die ability and play its animation.

![The current UCC Abilities list shows Interact above Die, giving Interact the higher priority.](https://opsive.com/wp-content/uploads/2018/03/AbilityInteractPriority.webp?v=a8d79a8016e3)

Move **Die** above **Interact** so death can take control of the character while an interaction is active.

![The current UCC Abilities list shows Die above Interact so death has the higher priority.](https://opsive.com/wp-content/uploads/2018/03/AbilityDiePriority.webp?v=897de8276547)

List order handles the usual non-concurrent case. An ability can also explicitly block another ability from starting or stop an active ability when it begins. Make an ability concurrent only when it should overlap compatible behavior, such as changing movement speed while another action runs.

## Choose start and stop behavior

- Use **Automatic** when the ability should test its conditions every update, or **Manual** when another script controls it.
- Use **Button Down**, **Button Down Continuous**, **Double Press**, **Long Press**, **Tap**, or **Axis** for player-driven starts. **Input Names** identifies the input to read.
- Use **Custom** when an [Ability Starter](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/ability-starter/) should decide when the ability may begin.
- Stop with **Automatic**, **Manual**, **Button Up**, **Button Down**, **Button Toggle**, **Long Press**, **Axis**, or a custom stopper. An Axis stop occurs when the configured axis returns to zero.
- Use **State**, **Ability Index Parameter**, and **Animator Motion** when the ability must change animation or state behavior while active.
- Use the gravity, root-motion, positional input, rotational input, and collision options only for temporary overrides while the ability runs.

## Find the right ability workflow

### Use built-in character and item behavior

- [Included Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/) covers locomotion and character behaviors such as Jump, Interact, Die, Speed Change, and Ragdoll.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) covers equipping, aiming, using, reloading, blocking, and dropping items.

### Coordinate movement and animation

- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) explains how an ability can move the character to a required position before it starts.
- [Animator Motion](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/animator-motion/) explains reusable root-motion and Animator-driven movement shared by abilities.

### Author custom behavior

- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) shows how to implement and add a game-specific ability.
- [Ability Starter](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/ability-starter/) shows how to reuse custom start logic without placing that logic in every ability.

## Verify in Play Mode

1. Trigger the configured input or start condition and confirm **(Active)** appears beside the intended ability in the Inspector.
2. Confirm its animation, state, movement, gravity, root motion, and collision behavior change only where configured.
3. While it is active, trigger a higher-priority non-concurrent ability and confirm the first ability is interrupted. Test concurrent abilities separately and confirm both can remain active when their rules allow it.
4. Trigger the configured stop condition and confirm the ability becomes inactive and the character returns to its normal controls.

## Troubleshoot abilities

- **The ability does not start:** confirm **Enabled**, **Start Type**, and **Input Names**; then check its ability-specific conditions and whether an active higher-priority ability is blocking it.
- **The ability will not stop:** confirm **Stop Type** and its input, or check whether the ability's stop condition is deliberately keeping it active.
- **The wrong behavior wins:** drag the ability that must take control higher in the **Abilities** list, then retest the interruption in Play Mode.
- **Two abilities cannot run together:** confirm the overlapping behavior is intended to be concurrent and that neither ability explicitly blocks the other.
- **The ability runs without the expected animation:** check **Ability Index Parameter**, **Animator Motion**, and the active state, then confirm the character Animator contains the matching transitions.
- **An item action does not run:** configure it in **Item Abilities** and confirm the expected item and slot are active.

## Related topics

- [Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/)
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)

## Developer reference

Get the ability from **UltimateCharacterLocomotion**, then call **TryStartAbility** or **TryStopAbility**. A start request can still fail when the ability is disabled, its start conditions fail, or another active ability blocks it.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;

public class MyObject : MonoBehaviour
{
    [Tooltip("The character that should start and stop the jump ability.")]
    [SerializeField] protected GameObject m_Character;

    /// <summary>
    /// Starts and stops the jump ability.
    /// </summary>
    private void Start()
    {
        var characterLocomotion = m_Character.GetComponent<UltimateCharacterLocomotion>();
        var jumpAbility = characterLocomotion.GetAbility<Jump>();
        // Tries to start the jump ability. There are many cases where the ability may not start,
        // such as if it doesn't have a high enough priority or if CanStartAbility returns false.
        characterLocomotion.TryStartAbility(jumpAbility);

        // Stop the jump ability if it is active.
        if (jumpAbility.IsActive) {
            characterLocomotion.TryStopAbility(jumpAbility);
        }
    }
}
```

The built-in event system sends **OnCharacterAbilityActive** with the ability and an active-state boolean whenever an ability starts or stops. The corresponding Unity event on the locomotion component is also invoked.

```csharp
using UnityEngine;
using Opsive.Shared.Events;
using Opsive.UltimateCharacterController.Character.Abilities;

public class MyObject : MonoBehaviour
{
    /// <summary>
    /// Initialize the default values.
    /// </summary>
    public void Awake()
    {
        EventHandler.RegisterEvent<Ability, bool>(gameObject, "OnCharacterAbilityActive", OnAbilityActive);
    }

    /// <summary>
    /// The specified ability has started or stopped.
    /// </summary>
    /// <param name="ability">The ability that has been started or stopped.</param>
    /// <param name="activated">Was the ability activated?</param>
    private void OnAbilityActive(Ability ability, bool activated)
    {
        Debug.Log(ability + " activated: " + activated);
    }

    /// <summary>
    /// The GameObject has been destroyed.
    /// </summary>
    public void OnDestroy()
    {
        EventHandler.UnregisterEvent<Ability, bool>(gameObject, "OnCharacterAbilityActive", OnAbilityActive);
    }
}
```

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities"></a>

# Included Abilities

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/)

Ultimate Character Controller includes abilities for locomotion, animation, interaction, damage, AI movement, and perspective-specific behavior. Use this catalog to choose a concrete ability, understand how it normally starts, and place it correctly in the character's **Abilities** list.

The activation labels below describe the default behavior of a newly added ability:

- **Player input** reads a configured button or axis.
- **Automatic** tests its conditions without a separate start call.
- **System/manual** starts when another controller system, component, or script requests it.
- **Support base** is an abstract authoring reference and does not appear as a concrete choice in the ability picker.

## Add an included ability

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and choose the concrete ability type.
4. Select the new row to show its fields below the list. Confirm **Enabled**, then configure the ability-specific fields and any required **Input Names**.
5. Drag the row into the correct priority position. An ability nearer the top has a higher priority than a non-concurrent ability below it.
6. Enter Play Mode and test both the ability's start condition and any ability it should interrupt or run beside.

Do not change **Start Type** or **Stop Type** just to make an ability start during setup. The included abilities already supply defaults for their intended activation model; first complete the linked ability's prerequisites.

## Choose by player scenario

### Air movement, ground alignment, and stance

| Ability | Default activation | Choose it when |
| --- | --- | --- |
| [Align To Gravity Zone](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/align-to-gravity-zone/) | System/manual; concurrent | Gravity Zones should reorient the character, including between differently oriented surfaces. |
| [Align To Ground](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/align-to-ground/) | Automatic; concurrent | The character should align its up direction to the detected ground normal. |
| [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/) | Automatic | The character needs a falling state and animation after leaving the ground. |
| [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) | Player input | The player should launch the character, optionally with variable height, coyote time, or airborne jumps. |
| [Move With Object](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-with-object/) | Automatic; concurrent | The character should inherit the movement of a selected platform or target object. |
| [Slide](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/slide/) | Automatic; concurrent | Steep slopes should apply a sliding force to the character. |
| [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) | Held player input; concurrent | The player should run, sneak, or switch to another movement speed while other behavior continues. |
| [Height Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/height-change/) | Toggle player input; configurable concurrency | The character should crouch, crawl, or use another stance with a different height. |

### Starting, stopping, turning, and constraining locomotion

| Ability | Default activation | Choose it when |
| --- | --- | --- |
| [Quick Start](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-start/) | Automatic | Starting to move should play a dedicated acceleration animation. |
| [Quick Stop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-stop/) | Automatic | A sudden stop should play a dedicated deceleration animation. |
| [Quick Turn](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-turn/) | Automatic | A 180-degree turn should use an explicit turn animation. |
| [Stop Movement Animation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/stop-movement-animation/) | System/manual; concurrent | Movement animation should stop before root motion drives the character into a solid object. |
| [Restrict Position](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-position/) | Automatic; concurrent | The character must remain inside configured world-space bounds. |
| [Restrict Rotation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-rotation/) | Automatic; concurrent | The character's facing direction must remain within a configured range. |
| [Target Orbit](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/target-orbit/) | Automatic; concurrent | Movement should rotate consistently around a selected target. |
| [Rotate Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rotate-towards/) | Automatic | The character should turn toward a target using Animator root motion or motor rotation. |

### Aiming, pathfinding, and precise positioning

| Ability | Default activation | Choose it when |
| --- | --- | --- |
| [Assist Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/) | Automatic; concurrent | The camera or character should rotate toward a target supplied directly or by the Crosshairs Monitor. |
| [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) | System/manual; concurrent | Another ability requires the character to reach an exact interaction or animation position first. |
| [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) | Automatic; concurrent | AI or point-and-click movement should translate a Unity NavMeshAgent path into character input. |

### Interactions and reusable building blocks

| Ability | Default activation | Choose it when |
| --- | --- | --- |
| [Detect Ground Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-ground-ability-base/) | Support base | A custom ability must validate the ground by object identifier or layer. This abstract base is not added directly. |
| [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) | Support base | A custom interaction, pickup, climb, or similar ability must find and validate a nearby object. This abstract base is not added directly. |
| [Generic](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/generic/) | Player input | A one-off animation should run without writing a new ability class. |
| [Item Equip Verifier](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/item-equip-verifier/) | System/manual; concurrent | Other abilities temporarily restrict equipped item slots and the original items should be restored afterward. |
| [Rideable](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rideable/) | System/manual; concurrent | One Ultimate Character Controller character should act as the mount for another character's Ride ability. |

### Damage, death, and recovery

| Ability | Default activation | Choose it when |
| --- | --- | --- |
| [Damage Visualization](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/damage-visualization/) | System/manual | External damage should play a directional or damage-type animation. |
| [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/) | System/manual | Character death should take control and play the appropriate death animation. |
| [Impact Knock Back](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/impact-knock-back/) | System/manual | A melee counterattack should produce a full-body knock-back response. |
| [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/) | System/manual | Death, an impact, or gameplay logic should switch the character to a physics ragdoll. |
| [Revive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/) | System/manual | A dead or grounded character should play a get-up animation and return to play. |

### Presentation and perspective-specific behavior

| Ability | Default activation | Choose it when |
| --- | --- | --- |
| [Idle](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/idle/) | Automatic | An unmoving character should play varied idle animations after a delay. |
| [Lean (first person)](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/first-person-lean/) | Player axis; concurrent | A first-person camera should lean around cover without rotating the character body. |
| [Follow Pseudo3D Path (third person)](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/follow-pseudo3d-2-5d-path/) | System/manual; concurrent | A Pseudo3D movement type should keep the character aligned to its configured 2.5D path. |

## Order abilities intentionally

List order is part of the setup, even when the abilities have otherwise correct fields:

- Place character-wide responses such as **Die**, **Ragdoll**, **Revive**, **Damage Visualization**, and **Impact Knock Back** near the top so lower-priority actions do not prevent them from taking control.
- Place **Rotate Towards** near the top when it must control facing before lower-priority actions.
- Keep **Jump** directly above **Fall**. Jump explicitly stops an active Fall when a new jump is allowed.
- Keep **Speed Change** above **NavMeshAgent Movement**. Pathfinding Movement already applies the active speed multiplier when it writes the character input; placing Speed Change below it would apply the multiplier again.
- Keep **Quick Start**, **Quick Stop**, and **Quick Turn** near the bottom so their automatic animation checks do not prevent a more important ability from starting.
- Keep **Stop Movement Animation**, **Target Orbit**, and **Follow Pseudo3D Path** near the bottom because their concurrent updates should run after the movement they modify.
- Keep **Idle** at the bottom so any meaningful action can replace it.
- Keep **Rideable** near the bottom on the mount. The rider's separate Ride ability should have the higher control priority described on the Rideable page.

Concurrent means an ability can overlap other behavior; it does not always mean its list position is irrelevant. When an ability modifies input, rotation, or animation after another ability, follow the linked page's update-order guidance.

## Verify in Play Mode

1. Keep the **Ultimate Character Locomotion** Inspector visible and trigger the selected ability. Confirm **(Active)** appears beside the expected row.
2. Test an input-driven ability with its configured button or axis, an automatic ability by creating its condition, and a system/manual ability through the gameplay event that owns it.
3. Trigger a higher-priority response while a lower-priority non-concurrent ability is active and confirm the higher row takes control.
4. Test concurrent abilities together and confirm each changes only its intended movement, rotation, stance, or presentation behavior.
5. End the trigger condition and confirm the ability stops or remains active according to its documented **Stop Type**.

## Troubleshoot included abilities

- **The ability is missing from the picker:** confirm that its required first-person or third-person package is installed. Abstract entries such as **Detect Ground Ability Base** and **Detect Object Ability Base** are references for custom abilities and are not selectable.
- **The ability never becomes active:** confirm **Enabled**, required components or target objects, and **Input Names** for player-input abilities before changing the default activation type.
- **A lower-priority action prevents an important response:** move the response higher in **Abilities**, then repeat the conflict in Play Mode.
- **An automatic animation interrupts gameplay:** move Quick Start, Quick Stop, Quick Turn, or Idle lower and confirm its Animator parameters and transitions match the linked setup.
- **A concurrent ability produces the wrong final movement or rotation:** apply the linked page's update-order recommendation; concurrent abilities can still depend on which row updates first.
- **A system/manual ability does not start:** test the damage, death, interaction, item, mount, or script event responsible for requesting it rather than assigning an arbitrary input.

## Related topics

- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains priority, shared fields, lifecycle, and custom authoring.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) covers equipping, aiming, using, reloading, blocking, and dropping items.
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) explains how to implement behavior that is not covered by this catalog.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-align-to-ground"></a>

# Align To Ground

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/align-to-ground/)

Align To Ground rotates the character's up direction toward the detected ground normal. Use it when a character should follow slopes with its whole body, especially for long generic characters such as horses whose front and rear may stand at different heights.

## Before you begin

- The character must have an **Ultimate Character Locomotion** component and correctly sized locomotion Colliders.
- The surfaces that should control alignment must be included in **Solid Object Layers**. Ground sampling ignores triggers.
- Use [Align To Gravity Zone](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/align-to-gravity-zone/) instead when a trigger volume, planet, or other custom gravity source should define the direction.

## Add Align To Ground

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **Align To Ground**.
4. Keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Manual**.
5. Set **Distance** long enough to find the intended ground without reaching an unrelated surface below it.
6. Choose a **Depth Offset** sampling mode and configure **Normalize Direction** as described below.
7. Set **Align Smoothing**, **Align Gravity Direction**, **Stop Direction**, and **Airborne Stop Time** for the desired transition on slopes and in the air.
8. Enter Play Mode and test flat ground, the steepest supported slope, a ridge, and an airborne transition.

Align To Ground is concurrent and has no special list-order requirement. Avoid deliberately combining it with another active ability that also writes the character's up direction.

## Choose how the ground is sampled

### Collider-shaped cast for a compact character

Set **Depth Offset** to `0` to cast the character's locomotion Colliders downward by **Distance**. The cast uses each Collider's shape, even when a debug visualization represents it with a yellow line. This is a useful starting point for a compact humanoid whose support area is well represented by its Collider.

![Single downward collider-shaped ground cast shown as a yellow line beneath the character when Depth Offset is zero](https://opsive.com/wp-content/uploads/2018/03/AlignToGroundCast.png?v=60ae184e112b)

The ability accepts a hit only when its point is below the tested Collider. Keep **Distance** short enough that a floor on a lower level does not influence the character through a ledge or opening.

### Two rays for a long character

Set **Depth Offset** above `0` to sample with two downward rays separated along the character's local depth. The current forward input determines which side is treated as the front. When forward input is zero, both origins collapse to the center, so evaluate the separation while the character is moving. When both rays hit, the default behavior averages their surface normals; when only one hits, that hit supplies the normal.

![Two yellow ground rays sampling ahead of and behind a long character when Depth Offset is nonzero](https://opsive.com/wp-content/uploads/2018/03/AlignToGroundDualCast.png?v=dde7412912c4)

Increase **Depth Offset** until the rays represent the front and rear support points without extending beyond the character. This helps a horse or another long body bridge a crest or transition between slopes without reacting to only one point.

Enable **Normalize Direction** when the direction between the two hit points should define the aligned plane instead of averaging their normals. This is particularly useful for a long generic character. Keep it disabled when the average of the actual surface normals produces the more natural result.

## Choose alignment and airborne behavior

**Align Smoothing** is the smoothing time used to change the up direction. Its default is `0.2`.

- Reduce it for faster response on sharp slope changes.
- Increase it to reduce abrupt body rotation on gradual terrain.
- Test the value at full movement speed; excessive smoothing can leave the body behind the surface angle.

Keep **Align Gravity Direction** enabled when gravity should remain opposite the aligned up direction. Disable it only when another system intentionally owns **Gravity Direction**.

**Stop Direction** and **Airborne Stop Time** control what happens after leaving the ground:

- Leave **Stop Direction** at `(0, 0, 0)` when the character should retain its last orientation until another surface or system changes it.
- Set a normalized **Stop Direction**, such as `(0, 1, 0)`, when an airborne character should turn back toward world-up. The ability begins aligning to this direction while airborne.
- Leave **Airborne Stop Time** at its default `-1` to disable the scheduled airborne stop.
- Set **Airborne Stop Time** to `0` or greater when the ability should try to stop after that many seconds in the air. Landing before the delay finishes cancels the scheduled stop.

With **Start Type** set to **Automatic**, a stopped Align To Ground ability is eligible to start again on the next ability update. If it must remain stopped after **Airborne Stop Time**, use **Manual** activation or a state/gameplay system that disables or controls the ability until it should resume.

## How Align To Ground runs

Because **Start Type** is **Automatic**, an enabled Align To Ground ability starts without player input. Starting enables the locomotion system's up-direction alignment.

While grounded, or while no nonzero Stop Direction is taking over in the air, the ability samples below the character using the selected cast mode. A valid result is smoothed into the character's **Up** value. When **Align Gravity Direction** is enabled, **Gravity Direction** is updated to the opposite direction at the same time.

After the character becomes airborne, a nonzero Stop Direction takes priority over further ground sampling. A nonnegative Airborne Stop Time schedules the ability to stop; landing cancels that request. When the ability stops, it releases up-direction alignment unless another Align Up Direction ability is still active.

Align To Gravity Zone force-stops an active Align To Ground ability when zone alignment begins so the zone can take control.

## Verify in Play Mode

1. Keep the **Ultimate Character Locomotion** Inspector visible and confirm **(Active)** appears beside Align To Ground.
2. Walk from flat ground onto a slope and confirm the character's up direction follows the surface without visible snapping.
3. With **Depth Offset** set to `0`, confirm the Collider-shaped cast detects the intended ground and does not reach a lower level through an edge.
4. On a long character, set a nonzero Depth Offset and cross a ridge. Confirm the front and rear samples create a steadier body orientation.
5. Compare **Normalize Direction** enabled and disabled on the most difficult terrain, then keep the mode that produces the expected body plane.
6. Jump with **Align Gravity Direction** enabled and confirm gravity remains opposite the current up direction.
7. Set a nonzero **Stop Direction**, jump, and confirm the character begins turning toward it while airborne.
8. To test a persistent airborne stop, use **Manual** or state-controlled activation, set **Airborne Stop Time** to a nonnegative value, and remain airborne longer than that delay. Confirm the ability stops. Repeat with a short jump and confirm landing cancels the scheduled stop.

## Troubleshoot Align To Ground

- **The ability never becomes active:** check **Enabled** and **Start Type**. Automatic activation does not require an input binding.
- **The character remains upright on a slope:** confirm the surface is included in **Solid Object Layers**, increase **Distance** enough to reach it, and verify the cast is not hitting a trigger.
- **A lower floor changes the character near a ledge:** reduce **Distance** so the cast cannot reach an unrelated surface below the intended ground.
- **The character rocks or reacts to only one end of a long body:** use a nonzero **Depth Offset**, position the two samples within the support length, and compare **Normalize Direction** with averaged normals.
- **The character jitters as it crosses a ridge:** increase **Align Smoothing** slightly, use the two-ray mode, and check that both sampled surfaces have stable Collider normals.
- **The body lags behind steep terrain:** reduce **Align Smoothing** or lower movement speed until alignment can keep pace.
- **The character aligns visually but gravity still pulls in the old direction:** enable **Align Gravity Direction** and confirm **Use Gravity** is enabled on Ultimate Character Locomotion.
- **The character stays tilted in the air:** set **Stop Direction** to the required airborne up direction. Set **Airborne Stop Time** only if the ability should also stop after a delay.
- **The ability stops during a long jump:** set **Airborne Stop Time** to `-1` or increase the delay. Landing cancels a pending stop.
- **The ability immediately restarts after Airborne Stop Time:** **Start Type** is still **Automatic**. Use manual or state-controlled activation when the airborne stop must persist.
- **Gravity Zone alignment replaces the ground normal:** this is expected when Align To Gravity Zone begins. Use one up-direction owner for each part of the scene.

## Related topics

- [Align To Gravity Zone](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/align-to-gravity-zone/) uses trigger-defined, weighted directions instead of ground casts.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains automatic activation, concurrent abilities, and runtime state.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) documents the solid layers used by collision and ground checks.
- [Generic Character](https://opsive.com/support/documentation/ultimate-character-controller/character/generic-character/) covers non-humanoid character setup where dual ground samples are especially useful.
- [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) explains synchronized moving surfaces that should also be included in terrain testing.

## Developer reference

The current runtime surface includes:

- **Distance:** controls the downward cast distance.
- **DepthOffset:** selects the Collider-shaped cast at `0` or separates the two rays at a nonzero value.
- **NormalizeDirection:** derives the aligned plane from the two hit positions instead of averaging both normals.
- **AirborneStopTime:** schedules a stop after the character becomes airborne; a negative value disables it.
- **AlignSmoothing**, **AlignGravityDirection**, and **StopDirection:** expose the shared Align Up Direction settings.
- **IsConcurrent:** returns `true`.
- **CanStayActivatedOnDeath:** returns `true`.
- **OnCharacterGrounded:** schedules the airborne stop when the character leaves the ground and cancels it after landing.

Align To Ground does not send a feature-specific event. It listens to the shared grounded event and writes the character locomotion system's up and gravity directions during its normal ability update.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-align-to-gravity-zone"></a>

# Align To Gravity Zone

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/align-to-gravity-zone/)

Align To Gravity Zone reorients the character and, by default, its gravity as the character enters a Gravity Zone trigger. Use it for spherical worlds, transitions between differently oriented surfaces, or another area where world-down should not remain the character's down direction.

## Before you begin

- The character must have an **Ultimate Character Locomotion** component and the Align To Gravity Zone ability.
- The character's main collider GameObject must use the **Character** layer so a Gravity Zone can recognize it.
- Each Gravity Zone needs a trigger Collider. A **Spherical Gravity Zone** specifically requires a **Sphere Collider** on the same GameObject.
- Avoid running another system that writes the character's up direction at the same time. Align To Gravity Zone stops an active [Align To Ground](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/align-to-ground/) ability when the zone alignment begins.

## Add the ability and a spherical zone

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **Align To Gravity Zone**.
4. Keep **Enabled** selected and both **Start Type** and **Stop Type** set to **Manual**. Gravity Zone trigger callbacks start and stop the ability, so it does not need an input binding.
5. Set **Align Smoothing**, **Align Gravity Direction**, and **Stop Direction** for the transition required by the scene.
6. Create or select the GameObject at the center of the spherical gravity area.
7. Add a **Sphere Collider**, enable **Is Trigger**, and set its radius and Transform scale to cover the intended area.
8. Add **Spherical Gravity Zone** to the same GameObject.
9. Configure **Influence** and **Influence Multiplier**, then enter Play Mode and cross the trigger boundary with the character.

The demo places spherical zones around exterior planets so the character's up direction points away from each planet center.

![Character between exterior planets whose overlapping spherical Gravity Zones orient the character toward their surfaces](https://opsive.com/wp-content/uploads/2019/01/PlanetGravityZone.png?v=b9e69c845508)

## Choose alignment and exit behavior

**Align Smoothing** is the smoothing time used while the character changes orientation. Its default is `0.2`.

- Reduce it for a quicker response when crossing a sharp gravity boundary.
- Increase it for a slower transition when the character has enough space to rotate gradually.
- Test the value at the character's fastest expected entry speed; a visually smooth transition can still be too slow for collision and movement needs.

Keep **Align Gravity Direction** enabled when gravity should pull opposite the newly selected up direction. Disable it only when another system deliberately owns **Gravity Direction** and this ability should change orientation without changing that force.

**Stop Direction** controls the orientation applied when the final zone is unregistered:

- Leave it at `(0, 0, 0)` to keep the last zone orientation after the ability stops.
- Use a normalized direction such as `(0, 1, 0)` to return to world-up when the character leaves all zones.

## Configure spherical influence

The spherical zone's Transform position is its center. For a character inside the Sphere Collider, the zone returns an outward direction from that center, making the character's gravity point inward when **Align Gravity Direction** is enabled.

**Influence** is an Animation Curve evaluated by distance. Its horizontal value is `0` at the sphere radius and `1` at the center; its vertical value controls the strength at that distance. **Influence Multiplier** scales the result, allowing a larger or more important zone to outweigh another zone in an overlap.

Use the Collider radius to define where the zone registers the character, and use the curve and multiplier to decide how strongly it competes inside an overlap. Avoid opposing directions with equal strength in an airborne overlap because their sum can cancel and leave no new alignment direction.

## How overlapping zones run

Entering a Gravity Zone registers it with the ability. The first registered zone starts Align To Gravity Zone, enables up-direction alignment, and begins smoothing toward the zone result.

When the character is airborne, the ability adds the direction vectors from every registered zone and normalizes the result. The vector magnitude returned by each zone therefore acts as its weight.

When the character is grounded, the ability uses only the registered zone with the strongest direction magnitude. This prevents a second overlapping zone from pulling the character away from the surface currently supporting it.

Leaving a trigger unregisters that zone. The ability stays active while at least one zone remains, then stops after the last zone is removed and applies **Stop Direction** when configured. The ability is concurrent and can remain active with compatible locomotion abilities.

## Verify in Play Mode

1. Keep the **Ultimate Character Locomotion** Inspector visible and move the character into one Gravity Zone.
2. Confirm **(Active)** appears beside Align To Gravity Zone.
3. Confirm the character's up direction turns toward the zone result at the rate implied by **Align Smoothing**.
4. With **Align Gravity Direction** enabled, jump and confirm gravity pulls opposite the character's new up direction.
5. Enter an overlap while airborne and confirm the character follows the weighted blend between both zones.
6. Land inside the overlap and confirm the strongest zone controls orientation instead of the blended airborne direction.
7. Exit one zone and confirm the remaining zone continues to control the character.
8. Exit the final zone and confirm the ability becomes inactive and the character either keeps its orientation or aligns to **Stop Direction**, as configured.

## Troubleshoot Align To Gravity Zone

- **The ability never becomes active:** check that the character has the ability, its main collider is on the **Character** layer, the zone Collider has **Is Trigger** enabled, and the physics collision matrix allows the trigger pair.
- **A Spherical Gravity Zone produces an error or no direction:** add a **Sphere Collider** to the same GameObject as **Spherical Gravity Zone** and give it a nonzero radius.
- **The character orients correctly but falls in the old direction:** enable **Align Gravity Direction** and confirm **Use Gravity** is enabled on Ultimate Character Locomotion.
- **The character rotates too slowly or snaps too quickly:** reduce **Align Smoothing** for a faster transition or increase it for a slower one, then retest at gameplay speed.
- **The character points toward a planet center instead of standing on its surface:** a custom Gravity Zone is likely returning gravity-down rather than the desired up direction. Return the desired character-up vector; the ability negates it when setting **Gravity Direction**.
- **Orientation flickers while grounded in overlapping zones:** adjust **Influence Multiplier**, the influence curves, or the trigger overlap so one zone remains clearly strongest on that surface.
- **Airborne alignment stalls between zones:** check for equal, opposing direction vectors that cancel. Change their influence or overlap geometry.
- **The character remains sideways after leaving every zone:** set **Stop Direction** to the required final up direction, such as `(0, 1, 0)` for world-up.
- **The ability remains active after leaving:** confirm every entered trigger receives an exit and unregisters. A custom zone or a zone disabled while occupied must also call **UnregisterGravityZone** for the character.
- **Another ability changes orientation at the same time:** prevent another up-alignment ability from starting while the zone is active. Align To Gravity Zone stops Align To Ground when it begins, but two active alignment writers should not be deliberately combined.

## Related topics

- [Align To Ground](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/align-to-ground/) aligns to detected surface normals instead of trigger-defined gravity.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains manual starts, concurrent abilities, and runtime activation.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) documents the **Character** layer used by Gravity Zone triggers.
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) explains how movement input is interpreted after the character's orientation changes.

## Developer reference

**GravityZone** is abstract. A custom zone implements **DetermineGravityDirection(Vector3)** and returns the desired character-up vector. The vector's magnitude supplies its relative influence when zones overlap.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Objects.CharacterAssist;

public class DirectionalGravityZone : GravityZone
{
    [SerializeField] private Vector3 m_LocalUp = Vector3.up;
    [SerializeField] private float m_Influence = 1;

    public override Vector3 DetermineGravityDirection(Vector3 position)
    {
        return transform.TransformDirection(m_LocalUp).normalized * m_Influence;
    }
}
```

The current runtime surface includes:

- **RegisterGravityZone(GravityZone):** adds a zone and starts the ability when it was inactive.
- **UnregisterGravityZone(GravityZone):** removes a zone and stops the ability after the final zone leaves.
- **DetermineGravityDirection(Vector3):** supplies a custom zone's weighted alignment vector for the character position.
- **AlignSmoothing**, **AlignGravityDirection**, and **StopDirection:** expose the inherited Inspector settings.
- **IsConcurrent:** returns `true`.
- **CanStayActivatedOnDeath:** returns `true`.

Align To Gravity Zone does not send a feature-specific event. Gravity Zone trigger callbacks control its registration and lifecycle directly.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-assist-aim"></a>

# Assist Aim

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/)

Assist Aim selects or accepts a target, then helps the camera, character, and item-use movement stay oriented toward it. Use it for target lock, controller-friendly aiming, or attacks that should track an enemy without replacing the normal camera and locomotion systems.

## Before you begin

- The character must have **Ultimate Character Locomotion** and an attached **Camera Controller** look source. Assist Aim cannot start without the Camera Controller.
- Potential target Colliders must be on a layer included in the character's **Enemy Layers**. Automatic searches ignore trigger Colliders.
- When **Require Line Of Sight** is enabled, configure **Solid Object Layers** so the ray can hit the target and the surfaces that should block it.
- Decide whether the ability, the Crosshairs Monitor, or gameplay code owns target selection. Do not leave two selection systems competing for **Target**.

## Add Assist Aim

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **Assist Aim**.
4. Keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Manual** for target-driven activation.
5. Choose one target source:
   - Keep **Auto Select Target** enabled to search **Enemy Layers** within **Radius** and **Angle**.
   - On the Crosshairs Monitor, enable **Auto Assign Assist Aim Target** to supply the Collider under the crosshairs. Attaching this monitor disables Assist Aim's automatic selection.
   - Disable **Auto Select Target** and assign **Target** from gameplay code for a scripted lock.
6. Configure target scoring, the aim point, rotation, movement, switching, and unlock behavior described below.
7. Enter Play Mode with at least two target Colliders and test acquisition, obstruction, target switching, item use, and target loss.

Assist Aim is concurrent. Target search itself has no special list-order requirement, but character rotation and desired movement are processed in ability-list order. Place Assist Aim below another concurrent ability when Assist Aim's target-facing or item-use movement should be the final value. Its default state is **AssistAim**.

## Choose automatic target selection

**Radius** defines the overlap search around **Center Offset**. Its default is `10`. **Angle** defines the complete search cone around the camera look direction; the runtime compares candidates against half of this value on each side. Its default is `10` degrees.

Each candidate receives an angle score multiplied by a distance score:

- **Angle Influence** evaluates the candidate angle divided by the half-angle. Shape it so targets near the camera look direction receive the preferred score.
- **Distance Influence** evaluates normalized squared distance from the character to the edge of Radius. Shape it so the desired near or far targets receive the preferred score.
- The candidate with the highest positive combined score becomes **Target**.

Keep **Require Line Of Sight** enabled when a wall should release the current target. The check casts from the character's transformed **Center Offset** to the selected target point and ignores triggers.

This line-of-sight option belongs to Assist Aim's automatic search. When **Auto Select Target** is disabled, the Crosshairs Monitor or gameplay system that owns Target must decide when an obstructed target should be cleared.

**Stickiness Angle** gives the current target a wider permitted angle during active rescoring. The default is `180` degrees. The current **Stickiness Score** field is serialized and publicly exposed, but the current target-scoring code does not read it; changing that value has no runtime effect.

While the player is input-aiming or a usable item is active, automatic selection retains an existing visible target instead of rescoring it by Radius and Angle. Losing line of sight can still clear the target.

## Choose the aim point and camera framing

Enable **Target Humanoid Bone** to replace a humanoid target with **Humanoid Bone Target**, which defaults to **Chest**. Configure these fields before selecting the target. The target needs a valid humanoid Animator reachable through its model or animation components.

For a non-humanoid target, add **Pivot Offset** to its target GameObject when its Transform pivot is not a useful aim point. **Target Offset** adds another local offset when Assist Aim computes camera, rotation, line-of-sight, and movement directions.

**Rotate Camera Towards Target** installs the camera rotational override while the ability is active:

- In first person, the override looks directly at the selected target point.
- In third person, enable **Look At Target** to look directly at the target. Leave it disabled to use the intermediate framing direction intended to keep the character and target in view together.

Disable **Rotate Camera Towards Target** when only character rotation or movement should use the lock. The rotational override then returns the Camera Controller's original rotation unchanged.

## Choose character rotation and movement

Enable **Rotate Character Towards Target** when the character should face the selected target. Outside input-aiming, a moving character keeps its normal locomotion-facing behavior; Assist Aim turns it while stationary. During input-aiming, it can face the target while moving as well.

**Move Character Towards Target** only applies while a usable item reports that it is actively being used. Merely locking or aiming at a target does not start this movement.

- **Min Distance** stops the assisted movement inside the chosen range. Its default is `2`.
- **Motor Distance Multiplier** evaluates distance divided by Radius, clamped from `0` to `1`, then writes the resulting movement magnitude toward the target.
- Test this option with the actual attack or item-use animation because Assist Aim replaces the desired movement during use.

Enable **Stop Speed Change** when an input-started Assist Aim should prevent or stop Speed Change. Automatic target-driven activation has no input index, so this setting is not applied to the default automatic start workflow.

## Configure switching and releasing the target

Enable **Can Switch Targets** to register the axis named by **Switch Target Input Name**, which defaults to **Horizontal**. A switch occurs when the absolute axis value exceeds **Switch Target Magnitude**, default `0.8`. The axis must return below `0.01` before another switch is allowed.

Switching searches **Enemy Layers** around the current target. It selects the next target on the requested side and wraps to the opposite extreme when none exists in that direction.

**Break Force** clears the target when the absolute value from **Horizontal Break Force Input Name** or **Vertical Break Force Input Name** exceeds the threshold. The defaults use **Mouse X**, **Mouse Y**, and a threshold of `1.5`.

- Set Break Force to `-1` to disable this release gesture.
- Break input is ignored while a usable item is actively being used.
- Clearing the target stops Assist Aim and removes its camera override.

## How Assist Aim runs

While inactive, Assist Aim can search for a target. With automatic start enabled, a non-null target and attached Camera Controller allow the ability to start. Starting installs the camera rotational override and registers configured switch and break-force input events.

While active, automatic selection revalidates line of sight and either keeps or rescores the target according to the aiming and item-use state. Character rotation runs during the locomotion rotation update. Assisted movement runs later during desired-movement calculation and only while an item is in use.

Changing **Target** sends **OnAimTargetChange**. A target death event clears Target, as does a valid break-force input or a failed line-of-sight check. Setting Target to null stops the ability. Stopping also clears the target, removes the camera override, and unregisters its temporary input events.

## Verify in Play Mode

1. Keep the **Ultimate Character Locomotion** Inspector visible and place one valid enemy inside Radius and Angle.
2. Confirm **Target** is assigned and **(Active)** appears beside Assist Aim.
3. Move a second enemy closer to the camera look direction and confirm the influence curves choose the expected candidate while neither aiming nor using an item.
4. Place an obstacle between the character and target. With **Require Line Of Sight** enabled, confirm the target clears and the ability stops.
5. Test the configured humanoid bone, Pivot Offset, and Target Offset and confirm projectiles, camera framing, and character facing use the intended point.
6. Compare first-person and third-person camera behavior, including both **Look At Target** settings.
7. Move normally without input-aiming, then aim from input while moving. Confirm character rotation changes only in the intended state.
8. Use an item with **Move Character Towards Target** enabled. Confirm movement begins only during item use and stops inside Min Distance.
9. Switch left and right between at least three targets. Confirm one switch occurs per axis deflection and that returning the axis to center permits the next switch.
10. Apply break input while not using an item and confirm the target releases. Repeat during item use and confirm the break input is ignored.
11. Defeat the selected target and confirm Target clears, the ability stops, and the camera override is removed.

## Troubleshoot Assist Aim

- **Assist Aim never becomes active:** confirm a Camera Controller is attached as the character's look source, **Target** is non-null, and **Enabled** and **Start Type** allow activation.
- **Automatic selection finds no targets:** check the target's non-trigger Collider, **Enemy Layers**, Radius, Angle, Center Offset, and the influence curves. A score of `0` is not selected.
- **Crosshairs selection and automatic selection fight each other:** enable **Auto Assign Assist Aim Target** on Crosshairs Monitor and keep Assist Aim's **Auto Select Target** disabled.
- **A scripted target is immediately replaced:** disable **Auto Select Target** before assigning the Target property.
- **A target clears when unobstructed:** ensure the target and blocking world layers are represented correctly in **Solid Object Layers**, and confirm the line from Center Offset reaches the target or its hierarchy.
- **Humanoid bone targeting uses the root or wrong point:** enable **Target Humanoid Bone** before selection, choose **Humanoid Bone Target**, and confirm the target exposes a valid humanoid Animator.
- **A non-humanoid is aimed at near its feet or origin:** add **Pivot Offset** to the selected target GameObject or configure **Target Offset**.
- **The character will not face the target while running:** this is expected outside input-aiming. Start the Aim item ability from input, or use a movement workflow designed to face the target.
- **Move Character Towards Target does nothing:** it runs only during a usable item's active-use event. Confirm the item is currently being used and the character is outside Min Distance.
- **Target switching repeats too quickly or does not occur:** confirm **Can Switch Targets**, the axis name, Switch Target Magnitude, and that the axis returns near zero between switches.
- **Break input does not release the lock:** confirm Break Force is not `-1`, the input axis names are valid, and no usable item is currently active.
- **Changing Stickiness Score has no effect:** the current runtime does not apply this serialized value. Tune Stickiness Angle and the influence curves instead.
- **Speed Change remains active:** Stop Speed Change only participates when Assist Aim itself was input-started. Control Speed Change separately in the automatic target workflow.

## Related topics

- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) supplies the input-aiming state used by Assist Aim's moving-rotation behavior.
- [Target Orbit](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/target-orbit/) can use the Assist Aim target to keep movement rotating around the selected object.
- [Look At](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/look-at/) controls character IK without rotating the camera.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) defines **Enemy Layers** and **Solid Object Layers**.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains automatic activation, concurrent abilities, list order, and runtime state.

## Developer reference

Set the **Target** property rather than calling a SetTarget method. Disable automatic selection when gameplay code should retain ownership of that target.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;

public class AimTarget : MonoBehaviour
{
    [SerializeField] private Transform m_Target;

    private AssistAim m_AssistAim;

    private void Awake()
    {
        var characterLocomotion = GetComponent<UltimateCharacterLocomotion>();
        m_AssistAim = characterLocomotion.GetAbility<AssistAim>();
        m_AssistAim.AutoSelectTarget = false;
    }

    public void SelectTarget()
    {
        m_AssistAim.Target = m_Target;
    }

    public void ClearTarget()
    {
        m_AssistAim.Target = null;
    }
}
```

The main runtime surface includes:

- **Target:** registers target-death handling, resolves optional humanoid bones and Pivot Offset, sends **OnAimTargetChange**, and stops the ability when cleared.
- **TrySwitchTargets(bool):** requests the next target on the right or left.
- **AutoSelectTarget**, **Radius**, **Angle**, **RequireLineOfSight**, **CenterOffset**, **DistanceInfluence**, **AngleInfluence**, **StickinessAngle**, and **StickinessScore:** expose selection settings. StickinessScore is not consumed by the current scoring implementation.
- **TargetHumanoidBone**, **HumanoidBoneTarget**, **LookAtTarget**, and **TargetOffset:** expose target-point and camera-framing settings.
- **RotateCharacterTowardsTarget**, **RotateCameraTowardsTarget**, **MoveTowardsTarget**, **MinDistance**, and **MotorDistanceMultiplier:** expose rotation and movement settings. The public movement property is named **MoveTowardsTarget** even though the Inspector label is **Move Character Towards Target**.
- **CanSwitchTargets**, **SwitchTargetMagnitude**, **BreakForce**, and **StopSpeedChange:** expose switching and release behavior.
- **IsTargetValid(Transform)** and **GetTargetScore(Transform, bool):** are protected virtual extension points for custom target rules and scoring.
- **OnAimTargetChange:** reports the selected Transform and input-aiming state through the shared character event system.

Assist Aim also listens for **OnCharacterAttachLookSource**, **OnItemStartUse**, **OnAimAbilityStart**, and the selected target's **OnDeath** event to coordinate its lifecycle.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-damage-visualization"></a>

# Damage Visualization

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/damage-visualization/)

Damage Visualization plays a directional hit-reaction animation when the character receives enough damage from an external attacker. Use it to show where a bullet, melee strike, or another sourced hit came from while the additive Animator layer preserves the underlying locomotion pose.

The built-in ability selects one of four reactions: front-left, front-right, back-left, or back-right. Damage with no attacker, such as the standard fall-damage workflow, does not start this ability.

## Before you begin

- The character needs **Ultimate Character Locomotion**, a Health component that sends **OnHealthDamage**, and an Animator configured for UCC parameters.
- The damage source must provide a non-null source owner as the attacker. A visual hit does not play when the Health event's attacker is null.
- The shipped Animator expects Damage Visualization to use **Ability Index Parameter** `10` and direction values `0` through `3`.

## Add Damage Visualization

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **Damage Visualization**.
4. Keep **Enabled** selected and both **Start Type** and **Stop Type** set to **Manual**. The Health event starts the ability, and its completion trigger stops it.
5. Place Damage Visualization near the top of the ability list. Its default index is `10`; a higher-priority active nonconcurrent ability can prevent it from starting, while Damage Visualization can stop lower-priority nonconcurrent abilities.
6. Keep **Ability Index Parameter** at `10` when using the shipped Animator Controller.
7. Set **Min Damage Amount** and configure **Damage Visualization Complete Event** for either a duration or an animation event.
8. Apply external damage from each side in Play Mode and confirm the four Animator branches match the hit positions.

## Choose which damage shows a reaction

**Min Damage Amount** is the inclusive threshold for a reaction. The default is `0`: damage starts the ability when its amount is equal to or greater than the threshold.

- Raise the value when small damage-over-time ticks should not interrupt other ability logic.
- Keep it low when every external impact needs visible feedback.
- Damage below the threshold is ignored before direction selection.

The attacker check is separate from the amount. The Health component derives the attacker from the damage source's source owner. If that value is null, Damage Visualization treats the damage as internal and does not start. This is why standard fall damage has no reaction, but it also means a custom projectile or hazard must identify its source owner when a reaction is expected.

## How direction selects an animation

The ability transforms the damage position into the character's local space at the moment of the hit:

| `AbilityIntData` | Local hit position | Built-in reaction |
| --- | --- | --- |
| `0` | Front and left | Front Left |
| `1` | Front and right | Front Right |
| `2` | Back and left | Back Left |
| `3` | Back and right | Back Right |

The default calculation uses the hit position, not the force direction or attacker position. Supply the actual world-space impact point when dealing damage. A result of `-1` prevents the ability from starting; the built-in calculation returns `-1` when the local hit position has no front or back component.

The shipped transitions are in **Additive Layer -> Damage Visualization**. The additive layer lets the hit reaction overlay movement such as running or jumping, even though Damage Visualization itself is a nonconcurrent character ability whose list priority can affect other abilities.

## Choose how the reaction completes

**Damage Visualization Complete Event** is an Animation Event Trigger with two modes:

- Disable **Wait For Animation Event** to stop after **Duration**. The default duration is `0.2` seconds. Use this for simple, consistent reactions that do not require clip-specific timing.
- Enable **Wait For Animation Event** to keep the ability active until **OnAnimatorDamageVisualizationComplete** is received. Add an Animation Event to every reaction clip that can play, set its function to `ExecuteEvent`, and use `OnAnimatorDamageVisualizationComplete` as its string value.

Choose the duration or event point at the moment the ability should release its priority. The visual animation can blend out through the Animator after that point.

## How Damage Visualization runs

Damage Visualization listens for **OnHealthDamage**. It first checks Min Damage Amount and the attacker, then calls **GetDamageTypeIndex** with the damage amount, world position, force, and attacker.

When the returned index is not `-1`, the ability starts manually. **Ability Index** becomes `10` by default, and **AbilityIntData** exposes the selected direction index to the Animator. The ability either schedules its completion by Duration or waits for the Animator event.

Completion stops the ability and cancels any pending scheduled event. Destroying the character unregisters both damage and Animator-completion listeners.

## Verify in Play Mode

1. Keep the **Ultimate Character Locomotion** and Animator Inspectors visible.
2. Apply damage equal to Min Damage Amount with a valid attacker and confirm Damage Visualization becomes active.
3. Confirm **Ability Index** is `10` and AbilityIntData is `0`, `1`, `2`, or `3` for front-left, front-right, back-left, and back-right hits.
4. Confirm the corresponding additive reaction plays without replacing the underlying locomotion animation.
5. Apply damage below Min Damage Amount and confirm the ability does not start.
6. Apply damage with a null attacker, including fall damage, and confirm the ability does not start.
7. In duration mode, confirm the ability stops after the configured Duration.
8. In event mode, confirm every reaction clip sends **OnAnimatorDamageVisualizationComplete** and the ability stops at the intended frame.
9. Start a lower-priority nonconcurrent ability, apply damage, and confirm Damage Visualization takes priority. Repeat with a higher-priority ability and confirm the intended priority rule.

## Troubleshoot Damage Visualization

- **The character takes damage but the ability never starts:** confirm the amount meets **Min Damage Amount**, the Health event has a non-null attacker, and Damage Visualization is enabled.
- **A projectile or hazard causes no reaction:** check its DamageSource and source owner. Health sends a null attacker when no source owner is available.
- **Fall damage does not play a hit reaction:** this is expected because fall damage has no external attacker.
- **The wrong directional animation plays:** pass the world-space impact position rather than the attacker position or force vector, then verify the character's facing at the damage frame.
- **Every hit plays the same clip:** confirm the Animator transitions test AbilityIntData values `0` through `3` and the damage position changes between tests.
- **No reaction plays while another ability is active:** place Damage Visualization above the ability it should interrupt. A higher-priority nonconcurrent ability can block it.
- **Movement or another action stops unexpectedly:** Damage Visualization is nonconcurrent and can stop lower-priority nonconcurrent abilities. Adjust list priority only after deciding which response should win.
- **The ability stops before the visible reaction finishes:** increase Duration or move **OnAnimatorDamageVisualizationComplete** later in the clip.
- **The ability remains active indefinitely:** when **Wait For Animation Event** is enabled, confirm every reachable reaction clip sends **OnAnimatorDamageVisualizationComplete** with the exact string value.
- **A custom reaction never plays:** confirm the override returns the expected new AbilityIntData value and the Additive Layer contains a transition for that value.

## Related topics

- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) explains damage sources and the **OnHealthDamage** event.
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains the additive layer used for the reaction states.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains Ability Index and AbilityIntData.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists Damage Visualization's default index of `10`.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains duration and Animator-event completion modes.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains priority, manual activation, and nonconcurrent ability behavior.

## Developer reference

Override **GetDamageTypeIndex** to add another damage category. Return `-1` to suppress the reaction. This example uses AbilityIntData `4` for damage above `20` and preserves the built-in directional result for other hits.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character.Abilities;

[System.Serializable]
public class MyDamageVisualizationAbility : DamageVisualization
{
    /// <summary>
    /// Returns the value assigned to the AbilityIntData Animator parameter.
    /// </summary>
    protected override int GetDamageTypeIndex(float amount, Vector3 position, Vector3 force, GameObject attacker)
    {
        if (amount > 20) {
            return 4;
        }

        return base.GetDamageTypeIndex(amount, position, force, attacker);
    }
}
```

Replace the built-in ability with the subclass so both do not respond to the same Health event. In the Animator Controller, add the custom clip to **Additive Layer -> Damage Visualization** and create a transition whose AbilityIntData condition equals `4`.

![Animator Controller Damage Visualization sub-state machine with a custom reaction selected when AbilityIntData equals 4](https://opsive.com/wp-content/uploads/2018/03/CustomTakeDamage-1024x385.png)

If the ability waits for an animation event, add **OnAnimatorDamageVisualizationComplete** to the custom clip as well.

The feature-specific runtime surface is intentionally small:

- **AbilityIntData:** returns the selected damage type index.
- **GetDamageTypeIndex(float, Vector3, Vector3, GameObject):** is the protected virtual extension point for reaction selection.
- **OnHealthDamage:** supplies the amount, position, force, attacker, and hit Collider used to trigger the workflow.
- **OnAnimatorDamageVisualizationComplete:** stops the active reaction.

**Min Damage Amount** and **Damage Visualization Complete Event** are serialized Inspector settings but are not exposed as public properties by the current Damage Visualization class.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-detect-ground-ability-base"></a>

# Detect Ground Ability Base

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-ground-ability-base/)

Detect Ground Ability Base lets a specialized ability run only while the character stands on eligible ground. Use it when an ability should recognize a particular platform, ledge, diving board, or surface rather than every object that can support the character.

This is an abstract support class, so it does not appear as an ability that you can add directly. You encounter its settings on a concrete or custom ability that derives from it. Opsive add-ons currently use it for abilities such as Balance, Ledge Strafe, and Dive.

## Before you begin

- The character needs an **Ultimate Character Locomotion** component and must be grounded for the base check to succeed.
- Add the concrete ability that supplies the gameplay behavior. The base class only decides whether the ground beneath the character is valid.
- Decide whether a layer is enough to identify the surface or whether the surface also needs an [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/).

## Configure valid ground

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities** and select the concrete ability that uses Detect Ground Ability Base.
3. Set **Layer Mask** to include every layer that can activate the ability.
4. Leave **Object ID** at `-1` when the layer is the only required identity check.
5. To target a particular kind of ground more narrowly, add **Object Identifier** to the same GameObject as the ground collider and give it an ID. Enter that value in the ability's **Object ID** field.
6. Set **Ground Normal Sensitivity** for the steepest surface that should remain valid.
7. Leave **Angle Threshold** at `180` when facing direction should not matter, or lower it when the character must face along the ground object's forward direction.

When **Object ID** is not `-1`, the ground must have a matching Object Identifier *and* its layer must be included in **Layer Mask**. The two filters are combined; a matching ID does not bypass the layer check.

## Choose the surface and direction rules

- **Layer Mask** is the broad filter. It is usually sufficient when all objects on the selected layers should work.
- **Object ID** adds a second identity check. Use it when only selected colliders on an allowed layer should work.
- **Ground Normal Sensitivity** ranges from `0` to `1`. Higher values require the ground normal to align more closely with the character's up direction, so the accepted surface must be flatter relative to the character.
- **Angle Threshold** ranges from `0` to `180`. Lower values require the character to face more closely toward the ground transform's forward direction.

If the same object should accept several evenly spaced facing directions, add **Object Forward Faces** to the ground object and set **Forward Face Count**. The base class uses those faces when evaluating **Angle Threshold**.

## How it runs

Before the concrete ability starts, the base class checks the character's current grounded raycast. The character must be grounded, and the hit must pass the surface-normal, facing-angle, layer, and optional Object Identifier checks.

While the ability is active, the base class repeats the ground check during each update. Stepping off the object, becoming airborne, turning outside the allowed angle, or moving onto a disallowed surface stops the ability. The concrete ability can add its own requirements, such as a nearby wall or water below a diving platform.

The base class can also attach the character to the detected ground for the ability's lifetime through its `MoveWithObject` property. This option is hidden by the generic ability Inspector and is intended for a derived ability or custom drawer to expose when needed. When enabled, it uses the locomotion moving-platform relationship while the ability is active and releases that relationship when the ability stops.

## Verify in Play Mode

1. Place one valid and one invalid ground object in the scene.
2. Meet the concrete ability's other start requirements, then move the character onto the valid object.
3. In **Ultimate Character Locomotion**, confirm that **(Active)** appears beside the concrete ability when its activation condition is met.
4. Turn the character within and beyond **Angle Threshold**, if that filter is in use, and confirm the ability is active only in the accepted directions.
5. Move onto the invalid object or leave the ground. Confirm the ability stops.
6. If the derived ability enables `MoveWithObject`, move or rotate the ground object and confirm the character follows it only while the ability remains active.

## Troubleshoot ground detection

| Symptom | Check | Fix |
| --- | --- | --- |
| Detect Ground Ability Base is missing from the ability picker. | The type is abstract and cannot be added directly. | Add a concrete ability that derives from it, or create a custom ability for the required behavior. |
| The concrete ability never starts on the intended object. | Confirm that the character is grounded and that the collider's layer is included in **Layer Mask**. | Correct the collider layer or expand **Layer Mask**, then check any additional start requirements on the concrete ability. |
| The Object ID matches, but the ground is rejected. | A matching ID and an allowed layer are both required. The Object Identifier is read from the ground collider's GameObject. | Include that GameObject's layer and place a matching **Object Identifier** on the same GameObject as the collider. |
| The ability starts on flat ground but stops on a slope. | **Ground Normal Sensitivity** may require a flatter surface. | Lower the value gradually and retest the steepest surface that should be accepted. |
| The ability works from one direction only. | **Angle Threshold** is measured against the ground transform's forward direction. | Rotate the ground transform, increase **Angle Threshold**, or add **Object Forward Faces** for a multi-sided object. |
| A moving surface carries the character only through normal ground detection. | The derived ability may not expose or enable `MoveWithObject`. | Use the standard [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) workflow, or have the derived ability own the moving-ground relationship. |

## Related tasks

- [Included Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/) explains how to select and order concrete abilities.
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) walks through creating a custom ability.
- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) provides detection for nearby or targeted objects rather than the ground beneath the character.
- [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) explains the component used by the optional ID filter.
- [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) covers ordinary ground-based platform movement.

## Developer reference

`DetectGroundAbilityBase` exposes `ObjectID`, `LayerMask`, `NormalSensitivity`, `AngleThreshold`, and `MoveWithObject` properties. The Inspector label **Ground Normal Sensitivity** maps to the `NormalSensitivity` property.

`CanStartAbility` calls the grounded-object check after the shared ability checks. `IsValidGroundObject(GameObject)` performs the Object Identifier and layer tests, while the protected grounded-object checks also apply the normal and angle rules. `Update` stops the active ability as soon as the current ground becomes invalid.

A derived ability that overrides `CanStartAbility`, `AbilityStarted`, `Update`, or `AbilityStopped` should preserve the corresponding base call so ground validation, moving-ground attachment, and cleanup continue to run.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base"></a>

# Detect Object Ability Base

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/)

Detect Object Ability Base gives a specialized ability a consistent way to find a nearby or targeted object before it starts. Use its inherited settings when an interaction, pickup, vehicle, mount, climbing action, or similar ability should be available only for an eligible scene object.

This is an abstract support class, so it does not appear in the ability picker. Select a concrete ability that derives from it and configure detection on that ability.

## Choose the concrete ability

The included derived abilities apply the detected object in different ways:

| Goal | Ability |
| --- | --- |
| Press a button, open a door, or run another scene interaction. | [Interact](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/) |
| Turn the character's IK toward a nearby point of interest. | [Look At](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/look-at/) |
| Play an animation while collecting an item, health pickup, or another object. | [Pickup](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/) |
| Enter and control a vehicle. | [Drive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/) |
| Mount and dismount a rideable character. | [Ride](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/ride/) |

Optional Opsive add-ons also use the base for actions such as Vault, Hang, climbing, and swimming. Each concrete ability performs its own final validation, so follow that ability's page for the components required on the detected object.

## Before you begin

- The character needs an **Ultimate Character Locomotion** component and the chosen concrete ability.
- The target needs a collider on a layer that the ability can detect. Enable **Is Trigger** when using trigger detection.
- If **Use Look Position** or **Use Look Direction** will be enabled for a cast, the character needs an attached Look Source.
- Add any component required by the concrete ability, such as an Interactable for the Interact ability.

## Configure object detection

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities** and select the concrete ability.
3. Set **Object Detection** to the method that matches the interaction area. Keep the concrete ability's default unless the scene needs a different method.
4. Set **Detect Layers** to include the layer of the target collider or trigger.
5. Leave **Object ID** at `-1` when every eligible object on those layers should be considered. To identify a narrower set, add [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) to the detected object or one of its parents and enter the matching ID.
6. For a cast, choose whether **Use Look Position** and **Use Look Direction** should follow the camera or another Look Source. Disable them to use the character's position and forward direction instead.
7. Set **Cast Distance** and **Cast Offset** so the cast reaches the intended object without reaching unrelated objects. Keep **Cast Frame Interval** at `0` to test every frame, or increase it when detection does not need to update every frame.
8. For **Spherecast**, set **Spherecast Radius**. For **Raycast** or **Spherecast**, use **Trigger Interaction** to decide whether the cast can hit trigger colliders.
9. Use **Angle Threshold** when a cast should approach the target from an accepted direction. Leave it at `360` to impose no angle limit.
10. Enable **Move With Object** only when the character should follow the detected object's movement while the concrete ability is active.

## Choose a detection method

- **Trigger** is best for a defined proximity area around a button, pickup, mount, or point of interest. **Max Trigger Object Count** limits how many valid trigger candidates can be tracked at once. Trigger-only detection does not apply **Angle Threshold** because it has no cast hit direction.
- **Charactercast** sweeps the character colliders forward. Use it when the character's full collision shape should determine whether an obstacle or action point is reachable.
- **Raycast** provides a narrow, precise check from **Cast Offset** along the chosen direction.
- **Spherecast** provides a more forgiving check around the chosen direction. **Spherecast Radius** controls that width.
- **Customcast** is for a derived ability that implements its own detection rule.

**Object Detection** is a mask, so it can contain more than one built-in method. A single method is easier to reason about unless the concrete ability intentionally combines them. When methods are combined, valid trigger candidates are checked first, followed by Charactercast, Raycast, and Spherecast.

## Refine which object is accepted

**Detect Layers** is always the broad physics filter. **Object ID** adds an identity check after an object is found; it does not replace the layer filter. The base searches the detected GameObject and its parents for a matching Object Identifier.

For cast detection, **Angle Threshold** compares the detection direction with the face that the cast hit. Lower values require a more direct approach. Add **Object Forward Faces** to the target or a parent when the object should expose several evenly spaced valid facing directions; in that case the configured forward faces are used instead of the individual hit normal.

**Use Look Position** changes the cast origin to the Look Source transform. **Use Look Direction** changes only the cast direction. This allows a camera-directed interaction, a character-directed interaction, or a mix of the two.

## How it runs

When the locomotion system checks whether the concrete ability can start, Detect Object Ability Base first evaluates stored trigger candidates. If no trigger candidate qualifies, it runs the selected casts when their frame interval is due. A target must be active, on a detected layer, match **Object ID** when one is set, pass the cast angle when applicable, and satisfy the concrete ability's own validation.

The read-only **Detected Object** field shows the current candidate in the ability Inspector. When that reference changes, the base sends `OnObjectDetected` to the old and new objects. Trigger candidates are updated as the character enters and exits their colliders; a failed cast clears the cast result.

Detection makes an object available to the concrete ability, but the concrete ability still controls its input, start conditions, action, and stopping behavior. For example, finding an Interactable does not press the button until the Interact ability starts.

When **Move With Object** is enabled, starting the ability assigns the detected Transform as the character's moving-platform relationship if another moving platform does not already own it. Stopping the ability releases the relationship that it assigned.

## Verify in Play Mode

1. Create one valid target and one object that should be rejected. Give both colliders clear, known layers.
2. Enter Play Mode and approach or aim at the valid target using the selected detection method.
3. Select the concrete ability under **Ultimate Character Locomotion** and confirm **Detected Object** shows the valid target.
4. Move outside the trigger, turn the cast away, or exceed **Cast Distance**. Confirm **Detected Object** changes to another valid candidate or becomes empty.
5. Approach the rejected object and confirm it is not selected because of its layer, Object ID, angle, or missing ability-specific component.
6. Activate the concrete ability and confirm only the detected target responds.
7. If **Move With Object** is enabled, move or rotate the target while the ability is active and confirm the character follows it until the ability stops.

## Troubleshoot object detection

| Symptom | Check | Fix |
| --- | --- | --- |
| Detect Object Ability Base is missing from the ability picker. | The base type is abstract. | Add Interact, Pickup, Drive, Ride, Look At, or another concrete derived ability. |
| **Detected Object** always remains empty for a cast. | Check **Object Detection**, **Detect Layers**, **Cast Distance**, **Cast Offset**, and the target collider. If either look option is enabled, confirm a Look Source is attached. | Select the intended cast, include the collider layer, adjust the cast volume, or disable the look option for a character-relative cast. |
| Trigger detection never sees the target. | Check that the target collider has **Is Trigger** enabled and its layer is included in **Detect Layers**. | Correct the collider and layer setup, then re-enter the trigger. |
| The Console says the maximum number of trigger objects should be increased. | More valid triggers overlap the character than **Max Trigger Object Count** allows. | Increase the count or reduce overlapping interaction volumes. |
| **Angle Threshold** does not restrict a trigger interaction. | Trigger detection has no raycast hit and intentionally skips the angle test. | Use a cast for directional detection or let the concrete ability validate facing. |
| The correct Object ID is rejected. | The collider layer must still be in **Detect Layers**, and a matching Object Identifier must exist on the detected object or a parent. | Correct the layer and ID hierarchy, then verify the exact numeric value. |
| An object is detected but the concrete ability still cannot start. | The derived ability may require its own component, state, input, or arrival position. | Follow the concrete ability's setup and add a [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) when that action requires precise placement. |
| The character does not follow a moving detected object. | **Move With Object** may be disabled, or another moving-platform relationship may already be active. | Enable the setting for the concrete ability or use the standard [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) workflow. |

## Related tasks

- [Included Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/) explains how to add, select, and order concrete abilities.
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) shows how to create a custom ability from an ability base class.
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) defines a required position and rotation for actions such as Interact, Drive, and Ride.
- [Detect Ground Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-ground-ability-base/) filters the surface beneath the character instead of an object ahead or nearby.
- [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) explains the optional identity component.

## Developer reference

`DetectObjectAbilityBase` exposes `ObjectDetection`, `DetectLayers`, `DetectAngleThreshold`, `ObjectID`, `UseLookPosition`, `UseLookDirection`, `CastDistance`, `CastOffset`, `TriggerInteraction`, `SpherecastRadius`, `MaxTriggerObjectCount`, `MoveWithObject`, and the read-only `DetectedObject`. The protected `m_CastFrameInterval` field controls cast culling.

Override `ValidateObject(GameObject, RaycastHit?)` to add ability-specific requirements after calling the base implementation. Trigger detections pass a null hit, while cast detections provide the hit used by the angle test. A custom detector can use **Customcast** and the protected `DetectedObject` setter.

The base handles `OnTriggerEnter`, `OnTriggerExit`, detection-change events, and moving-object attachment. Derived abilities that override the corresponding lifecycle methods should preserve the base calls so candidate tracking and cleanup continue to work.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-drive"></a>

# Drive

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/)

Drive moves the character into and out of a vehicle, then lets the vehicle's own controller take over. Use it with a vehicle integration or a custom Drive Source; the ability handles the character transition but does not provide vehicle physics or movement.

## Before you begin

- The character needs **Ultimate Character Locomotion**, the Drive ability, and an Animator with the required Drive states when using animated entry and exit.
- The vehicle needs a component that implements `IDriveSource`. The demo's SkyCar is a simple example, while supported vehicle integrations provide their own Drive Source component.
- Add at least one [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) below the vehicle's Drive Source GameObject. Drive requires a valid location even when **Teleport Enter Exit** is enabled because the same location is used for exiting.
- The detected vehicle collider or trigger must be on a layer included by Drive's inherited **Detect Layers** setting.

## Set up the character

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities** and use the plus button to add **Drive**.
3. For an animated approach, also add [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) and keep Move Towards above Drive in the list. Pathfinding, when used, remains above Move Towards.
4. Keep Drive's default **Start Type** set to **Button Down**, **Stop Type** set to **Button Toggle**, and **Input Names** set to `Action` unless the project uses a different control.
5. Configure the inherited **Object Detection** settings. **Trigger** is a straightforward choice for a door-side interaction volume; a cast works when the player should aim or face toward the vehicle.
6. Set **Detect Layers** to include the detected collider. Use **Object ID** only when Drive must distinguish the vehicle from other detected objects.
7. Leave **Allow Equipped Slots** empty when items must be put away before driving. Add [Item Equip Verifier](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/item-equip-verifier/) when those items should be unequipped and restored through the normal ability workflow.
8. Choose animated or immediate entry with **Teleport Enter Exit**, then configure **Can Aim** and **Disable Mesh Renderers** for the vehicle presentation.

## Set up the vehicle

1. Add the Drive Source component supplied by the vehicle integration. For a custom vehicle, implement `IDriveSource` as described in the developer reference below.
2. Create a child Transform at the driver's seated position and rotation. Assign it to the Drive Source's **Driver Location** field.
3. Add one or more **Move Towards Location** components as children of the GameObject returned by the Drive Source. Place them beside the doors or other valid entry and exit points, with their forward direction matching the desired character facing.
4. If a Move Towards Location has a Box, Capsule, or Sphere Collider for exit-clearance testing, size it to the space the character needs and keep it clear of the vehicle and scenery. Drive skips a location while that collider overlaps another object.
5. Add the detection trigger or collider, place it on a layer included by **Detect Layers**, and ensure the Drive Source component is on that GameObject or a parent.
6. Ensure the Drive Source returns the vehicle colliders that should ignore the character while driving.
7. For a Rigidbody vehicle, choose the Rigidbody's interpolation mode intentionally. After entry, Drive matches the character locomotion interpolation to that Rigidbody and restores the previous character setting on exit.
8. When using animated entry and exit, ensure the entry animation sends `OnAnimatorEnteredVehicle` and the exit animation sends `OnAnimatorExitedVehicle` through the Animator Monitor event workflow.

## Choose the entry and exit style

### Animated entry and exit

Leave **Teleport Enter Exit** disabled when the character should approach a door, play an entry animation, remain seated, and play an exit animation. Move Towards selects the closest configured location for entry. The entry event completes the handoff to the vehicle; the exit event restores normal character ownership.

Every exit request still needs an unobstructed Move Towards Location. When several locations exist, Drive selects the first clear location returned from the Drive Source hierarchy for the exit.

### Immediate entry and exit

Enable **Teleport Enter Exit** when the vehicle has no entry or exit animations. Drive skips the Move Towards approach, immediately positions the character at **Driver Location**, and places the character at a valid Move Towards Location on exit. The vehicle still needs at least one valid Move Towards Location before Drive can start or stop.

## Choose item, aiming, and visibility behavior

- **Can Aim** allows the Aim ability to remain active while driving. The relevant item slot must also be selected in **Allow Equipped Slots**; with no allowed slots, Drive blocks all item abilities, including Aim.
- **Disable Mesh Renderers** hides every Skinned Mesh Renderer below the character after entry and restores them when exit begins. Enable it for a cockpit view that should not show the character body; leave it disabled for visible drivers.
- The inherited **Reequip Slots** setting determines whether Item Equip Verifier restores items after Drive finishes.
- **Move Speed** remains visible in the current Inspector, but the current Drive runtime does not read it. Move Towards controls the approach, the entry animation supplies animated movement, and Drive keeps the seated character aligned directly to **Driver Location**.

## Use one Drive ability with several vehicles

A single Drive ability can detect multiple Drive Source implementations. Give each vehicle animation set its own **Animator ID**, reserving separate groups of values conventionally in increments of `10`.

Drive adds its state offset to the Drive Source's **Animator ID** for the character's [AbilityIntData](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/):

- Enter adds `0`.
- Drive adds `1`.
- Exit adds `2`.

For example, an Animator ID of `70` produces AbilityIntData values `70`, `71`, and `72`. This lets the Animator select a vehicle-specific entry, seated, and exit sequence while the character keeps one Drive ability.

## How Drive runs

Detection succeeds only when the found object or one of its parents implements `IDriveSource` and the source has at least one valid Move Towards Location. Starting Drive makes the vehicle Transform the character's moving-platform reference, parents the character to it, enters the Enter state, and calls the source's entry callback.

For animated entry, the character remains in the Enter state until `OnAnimatorEnteredVehicle`. For immediate entry, Drive completes that step itself and teleports to **Driver Location**. Once seated, Drive ignores collisions between the character and the colliders supplied by the source, calls the source's entered callback, disables character root motion, and keeps the character positioned and rotated at **Driver Location**. The vehicle's Drive Source is responsible for enabling and controlling the actual vehicle.

Pressing the toggle input while seated requests an exit. Drive refuses the request when no exit location is clear. It calls the source's exit callback and either waits for `OnAnimatorExitedVehicle` or completes an immediate exit. Completion restores collision, interpolation, the original character parent, gravity alignment, and the ordinary moving-platform relationship.

## Verify in Play Mode

1. Approach the vehicle and confirm Drive's inherited **Detected Object** field shows its detection collider.
2. Press the configured `Action` input. For an animated approach, confirm Move Towards becomes active, reaches the expected door location, and then hands control to Drive.
3. Confirm **(Active)** appears beside Drive and the character reaches the Enter state followed by the seated Drive state.
4. After entry, confirm the character stays aligned with **Driver Location**, the vehicle controller becomes active, and the character does not collide with the vehicle body.
5. Steer the vehicle and confirm the character's AbilityFloatData follows horizontal input if the vehicle animation uses it.
6. Test aiming, equipped items, and character visibility against **Can Aim**, **Allow Equipped Slots**, and **Disable Mesh Renderers**.
7. Press `Action` again with a clear exit. Confirm the character reaches the Exit state, uses the intended location, returns to its original parent, and can move normally.
8. Re-enter, block the clearance collider, and request exit again. Confirm Drive remains active until another exit location is clear.

## Troubleshoot Drive

| Symptom | Check | Fix |
| --- | --- | --- |
| **Detected Object** never shows the vehicle. | Check the detection collider's layer and whether an `IDriveSource` component exists on that object or a parent. | Include the layer in **Detect Layers**, correct the optional **Object ID**, and use the integration's Drive Source component. |
| The vehicle is detected but Drive will not start. | Drive requires at least one valid Move Towards Location, even with teleporting enabled. | Add the component below the Drive Source GameObject and clear any overlap around its optional clearance collider. |
| The character reaches the door but never becomes seated. | The animated entry may not send `OnAnimatorEnteredVehicle`. | Add the exact event to every reachable entry clip or enable **Teleport Enter Exit** when no animation is required. |
| The exit input does nothing. | Check for a clear Move Towards Location and confirm Drive is already in its seated Drive state. | Clear or add an exit location, then retry after the entry has completed. |
| The exit animation plays forever. | The clip may not send `OnAnimatorExitedVehicle`. | Add the exact event to every reachable exit clip or use immediate exit. |
| The character sits at the vehicle origin or in the wrong pose. | **Driver Location** is missing or incorrectly positioned. | Assign and orient a dedicated seat Transform on the Drive Source. |
| The character enters correctly but the vehicle does not move. | Drive does not provide vehicle movement; the Drive Source must enable the vehicle controller in its entry callbacks. | Complete the integration setup or correct the custom source implementation. |
| The character or camera jitters while driving. | Compare the vehicle Rigidbody interpolation with the character's runtime interpolation and check for competing movement scripts. | Choose the intended Rigidbody interpolation and give the Drive Source sole control of the vehicle Transform. |
| **Can Aim** is enabled but Aim is blocked. | **Allow Equipped Slots** may still exclude every item slot. | Allow the required slot and verify that its item can remain equipped while driving. |
| Changing **Move Speed** has no effect. | The current runtime does not consume this serialized value. | Tune Move Towards, the Move Towards Location, or the entry animation instead. |

## Related tasks

- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) explains the inherited trigger, cast, layer, and Object ID settings.
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) controls the animated approach and must remain above Drive.
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) defines vehicle entry and exit points.
- [Item Equip Verifier](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/item-equip-verifier/) manages items excluded by **Allow Equipped Slots**.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains AbilityIntData and the other character parameters.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains the Animator Monitor event-string workflow used by custom clips.
- [Vehicle integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/) includes Edy's Vehicle Physics, NWH Vehicle Physics, Realistic Car Controller, and Realistic Car Controller Pro setup pages.

## Developer reference

An `IDriveSource` implementation supplies `GameObject`, `Transform`, `DriverLocation`, `Colliders`, and `AnimatorID`. It also implements four lifecycle callbacks:

- `EnterVehicle(Drive)` runs when the character starts entering.
- `EnteredVehicle(Drive)` runs after the character reaches the seated state.
- `ExitVehicle(Drive)` runs when a valid exit begins.
- `ExitedVehicle(Drive)` runs after the character has left the vehicle.

The demo SkyCar enables its vehicle controller in `EnteredVehicle`, disables it in `ExitVehicle`, and uses the other callbacks to manage door events. A custom source can use the same boundaries for input ownership, cameras, audio, lights, and vehicle state.

Drive exposes `TeleportEnterExit`, `CanAim`, and `MoveSpeed` properties. `AbilityIntData` returns `AnimatorID + DriveState`, while `AbilityFloatData` returns the character's raw horizontal input for steering animation. **Disable Mesh Renderers** is serialized as `m_DisableMeshRenderers`; the current class does not expose a public property for it. The serialized `MoveSpeed` value is also currently unused by Drive's runtime methods.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-interact"></a>

# Interact

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/)

Interact lets a character press a button, open a door, start a platform, or trigger several related object responses at one deliberate point in an animation. Use it when the character must detect an object, optionally move into position, and let that object's Interactable decide what happens.

## Before you begin

- The character needs **Ultimate Character Locomotion** and the Interact ability.
- The scene object needs an **Interactable** component and at least one component that implements `IInteractableTarget` in its **Targets** array.
- Add [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) to the character when the interaction animation must begin from a precise position.
- Choose whether **Interact Event** and **Interact Complete Event** use animation events or fixed durations. Custom character clips need the matching events when event mode is enabled.

## Add Interact to the character

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities** and use the plus button to add **Interact**.
3. Keep the default **Start Type** set to **Button Down**, **Input Names** set to `Action`, and **Ability Index** set to `9` unless the project uses a custom input or Animator setup.
4. Choose the inherited **Object Detection** method. **Trigger** works well for a proximity interaction; Raycast or Spherecast works when facing or aiming should select the target.
5. Set **Detect Layers** to include the detected collider. Leave the inherited **Object ID** at `-1` unless the object or one of its parents has a matching Object Identifier.
6. Leave **Interactable ID** at `-1` for a general Interact ability, or match it to the **ID** on one group of Interactable components.
7. Add Move Towards above Interact in the ability list when the object supplies a Move Towards Location. If pathfinding is used, keep it above Move Towards.
8. Choose whether an already active Height Change or Aim may remain active with **Allow Active Height Change** and **Allow Aim**. Enable **Concurrent** only when Interact should overlap other compatible abilities.
9. Set **Ability Int Data Value** when this interaction needs a particular character animation branch.
10. Configure **Interact Event** and **Interact Complete Event** for the animation or timing described below.

## Build a button interaction

This example makes one button start a moving platform and play a button animation.

1. Select the button GameObject and add **Interactable**.
2. Set **Targets** to contain two elements: the Moving Platform component that should start and an Animated Interactable component on the button.

![Button Inspector with an Interactable component that links the character to the button targets](https://opsive.com/wp-content/uploads/2018/03/ButtonInteractable.png?v=73f38d280f6d)

3. On the Moving Platform, enable **Enable On Interact**. Moving Platform already implements `IInteractableTarget`.
4. Add an Animator and **Animated Interactable** to the button. Set **Trigger Parameter** to the exact Animator trigger name, such as `Press`.
5. Assign the Moving Platform and Animated Interactable component instances to the Interactable **Targets** array. Every target must be assigned and must allow the interaction before Interact can start; when it runs, every target is invoked.

![Interactable Targets array connected to a Moving Platform and an Animated Interactable with Trigger Parameter set to Press](https://opsive.com/wp-content/uploads/2018/03/ButtonInteractableTargets.png?v=b608b77a7477)

6. For a positioned character animation, add **Move Towards Location** to the same GameObject as **Interactable**. Place and rotate its gizmo where the character should stand and face.

![Move Towards Location gizmo positioned in front of the button for the character interaction pose](https://opsive.com/wp-content/uploads/2018/03/ButtonStartLocation.webp?v=01e2d9cc18d7)

7. For proximity detection, add a trigger collider to the button or a child, place it on a layer included by **Detect Layers**, and size it to the intended interaction area. Interact can find the Interactable on a parent.

![Button interaction trigger volume surrounding the area where the character can use the button](https://opsive.com/wp-content/uploads/2018/03/ButtonTrigger.png?v=69f22bbf6739)

8. Enter Play Mode and test the full chain: detection, optional approach, character interaction timing, target response, and completion.

## Choose how the object responds

### One or several targets

**Interactable** is a coordinator. Its **Targets** array contains the components that perform the action. One target may open a door; several targets can start a platform, animate a button, and play another gameplay response together.

Before Interact can start, every target's `CanInteract` result must be true. This prevents a partly available interaction from running only some of its targets. When the interaction event occurs, Interactable calls every target in array order.

### Animated Interactable

Use **Animated Interactable** for simple Animator and audio responses without a custom target script:

- **Trigger Parameter** fires a trigger each time the target is used.
- **Bool Parameter** sets a bool to **Bool Interact Value**. Enable **Toggle Bool Interact Value** for states such as open/closed.
- **Single Interact** prevents further use after the first interaction until `ResetInteract` is called.
- **Interact Audio Clips** plays the configured clips sequentially across interactions.
- **Bool Enabled Message** and **Bool Disabled Message** provide the dynamic message for the next bool state.

### Hand or foot placement

Add one or more **Ability IK Target** components below the Interactable when a limb should reach a handle, button, or pedal. Set **Goal**, **Delay**, **Interpolation Duration**, and **Duration** for each contact point. Interact uses the character's Character IK component to blend to these targets and clears them when their duration ends or the ability stops.

## Choose detection, IDs, and positioning

- **Trigger** makes the interaction available while the character overlaps the detection volume. Leaving the trigger during an active interaction does not cancel it; cleanup occurs after Interact finishes.
- **Raycast**, **Spherecast**, and Charactercast use the inherited range, direction, layer, and angle settings. They are useful for focused interactions without a large proximity volume.
- **Object ID** belongs to the inherited Detect Object filter and matches an Object Identifier on the detected object or a parent.
- **Interactable ID** matches the **ID** on the Interactable component. Use it when the same character has multiple Interact ability entries with different animations, timings, or inputs.
- **Move Towards Location** controls where an aligned interaction begins. For Interact, place it on the same GameObject as the Interactable; Move Towards reads the locations from that exact object.

## Choose interaction timing

**Interact Event** controls when the targets respond after Interact starts:

- Disable **Wait For Animation Event** and set **Duration** for a timer. The default is `0.2` seconds.
- Enable **Wait For Animation Event** when the action must match a character animation. The clip must send `OnAnimatorInteract` at the contact frame.

After the targets respond, **Interact Complete Event** controls when the ability stops:

- Disable **Wait For Animation Event** and set **Duration** for a timed finish. Its default is also `0.2` seconds.
- Enable **Wait For Animation Event** when the animation owns completion. The clip must send `OnAnimatorInteractComplete`.

Use separate events so the object can respond at the hand-contact frame while the character finishes the rest of the animation before movement and lower-priority actions resume.

## Configure interaction messages

Set **Ability Message Text** for the prompt shown while Interact can start. A fixed prompt such as `PRESS F TO USE` needs no placeholder.

For a prompt that changes with object state, include `{0}`, such as `PRESS F TO {0} DOOR`. Interactable asks the first target in **Targets** that implements `IInteractableMessage` for replacement text. Animated Interactable supplies **Bool Enabled Message** or **Bool Disabled Message**, allowing the prompt to alternate between values such as `OPEN` and `CLOSE`.

## Choose ability overlap

- **Allow Active Height Change** keeps an already active Height Change ability running when Interact starts. Disable it when the interaction needs the standing collision height and pose.
- **Allow Aim** keeps an already active Aim ability running when Interact starts. Interact still blocks new Item Abilities from starting while it is active, so this does not start Aim midway through an interaction.
- **Concurrent** allows Interact to overlap other compatible abilities, but Interact still blocks Item Abilities, Stored Input abilities, and abilities lower in the list while it is active.

Keep important interrupts such as death or ragdoll above Interact. Keep Move Towards above Interact so it can complete alignment before the interaction begins.

## How Interact runs

The inherited detector finds a collider and Interact searches that object and its parents for an Interactable with a matching **Interactable ID**. The ability can start only when detection succeeds and every assigned target reports that it can interact. Move Towards runs first when the Interactable supplies a location and the character is not already aligned.

When Interact starts, it schedules any Ability IK Targets and waits for **Interact Event**. At that event it invokes all Interactable targets exactly once, then waits for **Interact Complete Event**. Completion stops the ability and clears any remaining scheduled IK targets.

If the character exits a trigger while Interact is active, the current interaction is allowed to finish. The trigger candidate and Interactable reference are cleared when the ability stops so the character must detect the object again before another use.

## Verify in Play Mode

1. Enter the trigger or aim the configured cast at the object. Confirm Interact's inherited **Detected Object** field shows the expected collider.
2. Confirm the ability message appears and any `{0}` placeholder displays the state supplied by the target.
3. Press `Action` from outside the Move Towards Location. Confirm Move Towards activates first and aligns the character before Interact becomes active.
4. Confirm **(Active)** appears beside Interact and **Ability Int Data Value** reaches AbilityIntData when the animation begins.
5. At `OnAnimatorInteract` or the configured duration, confirm every target responds once. In the example, the platform starts and the button trigger fires together.
6. At `OnAnimatorInteractComplete` or its duration, confirm Interact stops and normal character control resumes.
7. Leave the trigger after Interact starts and confirm the action completes, then verify the object is no longer detected outside the volume.
8. Test all state-dependent cases: a target that returns false from `CanInteract`, a toggled Animated Interactable, any allowed Aim or Height Change, and **Single Interact** when used.

## Troubleshoot Interact

| Symptom | Check | Fix |
| --- | --- | --- |
| **Detected Object** stays empty. | Check the collider layer, **Object Detection**, inherited **Object ID**, and whether an Interactable exists on the collider or a parent. | Correct the detection volume and layer, or add the expected component and identifier. |
| The object is detected but Interact will not start. | Check **Interactable ID**, every **Targets** entry, and each target's `CanInteract` state. | Match the IDs, remove null or incompatible targets, and make every required target available. |
| Only one part of a combined interaction responds. | The missing component may not be in **Targets**, or its own setup may be disabled. | Assign every target component; for the platform example, enable **Enable On Interact** and configure the button's Animator parameter. |
| Move Towards never aligns the character. | Its ability may be below Interact, or Move Towards Location may be on a child instead of the Interactable GameObject. | Move the ability above Interact and put the location component on the same GameObject as Interactable. |
| The object responds too early or too late. | Check **Interact Event** mode, duration, and the position of `OnAnimatorInteract`. | Adjust the timer or move the exact event to the contact frame. |
| Interact remains active after the animation. | **Interact Complete Event** may be waiting for a missing event. | Add `OnAnimatorInteractComplete` to every reachable clip or disable event mode and set a duration. |
| A hand does not reach the interaction point. | Check for Character IK and the Ability IK Target's **Goal**, hierarchy, delay, and duration. | Add the target below Interactable and give it enough interpolation and hold time. |
| Aim or crouch stops unexpectedly. | **Allow Aim** or **Allow Active Height Change** is disabled. | Enable the relevant option only when that pose is compatible with the interaction animation. |
| The prompt does not change between states. | Check `{0}` in **Ability Message Text** and ensure a target implements `IInteractableMessage`. | Add the placeholder and configure Animated Interactable's bool messages, or implement the message interface. |
| The Console reports an invalid target element. | A **Targets** entry is null or references a MonoBehaviour that does not implement `IInteractableTarget`. | Assign the actual target component rather than an unrelated component or empty slot. |

## Related tasks

- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) explains inherited trigger, cast, layer, angle, and Object ID settings.
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) controls the approach and must remain above Interact.
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) defines the accepted character position and facing.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains event-versus-duration timing.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains Ability Index and AbilityIntData.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) covers the actions that Interact blocks while active.
- [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) supplies the built-in target used by the button example.
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) explains custom ability authoring and priority behavior.

## Developer reference

`IInteractableTarget` receives both the character and the active Interact ability:

```csharp
bool CanInteract(GameObject character, Interact interactAbility);
void Interact(GameObject character, Interact interactAbility);
```

`CanInteract` should return false while the target cannot accept the complete action. `Interact` performs the response after **Interact Event**. Interactable requires every target to pass before starting and invokes all targets when the event occurs.

Implement `IInteractableMessage` when a target supplies state-dependent prompt text:

```csharp
string AbilityMessage();
```

Interact exposes `InteractableID`, `AllowActiveHeightChange`, `AllowAim`, `Concurrent`, `AbilityIntDataValue`, `InteractEvent`, `InteractCompleteEvent`, and the current `Interactable`. The runtime registers `OnAnimatorInteract` and `OnAnimatorInteractComplete`, returns **Ability Int Data Value** through `AbilityIntData`, and returns **Concurrent** through `IsConcurrent`.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-look-at"></a>

# Look At

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/look-at/)

Look At turns the character's inverse kinematics toward nearby points of interest. Use it for details such as signs, speakers, or scene objects that should attract the character's attention without rotating the camera.

Look At changes character IK only. Use [Assist Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/) when the camera or character rotation should follow an aim target.

## Before you begin

- The character needs **Ultimate Character Locomotion** and a working [Character IK](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) component. Unity's built-in IK requires a humanoid Animator.
- Each point of interest needs a trigger collider on a layer included by Look At's **Detect Layers**.
- Decide whether every trigger on those layers is valid or whether an [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) should filter a smaller group.

## Add Look At to the character

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities** and use the plus button to add **Look At**.
3. Keep **Start Type** set to **Automatic** and **Object Detection** set to **Trigger**. Look At selects its target from the tracked trigger objects, so the cast detection modes are not suitable for this ability.
4. Set **Detect Layers** to include the point-of-interest triggers.
5. Leave **Object ID** at `-1` when every eligible trigger is a point of interest. To filter them, enter an ID and add a matching Object Identifier to each trigger object or one of its parents.
6. Set **Max Trigger Object Count** high enough for the greatest number of eligible triggers that can overlap the character at once.
7. Set **Field Of View** to the complete viewing cone. The default `160` accepts targets up to 80 degrees to either side of the character's forward direction.

## Create a point of interest

1. Add a Collider to the scene object and enable **Is Trigger**.
2. Put that trigger GameObject on a layer included by the character's **Detect Layers**.
3. Size the trigger to define when the object begins competing for the character's attention.
4. Position the trigger GameObject's Transform at the desired look point. If the trigger volume must be centered elsewhere, add **Pivot Offset** to that same GameObject and set **Offset** to the local look point.
5. Add Object Identifier only when the Look At ability uses an **Object ID** other than `-1`. The identifier may be on the trigger or a parent, but Pivot Offset must be on the exact trigger GameObject.

Repeat this setup for each point of interest. Overlapping triggers are supported; Look At chooses among them at runtime.

## Choose the target behavior

- **Trigger size** decides when a point of interest is available. Use a compact trigger for a detail the character should notice only nearby, or a wider trigger for an important landmark.
- **Field Of View** decides whether an available point remains far enough in front of the character. The value is the full cone, split evenly around character forward.
- **Distance** breaks competition between valid points. Look At selects the closest qualifying trigger Transform, regardless of which trigger was entered first.
- **Pivot Offset** moves the IK target without moving the trigger. It is useful when the Collider surrounds a large object but the character should look at a face, sign, or control panel.
- **Object ID** is optional. Use it only when the selected layers also contain triggers that Look At should ignore.

The inherited **Angle Threshold** does not filter trigger detection. Use **Field Of View** for Look At's directional limit.

The current Version 3 Inspector also shows **Origin**, but Look At's runtime selection and IK update do not read that value. Leave it unassigned and control the result with the trigger Transform or Pivot Offset.

## How it runs

Look At starts automatically when Character IK is available and at least one matching trigger has been detected. It is concurrent, so it can update the gaze without replacing ordinary locomotion.

Each update checks all tracked, active trigger GameObjects. It rejects any target outside half of **Field Of View** on either side, then selects the nearest remaining target based on its Transform position. The IK target is that position plus the target's local Pivot Offset, when one exists.

When no tracked target is inside the viewing cone, Look At sends Character IK its default look position. Because its default **Stop Type** is **Manual**, leaving the last trigger does not by itself stop an already active Look At ability; the visible gaze returns to the Character IK default instead.

Interact temporarily stops and prevents Look At. The Aim, Use, and Reload item abilities do the same, so an interaction or item action owns the character's attention while it runs. With a valid trigger still present, Look At can start automatically again after the preventing ability stops.

## Verify in Play Mode

1. Enter one point-of-interest trigger and select Look At under **Ultimate Character Locomotion**. Confirm **Detected Object** shows an eligible trigger and **(Active)** appears beside the ability.
2. Face the target and confirm the character's head and configured upper-body IK turn toward its Transform or Pivot Offset. The camera should not rotate.
3. Turn until the target passes half of **Field Of View** to one side. Confirm the gaze blends back to the Character IK default.
4. Overlap two valid triggers and move between them. Confirm the character looks at the closer trigger Transform.
5. Leave every trigger. Confirm the character returns to the default look direction even if Look At remains active.
6. Start Interact, Aim, Use, and Reload in their applicable scenarios. Confirm Look At yields while each action is active and can resume when the action ends.

## Troubleshoot Look At

| Symptom | Check | Fix |
| --- | --- | --- |
| Look At never becomes active. | Check for an active Character IK component, **Object Detection** set to **Trigger**, the trigger layer, **Is Trigger**, and the optional **Object ID**. | Restore Character IK, correct the trigger and layer, or leave **Object ID** at `-1` when filtering is unnecessary. |
| The Console reports too many trigger objects. | More eligible triggers overlap the character than **Max Trigger Object Count** allows. | Increase the count or reduce overlapping trigger volumes. |
| The object is detected but the character does not look toward it. | The target may be outside **Field Of View**, or Character IK look weights may be zero or clamped. | Turn toward the target, increase the cone if appropriate, and verify the Character IK look settings. |
| The character looks at the object's base or center. | Look At uses the detected trigger Transform as its target. | Move that Transform or add Pivot Offset to the exact trigger GameObject and adjust **Offset**. |
| The wrong object wins when triggers overlap. | Look At always chooses the nearest qualifying trigger Transform. | Reposition the trigger Transforms or narrow the trigger volumes to create the intended priority. |
| **Angle Threshold** has no effect. | Trigger detection intentionally skips the inherited cast-angle test. | Set the direction limit with **Field Of View**. |
| Changing **Origin** has no effect. | The current Version 3 runtime does not use this serialized field after initialization. | Leave it unassigned and position the target with its Transform or Pivot Offset. |
| The head turns but the camera does not. | This ability controls Character IK only. | Configure [Assist Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/) when the camera or character rotation should follow the target. |
| Look At stops during an interaction or item action. | Interact, Aim, Use, and Reload intentionally prevent it. | Allow the action to finish; Look At can restart automatically while a valid trigger remains. |

## Related tasks

- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) explains inherited trigger, layer, Object ID, and diagnostic settings.
- [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) controls how strongly the body, head, eyes, and arms follow the look target.
- [Assist Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/) rotates toward an aim target rather than supplying an IK-only point of interest.
- [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) explains the optional numeric filter used by **Object ID**.
- [Included Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/) explains ability selection, input, concurrency, and ordering.

## Developer reference

`LookAt` derives from `DetectObjectAbilityBase`, uses trigger detection by default, and returns `true` from `IsConcurrent`. Its **Field Of View** and **Origin** values are protected serialized fields rather than public properties.

At runtime, `LookAt.Update` iterates the tracked trigger GameObjects, compares each position to the character Transform's forward direction, and calls `CharacterIKBase.SetLookAtPosition`. A `PivotOffset` on the selected trigger supplies the local-space offset. The current implementation assigns a fallback head or character Transform to **Origin** during initialization but does not use that Transform in its selection or IK calculation.

Look At listens for character and item ability lifecycle events. Interact, Aim, Use, and Reload are added to its internal preventative set while active; Look At stops immediately when one of them begins and cannot restart until that preventer ends.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-pickup"></a>

# Pickup

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/)

Pickup lets the character play a deliberate reach or collect animation before adding a detected pickup to its inventory. Use it when pressing an input should collect an item from the ground or a surface instead of collecting it immediately on contact.

## Before you begin

- The character needs **Ultimate Character Locomotion** and an enabled [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/). An animated equippable-item workflow also needs an Item Set Manager and the appropriate Equip Unequip item abilities.
- The pickup needs an Item Pickup component and a trigger collider on a layer included by the character's **Detect Layers**.
- The character Animator needs the Pickup state for **Ability Index** `11`, or a project-specific replacement, when an animation should play.
- Decide whether the action is timed by animation events or fixed durations. Custom clips need `OnAnimatorPickup` and `OnAnimatorPickupComplete` when their corresponding event modes are enabled.

## Add Pickup to the character

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities** and use the plus button to add **Pickup**.
3. Keep the default **Start Type** set to **Button Down**, **Input Names** set to `Action`, and **Ability Index** set to `11` when using the included pickup animation.
4. Keep **Object Detection** set to **Trigger** for a proximity pickup and set **Detect Layers** to include the pickup's trigger layer.
5. Set **Allowed Pickups** to **Item** for the standard inventory-item workflow.
6. Leave **Slot ID** at `-1` when the inventory may choose the slot. Enter a specific slot ID only when every item handled by this ability belongs in that slot.
7. Leave **Pickup Item Definitions** empty when every detected Item Definition should use the animation. Add definitions when only selected items should animate; other detected items are collected immediately rather than rejected.
8. Set **Max Trigger Object Count** high enough for the greatest number of Item Pickup triggers that can overlap the character at once.
9. Configure **Pickup Event** and **Pickup Complete Event** as described below.
10. Place Pickup high enough in the ability list to start over lower-priority actions, while keeping critical interrupts such as death or ragdoll above it.

## Create an animated item pickup

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name**, set **Object Type** to **Item Pickup**, and assign the item's visible model to **GameObject**. Use the model rather than an already created Character Item.
3. Select **Build Object** and save the prefab.
4. On the created Item Pickup component, disable **Pickup On Trigger Enter**. Leaving it enabled collects the item on contact and bypasses the Pickup ability.
5. In the Item Definition and Amount list, add each Item Definition the object supplies and enter its quantity.
6. Enable **Equip** when the picked-up item should become active. Set **Item Set Group** and, when needed, **Item Set Name** to select the intended item set.
7. Confirm the pickup has a trigger Collider on a layer included by the character's **Detect Layers**. Size it to the area in which the prompt and input should be available.
8. Optionally set **Pickup Message Text**, **Pickup Message Icon**, **Pickup Audio Clip Set**, rotation, destruction delay, and Respawner behavior on the pickup prefab.
9. Place the prefab in the scene and position its model for the character's pickup animation.

See [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) for the world-object fields and inventory-item setup.

## Choose the pickup behavior

### Animated input or immediate contact

- Disable **Pickup On Trigger Enter** and use Pickup's `Action` input for a deliberate animated collection.
- Enable **Pickup On Trigger Enter** when walking through the trigger should collect the item immediately. This path does not start the character's Pickup ability.
- Set **Ability Index** to `-1` when the ability should perform its pickup immediately without entering an Animator state.
- **Always Pickup** controls whether a direct Item Pickup is consumed when the inventory cannot accept its contents. The animated path reserves the world pickup before its delayed inventory event, so test limited-capacity inventories explicitly.

### Which objects may start the ability

**Allowed Pickups** contains three flags:

- **Item** accepts a non-depleted Item Pickup whose **Pickup On Trigger Enter** option is disabled.
- **Health** accepts a Health Pickup.
- **Other** accepts a component that implements `IObjectPickup`; it does not make an arbitrary GameObject collectible.

Use a separate Pickup ability entry for each type when the objects need different detection, inputs, animations, or timing. In the current Version 3 runtime, the **Item** path takes precedence whenever that flag is included, so combining **Item** with **Health** or **Other** does not create a general-purpose mixed pickup action.

A standard Health Pickup performs its own pickup when the character enters its trigger. Use cast detection or a custom `IObjectPickup` when a health or other pickup must wait for the character animation instead of responding on contact.

### Item filtering and overlapping pickups

An empty **Pickup Item Definitions** list gives every eligible item the animated path. A nonempty list is an animation filter: a pickup containing a listed definition may use the animation, while an unlisted pickup falls back to immediate inventory collection.

To include the selected object's text in the prompt, put `{0}` in Pickup's inherited **Ability Message Text**. The first tracked Item Pickup's **Pickup Message Text** replaces that placeholder and can also be shown by the Message Monitor after collection.

When several Item Pickup triggers overlap, Pickup processes the first available entry in its tracked queue rather than choosing the nearest model. Keep interaction volumes distinct when the player needs predictable selection.

The animated item path is designed around items that an Equip Unequip ability can equip. A pickup that adds only a consumable definition may be added immediately without playing the reach animation. Test equippable items and consumable-only pickups as separate cases.

### Animation timing

**Pickup Event** controls when the item definitions are added:

- Enable **Wait For Animation Event** and send `OnAnimatorPickup` at the hand-contact frame.
- Disable it and set **Duration** for fixed timing. A newly added ability defaults to event mode.

**Pickup Complete Event** controls when the ability stops after collection:

- Enable **Wait For Animation Event** and send `OnAnimatorPickupComplete` near the end of the clip.
- Disable it and set **Duration** for a timed finish. Its default is duration mode at `0.4` seconds.

These are independent triggers. The first changes the inventory; the second releases the ability. See [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) for the exact Unity event setup.

## How it runs

When the character enters a valid Item Pickup trigger, Pickup records that object and exposes it through the inherited detection workflow. Pressing `Action` starts the ability, takes the first tracked available pickup, prepares the character's Equip Unequip abilities, and reserves that world pickup for the sequence.

At **Pickup Event**, the Item Pickup adds its configured Item Definitions and amounts to the Inventory, using **Slot ID** when one was specified. The item may then be equipped according to the Item Pickup and item-set configuration. At **Pickup Complete Event**, Pickup stops and ordinary ability control resumes.

The world pickup is marked as picked up when the animated sequence is prepared, before the delayed inventory event. Its destruction delay or Respawner then controls its visible lifecycle. Verify inventory-capacity rules before using this flow for a limited inventory so a reserved pickup cannot disappear before the inventory accepts its contents.

Pickup can receive another start while already active, allowing queued overlapping item pickups to be processed, but separate trigger volumes produce a clearer player choice.

## Verify in Play Mode

1. Enter the Item Pickup trigger. In the Pickup Inspector, confirm **Detected Object** shows the pickup and the expected ability message appears.
2. Press `Action` and confirm **(Active)** appears beside Pickup and the Animator receives AbilityIndex `11`.
3. Before `OnAnimatorPickup` or the configured **Pickup Event** duration, confirm the item amount has not yet been added.
4. At the pickup event, confirm the Inventory amount increases by the Item Pickup's configured amount and the intended item equips when **Equip** and its item-set settings allow it.
5. At `OnAnimatorPickupComplete` or the configured **Pickup Complete Event** duration, confirm Pickup stops and normal control resumes.
6. Test an unlisted Item Definition when **Pickup Item Definitions** is populated. Confirm it is collected immediately without the animation.
7. Test two nearby triggers separately, then overlap them deliberately and confirm the first tracked pickup is selected.
8. If a Respawner is configured, wait for its interval and confirm the pickup returns with its trigger active again.

## Troubleshoot Pickup

| Symptom | Check | Fix |
| --- | --- | --- |
| The item disappears as soon as the character touches it. | **Pickup On Trigger Enter** is enabled on the Item Pickup. | Disable it when collection should wait for the Pickup ability and input. |
| **Detected Object** remains empty. | Check **Object Detection**, **Detect Layers**, the trigger Collider, **Allowed Pickups**, inherited **Object ID**, and whether the Item Pickup is already depleted. | Use Trigger detection, include the trigger layer, correct the optional ID, and reinitialize or respawn the pickup. |
| The prompt appears but `Action` does not start Pickup. | Check **Input Names**, ability priority, the Inventory and Item Set Manager, Equip Unequip abilities, and whether another nonconcurrent ability has higher priority. | Restore the required character components, correct input, or move Pickup above the actions it should interrupt. |
| One item is collected without its animation. | Its definition may not be in **Pickup Item Definitions**, it may not be equippable through an Equip Unequip ability, or **Ability Index** may be `-1`. | Add the definition to the animation filter, complete its item-set setup, and use the intended Animator index. |
| Pickup starts but the inventory never changes. | **Pickup Event** may be waiting for a missing `OnAnimatorPickup` event. | Add the exact event to every active pickup clip or disable event mode and set a duration. |
| The inventory changes but Pickup never stops. | **Pickup Complete Event** may be waiting for a missing `OnAnimatorPickupComplete` event. | Add the exact completion event or use duration mode. |
| The item is added but does not equip. | Check **Equip**, **Item Set Group**, **Item Set Name**, the character's item sets, and whether Use or Reload is active. | Correct the item-set selection and retry when the conflicting item ability is inactive. |
| The wrong pickup is selected in an overlap. | Pickup uses its first tracked available item, not distance from the character. | Separate or resize the trigger volumes so only one candidate is available at a time. |
| The Console warns that the maximum trigger-object count is too small. | More Item Pickups overlap than **Max Trigger Object Count** can track. | Increase the count or reduce overlapping pickup volumes. |
| A Health Pickup is collected before the Pickup animation. | The built-in Health Pickup responds directly to trigger entry. | Use an appropriate cast or a custom externally controlled `IObjectPickup` for animation-gated health collection. |

## Related tasks

- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) configures the world object, Item Definitions, quantities, equipping, and pickup presentation.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) explains the character-side storage and loadout.
- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) explains inherited trigger, layer, Object ID, message, and diagnostic fields.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) controls which item set becomes active during the animated item path.
- [Item Equip Verifier](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/item-equip-verifier/) coordinates equipped items when another character ability starts.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains event-versus-duration timing.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains AbilityIndex and the character Animator values.
- [Health Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/health-pickup/) covers the built-in health object used by the **Health** option.

## Developer reference

`Pickup` derives from `DetectObjectAbilityBase`. It exposes `AllowedPickup`, `SlotID`, `PickupItemDefinitions`, `PickupEvent`, and `PickupCompleteEvent`. It returns `true` from `CanReceiveMultipleStarts` and `ImmediateStartItemVerifier`.

The ability registers `OnAnimatorPickup` to perform the inventory or `IObjectPickup` action and `OnAnimatorPickupComplete` to stop. For item pickups it maintains a queue sized from **Max Trigger Object Count**, coordinates each Equip Unequip ability through the item-pickup lifecycle events, and calls `ItemPickupBase.DoItemIdentifierPickup` at the pickup event.

For a non-item path, the detected GameObject must provide `IObjectPickup` and its `DoPickup(GameObject target)` implementation owns the result. A custom Object Pickup should also define how trigger entry differs from an externally requested pickup; the base `Pickup On Trigger Enter` value is not enforced centrally for every derived implementation.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-detect-object-ability-base-ride"></a>

# Ride

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/ride/)

Ride lets one Ultimate Character Controller character mount and control another, such as a humanoid rider on a horse. Use [Rideable](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rideable/) on the mount; Ride does not turn an arbitrary prop or vehicle into a controllable mount.

## Before you begin

- Both the rider and mount need **Ultimate Character Locomotion** and **Ultimate Character Locomotion Handler** components.
- The rider needs animations for approaching, mounting, riding, and dismounting. The mount needs a compatible Animator and movement type, such as a four-legged movement type for a horse.
- The rider needs [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) when it should approach a precise left or right mount point before Ride starts.
- Decide which equipped items may remain active. The default Ride setup allows no equipped slots during the transition and works with Item Equip Verifier to unequip and optionally restore them.

## Set up the rider

1. Select the rider GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities** and add **Move Towards** when the character should approach the mount automatically.
3. Add **Ride** below Move Towards. Keep Ride high enough to control lower-priority actions, while leaving critical interrupts such as death or ragdoll above it.
4. Keep the default **Start Type** set to **Button Down**, **Stop Type** set to **Button Toggle**, **Input Names** set to `Action`, and **Ability Index** set to `12` when using the included Ride Animator states.
5. For a proximity mount, set **Object Detection** to **Trigger** and set **Detect Layers** to include the mount's detection trigger. A newly added Ride otherwise inherits Charactercast from Detect Object Ability Base, which is useful only when its cast and layer settings reliably hit the mount.
6. Leave **Object ID** at `-1` unless one Ride entry must recognize only a particular class of mount. Ride supports duplicate entries, so separate Object IDs and Animator values can route different mount types to different animations.
7. Configure **Mount Event**, **Mount Complete Event**, **Mount Complete State**, and **Dismount Event** as described below.
8. Enable **Reequip Item After Mount** when Item Equip Verifier should restore the rider's previous item after the mount transition.

## Set up the mount

1. Select the mount character and confirm its locomotion, movement type, Animator, and **Ultimate Character Locomotion Handler** work before adding a rider.
2. In **Ultimate Character Locomotion > Abilities**, add **Rideable**. Keep its **Start Type** and **Stop Type** set to **Manual**, its **Ability Index** set to `12`, and place it near the bottom so the mount's locomotion abilities can continue to drive movement.
3. Create a child Transform at the final saddle or seat pose. Match its position and rotation to the rider's root and assign it to Rideable's **Ride Location**.
4. Confirm Rideable has **Left Dismount Collider** and **Right Dismount Collider** assigned. Adding Rideable normally creates `Left Dismount Collider` and `Right Dismount Collider` children; use **Add Dismount Colliders** in the Rideable drawer if they are missing.
5. Position and size those colliders around the spaces the rider's left and right dismount animations need. They are disabled as physical colliders at runtime and used as clearance probes against solid-object layers.
6. Add two [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) components below the mount: one at the left mounting pose and one at the right. Set each **Offset**, **Yaw Offset**, position tolerance, and facing tolerance so the corresponding root-motion clip starts from a stable pose.
7. Add or identify a detection Collider on the mount or one of its children. For Trigger detection, enable **Is Trigger**, place it on a layer in the rider's **Detect Layers**, and size it to the intended mounting area. Ride finds the parent Ultimate Character Locomotion and its Rideable ability.
8. If the rider uses [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/), add Speed Change to the mount too and match the important speed settings. Ride explicitly starts and stops the mount's Speed Change with the rider's; other abilities are not mirrored automatically.

## Choose the mount and dismount timing

### Mount Event

**Mount Event** is the point where the rider finishes the root-motion approach and becomes locked to **Ride Location**.

- Enable **Wait For Animation Event** and send `OnAnimatorRideMount` at the frame where the rider reaches the seat.
- Disable it and use **Duration** only when a fixed delay is reliable for every active mount clip.

A newly added Ride defaults to animation-event mode for this trigger. When the event occurs, Ride changes to its riding state, stops using root-motion position, forwards input to the mount, and asks Rideable to use the rider's colliders for movement collision.

### Mount Complete Event and state

**Mount Complete Event** marks the end of the transition and allows the toggle input to begin a dismount. It defaults to duration mode at `0.2` seconds. Use `OnAnimatorRideMountComplete` instead when the exact end frame varies between clips.

**Mount Complete State** defaults to `RideMounted`. The state activates after mount completion and remains active until dismount starts. Use it for rider properties that apply only while seated, such as IK, item, or presentation changes. Leave the name empty when no mounted state is required.

### Dismount Event

**Dismount Event** releases the rider from the mount and completes both abilities.

- Enable **Wait For Animation Event** and send `OnAnimatorRideDismount` after the root-motion clip has placed the rider safely beside the mount.
- Disable it and use **Duration** only when the clip timing is fixed.

A newly added Ride defaults to animation-event mode for this trigger. Ride has no **Teleport Enter Exit** option: a timer changes when the handoff occurs but does not create a dismount trajectory, so a nonanimated implementation must provide its own safe repositioning before completion.

See [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) for the exact Unity event workflow.

## Choose movement, sides, and items

- Move Towards chooses the closest child Move Towards Location before Ride begins. Ride then determines left or right from the rider's local position relative to the mount, selecting the matching mount animation branch.
- Dismount first tries the same side. If that clearance collider overlaps a solid object or is missing, Ride tries the opposite side. The rider remains mounted only when neither side has an assigned, clear collider.
- During the riding state, the rider's horizontal, forward, and look inputs are forwarded to the mount's locomotion handler. The rider is continuously positioned and rotated at **Ride Location**.
- Adding Rideable disables ordinary gameplay input on the mount. The mount receives the rider's forwarded input while occupied; an unoccupied AI mount needs its own non-player control workflow.
- **Reequip Item After Mount** restores an item that Item Equip Verifier removed for the mounting transition. Before dismount, Ride waits for the required item unequip and stops Aim.
- Speed Change start and stop are synchronized when both characters have that ability. Match their Speed Change multipliers and animation expectations; the values themselves are not copied at runtime.

## How it runs

Ride accepts only a detected object whose parent hierarchy contains Ultimate Character Locomotion with an available Rideable ability. A Rideable can accept its current rider or one new rider, preventing a second character from mounting while it is occupied.

After Move Towards reaches the chosen left or right location, Ride starts on the rider and Rideable starts manually on the mount. The mount updates before the rider, collision relationships are adjusted, and the rider treats the mount as its moving platform while the mount animation begins.

At **Mount Event**, Ride enters the riding phase and keeps the rider at **Ride Location**. The mount receives the rider's movement and look input. At **Mount Complete Event**, dismount input becomes available and **Mount Complete State** activates.

Pressing the toggle input checks dismount clearance, tries the other side when necessary, and waits for item unequip when required. The rider returns to root-motion positioning for the dismount clip. At **Dismount Event**, both abilities stop, collider ownership and input overrides are restored, the moving-platform relationship is cleared, and normal rider control resumes.

## Verify in Play Mode

1. Approach the mount from the left. Confirm Ride's inherited **Detected Object** shows a mount collider and the ability message is available.
2. Press `Action` outside the left Move Towards Location. Confirm Move Towards aligns the rider before Ride and Rideable become active.
3. Confirm both Animators use **Ability Index** `12` and the left mount branch. At `OnAnimatorRideMount`, verify the rider settles at **Ride Location** without sliding or clipping.
4. Move and look after mounting. Confirm the mount responds to the rider's input while the rider remains aligned to the saddle.
5. Confirm the toggle input cannot dismount until **Mount Complete Event** has occurred and `RideMounted` is active when configured.
6. Press `Action` with the original side clear. Confirm any required item unequips, the matching dismount animation plays, and `OnAnimatorRideDismount` restores independent control.
7. Mount again, block the original dismount collider, and confirm Ride uses the opposite side. Block both sides and confirm the rider remains mounted.
8. Repeat from the right, with Speed Change active, and with **Reequip Item After Mount** both enabled and disabled.

## Troubleshoot Ride

| Symptom | Check | Fix |
| --- | --- | --- |
| Ride never detects the mount. | Check **Object Detection**, **Detect Layers**, the collider, optional **Object ID**, and whether the collider's parent has Ultimate Character Locomotion with Rideable. | Correct the detector and hierarchy, or use a trigger volume on an included layer for proximity mounting. |
| The mount is detected but Ride will not start. | Rideable may already have another rider, Move Towards may be waiting, or a higher-priority ability may block Ride. | Free the mount, verify the approach locations, and correct ability ordering or active state. |
| The Console reports that a locomotion handler is required. | Ride or Rideable cannot find **Ultimate Character Locomotion Handler** on its character. | Add and configure the handler on both rider and mount. |
| The rider approaches the wrong side or starts misaligned. | Check the two Move Towards Locations, their offsets and facing, and which one is closest. | Move the locations farther apart and match each pose to its left or right root-motion clip. |
| The rider never reaches the seat. | **Mount Event** may be waiting for a missing `OnAnimatorRideMount`, or the clip does not supply the expected root motion. | Add the exact event at the seat-contact frame and verify root motion and **Ability Index** `12`. |
| The rider is seated but cannot dismount. | **Mount Complete Event** may not have completed, an item may still be equipping, or both dismount colliders may be blocked or missing. | Add `OnAnimatorRideMountComplete` or use a duration, finish the item transition, and restore clear collider probes on both sides. |
| Dismount animation plays but Ride remains active. | **Dismount Event** is waiting for a missing `OnAnimatorRideDismount`. | Add the exact event near the end of every dismount clip or use duration mode. |
| The rider drops at the saddle after a timer-only dismount. | A duration completes the ability but does not move the rider away from the seat. | Use a root-motion dismount clip or custom repositioning before the event completes. |
| The mount does not respond to rider input. | Check that Rideable is active, the mount has Ultimate Character Locomotion Handler, and no other script owns its input. | Restore the Rideable setup and give the forwarded override exclusive control while mounted. |
| The rider and mount use different run speeds or animations. | Speed Change may be missing on one character or its settings may differ. | Add Speed Change to both and match its multiplier and relevant Animator setup. |
| An item does not return after mounting. | Check Item Equip Verifier, allowed equipped slots, and **Reequip Item After Mount**. | Complete the item-verifier setup and enable the option when that item is valid while riding. |

## Related tasks

- [Rideable](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rideable/) is the mount-side ability and owns Ride Location and dismount-clearance colliders.
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) approaches the mounting pose and must remain above Ride.
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) defines the rider's left and right starting positions.
- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) explains inherited trigger, cast, layer, Object ID, and message settings.
- [Item Equip Verifier](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/item-equip-verifier/) coordinates item unequip and restoration around mounting.
- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) is the locomotion ability Ride explicitly mirrors to the mount.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains event-versus-duration timing.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains AbilityIndex and AbilityIntData.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains the default `RideMounted` state.
- [Drive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/) handles a vehicle through a Drive Source instead of another Ultimate Character Controller character.

## Developer reference

`Ride` exposes `MountEvent`, `MountCompleteEvent`, `MountCompleteState`, `DismountEvent`, `ReequipItemAfterMount`, the active `Rideable`, and references to the rider locomotion and GameObject. The type allows duplicate entries and implements `IItemToggledReceiver` so dismount can continue after Item Equip Verifier finishes.

Ride and Rideable both use **Ability Index** `12`. Ride's AbilityIntData is `1` for left mount, `2` for right mount, `3` while riding, `4` for left dismount, `5` for right dismount, and `6` after dismount. Rideable mirrors that value so both Animators can remain synchronized.

Ride registers `OnAnimatorRideMount`, `OnAnimatorRideMountComplete`, and `OnAnimatorRideDismount`. During the riding phase it forwards the rider's raw horizontal and forward input plus look vector through `UltimateCharacterLocomotionHandler`, while its position and rotation methods keep the rider aligned to `Rideable.RideLocation`.

Rideable's clearance check supports Capsule Collider, Box Collider, or Sphere Collider and queries the mount's solid-object layers while ignoring triggers. `CanMount` accepts only the current Ride instance or an unoccupied mount. Custom mount behavior can derive from Rideable and override `Mount` or `Dismounted` while preserving the base lifecycle and input cleanup.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-die"></a>

# Die

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/)

Die plays an animation-based death response when the character's Health reaches zero. Use it when the character should choose a directional death animation, remain dead for the respawn delay, and then return through the Character Respawner.

## Before you begin

- The character needs **Character Attribute Manager**, **Character Health**, and **Character Respawner**. In **Tools > Opsive > Ultimate Character Controller > Character Manager**, choose the existing character, enable **Health**, and select **Update Character** to add this set.
- In **Character Attribute Manager**, confirm that the attribute selected by **Character Health > Health Attribute** exists. The standard setup uses `Health`.
- The Animator must contain the UCC death states. The included Animator Controller expects Die's **Ability Index Parameter** to be `4`.
- Decide whether this character uses Die or [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/) as its primary death response. Do not leave both enabled without intentionally designing their ability priority and transition behavior.

## Set up an animated death

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities**, select the plus button, and add **Die**.
3. Drag Die near the top of the list, above ordinary movement, interaction, and item abilities. A higher-priority non-concurrent death ability can prevent it from starting.
4. Keep **Enabled** selected, **Start Type** set to **Manual**, **State** set to `Death`, and **Ability Index Parameter** set to `4` when using the included Animator Controller. Health starts Die through the death event; it is not a player-input ability.
5. Keep **Disable Colliders** enabled for the standard animation-based death, or disable it only when the main character colliders must continue participating in the scene while dead.
6. Set **Camera Rotational Force** for the desired camera reaction. The configured vector is multiplied by the magnitude of the killing force.

Adding Health in the Character Manager does not add Die to the ability list. Complete both parts of the setup.

## Connect Health and respawning

1. In **Character Health**, select the correct **Health Attribute**. Assign a **Shield Attribute** only when damage should consume a separate shield before health.
2. Leave **Deactivate On Death** disabled when **Character Respawner** should return this character. Character Respawner cannot respawn an inactive character GameObject, and character deactivation cancels its scheduled respawn.
3. In **Character Respawner**, enable **Schedule Respawn On Death**.
4. Choose **Positioning Mode**:
   - **None** keeps the character at the death position.
   - **Start Location** returns it to the position and rotation recorded when the scene started.
   - **Spawn Point** asks the Spawn Point system for a placement. Use **Grouping** to restrict which spawn points are eligible; `-1` ignores grouping.
5. Set **Min Respawn Time** and **Max Respawn Time**. The actual delay is selected between those values for each death.
6. Enable **Check For Obstruction** when a character should wait instead of appearing inside another solid object. An obstructed placement is retried after another respawn delay.
7. Use **Time Invincible After Spawn** on Character Health when the character needs a short grace period before it can take damage again.

## Choose the death presentation

### Directional animations

The built-in Die ability compares the killing position with the character. A position in front selects **Ability Int Data** `0` (`Forward`); a position behind selects `1` (`Backward`). The Animator uses that value to choose the matching branch inside **Full Body Layer > Die**.

The names describe the built-in animation branches. Test both directions with the character's actual clips rather than assuming a particular fall direction from the attacker's location.

### Animation or ragdoll

Use Die for an Animator-driven death. Use [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/) with **Start On Death** when the body should be controlled by physics instead. Ragdoll has its own collider, force, layer, and respawn cleanup, so disable the unused death ability unless a custom setup deliberately coordinates both.

### Colliders and camera force

With **Disable Colliders** enabled, Die disables the main colliders registered with Ultimate Character Locomotion and remembers which ones were active. It restores only those colliders when the character respawns. This prevents the animated body from continuing to behave like a live locomotion capsule.

**Camera Rotational Force** is scaled by the killing force magnitude and sent to the camera through the death response. Reduce the vector when strong impacts rotate the camera too far. A death with zero force produces no scaled rotation.

## How it runs

Character Health consumes shield first when one is assigned, then reduces health. When neither attribute has value remaining, it sends the death position, force, and attacker through the `OnDeath` event.

Ultimate Character Locomotion marks the character as not alive, stops abilities that cannot remain active through death, and clears movement input. Die receives the same event, stores the force and position, selects the directional **Ability Int Data**, activates the `Death` state, resets locomotion position and rotation, sends the camera force, and optionally disables the main colliders. Die remains active until respawn.

Character Respawner schedules the return when **Schedule Respawn On Death** is enabled. At the chosen time it selects the configured position, sends `OnWillRespawn`, moves the character when required, and sends `OnRespawn`. Health resets the health and shield attributes and restores the living layer. Die then stops and restores the colliders that it disabled.

## Verify in Play Mode

1. Keep **Ultimate Character Locomotion**, **Character Health**, and **Character Respawner** visible in the Inspector.
2. Apply lethal damage from in front of the character. Confirm the Health value reaches zero, Die shows **(Active)**, the character stops accepting movement, and the Animator reports **Ability Index** `4` with **Ability Int Data** `0`.
3. Repeat from behind and confirm **Ability Int Data** changes to `1` and the other death branch plays.
4. While dead, confirm the main locomotion colliders match **Disable Colliders** and that the camera reaction is proportional to the killing force.
5. Wait through the configured respawn range. Confirm the character appears at the expected position, Health and Shield reset, Die is no longer active, the original colliders are restored, and movement works again.
6. Kill the character a second time to confirm the complete cycle is repeatable. If **Check For Obstruction** is enabled, block the spawn area and confirm respawn waits until a valid placement is available.

## Troubleshoot Die

| Symptom | Check | Fix |
| --- | --- | --- |
| Health reaches zero but Die does not start. | Check that Die is present and enabled, and whether a higher-priority Ragdoll, Revive, or other non-concurrent ability responded to the same death. | Enable the intended death ability, move it above ordinary abilities, and disable competing death responses unless their coordination is intentional. |
| The character dies but no death animation plays. | Check **State: Death**, **Ability Index Parameter: 4**, the Animator Controller, and its Die transitions for **Ability Int Data** `0` and `1`. | Restore the included values and Animator branches, or update both the ability and custom Animator to use the same parameters. |
| The wrong directional animation plays. | Watch **Ability Int Data** while applying the lethal hit and check the position supplied by the damage source. | Correct the damage hit position or swap the custom Animator branches if the clips are assigned opposite to the intended result. |
| The character never respawns. | Check **Schedule Respawn On Death**, whether **Deactivate On Death** disabled the GameObject, and whether **Spawn Point** can find a placement for the selected **Grouping**. | Enable death scheduling, keep Character Health from deactivating the character, and provide an eligible unblocked spawn point. |
| The character respawns at the wrong location. | Check **Positioning Mode** and **Grouping**. | Use **None**, **Start Location**, or **Spawn Point** for the intended behavior and match the spawn-point grouping. |
| Respawn keeps being delayed. | Check **Check For Obstruction** and the character's solid colliders at the requested position. | Clear the spawn volume, choose another spawn point, or disable the obstruction check only when overlaps are acceptable. |
| The character still collides like a live capsule while dead. | Check **Disable Colliders** on Die and confirm Die, rather than a different death ability, is active. | Enable **Disable Colliders** or configure the active Ragdoll's collider workflow. |
| Colliders or Health do not reset. | Check that the respawn path sends `OnRespawn` instead of only moving or re-enabling the GameObject. | Respawn through Character Respawner or send the complete UCC respawn lifecycle from the custom system. |
| The camera rotates too far on strong hits. | Compare **Camera Rotational Force** with the killing force magnitude. | Reduce the configured vector or reduce the force supplied by the damage source. |

## Related tasks

- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) configures damage, health and shield attributes, death effects, and post-spawn invincibility.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) explains respawn timing and positioning modes.
- [Spawn Points](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/spawn-points/) configures the placements used by **Positioning Mode: Spawn Point**.
- [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/) provides the physics-based alternative to an animated death.
- [Revive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/) provides a different return-from-death workflow when the character should recover in place through an ability.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains ability-list priority and concurrent activation.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains **Ability Index** and **Ability Int Data**.

## Developer reference

Die uses **Ability Index Parameter** `4`. Its **Ability Int Data** is `0` for the built-in Forward branch and `1` for Backward. The public `Force` and `Position` properties contain the values supplied by the death event while the ability is active.

Die listens for `OnDeath`, sends `OnCameraRotationalForce`, and stops on `OnRespawn`. If code starts Die manually, the ability sends `OnDeath` itself so the rest of the character death lifecycle is notified. In normal gameplay, let Character Health remain the authority that decides when the character is dead.

### Add another death animation

Subclass Die and override `GetDeathTypeIndex` to provide another **Ability Int Data** value. Replace the built-in Die entry with the subclass so two abilities do not respond to the same death event.

```csharp
using Opsive.UltimateCharacterController.Character.Abilities;
using UnityEngine;

public class MyDieAbility : Die
{
    protected override int GetDeathTypeIndex(Vector3 position, Vector3 force, GameObject attacker)
    {
        if (force.magnitude > 10f) {
            return 3;
        }

        return base.GetDeathTypeIndex(position, force, attacker);
    }
}
```

In the Animator Controller, add the new state inside **Full Body Layer > Die** and create a branch whose **Ability Int Data** condition equals `3`. Keep the parent Die transition aligned with **Ability Index** `4`.

![Animator Die sub-state with a custom death-animation branch conditioned on Ability Int Data equal to 3](https://opsive.com/wp-content/uploads/2018/03/CustomDie-1024x340.png)

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-fall"></a>

# Fall

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/)

The Fall ability gives an airborne character its falling and landing animation states. It starts automatically after the character is far enough from the ground and no higher-priority non-concurrent ability is active. During a normal jump, **Jump** controls the ascent first and Fall takes over when Jump ends.

Keep Fall directly below [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) in the **Abilities** list. This gives Jump the higher priority and allows a permitted airborne jump to replace an active Fall.

## Add Fall to the character

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **Fall**.
4. Add **Jump** if the character can jump, then drag **Fall** directly below it.
5. Select Fall and keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Automatic**.
6. Configure **Min Fall Height** and the landing options for the required gameplay feel.
7. Enter Play Mode and test both walking from a ledge and landing after Jump.

Fall defaults to **Ability Index Parameter 2** and does not use root-motion position or rotation. Keep those defaults when using the included Animator Controller; change them only when a custom Animator is designed for different values.

## Choose settings by gameplay scenario

### Ignore steps and very short drops

**Min Fall Height** is the downward distance that must be clear before Fall may start. Its default is **0.2**.

- Increase it when small steps, uneven ground, or brief airborne frames should remain in normal locomotion.
- Set it to **0** when every ungrounded frame should be allowed to start Fall.
- Reduce it when the falling animation starts too late on short ledges.

The check casts downward against solid-object layers, so a nearby surface inside this distance prevents Fall from starting.

### Play a hard-landing surface effect

Assign **Land Surface Impact** when a sufficiently fast landing should produce a surface-aware effect. **Min Surface Impact Velocity** is the vertical-velocity threshold; its default is **-4**. The impact plays only when the landing velocity is more negative than this value.

- Keep a more negative threshold when only hard landings should trigger the effect.
- Move the threshold closer to zero when lighter landings should also trigger it.
- Leave **Land Surface Impact** unassigned when Fall should not create a landing effect.

### Wait for a landing animation

**Land Event** controls when Fall ends after the character becomes grounded.

- Keep **Wait For Animation Event** enabled when the landing animation sends **OnAnimatorFallComplete**.
- Use a duration when the landing animation should end after a fixed time instead of an event.
- Disable **Wait For Animation Event** and set **Duration** to **0** when Fall should end immediately on landing.

## How Fall runs

While inactive, Fall checks that the character is not grounded and that the nearest solid surface is farther away than **Min Fall Height**. The higher list priority of Jump keeps Fall from replacing an active jump.

When Fall starts, its Animator state is the airborne state and its float data tracks the character's local vertical velocity. This allows the Animator to respond differently while rising or descending. Fall also prevents Height Change from starting while the character is airborne.

When the character becomes grounded, Fall changes to its landing state, optionally spawns the assigned Surface Impact, and waits for **Land Event**. The animation event or duration marks the landing complete, then Fall stops. An immediate transform change, such as a teleport that snaps the Animator or places the character on the ground, also clears the active Fall state.

## Verify in Play Mode

1. Keep the **Ultimate Character Locomotion** Inspector visible and walk from a ledge taller than **Min Fall Height**. Confirm **(Active)** appears beside Fall.
2. Jump and confirm Jump becomes active first, followed by Fall after Jump ends.
3. Step across a gap or drop shorter than **Min Fall Height** and confirm Fall does not take over.
4. Land slowly without crossing the configured velocity threshold and confirm no Surface Impact plays; then test a faster landing and confirm the effect uses the contacted surface.
5. On landing, confirm the landing animation completes and **(Active)** disappears after **OnAnimatorFallComplete** or the configured duration.

## Troubleshoot Fall

- **Fall never starts:** confirm **Enabled**, **Start Type: Automatic**, that the character becomes ungrounded, and that the downward clearance exceeds **Min Fall Height**. Check whether another higher-priority non-concurrent ability is still active.
- **Fall takes over before Jump finishes:** move Jump directly above Fall and confirm Jump remains active for the intended ascent.
- **Fall triggers on tiny steps:** increase **Min Fall Height** so nearby ground keeps normal locomotion active.
- **The landing animation never ends:** confirm the Animator sends **OnAnimatorFallComplete**. If no event is needed, disable **Wait For Animation Event** and set **Duration** to **0**.
- **The landing effect never appears:** assign **Land Surface Impact**, confirm the landing velocity is more negative than **Min Surface Impact Velocity**, and verify the contacted surface is configured for the Surface System.
- **The wrong airborne or landing animation plays:** confirm **Ability Index Parameter 2** and the Fall transitions in the character's Animator Controller.
- **The character cannot crouch in the air:** Fall intentionally blocks Height Change while active. Use a custom ability rule if the game requires that combination.

## Related topics

- [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) controls the launch and gives way to Fall during the normal airborne sequence.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains list priority, automatic activation, shared settings, and runtime states.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains event-versus-duration completion settings.
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) explains the landing effect assigned to **Land Surface Impact**.

## Developer reference

Fall uses these default Animator values and runtime events:

- **Ability Index:** `2`.
- **Ability Int Data:** `0` while airborne and `1` after becoming grounded.
- **Ability Float Data:** the character's local vertical velocity.
- **OnAnimatorFallComplete:** completes **Land Event** and allows Fall to stop.
- **OnCharacterGrounded:** switches between the airborne and landing states.
- **OnCharacterImmediateTransformChange:** stops Fall after a compatible teleport or Animator snap.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-first-person-lean"></a>

# First Person Lean

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/first-person-lean/)

First Person Lean moves and rolls the first-person camera to either side without rotating or moving the character body. Use it to let the player peek around cover while collision probes reduce the lean before the camera enters a wall.

## Before you begin

- The character needs a first-person perspective and an active first-person camera view type. Lean disables itself when the character changes to third person.
- A player-controlled character should have **Ultimate Character Locomotion Handler** so the ability can receive axis changes while it is active.
- The input source needs a signed `Lean` axis. With Unity's legacy Input Manager setup generated by UCC, `Z` supplies the positive side and `X` supplies the negative side.
- Surfaces that should limit the camera must be included in **Character Layer Manager > Solid Object Layers**. Trigger Colliders are ignored.

## Add Lean to the character

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities**, select the plus button, and add **Lean** from the first-person abilities.
3. Keep **Enabled** selected, **Start Type** set to **Axis**, **Stop Type** set to **Axis**, and **Input Names** set to `Lean`.
4. Confirm the ability's **Colliders** list contains a generated `LeanCollider` for each character model. Adding Lean normally creates these automatically. Use **Add Colliders** in the Lean drawer if they are missing.
5. Select each `LeanCollider` and position its Capsule Collider around the upper-body or head area that should test the available lean space. Match the shape to the character without making it overlap nearby geometry while standing in open space.
6. Set **Distance** and **Tilt** for the desired camera movement, then set **Item Tilt Multiplier** for the first-person item response.
7. Set **Collider Offset Multiplier** to position the probes between the character center and the maximum camera offset. Keep **Max Collision Count** large enough for the number of solid Colliders a probe may overlap at once.

Lean is concurrent, so it can remain active while ordinary locomotion abilities run. Its position in the list does not need to replace the movement ability that is controlling the character.

## Configure the input

Lean expects one axis whose value returns to `0` when neither side is held:

- A positive value selects one side and a negative value selects the other.
- A nonzero value starts Lean. Returning to zero stops it and recenters the camera.
- Changing directly from positive to negative updates the active lean without requiring the ability to stop and start again.

For the Input System, use a signed one-dimensional composite or another binding that produces both negative and positive values under the action named `Lean`. If the visual directions are reversed, swap the positive and negative bindings rather than changing **Distance** to a negative number.

## Choose the camera and collision settings

### Camera movement

- **Distance** is the maximum sideways camera offset. The Version 3 default is `0.7`.
- **Tilt** is the maximum camera roll in degrees. The default is `7`.
- **Item Tilt Multiplier** scales the roll applied to first-person perspective items. `0` keeps the item upright, `1` matches the camera tilt, and the default `2` gives the item a stronger response.

Use a smaller Distance for tight indoor spaces. Reduce Tilt when the roll feels disorienting, even if the sideways view distance is correct.

### Collision probes

Lean supports only Capsule Colliders and Sphere Colliders in **Colliders**. Do not assign Box Colliders or leave null entries in the list. The drawer creates Capsule Colliders and places their GameObjects on the Ignore Raycast layer.

**Collider Offset Multiplier** controls how far sideways each probe moves relative to **Distance**. Its range is `0` to `1`, with a default of `0.75`:

- `0` keeps the probe on the character centerline.
- `1` places it at the full camera lean distance.
- A middle value detects cover before the camera reaches its maximum offset while keeping the probe close to the body.

The probe remains at its maximum configured offset while Lean checks overlaps. When it intersects a solid, non-trigger Collider, the ability measures the penetration and proportionally reduces both Distance and Tilt. **Max Collision Count** sets the capacity of the non-allocating overlap query; increase it when dense geometry can overlap a probe and some blockers are being missed.

## How it runs

When the signed axis becomes nonzero, Lean activates its `LeanCollider` GameObjects, stores the current side, and sends the calculated distance, tilt, and item multiplier through `OnCharacterLean`. The first-person camera shifts its position spring sideways and rolls its rotation spring. Equipped first-person items use the same event and apply the item tilt multiplier.

Every update, Lean checks each active Capsule or Sphere probe against **Solid Object Layers** and ignores triggers. If a probe overlaps a wall, the camera and item response retract in proportion to the detected penetration. Moving away from the wall restores the full configured lean.

When the axis returns to zero or the ability is stopped, Lean sends a zero distance and tilt to recenter the view and deactivates the probe GameObjects. A perspective change disables Lean in third person and enables it again when first person becomes active.

## Verify in Play Mode

1. Stand in open space in first person and hold the positive `Lean` binding. Confirm Lean shows **(Active)**, the camera moves to one side, and the view rolls by **Tilt**.
2. Change directly to the negative binding. Confirm the camera crosses to the other side without first returning to an inactive ability state.
3. Release both bindings. Confirm the camera and equipped first-person item return to their normal position and Lean is no longer active.
4. Stand beside a solid wall and lean toward it. Confirm the lean distance and roll reduce before the camera enters the wall. Lean away from the wall and confirm the full offset remains available.
5. Repeat beside a trigger volume and confirm the trigger does not restrict the lean.
6. Test with every switchable character model and equipped first-person item. Confirm each active model has a correctly placed probe and that **Item Tilt Multiplier** gives a consistent result.
7. If the character supports both perspectives, switch to third person and confirm Lean disables, then switch back and confirm the bindings work again.

## Troubleshoot First Person Lean

| Symptom | Check | Fix |
| --- | --- | --- |
| Lean never starts. | Check that the character is in first person, Lean is enabled, **Start Type** and **Stop Type** are **Axis**, and the `Lean` action produces nonzero signed values. | Restore the first-person view and axis settings, then correct the input binding or Input System action. |
| Lean becomes disabled when Play Mode starts. | Check whether **Colliders** is null or the generated `LeanCollider` objects were removed. | Select Lean and use **Add Colliders**, then keep valid probes assigned. |
| The Console reports that only Capsule and Sphere Colliders are supported. | Inspect every entry in **Colliders** for an unsupported type or a missing reference. | Replace each invalid entry with a Capsule Collider or Sphere Collider and remove null entries. |
| Both bindings lean in the same direction or the sides are reversed. | Watch the `Lean` axis values for the two controls. | Use a signed one-dimensional binding and swap its positive and negative controls when necessary. |
| The camera clips through cover. | Check the probe's height, radius, local position, **Collider Offset Multiplier**, the wall's layer, and **Max Collision Count**. | Resize and reposition the probe, include the wall in **Solid Object Layers**, or raise the collision capacity. |
| Lean is restricted while standing in open space. | Check whether a probe already overlaps the character, scenery, or another solid Collider at its maximum offset. | Move or resize the probe and correct the involved collision layers. |
| Trigger volumes prevent leaning. | Confirm the blocking object is actually a trigger and that another non-trigger Collider is not overlapping the probe. | Make the intended volume a trigger or remove the separate solid blocker; Lean itself ignores triggers. |
| The camera leans correctly but the item rolls too far. | Compare **Item Tilt Multiplier** with **Tilt**. | Reduce the multiplier; use `1` to match the camera or `0` to keep the item upright. |
| One character model clips while another works. | Check that each model has its own assigned `LeanCollider` and that the active model's probe fits its proportions. | Add the missing probe and tune each model's Capsule or Sphere Collider separately. |

## Related tasks

- [First Person view type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/) configures the camera that receives the lean offset and tilt.
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) explains the character input abstraction and action names.
- [Input System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/input-system/) explains connecting Unity Input System actions to UCC.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) defines **Solid Object Layers**, which control the clearance query.
- [First Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) configures the item presentation affected by **Item Tilt Multiplier**.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains axis activation, concurrency, and ability-list behavior.

## Developer reference

`Lean` is a concurrent ability with default **Start Type: Axis**, **Stop Type: Axis**, and **Input Name: Lean**. It does not use an Animator ability index or a state by default.

The ability sends `OnCharacterLean(float distance, float tilt, float itemTiltMultiplier)` whenever the side, collision restriction, start state, or stop state changes. The Version 3 first-person camera consumes distance and tilt; first-person perspective items consume tilt multiplied by the item value.

The collision query uses `Physics.OverlapCapsuleNonAlloc` or `Physics.OverlapSphereNonAlloc` with **Solid Object Layers** and `QueryTriggerInteraction.Ignore`. It then uses `Physics.ComputePenetration` to determine how much to retract the camera response. The public runtime properties expose `Distance`, `Tilt`, `ItemTiltMultiplier`, `Colliders`, and `ColliderOffsetMultiplier`.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-follow-pseudo3d-2-5d-path"></a>

# Follow Pseudo3D Path

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/follow-pseudo3d-2-5d-path/)

Follow Pseudo3D Path keeps a third-person 2.5D character at a consistent horizontal offset from a curved Path. Use it with the Pseudo3D Movement Type when the route bends; the ability constrains the character to the route but does not supply movement or snap the character onto the curve.

## Before you begin

- The character needs the [Third Person Pseudo3D Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/).
- The camera should use the matching [Third Person Pseudo3D view type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/).
- The scene needs a **Path** component with at least one curve segment. Assigning an empty Path component is not a valid route.
- Place the character on the intended lane relative to the curve before the Pseudo3D Movement Type activates. Follow Pseudo3D Path preserves that starting offset rather than moving the character to the centerline.

## Create and assign the Path

1. Create an empty GameObject in the scene and give it a descriptive name such as `MainRoute`.
2. Add the **Path** component.
3. Select **Add Curve Segment**. The Scene view displays the first cubic Bezier segment with a green start point, a red end point, and tangent controls.
4. Select an endpoint or its smaller tangent handle and position it with the Scene view tool. With a control point selected, use the **Position** field for exact values.
5. Select **Add Curve Segment** again for each additional bend. Adjacent segments share their endpoint, and editing a tangent beside an internal point keeps the opposite tangent aligned for a continuous curve.
6. Traverse the curve visually from its green start to red end. Keep adjacent handles smooth and avoid sharp reversals that would produce an abrupt tangent change.
7. Select the character. In **Ultimate Character Locomotion > Movement Types**, select **Third Person Pseudo3D** and assign `MainRoute` to **Path**.

Build and shape the Path before entering Play Mode. The Version 3 Path calculates its runtime curve from the control points during `Awake`; moving its Transform or editing points afterward does not rebuild that cached curve.

## Add Follow Pseudo3D Path

1. On the character's **Ultimate Character Locomotion** component, expand **Abilities**.
2. Select the plus button and add **Follow Pseudo3D Path**.
3. Keep **Enabled** selected, **Start Type** set to **Manual**, and **Stop Type** set to **Manual**. The Pseudo3D Movement Type change event starts and stops the ability; no input name is required.
4. Place Follow Pseudo3D Path near the bottom of the ability list. It is concurrent, but its position correction should run after the ordinary movement abilities that produce the frame's desired movement.
5. Make **Third Person Pseudo3D** the active Movement Type. When both perspectives are installed, also select it as **Third Person Movement Type**.
6. On the Camera Controller, make **Third Person Pseudo3D** the active third-person view type.

The ability can start only while Third Person Pseudo3D is active and its **Path** field is assigned. Switching away from that Movement Type stops the ability. Switching back starts it again when a Path is available.

## Choose the movement scenario

### Straight side-scroller

Leave **Path** empty when the stage remains on one fixed plane. The Pseudo3D Movement Type and view type can provide side-view controls and framing without Follow Pseudo3D Path; the ability will not start without a Path.

### Curved single lane

Assign a Path and disable **Allow Depth Movement** on the Pseudo3D Movement Type. Follow Pseudo3D Path records the character's horizontal offset from the curve when it starts and corrects each frame's desired movement so that offset remains constant around bends.

This is the most predictable setup for a platformer or side-scroller whose playable route curves through world space.

### Curved route with depth lanes

Assign a Path and enable **Allow Depth Movement** when forward and backward input should move the character across the camera-relative depth axis. While that input is present, Follow Pseudo3D Path updates its stored offset instead of forcing the character back to the original lane. It then preserves the new offset as the route curves.

Test the full allowed lane width at every bend. The Path defines the reference curve, not lane boundaries; use level collision or other gameplay constraints for the outer limits.

### Character facing

**Look In Move Direction** belongs to the Pseudo3D Movement Type rather than this ability. Enable it when the character should face its movement direction along or across the route. When it is disabled, cursor or look-axis input determines facing, using the Path tangent as the local 2.5D plane.

Use **Look Rotate Buffer** to prevent rapid direction changes while cursor aiming near the character. It does not change how Follow Pseudo3D Path constrains position.

## How it runs

When the Pseudo3D Movement Type activates with a Path assigned, Follow Pseudo3D Path starts and finds the closest point and tangent on the curve near the character. It expresses the character position in that local path orientation and stores the horizontal offset.

Each position update starts with the movement already requested by locomotion, root motion, or another ability. Follow Pseudo3D Path evaluates the closest point and tangent at that target position, then changes **Desired Movement** only enough to preserve the stored offset. It does not set speed, choose a destination, control vertical motion, or advance the character automatically.

When **Allow Depth Movement** is enabled and forward or backward input is present, that camera-depth movement changes the stored offset. Removing the **Path** reference while the ability is active stops it. Deactivating the Pseudo3D Movement Type also stops it.

The camera uses the same active Movement Type's Path tangent to rotate its side view around bends. Camera rotation and character position correction are separate: assigning the Path can orient the camera, but Follow Pseudo3D Path is still required to hold the character's lane through the curve.

## Verify in Play Mode

1. Enter Play Mode with **Third Person Pseudo3D** active on both the character and camera. Confirm Follow Pseudo3D Path shows **(Active)** without a button press.
2. Start the character on the Path centerline and move through the complete route in both directions. Confirm it follows every bend without drifting across the curve.
3. Start again at a deliberate offset from the centerline. Confirm that same relative offset is preserved; the ability should not snap the character onto the line.
4. With **Allow Depth Movement** disabled, apply forward and backward input and confirm it does not move the character into or out of the gameplay plane.
5. Enable **Allow Depth Movement**, move to another lane, release the depth input, and continue around a bend. Confirm the new offset remains stable.
6. Confirm the camera turns with each Path tangent while the character remains framed from the intended side.
7. Switch to another Movement Type and confirm the ability stops. Switch back to Third Person Pseudo3D and confirm it starts again with the assigned Path.
8. Test jumps, root-motion actions, and any other position-modifying abilities used by the game. Vertical motion should remain available while the horizontal route offset stays consistent.

## Troubleshoot Follow Pseudo3D Path

| Symptom | Check | Fix |
| --- | --- | --- |
| The ability never becomes active. | Check **Enabled**, the active Movement Type, and the Pseudo3D **Path** field. A Path assigned after Pseudo3D was already activated does not emit a new movement-type event. | Activate **Third Person Pseudo3D** with a valid Path already assigned, or switch away and back after assigning it. |
| Play Mode reports a Path error as soon as the ability starts. | Check whether the assigned Path contains at least one curve segment. | Select the Path and use **Add Curve Segment** before entering Play Mode. |
| The camera turns at bends but the character drifts away from the route. | The Path can orient the Pseudo3D camera even when Follow Pseudo3D Path is missing, inactive, or updated before another position modifier. | Add and enable the ability, confirm it is active, and keep it near the bottom of the ability list. |
| The character stays a fixed distance away from the curve instead of snapping to it. | Check the character's position when the ability first activated. | Place the character on the intended lane before activation; preserving the initial offset is expected behavior. |
| Forward and backward input do not change lanes. | Check **Allow Depth Movement** on the Pseudo3D Movement Type. | Enable it only for a game that supports camera-depth movement, then provide collision or level limits for the lane width. |
| The character slides across lanes around a bend. | Check whether another ability below Follow Pseudo3D Path changes **Desired Movement**, or whether the curve has abrupt tangent reversals. | Move Follow Pseudo3D Path later in the list and smooth the Path handles through the bend. |
| Character facing does not match movement. | Check **Look In Move Direction**, the Path direction, and **Look Rotate Buffer**. | Enable movement-based facing or tune the look settings for cursor/controller aiming, then test travel in both directions. |
| The camera appears on the wrong side of the route. | Check the Path's green-to-red direction and the Pseudo3D view type's **Forward Axis**. | Reverse or reshape the route when its direction is wrong, or adjust **Forward Axis** for the intended camera side. |
| A Path edited or moved during Play Mode still uses its old shape. | The runtime Path curve is cached during `Awake`. | Finish the route before Play Mode. Use a custom runtime path implementation when the curve itself must change during play. |
| Changing directly to a different Path at runtime produces a wrong offset. | Follow Pseudo3D Path retains its current offset and segment state; runtime Path swapping is not a built-in route-transition workflow. | Use a designed transition or custom ability that explicitly establishes the new route and offset instead of replacing the reference in place. |

## Related tasks

- [Third Person Pseudo3D Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/) configures **Allow Depth Movement**, facing, and the **Path** reference.
- [Third Person Pseudo3D view type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/) configures the matching side-view camera and Path-based rotation.
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) explains active Movement Types and perspective-specific selection.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains concurrency, list update order, and manual activation.
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) explains configuring a third-person character through the Character Manager.

## Developer reference

`FollowPseudo3DPath` is a concurrent ability with default **Start Type: Manual** and **Stop Type: Manual**. It has no feature-specific serialized fields, Animator ability index, or default state.

The ability listens for `OnCharacterChangeMovementType(MovementType movementType, bool active)`. `CanStartAbility` requires the active Movement Type to be `Pseudo3D` with a non-null `Path`. `Update` stops the ability if that Path becomes null, and `UpdatePosition` adjusts `UltimateCharacterLocomotion.DesiredMovement` rather than moving the Transform directly.

At activation, the ability stores a path-segment index and the character's local horizontal offset from the closest curve point. The Version 3 `Path` component constructs one cubic Bezier segment from four control points and adds three control points for each later segment. It converts those local points to a cached world-space curve during `Awake`.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-generic"></a>

# Generic

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/generic/)

Generic plays a character animation through the standard ability system without requiring a new ability class. Use it for an emote, gesture, pose, short interaction animation, or other self-contained clip that only needs input, Animator parameters, ability settings, and a reliable completion point.

## Before you begin

- Import the animation clip and confirm it previews correctly on the character's Avatar.
- Use an Animator Controller with the UCC `AbilityIndex`, `AbilityChange`, and `AbilityIntData` parameters.
- Decide whether the animation is presentation-only. Generic does not apply damage, choose a target, spawn an object, or run custom gameplay logic. Use a purpose-built or [custom ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) when the animation must coordinate those results.
- Choose a project-unique **Ability Index Parameter**. Generic defaults to `10000`; the worked example below uses `10100`.

The numeric Ability Index selects an Animator branch. It does not set ability-list priority; the Generic entry's position in **Abilities** controls priority.

## Add a no-code animation

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities**, select the plus button, and add **Generic**.
3. Keep **Enabled** selected and set **Ability Index Parameter** to the unique value reserved for this animation. This example uses `10100`.
4. Leave **Ability Int Data Value** at `-1` when the transition needs only the Ability Index. Assign a deliberate integer when several animation variants share one index.
5. Choose how the ability starts. The default is **Start Type: Button Down** with **Input Names: Action**. Change the input name or use another standard start type when the animation needs a different control.
6. Keep **Stop Type** set to **Manual** so Generic's **Stop Event** owns completion.
7. Place Generic at the desired priority. Keep critical interruptions such as death above it. Place it below actions that should block the gesture, or above lower-priority actions it is allowed to interrupt.
8. Configure movement, root motion, items, and an optional State as described below.

Generic allows duplicate entries. Add one entry per independently configured animation, give each a clear **Inspector Description**, and use distinct inputs or start conditions so several entries do not compete for the same press.

## Add the Animator state

1. Open **Window > Animation > Animator** and select the character's Animator Controller.
2. In **Full Body Layer**, create or open a sub-state machine for the project's Generic animations.
3. Create a state for the clip. The legacy example uses a `PutGlassesOn` state.
4. Follow the controller's existing ability-transition pattern: enter the branch when `AbilityChange` is triggered and `AbilityIndex` equals the Generic entry's **Ability Index Parameter**. Add an `AbilityIntData` condition when that value selects a variant.
5. Add the return transition used by the controller when the active Ability Index no longer selects this state. Do not rely on the clip reaching its final frame to stop the UCC ability; **Stop Event** controls the ability lifetime.

![Animator Generic branch entering the PutGlassesOn state for Ability Index 10100](https://opsive.com/wp-content/uploads/2018/03/PutGlassesOnAnimation-1024x328.png)

The example value `10100` is not required. The Inspector value and Animator condition only need to match and remain distinct from other ability branches in the project.

## Choose the completion timing

Expand **Stop Event** and choose one mode.

### Stop after a duration

Disable **Wait For Animation Event** and set **Duration** to the number of seconds after the ability starts. A new Generic entry defaults to duration mode with `0.5` seconds.

Use duration mode for a quick prototype or a clip whose timing and playback speed are fixed. Retune the duration whenever the clip, transition, or Animator speed changes.

### Stop on the animation frame

Enable **Wait For Animation Event** when the ability should finish at a frame authored in the clip:

1. Open **Window > Animation > Animation** and select the clip.
2. Add an Animation Event at the intended completion frame.
3. Set **Function** to `ExecuteEvent`.
4. Set the String value to `OnAnimatorGenericAbilityComplete` exactly. Event names are case-sensitive.
5. Add the event to every first-person or third-person clip that can drive this same Generic animation.

![PutGlassesOn clip with an ExecuteEvent animation event for OnAnimatorGenericAbilityComplete near the end](https://opsive.com/wp-content/uploads/2018/03/PutGlassesOnAnimationCompleteEvent.webp?v=a6f4174f55b3)

Animation-event mode follows the meaningful frame when playback speed changes. It has no duration fallback: if the active clip never sends the event, Generic remains active.

## Choose movement and presentation

### In-place gesture

For a wave, salute, or other animation that should hold the character in place:

- Disable **Allow Positional Input** and **Allow Rotational Input** when the player must not steer during the gesture.
- Prefer an in-place clip. Leave **Use Root Motion Position** and **Use Root Motion Rotation** at **No Override** when the character's existing settings already suppress unwanted motion; set both overrides to **False** when this ability must force an in-place result.
- Use **Allow Equipped Items** or Item Equip Verifier settings when the gesture is incompatible with equipped items.

### Clip-authored movement

Set **Use Root Motion Position** or **Use Root Motion Rotation** to **True** when the clip itself should move or turn the character. Test collision, slopes, and the return to locomotion over the entire clip. Generic supplies no destination or obstacle planning beyond the standard locomotion settings.

### Temporary character configuration

Assign **State** when the animation needs an existing State System preset while it is active, such as a camera, movement, or presentation adjustment. The state activates when Generic starts and clears when it stops. Use a specialized ability when the scenario needs logic beyond property changes.

## Use several Generic animations

Generic can be added more than once:

- Use a different **Ability Index Parameter** for completely separate Animator branches.
- Reuse one Ability Index and assign different **Ability Int Data Value** values when several variants belong inside the same Generic branch.
- Give each entry a distinct **Input Name**, custom starter, or manual caller. If duplicate non-concurrent entries respond to the same input, the higher-priority entry starts first and prevents the lower entry from starting.
- Test a direct transition between variants. `AbilityChange` is raised when the Ability Index changes; an Animator that switches variants under the same index must also respond correctly to `AbilityIntData`.

## How it runs

When its configured start condition succeeds, Generic enters the active ability list and exposes its **Ability Index Parameter** and **Ability Int Data Value** to Animator Monitor. The highest-priority active ability that supplies those parameters controls the Animator values. Generic also applies its standard input, root-motion, item, attribute, and State settings.

Generic is non-concurrent. A higher-priority active non-concurrent ability can block it, while a newly started higher-priority ability can interrupt it according to the normal ability rules.

As soon as Generic starts, **Stop Event** begins waiting. Duration mode schedules completion after **Duration**. Animation-event mode waits for `OnAnimatorGenericAbilityComplete`. Completion stops Generic, clears its State and overrides, and allows the Animator parameters to return to the next active ability or their neutral values.

## Verify in Play Mode

1. Keep **Ultimate Character Locomotion** and the Animator window visible, then activate the configured input.
2. Confirm Generic shows **(Active)** and the Animator reports the intended `AbilityIndex` and `AbilityIntData` values.
3. Confirm the correct clip plays once and the character retains or loses movement input according to **Allow Positional Input** and **Allow Rotational Input**.
4. For root-motion animation, confirm the character moves or rotates with the clip and does not pass through the tested scene geometry.
5. In duration mode, confirm Generic stops after **Duration**. In animation-event mode, enable **Animator Monitor > Editor > Log Events** and confirm `OnAnimatorGenericAbilityComplete` executes at the authored frame.
6. Confirm Generic is no longer active, its optional State is cleared, locomotion and items return to their expected behavior, and the Animator exits the Generic state.
7. Repeat with every supported perspective, equipped-item combination, and higher-priority interruption.
8. If duplicate Generic entries exist, trigger each one separately and confirm its input, index, data value, clip, and completion timing are independent.

## Troubleshoot Generic

| Symptom | Check | Fix |
| --- | --- | --- |
| The input does nothing. | Check **Enabled**, **Start Type**, **Input Names**, and whether a higher-priority non-concurrent ability is active. | Correct the input setting, release or reorder the blocking ability, and test the live input value. |
| Generic becomes active but the animation does not play. | Compare **Ability Index Parameter** with the Animator's `AbilityIndex` condition and confirm the transition uses `AbilityChange`. | Make the values match and restore the standard ability entry condition. |
| The wrong Generic variant plays. | Compare **Ability Int Data Value** with the Animator's `AbilityIntData` conditions. | Give each variant a unique value and make its transition conditions mutually exclusive. |
| Generic never stops in animation-event mode. | Check the active clip for **Function: ExecuteEvent** and the exact String `OnAnimatorGenericAbilityComplete`. | Add or correct the event on every clip that can play, or deliberately use duration mode. |
| The animation ends before or after Generic stops. | Check the **Duration**, event-frame position, transitions, and playback speed. | Retune Duration or move the animation event to the intended completion frame. |
| The character can move during an in-place gesture. | Check **Allow Positional Input**, **Allow Rotational Input**, the clip, and root-motion overrides. | Use an in-place clip, disable unwanted input, and set both root-motion overrides to **False** when the ability must force an in-place result. |
| Root motion in the clip has no gameplay effect. | Check **Use Root Motion Position**, **Use Root Motion Rotation**, and the clip's imported root-motion data. | Set the required override to **True** and correct the clip import or Animator setup. |
| A duplicate Generic entry never starts. | Check whether another entry uses the same input and has higher list priority. | Give the entries distinct controls or start conditions, or invoke the intended entry manually. |
| The animation plays, but its intended gameplay effect never occurs. | Check whether the scenario requires behavior beyond Animator parameters and standard ability settings. | Use the appropriate included ability or create a custom ability that performs the gameplay action at a defined event. |

## Related tasks

- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains duration and exact-frame completion.
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains organizing ability states and transitions.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains `AbilityIndex`, `AbilityChange`, and `AbilityIntData`.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains start types, list priority, input permissions, root motion, items, and States.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains property presets activated through **State**.
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) is the next step when the animation requires custom gameplay behavior.

## Developer reference

`Generic` allows duplicate ability types. Its defaults are **Ability Index Parameter** `10000`, **Ability Int Data Value** `-1`, **Start Type: Button Down**, **Input Names: Action**, and a **Stop Event** in duration mode at `0.5` seconds. It inherits non-concurrent behavior and the base **Stop Type: Manual**.

On `Awake`, Generic registers `OnAnimatorGenericAbilityComplete`. `AbilityStarted` calls `StopEvent.WaitForEvent`; the completion callback cancels the pending wait and calls `StopAbility`. Changing the public `AbilityIntData` property while Generic is active immediately updates the Animator integer parameter.

Generic contains no custom movement, targeting, collision, or gameplay-effect callbacks. Code can retrieve a particular duplicate with the normal Ultimate Character Locomotion ability APIs and start it manually, but a reusable scenario with its own validation or runtime work should derive a dedicated ability instead.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-height-change"></a>

# Height Change

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/height-change/)

The Height Change ability lets a grounded character enter a shorter stance such as crouching or crawling, then return to full height only when there is enough clearance. It coordinates the input, Animator **Height** parameter, State System state, and character collider rather than merely playing a crouch animation.

## Before you begin

- A character created with **Standard Abilities** may already have Height Change. Add another instance only when the character needs a separate stance with its own input and animation value.
- The included Animator Controller uses **Ability Index Parameter 3** for Height Change and reads the **Height** parameter to select the stance. A custom controller needs equivalent transitions.
- Leave **Detect Horizontal Collisions** and **Detect Vertical Collisions** enabled on **Ultimate Character Locomotion** if the character must remain crouched beneath a low obstacle.
- Make sure ceilings and other blocking geometry use a non-trigger collider on a layer included in **Character Layer Manager > Solid Object Layers**.

## Configure a crouch stance

1. Select the character GameObject, then find **Ultimate Character Locomotion** in the Inspector.
2. Expand **Abilities**. If Height Change is not already present, select the plus button and add **Height Change**.
3. Keep Height Change near the bottom of the list and below **Speed Change**, matching the standard character order. Higher-priority movement and airborne abilities can then take control while the stance remains active concurrently.
4. Set **Start Type** to **Button Down**, **Stop Type** to **Button Toggle**, and **Input Names** to **Crouch** for a press-to-toggle crouch.
5. Keep **Concurrent Ability** enabled when the crouch pose should remain available while another compatible ability runs.
6. Keep **State** set to **Crouch**, **Ability Index Parameter** set to `3`, and **Height** set to `1` when using the included Animator Controller.
7. For a character without an Animator, tune **Capsule Collider Height Adjustment** so the capsule matches the shorter stance. The default adjustment is `-0.4`.
8. Choose whether **Allow Speed Change** should permit the Speed Change ability while crouched.

## Choose the stance behavior

### Toggle or hold the input

The default **Button Down** start and **Button Toggle** stop make each press switch between standing and crouching. For hold-to-crouch, keep **Start Type** as **Button Down** and change **Stop Type** to **Button Up**. An AI-controlled character can instead start and stop the ability manually without an input name.

### Coordinate the animation and collider

The standard crouch uses **Height** `1`; `0` represents the standing state. A different nonzero value can select another stance only when the custom Animator Controller defines that value. A value of `-1` tells Height Change not to change the Animator **Height** parameter.

On an animated character, **Capsule Collider Positioner** follows its configured end-cap targets as the pose changes. **Capsule Collider Height Adjustment** is used only when the character has no Animator and Capsule Collider Positioner creates its own second end cap. Tune the animation or end-cap setup for an animated character, and tune the numeric adjustment for an animatorless character.

The **Crouch** state can also change movement or other properties through the State System. Keep that state name aligned with the preset used by the character.

### Allow or prevent faster movement

With **Allow Speed Change** disabled, starting Height Change stops an active Speed Change, and Speed Change cannot start while Height Change remains active. Enable it for a crouch-run or another stance that should retain the configured speed multiplier.

### Add another height stance

Height Change supports more than one instance. For a crawl or other alternate stance, add a second Height Change and give it a distinct input or manual start rule, State, and Animator **Height** value. Make the start conditions mutually exclusive so two concurrent height stances do not activate together.

## How Height Change runs

Height Change can start only while the character is grounded. When it starts, it saves the current collider dimensions, activates its configured State System state, sets the Animator **Height** value unless that value is `-1`, and requests the configured animatorless capsule adjustment.

Because the ability is concurrent by default, its **Height** value can remain active while another compatible ability supplies the main **Ability Index**. This allows an Animator to choose, for example, a jump animation that begins from a crouched pose. Jump and Fall prevent a new Height Change from starting once the character is already airborne.

When Height Change is asked to stop, it tests the character's original collider shape against **Solid Object Layers** and ignores trigger colliders. If restoring the standing shape would overlap a solid object, the ability stays active. Once there is room, it restores the collider, resets **Height** to `0`, and deactivates the configured state.

## Verify in Play Mode

1. Keep the character's **Ultimate Character Locomotion** component and Unity's Animator window visible.
2. Start on the ground and press the crouch input. Confirm Height Change displays **(Active)**, the pose becomes shorter, and Animator **Height** changes to `1`.
3. Move while crouched and confirm the collider continues to fit the visible pose. Test Speed Change both disabled and enabled according to **Allow Speed Change**.
4. Enter a space with a low, non-trigger ceiling while crouched, then request standing. Height Change should remain active and **Height** should remain `1`.
5. Move into open space and request standing again. Confirm the full collider is restored, **Height** returns to `0`, and **(Active)** disappears.
6. If the game permits jumping from crouch, jump while Height Change is active and confirm the intended crouched jump animation uses the persistent **Height** value.

## Troubleshoot Height Change

| Symptom | Check | Fix |
| --- | --- | --- |
| Crouch never starts. | The character may be airborne, the ability or input may be disabled, or a higher-priority ability may block it. | Test while grounded, confirm **Enabled** and the **Crouch** input mapping, then inspect the active abilities above Height Change. |
| The ability becomes active but the pose does not change. | The Animator may not contain the **Height** parameter or transitions for Height `1` and Ability Index `3`. | Add the Version 3 parameters and compare the ability values with the Animator transition conditions. |
| The animated pose changes but the capsule does not fit it. | **Capsule Collider Positioner** may have incorrect end-cap targets or height adjustment disabled. | Correct the positioner's targets and settings so it follows the animated crouch pose. Do not use **Capsule Collider Height Adjustment** as the animated-character fix. |
| An animatorless character keeps its standing capsule. | **Capsule Collider Height Adjustment** may be `0` or too small. | Use a negative adjustment and verify the resulting capsule still remains taller than twice its radius. |
| The character stands through a low ceiling. | Horizontal or vertical collision detection may be disabled, the ceiling may be a trigger, or its layer may be absent from **Solid Object Layers**. | Enable both collision checks and use a non-trigger collider on a solid-object layer. |
| Sprint stops when crouching or cannot start while crouched. | **Allow Speed Change** is disabled by default. | Enable it only when the crouched stance and animations support faster movement. |
| Two stance animations activate together. | Multiple concurrent Height Change instances may share an input or start condition. | Give each stance an exclusive input or manual start rule and a distinct Animator **Height** value. |

## Related tasks

- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) controls the movement-speed ability that Height Change can block or allow.
- [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) and [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/) explain the airborne abilities that interact with a persistent height stance.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) describes **Height**, **Ability Index**, and the other Version 3 parameters.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains list priority, concurrency, input start and stop types, and shared ability settings.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains the **Crouch** state activated by the ability.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) explains **Solid Object Layers**, which control the standing-clearance test.

## Developer reference

Height Change uses these Version 3 defaults and runtime rules:

- **Input Name:** `Crouch`.
- **Start Type:** `Button Down`; **Stop Type:** `Button Toggle`.
- **State:** `Crouch`.
- **Ability Index Parameter:** `3`; **Ability Int Data:** `1`.
- **Concurrent Ability:** enabled; **Height:** `1`; **Capsule Collider Height Adjustment:** `-0.4`; **Allow Speed Change:** disabled.
- `CanStartAbility` requires the character to be grounded.
- `OnHeightChangeAdjustHeight` sends the capsule adjustment at start and its inverse at stop. An animatorless Capsule Collider Positioner listens for this event.
- A normal stop checks the saved capsule, sphere, and box collider shapes against **Solid Object Layers** with triggers ignored. A forced stop bypasses the clearance test.
- An active Height Change blocks `StoredInputAbilityBase`. It also blocks or stops `SpeedChange` when **Allow Speed Change** is disabled.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-idle"></a>

# Idle

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/idle/)

The Idle ability adds delayed animation variations while the character is grounded and not moving. Use it for longer-lived poses or small character moments, such as looking around, shifting weight, or checking equipment, after the normal locomotion idle has played for a while.

Idle selects each variation through the **Ability Float Data** Animator parameter. It stops as soon as the character moves or leaves the ground, so regular movement and airborne abilities can take over.

## Add Idle to the character

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **Idle**.
4. Drag Idle to the bottom of the **Abilities** list so every more important non-concurrent ability has a higher priority.
5. Select Idle and keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Automatic**.
6. Set **Start Delay**, **Max Ability Float Data Value**, **Random Value**, **Min Duration**, and **Max Duration** for the available variations.
7. Confirm the character Animator uses **Ability Float Data** to select the intended idle animations.

The included demo Animator contains three variations in **Base Layer > Idle > Idle Blend Tree**.

![Animator Base Layer Idle Blend Tree using Ability Float Data to select three idle animation variations](https://opsive.com/wp-content/uploads/2018/03/IdleBlendTree.png?v=5f61f849eba5)

## Choose the idle timing

### Delay special idles

**Start Delay** is how long the character must remain grounded and not moving before Idle can start. The default is **15 seconds**.

- Use a longer delay when special idles should feel occasional and should not replace the normal locomotion idle too quickly.
- Use a shorter delay when the character should show personality soon after stopping.
- Moving or leaving the ground resets the timer, so the full delay is required again after the character settles.

### Match the Animator values

**Max Ability Float Data Value** is the highest zero-based value in the idle blend tree. It is not the number of animations.

- One variation at value **0** uses a maximum of **0**.
- Three variations at values **0**, **1**, and **2** use a maximum of **2**.
- Keep each Animator threshold on a whole-number value because Idle chooses whole-number indices.

### Choose random or sequential variations

Enable **Random Value** to choose any value from **0** through the configured maximum each time. Random selection can choose the same variation more than once in a row.

Disable **Random Value** to advance through the values in sequence and wrap back to **0** after the maximum. Use this when every variation should appear in a predictable rotation.

### Control how long each variation remains active

**Min Duration** and **Max Duration** define the time range before Idle chooses another Ability Float Data value. Their defaults are **5** and **10 seconds**.

- Increase both values for longer, calmer idle poses.
- Decrease them for more frequent variation.
- Keep **Min Duration** at or below **Max Duration** and allow enough time for the associated animation to read clearly.

## How Idle runs

While inactive, Idle waits until the character is grounded, not moving, and has remained that way for **Start Delay**. Any movement or ungrounded frame clears that pending timer.

When Idle starts, it chooses the first Ability Float Data value and updates the Animator. It then schedules another selection after a random time between **Min Duration** and **Max Duration**. This continues while the ability remains active.

Idle stops automatically when the character starts moving or is no longer grounded. Stopping cancels the pending value change and resets the start timer. Placing Idle at the bottom of the list also allows a higher-priority non-concurrent ability to replace it immediately.

## Verify in Play Mode

1. Keep the **Ultimate Character Locomotion** Inspector visible and leave the character grounded without movement for longer than **Start Delay**.
2. Confirm **(Active)** appears beside Idle and the Animator's **Ability Float Data** changes to a whole value within the configured range.
3. Wait through several duration intervals and confirm the expected random or sequential variations play.
4. Move the character and confirm Idle becomes inactive immediately.
5. Stop again and confirm the full **Start Delay** passes before Idle restarts.
6. Walk from a ledge or trigger another higher-priority ability and confirm it replaces Idle without waiting for the current variation to finish.

## Troubleshoot Idle

- **Idle never starts:** confirm **Enabled**, **Start Type: Automatic**, that the character is grounded and not moving, and that no higher-priority non-concurrent ability remains active. Wait for the complete **Start Delay**.
- **Idle starts too soon:** increase **Start Delay**. Remember that normal locomotion idle animation does not require this ability.
- **A variation is missing or the wrong animation plays:** set **Max Ability Float Data Value** to the highest zero-based blend value and confirm the blend tree uses **Ability Float Data** at matching whole-number thresholds.
- **The same random animation repeats:** this is valid when **Random Value** is enabled. Disable it for a sequential cycle.
- **Variations change too quickly or slowly:** adjust **Min Duration** and **Max Duration**, keeping the minimum no greater than the maximum.
- **Idle prevents another action:** move Idle to the bottom of **Abilities** and verify the intended action is non-concurrent or explicitly stops Idle.
- **Idle does not stop when input begins:** confirm the Ultimate Character Locomotion component reports the character as moving and that **Stop Type** remains **Automatic**.

## Related topics

- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains automatic activation, list priority, and the **(Active)** runtime indicator.
- [Quick Start](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-start/), [Quick Stop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-stop/), and [Quick Turn](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-turn/) cover automatic movement-transition animations that should also remain near the bottom of the list.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains **Ability Float Data** and the other character parameters.
- [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/) explains the timed callback system used to rotate idle values.

## Developer reference

Idle uses the inherited **Automatic** start type and an **Automatic** stop type. Its runtime behavior is:

- **CanStartAbility:** begins the delay only while the character is grounded and not moving, then permits the ability after **Start Delay**.
- **AbilityFloatData:** returns the current whole-number variation as a float for the Animator.
- **Random Value:** chooses an integer from `0` through **Max Ability Float Data Value**, inclusive.
- **Sequential Value:** increments the current value and wraps with the configured maximum.
- **Scheduled update:** chooses the next value after a random duration between **Min Duration** and **Max Duration**.
- **CanStopAbility:** stops when the character moves or is no longer grounded.
- **AbilityStopped:** resets the delay and cancels the scheduled value update.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-rotate-towards"></a>

# Rotate Towards

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rotate-towards/)

Rotate Towards keeps the character facing a Transform while still allowing ordinary movement. Use it for a conversation, interaction, cutscene, AI focus target, or another situation where the character should track a world object without moving toward it.

## Before you begin

- **Target** is a direct Transform reference. Rotate Towards does not search with a trigger, raycast, layer mask, tag, or Object ID.
- The source default is **Start Type: Automatic** with **Stop Type: Manual**. A non-null target makes the ability eligible to start; clearing the public `Target` property stops an active instance.
- Rotate Towards is non-concurrent. Its position in the regular ability list determines whether it can replace lower-priority non-concurrent actions or is blocked by a higher-priority one.
- The ability turns around the character's current up axis and ignores the target's vertical offset. Keep the target horizontally separated from the character.
- Turn response always uses **Motor Rotation Speed** on Ultimate Character Locomotion. The Version 3 source default is `0.15`.
- Rotate Towards has no default State, Animator branch, **Ability Index Parameter**, input name, or completion event.

## Face a scene target automatically

1. Select the character and open **Ultimate Character Locomotion**.
2. Expand **Abilities**, select **+**, and add **Rotate Towards**.
3. Assign the world object's Transform to **Target**.
4. Keep **Start Type** set to **Automatic** and **Stop Type** set to **Manual** for continuous tracking. The ability starts on the next ability update while the target is assigned.
5. Keep **Allow Positional Input** enabled when the character should walk while facing the target. **Allow Rotational Input** also defaults to enabled, but Rotate Towards replaces the normal input-derived rotation while it is active.
6. Choose the list position deliberately. Put Rotate Towards above actions it must interrupt; place critical reactions such as death or ragdoll above it.
7. Adjust **Motor Rotation Speed** on Ultimate Character Locomotion while watching the result in Play Mode. This value is a spherical-interpolation response factor, not a degrees-per-second limit.
8. Optionally set the inherited **State** field when the facing mode should temporarily change locomotion, animation, or Motor Rotation Speed properties.

The target can move at runtime and the character will continuously update its heading. Disabling the target GameObject does not clear its Transform reference; explicitly clear or replace **Target** when tracking should end.

## Choose the control pattern

### Always face one object

Assign **Target** in the scene and use the default automatic start. This suits a stationary actor, turret-like character, or an NPC that should always face a fixed point. The ability remains active after it reaches the heading; it does not have an angle threshold or automatic completion.

### Face a temporary interaction target

Set **Start Type** to **Manual**, assign `Target` from gameplay code, and call `TryStartAbility`. Clear `Target` at the end of the interaction. Manual start avoids an assigned target immediately reclaiming the non-concurrent ability slot after another system stops it.

### Move while maintaining focus

Leave positional input allowed. The current Movement Type still produces movement, while Rotate Towards controls the final heading. The ability does not approach, orbit, maintain distance, or stop at the target; combine it with a separate movement workflow only when that workflow can coexist with its priority.

### Use detection or player aim

Resolve the target elsewhere, then assign the returned Transform. Use [Assist Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/), [Target Orbit](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/target-orbit/), or the item [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) ability when the desired behavior already belongs to those systems. Adding a target to Rotate Towards does not create detection or camera aiming.

### Combine rotation modifiers

The base locomotion rotation runs first. Rotate Towards then writes its result during `UpdateRotation`. A later active ability that also writes rotation during that phase can replace it. Afterward, an `ApplyRotation` ability such as [Restrict Rotation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-rotation/) can quantize or otherwise modify the selected target heading.

Because Rotate Towards is non-concurrent, another regular non-concurrent ability normally cannot remain active with it. Concurrent regular abilities and item abilities can still affect the later rotation phases, so verify their order and settings together.

## How it runs

1. Automatic mode tries to start Rotate Towards whenever it is enabled, inactive, and has a non-null target. Manual or input-based start types still require the target before `CanStartAbility()` succeeds.
2. Ultimate Character Locomotion first calculates its normal input or root-motion rotation for the frame.
3. Rotate Towards subtracts the character position from the target position, converts that direction into the character's local frame, zeros local Y, and converts it back. The resulting heading lies on the plane perpendicular to the character's current up direction.
4. It creates a target rotation with that flattened direction and the character's current up vector.
5. It spherically interpolates from the current rotation toward the target with **Motor Rotation Speed × Delta Time**, then assigns that absolute delta to **Desired Rotation**.
6. Remaining `UpdateRotation` callbacks run, followed by all `ApplyRotation` callbacks, before Character Locomotion applies the result.

The released Version 3 implementation replaces the base frame rotation after root motion or input has been evaluated. As a result, root-motion rotation does not determine Rotate Towards speed while the ability is active; **Motor Rotation Speed** always controls its interpolation. If the animation must own turn timing, use the animation's root rotation without Rotate Towards or implement a project-specific rotation ability.

The flattened direction becomes zero when the target shares the character's horizontal position, including a target directly above or below it. Avoid that geometry or stop the ability before the two positions coincide.

## Verify in Play Mode

1. Keep the character Transform, Ultimate Character Locomotion, active ability list, and target Transform visible.
2. Assign a target several metres in front and to one side. Confirm Rotate Towards starts automatically and remains active after the character faces it.
3. Move the target in a full circle at the character's height. Confirm the character tracks continuously without pitching up or down.
4. Raise and lower the target without changing its horizontal position. Confirm the facing direction remains level around the character's current up axis.
5. Move the character with positional input. Confirm translation still works while the target, rather than movement input, controls facing.
6. Change **Motor Rotation Speed** from a low to a high value and confirm it changes the turn response for both root-motion and non-root-motion setups.
7. Start a higher-priority non-concurrent ability and confirm it blocks or interrupts Rotate Towards as intended. Then test a lower-priority action and confirm Rotate Towards wins only when that priority is deliberate.
8. Enable any item aiming or concurrent rotation abilities used by the character and confirm the final writer produces the intended heading.
9. Clear the public `Target` property and confirm the active ability stops. In automatic mode, verify it stays stopped until a new target is assigned.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Rotate Towards never starts | **Target** is null, the ability is disabled, or a higher-priority non-concurrent ability is active. | Assign a Transform, enable the ability, and inspect regular ability ordering. |
| The ability starts without detecting a nearby object | Rotate Towards has no detector; a scene or script assigned **Target** directly. | Clear the reference and use the intended detection system before assigning a target. |
| The character keeps reclaiming control after Rotate Towards is stopped | **Start Type** is **Automatic** and **Target** remains assigned. | Clear `Target`, disable the ability, or use **Manual** start for temporary facing. |
| The character turns too slowly | **Motor Rotation Speed** is low. | Increase it directly or through a State active only during the facing mode. |
| Root-motion turn speed has no effect | Rotate Towards replaces the base root-motion rotation and uses **Motor Rotation Speed**. | Tune the motor value, remove Rotate Towards for animation-owned turning, or use a custom ability. |
| The character ignores the target's height | Vertical offset is removed intentionally. | Use a look/aim system for upper-body pitch or write a full 3D rotation implementation. |
| Unity reports an invalid look rotation or the heading becomes unstable | The target is at the same horizontal position as the character. | Keep a nonzero planar separation or clear the target at that point. |
| The final facing differs from the target heading | A later `UpdateRotation` writer replaced the result or an `ApplyRotation` modifier changed it. | Inspect active regular and item abilities, then adjust their ordering or settings. |
| The character rotates into nearby geometry | Rotate Towards assigns **Desired Rotation** after the base locomotion rotation check has run. | Test the full collider near obstacles and use a custom collision-aware rotation implementation where required. |
| A destroyed target produces a missing-reference error | The object was destroyed without clearing the public `Target` property first. | Set `Target` to null before destroying or replacing the tracked object. |
| Rotate Towards restarts after death or another forced stop | Its current `CanStartAbility()` override checks only for a target, and automatic mode keeps retrying. | Clear the target or disable Rotate Towards as part of the death/interruption State. |

## Related tasks

- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) moves and aligns the character to a destination instead of only rotating.
- [Target Orbit](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/target-orbit/) produces orbit movement and can rotate toward its target.
- [Assist Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/) selects an aim-assist target and can rotate the character toward it.
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) handles item and look-source aiming.
- [Restrict Rotation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-rotation/) constrains a produced heading to fixed angular steps.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) can tune Motor Rotation Speed or disable the ability for a mode.
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) explains how to author project-specific rotation behavior.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains priority, start/stop types, concurrency, and input control.

## Developer reference

Rotate Towards inherits **Enabled** `true`, **Start Type** `Automatic`, **Stop Type** `Manual`, empty input names, an empty State, **Ability Index Parameter** `-1`, allowed positional and rotational input, and no root-motion override. `Target` defaults to null and `IsConcurrent` remains `false`.

Its only feature-specific public property is `Transform Target`. Assigning a new Transform changes the tracked object without restarting the ability. Assigning null through the property stops it when active. `CanStartAbility()` currently returns only whether Target is non-null; it does not call the base ability check, so do not rely on the inherited alive or Attribute Modifier checks to gate automatic startup.

Rotate Towards sends no target-changed, aligned, or completion event. Start and stop use the standard `OnCharacterAbilityActive` event. Use `UltimateCharacterLocomotion.TryStartAbility` and `TryStopAbility` for manual control.

The following component assumes Rotate Towards uses **Start Type: Manual**:

```csharp
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using UnityEngine;

public class FaceInteractionTarget : MonoBehaviour
{
    [SerializeField] private UltimateCharacterLocomotion m_CharacterLocomotion;

    private RotateTowards m_RotateTowards;

    private void Awake()
    {
        m_RotateTowards = m_CharacterLocomotion.GetAbility<RotateTowards>();
    }

    public void BeginFacing(Transform target)
    {
        m_RotateTowards.Target = target;
        m_CharacterLocomotion.TryStartAbility(m_RotateTowards);
    }

    public void StopFacing()
    {
        m_RotateTowards.Target = null;
    }
}
```

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-impact-knock-back"></a>

# Impact Knock Back

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/impact-knock-back/)

Impact Knock Back plays a full-body response when an impact explicitly requests it, most often after a melee counterattack. Use it when the receiving character should briefly give up control to an authored reaction animation; ordinary damage reactions are handled separately by Damage Visualization.

**Character Knock Back** starts this ability, but it does not deal damage or apply a physical force by itself. Keep the item's damage actions and add **Add Force** separately when the hit should also move the target beyond the response clip's root motion.

## Before you begin

- The receiving character needs **Ultimate Character Locomotion**, an Animator configured for the UCC parameters, and an animation transition for **Ability Index** `13` plus the chosen response ID in **AbilityIntData**.
- The attacking item needs a working **Melee Action** with collision detection. Complete a normal hit before adding the response.
- Decide which **Impact Knock Back ID** selects each response clip. The value comes from the impact action, not from a field on the ability.
- The GameObject reported as the impact target must be the character or one of its children so Character Knock Back can find the parent **Ultimate Character Locomotion** component.

## Add the ability to the receiving character

1. Select the receiving character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities**, select the plus button, and add **Impact Knock Back**.
3. Move the ability near the top of the list, above every lower-priority action it must interrupt. Impact Knock Back is nonconcurrent and cannot replace an active nonconcurrent ability above it.
4. Keep **Enabled** selected and leave **Start Type** and **Stop Type** set to **Manual**. The impact action starts the ability, and **Stop Event** ends it.
5. Keep **Ability Index Parameter** at `13` when using the shipped Animator Controller.
6. Keep **Use Root Motion Position** set to **True** when the response clip contains the intended displacement. The Version 3 default does not override root-motion rotation.
7. Configure **Stop Event**. The default disables **Wait For Animation Event** and uses a **Duration** of `0.2` seconds.

Do not add an input name. A player button is not part of this workflow.

## Add Character Knock Back to the melee item

1. Select the melee item GameObject and its **Melee Action**.
2. Expand **Impact Module Group** and select the enabled **Generic Melee Impact Module** that already handles the intended hit. If the item does not have one, use the plus button to add it.
3. Use **Substate Index** or **Attack ID** when only a particular attack should cause the response. Their default value of `-1` accepts every substate or attack ID.
4. Confirm the module's **Conditions** describe a hit that should reach **Impact Actions** rather than **Fail Impact Actions**.
5. In **Impact Actions**, select the plus button and add **Character Knock Back**.
6. Set **Impact Knock Back ID** to the value expected by the receiving character's Animator transition.
7. Keep **Delay** at `0` for an immediate reaction, or set a deliberate delay when the response should begin later.
8. Add **Add Force** to the same **Impact Actions** only when the hit also needs a physics-driven push.

A newly added Generic Melee Impact Module contains the standard damage, surface-effect, and impact-event actions. Remove actions that another enabled module already invokes so the target is not damaged twice.

## Choose the response behavior

### Select the animation with an ID

When Character Knock Back hits a UCC character, **Impact Knock Back ID** becomes the ability's **AbilityIntData**. The shipped ability supplies **Ability Index** `13`. The Animator needs a transition whose two conditions match those values.

Use a separate ID for each authored response, such as left, right, light, or heavy. The IDs are project-defined; assigning a value without a matching Animator transition starts the ability but produces no visible response.

Use the Generic Melee Impact Module's **Substate Index** and **Attack ID** filters to decide which attack sends a particular response ID. This keeps a counterattack-specific reaction from playing on every swing.

### Choose root motion or an added force

**Use Root Motion Position: True** lets the full-body response clip move the character through the controller. This is the Version 3 default. Use an authored root-motion clip when its displacement must stay synchronized with the pose.

**Character Knock Back** does not add force. Add an **Add Force** impact action for a physical push, including an in-place response clip, or combine it carefully with root motion when both are intentional. Test the total displacement rather than assuming the animation and force will not stack.

The ability leaves **Allow Positional Input** and **Allow Rotational Input** enabled by default. Disable either inherited setting when the response must ignore that form of player input for its entire active window.

### End by duration or animation event

Expand **Stop Event** and choose one completion mode:

- Leave **Wait For Animation Event** disabled to stop after **Duration**. The default is `0.2` seconds. Tune this to the point where other gameplay abilities may resume, which may be earlier than the clip's final blend-out frame.
- Enable **Wait For Animation Event** to stop only when the active response clip sends `OnAnimatorImpactKnockBackComplete`. Add that exact event to every response clip that can play.

These modes do not fall back to one another. A missing event leaves the ability active.

### Decide what the reaction interrupts

Place Impact Knock Back near the top of **Abilities** so it can replace the intended lower-priority nonconcurrent abilities. Starting it explicitly stops an active **Use** item ability on the receiving character. While the response is active, its own block rule rejects new abilities except Ragdoll. If a manually started Ragdoll must interrupt this response, place Ragdoll above Impact Knock Back; the exception does not bypass normal list priority.

## How Impact Knock Back runs

On a qualifying hit, the Generic Melee Impact Module runs its **Impact Actions**. Character Knock Back reads the reported impact GameObject, finds **Ultimate Character Locomotion** on that object or a parent, and looks up the first Impact Knock Back ability on the receiving character. If either component is missing, the action ends without starting a response.

Character Knock Back passes **Impact Knock Back ID** to the ability. The ability exposes that value as **AbilityIntData**, starts manually, forces root-motion position by default, and begins waiting on **Stop Event**. The Animator then selects the matching full-body response with Ability Index `13` and the received ID.

When the configured duration elapses or `OnAnimatorImpactKnockBackComplete` arrives, the ability stops and releases its priority. Damage, surface effects, and an added force continue to be owned by their separate impact actions.

## Verify in Play Mode

1. Keep the receiving character's **Ultimate Character Locomotion** Inspector and Animator window visible.
2. Trigger the melee attack whose **Substate Index** or **Attack ID** matches the configured Generic Melee Impact Module. Confirm Impact Knock Back displays **(Active)**.
3. Confirm Animator **Ability Index** becomes `13`, **AbilityIntData** matches **Impact Knock Back ID**, and the intended full-body response plays.
4. Start an item **Use** or another lower-priority nonconcurrent ability on the receiver before the hit. Confirm the response interrupts it and another normal ability cannot start until the response ends.
5. Trigger an attack that does not match the configured Substate Index or Attack ID. Confirm Impact Knock Back does not start from that module.
6. In duration mode, confirm **(Active)** disappears after the configured Duration. In event mode, confirm the response clip sends `OnAnimatorImpactKnockBackComplete` at the intended frame.
7. If **Add Force** is present, confirm the physical push occurs once and produces the intended total displacement with the clip's root motion.

## Troubleshoot Impact Knock Back

| Symptom | Check | Fix |
| --- | --- | --- |
| The melee hit lands but the ability never starts. | Confirm Character Knock Back is in the active module's **Impact Actions**, its **Conditions** pass, and the Substate Index or Attack ID matches. | Move the action to the correct Generic Melee Impact Module or correct the filter and condition. |
| The impact action runs but cannot find the receiver. | The reported impact GameObject may not be the character or a child of the GameObject with **Ultimate Character Locomotion**. | Put the hit collider under the character hierarchy or correct the collision target reported by the melee setup. |
| A receiver with UCC still does not react. | Impact Knock Back may be missing, disabled, or below an active higher-priority nonconcurrent ability. | Add and enable the ability, then move it above the action it must interrupt. |
| Impact Knock Back becomes active but no animation plays. | The Animator may lack Ability Index `13`, the selected AbilityIntData transition, or the required UCC parameters. | Match **Ability Index Parameter** and **Impact Knock Back ID** to a valid Animator transition. |
| The wrong response clip plays. | The item's Impact Knock Back ID may point to another AbilityIntData branch. | Compare the action's ID with the transition conditions and give each response a deliberate ID. |
| The response ends too early or too late. | Check whether **Stop Event** uses Duration or the Animator event. | Retune Duration or move `OnAnimatorImpactKnockBackComplete` to the intended release frame. |
| The response never ends. | **Wait For Animation Event** is enabled, but the active clip does not send the exact completion event. | Add `OnAnimatorImpactKnockBackComplete` to every reachable response clip or switch deliberately to Duration mode. |
| The animation plays but the target is not pushed. | Character Knock Back starts the ability but applies no force. The clip may also be in-place. | Use a root-motion response clip or add and configure **Add Force** as a separate impact action. |
| The target takes damage twice. | A new Generic Melee Impact Module may duplicate the standard damage actions already present in another enabled module. | Reuse the existing module or remove the duplicate Simple Damage action. |

## Related tasks

- [Melee](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) explains the Melee Action and its module groups.
- [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) covers conditions, delays, damage, force, and other impact results.
- [Damage Visualization](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/damage-visualization/) is the additive, damage-event-driven alternative for ordinary hit reactions.
- [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/) handles a physics-driven body response rather than an authored full-body knock-back clip.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains **Ability Index** and **AbilityIntData**.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains duration and Animator-event completion modes.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains manual activation, list priority, and nonconcurrent abilities.

## Developer reference

Impact Knock Back has these released Version 3 defaults and runtime rules:

- **Start Type:** `Manual`; **Stop Type:** `Manual`.
- **Ability Index Parameter:** `13`.
- **Use Root Motion Position:** `True`; **Use Root Motion Rotation:** `No Override`.
- **Allow Positional Input** and **Allow Rotational Input:** enabled.
- **Stop Event:** **Wait For Animation Event** disabled and **Duration** `0.2`.
- `StartKnockBackResponse(int id)` stores the response ID and calls `StartAbility`; `AbilityIntData` returns that stored ID.
- `OnAnimatorImpactKnockBackComplete` completes Stop Event when animation-event mode is enabled.
- `ShouldBlockAbilityStart` blocks every starting ability except `Ragdoll` while Impact Knock Back is active.
- `ShouldStopActiveAbility` explicitly stops an active `Items.Use` when the response starts.

Character Knock Back is an Impact Action with **Enabled** on, **Delay** `0`, **Allow Multi Hits** off, and **Impact Knock Back ID** `0` by default. It resolves the impacted object's parent Ultimate Character Locomotion, retrieves its first `ImpactKnockBack` ability, and calls `StartKnockBackResponse`. It does not apply damage or force.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-item-equip-verifier"></a>

# Item Equip Verifier

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/item-equip-verifier/)

Item Equip Verifier temporarily changes the character to an item set that an ability allows, waits for the item transition to finish, and can restore the previous item set afterward. Use it for actions such as Interact or Drive when the character needs empty hands, selected slots, or particular Item Definitions while the action runs.

The controller starts this helper automatically. Do not assign it to a player input. Configure the equipment rule on the ability that needs it, not on Item Equip Verifier itself.

## Before you begin

- The character needs **Inventory** and **Item Set Manager** on the same GameObject as **Ultimate Character Locomotion**. The **Allow Equipped Items** controls are hidden when either inventory component is missing.
- Configure the Item Set rules so the normal loadout and the restricted state can both be reached. For example, an interaction that requires empty hands needs a target state that does not equip the weapon.
- Add an **Equip Unequip** item ability for each Item Set Group that must change. Its **Item Category** must match that group's category.
- Confirm ordinary item equip and unequip animations work before adding an ability-specific restriction. Item Equip Verifier waits for Equip Unequip to finish; it does not replace that item ability.

Characters built with item support normally already contain Item Equip Verifier. Add it only when it is missing.

## Add Item Equip Verifier

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities** and confirm there is one **Item Equip Verifier** entry.
3. If it is missing, select the plus button and add **Item Equip Verifier**.
4. Keep **Enabled** selected, **Start Type** set to **Manual**, and **Stop Type** set to **Manual**. Do not add an Input Name.
5. Expand **Item Abilities** and confirm every item category that must be switched has an **Equip Unequip** entry with the matching **Item Category**.

Item Equip Verifier is concurrent and is started directly by Ultimate Character Locomotion. Its own position in the **Abilities** list does not set the priority of the action being prepared: while it is active, it follows the starting ability's priority and interruption rules. Keep only one verifier on the character.

## Configure the ability that needs an item rule

The following example makes Interact put away every non-default equipped item before the interaction and restore the previous loadout afterward.

1. In **Ultimate Character Locomotion**, select the **Interact** entry under **Abilities**.
2. Expand **Allow Equipped Items**.
3. Clear **Slot 0**, **Slot 1**, and every other listed slot. A selected slot may remain equipped; a cleared slot must use a compatible Item Set before Interact can start.
4. Leave **Allow Item Definitions** empty because this example uses only the slot rule.
5. Leave **Immediate Unequip** disabled so Equip Unequip can use its configured animation or duration.
6. Keep **Reequip Slots** enabled so the loadout that was active before Interact is restored when Interact stops.

The released Version 3 defaults select every slot, leave **Allow Item Definitions** empty, disable **Immediate Unequip**, and enable **Reequip Slots**. With those defaults, Item Equip Verifier has no reason to change the loadout.

## Key choices

### Require empty hands

Clear every **Slot** toggle on the ability. Item Equip Verifier asks each relevant Item Set Group for a valid set with no ordinary equipped item in those slots.

An item in the active default Item Set can remain visible to the system as equipped while being treated as already unequipped. This allows a default body item used for punches or kicks to remain available. If an unexpected item remains, inspect which Item Set is marked as the group's default before changing the slot rule.

### Keep selected slots equipped

Select only the slots that the action may keep. For example, leave the shield slot selected and clear the weapon slot when an action should preserve the off-hand item but put away the main weapon.

The mask describes slot positions, not item categories. The Item Set Manager still chooses a valid Item Set for each group according to its category and rules.

### Allow only particular items

Add exact Item Definitions to **Allow Item Definitions** when the action may run with a small whitelist, regardless of which allowed slot contains the item. Any equipped non-default item that does not match the list causes a transition to a compatible Item Set.

The slot rule is evaluated first. Use the slot toggles for a location-based restriction and the definition list for an exact item whitelist; test the combination when both are populated.

### Animate or switch immediately

Leave **Immediate Unequip** disabled for visible weapon stow and draw animations. The original ability waits until all active Equip Unequip item abilities have completed.

Enable **Immediate Unequip** for a deliberate same-frame change, such as a transition where no item animation should be shown. This uses the same Item Set rules but does not wait for an equip or unequip animation.

### Restore or keep the restricted loadout

Keep **Reequip Slots** enabled when the character should return to the loadout that was active before the ability. Disable it when the restricted loadout should remain after the action ends.

The verifier does not overwrite a newer player or system choice. If an Item Set Group changes to a different active set while the restriction is in effect, that group is not forced back to its originally saved set.

## How Item Equip Verifier runs

When an ability attempts to start, Ultimate Character Locomotion first applies the normal ability priority rules and then asks Item Equip Verifier to check that ability's **Allow Equipped Items** settings. If the current loadout is already allowed, the original ability starts normally.

When a change is required, the verifier records the active Item Set for every Equip Unequip category, asks Item Set Manager for a valid target set, and starts those Equip Unequip item abilities. The verifier is concurrent while this happens and adopts the starting ability's positional-input, rotational-input, blocking, and interruption behavior.

The verifier watches the `OnCharacterItemAbilityActive` event until every Equip Unequip operation has stopped. It then stops itself before starting the original ability, so the helper cannot block the action it prepared. If Move Towards is preparing the same action, arrival still owns the final start.

When the original ability stops, the controller runs the verifier again if **Reequip Slots** is enabled and an item was removed. It restores the saved Item Sets through Equip Unequip and finishes after those item abilities stop. If the original ability ends before unequipping finishes, the verifier cancels that preparation and requests the saved sets again.

## Verify in Play Mode

1. Equip a visible weapon and confirm its Item Set is active in **Item Set Manager**.
2. Start the restricted ability from the example above. Confirm **Item Equip Verifier** and the relevant **Equip Unequip** entry become active while the weapon is put away.
3. Confirm the original ability does not become active until the required Equip Unequip operations finish.
4. While the original ability runs, confirm only the slots or Item Definitions allowed by its **Allow Equipped Items** settings remain equipped.
5. Stop the original ability. With **Reequip Slots** enabled, confirm the prior Item Set returns after the equip operation finishes.
6. Repeat with **Immediate Unequip** enabled and confirm the item change happens in the same frame without waiting for an item animation.
7. If the character has several Item Set Groups, watch each group in Item Set Manager and confirm every matching Equip Unequip entry reaches a compatible target.

## Troubleshoot Item Equip Verifier

| Symptom | Check | Fix |
| --- | --- | --- |
| **Allow Equipped Items** is not shown on an ability. | Confirm **Inventory** and **Item Set Manager** are on the same GameObject as Ultimate Character Locomotion. | Add or restore the item-support components, then reopen the ability Inspector. |
| The Console reports that Item Equip Verifier needs an EquipUnequip ability. | The character has no **Equip Unequip** entry under **Item Abilities**. | Add Equip Unequip and assign its **Item Category** to a category used by an Item Set Group. |
| The restricted ability starts while the weapon remains equipped. | Its slot may still be selected, the rule may have been configured on Item Equip Verifier instead of the starting ability, or the item may belong to the active default Item Set. | Configure **Allow Equipped Items** on the starting ability, clear the required slot, and verify the group's default set. |
| The weapon is removed but the original ability never starts. | An Equip Unequip operation may still be waiting for an animation event or may not have a usable target state. | Test Equip Unequip independently, correct its event or duration, and fix the Item Set rules so the allowed loadout can be selected. |
| One item category does not change. | Its Equip Unequip **Item Category** may not match the corresponding Item Set Group. | Match the categories and confirm that group contains a valid restricted Item Set. |
| The previous loadout is not restored. | **Reequip Slots** may be disabled, or the group's active Item Set may have changed after the verifier selected its restricted target. | Enable Reequip Slots. If another system intentionally changed the set, let that newer choice remain or coordinate the two systems. |
| A body item remains active after every slot is cleared. | The body item may be part of the active default Item Set, which the verifier treats as unequipped. | Keep this behavior when the body item supports unarmed actions; otherwise correct the default Item Set configuration. |
| The action appears to wait after the items are ready. | Move Towards may still be approaching the action's required location. | Verify the Move Towards target and wait for arrival; the verifier does not bypass the positioning step. |

## Related tasks

- [Interact](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/) is a common example of an ability that may require empty hands.
- [Drive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/) can restrict equipped items while the character enters and controls a vehicle.
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) explains the controller-owned positioning helper that can prepare the same starting ability.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains how item abilities differ from character abilities.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs the actual item transitions and owns their animation timing.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) explains Item Set Groups, default sets, validity, and runtime inspection.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains list priority, concurrency, and shared ability settings.

## Developer reference

Item Equip Verifier has these released Version 3 defaults and runtime rules:

- **Start Type:** `Manual`; **Stop Type:** `Manual`; **Concurrent:** `True`.
- The ability has no verifier-specific serialized Inspector fields. It reads `AllowEquippedSlotsMask` (`-1` by default), `AllowItemDefinitions` (empty), `ImmediateUnequip` (`false`), and `ReequipSlots` (`true`) from the ability being started.
- Ultimate Character Locomotion caches the verifier and calls `TryToggleItem(ability, true)` before a normal ability starts and `TryToggleItem(ability, false)` after it stops.
- While active, `ShouldBlockAbilityStart` and `ShouldStopActiveAbility` delegate to the starting ability and preserve its list priority. Equip Unequip is never blocked by the verifier.
- One target and starting Item Set index is stored for each Equip Unequip item ability. Restoration occurs only while that group's active set is still the restricted target selected by the verifier.
- `OnCharacterItemAbilityActive` tracks active Equip Unequip operations. When the tracked set becomes empty, the verifier completes the transition; `OnDeath` resets its saved starting ability and unequipped state.
- Pickup is excluded from `TryToggleItem` because its pickup flow manages equipment separately. Move Towards defers the original start to its on-arrival ability, and an ability whose `ImmediateStartItemVerifier` override is true is not held until the verifier stops.
- An already active starting ability that implements `IItemToggledReceiver` receives `ItemToggled()` after the item transition completes.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-jump"></a>

# Jump

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/)

The Jump ability launches the character upward and supports optional variable-height, coyote-time, and airborne jumps for characters that need player-controlled jumping.

## Add Jump to the character

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the **+** button and add **Jump**.
4. Keep **Jump** directly above **Fall** in the Abilities list. If Fall is not present, add it and place it immediately below Jump.
5. Keep the default **Start Type** set to **Button Down**, **Stop Type** set to **Automatic**, and **Input Names** set to **Jump** unless the project uses a different input setup.
6. Configure **Jump Event** for the character's animation setup:
   - For a full-body character with the supplied jump animation event, leave **Wait For Animation Event** enabled.
   - For a first-person character without a body animation, disable **Wait For Animation Event** and use **Duration** as a timer. Set Duration to `0` to apply the force immediately.

The animation-event version waits for `OnAnimatorJump` before applying the initial force. See [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) when using a custom Animator Controller.

## Choose the jump feel

### Standard jump height and response

Use **Force** for the initial upward force. **Frames** spreads that force across multiple frames: a larger value makes the initial response less immediate. **Force Damping** controls how quickly the applied force wears off.

The ability stays active during the upward part of the jump. **Vertical Velocity Stop Threshold** determines the velocity at which Jump ends so Fall can take over near the apex.

### Variable-height jumps

Use **Force Hold** when holding the Jump input should produce a higher jump than tapping it. The ability adds this force while the input remains held, and **Force Damping Hold** controls how quickly the hold force wears off. Set Force Hold to `0` when tap and hold should produce the same jump.

### Sideways and backward movement

**Sideways Force Multiplier** and **Backwards Force Multiplier** affect only the initial jump force. Use values below `1` when strafing or moving backward should produce a lower jump; move them closer to `1` when direction should not noticeably reduce the launch.

### Coyote time and blocked jumps

**Grounded Grace Period** allows a jump shortly after the character leaves a ledge. Set it to `-1` to allow the grounded jump after any amount of airborne time, subject to the other airborne-jump limits.

**Min Ceiling Jump Height** prevents Jump from starting when a flat object is too close above the character; set it to `-1` to disable this check. Keep **Prevent Slope Limit Jump** enabled when the character should not jump from a surface steeper than the locomotion slope limit.

### Double and repeated jumps

Set **Max Airborne Jump Count** to the number of extra jumps allowed before landing. Use `0` for no airborne jump, `1` for a double jump, or `-1` for no limit.

When airborne jumps are enabled, use **Airborne Jump Force** and **Airborne Jump Frames** to tune their launch separately from the grounded jump. **Airborne Jump Audio Clip Set** can play feedback for each airborne jump. **Recurrence Delay** sets the minimum wait before Jump can start again, including an airborne jump.

### Takeoff feedback

Assign **Jump Surface Impact** when leaving the ground should trigger a Surface System effect. This is optional and does not change the jump motion.

## How Jump and Fall work together

Pressing the configured Jump input starts the ability when its ceiling, slope, grace-period, airborne-count, and recurrence checks allow it. The Jump Event applies the initial force through its animation event or timer. Holding the input can add the configured hold force, and another press can apply an airborne jump when enabled.

As the character approaches the apex and its vertical velocity reaches **Vertical Velocity Stop Threshold**, Jump stops automatically. The Fall ability can then activate for the downward part of the motion. Landing resets the airborne jump count.

## Verify in Play Mode

1. Stand on level ground with clear space above the character and press Jump. The character should leave the ground, rise, and transition to Fall near the apex.
2. If **Force Hold** is greater than `0`, compare a tap with a held input. Holding should produce more upward movement.
3. Walk from a ledge and press Jump within **Grounded Grace Period**. The jump should still start inside that window.
4. If **Max Airborne Jump Count** is `1`, press Jump once more while airborne. The character should receive one additional launch and should not receive another before landing.
5. Move under a low, flat ceiling within **Min Ceiling Jump Height**. Jump should be prevented.

## Troubleshoot common results

- **The jump animation starts but the character does not rise:** Check whether **Jump Event** is waiting for `OnAnimatorJump`. Add the correct animation event, or disable **Wait For Animation Event** and set an appropriate Duration.
- **Jump does not start:** Check **Input Names**, overhead clearance, the current slope, and **Recurrence Delay**. Correct the input mapping or the setting that is blocking the start.
- **An airborne jump does not occur:** Check **Max Airborne Jump Count** and **Recurrence Delay**. Set the count to at least `1` for a double jump and wait until the recurrence delay has passed.
- **Sideways or backward jumps are unexpectedly low:** Check the corresponding force multiplier and move it closer to `1` if directional movement should retain more of the initial force.

## Related pages

- [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/) handles the downward and landing portion of the airborne flow.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains priority, common Ability settings, and the general API.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains the event and timer modes used by Jump Event.
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) covers the controller's input setup.
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) explains the optional takeoff effect.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-move-towards"></a>

# Move Towards

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)

Move Towards places and faces a character at a precise location before another ability begins. Use it when an interaction, climb, animation, or other action should start from a controlled position, or when gameplay code needs to send the character to a location without starting a follow-up ability.

## Before you begin

- The character must have an **Ultimate Character Locomotion** component.
- For an arrival ability such as Interact, add one or more [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) components to the object that provides the interaction or action point.
- If the character should navigate around obstacles, set up [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) and a baked NavMesh.
- Ensure the character's movement animations can cover the approach speed. With root motion enabled, the animation supplies the visible displacement.

## Add Move Towards

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **Move Towards**.
4. Keep **Start Type** set to **Manual**. Another ability or gameplay code starts Move Towards when a destination is available.
5. Order the abilities from higher to lower in this sequence: pathfinding above Move Towards, then Move Towards above the ability it prepares. For example, place **NavMeshAgent Movement** above **Move Towards** and **Move Towards** above **Interact**. If [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) is also present, keep it above NavMeshAgent Movement.
6. If the character turns too slowly during final alignment, create a [state](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) for Move Towards and increase **Motor Rotation Speed** while that state is active. The demo uses a value of `100`.
7. Choose a destination source and configure the movement and stop settings described below.

## Choose how to supply the destination

### Move before another ability

An ability that requires exact placement supplies an array of Move Towards Location components. Move Towards chooses the closest location, travels to it, stops, and then starts the waiting ability. If the character already satisfies a location's position and rotation thresholds, Move Towards does not need to start.

Place Move Towards above the waiting ability in the **Abilities** list. A waiting ability above Move Towards has higher priority and can cause unintended behavior.

### Move to an independent location

Assign **Independent Move Towards Location** when Move Towards should use one particular component without a waiting ability. Start the ability manually through the locomotion system.

Gameplay code can instead call **MoveTowardsLocation** with a position or with a position and rotation. The position-only overload accepts any final facing direction. Both overloads create an independent location when one has not already been assigned and can update the destination while Move Towards is active.

## Configure the destination

The Move Towards Location component defines where arrival is valid:

- **Offset** and **Yaw Offset** place and face the character relative to the location object's Transform.
- **Size** creates an acceptable area instead of requiring one exact point. **Distance** adds positional tolerance.
- **Angle** controls the accepted facing range. Increase it when exact facing does not matter; reduce it when the following animation must begin from a specific orientation.
- **Require Grounded** prevents arrival until the character is grounded.
- **Precision Start** waits for movement and Animator transitions to settle before the waiting ability begins. Keep it enabled for tightly aligned interactions; disable it when an immediate handoff is more important than a settled pose.
- **Movement Multiplier** scales movement for this location without changing every Move Towards use on the character.

Use the location gizmo in the Scene view to confirm that the target point, valid area, and facing direction match the object the character will use.

## Choose movement and rotation behavior

**Input Multiplier** scales the input Move Towards supplies. The final value also includes the selected location's **Movement Multiplier** and any active Speed Change multiplier.

- Without a pathfinding ability, Move Towards supplies direct input toward the location, limits the final movement to avoid overshooting, and rotates toward the target using the character's **Motor Rotation Speed**.
- With Pathfinding Movement above Move Towards, pathfinding handles the route to the target. Move Towards then checks the location's final position and rotation requirements before completing the handoff.
- With root motion enabled, these input values select and drive movement animation, but the animation's root motion determines the character's visible displacement. Use an animation whose speed matches the intended approach.

Move Towards temporarily takes independent control of looking so it can complete the requested facing. That control is released when the ability stops.

## Choose what happens when movement cannot finish

- **Inactive Timeout** is how long the character may make no positional or rotational progress before Move Towards stops early. The default is `1` second.
- **Moving Target Distance Timeout** is how far the target may move from its starting position before Move Towards stops early. Its default is effectively unlimited.
- **Teleport On Early Stop** is enabled by default. When enabled, an early stop places the character at the target and starts the waiting ability when one is pending. Disable it when teleporting would be visible or when a blocked approach should cancel the action instead.
- **Disable Gameplay Input** sends the gameplay-input event while Move Towards is active, preventing player input from competing with the automatic approach. Input is restored when the ability stops.

## How Move Towards runs

When another ability requests movement, Move Towards selects the closest supplied location. For an independent request, it uses the assigned or script-created location. The ability does not start when the character is already inside the allowed position and rotation thresholds.

If a Pathfinding Movement ability exists above Move Towards, it receives the destination and guides the character along the NavMesh. Move Towards otherwise supplies direct input. Near the destination, it checks the position, grounded requirement, and facing angle, then waits for the precision-start condition when enabled.

After arrival, Move Towards stops its active pathfinding ability, restores gameplay input and normal look control, and starts the waiting ability. A stalled character or a target that exceeds the configured movement limit follows **Teleport On Early Stop** instead.

## Verify in Play Mode

1. Trigger the waiting ability while the character is outside the Move Towards Location's valid area.
2. Confirm **(Active)** appears beside Move Towards in the **Ultimate Character Locomotion** Inspector.
3. If NavMeshAgent Movement is configured above it, confirm the character follows the NavMesh toward the destination. Without pathfinding, confirm the character approaches directly.
4. Confirm the character reaches the location's allowed position, becomes grounded when required, and turns inside the configured **Angle**.
5. With **Precision Start** enabled, confirm the movement pose settles before the waiting ability starts.
6. For a root-motion character, confirm the intended approach animation plays and its motion reaches the location without sliding.
7. Block the route long enough to exceed **Inactive Timeout** and verify that the result matches **Teleport On Early Stop**.
8. Move the target beyond **Moving Target Distance Timeout** and confirm the same early-stop policy is applied.

## Troubleshoot Move Towards

- **The waiting ability starts before the character is aligned:** check that it returns the intended Move Towards Location, place Move Towards above that ability, enable **Precision Start**, and reduce the location's **Distance** or **Angle** as needed.
- **A path is never used:** confirm the NavMesh is baked, the character and destination are on it, and NavMeshAgent Movement is above Move Towards in the list.
- **The character reaches the point but turns too slowly:** check the Move Towards state and increase **Motor Rotation Speed** while it is active.
- **The character overshoots or slides around the point:** check that the movement animation matches the requested input, reduce **Input Multiplier** or the location's **Movement Multiplier**, and increase **Distance** slightly when an exact point is unnecessary.
- **The character stops after one second:** it is not producing position or rotation progress. Check collision, the path, movement animation, and rotation speed, then increase **Inactive Timeout** only if the approach legitimately pauses.
- **The character unexpectedly teleports:** disable **Teleport On Early Stop** or correct the obstruction, movement timeout, or moving-target limit that caused the early stop.
- **Player input changes the approach:** enable **Disable Gameplay Input** when the automatic movement should have exclusive control.
- **A root-motion character does not move faster after increasing Input Multiplier:** use a faster root-motion animation at the resulting movement input; the multiplier does not change the distance embedded in the clip.

## Related topics

- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) defines the valid arrival position and rotation.
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) provides obstacle-aware pathfinding and must remain above Move Towards.
- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) can scale the approach input and must remain above NavMeshAgent Movement when both are present.
- [Interact](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/) is a common example of an ability that waits for precise placement.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains list priority, manual activation, and the shared ability lifecycle.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains temporary property changes such as a faster Motor Rotation Speed.

## Developer reference

The Move Towards ability can be started through script with the **MoveTowardsLocation** method. This example supplies a position; the position-only overload accepts any final rotation.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;

public class MyObject : MonoBehaviour
{
    [Tooltip("The character that should move towards the destination.")]
    [SerializeField] protected GameObject m_Character;
    [Tooltip("The destination that the character should move towards.")]
    [SerializeField] protected Vector3 m_Destination;

    /// <summary>
    /// Starts moving to the destination.
    /// </summary>
    private void Start()
    {
        var characterLocomotion = m_Character.GetComponent<UltimateCharacterLocomotion>();
        characterLocomotion.MoveTowardsAbility.MoveTowardsLocation(m_Destination);
    }
}
```

The current runtime surface includes:

- **MoveTowardsLocation(Vector3):** starts or updates movement to a position and accepts any final rotation.
- **MoveTowardsLocation(Vector3, Quaternion):** starts or updates movement to a position and rotation.
- **StartMoving(MoveTowardsLocation[], Ability):** chooses the closest location and returns whether Move Towards started for the waiting ability.
- **StartLocation** and **OnArriveAbility:** expose the selected location and waiting ability while the workflow is active.
- **InputMultiplier**, **InactiveTimeout**, **MovingTargetDistanceTimeout**, **TeleportOnEarlyStop**, **DisableGameplayInput**, and **IndependentMoveTowardsLocation:** expose the Inspector configuration.
- **OnEnableGameplayInput:** is sent with `false` and then `true` when **Disable Gameplay Input** is enabled.
- **OnCharacterForceIndependentLook:** is sent while Move Towards owns final facing and again when that control is released.
- **OnCharacterAbilityActive:** lets Move Towards track an active Speed Change and include its multiplier in the generated input.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-move-with-object"></a>

# Move With Object

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-with-object/)

Move With Object keeps the character at the same relative position and rotation as a selected moving object. Use it when the character must follow an object even when ordinary grounded moving-platform detection should not control the relationship.

## Before you begin

- The character must have an **Ultimate Character Locomotion** component.
- Add the **Kinematic Object** component to the exact target Transform that will be assigned to the ability. Move With Object rejects a target without this component.
- Set up the target's movement before connecting it to the character. **Kinematic Object** registers externally moved objects with the Simulation Manager so their motion can remain synchronized.

For a floor, elevator, or other surface that the character simply stands on, use the normal [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) workflow. Move With Object is for an explicit target relationship that overrides normal ground-based platform selection.

## Add Move With Object

1. Select the GameObject that the character should follow.
2. In the Inspector, select **Add Component** and add **Kinematic Object** to that same GameObject.
3. Select the character GameObject.
4. In the **Ultimate Character Locomotion** component, expand **Abilities**.
5. Select the plus button and add **Move With Object**.
6. Keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Automatic**.
7. For a fixed scene relationship, drag the target Transform into **Target**. For a relationship chosen during gameplay, leave **Target** empty and assign it at runtime.

Move With Object is concurrent and has no special list-order requirement. It can remain active while the character uses normal locomotion and other compatible abilities.

## Choose how to use the target

### Follow one known object

Assign a scene object to **Target** in the Inspector when the character should follow it as soon as the scene begins. Because the ability starts automatically, a valid assigned target activates Move With Object in Play Mode without an input binding.

### Attach and detach during gameplay

Leave **Target** empty when an interaction, animation, or gameplay system decides when the relationship begins. Set the **Target** property to a Transform with **Kinematic Object** to attach, then set it to `null` to detach. The automatic stop waits for the target to become null.

If the character should switch directly between two moving objects, assign the new valid target while the ability is active. The locomotion system immediately records the character's relationship to the replacement target.

### Use an ability-owned relationship

Some detected-object and detected-ground abilities expose their own **Move With Object** setting. Use that setting when the relationship should exist only for that ability's lifetime. Use the standalone Move With Object ability when another gameplay system owns the target and attachment timing.

## How Move With Object runs

The automatic start check succeeds only while **Target** is not null. When the ability starts, it calls the character locomotion system's moving-platform workflow with an override, storing the character's position and rotation relative to the target.

Each locomotion update adds the target's movement and rotation changes to the character. The override prevents ordinary ground detection from replacing the selected target, while the concurrent ability allows the character's own movement and compatible abilities to continue relative to that object.

Setting **Target** to `null` allows the automatic stop. Stopping clears the moving-platform override and returns ownership to normal ground detection. The character's **Stick To Moving Platform**, **Moving Platform Disconnect Movement Multiplier**, and **Moving Platform Force Damping** settings determine how platform motion is handled around separation.

## Verify in Play Mode

1. Start with a valid **Target** assigned or assign one through the gameplay system.
2. In the **Ultimate Character Locomotion** Inspector, confirm **(Active)** appears beside Move With Object.
3. Translate the target and confirm the character preserves its relative position.
4. Rotate the target and confirm the character follows the expected platform rotation without drifting.
5. Move the character while the target is moving and confirm normal locomotion remains available relative to the target.
6. Assign a second valid target and confirm the character begins following it without first needing to stop the ability.
7. Set **Target** to `null`. Confirm Move With Object becomes inactive and later target movement no longer carries the character.

## Troubleshoot Move With Object

- **The ability never becomes active:** check that **Enabled** is selected, **Start Type** is **Automatic**, and **Target** is assigned.
- **The Console reports that the target does not have Kinematic Object:** add **Kinematic Object** to the exact Transform assigned to **Target**. A component on a parent or child does not satisfy the target check.
- **The character jitters while following the object:** confirm the assigned Transform has **Kinematic Object** and is not being moved by multiple competing systems.
- **The character follows only while standing on the object:** confirm Move With Object is active. A character that follows only while grounded is using normal moving-platform detection rather than the explicit override.
- **The ability stops and immediately starts again:** clear **Target** before force-stopping it. A non-null target continues to satisfy the automatic start condition.
- **The wrong object carries the character:** check which system last assigned **Target** or called the locomotion moving-platform API, then give one system ownership of the relationship.
- **The character keeps too much or too little motion after detaching:** review **Stick To Moving Platform**, **Moving Platform Disconnect Movement Multiplier**, and **Moving Platform Force Damping** on Ultimate Character Locomotion.

## Related topics

- [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/) covers automatic ground-based platform movement and platform components.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains automatic start and stop types, concurrent abilities, and runtime activation.
- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) includes an ability-owned **Move With Object** option for detected objects.
- [Detect Ground Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-ground-ability-base/) includes the equivalent option for a detected ground object.

## Developer reference

Retrieve Move With Object from **UltimateCharacterLocomotion** and assign its **Target** property. Assigning a Transform without **Kinematic Object** logs a Console message and resets the target to null.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;

public class MoveWithTarget : MonoBehaviour
{
    [SerializeField] private UltimateCharacterLocomotion m_CharacterLocomotion;
    [SerializeField] private Transform m_Target;

    public void Attach()
    {
        var moveWithObject = m_CharacterLocomotion.GetAbility<MoveWithObject>();
        moveWithObject.Target = m_Target;
    }

    public void Detach()
    {
        var moveWithObject = m_CharacterLocomotion.GetAbility<MoveWithObject>();
        moveWithObject.Target = null;
    }
}
```

The runtime behavior is intentionally small:

- **Target** validates the assigned Transform and changes the active moving-platform override when the target changes.
- **CanStartAbility** requires a non-null target.
- **CanStopAbility** allows the automatic stop after the target becomes null; a forced stop can occur at any time.
- **AbilityStarted** calls `SetMovingPlatform(Target, true)`.
- **AbilityStopped** calls `SetMovingPlatform(null, false)`.
- **IsConcurrent** returns `true`.

Move With Object does not send a feature-specific event. Use the shared ability lifecycle or observe the **Target** property when another system needs attachment state.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-navmeshagent-movement"></a>

# NavMeshAgent Movement

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)

NavMeshAgent Movement converts a Unity NavMeshAgent path into input and rotation for Ultimate Character Locomotion. Use it for AI, point-and-click movement, or any character that should follow a baked NavMesh while retaining UCC collision, animation, abilities, and root motion.

The NavMeshAgent calculates the path, but Ultimate Character Locomotion moves the character. The ability keeps the agent synchronized with the character rather than allowing the agent to update the Transform directly.

## Before you begin

- Build an active NavMesh that includes the character's starting position and intended destination.
- Place the character on that NavMesh.
- Ensure the character already has an **Ultimate Character Locomotion** component.
- Add [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) and [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/) if the agent should traverse jump links.

## Add NavMeshAgent Movement

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **NavMeshAgent Movement**. Its required **NavMeshAgent** component is added when needed.
4. Select the ability and keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Manual**.
5. If the character also uses [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/), drag **Speed Change above NavMeshAgent Movement**. Pathfinding Movement already applies the active multiplier when it writes the character input; placing Speed Change below it would multiply that input again.
6. Configure **Auto Enable**, **Rotation Override**, **Arrived Distance**, airborne movement, and off-mesh link settings.
7. Set a destination through gameplay code or another controlling system, then verify the path in Play Mode.

## Choose destination and enable behavior

**Auto Enable** controls what happens when **SetDestination** is called on a disabled ability.

- Keep it enabled when assigning a destination should enable the ability and NavMeshAgent automatically.
- Disable it when another AI state or gameplay system owns ability activation. In this mode, a destination request fails while the ability is disabled.

**SetDestination** updates the destination of an active agent. If the ability is inactive, it enables the agent when allowed, verifies that the agent is on a NavMesh, sets the path, and starts the ability. The call returns whether the destination was accepted.

**Arrived Distance** is the remaining-distance threshold used by **HasArrived** and the stop check. The default is **0.2**.

- Increase it when the character only needs to approach the target or oscillates while trying to reach an exact point.
- Decrease it when interactions require tighter placement, while leaving enough tolerance for the character collider and path resolution.

## Choose rotation control

**Rotation Override** determines which system supplies facing while following the path:

- **No Override:** use the NavMeshAgent's **updateRotation** setting.
- **NavMesh:** face along the NavMesh path even when agent rotation would otherwise be disabled.
- **Character:** preserve the character's own rotation so another movement type, look source, or ability can control facing.

Use **SetDestinationRotation** when the character should adopt a specific rotation after arriving. The ability continues to use path-facing behavior while it is still traveling.

## Choose speed and airborne behavior

Pathfinding Movement reads an active Speed Change multiplier and applies it when writing the input vector. Keep Speed Change above this ability in the list so Speed Change does not process the generated input a second time.

For a root-motion character, the NavMeshAgent's speed does not directly determine visible displacement. Use Speed Change and matching movement animations so the Animator selects the intended walking, running, or sneaking motion.

**Allow Movement In Air** is inherited from Pathfinding Movement:

- Keep it enabled when the agent should continue supplying planar input while airborne.
- Disable it when airborne abilities should own movement and rotation until the character lands.

## Configure off-mesh links

NavMeshAgent Movement disables the agent's automatic link traversal and coordinates supported links with UCC:

- **Manual Off Mesh Link Name** identifies the NavMesh area used for a manually authored jump link. The default is **Jump**.
- Enable **Jump Across Manual Off Mesh Link** when a manual link in that area should start the character's Jump ability.
- Built-in jump-across links can also start Jump. The ability waits when Fall is already active instead of starting another jump.
- Drop-down links complete after the character becomes grounded.

Confirm the NavMesh link type, area name, and landing surface match the ability settings.

## How NavMeshAgent Movement runs

The ability can start while its NavMeshAgent is on a NavMesh. Setting a destination supplies or updates the path, then the ability translates the agent's desired velocity into the character's two-dimensional input. Input larger than a magnitude of one is normalized, while smaller values are preserved so the character can slow near the destination.

Each update also computes the requested rotation. Ultimate Character Locomotion applies movement and collision, and the ability synchronizes **NavMeshAgent.nextPosition** to the resulting character position during Late Update. Near the destination, it limits final movement so the character does not repeatedly overshoot the target.

**HasArrived** becomes true when the path is no longer pending and the remaining distance is at or below **Arrived Distance**. The default stop type is manual, so reaching the destination does not by itself require the ability to disappear from the active list; the controlling AI can query arrival, assign another destination, stop the ability, or disable it.

Teleport, landing, death, and respawn events keep the NavMeshAgent position, links, and rotation state synchronized with the character.

## Verify in Play Mode

1. Confirm the character begins on the baked NavMesh and the NavMeshAgent is enabled.
2. Keep the **Ultimate Character Locomotion** Inspector visible, assign a reachable destination, and confirm **(Active)** appears beside NavMeshAgent Movement.
3. Confirm a path is created and the character follows it without the NavMeshAgent moving the Transform independently.
4. Observe the character slowing or stopping within **Arrived Distance**, then confirm **HasArrived** reports true.
5. Test each **Rotation Override** option used by the game and confirm the character faces from the intended source.
6. Activate Speed Change with Speed Change above this ability and confirm the path input is scaled once.
7. Traverse a configured jump or drop link and confirm Jump, Fall, landing, and path continuation occur in order.
8. Teleport or respawn the character and confirm the NavMeshAgent resumes from the new position rather than the previous path position.

## Troubleshoot NavMeshAgent Movement

- **SetDestination returns false:** confirm the character and destination are on the baked NavMesh. If the ability is disabled, enable **Auto Enable** or enable the ability before the call.
- **The character has a destination but does not move:** check that the NavMeshAgent has a valid, non-pending path, is not stopped, and is farther than **Arrived Distance** from the destination.
- **The character moves too fast when Speed Change is active:** place Speed Change above NavMeshAgent Movement. The pathfinding base already applies its active multiplier.
- **Changing NavMeshAgent speed does not affect root-motion movement:** configure Speed Change and movement animations with the required root-motion speed.
- **The character faces the wrong direction:** choose the appropriate **Rotation Override** and check the NavMeshAgent's **updateRotation** value when using **No Override**.
- **The agent will not cross a jump link:** confirm Jump and Fall exist, **Jump Across Manual Off Mesh Link** is enabled when required, and **Manual Off Mesh Link Name** matches the link area.
- **Airborne input stops unexpectedly:** enable **Allow Movement In Air**, or confirm that the intended airborne ability supplies its own movement.
- **The agent jitters near the target:** increase **Arrived Distance** and confirm the destination is reachable at the character collider's scale.
- **The agent returns to an old location after teleport or respawn:** confirm the immediate-transform and respawn events reach the character's UCC components.

## Related topics

- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) configures the active pathfinding speed multiplier and must remain above this ability.
- [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) and [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/) handle supported airborne link traversal.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains list update order, automatic and manual activation, and runtime state.
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains movement blend trees and root-motion animation setup.

## Developer reference

Retrieve the ability from **UltimateCharacterLocomotion** and call **SetDestination**. The method returns `false` when the disabled ability cannot auto-enable, the agent is not on a NavMesh, or the agent rejects the destination.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities.AI;

public class MyObject : MonoBehaviour
{
    [Tooltip("The character whose NavMeshAgent Movement ability should receive the destination.")]
    [SerializeField] protected GameObject m_Character;
    [Tooltip("The NavMeshAgent destination.")]
    [SerializeField] protected Vector3 m_Destination;

    /// <summary>
    /// Sets the NavMeshAgentMovement destination.
    /// </summary>
    private void Start()
    {
        var characterLocomotion = m_Character.GetComponent<UltimateCharacterLocomotion>();
        var navMeshAgentMovement = characterLocomotion.GetAbility<NavMeshAgentMovement>();
        navMeshAgentMovement.SetDestination(m_Destination);
    }
}
```

The current runtime surface includes:

- **SetDestination(Vector3):** sets or updates the path and returns whether it was accepted.
- **GetDestination():** returns the current destination.
- **HasArrived:** reports a completed path inside **Arrived Distance**.
- **SetDestinationRotation(Quaternion):** sets the desired facing at the destination.
- **Teleport(Vector3):** warps the NavMeshAgent to a new position.
- **InputVector** and **DeltaRotation:** expose the pathfinding output consumed by Ultimate Character Locomotion.
- **OnCharacterAbilityActive:** tracks the active Speed Change multiplier.
- **OnCharacterImmediateTransformChange:** warps the agent after a character teleport.
- **OnCharacterGrounded**, **OnDeath**, and **OnRespawn:** synchronize links, agent rotation, and agent position with character state.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-quick-start"></a>

# Quick Start

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-start/)

Quick Start plays a dedicated first-step animation when a grounded character begins moving from rest. Use it when walking, running, strafing, or turning should have an authored start instead of blending directly from idle into the normal locomotion loop.

Quick Start selects an Animator variation; it does not add force or make the character move faster. The character continues to use its normal locomotion input, motor, gravity, and root-motion configuration while the start animation plays.

## Before you begin

- The character needs **Ultimate Character Locomotion**, an **Animator Monitor**, and an Animator Controller with the standard `AbilityIndex`, `AbilityChange`, and `AbilityIntData` parameters.
- The Animator Controller needs a Quick Start state or sub-state machine that recognizes **Ability Index Parameter** `6` and the direction value described below.
- Every start clip that can play must send `OnAnimatorStartMovementComplete`. Quick Start has no duration fallback and cannot stop normally until this event arrives.
- Test ordinary grounded movement first. Quick Start does not activate while the character is airborne.

## Add Quick Start to the character

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities**, select the plus button, and add **Quick Start**.
3. Move Quick Start near the bottom of the list, below gameplay abilities that must take priority. It is nonconcurrent, so placing it too high can prevent a lower row from starting until the start animation completes.
4. Keep **Speed Change** above Quick Start when Speed Change supplies the larger input values used to select the run-start animations. Ability rows update from top to bottom.
5. Keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Automatic**. Do not add an Input Name.
6. Keep **Ability Index Parameter** at `6` when using the shipped Version 3 Animator setup, or update both this value and the custom Animator transition conditions together.
7. Start with **Max Input Count** at its default of `10` and **Speed Change Threshold** at its default of `1`.
8. Keep **Allow Positional Input** and **Allow Rotational Input** enabled unless the start clip deliberately takes complete control. Quick Start does not override gravity, root-motion position, or root-motion rotation by default.

Keep Quick Start, Quick Stop, and Quick Turn together near the bottom, with Idle below the movement-transition abilities. Higher-priority gameplay abilities can then replace Quick Start immediately instead of waiting for its completion event.

## Set up the start animations

1. Open **Window > Animation > Animator** and locate or create the start-movement state or sub-state machine.
2. Enter that flow when `AbilityIndex` equals `6`. Use `AbilityChange` with the entry condition when the state must respond as soon as Quick Start becomes the selected ability.
3. Use `AbilityIntData` to select the walk or run clip for the current direction. The shipped mapping is listed below.
4. Keep each start clip non-looping and transition from it into the matching normal locomotion state.
5. Open each reachable clip in **Window > Animation > Animation** and add an Animation Event near the intended handoff frame.
6. Set the event **Function** to `ExecuteEvent` and its String value to `OnAnimatorStartMovementComplete`. The spelling and capitalization must match exactly.
7. Repeat the event setup for every first-person or third-person clip that can drive this ability, then test every reachable direction.

The 16 shipped Version 3 start clips already contain `OnAnimatorStartMovementComplete`. Replaced or project-specific clips must preserve that event.

## Key choices

### Choose the walk and run threshold

**Speed Change Threshold** compares each processed locomotion-input axis with the configured value. An axis must be strictly greater than the positive threshold or less than its negative equivalent to select a run variation; otherwise Quick Start selects the corresponding walk variation.

The default threshold is `1`. With normal input values of `-1` through `1`, this selects walk starts. The default Speed Change multiplier raises a full input axis to `-2` or `2`, allowing Quick Start to select the run set when Speed Change updates first.

- Keep **Speed Change** above Quick Start when it defines walk versus run.
- Lower the threshold when analog input within the usual `-1` to `1` range should select run starts without Speed Change.
- Match the threshold to the values visible in `HorizontalMovement` and `ForwardMovement`, not to world-space velocity.
- Test diagonal input because both processed axes participate in the turn-variant choice.

### Match the direction data to the Animator

Quick Start exposes the selected variation through `AbilityIntData`:

| Start direction | Walk value | Run value |
| --- | ---: | ---: |
| Forward | `1` | `9` |
| Forward and turn left | `2` | `10` |
| Forward and turn right | `3` | `11` |
| Strafe left | `4` | `12` |
| Strafe right | `5` | `13` |
| Backward | `6` | `14` |
| Backward and turn left | `7` | `15` |
| Backward and turn right | `8` | `16` |

These directions come from the input vector produced by the active Movement Type. They are not calculated from the character's world-space velocity. A custom Animator can support only the directions the project needs, but every value that can be produced still needs a valid transition or fallback.

### Control how soon another start can play

**Max Input Count** is the size of the recent grounded-movement input history. While the character is stopped, one stored sample is removed on each inactive update. Quick Start does not rearm if movement resumes before that history reaches zero.

- Increase the value when tiny pauses or noisy input should not replay a start animation.
- Decrease it when a shorter, deliberate stop should be enough to play another start.
- Keep the value positive. The default of `10` is a useful starting point for filtering brief stop-and-start changes.

This setting is a restart filter, not the number of frames in the start animation and not a delay before the first movement begins.

### Use in-place or root-motion clips

Quick Start leaves positional input and rotational input enabled and makes no root-motion override by default.

- For an in-place start clip, the normal character motor continues to move the character while the Animator supplies the pose.
- For a root-motion start clip, use the character's normal root-motion setup and verify that the authored displacement blends cleanly into locomotion.
- Do not use **Speed Change Threshold** to tune physical acceleration. It only chooses between animation variants.

## How Quick Start runs

Ultimate Character Locomotion evaluates automatic abilities in list order. Quick Start can begin only when it is enabled, the character is grounded, the processed input is nonzero, no higher-priority nonconcurrent ability blocks it, and the stored-input restart filter has cleared.

When it starts, Quick Start reads the processed horizontal and forward input, assigns the matching walk or run direction to `AbilityIntData`, clears its stored history, and marks itself ineligible to start again until the character reports that it has stopped. Animator Monitor then exposes **Ability Index** `6` and the selected **Ability Int Data** value to the Animator.

Because **Stop Type** is **Automatic**, the controller tries to stop Quick Start on each update. `CanStopAbility` remains false until `OnAnimatorStartMovementComplete` arrives. The completion event permits the next automatic stop, after which the regular locomotion state takes over. A higher-priority nonconcurrent ability can force-stop Quick Start before that event.

When a stored-input ability stops, it resets the shared stored-input history used by Quick Start, Quick Stop, and Quick Turn. Leaving the ground or performing an immediate transform change also clears that history so stale movement samples do not trigger a transition later.

## Verify in Play Mode

1. Keep **Ultimate Character Locomotion** and the Animator **Parameters** tab visible. Begin from a grounded, stationary character.
2. Press forward without Speed Change. Confirm Quick Start displays **(Active)**, `AbilityIndex` becomes `6`, `AbilityIntData` becomes `1`, and the walk-forward start clip plays.
3. Confirm the clip sends `OnAnimatorStartMovementComplete`, Quick Start becomes inactive, and the Animator blends into normal forward locomotion.
4. Stop long enough for the stored-input history to clear, hold the Speed Change input, and move forward again. With Speed Change above Quick Start, confirm `AbilityIntData` becomes `9` and the run-forward start plays.
5. Repeat with backward, strafe, and diagonal input. Confirm the data values and clips match the table.
6. Make a very brief stop and resume movement. Confirm Quick Start does not replay while stored input remains. Then stop longer and confirm it can play again.
7. Start a higher-priority action while Quick Start is active and confirm that action replaces it immediately.
8. If the project supports both in-place and root-motion characters, verify that neither setup gains an unintended speed burst or foot slide at the handoff.

## Troubleshoot Quick Start

| Symptom | Check | Fix |
| --- | --- | --- |
| Quick Start never becomes active. | Confirm **Enabled**, **Start Type: Automatic**, grounded state, nonzero processed input, and that no higher-priority nonconcurrent ability remains active. | Restore the defaults, test from a complete stop, and resolve the active higher-priority ability. |
| Quick Start activates, but no start animation plays. | Watch `AbilityIndex` and `AbilityIntData`. The Animator may not have a transition for index `6` and the selected direction value. | Match **Ability Index Parameter** and every reachable data value to the custom Animator transitions. |
| The walk start plays while Speed Change is active. | The processed input may not exceed **Speed Change Threshold**, or Speed Change may be below Quick Start and update afterward. | Move Speed Change above Quick Start and compare the live movement parameters with the threshold. |
| The wrong direction animation plays. | The Animator mapping may not match the shipped data table, or the Movement Type may transform input differently than expected. | Inspect `HorizontalMovement`, `ForwardMovement`, and `AbilityIntData`, then correct the transition conditions. |
| Quick Start remains active after the clip ends. | The active clip may not send the exact completion event. There is no duration fallback. | Add an event with **Function: ExecuteEvent** and String `OnAnimatorStartMovementComplete` to every reachable clip. |
| Quick Start replays after tiny pauses. | **Max Input Count** may be too small, or the input dead zone may repeatedly report moving and stopped. | Increase Max Input Count and correct the input dead zone so deliberate stops are distinct from noise. |
| Quick Start does not replay after a deliberate stop. | The stored input history may not have drained before movement resumed. | Wait through a complete stop or reduce Max Input Count carefully. |
| A gameplay ability cannot start during the first-step animation. | Quick Start may be above that nonconcurrent ability in the list. | Move Quick Start near the bottom so the gameplay ability has the lower list index and higher priority. |
| The pose plays, but movement speed or displacement is wrong. | Quick Start does not change speed and does not force a root-motion mode. | Correct the locomotion speed, Speed Change setup, clip root motion, or character root-motion setting rather than the direction threshold. |
| Quick Start does not play while airborne. | Stored Input Ability Base requires the character to be grounded. | Use Fall, Jump, or a project-specific airborne ability for that transition instead. |

## Related tasks

- [Quick Stop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-stop/) plays the matching authored transition when movement ends.
- [Quick Turn](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-turn/) handles a sharp direction change while the character is moving.
- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) supplies the multiplied input that the default threshold uses to distinguish run starts.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains automatic activation, nonconcurrent priority, list order, and the runtime active indicator.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains `AbilityIndex`, `AbilityChange`, `AbilityIntData`, and the movement parameters.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the shipped Version 3 ability indices.
- [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) covers preserving events when start clips are changed.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains the **ExecuteEvent** and String workflow used by UCC animation events.

## Developer reference

Quick Start has these released Version 3 defaults and runtime rules:

- **Start Type:** `Automatic`; **Stop Type:** `Automatic`; **Ability Index Parameter:** `6`; **Concurrent:** `False`.
- **Max Input Count:** `10`; **Speed Change Threshold:** `1`.
- **Allow Positional Input** and **Allow Rotational Input:** enabled. Gravity, root-motion position, and root-motion rotation use `No Override`.
- `StoredInputAbilityBase` stores raw grounded movement input, clears it while stopped, and rejects starts while ungrounded. Quick Start performs its final direction selection from the processed `InputVector`.
- `OnCharacterMoving(false)` rearms Quick Start. It starts only with a nonzero processed input and only after its stored input count has reached zero.
- `AbilityIntData` returns one of the 16 walk/run direction indices in the table. Quick Start does not expose a feature-specific float value.
- `OnAnimatorStartMovementComplete` sets the internal completion flag. Automatic stopping succeeds only after that flag is set; a forced stop bypasses it.
- `OnCharacterGrounded(false)`, `OnCharacterImmediateTransformChange`, and `OnStoredInputAbilityResetStoredInputs` clear the inherited input history.
- The shared `OnCharacterAbilityActive` event reports Quick Start starting and stopping. When it stops, Stored Input Ability Base sends `OnStoredInputAbilityResetStoredInputs` so the other stored-input abilities also discard their history.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-quick-stop"></a>

# Quick Stop

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-stop/)

Quick Stop plays a planted or decelerating animation when a grounded character releases movement input. Use it when moving directly into the idle blend feels too abrupt. The ability chooses an animation from the character's recent direction and speed; it does not brake the character or apply movement force.

## Before you begin

- The character needs an Ultimate Character Locomotion component and an Animator Monitor.
- The Animator Controller needs Quick Stop states that use **Ability Index** `7` and the **Ability Int Data** values listed below.
- Each stop animation needs an Animation Event that sends `OnAnimatorStopMovementComplete`. Quick Stop has no duration fallback while the character remains stationary.
- Quick Stop only records movement while the character is grounded.

## Add Quick Stop

1. Select the character and open **Ultimate Character Locomotion**.
2. Expand **Abilities**, select **+**, and add **Quick Stop**.
3. Place Quick Stop near the bottom of the ability list so more important gameplay abilities have higher priority. A useful order is **Speed Change**, **Quick Start**, **Quick Stop**, **Quick Turn**, then **Idle**.
4. Keep **Start Type** and **Stop Type** set to **Automatic**. Quick Stop does not need an input name.
5. Set **Ability Index** to `7` when using the supplied Animator Controller.
6. Start with the source defaults: **Max Input Count** `10`, **Speed Change Threshold** `1`, **Stop Threshold** `0.01`, and **Required Start Success Count** `2`.
7. Leave **Allow Positional Input** and **Allow Rotational Input** enabled unless the stop animation is designed to control those values. The ability does not override gravity, root-motion position, or root-motion rotation by default.

## Configure the Animator

Quick Stop starts with **Ability Int Data** `0` while it confirms that the character really stopped. After confirmation, it publishes one of these values so the Animator can select the matching stop animation:

| Ability Int Data | Stop direction |
| ---: | --- |
| `1` | Walk Forward |
| `2` | Walk Forward Turn Left |
| `3` | Walk Forward Turn Right |
| `4` | Walk Strafe Left |
| `5` | Walk Strafe Right |
| `6` | Walk Backward |
| `7` | Walk Backward Turn Left |
| `8` | Walk Backward Turn Right |
| `9` | Run Forward |
| `10` | Run Forward Turn Left |
| `11` | Run Forward Turn Right |
| `12` | Run Strafe Left |
| `13` | Run Strafe Right |
| `14` | Run Backward |
| `15` | Run Backward Turn Left |
| `16` | Run Backward Turn Right |

Do not enter a stop animation for value `0`; it is the confirmation state. Keep the stop clips non-looping and add an Animation Event with **Function** `ExecuteEvent` and **String** `OnAnimatorStopMovementComplete`. The supplied controller includes walk and run clips for every direction, with left- and right-foot variants.

## Choose the stopping behavior

### Stop sensitivity

**Stop Threshold** is compared with the squared magnitude of the current raw input. Its default of `0.01` requires input to be very close to zero. Increase it if a controller dead zone prevents Quick Stop from starting, or reduce it if the ability starts while the player is still intentionally moving.

**Required Start Success Count** keeps **Ability Int Data** at `0` for a short confirmation period. The default of `2` gives Quick Turn time to recognize a direction reversal instead of immediately playing a stop. A value of `0` selects the stop animation immediately; larger values add more confirmation time.

### Direction and walk/run selection

**Max Input Count** controls how many recent grounded input samples are averaged. A larger history produces a steadier direction but reacts more slowly to a late direction change. A smaller history follows recent input more closely but can be more sensitive to noisy input.

**Speed Change Threshold** separates the walk and run variants. The default is `1`, and a component must exceed that value to select the corresponding run direction. Keep [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) above Quick Stop so its active multiplier is included in the stored movement input. If analog input never exceeds the threshold, lower it to match the character's configured input range.

### Movement during the animation

Quick Stop selects an Animator state but does not slow or reposition the character. The locomotion motor, root-motion settings, and stop clip determine the visible displacement. Match the clip and root-motion configuration if the character slides or travels too far.

## How it runs

While inactive, Quick Stop stores recent grounded movement input. It can start automatically after meaningful movement when the current input is moving toward zero and its squared magnitude reaches **Stop Threshold**.

During the confirmation period, the ability remains active with **Ability Int Data** `0` and checks that the stop is still valid. Once confirmed, it averages the stored input, chooses the walk or run direction, and updates the Animator parameters. New movement input cancels the stop, which allows a direction reversal to continue into Quick Turn. The animation event completes a stationary stop.

After a confirmed Quick Stop ends, the shared recent-input history is cleared. If it cancels during confirmation, that history remains available so another stored-input ability can evaluate the same movement change.

## Verify in Play Mode

1. Open the Animator window and watch **Ability Index**, **Ability Int Data**, and the active ability list on Ultimate Character Locomotion.
2. Walk forward, release input, and confirm that Quick Stop activates with data `0`, changes to `1` after the confirmation period, plays once, and stops after `OnAnimatorStopMovementComplete`.
3. Run forward with Speed Change active, release input, and confirm that the data changes to `9` instead of `1`.
4. Repeat from backward and strafe movement. Confirm that the values match the table and that each state uses the intended clip.
5. Reverse direction quickly. Quick Stop should cancel before selecting a stop clip, allowing Quick Turn to handle the reversal.
6. Press movement during a stop. The ability should end immediately and locomotion should resume.
7. Start a higher-priority gameplay ability while stopping and confirm that its animation can take priority.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Quick Stop never starts | The character is grounded, has recent movement history, and raw input reaches **Stop Threshold**. | Test after sustained grounded movement. Adjust the input dead zone or raise **Stop Threshold** slightly if released input never reaches the default. |
| The ability is active with data `0` | The confirmation period has not completed, or input resumed before it could complete. | Briefly seeing `0` is expected. Check **Required Start Success Count** and confirm that released input stays below **Stop Threshold**. |
| A run uses a walk stop | **Speed Change** is above Quick Stop and the stored input exceeds **Speed Change Threshold**. | Correct the ability order or tune the threshold for the configured input multiplier. |
| The wrong directional clip plays | The Animator's **Ability Int Data** conditions match the direction table. | Correct the transition value. If input changed just before release, tune **Max Input Count** to change how much history is averaged. |
| Quick Stop starts too early or too late | **Stop Threshold** is compared with squared raw-input magnitude. | Lower the value for a stop nearer zero, or raise it for an earlier stop. |
| Quick Stop wins instead of Quick Turn | The abilities are adjacent near the bottom and **Required Start Success Count** is not too low. | Restore the default confirmation count of `2`, then verify the Quick Turn setup and ordering. |
| The ability stays active after the clip ends | The clip or an interruption path did not send `OnAnimatorStopMovementComplete`, and the character remained stationary. | Add the exact event to every reachable stop clip. If a transition can leave early, ensure that path also sends the completion event. |
| The character slides during the stop | Quick Stop does not apply braking force. | Match the clip to the character's root-motion and locomotion settings. |
| Other gameplay abilities cannot start cleanly | Quick Stop is too high in the ability list. | Move it near the bottom, below abilities that should take priority. |

## Related tasks

- [Quick Start](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-start/) adds a directional start animation before regular locomotion.
- [Quick Turn](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-turn/) handles rapid movement reversals.
- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) supplies the multiplied input used to distinguish walk and run stops.
- [Idle](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/idle/) runs after the character has remained still for its configured delay.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains **Ability Index**, **Ability Int Data**, and the other runtime parameters.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains event-driven and duration-based animation completion patterns.

## Developer reference

Quick Stop derives from `StoredInputAbilityBase`. Player-controlled characters store processed `InputVector` history but test the current `RawInputVector` for the stop; AI-controlled characters with a local look source store raw history and test the processed input when checking whether movement is decreasing. The stored average must also have a squared magnitude of at least `0.01`, which prevents a stop from starting without meaningful prior movement.

The ability stops when it receives `OnAnimatorStopMovementComplete` or when current input has a squared magnitude greater than `0.001`. Its `CanStopAbility` implementation uses those conditions even for a forced stop request, so every Animator interruption path should still deliver the completion event when the character can remain stationary. Start and stop are also reported through the standard `OnCharacterAbilityActive` event.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-quick-turn"></a>

# Quick Turn

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-turn/)

Quick Turn plays an authored turn when a grounded character makes a strong reversal, such as changing directly from forward to backward movement. Use it when the character should visibly plant and rotate instead of instantly changing direction. It is intended for movement styles such as the [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) view type; strafe and top-down movement usually do not need it.

## Before you begin

- The character needs an Ultimate Character Locomotion component and an Animator Monitor.
- The Animator Controller needs Quick Turn states that use **Ability Index** `8`, **Ability Float Data**, and **Leg Index** as described below.
- Each turn clip needs an Animation Event that sends `OnAnimatorQuickTurnComplete`.
- The turn clips must contain suitable root-motion rotation. Quick Turn forces root-motion rotation while active.
- Quick Turn only records movement while the character is grounded.

## Add Quick Turn

1. Select the character and open **Ultimate Character Locomotion**.
2. Expand **Abilities**, select **+**, and add **Quick Turn**.
3. Place Quick Turn near the bottom of the ability list so gameplay abilities have higher priority. A useful order is **Speed Change**, **Quick Start**, **Quick Stop**, **Quick Turn**, then **Idle**.
4. Keep **Start Type** and **Stop Type** set to **Automatic**. Quick Turn does not need an input name.
5. Set **Ability Index** to `8` when using the supplied Animator Controller.
6. Start with the source defaults: **Max Input Count** `10`, **Min Input Sqr Magnitude** `0.1`, and **Speed Change Threshold** `1`.

## Configure the Animator

Quick Turn publishes a walk/run choice through **Ability Float Data**. The supplied controller combines it with **Leg Index** to choose one of four states:

| Ability Float Data | Leg Index | Supplied state |
| ---: | ---: | --- |
| `0` | `0` | Quick Turn Walk Right |
| `0` | `1` | Quick Turn Walk Left |
| `1` | `0` | Quick Turn Run Right |
| `1` | `1` | Quick Turn Run Left |

The left and right state names distinguish the supplied foot-compatible variants; they are not additional values produced by Quick Turn. Configure transitions with **Ability Change**, **Ability Index** `8`, **Ability Float Data**, and **Leg Index**.

Keep the clips non-looping. Add an Animation Event near the end of every reachable turn clip with **Function** `ExecuteEvent` and **String** `OnAnimatorQuickTurnComplete`. Quick Turn does not use a duration fallback while the character continues moving.

## Choose the turn behavior

### Reversal sensitivity

**Min Input Sqr Magnitude** is compared with the squared magnitude of the current raw input. Its default of `0.1` rejects a very light stick movement. Increase it to require a stronger reversal, or lower it to remove this first gate for a low-range input device. Lowering it does not change the separate dot-product requirement.

The ability also compares the current input with the average stored direction. At least one axis must reverse sign, and their dot product must be `-0.5` or lower. This accepts a strong, roughly opposite direction change but rejects a 90-degree turn and shallow diagonal changes. The dot-product limit is fixed by the ability rather than exposed in the Inspector.

### Input history

**Max Input Count** controls how many recent grounded raw-input samples are averaged. A larger history gives a steadier previous direction but reacts more slowly after a late course correction. A smaller history emphasizes the latest input but can make noisy changes less predictable.

### Walk or run turn

**Speed Change Threshold** separates the walk and run clips. Quick Turn sets **Ability Float Data** to `1` when the absolute value of either averaged input axis is greater than the threshold; otherwise it uses `0`. The comparison is strict, so the default threshold of `1` requires a multiplied input above `1` for a run turn.

Keep [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) above Quick Turn. Speed Change updates both the processed and raw input vectors before lower abilities record them, allowing its default multiplier to select the run variant.

### Camera and movement style

Use Quick Turn when the character normally faces its travel direction, as with Adventure movement. A movement style that keeps the character facing the camera or a target can reverse travel without turning the body, so its Animator generally should not enter these states.

## How it runs

While inactive, Quick Turn stores recent raw movement input whenever the character is grounded and moving. It starts automatically when the current input is strong enough and points roughly opposite the averaged history.

On start, it selects walk (`0`) or run (`1`) from that history, updates the Animator, clears its stored samples, and forces root-motion rotation so the clip turns the character. It stops when `OnAnimatorQuickTurnComplete` is received, when the character is no longer moving, or when a higher-priority ability force-stops it. Root-motion rotation is released when the ability ends, and the stored-input history shared by Quick Start, Quick Stop, and Quick Turn is reset.

The default Quick Stop confirmation period helps distinguish a stop from a reversal. When input returns in the opposite direction, Quick Stop can cancel before choosing a stop animation and Quick Turn can then evaluate the same recent movement.

## Verify in Play Mode

1. Open the Animator window and watch **Ability Index**, **Ability Float Data**, **Leg Index**, and the active ability list on Ultimate Character Locomotion.
2. Walk forward for several frames, then press directly backward without releasing to neutral for long. Confirm that Quick Turn activates with **Ability Index** `8` and **Ability Float Data** `0`.
3. Repeat while Speed Change is active. Confirm that **Ability Float Data** is `1` and the run turn plays.
4. Repeat with both **Leg Index** values and confirm that the corresponding left/right state is selected.
5. Change from forward to strafe input. A 90-degree direction change should remain in normal locomotion instead of starting Quick Turn.
6. Allow a turn to complete and confirm that `OnAnimatorQuickTurnComplete` stops the ability and root-motion rotation returns to its normal setting.
7. Release movement during the turn, then start a higher-priority gameplay ability during another turn. Confirm that both paths stop Quick Turn cleanly.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Quick Turn never starts | The character is grounded, has recent movement history, and the current raw input reverses strongly enough. | Test with sustained movement followed by a direct opposite input. Check the movement style and raw-input scale. Lower **Min Input Sqr Magnitude** only to change that first gate; the dot product must still reach `-0.5`. |
| A 90-degree or shallow direction change does not turn | Quick Turn requires a dot product of `-0.5` or less. | This is expected. Use normal locomotion for those changes or implement a different turn ability for a wider angle range. |
| A run uses the walk turn | **Speed Change** is above Quick Turn and the averaged raw input exceeds **Speed Change Threshold**. | Correct the ability order or tune the threshold for the configured multiplier. |
| The wrong left/right clip plays | The Animator transitions use **Leg Index** rather than a custom direction value. | Match `0` to the supplied right variant and `1` to the supplied left variant, or adjust both conditions to match custom clips. |
| The character does not rotate with the clip | The clip contains root-motion rotation and its import settings preserve it. | Use a turn clip with the required rotation and verify its root-motion import and Animator setup. Quick Turn forces root-motion rotation while active. |
| The ability remains active after the animation | A reachable clip did not send `OnAnimatorQuickTurnComplete` while movement continued. | Add the exact event to every walk/run and left/right clip, including any replacement animation. |
| The turn ends immediately | The character is no longer considered moving, or the event occurs too early. | Keep reversal input active through the turn and move the completion event near the intended end of the clip. |
| Quick Stop plays instead of Quick Turn | Quick Stop's confirmation or the stored-input ability order has been changed. | Keep Quick Stop directly above Quick Turn and restore its default **Required Start Success Count** of `2`. |
| Other gameplay abilities are blocked | Quick Turn is too high in the ability list. | Move it near the bottom, below abilities that should take priority. |

## Related tasks

- [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) provides the camera-relative movement style for the supplied setup.
- [Quick Stop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-stop/) handles released movement input before a stop animation is selected.
- [Quick Start](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-start/) adds a directional start animation.
- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) provides the multiplied input used for run turns.
- [Idle](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/idle/) can remain below the stored-input movement abilities.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains **Ability Index**, **Ability Float Data**, and **Leg Index**.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains the animation-event workflow.

## Developer reference

Quick Turn derives from `StoredInputAbilityBase` and stores `RawInputVector` samples. `CanStartAbility` requires a grounded character with stored input, a current squared raw-input magnitude of at least `MinInputSqrMagnitude`, an opposite sign on at least one nonzero axis, and a dot product between current and averaged input of `-0.5` or less.

`AbilityFloatData` returns `0` for a walk turn and `1` for a run turn. While active, the ability sets `ForceRootMotionRotation` to `true`; it resets the flag on every stop path. A normal stop is allowed after `OnAnimatorQuickTurnComplete` or when `UltimateCharacterLocomotion.Moving` becomes false, while a forced stop is always accepted. Start and stop are also reported through the standard `OnCharacterAbilityActive` event.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-ragdoll"></a>

# Ragdoll

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/)

Ragdoll gives a humanoid character's body to Unity physics, allowing impacts and the environment to determine how it falls. Use it for physics-based deaths or scripted knockdowns. It is different from [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/), which keeps the Animator in control and plays a selected death animation.

## Before you begin

- The built-in Character Manager workflow requires a Humanoid model with an Animator and mapped bones. It does not build Unity ragdolls for Generic models.
- The model needs child bone **Rigidbody**, **Collider**, and **Character Joint** components. The character's main Rigidbody remains on the root and is not part of the ragdoll body.
- Run the Setup Manager's Project setup so the **Character**, **SubCharacter**, and **VisualEffect** layers and their collision matrix exist.
- Decide whether death should use Ragdoll or [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/). Both listen to the death lifecycle, so do not leave both responses enabled unless their priority and states are deliberately coordinated.
- Ragdoll does not include a stand-up animation or reposition the controller to the final physics pose. A recoverable knockdown needs additional recovery logic.

## Build the ragdoll

### Build with Character Manager

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the existing Humanoid character and confirm its Animator model is valid.
3. Enable **Ragdoll** and select **Update Character**. For a new character, leave **Ragdoll** enabled when selecting **Build Character**.
4. Character Manager adds the Ragdoll ability and runs Unity's Ragdoll Builder for each Humanoid model.
5. Expand the model hierarchy and inspect the generated colliders, rigidbodies, and joints. Adjust collider sizes and joint limits so they fit the mesh without intersecting neighboring body parts.

### Add it to an existing ability list

1. Select the character and open **Ultimate Character Locomotion**.
2. Expand **Abilities**, select **+**, and add **Ragdoll**.
3. Move Ragdoll near the top of the list, above ordinary movement, interaction, item, and impact abilities. The supplied character places it first.
4. In the Ragdoll ability, select **Add Ragdoll Colliders**. Review the prefilled Humanoid bone assignments in Unity's Ragdoll Builder and complete the build.
5. If the hierarchy already has a complete ragdoll, do not build a second one. Each participating bone should have one intended Rigidbody and Collider setup.

At runtime, Ragdoll treats every child Rigidbody beneath the character root as part of the physics body. Keep unrelated rigidbodies, such as detachable props, outside that hierarchy or verify that controlling them with the ragdoll is intentional.

## Configure the ability

1. Keep **Start Type** and **Stop Type** set to **Manual**. The death event or gameplay code starts and stops the ability.
2. Keep **State** set to `Death` for the standard death-state response.
3. Enable **Start On Death** for a physics-based death. Disable it for a knockdown that should be controlled only by gameplay code.
4. Start with the source defaults:
   - **Start Delay**: `0`
   - **Ragdoll Layer**: `Character`
   - **Inactive Ragdoll Layer**: `SubCharacter`
   - **Camera Rotational Force**: `(0, 0, 0.75)`
   - **Interpolation Mode**: `None`
   - **Collision Detection Mode**: `Continuous`
5. Leave **Allow Positional Input** and **Allow Rotational Input** disabled. The standard ability also disables the main controller's gravity and horizontal and vertical collision detection while active; the child rigidbodies handle those responsibilities.

Ragdoll does not use an **Ability Index** or an Animator state-machine branch. It disables the Animator when physics begins.

## Choose the physics behavior

### Death or recoverable knockdown

With **Start On Death** enabled, Ragdoll receives the position and force from `OnDeath`, starts even though the character is no longer alive, and remains active until the respawn lifecycle sends `OnWillRespawn`.

For a temporary knockdown, disable **Start On Death** and start and stop Ragdoll from gameplay code. Stopping while the character is alive freezes the child rigidbodies, enables the Animator and main colliders, and sends an Animator snap. The controller stays at its existing transform, so a body that has rolled away will visually snap back. Reposition the controller and select an appropriate get-up pose before stopping if recovery should happen at the body's final location.

### Start delay

**Start Delay** postpones the switch from animation to physics. The Death state and camera response begin immediately, while the Animator and main colliders remain active until the fixed-time delay expires.

Keep the delay shorter than every possible respawn or manual-recovery time. The Version 3 ability schedules the physics switch without retaining a cancellation handle, so stopping before the delay expires does not cancel that pending switch.

### Active and inactive layers

**Ragdoll Layer** is assigned to every child Rigidbody while physics is active. The default is `Character`. The source tooltip recommends `VisualEffect` when other characters should not step over the body; verify the result against the project's collision matrix and gameplay requirements.

**Inactive Ragdoll Layer** defaults to `SubCharacter`. This keeps the frozen child colliders from behaving like additional locomotion colliders while the character is animated. A wrong inactive layer commonly causes self-collision or movement jitter.

### Camera and rigidbody settings

**Camera Rotational Force** adds a camera reaction when the ability starts. A death multiplies this vector by the killing force magnitude; a manual start uses the configured vector directly.

**Interpolation Mode** and **Collision Detection Mode** are applied to every child Rigidbody while active. Use interpolation when the visible physics needs smoothing. Keep a continuous collision mode for fast impacts, or test a less expensive mode when the body moves slowly and physics cost matters.

## How it runs

On initialization, Ragdoll disables its child physics: the rigidbodies become kinematic and frozen, their collision mode becomes Discrete, their interpolation becomes None, and their GameObjects move to **Inactive Ragdoll Layer**.

When the ability starts, it sends the camera force and waits for **Start Delay**. It then disables the Animator, clears locomotion position and rotation forces, disables the main character colliders, and activates every child Rigidbody. The rigidbodies inherit the character's configured gravity, use the selected interpolation and collision mode, move to **Ragdoll Layer**, and receive the killing force at the supplied impact position.

When Ragdoll stops, it reverses those changes: child bodies freeze, the Animator and main colliders return, and the inactive layer is restored. With **Start On Death** enabled, this happens on `OnWillRespawn`, before the Respawner moves and reactivates the character. A manual living recovery also sends `OnCharacterSnapAnimator` so the model returns to the controller pose.

## Verify in Play Mode

1. Keep the Ragdoll ability, Animator, root Rigidbody, and several child bone rigidbodies visible in the Inspector.
2. Before activation, confirm the Animator is enabled, the main character colliders are enabled, and child rigidbodies are kinematic, frozen, and on **Inactive Ragdoll Layer**.
3. Apply lethal damage with a visible impact force. Confirm Ragdoll becomes active, the camera reacts, and physics begins after **Start Delay**.
4. While active, confirm the Animator and main colliders are disabled, child rigidbodies are non-kinematic and unconstrained, and the hit force moves the body from the correct position.
5. Repeat with a low and high killing force. Confirm the physical and camera reactions scale with that force.
6. Allow Character Respawner to run. Confirm Ragdoll stops on `OnWillRespawn`, the inactive layer and frozen child bodies return, the Animator and main colliders are enabled, and normal movement works after respawn.
7. For a recoverable knockdown, start and stop the ability while the character is alive. Confirm the expected snap behavior before implementing any custom root repositioning or get-up animation.
8. Test the complete cycle on slopes, stairs, walls, and around other characters to validate collider sizes, joint limits, and layer collisions.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Add Ragdoll Colliders** does nothing | The model has an Animator Monitor, an Animator, a Humanoid Avatar, and mapped required bones. | Configure the model as Humanoid and rebuild through Character Manager. Generic models are not supported by the built-in ragdoll builder workflow. |
| The character collapses incorrectly or explodes | Generated colliders overlap, joint anchors or limits are unsuitable, or the model scale is problematic. | Adjust the Rigidbody mass distribution, collider shapes, and Character Joint limits in the model hierarchy, then retest from a neutral pose. |
| The body does not fall | Child bones have rigidbodies and **Start Delay** has elapsed. | Build the ragdoll, verify the child bodies are beneath the character root, and confirm they become non-kinematic and unconstrained when active. |
| The Animator continues controlling the body | Ragdoll is active and the selected child rigidbodies were discovered during initialization. | Confirm the correct Ragdoll ability instance starts and that the model uses the character's Animator Monitor. |
| The body ignores the killing force | The death source supplied a nonzero force and hit position through `OnDeath`. | Correct the damage impact data. For a manual start, assign Ragdoll's **Force** and **Position** properties before starting it. |
| The character jitters before ragdolling | Child colliders are on **Inactive Ragdoll Layer** and the UCC layer matrix is installed. | Restore `SubCharacter`, rerun the Setup Manager's Project layer setup, and remove unrelated child rigidbodies from the ragdoll hierarchy. |
| Other characters collide with the body incorrectly | **Ragdoll Layer** and the project collision matrix do not match the desired corpse behavior. | Test `Character` and the component-recommended `VisualEffect` layer, then keep the choice that matches navigation and collision requirements. |
| Ragdoll and a death animation compete | Both Ragdoll **Start On Death** and Die are enabled. | Disable the unused response or deliberately coordinate their list priority and states. |
| The body reactivates after an early recovery or respawn | The ability stopped before a nonzero **Start Delay** expired. | Keep recovery and respawn later than the delay, or use `0` until custom cancellation is implemented. |
| The model snaps away when a living knockdown ends | The controller root was not moved to the final ragdoll pose. | Position and orient the controller from the chosen body reference, prepare a get-up pose, then stop Ragdoll. |
| The character remains ragdolled after a custom respawn | The custom path did not send `OnWillRespawn`, or **Start On Death** is disabled for a manually controlled ragdoll. | Stop Ragdoll explicitly before moving the character, or use the complete Character Respawner lifecycle. |
| Main colliders or animation do not return | The Ragdoll ability never stopped. | Confirm the respawn path sends `OnWillRespawn`, or call the standard ability stop API for a manual knockdown. |

## Related tasks

- [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/) provides an Animator-driven death instead of a physics body.
- [Impact Knock Back](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/impact-knock-back/) provides a brief animated impact response and explicitly allows Ragdoll to take priority.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) sends the death position and force used by Ragdoll.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) sends the pre-respawn event that stops a death ragdoll.
- [Revive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/) provides a different recovery path when the character should return through an ability.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) explains the UCC collision layers.
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) explains building and updating a Humanoid character through Character Manager.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains list priority and manual ability control.

## Developer reference

Ragdoll uses **Start Type** `Manual`, **Stop Type** `Manual`, and the `Death` state. It allows itself to remain active after death. It listens for `OnDeath` and `OnWillRespawn`, sends `OnCameraRotationalForce`, and sends `OnCharacterSnapAnimator` when a living character returns to animation. The usual `OnCharacterAbilityActive` event also reports its start and stop.

For a manual knockdown, set the optional force and position before starting the ability:

```csharp
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using UnityEngine;

public class RagdollExample : MonoBehaviour
{
    [SerializeField] private UltimateCharacterLocomotion m_CharacterLocomotion;

    public void StartRagdoll(Vector3 position, Vector3 force)
    {
        var ragdoll = m_CharacterLocomotion.GetAbility<Ragdoll>();
        ragdoll.Position = position;
        ragdoll.Force = force;
        m_CharacterLocomotion.TryStartAbility(ragdoll);
    }

    public void StopRagdoll()
    {
        var ragdoll = m_CharacterLocomotion.GetAbility<Ragdoll>();
        m_CharacterLocomotion.TryStopAbility(ragdoll);
    }
}
```

Death-supplied force is multiplied by `MathUtility.RigidbodyForceMultiplier` before it is applied to each child Rigidbody. Under the multiplayer compile symbol, the ability also serializes each child body's position, rotation, velocity, and angular velocity as its network start data.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-restrict-position"></a>

# Restrict Position

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-position/)

Restrict Position keeps the character's root inside a world-aligned range on the X axis, Z axis, or both. Use it for a rectangular arena, a lane, or a 2.5D movement strip when creating physical walls is unnecessary.

## Before you begin

- The limits use world-space X and Z coordinates. They are not relative to the character, a parent, a moving platform, or a custom reference transform.
- Y is never restricted, so the character can still follow slopes, stairs, gravity, and vertical abilities.
- The limits clamp the character root, not the outside of its capsule. Inset the values by the required collider radius when the complete body must remain inside a visible edge.
- A new ability defaults to **Restrict XZ** with every minimum and maximum set to `0`. Configure a valid range containing the character before allowing it to start.
- Add [Stop Movement Animation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/stop-movement-animation/) when the locomotion animation should stop at the invisible boundary instead of continuing to run in place.

## Add a permanent boundary

1. Select the character and open **Ultimate Character Locomotion**.
2. Expand **Abilities**, select **+**, and add **Restrict Position**.
3. Disable the ability temporarily while entering its limits, or enter a range that already contains the character's current world position.
4. Choose **Restriction**:
   - **Restrict X** clamps world X and leaves Z free, which is useful for a corridor running along Z.
   - **Restrict Z** clamps world Z and leaves X free, which is useful for a side-scrolling plane.
   - **Restrict XZ** clamps both axes to a world-aligned rectangle.
5. Enter **Min X Position** and **Max X Position** when X is restricted. Enter **Min Z Position** and **Max Z Position** when Z is restricted. Each minimum must be less than or equal to its maximum.
6. For a permanent boundary, keep **Start Type** set to **Automatic**, **Stop Type** set to **Manual**, and re-enable the ability. It starts as soon as the enabled character updates and remains active.
7. Place Restrict Position below other abilities whose final movement should be clamped. It is concurrent and does not block them, but active abilities call `ApplyPosition` in list order.

Restrict Position does not use an **Ability Index** or require an Animator state.

## Configure useful scenarios

### Rectangular arena

Choose **Restrict XZ** and enter the arena's world edges. For example, X from `-10` to `10` and Z from `-8` to `8` keeps the character root within a 20-by-16-unit rectangle. Inset those values if the visible capsule must not cross the border.

### 2.5D movement strip

Choose **Restrict Z** and use a narrow Z range, such as `-0.1` to `0.1`, while leaving X unrestricted. Pair it with the [Pseudo 3D / 2.5D movement type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/) when the scene is aligned to the world axes.

### Temporary scripted area

For a boundary that should turn on and off, set **Start Type** to **Manual** and start and stop the ability from a state or gameplay script. Another option is to leave the source-default automatic start but keep **Enabled** off in the default state and use a State preset to enable it only inside the relevant mode or zone.

Do not only stop an enabled ability whose **Start Type** is still **Automatic**. It will try to start again on the next character update.

### Moving or rotated area

The built-in ability has no reference-transform field and never converts the target into local space. A platform-relative or rotated boundary therefore needs a custom ability or code that continually converts the desired area to world X/Z limits. For a rotated rectangular volume, physical colliders are often the clearer option.

## How it runs

Restrict Position is concurrent, so it can remain active while locomotion and other abilities run. During the position-application phase it reads **Target Position**, clamps the selected world X and Z components, and replaces **Desired Movement** with the offset from the current position to that clamped target. Movement along Y and any unrestricted horizontal axis remains unchanged.

There is no boundary collider, cast, impact, or boundary-hit event. The character simply cannot receive a final target beyond the configured coordinate. If [Stop Movement Animation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/stop-movement-animation/) is present and Restrict Position is active, that ability predicts a boundary crossing and clears horizontal input so the locomotion animation also stops.

AI and scripted movement remain subject to the same clamp. A NavMesh or Move Towards destination outside the range will not become reachable merely because the character has reached the restriction edge; keep those destinations inside the allowed area or handle the blocked result separately.

## Verify in Play Mode

1. Display the character's Transform, Ultimate Character Locomotion, Restrict Position, and active ability list.
2. Confirm Restrict Position becomes active automatically and the character begins inside every enabled minimum/maximum pair.
3. Move toward each restricted edge. Watch the root position stop exactly at the configured world coordinate while Y continues to respond to terrain.
4. Move along an unrestricted axis and confirm it is unaffected.
5. Approach a corner with **Restrict XZ** and confirm both coordinates clamp without pushing the character outside the other edge.
6. With Stop Movement Animation present, hold input into an edge and confirm the locomotion animation stops. Disable that ability and compare the visual result.
7. Start a movement ability, apply root motion, and test a moving-platform or teleport scenario used by the game. Confirm list order and world-space limits produce the intended final position.
8. For a temporary setup, leave the zone or clear its State and confirm Restrict Position is no longer active. Re-enter and confirm it starts again with the expected bounds.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character jumps to the world origin | A newly added **Restrict XZ** ability started with all limits at `0`. | Disable it, enter limits containing the current world position, then re-enable it. |
| The character is clamped to the wrong place | The values were entered as local or parent-relative coordinates. | Convert the intended edges to world X/Z values. Use a custom solution when the reference transform moves or rotates. |
| The restriction behaves incorrectly after rotating the level | The implementation always clamps world X and Z. | Align the restricted area to world axes, use physical walls, or write a reference-transform-based ability. |
| The capsule crosses the visible edge | The ability limits the character root rather than the collider extent. | Inset the minimum and maximum values by the necessary capsule radius. |
| The character cannot move after adding the ability | Minimum and maximum values are equal, reversed, or do not contain the current position. | Set each minimum less than or equal to its maximum and choose a nonzero usable range. |
| The animation keeps running at the edge | Restrict Position changes movement but does not control the Animator. | Add and configure Stop Movement Animation so it detects the active restriction. |
| Another ability moves past the boundary | A later active ability changes **Desired Movement** after Restrict Position applies its clamp. | Move Restrict Position lower in the ability list and retest the interaction. |
| NavMesh Agent Movement keeps pressing into an edge | Its destination is outside the allowed range. | Clamp or replace the destination before assigning it, or stop the AI movement when the restriction reports a blocked target. |
| A temporary restriction restarts immediately | **Start Type** is **Automatic** and the ability remains enabled. | Use **Manual** start for scripted control or toggle **Enabled** through a State preset. |
| The boundary disappears after a State change | A State preset disabled or replaced the ability values. | Inspect the active States and ensure the intended preset contains the correct enabled state and limits. |

## Related tasks

- [Stop Movement Animation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/stop-movement-animation/) stops locomotion animation at a restriction or solid obstacle.
- [Restrict Rotation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-rotation/) limits the character's facing direction.
- [Pseudo 3D / 2.5D Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/) configures a world-aligned side-scrolling movement plane.
- [NavMesh Agent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) must receive a destination inside the allowed bounds.
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) can also be prevented from reaching a target outside the restriction.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) can enable a temporary restriction and restore the default setup afterward.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains concurrent abilities and list order.

## Developer reference

`RestrictPosition.RestrictedPosition(ref Vector3 targetPosition)` clamps a supplied world position and returns `true` when either selected component changed. The public restriction property is spelled `Restiction` in the released Version 3 API; use that exact spelling when configuring the enum from code. The four numeric properties are `MinXPosition`, `MaxXPosition`, `MinZPosition`, and `MaxZPosition`.

The ability defaults to **Automatic** start, **Manual** stop, and `IsConcurrent == true`. It has no dedicated boundary event; its activation and deactivation are reported through the standard `OnCharacterAbilityActive` event.

The following component assumes **Start Type** has been changed to **Manual** in the Inspector:

```csharp
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using UnityEngine;

public class ArenaRestriction : MonoBehaviour
{
    [SerializeField] private UltimateCharacterLocomotion m_CharacterLocomotion;

    public void EnableArena(float minX, float maxX, float minZ, float maxZ)
    {
        var restriction = m_CharacterLocomotion.GetAbility<RestrictPosition>();
        restriction.Restiction = RestrictPosition.RestrictionType.RestrictXZ;
        restriction.MinXPosition = minX;
        restriction.MaxXPosition = maxX;
        restriction.MinZPosition = minZ;
        restriction.MaxZPosition = maxZ;
        m_CharacterLocomotion.TryStartAbility(restriction);
    }

    public void DisableArena()
    {
        var restriction = m_CharacterLocomotion.GetAbility<RestrictPosition>();
        m_CharacterLocomotion.TryStopAbility(restriction);
    }
}
```

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-restrict-rotation"></a>

# Restrict Rotation

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-rotation/)

Restrict Rotation snaps the character's desired facing to evenly spaced headings. Use it for four-way or eight-way movement, a 2.5D character that should face only along the play plane, or a camera-relative grid. It does not clamp rotation between a minimum and maximum angle.

## Before you begin

- **Restriction** must be greater than `0`. The runtime divides by this value when choosing the nearest heading.
- With the standard world-up direction, headings are based on world yaw rather than the character's parent or starting rotation.
- With custom gravity, the ability quantizes around **Ultimate Character Locomotion > Up**, using world forward as the reference direction for that up-aligned frame.
- **Relative Look Source Rotation** requires an attached look source. The character normally receives one when a Camera Controller or AI look source is connected.
- The ability changes facing only. It does not constrain movement input or position; pair it with [Restrict Position](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-position/) when the character also needs to stay on a lane or plane.

## Add a heading restriction

1. Select the character and open **Ultimate Character Locomotion**.
2. Expand **Abilities**, select **+**, and add **Restrict Rotation**.
3. Choose a positive **Restriction**. The source default is `45`, which creates eight headings around a full turn.
4. Set **Offset** to rotate the heading grid. The source default is `0`.
5. Enable **Relative Look Source Rotation** only when the grid should rotate with the camera or another look source. Its source default is disabled.
6. When the grid is look-relative, use **Look Source Offset** for an additional correction. Its source default is `0`.
7. Enable **Rotation Smoothing** for a gradual turn toward the selected heading. It is disabled by default, producing an immediate snap.
8. For a permanent restriction, keep **Start Type** set to **Automatic**, **Stop Type** set to **Manual**, and **Enabled** selected.
9. Place Restrict Rotation below other regular abilities whose final rotation should be quantized. It is concurrent and does not block them, but active abilities call `ApplyRotation` in list order.

Restrict Rotation does not use an **Ability Index** or require an Animator state.

## Configure useful heading grids

### World-aligned movement

With the standard up direction and **Offset** `0`, the allowed headings are world yaw values separated by **Restriction**:

| Restriction | Result |
| ---: | --- |
| `45` | Eight headings: forward, backward, left, right, and the four diagonals |
| `90` | Four headings: `0`, `90`, `180`, and `270` degrees |
| `180` | Two headings: `0` and `180` degrees |
| `360` | One heading at the configured offset |

The target switches to whichever allowed heading is nearest. For a `90`-degree grid, it changes heading after the desired rotation crosses the midpoint between two choices.

### Offset grid

**Offset** shifts every allowed heading without changing their spacing. For example, **Restriction** `90` with **Offset** `45` allows `45`, `135`, `225`, and `315` degrees. Use this for a level whose paths are diagonal relative to world forward.

### Camera-relative grid

Enable **Relative Look Source Rotation** to add the current look-source yaw to **Offset** before the nearest heading is selected. A `90`-degree grid then stays aligned with the camera as it rotates. **Look Source Offset** rotates the grid again; for example, `180` reverses its forward reference.

If the camera can orbit continuously, consider **Rotation Smoothing** so small look-source changes do not produce visibly abrupt character snaps.

### 2.5D facing

For a character that travels along a world-aligned side-scrolling plane, **Restriction** `180` produces two opposite headings. Choose **Offset** so those headings face along the playable axis. The supplied character enables Restrict Rotation from its `2.5D` State rather than leaving it active for every movement type.

### Temporary mode

Set **Start Type** to **Manual** when gameplay code should start and stop the restriction. Alternatively, leave automatic start configured, disable the ability in the default State, and use a State preset to enable it only for the relevant camera or movement mode.

Stopping an enabled automatic ability is temporary: it will try to start again on the next character update. Use manual start or toggle **Enabled** when the restriction must remain off.

## How it runs

Restrict Rotation is concurrent, so locomotion and other abilities can remain active. During the rotation-application phase it reads **Target Rotation**, expresses that rotation in a frame aligned to the character's current **Up**, and rounds the yaw to the nearest multiple of **Restriction** after subtracting the effective offset. It then adds the offset again and writes the result to **Desired Rotation**.

The effective offset is **Offset** by itself, or **Offset + look-source yaw + Look Source Offset** when **Relative Look Source Rotation** is enabled. Pitch and roll in the up-aligned target frame are retained; only the yaw component is quantized.

With **Rotation Smoothing** disabled, the desired result is the selected heading immediately. When enabled, the ability uses a spherical interpolation from the current rotation with **Motor Rotation Speed** and the current time-step delta. Root motion and rotation-producing abilities establish the target first, after which Restrict Rotation quantizes it. A later ability that also changes rotation during `ApplyRotation` can replace that result, so test and adjust list order when combining custom rotation modifiers.

The ability listens for `OnCharacterAttachLookSource` and updates its cached reference when the camera or AI look source changes. It does not send an event when the selected heading changes.

## Verify in Play Mode

1. Display the Transform rotation, Ultimate Character Locomotion, Restrict Rotation, and active ability list.
2. With **Restriction** `90`, **Offset** `0`, and smoothing disabled, rotate or steer through a full circle. Confirm the character selects only four world-aligned headings.
3. Change **Offset** to `45` and confirm all four choices rotate by 45 degrees.
4. Enable **Rotation Smoothing** and confirm the character turns gradually toward each selected heading. Change **Motor Rotation Speed** to verify it controls the response.
5. Attach the Camera Controller, enable **Relative Look Source Rotation**, and orbit the camera. Confirm the heading grid rotates with the look-source yaw.
6. Set **Look Source Offset** to `180` and confirm the camera-relative reference reverses.
7. Activate root-motion, Rotate Towards, or another rotation-producing ability used by the game. Confirm Restrict Rotation remains active concurrently and the final facing follows the intended ordering.
8. If the project uses custom gravity, test several **Up** directions and confirm the character rotates around the expected axis.
9. For a State-controlled setup, enter and leave the relevant mode and confirm Restrict Rotation activates and restores its default state correctly.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character rotation becomes invalid or unstable | **Restriction** is `0` or negative. | Set a positive spacing such as `45`, `90`, or `180`. |
| The character faces unexpected world directions | The grid uses an up-aligned world reference, not the parent or initial rotation. | Set **Offset** to the level's desired forward heading, or use a custom reference-transform implementation. |
| The grid is consistently rotated by the wrong amount | **Offset** and **Look Source Offset** are both part of the effective offset. | Set the base world correction in **Offset** and reserve **Look Source Offset** for the look-relative correction. |
| Enabling look-relative rotation causes an error | No look source is attached to the character. | Attach the Camera Controller or intended AI look source before enabling **Relative Look Source Rotation**. |
| The character snaps too abruptly | **Rotation Smoothing** is disabled. | Enable smoothing and tune **Motor Rotation Speed** on Ultimate Character Locomotion. |
| The character turns too slowly or never seems to settle | Smoothing is enabled and **Motor Rotation Speed** is too low, or the look-relative grid keeps moving. | Increase the motor rotation speed or disable smoothing for a fixed snap. |
| Another ability ignores the heading grid | A later regular ability changes **Desired Rotation** during `ApplyRotation`, or another system writes the transform afterward. | Move Restrict Rotation lower in the regular ability list and identify any post-locomotion rotation writer. |
| Movement does not follow the snapped facing | Restrict Rotation changes rotation but not **Input Vector** or **Desired Movement**. | Configure the intended Movement Type, or pair the rotation with the matching position/input restriction. |
| A 2.5D character faces the wrong two directions | **Restriction** or **Offset** does not match the playable world axis. | Use `180` and adjust **Offset** until both allowed headings align with the plane. |
| The restriction restarts after being stopped | **Start Type** remains **Automatic** and the ability is enabled. | Use **Manual** start or toggle **Enabled** through a State preset. |
| Custom-gravity facing is inconsistent | The current **Up** and world-forward reference do not match the intended surface frame. | Verify the gravity orientation in Play Mode; use a custom reference frame when the built-in world-forward baseline is unsuitable. |

## Related tasks

- [Restrict Position](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-position/) limits world X/Z movement for arenas and 2.5D planes.
- [Rotate Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rotate-towards/) produces a target-facing rotation that Restrict Rotation can quantize.
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) can provide movement and facing toward a destination.
- [Pseudo 3D / 2.5D Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/) configures the matching side-scrolling movement mode.
- [Pseudo 3D / 2.5D Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/) configures the corresponding camera view.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) can enable and configure the restriction for a specific mode.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains concurrent abilities, automatic start, and list order.

## Developer reference

The public runtime properties are `Restriction`, `Offset`, `RelativeLookSourceRotation`, `LookSourceOffset`, and `RotationSmoothing`. Restrict Rotation defaults to **Automatic** start, **Manual** stop, and `IsConcurrent == true`. Its source defaults are `45`, `0`, `false`, `0`, and `false`, respectively.

The ability consumes `OnCharacterAttachLookSource` and reports activation through the standard `OnCharacterAbilityActive` event. It has no heading-change event or public helper that quantizes an arbitrary Quaternion.

The following component assumes **Start Type** has been changed to **Manual** in the Inspector:

```csharp
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using UnityEngine;

public class HeadingRestriction : MonoBehaviour
{
    [SerializeField] private UltimateCharacterLocomotion m_CharacterLocomotion;

    public void EnableFourWayFacing(float offset)
    {
        var restriction = m_CharacterLocomotion.GetAbility<RestrictRotation>();
        restriction.Restriction = 90;
        restriction.Offset = offset;
        restriction.RelativeLookSourceRotation = false;
        restriction.RotationSmoothing = true;
        m_CharacterLocomotion.TryStartAbility(restriction);
    }

    public void DisableFacingRestriction()
    {
        var restriction = m_CharacterLocomotion.GetAbility<RestrictRotation>();
        m_CharacterLocomotion.TryStopAbility(restriction);
    }
}
```

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-revive"></a>

# Revive

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/)

Revive plays a get-up animation and, when the character is dead, completes the respawn only after that animation finishes. Use it for an in-place second chance, an ally-triggered revival, or a nonlethal knockdown that should visibly stand up again.

## Before you begin

- Add a **Respawner** component to the same GameObject. Revive reports an error without it and relies on it to restore Health and the character's alive state.
- Keep the character active after death. Revive cannot start when the GameObject is inactive, so disable **Health > Deactivate On Death** for this flow.
- Use an Animator Controller with the Revive states, or add equivalent states to a custom controller. The supplied controller expects Revive's **Ability Index Parameter** to be `5`; at runtime **Ability Int Data** is `0` for the forward get-up and `1` for the backward get-up.
- Place Revive above Ragdoll and Die in the regular ability list. Revive is not concurrent; that higher priority lets it stop those active death abilities before the get-up animation begins.
- Use the regular [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) flow instead when the character should disappear and return at a checkpoint without a get-up animation.

## Configure an automatic in-place revive

1. Select the character and open **Ultimate Character Locomotion**.
2. Expand **Abilities**, select **+**, and add **Revive**.
3. Move Revive above **Ragdoll** and **Die**. Its position in this list controls runtime priority; it is separate from the **Ability Index Parameter** field.
4. Keep **Start Type** set to **Manual** and **Stop Type** set to **Manual**. The death callback starts the ability, and the animation-complete event stops it.
5. Keep **State** set to **Death** and **Ability Index Parameter** set to `5` when using the supplied Animator Controller.
6. Enable **Start On Death**. The Version 3 source default is disabled, although the supplied demo character enables it for its death-animation setup.
7. Set **Death Start Delay**. The source default is `3` seconds; this delay applies only when **Start On Death** schedules the revive.
8. On **Health**, clear **Deactivate On Death** so the delayed ability can still start.
9. Enter Play Mode once and inspect **Respawner**. When Revive is enabled with **Start On Death** at startup, it changes **Positioning Mode** to **None** and disables **Schedule Respawn On Death** and **Schedule Respawn On Disable**. This prevents a normal timed respawn from racing the get-up animation.

Do not enable a second automatic respawn path for the same death. Revive intentionally keeps the current transform and calls Respawner itself at the end of the animation.

## Choose the revival flow

### Automatic second chance

Enable **Start On Death** for a character that should stand up automatically after **Death Start Delay**. This is the simplest in-place flow and lets Revive configure Respawner during `Awake`.

### Player, ally, or environment trigger

Leave **Start On Death** disabled and start Revive from gameplay code when the interaction succeeds. For a genuinely dead character, keep the GameObject active, disable **Schedule Respawn On Death**, and choose the intended **Positioning Mode** before starting the ability. Use **None** to get up where the character fell.

Starting Revive while the character is still alive plays and stops the get-up ability but does not call `Respawner.Respawn()`. This is useful for a nonlethal knockdown, but the **Death** State still becomes active while the ability runs.

Changing **Start On Death** or **Enabled** after `Awake` does not automatically reconfigure Respawner. Update the Respawner settings at the same time when switching revival modes at runtime.

### Death animation or ragdoll

Revive can follow either Die or Ragdoll. On death, those abilities may remain active; when the delayed Revive starts from a higher list position, it force-stops the lower-priority death ability. Stopping Die restores the character colliders. Stopping Ragdoll restores the animated hierarchy, disables its physics bodies, and re-enables the Animator before the get-up state plays.

The built-in forward/backward choice uses the death hit position relative to the character, not the ragdoll's final resting pose. Test both directions when using physics-driven deaths and customize the revive type if the final pose needs a different animation.

## How it runs

1. Health reaches its minimum and sends `OnDeath` with the hit position, force, and attacker.
2. Ultimate Character Locomotion marks the character dead and stops abilities that are not allowed to remain active on death. Revive, Die, and Ragdoll are allowed to participate in the death flow.
3. When **Start On Death** is enabled, Revive selects an Animator type from the hit position and schedules `StartAbility()` after **Death Start Delay**.
4. The delayed start succeeds only if Revive is enabled, the GameObject is active in the hierarchy, and no higher-priority non-concurrent ability blocks it.
5. Revive activates the **Death** State and sets **Ability Index** to `5`. A hit in front of the character produces **Ability Int Data** `0`; a hit behind or at the character produces `1`.
6. The Animator plays the matching get-up animation. The included forward and backward clips send `OnAnimatorReviveComplete` near the end of the clip.
7. That event stops Revive. If the character is still dead, Revive immediately refreshes the Animator ability parameters and calls `Respawner.Respawn()`.
8. Respawner sends `OnWillRespawn`, performs any configured positioning, and then sends `OnRespawn`. Health resets its Health and Shield attributes, Ultimate Character Locomotion becomes alive, and Die stops if it is still active.

There is no duration fallback in Revive. The completion animation event is what advances a dead character from the get-up animation to the respawn cleanup.

## Verify in Play Mode

1. Temporarily set **Death Start Delay** to `1` so the sequence is easy to repeat.
2. Keep the **Ultimate Character Locomotion**, **Health**, **Respawner**, and Animator parameter views visible.
3. Apply lethal damage from in front of the character. Confirm **Alive** becomes false, the death ability runs for the delay, Revive becomes the active regular ability, **Ability Index** becomes `5`, and **Ability Int Data** becomes `0`.
4. Confirm any active Die or Ragdoll ability stops before the get-up animation begins.
5. Let the animation complete. Confirm Revive stops once, `OnRespawn` is sent once, Health returns to its starting value, **Alive** becomes true, and the character remains at the death location.
6. Repeat with the hit position behind the character and confirm **Ability Int Data** becomes `1` and the backward get-up state plays.
7. If Ragdoll is enabled, repeat on uneven ground and verify the blend into each get-up animation is acceptable.
8. Test a manual revival with **Start On Death** disabled. Confirm no normal Respawner timer completes first and the interaction starts Revive only when intended.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The console says Revive requires Respawner | The character has no **Respawner** on its root GameObject. | Add Respawner before entering Play Mode. |
| The character respawns before the get-up animation | **Schedule Respawn On Death** is still enabled, Revive was disabled at startup, or **Start On Death** was enabled only after `Awake`. | Use one respawn path. Disable ordinary scheduling and use **Positioning Mode > None** for an in-place revive. |
| Revive never starts after the delay | The GameObject was deactivated, Revive is disabled, or Die/Ragdoll has higher list priority. | Clear **Deactivate On Death**, enable Revive, and move it above the active death abilities. |
| The get-up animation starts but the character remains dead | The clip never sends `OnAnimatorReviveComplete`. | Add an Animation Event near the end that calls `ExecuteEvent` with `OnAnimatorReviveComplete` as its string data. |
| The wrong forward/backward animation plays | The choice is based on the death hit position in the character's local Z direction, not force direction or final ragdoll pose. | Verify the damage position, or override `GetReviveTypeIndex` for the game's pose rules. |
| The character teleports after standing | A manual flow uses **Start Location** or **Spawn Point** positioning. | Set **Positioning Mode** to **None**, or use a normal respawn rather than an in-place Revive. |
| Revive starts but another ability or item remains visually active | Revive is below that regular ability, or the custom death setup does not respond to death/respawn events. | Move Revive higher and verify the other system handles `OnDeath`, `OnWillRespawn`, or `OnRespawn`. |
| Custom get-up state never exits | Its conditions do not match the ability parameters, or its clip lacks the completion event. | Use **Ability Index** `5`, the intended **Ability Int Data** value, and the required completion event. |

## Related tasks

- [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/) plays the standard forward or backward death animation.
- [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/) uses physics for the death pose and must yield before Revive animates.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) sends the death event and restores attributes on respawn.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) owns positioning and the final respawn events.
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains the controller structure used by abilities.
- [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) covers changing supplied clips safely.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) can switch between automatic revive, death animation, and ragdoll configurations.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains list priority, start types, and Animator parameters.

## Developer reference

Revive defaults to **Manual** start, **Manual** stop, **State** `Death`, and **Ability Index Parameter** `5`. `StartOnDeath` defaults to `false`, `DeathStartDelay` defaults to `3`, the ability is non-concurrent, and `CanStayActivatedOnDeath` is `true`.

Its public configuration properties are `StartOnDeath` and `DeathStartDelay`. `AbilityIntData` exposes the selected revive type. `GetReviveTypeIndex(Vector3 position, Vector3 force, GameObject attacker)` is the protected extension point for additional get-up choices.

Revive consumes `OnDeath` and `OnAnimatorReviveComplete`. When the character is still dead, completion causes Respawner to send `OnWillRespawn` and `OnRespawn`; activation also uses the standard `OnCharacterAbilityActive` event. Revive does not send a separate revival event.

### Add another get-up animation

Subclass Revive and return an unused **Ability Int Data** value. This example selects type `3` for deaths caused by an attacker tagged `Human` while retaining the built-in forward/backward selection for every other death:

```csharp
using Opsive.UltimateCharacterController.Character.Abilities;
using UnityEngine;

public class MyReviveAbility : Revive
{
    protected override int GetReviveTypeIndex(Vector3 position, Vector3 force, GameObject attacker)
    {
        if (attacker != null && attacker.CompareTag("Human")) {
            return 3;
        }

        return base.GetReviveTypeIndex(position, force, attacker);
    }
}
```

In the Full Body Layer's Revive sub-state machine, add a state whose transition requires **Ability Index** `5` and **Ability Int Data** `3`. Add the same `ExecuteEvent` / `OnAnimatorReviveComplete` Animation Event near the end of the new clip so Respawner performs its cleanup.

![Animator Controller Revive sub-state machine with a custom get-up state selected by Ability Int Data value 3](https://opsive.com/wp-content/uploads/2018/03/CustomRevive-1024x341.png)

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-rideable"></a>

# Rideable

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rideable/)

Rideable turns one Ultimate Character Controller character into a mount for another, such as a four-legged horse controlled by a humanoid rider. It owns the seat pose, dismount-clearance areas, mount input override, and mount-side cleanup; the rider uses the separate [Ride](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/ride/) ability.

## Before you begin

- Both the rider and mount need **Ultimate Character Locomotion** and **Ultimate Character Locomotion Handler**.
- Build and verify the mount as its own UCC character first, with the intended Movement Type and Animator Controller.
- The rider needs Ride, compatible mount/dismount animations, and usually Move Towards for a repeatable approach pose.
- The mount Animator needs a Rideable branch compatible with **Ability Index** `12` and the rider's mount, ride, and dismount data values.
- Rideable disables ordinary gameplay input on the mount during `Awake`. An unoccupied mount that should patrol or follow an AI needs a separate non-player control workflow.

## Configure the mount

1. Select the mount and open **Ultimate Character Locomotion**.
2. Expand **Abilities**, select **+**, and add **Rideable**. Keep **Start Type** and **Stop Type** set to **Manual** and **Ability Index Parameter** set to `12` when using the supplied Animator setup.
3. Place Rideable near the bottom of the regular ability list. It is concurrent, so locomotion abilities keep running, while a higher-priority active mount ability can supply the Animator parameters when appropriate.
4. Create a child Transform at the final rider-root pose on the saddle or seat. Match its position and rotation to the intended seated character and assign it to **Ride Location**. Do not leave this reference empty; the runtime warns and falls back to the mount root.
5. Inspect **Left Dismount Collider** and **Right Dismount Collider**. Adding Rideable creates Capsule Collider children automatically. If either was removed, select **Add Dismount Colliders** in the Rideable drawer.
6. Position and size each dismount collider around the space needed by that side's root-motion animation. Use a Capsule Collider, Box Collider, or Sphere Collider; Rideable disables the assigned components at startup and uses their shapes only for overlap checks.
7. Add a [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) on each usable mounting side. Place and rotate each location so the rider reaches the exact root pose expected by its left or right mount animation.
8. Add or identify the Collider that the rider's Ride detector will find. For trigger detection, put it on a layer included by Ride's **Detect Layers** and enable **Is Trigger**.
9. On the rider, configure [Ride](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/ride/) with its input, object detection, animation events, item choices, and the same Animator index.

Rideable itself does not accept a mount button. Ride detects the mount and calls the mount-side ability manually after its own start checks pass.

## Make the important choices

### Seat position and rotation

**Ride Location** is the rider root's target, not merely a visual saddle marker. During the riding phase, Ride continually moves and rotates the rider to this Transform while treating the mount as a moving platform. Test turns, slopes, and animation poses; a small position or yaw error remains visible for the entire ride.

The mount is scheduled to update before the rider so the seat target is current when the rider follows it.

### Mount and dismount sides

The rider's local X position when Ride starts selects the left or right mount branch. Move Towards Locations make that choice predictable.

When dismount is requested, Rideable checks the collider on the original mounting side first. If that volume overlaps a solid-object layer, it tries the opposite side. A missing collider counts as blocked, and the rider remains mounted when neither side is both assigned and clear.

The generated clearance objects use Capsule Colliders, but Box and Sphere Colliders are also supported. Mesh Collider and other collider types are not valid clearance shapes for Rideable.

### Input, look, and camera behavior

Rideable sends `OnEnableGameplayInput(false)` on the mount during startup. Once occupied, it enables **Override Input** on the mount's Ultimate Character Locomotion Handler. Ride then forwards the rider's raw horizontal input, forward input, and look vector every update; the mount's Movement Type determines how those values steer it.

Ride also forces independent look on the rider during the mounted lifecycle, allowing its Movement Type to separate look direction from transform rotation. It clears that override after dismount. Keep the camera attached to and configured for the rider, then verify that the chosen rider and mount Movement Types interpret look input as intended.

### Items, abilities, and animation

- Ride blocks item abilities while mounting or dismounting. Item Equip Verifier can unequip the rider before a transition, restore the item after mounting, and wait for it to unequip before dismounting. Ride also stops Aim when dismount begins.
- Ride blocks Height Change and the incompatible In Air Melee Use ability; the third-person Item Pullback ability is also blocked when that controller is installed.
- Speed Change is the one regular ability Ride explicitly mirrors: starting or stopping it on the rider starts or stops the mount's Speed Change. Add it to both characters and match the relevant speed and animation settings.
- Other rider abilities are not copied automatically. Configure mount abilities deliberately and verify their priority and Animator behavior rather than duplicating every rider ability.
- Rideable exposes the same **Ability Int Data** as the active Ride ability, keeping both Animators on the same mount, ride, or dismount phase. A higher-priority mount ability with its own Animator data can take precedence.

### States and occupancy

Rideable has no default **State** name. Set its inherited State only when the mount needs properties for the entire occupied period. On the rider, Ride activates its **Mount Complete State** (`RideMounted` by default) after the mounting transition and clears it when dismount begins.

Only one different Ride instance can occupy a Rideable at a time. A second rider fails the mount check until the first rider completes or force-stops the lifecycle.

## How it runs

1. The rider's Ride detector finds a Collider whose parent hierarchy contains Ultimate Character Locomotion with an available Rideable ability.
2. After any Move Towards alignment and item verification, Ride starts. It identifies the mounting side, calls `Rideable.Mount(this)`, treats the mount as a moving platform, aligns to the mount's up direction, and enables independent look.
3. Rideable starts manually, orders the mount update before the rider, adjusts the two characters' ignored colliders, clears old override values, and enables input override on the mount handler.
4. At the rider's **Mount Event**, Ride enters its riding phase and moves the rider to **Ride Location**. `Rideable.OnCharacterMount()` updates the mount Animator immediately and adds the rider's colliders to the mount locomotion collision set so the combined character does not clip through obstacles.
5. During the ride, movement and look input are forwarded to the mount. Rideable mirrors the rider's Animator data. The rider remains aligned to **Ride Location**.
6. After **Mount Complete Event**, Ride permits toggle input to request a dismount and activates `RideMounted` when configured.
7. A dismount request checks both clearance colliders and waits for any required item unequip. Ride clears the mount input override, restores rider root-motion positioning, removes the rider colliders from the mount, and begins the matching side animation.
8. At **Dismount Event**, Rideable stops, clears its rider reference, restores collider and input handling, and both characters update their Animator parameters. Ride clears the moving-platform and independent-look states before normal rider control resumes.

A forced Ride stop also calls the Rideable cleanup path, so stale input and collision overrides should not remain after an interruption.

## Verify in Play Mode

1. Keep both Ultimate Character Locomotion components, both locomotion handlers, and both Animator parameter views visible.
2. Approach from the left and start Ride. Confirm Rideable becomes active, the mount handler enables **Override Input**, and the mount updates before the rider without a one-frame seat lag.
3. At `OnAnimatorRideMount`, confirm the rider root settles exactly on **Ride Location** and both Animators report **Ability Index** `12` with the left-mount data value.
4. Move and look in every direction. Confirm the mount responds to the rider's values, the rider stays aligned, and the camera/look behavior remains stable.
5. Toggle Speed Change. Confirm the matching mount Speed Change starts and stops and that both characters use the intended speed and animation.
6. Attempt to dismount before the mount-complete point and confirm the request is rejected. After completion, confirm `RideMounted` is active on the rider.
7. Dismount with the original side clear. Confirm item unequip completes when required, Aim stops, the correct animation runs, and both Ride and Rideable become inactive at `OnAnimatorRideDismount`.
8. Block the original dismount volume and confirm the opposite side is used. Block both sides and confirm the rider remains mounted.
9. Force-stop Ride during mounting, riding, and dismounting in separate tests. Confirm mount override inputs return to zero, **Override Input** turns off, and collider relationships are restored each time.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console reports that Ride Location is null | **Ride Location** has no assigned Transform. | Create and assign a correctly aligned seat Transform instead of relying on the mount-root fallback. |
| The Console reports that a locomotion handler is required | The mount has no **Ultimate Character Locomotion Handler**. | Add the handler to the mount root before entering Play Mode. |
| The rider detects the mount but cannot start Ride | Rideable is missing, disabled, already occupied, or blocked by mount/rider ability priority. | Enable one Rideable, finish the existing ride, and inspect both active ability lists. |
| The mount never responds to the rider | Rideable is inactive, the handler is missing, or another system writes the mount input after Ride. | Restore the mount handler and give Ride's override input exclusive control while occupied. |
| An unoccupied mount no longer responds to player input | Rideable disabled gameplay input during `Awake`. | Use an AI or custom non-player controller while unoccupied, or explicitly manage gameplay-input ownership for the project. |
| The rider floats, clips, or faces the wrong direction | **Ride Location** does not match the rider root and seated animation. | Adjust both position and rotation while comparing the settled Play Mode pose. |
| The rider cannot dismount | A side collider is missing, both overlap solid layers, or Mount Complete has not occurred. | Restore both supported collider shapes, clear their volumes, and verify the rider's Mount Complete Event. |
| Dismount chooses the wrong side | The rider began on the unexpected local-X side or that side's collider is blocked. | Correct the Move Towards Locations and inspect both clearance volumes. |
| The mount and rider use different ride phases | **Ability Index Parameter** or Animator transitions differ, or another mount ability has higher parameter priority. | Use index `12` on both, match the data branches, and correct mount ability ordering. |
| Speed Change affects only one character | The other character lacks Speed Change or its configuration differs. | Add it to both and match the relevant settings; only its active state is mirrored. |
| Input remains stuck after an interruption | A custom force-stop path bypassed Ride/Rideable cleanup. | Stop Ride through Ultimate Character Locomotion and preserve the base `AbilityStopped` calls in subclasses. |

## Related tasks

- [Ride](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/ride/) configures the rider's detection, input, items, and animation timing.
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) aligns the rider before the mount transition.
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) defines the left and right approach poses.
- [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) is the regular ability Ride explicitly synchronizes with the mount.
- [Item Equip Verifier](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/item-equip-verifier/) coordinates rider items around both transitions.
- [Third Person Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/) provides a suitable movement model for a horse-like mount.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains **Ability Index** and **Ability Int Data**.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) configures occupied-mount and `RideMounted` properties.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains concurrent behavior and list priority.

## Developer reference

Rideable defaults to **Manual** start, **Manual** stop, **Ability Index Parameter** `12`, no State name, and `IsConcurrent == true`. **Ride Location**, **Left Dismount Collider**, and **Right Dismount Collider** have no runtime field initializers, although the editor drawer creates and assigns the two clearance colliders when Rideable is added.

Its public properties are `RideLocation`, `LeftDismountCollider`, `RightDismountCollider`, `Ride`, `CharacterLocomotion`, `CharacterLocomotionHandler`, and `GameObject`. The lifecycle methods are `CanMount(Ride)`, virtual `Mount(Ride)`, `OnCharacterMount()`, `CanDismount(ref bool leftDismount)`, `StartDismount()`, and virtual `Dismounted()`.

Rideable sends `OnEnableGameplayInput(false)` during `Awake` and otherwise participates in the standard `OnCharacterAbilityActive` event when it starts or stops. The rider's Ride ability consumes `OnAnimatorRideMount`, `OnAnimatorRideMountComplete`, and `OnAnimatorRideDismount`, sends `OnCharacterForceIndependentLook`, and listens to `OnCharacterAbilityActive` to mirror Speed Change.

The clearance query supports Capsule Collider, Box Collider, and Sphere Collider shapes, checks **Solid Object Layers**, and ignores triggers. Override `Mount` or `Dismounted` for custom mount-side behavior, but call the base implementation so the rider reference, input override, Animator update, and collision cleanup remain intact.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-stop-movement-animation"></a>

# Stop Movement Animation

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/stop-movement-animation/)

Stop Movement Animation prevents a character from running in place or applying horizontal root motion while movement input points into a blocking wall or an active Restrict Position boundary. Use it when the locomotion animation should return to idle before collision resolution holds the character in place.

## Before you begin

- Keep both **Start Type** and **Stop Type** set to **Manual**. The ability uses those defaults because it starts and stops itself from its collision prediction; it does not need an input name.
- The obstacle must be included in the [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) **Solid Object Layers**. Trigger Colliders are not solid obstacles for this check.
- The ability intentionally ignores a dynamic, non-kinematic Rigidbody so a character can continue its movement animation while pushing a movable object.
- Walkable slopes, obstacles below **Max Step Height**, and wall contacts accepted by the locomotion **Wall Glide Curve** do not start the ability.
- Place Stop Movement Animation near the bottom of the **Abilities** list. It is concurrent, but its late update position lets it clear input and horizontal movement after abilities above it have made their changes.

## Add Stop Movement Animation

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities**.
3. Select **+** and add **Stop Movement Animation**.
4. Drag it near the bottom of the list, below stored-input abilities such as Quick Start, Quick Stop, and Quick Turn and below concurrent movement modifiers that it must override.
5. Select the ability and keep **Enabled** selected, **Start Type** set to **Manual**, and **Stop Type** set to **Manual**.
6. Set **Collision Check Distance**. The Version 3 default is `0.1`.
7. Set **Wall Glide Curve Threshold**. The default is `0.1`.
8. Keep **Ability Index Parameter** at `-1` unless a custom Animator Controller intentionally needs a separate blocked-movement state. The supplied behavior uses normal locomotion parameters instead.
9. Enter Play Mode and hold movement input directly into a solid, non-walkable wall.

Do not change the lifecycle selectors to **Automatic**. An automatic start would try to activate without first using this ability's predictive collision check, and an automatic stop would run before its active update can clear the movement values.

## Choose the collision prediction

### Collision Check Distance

**Collision Check Distance** is the distance of a character collision cast in the current movement-input direction. Increase it when a fast or strongly root-motion-driven character must stop its animation earlier. Reduce it when the character returns to idle too far from a wall or hesitates near corners.

The cast direction is normalized after the input has passed the minimum input check, so the distance is not shortened by a partially tilted stick. Test analog input as well as full keyboard input.

The prediction accepts only a hit that should truly block horizontal movement:

- A surface at or below the locomotion **Slope Limit** remains walkable.
- A hit point above the character base but no higher than **Max Step Height** remains stepable.
- A dynamic, non-kinematic Rigidbody remains pushable.
- A wall contact whose **Wall Glide Curve** output exceeds the configured threshold remains glidable.
- Other solid hits are treated as blocking.

### Wall Glide Curve Threshold

Stop Movement Animation evaluates the **Wall Glide Curve** from Ultimate Character Locomotion for the current approach angle. If the curve's output is greater than **Wall Glide Curve Threshold**, the character is allowed to glide and the ability remains inactive.

- Lower the threshold when more angled contacts should keep their locomotion animation and glide along the wall.
- Raise the threshold when more contacts should be treated as blocked and return to idle.
- Tune the locomotion Wall Glide Curve first when the physical glide itself is wrong; use this threshold to decide when the animation should stop.

### Restrict Position boundaries

When [Restrict Position](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-position/) is present and active, Stop Movement Animation also tests the predicted target against that boundary. A restricted target starts this ability even though no wall Collider exists. Keep Stop Movement Animation below Restrict Position when both can change the final movement.

## How Stop Movement Animation runs

While inactive, the ability checks for meaningful movement input and predicts the short move in that direction. A blocking collision or restricted target starts the ability through the normal ability controller.

While active, the same prediction runs every update. If the path remains blocked, the ability clears the locomotion **Input Vector** before the Animator update. This drives **Horizontal Movement** and **Forward Movement** toward zero and changes **Moving** to false. During position application, it also removes the character-relative horizontal components of **Desired Movement** while preserving the vertical component and rotation.

This second movement safeguard is important for root-motion characters. The input direction predicts the obstruction before the next animation movement is available, and the active ability removes horizontal root-motion displacement that would otherwise carry the character into the wall.

Stop Movement Animation is concurrent and has no dedicated animation by default. Its **Ability Index Parameter** is `-1`, and it does not override root-motion, gravity, or rotation settings. The visible result comes from the standard locomotion parameters returning the Animator to its nonmoving state.

Starting this ability stops any active ability derived from `StoredInputAbilityBase` and blocks another one from starting while the collision remains. In Version 3, this includes [Quick Start](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-start/), [Quick Stop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-stop/), and [Quick Turn](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-turn/). When the obstruction clears, Stop Movement Animation stops immediately and resets their stored input history so a stale movement sample does not trigger an animation.

The inherited **State** field is empty by default. Assign a State only when the project needs a property change for the duration of the blocked movement. The included demo also demonstrates a `DisableStopMovementAnimation` State preset for areas where this prediction should be turned off.

## Verify in Play Mode

1. Open the Animator window and watch **Horizontal Movement**, **Forward Movement**, and **Moving** while keeping the active **Abilities** list visible.
2. Hold forward input into a solid wall with an approach angle that cannot glide. Stop Movement Animation should become active, **Moving** should become false, and both movement parameters should settle at zero.
3. Confirm the character does not advance horizontally into the wall. Repeat with root-motion position enabled and verify that the animation also cannot push the character through it.
4. Turn away from the wall without releasing input. The ability should stop immediately, the movement parameters should recover, and locomotion should resume.
5. Approach the same wall at a glancing angle accepted by **Wall Glide Curve**. The ability should remain inactive while the character moves along the surface.
6. Walk onto a ramp within **Slope Limit** and over a step within **Max Step Height**. Neither should be mistaken for a blocking wall.
7. Push a dynamic Rigidbody. Stop Movement Animation should remain inactive for that hit.
8. Add and activate Restrict Position, remove any physical wall from the boundary, and hold input through the limit. The animation and horizontal movement should stop at the invisible boundary.
9. Build movement history for Quick Start, Quick Stop, or Quick Turn, then press into the wall. Confirm the active stored-input ability stops and no stale transition plays when the wall is cleared.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The ability never becomes active | **Enabled**, both lifecycle selectors, **Collision Check Distance**, input magnitude, and **Solid Object Layers**. | Restore **Manual** start and stop, increase the distance slightly, and test a static or kinematic wall on a solid layer. |
| The character returns to idle too far from the wall | The cast distance is longer than the character needs. | Reduce **Collision Check Distance** and retest at the highest expected movement speed. |
| The character freezes instead of gliding along an angled wall | The Wall Glide Curve output does not exceed **Wall Glide Curve Threshold**. | Lower the threshold or adjust the locomotion Wall Glide Curve so that approach angle is glidable. |
| The character glides when it should stop | The threshold is too low for the current Wall Glide Curve. | Raise **Wall Glide Curve Threshold** until the intended contact is treated as blocking. |
| A ramp or curb stops the animation | The surface normal exceeds **Slope Limit**, the hit is above **Max Step Height**, or the collision geometry has a vertical seam. | Correct those locomotion settings or simplify the Collider so the surface is recognized as walkable or stepable. |
| A pushable object does not stop the animation | Its Rigidbody is dynamic and non-kinematic. | This is intentional. Make the obstacle kinematic or use different gameplay logic when it should behave as a fixed blocker. |
| Restrict Position stops movement but the animation keeps playing | Restrict Position is missing, inactive, or later movement logic restores the input after this ability runs. | Confirm Restrict Position is active and place Stop Movement Animation near the bottom of the list. |
| Stop Movement Animation is active but a custom Animator still runs | The custom controller uses raw input or another parameter instead of the standard processed movement values. | Drive the locomotion blend with **Horizontal Movement**, **Forward Movement**, and **Moving**, or clear the custom parameter in the same blocked state. |
| Root motion still nudges the character into the wall | A later concurrent ability rewrites **Desired Movement**, or the prediction starts too late. | Move Stop Movement Animation lower and increase **Collision Check Distance** slightly. |
| Quick Start, Quick Stop, or Quick Turn does not play near a wall | Stop Movement Animation is active and deliberately blocks stored-input abilities. | Correct the false-positive collision or disable this ability with a State in the area where the stored-input animation should win. |

## Related tasks

- [Restrict Position](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-position/) creates the invisible movement boundary this ability can detect.
- [Quick Start](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-start/), [Quick Stop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-stop/), and [Quick Turn](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/quick-turn/) are the stored-input abilities stopped and reset while movement is blocked.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains concurrent updates, list order, States, and active ability inspection.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) documents **Horizontal Movement**, **Forward Movement**, **Moving**, and **Ability Index**.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) defines the solid layers used by the prediction cast.

## Developer reference

The released Version 3 `StopMovementAnimation` API exposes `CollisionCheckDistance` and `WallGlideCurveThreshold`. `IsConcurrent` returns `true`. The configured defaults are **Manual** start, **Manual** stop, `CollisionCheckDistance = 0.1`, `WallGlideCurveThreshold = 0.1`, and **Ability Index Parameter** `-1`.

Its internal collision test first rejects input below the locomotion Collider Spacing threshold. It checks an active `RestrictPosition`, then uses `SingleCast` against **Solid Object Layers**. It rejects dynamic non-kinematic Rigidbodies, walkable slopes, glidable contacts, and step-height hits before accepting the collision.

`ShouldStopActiveAbility` stops `StoredInputAbilityBase` instances when this ability starts, and `ShouldBlockAbilityStart` prevents those abilities from starting while it remains active. `ApplyPosition` clears local X and Z from `DesiredMovement`. Stopping sends `OnStoredInputAbilityResetStoredInputs`.

Normal activation and deactivation are reported through `OnCharacterAbilityActive(Ability, bool)`. There is no feature-specific public collision event. Although the lifecycle type is Manual, external code normally should not start this ability directly: `InactiveUpdate` owns its prediction timing, and the inherited `CanStartAbility()` does not repeat the collision test for an arbitrary manual start.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-slide"></a>

# Slide

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/slide/)

Slide moves a grounded character downhill when the surface is within a configured steepness range. Add it when steep ramps and ledges should carry the character instead of leaving the character standing in place.

## Before you begin

- The character must be grounded on a Collider that Ultimate Character Locomotion can detect. The slope and edge probes use the **Solid Object Layers** configured by the [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) and ignore triggers.
- The ground Collider's Physic Material affects acceleration through its **Dynamic Friction** value. A low-friction surface produces more slide acceleration than a high-friction surface.
- Slide starts and stops automatically. It does not need an input name.
- Slide is concurrent and allows positional and rotational input, so normal locomotion and other compatible abilities can remain active.
- Slide does not select an animation by default. The existing locomotion animation continues unless you configure a custom Animator transition or State.

## Add Slide to the character

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities**.
3. Select **+** and add **Slide**.
4. Select Slide and keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Automatic**.
5. Set **Slide Limit** to the range of slope angles that should trigger a normal slide. The default range is `50` to `89` degrees.
6. Set **Edge Slide Limit** for the shallower angle that may start a slide when the character is at an unsupported edge. The default is `30` degrees.
7. Start with **Acceleration** `0.14`, **Max Slide Speed** `0.54`, and **Slide Damping** `0.08`, then tune them together on representative terrain.
8. Leave **Override Up Direction** at `(0, 0, 0)` to measure slopes against the character's current up direction. Enter a nonzero direction only when the slide test must use a fixed custom up direction.
9. Assign Physic Materials to the test surfaces and choose their **Dynamic Friction** values.
10. Enter Play Mode and approach the test slopes from both uphill and downhill directions.

Because Slide is concurrent, its list position does not give it exclusive priority over other abilities. The position still determines update order. Slide adds to **Desired Movement**, so test the order deliberately when another concurrent ability also changes that value.

## Choose the surfaces that slide

### Regular slopes

**Slide Limit** is a minimum and maximum angle in degrees. The ability can start only while the character is grounded and the detected ground normal is within this range. Raising the minimum reserves sliding for steeper terrain; lowering it makes more ordinary ramps slide.

Keep the maximum greater than the minimum. The maximum is also used to scale acceleration, so a zero-width range cannot produce a useful result.

### Unsupported edges

Slide performs a downward support probe from the character for up to **Max Step Height**. If that probe finds no solid surface, **Edge Slide Limit** replaces the normal minimum angle. This lets a character begin sliding near a drop even when the current surface is not steep enough for the regular minimum.

Raise **Edge Slide Limit** when ordinary ledges trigger too readily. Keep it below **Slide Limit** maximum so the edge acceleration has a usable range.

### Custom up direction

At `(0, 0, 0)`, **Override Up Direction** uses the character's current up direction, including a direction managed by custom gravity. Set a nonzero value only when the slope and edge probes must use a different fixed reference, such as world up.

## Tune speed and surface friction

Slide acceleration increases with both slope angle and **Acceleration**. Within the chosen angle range, a slope close to the minimum contributes little acceleration and a slope close to the maximum contributes more.

The grounded Collider's **Dynamic Friction** reduces that acceleration. Slide uses the ground value directly: increasing Dynamic Friction makes that surface slide more slowly, while decreasing it makes the surface more slippery. Tune the Physic Material before compensating with a very large Acceleration value.

**Max Slide Speed** caps the accumulated slide speed. **Slide Damping** reduces the stored speed every update, including after the character leaves the qualifying slope. Increase damping for a shorter handoff onto flat ground; decrease it when momentum should persist longer.

## How Slide runs

An enabled Slide ability checks for a valid grounded slope every update. When one is found, Slide starts automatically, resets its stored slide speed, and keeps the character attached to the ground while the ability is active.

During the position update, Slide calculates the downhill direction from the ground normal, damps the previous speed, and adds acceleration based on the slope angle and the ground's Dynamic Friction. It then adds the resulting motion to the character's existing **Desired Movement**. If the character already has momentum uphill, Slide first reduces that opposing motion before carrying the character downhill.

A separate flat-step check prevents Slide from accumulating downhill movement across the top of a step. Use a continuous ramp Collider when a staircase should behave as one smooth slope.

After the character reaches ground outside the configured range, the stored speed continues to damp before the automatic stop completes. Becoming airborne force-stops Slide immediately and converts any remaining slide speed into an external force so the momentum is not discarded at the edge.

Slide does not set an Ability Index or change root-motion and gravity settings by default. It also has no feature-specific animation event, so the locomotion animation continues while the slide force is applied.

## Verify in Play Mode

1. Create one ramp below the **Slide Limit** minimum, one within the range, and one above the maximum. Use stable Colliders rather than a visually sloped mesh with unrelated collision geometry.
2. Give the in-range ramp a low-friction Physic Material, walk onto it, and confirm **(Active)** appears beside Slide in **Ultimate Character Locomotion**.
3. Release the movement input. The character should remain grounded and move downhill without an input binding for Slide.
4. Repeat on the below-minimum and above-maximum ramps. Slide should remain inactive on both.
5. Duplicate the valid ramp with a higher **Dynamic Friction** value. The character should accelerate more slowly on the higher-friction version.
6. Move from the valid ramp onto flat ground. Slide should retain a short, damped tail and then become inactive.
7. Leave a qualifying edge. Slide should stop as soon as the character becomes airborne while the remaining downhill momentum continues through the handoff.
8. If the project uses custom gravity, rotate the character's up direction and repeat the test with **Override Up Direction** at zero.
9. Exercise any other concurrent movement ability at the same time and confirm the final direction is correct for the chosen ability order.

## Troubleshoot Slide

| Symptom | Check | Fix |
| --- | --- | --- |
| Slide never becomes active | The ability is disabled, its start type is not **Automatic**, the character is airborne, or the detected angle is outside **Slide Limit**. | Enable Slide, restore **Automatic**, and test a grounded Collider with a known angle inside the range. |
| Slide is active but barely moves | The slope is close to the minimum, **Dynamic Friction** is high, **Acceleration** is low, or **Max Slide Speed** is restrictive. | Lower surface friction or the minimum angle, then increase Acceleration or Max Slide Speed gradually. |
| A ledge starts Slide too early | The support probe cannot find ground within **Max Step Height**, so **Edge Slide Limit** is being used. | Raise Edge Slide Limit or correct the ledge and ground collision geometry. |
| The character keeps sliding after reaching flat ground | Stored speed is still above the automatic stop threshold, or unstable ground normals still qualify. | Increase **Slide Damping** and inspect the Collider normals at the slope transition. |
| The character will not slide down visible stairs | The flat-step guard detects a level step ahead instead of a continuous slope. | Add a smooth ramp Collider over the stair tops when the staircase should act as a slope. |
| The slide direction is wrong with custom gravity | **Override Up Direction** conflicts with the character's actual up direction. | Reset it to `(0, 0, 0)` or supply the intended fixed up vector. |
| Another concurrent ability changes or cancels the motion | Both abilities write movement and their list order produces the unwanted final value. | Reorder the abilities and retest the combined case; use a single movement owner when the results are incompatible. |
| The character moves but no slide animation plays | Slide's **Ability Index Parameter** is `-1` by default and the ability has no dedicated animation. | Add a matching Animator transition and index, or use a [State](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) to apply the custom configuration while Slide is active. |

## Related tasks

- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains automatic activation, concurrency, list priority, States, and the active ability display.
- [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/) controls airborne and landing animation after Slide stops at an edge.
- [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) documents the slope checks that can prevent a jump from starting on steep ground.
- [Character](https://opsive.com/support/documentation/ultimate-character-controller/character/) covers the locomotion Collider, steps, slopes, gravity, and smooth ramp Colliders for stairs.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) defines the solid layers used by Slide's support and slope probes.

## Developer reference

The released Version 3 `Slide` API exposes `SlideLimit`, `EdgeSlideLimit`, `Acceleration`, `MaxSlideSpeed`, `SlideDamping`, and `OverrideUpDirection`. `IsConcurrent` returns `true`. The inherited defaults are **Automatic** start and **Automatic** stop, and the default **Ability Index Parameter** is `-1`.

`CanStartAbility()` requires a valid grounded slope or edge. A normal automatic stop waits until the surface no longer qualifies and the stored slide speed has damped to the locomotion system's Collider Spacing threshold. A forced stop is always allowed.

While active, Slide sets `ForceStickToGround`. It listens for `OnCharacterGrounded(bool)` and force-stops when the character becomes airborne. Start and stop are reported through the standard `OnCharacterAbilityActive(Ability, bool)` event; there is no Slide-specific event.

For script-controlled activation, change **Start Type** to **Manual**, retrieve the ability with `GetAbility<Slide>()`, and call `TryStartAbility` or `TryStopAbility`. The normal start call still runs Slide's grounded-slope check unless the caller explicitly bypasses that check, and a normal stop still respects the stored-speed condition.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-speed-change"></a>

# Speed Change

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/)

The Speed Change ability scales the character's horizontal and forward input for sprinting, sneaking, walking, or another alternate movement speed. It also sets the Animator's **Speed** parameter so states and blend trees can react while the ability remains active.

Speed Change is concurrent, so it can run beside other abilities. With root-motion movement, the selected animation still determines the character's actual displacement; the multiplied input values select the faster or slower animation. Without root motion, the scaled input also changes controller movement.

## Add Speed Change to the character

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Abilities**.
3. Select the plus button and add **Speed Change**.
4. Select the new row and keep **Enabled** selected.
5. For the default hold-to-run setup, keep **Start Type** set to **Button Down Continuous**, **Stop Type** set to **Button Up**, and **Input Names** set to **Change Speeds** or the corresponding input in the project.
6. Configure **Speed Change Multiplier**, **Min Speed Change Value**, **Max Speed Change Value**, **Speed Parameter**, and **Require Movement**.
7. Place Speed Change according to input update order. It can sit anywhere for ability priority, but with the current **NavMeshAgent Movement** ability, keep Speed Change above NavMeshAgent Movement because pathfinding applies the active multiplier when it writes its input.
8. Confirm the Animator has the required movement thresholds and test the input in Play Mode.

## Configure a faster or slower mode

### Sprint or run

The defaults create a typical run mode:

- **Speed Change Multiplier:** `2`
- **Min Speed Change Value:** `-2`
- **Max Speed Change Value:** `2`
- **Speed Parameter:** `2`
- **Require Movement:** enabled
- **State:** `Run`

Input values of `-1` or `1` therefore become `-2` or `2`. Match the movement blend tree's run animations to those multiplied thresholds.

![Movement blend tree using Horizontal and Forward Movement values of negative 2 and 2 for running animations](https://opsive.com/wp-content/uploads/2018/03/SpeedChange.png?v=15d321a03ece)

### Sneak or slow walk

Use a multiplier below `1`, such as `0.5`, to reduce the movement input. Add the slower animations at matching blend-tree thresholds, such as `-0.5` and `0.5`, and set **Speed Parameter** and **State** to values expected by the custom Animator setup.

### Separate movement modes

Speed Change allows duplicate types, so a character can have separate sprint, sneak, or alternate-speed rows with different inputs and Animator values. Avoid allowing multiple Speed Change abilities to remain active together unless their multipliers are intentionally cumulative.

## Choose the multiplier and limits

**Speed Change Multiplier** scales both axes of **Input Vector** and **Raw Input Vector** every update. **Min Speed Change Value** and **Max Speed Change Value** clamp the result after multiplication.

- Increase the multiplier for a faster mode and expand the limits when the Animator and controller support the larger range.
- Use a multiplier between `0` and `1` for a slower mode.
- Keep symmetric negative and positive limits when forward, backward, and lateral input should scale equally.
- Use the limits to prevent diagonal or externally supplied input from exceeding the range represented by the Animator.

For root-motion characters, changing these numbers alone does not make an animation move farther. The Animator must select a clip with the intended root-motion speed.

## Choose when Speed Change stops

The default **Button Down Continuous** and **Button Up** combination creates a held input: Speed Change starts while the input is held and stops when it is released.

- Keep **Require Movement** enabled when releasing movement input should stop the ability immediately. If the speed input remains held, the continuous start type can start it again when movement resumes.
- Disable **Require Movement** when the speed mode should remain active while the character is stationary, such as preparing to sprint before moving.
- Use **Button Down** with **Button Toggle** for a press-on, press-off mode.
- Use **Manual** start and stop types when AI or gameplay code controls the speed mode directly.

When Speed Change stops, it resets the Animator's **Speed** parameter to `0`.

## How Speed Change runs

Speed Change can start when its input condition passes and, if **Require Movement** is enabled, the character is already moving. Starting sets the configured **Speed Parameter** unless that value is `-1`.

Each active update multiplies and clamps the character's processed and raw input vectors. Updating both values lets the locomotion system, Animator, and other abilities observe the same speed mode. If **Require Movement** is enabled and the character stops, Speed Change force-stops without waiting for the button to be released.

Because the ability is concurrent, list position does not give it exclusive control over other abilities. List order still controls update order: an ability that writes a new Input Vector after Speed Change can replace its result, while an input writer before Speed Change is multiplied by it. Pathfinding Movement is a special case because it reads and applies the active multiplier itself.

## Verify in Play Mode

1. Keep the **Ultimate Character Locomotion** Inspector visible, move the character, and hold the configured speed input.
2. Confirm **(Active)** appears beside Speed Change and the Animator's **Speed** parameter changes to the configured value.
3. Confirm **Horizontal Movement** and **Forward Movement** reach the multiplied, clamped thresholds represented by the movement blend tree.
4. Release the speed input and confirm Speed Change becomes inactive and **Speed** returns to `0`.
5. With **Require Movement** enabled, stop directional movement while still holding the speed input and confirm the ability stops; resume movement and confirm it can start again.
6. For root motion, confirm the Animator selects a clip whose motion produces the intended visible speed.
7. If NavMeshAgent Movement is present, keep Speed Change above it and confirm the desired input is scaled once rather than twice.

## Troubleshoot Speed Change

- **Speed Change never starts:** confirm **Enabled**, the **Input Names** mapping, and **Start Type**. With **Require Movement** enabled, begin moving before testing the input.
- **The ability stops whenever the character pauses:** disable **Require Movement** if the mode should persist while stationary.
- **The Animator changes but the root-motion character does not move faster:** add or select an animation with the intended root-motion speed at the multiplied blend-tree threshold.
- **Movement is too fast, too slow, or capped unexpectedly:** check **Speed Change Multiplier** together with the minimum and maximum limits; the result is clamped after multiplication.
- **The wrong movement animation plays:** confirm **Speed Parameter**, **State**, and the Horizontal/Forward Movement thresholds in the Animator.
- **The multiplier appears to apply twice with pathfinding:** place Speed Change above NavMeshAgent Movement. Current Pathfinding Movement applies the active multiplier when it writes its input.
- **Sprint and sneak combine unexpectedly:** ensure duplicate Speed Change abilities do not activate together unless the cumulative multiplier is intentional.
- **A press-on mode turns off on button release:** use **Button Down** with **Button Toggle** instead of the default held-input combination.

## Related topics

- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains input types, concurrent behavior, list priority, and manual start and stop calls.
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) supplies pathfinding input and reads the active Speed Change multiplier.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains **Speed**, **Horizontal Movement**, and **Forward Movement**.
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains the movement states and blend trees that consume those values.

## Developer reference

Speed Change has no feature-specific public event. It uses the shared ability lifecycle and exposes these runtime behaviors:

- **AllowDuplicateTypes:** permits multiple configured Speed Change rows.
- **IsConcurrent:** returns `true`.
- **Default input:** **Change Speeds**.
- **Default state:** **Run**.
- **Default start and stop:** **Button Down Continuous** and **Button Up**.
- **CanStartAbility:** requires the character to be moving when **Require Movement** is enabled.
- **AbilityStarted:** sets the Speed parameter when **Speed Parameter** is not `-1`.
- **Update:** multiplies and clamps both **Input Vector** and **Raw Input Vector**.
- **AbilityStopped:** resets the Speed parameter to `0`.

---

<a id="page-ultimate-character-controller-character-abilities-included-abilities-target-orbit"></a>

# Target Orbit

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/target-orbit/)

Target Orbit reshapes existing movement so a character can strafe around a selected object without drifting away from the current orbit radius. Use it for target-lock combat, circling an interaction point, or AI movement that should follow a consistent arc.

## Before you begin

- Target Orbit does not search for a target. Assign a fixed **Target**, or let [Assist Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/) perform the detection and target switching.
- Target Orbit does not move or rotate the camera. For a player character it uses the current look source to interpret movement input, while the Camera Controller or Assist Aim remains responsible for framing and camera lock.
- The ability modifies movement already produced by a Movement Type, root motion, or another movement source. It needs both nonzero movement input and planar **Desired Movement**; it does not create speed, pathfinding, or collision avoidance.
- The defaults are **Start Type: Automatic**, **Stop Type: Automatic**, **Use Assist Aim Target: disabled**, **Target: None**, and **Rotate Towards Target: disabled**.
- Target Orbit is concurrent. Keep it near the bottom of the **Abilities** list so its position correction runs after the movement abilities it should reshape.
- The target needs a nonzero separation from the character on the plane perpendicular to the character's up direction. A target directly above, below, or at the same position cannot define an orbit direction.

## Orbit a fixed target

1. Select the character GameObject.
2. In **Ultimate Character Locomotion**, expand **Abilities**.
3. Select **+** and add **Target Orbit**.
4. Drag Target Orbit near the bottom of the list, below the abilities that create or modify its input movement.
5. Keep **Enabled** selected, **Start Type** set to **Automatic**, and **Stop Type** set to **Automatic**.
6. Leave **Use Assist Aim Target** disabled.
7. Assign the scene object's Transform to **Target**.
8. Enable **Rotate Towards Target** only when the character should face the target while circling it. It is disabled by default.
9. Enter Play Mode and provide movement both across and along the direction to the target.

The ability starts automatically as soon as its resolved target is non-null. Clearing or destroying the fixed target makes it stop on its next update.

## Use an Assist Aim target

1. Add **Assist Aim** to the same character before the character initializes.
2. Configure Assist Aim's target search. Its default automatic search uses **Enemy Layers**, a **Radius** of `10`, an **Angle** of `10`, and **Require Line Of Sight** enabled.
3. Configure Assist Aim target switching, stickiness, break force, and camera behavior for the required lock-on experience.
4. On Target Orbit, enable **Use Assist Aim Target**.
5. Optionally assign **Target** as a fallback. Target Orbit uses the current `AssistAim.Target` when available; otherwise it falls back to this fixed Transform.
6. Decide which ability owns character facing. Enable **Rotate Towards Target** on Target Orbit, or use Assist Aim's **Rotate Character Towards Target** behavior, then test their order rather than leaving two rotation writers unexamined.
7. Decide whether Assist Aim should move toward the target. Its **Move Character Towards Target** behavior can compete with an orbit setup during item use, so disable it when Target Orbit should be the only movement modifier.
8. Enter Play Mode, acquire several targets, and switch between them while moving.

Enabling **Use Assist Aim Target** does not itself activate Assist Aim, rotate the camera, or perform a search. It only tells Target Orbit where to read its preferred Transform.

## Choose the movement behavior

### Circle, approach, and retreat

Target Orbit changes movement only when the input direction has a component tangent to the current circle around the target.

- Pure sideways movement becomes an arc and receives a small inward correction so repeated steps retain the same radius.
- Input directly toward or away from the target has no tangential component, so Target Orbit leaves that movement unchanged.
- Diagonal input uses its tangential component for the orbit. The existing planar **Desired Movement** supplies the available movement magnitude.
- Vertical movement is preserved and the target's vertical offset is ignored when calculating the orbit plane.

This allows the same locked-on character to circle, approach, or retreat without a separate distance-control ability. Target Orbit does not enforce a minimum or maximum distance.

### Face the target

Enable **Rotate Towards Target** when the character should continually face the target while moving. Target Orbit projects the target direction onto the character's up plane and writes **Desired Rotation** using **Motor Rotation Speed** from Ultimate Character Locomotion. The Version 3 motor default is `0.15`.

Leave the option disabled when the Movement Type, root-motion animation, Assist Aim, or another ability should own facing. With it enabled, Target Orbit replaces the earlier input or root-motion rotation for that update; a later rotation writer can still replace its result.

### Player and camera-relative input

For a player character, Target Orbit converts **Raw Input Vector** through the attached look source's rotation. With a Camera Controller attached, orbit direction is therefore camera-relative. Without a look source, the character's own rotation provides the input frame.

Target Orbit never changes the camera. Pair it with the intended [camera view type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/), or let Assist Aim apply its camera rotational override while active.

### AI input

A character using `LocalLookSource` follows the AI path. Target Orbit requires a nonzero processed **Input Vector**, then uses planar **Desired Movement** as the preferred world direction. If Desired Movement is too small, it falls back to character-relative input.

An AI controller must therefore provide both meaningful locomotion input and movement. Target Orbit bends that movement around the target; it does not replace NavMesh path selection or obstacle avoidance.

## How Target Orbit runs

1. An inactive Target Orbit resolves the Assist Aim target when requested, otherwise the fixed Target, and starts automatically when the result is non-null.
2. The target direction is projected onto the plane perpendicular to the character's current up direction. Vertical separation does not change orbit radius or facing.
3. If **Rotate Towards Target** is enabled, Target Orbit writes the rotation required to face that planar direction.
4. Normal movement, root motion, and active movement abilities calculate **Desired Movement**.
5. During final position application, Target Orbit measures the tangential input relative to the target. If both tangential input and planar Desired Movement exist, it replaces the planar step with an arc that retains the current radius.
6. Target Orbit applies its arc correction during `ApplyPosition`, after the standard collision pass has shaped the original Desired Movement. It performs no second obstacle cast for the corrected arc, so it does not guarantee a clear path around walls or other characters.
7. A changed Assist Aim target is used on the next update without restarting the ability. If both the Assist Aim target and fixed fallback are null, Target Orbit stops automatically.

Target Orbit has no default State or Animator branch and keeps **Ability Index Parameter** at `-1`. Assign the inherited **State** only when lock-on movement should temporarily adjust properties such as Motor Rotation Speed, movement speed, or another compatible locomotion setting.

## Verify in Play Mode

1. Place the character several metres from a fixed target, assign **Target**, and keep the active **Abilities** list and both Transforms visible.
2. Enter Play Mode. Confirm Target Orbit becomes active automatically while the target reference is valid.
3. Move sideways relative to the target for several complete circles. Measure or watch the planar separation and confirm it does not gradually drift.
4. Move directly toward and away from the target. Confirm the character can change radius instead of being forced to circle.
5. Use diagonal input and confirm it produces a controlled arc without an unexpected speed increase.
6. Enable **Rotate Towards Target** and repeat. The character should face the target without pitching toward a target above or below it.
7. Test with root-motion position. Tangential input should reshape the root-motion distance into an arc; without tangential input, the underlying movement remains unchanged.
8. Test the intended camera view from several yaw angles. Player input should remain relative to the look source while Target Orbit leaves camera framing unchanged.
9. Enable **Use Assist Aim Target**, acquire and switch targets, and confirm the orbit changes to the selected target on the next update.
10. Clear the Assist Aim target. Confirm Target Orbit uses the fixed fallback when assigned, or stops when no fallback exists.
11. For AI, drive a nonzero Input Vector and Desired Movement around the target, then verify obstacle avoidance still comes from the AI navigation workflow.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Target Orbit never starts | Both the Assist Aim target and fixed **Target** are null, the ability is disabled, or a blocker rejects the start. | Assign a fixed target or confirm Assist Aim has selected one, then inspect the active ability list. |
| **Use Assist Aim Target** has no effect | Assist Aim was not added before initialization or currently has no target. | Add Assist Aim to the character before Play Mode, verify its detection settings, and optionally assign a fixed fallback. |
| The character does not move | Target Orbit does not generate input or speed, and planar **Desired Movement** is zero. | Supply movement through the active Movement Type, root motion, or AI locomotion before tuning Target Orbit. |
| Forward input approaches the target instead of orbiting | The input is radial and has no tangential component. | Use sideways input to circle. This is expected and allows approach and retreat. |
| The orbit radius slowly changes | A later ability rewrites **Desired Movement**, or another system moves the Transform directly. | Move Target Orbit lower, identify the final movement writer, and let Ultimate Character Locomotion own the Transform. |
| The corrected arc contacts or crosses tight geometry | Target Orbit applies its final correction after the ordinary collision pass and performs no pathfinding. | Increase clearance around the target, let navigation choose a safer path, or implement a project-specific orbit ability that casts the corrected step. |
| The character faces its movement instead of the target | **Rotate Towards Target** is disabled or a later rotation writer replaces it. | Enable the option and inspect the order of active rotation abilities. |
| The character faces the target but turns too slowly | **Motor Rotation Speed** is low. | Increase the value on Ultimate Character Locomotion or apply a lock-on State with the intended value. |
| Root-motion rotation no longer controls facing | **Rotate Towards Target** replaces the earlier root-motion rotation. | Disable the option when the animation should own rotation, or tune Motor Rotation Speed for target-facing movement. |
| The camera does not lock onto the target | Target Orbit never rotates the camera. | Configure Assist Aim's camera behavior or the selected Camera Controller view type. |
| The target changes but movement pulls inward or fights another ability | Assist Aim is also using **Move Character Towards Target**, or two abilities change Desired Movement. | Disable the competing movement behavior or establish an intentional list order and retest. |
| The character stops orbiting when directly above or below the target | The planar target direction is zero. | Keep a nonzero horizontal separation or choose a target Transform with an appropriate projected position. |
| AI movement is unchanged | The character has `LocalLookSource` but no nonzero processed Input Vector. | Supply an input vector as well as Desired Movement from the AI controller. |

## Related tasks

- [Assist Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/assist-aim/) detects, scores, switches, and reports the target that Target Orbit can follow.
- [Rotate Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rotate-towards/) faces a target without reshaping movement.
- [Restrict Rotation](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/restrict-rotation/) can post-process a target-facing rotation into angular steps.
- [Third Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/) provides camera-relative strafing that pairs naturally with target lock.
- [Camera View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/) explains how player framing and look-source rotation are selected.
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/) covers locomotion input and `LocalLookSource` for AI characters.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains concurrent update order, States, and active ability inspection.

## Developer reference

The released Version 3 `TargetOrbit` API exposes `UseAssistAimTarget` and `RotateTowardsTarget`. `IsConcurrent` returns `true`. The defaults are **Automatic** start and stop, both feature booleans `false`, a null fixed target, allowed positional and rotational input, no root-motion override, and **Ability Index Parameter** `-1`.

The serialized fixed `m_Target` field has no public `Target` property in Target Orbit. For runtime target changes, enable `UseAssistAimTarget` and assign `AssistAim.Target`, or expose the protected fixed field from a project-specific subclass. Target resolution prefers a non-null Assist Aim target and otherwise returns the serialized fallback.

`CanStartAbility()` calls the base check and requires a resolved target. `Update()` stops the ability when that target becomes null. Assist Aim target changes can be observed through `OnAimTargetChange(int, Transform, bool)`; Target Orbit itself sends no target-changed, orbit-complete, or radius event.

Start and stop are reported through the standard `OnCharacterAbilityActive(Ability, bool)` event. Use `UltimateCharacterLocomotion.TryStartAbility` and `TryStopAbility` only when changing from the default automatic lifecycle; the target requirement still applies to a manual start.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities"></a>

# Item Abilities

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/)

Item abilities connect character input and animation to equipped items and their Item Actions. Regular [abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) handle character-wide behavior such as jumping, falling, and dying; item abilities handle aiming, using, reloading, blocking, dropping, and switching equipment. They appear in a separate **Item Abilities** list on the Ultimate Character Locomotion component.

Multiple item abilities can usually remain active together. For example, **Aim** can stay active while **Use** fires a weapon. An item ability can still block another ability, change character input or rotation, and control the Animator when its behavior requires it.

## Add and configure an item ability

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Item Abilities**.
3. Select the plus button and choose the concrete item ability type.
4. Select the new row to show its settings below the list, then confirm **Enabled**.
5. Configure its **Input Names**, **Slot ID**, **Action ID**, **Item Category**, and animation settings where that ability exposes them.
6. Drag the row to the required list position. List order does not normally decide whether item abilities may run together, but it does decide which active item ability supplies the Animator state for a slot.
7. Equip a compatible item and verify the complete action in Play Mode.

## Choose by item scenario

### Aim, use, and protect a held item

| Item ability | Default activation | Choose it when |
| --- | --- | --- |
| [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) | Held player input | The character should enter an aiming state. The linked page also covers an always-aim first-person setup. |
| [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) | Player input | An Item Action should fire, swing, cast, throw, or perform another usable action. Multiple Use abilities can target different Action IDs or inputs. |
| [Item Pullback (third person)](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/third-person-item-pullback/) | Automatic | A third-person weapon should pull back near an obstacle and prevent shootable Use and Reload actions while obstructed. |

For specialized melee behavior, [In Air Melee Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/in-air-melee-use/) extends Use for airborne attacks, and [Melee Counter Attack](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/melee-counter-attack/) starts a counterattack after a valid block.

### Defend, reload, or discard equipment

| Item ability | Default activation | Choose it when |
| --- | --- | --- |
| [Block](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/) | System/manual | A Shield Item Action should trigger a block or parry animation when hit. |
| [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) | Player input | A reloadable Item Action should transfer ammunition and complete its reload animation. Duplicate Reload abilities can target different slots or Action IDs. |
| [Drop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) | Player input | The player should unequip and remove an item, optionally spawning its drop prefab. Duplicate Drop abilities can target different slots. |

### Equip and switch loadouts

[Item Set](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/) is the shared authoring reference for equipment-switching abilities. It is an abstract base, so select one of these concrete abilities from the picker instead:

- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs the actual animated equip and unequip operation for an Item Set category.
- [Equip Next](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-next/) and [Equip Previous](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-previous/) move through valid Item Sets in one category.
- [Equip Scroll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-scroll/) chooses the next or previous valid Item Set from an axis value.
- [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) switches between the active Item Set and the category's default set.

## Make the matching decisions first

- **Slot ID** selects the equipment slot an ability controls. On abilities that support it, **-1** applies to all compatible slots.
- **Action ID** must match the Item Action on the equipped Character Item. Use separate Use or Reload abilities when the same item exposes different actions or controls.
- **Item Category** connects an Item Set switcher to an Item Set Group. Add an **Equip Unequip** ability with the same category for Equip Next, Equip Previous, Equip Scroll, or Toggle Equip to perform the change.
- Use separate category-specific switchers when primary weapons, secondary items, or grenades need independent controls.
- If multiple Item Set Groups can supply the same slot, the earlier group in the Item Set Manager has the higher equipment priority.

## Understand concurrency and list order

Item abilities do not use list priority to decide ordinary coexistence. They can be active together unless an ability explicitly blocks or stops another one. Important built-in relationships include:

- **Aim** and **Use** can run together.
- An active **Use** has priority over **Reload** for the item being used.
- **Equip Unequip** can prevent Use or Reload while an item is being unequipped.
- **Drop** resolves active Use or Reload behavior before removing the item.
- **Item Pullback** blocks shootable Use and Reload while its collision volume is obstructed.
- A regular character ability can still block an item ability; Interact is a common example.

List order matters when two active item abilities both provide Animator values for the same slot. The first active row with a usable **Item State Index** or substate value wins for that parameter. Move the animation that should win higher in **Item Abilities**. An **Item State Index** of **-1** means that ability does not provide the parameter.

## Verify in Play Mode

1. Equip the Character Item and confirm its slot, Item Category, and Item Action match the item ability.
2. Keep the **Ultimate Character Locomotion** Inspector visible, trigger the action, and confirm **(Active)** appears beside the expected item ability.
3. Confirm the correct slot changes animation and that the expected Item Action runs.
4. Hold Aim while starting Use and confirm both remain active when the item supports that combination.
5. Try to reload the item while it is actively being used and confirm Use keeps control. After Use stops, confirm Reload can start.
6. For Item Sets, switch to another valid set and confirm Equip Unequip completes the visible equipment and Animator transition.
7. For third-person Item Pullback, move the configured collider near an obstacle and confirm shootable Use and Reload resume only after the obstruction clears.

## Troubleshoot item abilities

- **The ability is missing from the picker:** confirm the required perspective package is installed. **Item Set** is an abstract reference; add a concrete switcher such as Equip Unequip or Equip Next.
- **The row becomes active but the item does nothing:** confirm the item is equipped in **Slot ID** and its Item Action uses the matching **Action ID**.
- **The wrong animation plays:** check **Item State Index**, the item's substate configuration, and which active item ability appears first in the list.
- **An Item Set switcher is disabled or has no effect:** add **Equip Unequip** for the same **Item Category**, then confirm the target Item Set is valid for the current inventory.
- **Use or Reload will not start:** check for an active Equip Unequip, Drop, Item Pullback, Interact, or another item ability that deliberately blocks the action.
- **Equip, reload, block, or drop never completes:** verify the configured animation event or duration on the linked ability and its Item Action.
- **One Item Set Group unexpectedly replaces another:** check Item Set Group order and whether both groups claim the same slot.

## Related topics

- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains the shared lifecycle, input types, and character-ability priority system.
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/) explains the complete character item workflow.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) explains Item Set Groups, validity, and equipment selection.
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) explains how Action IDs connect abilities to item behavior.
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) provides the base authoring workflow used when creating a custom ItemAbility subclass.

## Developer reference

The built-in [event system](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) sends **OnCharacterItemAbilityActive** with the item ability and an active-state boolean whenever an item ability starts or stops. The corresponding Unity event on the locomotion component is also invoked.

```csharp
using UnityEngine;
using Opsive.Shared.Events;
using Opsive.UltimateCharacterController.Character.Abilities.Items;

public class MyObject : MonoBehaviour
{
    /// <summary>
    /// Initialize the default values.
    /// </summary>
    public void Awake()
    {
        EventHandler.RegisterEvent<ItemAbility, bool>(gameObject, "OnCharacterItemAbilityActive", OnItemAbilityActive);
    }

    /// <summary>
    /// The specified item ability has started or stopped.
    /// </summary>
    /// <param name="itemAbility">The item ability that has been started or stopped.</param>
    /// <param name="activated">Was the ability activated?</param>
    /// </summary>
    private void OnItemAbilityActive(ItemAbility itemAbility, bool activated)
    {
        Debug.Log(itemAbility + " activated: " + activated);
    }

    /// <summary>
    /// The GameObject has been destroyed.
    /// </summary>
    public void OnDestroy()
    {
        EventHandler.UnregisterEvent<ItemAbility, bool>(gameObject, "OnCharacterItemAbilityActive", OnItemAbilityActive);
    }
}
```

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-aim"></a>

# Aim

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/)

The Aim item ability puts equipped items into their aiming pose and, when appropriate, turns the character toward the look direction. Use it for held-input aiming in third person, passive aiming in first person, or a character that should remain in an aim state.

## Add and configure Aim

1. Select the character GameObject.
2. In the **Ultimate Character Locomotion** component, expand **Item Abilities**.
3. Select the plus button and add **Aim**.
4. Keep the starting defaults for standard player-controlled aiming: **Start Type** is **Button Down Continuous**, **Stop Type** is **Button Up**, and **Input Names** contains **Fire2**.
5. Keep **State** set to **Aim** and **Item State Index** set to **1** when using the supplied Animator setup.
6. Leave **Activate In First Person** enabled if changing to a first-person View Type should automatically prepare the items and character shadow for aiming.
7. Place **Use** and **Reload** above **Aim** in the **Item Abilities** list. When more than one active item ability supplies Animator values, the higher row has priority; Use or Reload below Aim cannot take control of those values.

Aim does not expose **Slot ID**, **Action ID**, or **Item Category**. One Aim ability supplies its item animation values across the character's slots, so do not add separate copies for individual weapons or categories.

## Choose the aiming behavior

### Hold a button to aim

Use the default **Button Down Continuous**, **Button Up**, and **Fire2** configuration. Holding the input starts Aim, activates the **Aim** State, and changes the fallback item substate from **0** to **1**. Releasing the input stops Aim in third person.

**Stop Speed Change** is enabled by default. An input-started Aim stops an active [Speed Change](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/speed-change/) and prevents it from starting until input aiming ends. Passive first-person aiming does not stop Speed Change.

### Aim automatically in first person

Keep **Activate In First Person** enabled. Entering first person starts Aim even when the player is not holding **Fire2**. This passive start keeps the first-person item pose and the character shadow correct, but it does not activate the **Aim** State or a camera zoom configured through that State.

The player can still hold **Fire2** while Aim is passively active. Aim accepts that second start, activates the **Aim** State, and switches to the input-started substate. Releasing **Fire2** clears the input-started State and zoom but leaves the underlying Aim ability active for as long as the character remains in first person.

Aim does not directly change a Camera Controller field. Configure camera or View Type changes with the [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) under the **Aim** State. Enable **Append Item** only when you also need an item-specific State named by joining `Aim` with the equipped Item Definition name.

### Keep the character aiming

For an always-aim setup, set **Start Type** to **Automatic** and **Stop Type** to **Manual**. This uses the input-style Aim State in every perspective and keeps the ability active until another system or your code stops it.

### Decide who controls rotation

**Rotate Towards Look Source Target** is enabled by default. Aim rotates a character whose Movement Type does not use independent look so the character faces the projected look direction.

Turn the setting off when another system owns facing. Aim also leaves rotation to an active **Assist Aim** configured with **Rotate Character Towards Target**, and it does not force facing when the active Movement Type uses independent look.

## Understand item and Animator behavior

- Aim supplies **Item State Index 1** for every item slot. The Animator uses the first active item ability in list order that supplies a valid value for that slot.
- The normal item substate is **0** for passive first-person aim and **1** for an input-started aim.
- A **Dominant Item** with a usable Item Action can supply its own use substate instead. This allows an item to select a more specific pose, including an unavailable or out-of-ammo variation.
- When third-person **Item Pullback** detects an obstruction, Aim cannot start. If it is already active, its aiming signal and item state values are suspended until the obstruction clears.
- Aim can remain active while **Use** runs. Keep Use and Reload above Aim so their higher-priority item animations can replace Aim temporarily.

## Verify in Play Mode

1. Equip an item and keep the character's **Ultimate Character Locomotion** component visible.
2. In third person, hold **Fire2**. Confirm that **Aim (Active)** appears, the item enters its aim pose, and the character faces the look direction when Aim owns rotation.
3. Release **Fire2** and confirm Aim stops and the item returns to its non-aim pose.
4. Change to first person without holding **Fire2**. Confirm Aim becomes active automatically without applying the input-only camera zoom or State change.
5. Hold and release **Fire2** in first person. Confirm the configured Aim State or zoom turns on and off while **Aim (Active)** remains visible after release.
6. While aiming, use and reload the item. Confirm those animations take priority and Aim resumes afterward.

## Troubleshoot Aim

- **Aim never starts from input:** check that **Input Names** contains the input mapped to the player's aim control, then confirm **Start Type** is **Button Down Continuous** and the ability is enabled.
- **Aim is active but the item does not use its aim pose:** check **Item State Index**, the item's Animator setup, and whether a higher item ability is supplying that slot's state. For the supplied Animator, Aim uses state index **1**.
- **Use or Reload becomes active but its animation does not play:** check the **Item Abilities** list. Move Use and Reload above Aim so they have higher Animator priority.
- **First-person view zooms without a button press:** check how the **Aim** State and camera preset are activated. A passive perspective start deliberately skips the Aim State; **Automatic** Start Type does not.
- **The character does not turn toward the reticle:** check **Rotate Towards Look Source Target**, then check whether the Movement Type uses independent look or Assist Aim already controls rotation.
- **The item leaves its aim pose near a wall in third person:** check [Item Pullback](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/third-person-item-pullback/). Its obstruction handling intentionally suspends the aim signal and item animation values without stopping Aim itself.
- **Only one item uses the wrong aim variation:** check whether that Character Item is marked **Dominant Item** and inspect the substate returned by its usable Item Action.

## Related tasks

- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains concurrency, list order, and the shared item-ability workflow.
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) explains the actions that provide item-specific use substates.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) describes **Aiming**, **Item State Index**, and **Item Substate Index**.
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/) explains first-person and third-person camera perspectives.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains how the **Aim** State can apply camera, item, or character presets.

## Developer reference

The public Aim properties are **StopSpeedChange**, **ActivateInFirstPerson**, **RotateTowardsLookSourceTarget**, and the read-only **InputStart** value. **InputStart** distinguishes a button or Automatic start from passive first-person aiming. Aim overrides **GetItemStateIndex** and **GetItemSubstateIndex** to provide the per-slot Animator values described above.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) sends two Aim-specific events:

- **OnAimAbilityStart** `(bool aim, bool inputStart)` reports starts and normal stops. The second value is `false` for a passive first-person start.
- **OnAimAbilityAim** `(bool aim)` is the general aiming signal used by item, Animator, and IK systems. Third-person Item Pullback temporarily sends `false` without stopping the underlying Aim ability.

Register for the input-aware event when custom gameplay should react only to deliberate player aiming:

```csharp
using Opsive.Shared.Events;
using UnityEngine;

public class AimListener : MonoBehaviour
{
    private void Awake()
    {
        EventHandler.RegisterEvent<bool, bool>(gameObject, "OnAimAbilityStart", OnAim);
    }

    private void OnAim(bool aim, bool inputStart)
    {
        if (!inputStart) {
            return;
        }

        Debug.Log($"Input aim active: {aim}");
    }

    private void OnDestroy()
    {
        EventHandler.UnregisterEvent<bool, bool>(gameObject, "OnAimAbilityStart", OnAim);
    }
}
```

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-block"></a>

# Block

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/)

The Block item ability plays a block or parry reaction when an equipped Shield Item Action is struck. The Shield Action and its collider decide whether damage is absorbed; Block supplies the reaction's item Animator values and ends it at the configured completion point.

## Before you begin

The defending Character Item needs a **Shield** Item Action and a correctly sized **Shield Collider** on each visible first-person or third-person object that should receive hits. Its Animator also needs states for the **Block Item State Index** and **Parry Item State Index** values used by the character.

Creating or updating an item with a **Shield** action through **Tools > Opsive > Ultimate Character Controller > Item Manager** performs most of this setup. The builder adds a Shield Action, an **Attribute Manager** with a **Durability** Attribute, and perspective-specific Shield Collider components. When the item is built directly on a character, it also adds a Block item ability if the character does not already have one. Resize each generated collider to cover the intended defensive surface.

## Configure the shield and Block

1. Open the **Item Manager**, create or select the Character Item, and add **Shield** to its **Actions** list. Select **Build Item** for a new item or **Update Item** for an existing one.
2. Select each visible shield object. Confirm its **Shield Collider** references the Character Item's **Shield Action**, and keep **Disable On Unequip** enabled unless the holstered object should continue receiving hits.
3. On the **Shield Action**, decide whether protection **Require Aim**. This is disabled by default.
4. Set **Absorption Factor**. The default of **1** absorbs all eligible damage; **0** passes all damage through to the character, and values between them split the damage.
5. Configure **Impact Animator Audio State Set** with the impact substate and any audio or State that should accompany the reaction.
6. Keep **Apply Impact** enabled when the shield should start Block and play its impact state or audio. Damage absorption still works when this option is disabled, but no Block reaction is requested.
7. Configure **Impact Complete Event**. Its starting default uses a **0.2** second duration rather than waiting for an animation event. Use an animation event when the clip length should control the reaction precisely.
8. Select the character, expand **Item Abilities** on **Ultimate Character Locomotion**, and select **Block**. Its **Start Type** and **Stop Type** are both **Manual** because Shield impacts control the lifecycle.
9. Set **Slot ID** to **-1** to respond to Shield Actions in every slot, or enter one slot ID to limit this Block ability. Keep **Block Item State Index** at **8** and **Parry Item State Index** at **9** when using the supplied Animator.
10. Place Block above [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) when the reaction animation should replace the aim pose. List order controls which active item ability supplies the Animator values for a slot.

Block does not filter by **Action ID** or **Item Category**. It listens for any Shield Action impact, then uses only **Slot ID** to decide whether to react. Item Definition and category choices still control how the item enters the inventory and equipment set, but they do not select the Block ability.

## Choose the protection behavior

### Require deliberate aiming

Enable **Require Aim** when the collider should protect the player only while they are actively aiming. For a player character, an input-started [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) satisfies this requirement; passive first-person Aim does not. AI characters using a local look source can update the shield from their programmatically controlled Aim state.

When **Require Aim** is disabled, an equipped shield can absorb any eligible hit that contacts its enabled Shield Collider.

### Use durability or an invincible shield

Leave **Durability Attribute Name** set to **Durability** to use the Attribute Manager created by the Item Manager. The shield removes only the amount it actually absorbs from that Attribute. When the Attribute reaches its minimum, later damage passes through to the character.

Leave the name empty for a shield that does not degrade. **Drop When Durability Depleted** is disabled by default; enable it when reaching the minimum should remove and drop one copy of the Character Item.

**Absorb Explosions** is disabled by default. An Explosion therefore bypasses both shield absorption and the Block reaction unless this option is enabled.

### Choose block or parry animation

A Character Item with a Shield Action uses **Block Item State Index 8**. If that same defending item also has a **Melee** Item Action, Block treats the reaction as a parry and uses **Parry Item State Index 9**. This choice describes the defending item: adding a Melee Action to a sword-and-shield-style item enables a parry reaction, while an ordinary shield uses block.

The attacking item affects the more detailed **Item Substate Index**, not the block-versus-parry choice. A melee attack can contribute its Animator Item ID and current use substate so different weapons or attack directions select different reaction clips.

Block and parry use the same Shield Action damage calculation. Parry changes the selected animation state; it does not grant a different absorption factor by itself.

### Complete one slot or all slots

With **Slot ID -1**, one Block ability can track simultaneous Shield impacts in multiple item slots and remains active until every reaction completes. Use the shared **OnAnimatorItemImpactComplete** event or a duration for this all-slot setup.

A slot-specific completion event is intended for a specific **Slot ID** and uses **OnAnimatorItemImpactCompleteSlot&lt;slotID&gt;**. This lets one hand complete without ending a reaction still running in another slot.

## How it runs

1. An impact hits the enabled Shield Collider for the current camera perspective.
2. The Shield Action checks **Require Aim** and **Absorb Explosions**, then applies **Absorption Factor** and any available durability before the remaining damage reaches the character.
3. When **Apply Impact** is enabled, the Shield Action selects its next impact Animator/audio state and sends **OnShieldImpact**.
4. Block ignores the request if the slot does not match or the character is currently using an item. Otherwise it starts, supplies the block or parry state index for that shield's slot, and updates the Animator.
5. The Shield Action's impact substate is used directly for a non-melee source. For a melee source, Block combines the attacker's Animator Item ID, attack use substate, and shield impact substate so the Animator can select a more specific reaction.
6. The configured duration or Animator event ends that slot's reaction. Block stops after no shield impacts remain.

Block and damage protection are related but separate. A shield can absorb damage with **Apply Impact** disabled, and an active Block row only indicates that a visual impact reaction is in progress.

## Understand ability order

Block does not use list priority to decide whether the shield may absorb damage. It explicitly declines a new reaction while any **Use** item ability is active, because the character cannot start a block reaction while using an item.

List order still controls animation when Block and another item ability are active together. Put Block above Aim or another persistent pose when the impact reaction should win. Decide its position relative to Reload or other short actions according to which animation should remain visible; the first active item ability with a valid value for that slot supplies the Animator parameter.

## Verify in Play Mode

1. Equip the Shield item and keep **Ultimate Character Locomotion**, the character's health, and the shield's **Durability** Attribute visible.
2. Strike the Shield Collider with a non-explosion attack. Confirm **Block (Active)** appears briefly, the slot uses **Item State Index 8**, and only unabsorbed damage reaches the character.
3. Confirm the reaction ends after **0.2** seconds or after the configured impact-complete Animator event.
4. Enable **Require Aim**, repeat the hit without aiming, and confirm all damage passes through. Hold the Aim input and repeat the hit; confirm the shield now absorbs it.
5. Add or test a defending item that contains both Shield and Melee actions. Confirm the reaction uses **Item State Index 9** for parry.
6. Test an Explosion with **Absorb Explosions** off and on, confirming that only the enabled case is absorbed.
7. If using durability, repeat impacts until the Attribute reaches its minimum. Confirm further damage reaches the character and, when enabled, the shield item is dropped.

## Troubleshoot Block

- **The character takes damage and Block never starts:** check that the hit collider has **Shield Collider**, its **Shield Action** reference is assigned, and the collider is enabled for the active perspective. Resize the collider so the attack actually contacts it.
- **The shield absorbs damage but no reaction plays:** enable **Apply Impact**, add at least one **Impact Animator Audio State Set** entry, and confirm the Block **Slot ID** accepts the shield's Character Item slot.
- **Block becomes active but the aim or reload pose remains visible:** check **Item Abilities** order. Move Block above the active pose that should yield, then confirm state indexes **8** and **9** exist in the Animator.
- **A hit during an attack does not start Block:** the built-in ability declines shield reactions while **Use** is active. Finish or stop Use before testing the block.
- **Require Aim never protects the player in first person:** press the Aim input. Passive first-person Aim intentionally does not satisfy **Require Aim** for a player character.
- **Durability never decreases:** verify an **Attribute Manager** exists on the Character Item and that **Durability Attribute Name** exactly matches the Attribute. An empty or unresolved name behaves as a non-degrading shield.
- **Block remains active:** check **Impact Complete Event**. If it waits for an animation event, add **OnAnimatorItemImpactComplete** to the clip, or use the configured duration. Use a specific Block **Slot ID** before relying on a slot-specific completion event.
- **The wrong parry animation plays:** confirm the defending item contains a Melee Action only when it should use the parry state, then verify the attacker's **Animator Item ID**, melee use substate, and the shield impact substate.

## Related tasks

- [Shield Item Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/shield/) covers damage absorption, durability, and impact presentation.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) explains how to build or update a Character Item through the Item Manager.
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) explains input-started aiming and why passive first-person Aim is different.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) explains the item ability that prevents a new Block reaction while active.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) describes **Item State Index** and **Item Substate Index**.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the supplied item state conventions.

## Developer reference

Block exposes **SlotID**, **BlockItemStateIndex**, **ParryItemStateIndex**, and the read-only **ImpactSources** array. **StartBlock(ShieldAction, ImpactCallbackContext)** is public, while **GetItemStateIndex** and **GetItemSubstateIndex** provide the per-slot Animator values.

For a melee impact, the substate is calculated as:

```text
(attacker Animator Item ID * 1,000,000)
+ (attacker melee use substate * 1,000)
+ shield impact substate
```

For example, Animator Item ID `22`, melee use substate `3`, and shield impact substate `1` produce `22003001`. Keep each component below `1000` if the Animator decodes the value as three groups.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) coordinates the reaction:

- **OnShieldImpact** `(ShieldAction, ImpactCallbackContext)` is sent by Shield Action when **Apply Impact** is enabled. Block receives it and calls **StartBlock**.
- **OnAnimatorItemImpactComplete** ends every active reaction that does not require a slot event.
- **OnAnimatorItemImpactCompleteSlot&lt;slotID&gt;** ends the reaction for a Block ability configured to that slot.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` is the standard item-ability lifecycle event and reports Block starting and stopping.

The Shield Action separately exposes **Damage**, **StopBlockImpact**, **DurabilityValue**, and **WaitingForImpactCompleteEvent** for custom damage or UI integrations.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-drop"></a>

# Drop

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/)

The Drop item ability removes one unit of an equipped Character Item and can leave its pickup prefab in the world. Use it for a player-controlled discard action or any other workflow that should drop the item currently held in one or more slots.

## Before you begin

The character needs an Inventory, at least one equipped Character Item, and a Drop item ability. To leave a world object behind, the equipped Character Item also needs a **Drop Prefab**.

Use a prefab with **Item Pickup** when the player should be able to collect the dropped object again. Drop writes the main Item Definition and amount into that pickup and also includes any extra item amounts supplied by the Character Item's actions, such as associated ammunition. A prefab without Item Pickup can still appear as a visual or physics object, but Drop cannot configure it as a collectible.

For an equipped item, the ability uses the **Drop Prefab** on that Character Item. The Inventory component's default **Drop Prefab** is not a fallback for an equipped Character Item whose field is empty. Leaving the Character Item field empty therefore removes the inventory unit without spawning a world object.

## Configure Drop

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager** and create or select the Character Item that can be dropped.
2. Assign its **Drop Prefab**, which is unassigned by default. Confirm the prefab has an Item Pickup component if it should restore inventory when collected.
3. Select the character, expand **Item Abilities** on **Ultimate Character Locomotion**, select the plus button, and add **Drop**.
4. Keep the standard input defaults for a player discard action: **Start Type** is **Button Down**, **Stop Type** is **Manual**, and **Input Names** contains **Drop**. The ability stops itself after the item has been processed.
5. Keep the default **Slot ID -1** to inspect every equipped slot, or enter one slot ID to drop only the active item in that slot.
6. **No Drop Item Definitions** is empty by default. Add protected definitions when needed. A slot-specific Drop cannot start for an excluded definition. In the released Version 3 implementation, do not rely on this list to protect one item during an all-slot drop; use separate slot-specific Drop rows when exclusions must be enforced.
7. Leave **Wait For Unequip** disabled for an immediate discard. Enable it only when the item's Equip Unequip ability and Item Set group should return to the group's default Item Set before removal. In released Version 3, use this option with **Slot ID -1** or slot **0**; use the direct Drop Event path for a single nonzero slot.
8. Configure **Drop Event**. Its starting values have **Wait For Animation Event** disabled and **Duration** set to **0**. Increase the duration for a timed release, or enable **Wait For Animation Event** when an animation clip should call **OnAnimatorDropItem** at the exact release frame.

Drop has no **Item Category** or **Action ID** selector. It always evaluates the active Character Item in the selected slot or slots. The ability allows duplicate types, so separate Drop rows can use different inputs, slots, exclusion lists, or timing when the character needs more than one discard action.

## Choose the drop behavior

### Drop one slot or every equipped slot

Use a specific **Slot ID** when an input should discard one hand, weapon slot, or other fixed equipment location. The ability can start only while that slot contains an active Character Item that is not excluded.

Use **-1** when the same input should discard every equipped item. Drop removes one inventory unit for each active slot; it does not remove the entire stack. Empty slots are ignored. See the released-Version-3 limitation below before combining all-slot mode with **No Drop Item Definitions**.

### Remove immediately or unequip first

With **Wait For Unequip** disabled, the Drop Event controls when the item is removed. A zero-duration event makes the discard effectively immediate. A short duration or **OnAnimatorDropItem** event can synchronize removal with a release animation.

With **Wait For Unequip** enabled, Drop asks every matching Equip Unequip ability to equip its Item Set group's default set. Each item is removed when its unequip-complete notification arrives, and Drop stops after all selected items have completed.

The Drop Event wait also begins when the ability starts. Do not leave it on an earlier zero-duration callback when the item must finish unequipping first, because that callback can process and stop Drop before the unequip-complete path. Coordinate the event with the unequip animation, and verify that the character has an Item Set Manager, a matching Equip Unequip ability, and a valid default Item Set.

### Spawn a pickup or only remove inventory

When the Character Item has a **Drop Prefab**, Drop spawns it at the currently visible item object's position and rotation before changing the inventory count. An Item Pickup component receives the main unit being removed, limited to the amount currently in inventory, plus the additional item identifiers returned by the Character Item's actions.

If the prefab has a **Trajectory Object**, Drop initializes it with the character's current locomotion velocity and torque. Drop does not add a forward throwing impulse. Use the prefab's physics and Trajectory Object configuration for the desired fall or movement; use a throwable Item Action rather than Drop for an aimed projectile throw.

The Character Item's **Full Inventory Drop** option is disabled by default and is intended for throwable-item workflows. The Drop ability itself requests exactly one unit and does not use that setting to empty the stack.

## How it runs

1. The input attempts to start Drop. The ability caches the active Character Item in the selected slot, or the active items across all slots when **Slot ID** is **-1**.
2. A slot-specific Drop refuses to start for an empty or excluded item. An all-slot Drop requires at least one active item that is not excluded before it can start.
3. Starting Drop stops an active **Use** or **Reload** item ability. While Drop remains active, it also prevents either ability from starting.
4. The ability supplies **Item State Index 6** and begins its Drop Event wait. When **Wait For Unequip** is enabled, it also requests the appropriate default Item Sets.
5. At the Drop Event or accepted unequip-complete point, the Inventory first attempts to create the Character Item's Drop Prefab. It then removes one unit and removes or unequips the corresponding Character Item from the slot.
6. Drop stops after the direct Drop Event has processed every cached item, or after every selected item has reported unequip completion.

Drop's direct Use and Reload rules do not depend on list order. List order still controls which active item ability supplies Animator values for a slot. If Drop waits for a release clip while a persistent ability such as [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) remains active, place Drop above that ability when **Item State Index 6** should win during the discard.

## Verify in Play Mode

1. Equip an item that has a Drop Prefab and keep the character's Inventory and **Ultimate Character Locomotion** components visible.
2. Press the **Drop** input. Confirm **Drop (Active)** appears, any active Use or Reload ability stops, and the selected slot loses one unit.
3. Confirm the world object appears at the Character Item's visible-object transform when the drop is processed. Walk into it and verify its Item Pickup restores the configured item amount.
4. Equip items in two slots, set **Slot ID** to **-1**, and press Drop. Confirm one unit is removed from each active slot.
5. To protect an item definition, configure a Drop row for that specific slot, add the definition to **No Drop Item Definitions**, and press its input. Confirm the ability does not start for that item.
6. If using a timed or animation-event release, confirm the world object appears on the intended frame and Drop stops immediately afterward.
7. If using **Wait For Unequip**, confirm the item finishes its unequip animation, the default Item Set becomes active, and only then is the pickup created and the inventory amount removed.

## Troubleshoot Drop

- **Pressing Drop does nothing:** check that the input name is mapped, **Start Type** is **Button Down**, the selected **Slot ID** contains an active Character Item, and its definition is not in **No Drop Item Definitions**.
- **The item disappears but no object appears:** assign **Drop Prefab** on the Character Item itself. The Inventory's default prefab does not replace a missing prefab for an equipped Character Item.
- **The object appears but cannot be collected:** check that the prefab has Item Pickup and its required trigger collider and layer setup. Rebuild or update the pickup rather than using only the held visual prefab.
- **The dropped object does not move away from the character:** Drop does not apply a throwing impulse. Check the prefab's Rigidbody or Trajectory Object setup, or use a throwable Item Action for a directed throw.
- **An excluded item is still removed by an all-slot Drop:** this is a released-Version-3 limitation. The start check recognizes the excluded definition, but the later all-slot processing retains that active Character Item when another slot is eligible. Use separate slot-specific Drop rows and apply **No Drop Item Definitions** to each row that must protect an item.
- **Wait For Unequip still drops immediately:** check **Drop Event**. A zero-duration callback can run before the unequip completes; coordinate the event timing, then confirm an Item Set Manager and matching Equip Unequip ability can select a valid default set.
- **Wait For Unequip fails for a specific nonzero slot:** this is a released-Version-3 limitation in the unequip-complete lookup. Use **Slot ID -1** or slot **0** for that path, or disable **Wait For Unequip** and synchronize the direct Drop Event instead.
- **Drop remains active:** when **Wait For Animation Event** is enabled, add **OnAnimatorDropItem** to the release clip. For **Wait For Unequip**, confirm the item reaches its unequip-complete event.
- **The drop animation is hidden by Aim or another persistent pose:** move Drop above the ability that should yield so **Item State Index 6** has Animator priority while Drop is active.
- **Using or reloading stops when Drop begins:** this is the built-in concurrency rule. Finish the action before dropping, or customize the ability interaction when a different design is required.

## Related tasks

- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains list order, inputs, and shared item-ability behavior.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) describes **Drop Prefab**, item identity, and the held item object.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) covers the collectible component expected on a reusable drop prefab.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) explains how to build or update Character Items with the Item Manager.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) controls the default Item Set transition used by **Wait For Unequip**.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists **Drop** as Item State Index **6**.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) and [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) describe the two item abilities that Drop stops and blocks.

## Developer reference

Drop exposes **SlotID**, **NoDropItemDefinitions**, **WaitForUnequip**, and **DropEvent**. Its read-only **DroppedItems** collection contains the spawned objects recorded by the direct Drop Event path. The unequip-complete path removes and drops its items without adding those returned objects to that collection.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) coordinates the lifecycle:

- **OnAnimatorDropItem** completes a Drop Event configured to wait for an animation event.
- **OnAbilityUnequipItemComplete** `(CharacterItem, int slotID)` lets **Wait For Unequip** process an item after its unequip finishes.
- **OnInventoryDropItem** is sent for the spawned object and also has a Character Item form `(CharacterItem, int amount, GameObject droppedObject)` for item-specific listeners.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` reports Drop starting and stopping like other item abilities.

The Character Item's **Drop Item** UnityEvent is also invoked whenever its drop operation runs, including when no Drop Prefab was assigned.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-item-set"></a>

# Item Set

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/)

Item Set abilities turn the valid equipment combinations generated by the Item Set Manager into player controls. Use them when a character should equip a numbered loadout, cycle weapons, scroll through available gear, or holster and restore one category without disturbing another.

**Item Set** is an abstract base and does not appear as a concrete choice in the ability picker. Add [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) to perform each equipment transition, then add one or more selector abilities that tell it which Item Set to use.

## Before you begin

The character needs these parts on the same GameObject:

- an Inventory containing the Character Items that may be equipped;
- an **Item Set Manager** with its **Item Collection** assigned;
- at least one entry under **Item Set Groups**, with an **Item Category** and one or more **Item Set Rules**; and
- one **Equip Unequip** item ability for each Item Category that needs independent equipment control.

The Item Set Manager creates the runtime **Item Sets** from its rules and current inventory. A set is valid only when the character has the items required by that combination. Cycling abilities also respect whether a set can be switched to.

## Configure an Item Set ability group

1. Select the character and open its **Item Set Manager**.
2. Assign the same **Item Collection** used to define the character's items and categories.
3. Expand **Item Set Groups**, add a group, and assign its **Item Category**. Add the **Item Set Rules** that describe valid slot combinations for that category.
4. On **Ultimate Character Locomotion**, expand **Item Abilities**, select the plus button, and add **Equip Unequip**.
5. Set the Equip Unequip **Item Category** to the category used by the Item Set Group. Keep **Prevent Start Use Reload Active** enabled unless this category is intentionally allowed to change while any Use or Reload item ability is active.
6. Add the selector that matches the intended control: **Equip Next**, **Equip Previous**, **Equip Scroll**, or **Toggle Equip**. Assign the same **Item Category** and configure its input.
7. Repeat the Equip Unequip and selector pairing for each independently controlled category, such as primary weapons and grenades.
8. If the equip or unequip animation must override a persistent pose such as Aim, place **Equip Unequip** above that pose in the **Item Abilities** list. The selector row stops after delegating and does not supply an item animation state of its own.

**Item Category** is unassigned by default. At runtime an unassigned Item Set ability uses the first Item Set Group's category. That fallback is convenient for a character with one group, but explicit assignments are safer and easier to verify when the character has multiple groups.

**Prevent Start Use Reload Active** is enabled by default. It checks for any active Use or Reload ability on the character, not only an action in the same category or slot. Keep the setting consistent across the selector and its Equip Unequip row unless the difference is deliberate.

## Choose the control by player goal

| Goal | Ability | Starting defaults | What it selects |
| --- | --- | --- | --- |
| Press a numbered key for a known set | [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) | **Button Down**; **Equip First Item** through **Equip Tenth Item** | The input's position maps directly to the Item Set index, then the ability performs the transition. |
| Cycle forward through available sets | [Equip Next](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-next/) | **Button Down**; **Equip Next Item** | The next valid, switchable set in the category, wrapping around the list. |
| Cycle backward through available sets | [Equip Previous](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-previous/) | **Button Down**; **Equip Previous Item** | The previous valid, switchable set in the category, wrapping around the list. |
| Use one bidirectional axis or mouse wheel | [Equip Scroll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-scroll/) | **Axis**; **Mouse ScrollWheel**; **Scroll Sensitivity 0.1** | Next for a positive axis value and previous for a negative value once the sensitivity threshold is reached. |
| Holster a category and restore its last valid set | [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) | **Button Down**; **Toggle Item Equip**; **Toggle Default Item Set On Start** disabled | The category's default set or the previously active non-default set. |

All five concrete abilities use the base **Stop Type Manual**. The selector abilities stop themselves immediately after requesting a change. Equip Unequip stops after its unequip, equip, and completion events have finished.

Equip Unequip starts with **Auto Equip** set to **Unequipped**, **Out Of Usable Item**, **Not Preset**, and **First Time**; **Always** is not selected. Its supplied Animator defaults are **Equip Item State Index 4**, **Unequip Item State Index 5**, and **Aim Item Substate Index Addition 100**.

## Make the category and rule decisions

### Use one group for each independent equipment family

An Item Set ability resolves its **Item Category** to one Item Set Group. A matching Equip Unequip row is required for Equip Next, Equip Previous, Equip Scroll, and Toggle Equip; a selector logs an error and disables itself when no match exists.

Use separate groups and duplicate selector types when the controls should be independent. For example, a primary-weapon group can use the mouse wheel while a grenade group uses a toggle button. Both can operate on the same character because each pair targets a different category ID.

If multiple Item Set Groups claim the same equipment slot, the earlier group in **Item Set Groups** has priority. Reorder the groups or change their rules when one category unexpectedly preserves or replaces another category's item.

### Decide which sets can be selected

Equip Next, Equip Previous, and Equip Scroll skip sets that are invalid for the current inventory or cannot be switched to. This means list order expresses the cycle order, but it does not guarantee that every row will appear during play.

The default Item Set represents the category's unequipped or fallback state. Toggle Equip returns to that default and later restores the remembered non-default set when it is still valid. Keep a valid default when the category needs a reliable holstered state.

### Decide whether switching waits for actions

Keep **Prevent Start Use Reload Active** enabled for weapons that should finish firing or reloading before they switch. Disable it only when the design supports an equipment change during those actions and the item animations, inventory changes, and action modules have been tested together.

The setting prevents the Item Set ability from starting; it does not cancel the active Use or Reload action. An active Equip Unequip also blocks a new Use or Reload while an item is in its unequip phase.

## How it runs

1. The Item Set Manager evaluates its Item Set Rules against the Inventory and builds the valid Item Sets for each group.
2. Input starts a selector or starts Equip Unequip directly. The ability resolves **Item Category** to its Item Set Group.
3. The shared start check rejects the request while Use or Reload is active when **Prevent Start Use Reload Active** is enabled.
4. A selector finds the requested valid index and calls its category-matched Equip Unequip ability. The selector then stops.
5. Equip Unequip compares the active and target sets slot by slot. It unequips items that should leave, waits for their configured events, equips the new items, and waits for their completion events.
6. During the transition, Equip Unequip supplies Item State Index **5** for an unequipping slot and **4** for an equipping slot. Aiming adds **100** to the Character Item's equip or unequip substate.
7. The Item Set Manager records the new active set, applies its State when one is configured, and notifies UI or gameplay listeners of the change.

The ability list position does not pair a selector with Equip Unequip; their matching Item Category does. List position matters only when Equip Unequip and another active item ability both offer Animator values for the same slot.

## Verify in Play Mode

1. Give the character the Item Definitions required by at least two sets in one group.
2. Keep **Item Set Manager** and **Ultimate Character Locomotion** visible. Confirm the group's runtime **Item Sets** list contains the expected combinations and shows a valid active set.
3. Trigger the category's selector. Confirm that selector becomes active only briefly, while its matching **Equip Unequip (Active)** remains visible through the equipment transition.
4. Confirm the old item uses **Item State Index 5**, the new item uses **Item State Index 4**, and the visible objects change only at their configured animation events or durations.
5. Cycle in both directions and confirm invalid or non-switchable sets are skipped and the sequence wraps through the valid choices.
6. Start Use or Reload and try to switch. With **Prevent Start Use Reload Active** enabled, confirm the set does not change until that action stops.
7. If the character has two Item Set Groups, operate each category's control and confirm the other category remains unchanged unless their rules intentionally share a slot.

## Troubleshoot Item Set abilities

- **Item Set is missing from the ability picker:** it is an abstract base. Add Equip Unequip or one of the four concrete selectors listed above.
- **A selector disables itself at runtime:** check that the character has an Item Set Manager group and an Equip Unequip ability with the same **Item Category**. Assign the category explicitly instead of relying on the first-group fallback.
- **The group contains no usable Item Sets:** check **Item Collection**, **Item Category**, **Item Set Rules**, and the Character Items currently in Inventory. The character must own every required item in a combination before that set is valid.
- **Next, Previous, or Scroll appears to skip a set:** inspect the runtime Item Set and confirm it is valid and can be switched to. Skipping an unavailable set is expected.
- **A numbered input equips the wrong set:** the Equip Unequip input position maps to the runtime Item Set index. Check the generated order and the input's position in **Input Names**.
- **Switching never starts while firing or reloading:** **Prevent Start Use Reload Active** is enabled by default and checks all active Use and Reload abilities. Wait for the action to finish or deliberately disable the option on the relevant rows.
- **Equip Unequip becomes active but never finishes:** check the Character Item's **Equip Event**, **Equip Complete Event**, **Unequip Event**, and **Unequip Complete Event**. Add the required Animator events or use verified durations.
- **The equip animation is hidden by Aim or another pose:** move Equip Unequip above the competing active item ability so state indexes **4** and **5** win for the affected slot.
- **Changing one category affects another:** check whether their Item Set Rules claim the same slot. The earlier Item Set Group has priority when groups overlap.

## Related tasks

- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) explains how groups, rules, validity, default sets, and group priority determine the generated combinations.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) explains how the character owns the Item Definitions that make sets valid.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) covers the equip and unequip timing stored on each item.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains shared inputs, concurrency, and Animator list order.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) describes Item State Index and Item Substate Index.

## Developer reference

`ItemSetAbilityBase` exposes **ItemCategory**, **ItemSetCategoryID**, **PreventStartUseReloadActive**, and the resolved read-only **ItemSetGroupIndex**. Equip Next, Equip Previous, Equip Scroll, Toggle Equip, and Equip Unequip allow duplicate types so code or authoring tools can create one category-specific copy per workflow.

Use `EquipUnequip.StartEquipUnequip(itemSetIndex)` when code already has the matching ability and index. Overloads accept `forceEquipUnequip` and `immediateEquipUnequip`. The Item Set Manager also exposes `TryEquipItemSet` overloads for a set name, index, or Item Set object; these validate the set and delegate to its Equip Unequip ability.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) reports the important transitions:

- **OnItemSetManagerUpdateNextItemSet** `(int groupIndex, int previousIndex, int nextIndex)` reports the pending set.
- **OnActiveItemSetChange** `(int groupIndex, ItemSet previousSet, ItemSet newSet)` reports the active-set change.
- **OnItemSetManagerUpdateItemSet** `(int groupIndex, int activeIndex)` reports the new active index.
- **OnEquipUnequipItemSetIndexChange** `(int itemSetIndex)` is sent on the matching Equip Unequip ability for selector synchronization.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` reports selector and Equip Unequip activation like other item abilities.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-item-set-equip-next"></a>

# Equip Next

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-next/)

Equip Next moves forward through the valid Item Sets in one equipment category. Use it for a next-weapon button, controller bumper, or any control that should skip unavailable loadouts and wrap from the end of the list to the beginning.

Equip Next selects the target only. A category-matched [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) ability performs the visible unequip and equip sequence.

## Before you begin

The character needs:

- an Inventory containing the Character Items used by the target sets;
- an **Item Set Manager** with an **Item Set Group** for the intended **Item Category**;
- at least two generated Item Sets in that group; and
- an **Equip Unequip** item ability with the same **Item Category**.

At least one alternative set must be enabled, valid for the current inventory, and allowed to switch to. Otherwise Equip Next has nowhere to move and will not start.

## Configure Equip Next

1. Select the character and expand the target group under **Item Set Manager > Item Set Groups**.
2. Confirm its **Item Category**, **Item Set Rules**, and runtime Item Set order describe the cycle you want.
3. On **Ultimate Character Locomotion**, expand **Item Abilities** and add **Equip Unequip** if the category does not already have one. Assign the same **Item Category**.
4. Add **Equip Next** to **Item Abilities** and assign that **Item Category**.
5. Keep the normal input defaults: **Start Type** is **Button Down**, **Stop Type** is **Manual**, and **Input Names** contains **Equip Next Item**. Equip Next stops itself after handing off the selected index.
6. Keep **Prevent Start Use Reload Active** enabled when firing or reloading should finish before the player changes equipment. This option is enabled by default.
7. Map **Equip Next Item** to the intended player control and leave the actual equip and unequip timing on each Character Item's animation events or durations.

**Item Category** is unassigned by default. An unassigned Item Set ability uses the first Item Set Group's category at runtime. Assign it explicitly whenever the character has more than one group so Equip Next finds the intended group and Equip Unequip row.

Equip Next allows duplicate types. Add separate rows with different Item Categories or input names when primary weapons, grenades, or other equipment families need independent next controls.

## Choose the cycle behavior

### Order the Item Sets

Equip Next starts immediately after the last tracked Item Set index and checks later entries in list order. When it reaches the end, it wraps to index **0** and continues until it returns to the starting point.

The runtime Item Set order is generated by the group's rules and can change when inventory or rules change. Inspect the group in Play Mode when the cycle does not match the order expected from the edit-time rule list.

### Decide which sets are eligible

Equip Next skips an Item Set when any of these conditions applies:

- the set is disabled;
- **Can Switch To** is disabled;
- its Item Set Rule reports that the combination is invalid;
- a required Character Item is missing from its slot or the inventory does not contain the required count; or
- a usable item in the set currently cannot be equipped, such as an item with no usable supply remaining.

The default Item Set participates in the forward cycle only when it is valid and **Can Switch To** is enabled. Keep **Can Switch To** disabled when the default represents a holstered state that should be reached only by [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) or another deliberate action.

### Decide when actions may delay switching

With **Prevent Start Use Reload Active** enabled, any active Use or Reload item ability prevents Equip Next from starting. The check is character-wide rather than limited to this category or slot.

Equip Next temporarily applies its prevention setting to the matching Equip Unequip call, then restores the Equip Unequip row's original value. This keeps a button-triggered change consistent with the selector's setting without permanently changing the worker ability.

## How it runs

1. Equip Next tracks the active Item Set index reported by its category's Equip Unequip ability and Item Set Manager.
2. The **Equip Next Item** input attempts to start the ability. The shared check first applies **Prevent Start Use Reload Active** and the normal ability restrictions.
3. Equip Next asks the Item Set Manager for the next active index after the tracked index.
4. The manager advances through the group, wraps at the end, and skips every set that fails the eligibility checks above.
5. Equip Next refuses to start when no alternative is found, the resulting index is **-1**, or the result is already active in the matching Equip Unequip ability.
6. For an accepted target, Equip Next calls `StartEquipUnequip` on the category-matched Equip Unequip ability and immediately stops itself.
7. Equip Unequip performs the visible transition. The manager marks the target active as the new items reach their equip point, and Equip Unequip remains active until their equip-complete events finish.

Equip Next does not supply an Item State Index or item substate. Its position in the Item Abilities list therefore does not choose the equip animation. Equip Unequip supplies the default unequip and equip state indexes **5** and **4**; position that row above a persistent pose such as Aim when the equipment transition should win.

## Verify in Play Mode

1. Give one Item Set Group three ordered sets, such as Sword, Rifle, and Bow, and add all required Character Items to the Inventory.
2. Start with Sword active and press **Equip Next Item**. Confirm **Equip Next (Active)** appears only briefly, **Equip Unequip (Active)** remains through the transition, and Rifle becomes active.
3. Press again and confirm Bow becomes active. Press once more and confirm the cycle wraps to Sword.
4. Remove Rifle's required Character Item or disable **Can Switch To** on that runtime set. Start from Sword and press again; confirm Equip Next skips Rifle and selects Bow.
5. Disable every alternative or leave only one generated set. Press the input and confirm Equip Next does not become active and the equipment remains unchanged.
6. Start Use or Reload and press the input. With **Prevent Start Use Reload Active** enabled, confirm the active set does not change until the action stops.
7. If the character has two groups, trigger each group's Equip Next input and confirm only the category assigned to that row changes.

## Troubleshoot Equip Next

- **Equip Next is disabled at runtime:** check that an Item Set Manager group and an Equip Unequip ability use the same **Item Category**. A missing match logs an error and disables the selector.
- **The input does nothing:** confirm **Input Names** contains the mapped control, the group has more than one generated set, and at least one alternative is enabled, valid, and switchable.
- **A set is unexpectedly skipped:** inspect it in the runtime Item Set list. Check **Enabled**, **Can Switch To**, the Item Set Rule, required slots and counts, and whether every usable Character Item can currently equip.
- **The cycle starts in the wrong group:** assign **Item Category** explicitly. Leaving it empty selects the first Item Set Group.
- **The sequence order is unexpected:** inspect the generated runtime order rather than only the edit-time rules. Inventory or rule updates can rebuild and reorder the available sets.
- **Switching waits until firing or reloading ends:** this is the default **Prevent Start Use Reload Active** behavior. Disable it only after confirming that the item actions and transition animations support switching mid-action.
- **Equip Next flashes active but the item never changes:** check the matching Equip Unequip row and its Character Item **Equip Event**, **Equip Complete Event**, **Unequip Event**, and **Unequip Complete Event**.
- **The new item appears but the wrong animation remains visible:** move Equip Unequip above the active item ability whose pose should yield. Reordering Equip Next itself does not change Animator priority.

## Related tasks

- [Item Set abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/) explains the shared category, Item Set Manager, and Equip Unequip architecture.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs the transition selected by Equip Next.
- [Equip Previous](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-previous/) moves through the same eligible sets in the opposite direction.
- [Equip Scroll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-scroll/) selects next or previous from one signed axis.
- [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) switches between a non-default set and the category's default set.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) explains generated sets, validity, **Can Switch To**, and the default Item Set.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) describes the Item State Index values supplied by Equip Unequip.

## Developer reference

Equip Next adds no serialized fields beyond `ItemSetAbilityBase`. The inherited public properties are **ItemCategory**, **ItemSetCategoryID**, **PreventStartUseReloadActive**, and the resolved read-only **ItemSetGroupIndex**. Use the normal ability start API when code should request the next set; Equip Next performs the same validation as player input.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) keeps its index synchronized:

- **OnEquipUnequipItemSetIndexChange** `(int itemSetIndex)` is received from the matched Equip Unequip ability.
- **OnItemSetIndexChange** `(int groupIndex, int itemSetIndex)` updates the tracked index when the matching Item Set Group is rebuilt or changed.
- **OnNextItemSet** `(CharacterItem characterItem, bool unequipOnFailure)` requests the next set only when that Character Item belongs to this category and is the active item for its slot. When the request cannot start and `unequipOnFailure` is `true`, Equip Next requests the group's default Item Set instead.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` reports the selector's brief start and stop like other item abilities.

When **Unequip All On Death** is enabled on the Inventory, Equip Next clears its remembered indices on death so the cycle can be established again from the post-respawn Item Set state.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-item-set-equip-previous"></a>

# Equip Previous

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-previous/)

Equip Previous moves backward through the valid Item Sets in one equipment category. Use it for a previous-weapon button, controller bumper, or any control that should skip unavailable loadouts and wrap from the beginning of the list to the end.

Equip Previous selects the target only. A category-matched [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) ability performs the visible unequip and equip sequence.

## Before you begin

The character needs:

- an Inventory containing the Character Items used by the target sets;
- an **Item Set Manager** with an **Item Set Group** for the intended **Item Category**;
- at least two generated Item Sets in that group; and
- an **Equip Unequip** item ability with the same **Item Category**.

At least one alternative set must be enabled, valid for the current inventory, and allowed to switch to. Otherwise Equip Previous has nowhere to move and will not start.

## Configure Equip Previous

1. Select the character and expand the target group under **Item Set Manager > Item Set Groups**.
2. Confirm its **Item Category**, **Item Set Rules**, and runtime Item Set order describe the reverse cycle you want.
3. On **Ultimate Character Locomotion**, expand **Item Abilities** and add **Equip Unequip** if the category does not already have one. Assign the same **Item Category**.
4. Add **Equip Previous** to **Item Abilities** and assign that **Item Category**.
5. Keep the normal input defaults: **Start Type** is **Button Down**, **Stop Type** is **Manual**, and **Input Names** contains **Equip Previous Item**. Equip Previous stops itself after handing off the selected index.
6. Keep **Prevent Start Use Reload Active** enabled when firing or reloading should finish before the player changes equipment. This option is enabled by default.
7. Map **Equip Previous Item** to the intended player control and leave the actual equip and unequip timing on each Character Item's animation events or durations.

**Item Category** is unassigned by default. An unassigned Item Set ability uses the first Item Set Group's category at runtime. Assign it explicitly whenever the character has more than one group so Equip Previous finds the intended group and Equip Unequip row.

Equip Previous allows duplicate types. Add separate rows with different Item Categories or input names when primary weapons, grenades, or other equipment families need independent previous controls.

## Choose the reverse-cycle behavior

### Order the Item Sets

Equip Previous starts immediately before the last tracked Item Set index and checks earlier entries in list order. From index **0**, it wraps to the final index and continues backward until it returns to the starting point.

The runtime Item Set order is generated by the group's rules and can change when inventory or rules change. Inspect the group in Play Mode when the reverse cycle does not match the order expected from the edit-time rule list.

### Decide which sets are eligible

Equip Previous skips an Item Set when any of these conditions applies:

- the set is disabled;
- **Can Switch To** is disabled;
- its Item Set Rule reports that the combination is invalid;
- a required Character Item is missing from its slot or the inventory does not contain the required count; or
- a usable item in the set currently cannot be equipped, such as an item with no usable supply remaining.

The default Item Set participates in the reverse cycle only when it is valid and **Can Switch To** is enabled. Keep **Can Switch To** disabled when the default represents a holstered state that should be reached only by [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) or another deliberate action.

### Decide when actions may delay switching

With **Prevent Start Use Reload Active** enabled, any active Use or Reload item ability prevents Equip Previous from starting. The check is character-wide rather than limited to this category or slot.

Equip Previous temporarily applies its prevention setting to the matching Equip Unequip call, then restores the Equip Unequip row's original value. This keeps a button-triggered change consistent with the selector's setting without permanently changing the worker ability.

## How it runs

1. Equip Previous tracks the active Item Set index reported by its category's Equip Unequip ability and Item Set Manager.
2. The **Equip Previous Item** input attempts to start the ability. The shared check first applies **Prevent Start Use Reload Active** and the normal ability restrictions.
3. Equip Previous asks the Item Set Manager for the previous active index before the tracked index.
4. The manager moves backward through the group, wraps from index **0** to the last index, and skips every set that fails the eligibility checks above.
5. Equip Previous refuses to start when no alternative is found, the resulting index is **-1**, or the result is already active in the matching Equip Unequip ability.
6. For an accepted target, Equip Previous calls `StartEquipUnequip` on the category-matched Equip Unequip ability and immediately stops itself.
7. Equip Unequip performs the visible transition. The manager marks the target active as the new items reach their equip point, and Equip Unequip remains active until their equip-complete events finish.

Equip Previous does not supply an Item State Index or item substate. Its position in the Item Abilities list therefore does not choose the equip animation. Equip Unequip supplies the default unequip and equip state indexes **5** and **4**; position that row above a persistent pose such as Aim when the equipment transition should win.

## Verify in Play Mode

1. Give one Item Set Group three ordered sets, such as Sword, Rifle, and Bow, and add all required Character Items to the Inventory.
2. Start with Bow active and press **Equip Previous Item**. Confirm **Equip Previous (Active)** appears only briefly, **Equip Unequip (Active)** remains through the transition, and Rifle becomes active.
3. Press again and confirm Sword becomes active. Press once more and confirm the reverse cycle wraps to Bow.
4. Remove Rifle's required Character Item or disable **Can Switch To** on that runtime set. Start from Bow and press again; confirm Equip Previous skips Rifle and selects Sword.
5. Disable every alternative or leave only one generated set. Press the input and confirm Equip Previous does not become active and the equipment remains unchanged.
6. Start Use or Reload and press the input. With **Prevent Start Use Reload Active** enabled, confirm the active set does not change until the action stops.
7. If the character has two groups, trigger each group's Equip Previous input and confirm only the category assigned to that row changes.

## Troubleshoot Equip Previous

- **Equip Previous is disabled at runtime:** check that an Item Set Manager group and an Equip Unequip ability use the same **Item Category**. A missing match logs an error and disables the selector.
- **The input does nothing:** confirm **Input Names** contains the mapped control, the group has more than one generated set, and at least one alternative is enabled, valid, and switchable.
- **A set is unexpectedly skipped:** inspect it in the runtime Item Set list. Check **Enabled**, **Can Switch To**, the Item Set Rule, required slots and counts, and whether every usable Character Item can currently equip.
- **The cycle starts in the wrong group:** assign **Item Category** explicitly. Leaving it empty selects the first Item Set Group.
- **The reverse order is unexpected:** inspect the generated runtime order rather than only the edit-time rules. Equip Previous decrements that runtime index and wraps from the first entry to the last.
- **Switching waits until firing or reloading ends:** this is the default **Prevent Start Use Reload Active** behavior. Disable it only after confirming that the item actions and transition animations support switching mid-action.
- **Equip Previous flashes active but the item never changes:** check the matching Equip Unequip row and its Character Item **Equip Event**, **Equip Complete Event**, **Unequip Event**, and **Unequip Complete Event**.
- **The new item appears but the wrong animation remains visible:** move Equip Unequip above the active item ability whose pose should yield. Reordering Equip Previous itself does not change Animator priority.

## Related tasks

- [Item Set abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/) explains the shared category, Item Set Manager, and Equip Unequip architecture.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs the transition selected by Equip Previous.
- [Equip Next](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-next/) moves through the same eligible sets in the forward direction.
- [Equip Scroll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-scroll/) selects next or previous from one signed axis.
- [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) switches between a non-default set and the category's default set.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) explains generated sets, validity, **Can Switch To**, and the default Item Set.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) describes the Item State Index values supplied by Equip Unequip.

## Developer reference

Equip Previous adds no serialized fields beyond `ItemSetAbilityBase`. The inherited public properties are **ItemCategory**, **ItemSetCategoryID**, **PreventStartUseReloadActive**, and the resolved read-only **ItemSetGroupIndex**. Call the public `StartAbility()` method when code should request the previous set; Equip Previous performs the same validation as player input.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) keeps its index synchronized:

- **OnEquipUnequipItemSetIndexChange** `(int itemSetIndex)` is received from the matched Equip Unequip ability.
- **OnItemSetIndexChange** `(int groupIndex, int itemSetIndex)` updates the tracked index when the matching Item Set Group is rebuilt or changed.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` reports the selector's brief start and stop like other item abilities.

When **Unequip All On Death** is enabled on the Inventory, Equip Previous clears its remembered indices on death so the cycle can be established again from the post-respawn Item Set state.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-item-set-equip-scroll"></a>

# Equip Scroll

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-scroll/)

Equip Scroll uses one signed input axis to move forward or backward through the valid Item Sets in one equipment category. Use it for a mouse wheel, controller wheel, or another bidirectional control where a positive value selects the next set and a negative value selects the previous set.

Equip Scroll selects the target only. A category-matched [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) ability performs the visible unequip and equip sequence.

## Before you begin

The character needs:

- an Inventory containing the Character Items used by the target sets;
- an **Item Set Manager** with an **Item Set Group** for the intended **Item Category**;
- at least two generated Item Sets in that group; and
- an **Equip Unequip** item ability with the same **Item Category**.

At least one alternative set must be enabled, valid for the current inventory, and allowed to switch to. Otherwise neither axis direction has a target and Equip Scroll will not start.

## Configure Equip Scroll

1. Select the character and expand the target group under **Item Set Manager > Item Set Groups**.
2. Confirm its **Item Category**, **Item Set Rules**, and runtime Item Set order describe the cycle you want.
3. On **Ultimate Character Locomotion**, expand **Item Abilities** and add **Equip Unequip** if the category does not already have one. Assign the same **Item Category**.
4. Add **Equip Scroll** to **Item Abilities** and assign that **Item Category**.
5. Keep the input defaults for a mouse wheel: **Start Type** is **Axis**, **Stop Type** is **Manual**, and **Input Names** contains **Mouse ScrollWheel**. Equip Scroll stops itself after handing off the selected index.
6. Start with **Scroll Sensitivity 0.1**. This is the default minimum absolute raw-axis value required for a switch.
7. Keep **Prevent Start Use Reload Active** enabled when firing or reloading should finish before the player changes equipment. This option is enabled by default.
8. Confirm the input source reports a positive value for the direction that should move forward and a negative value for the direction that should move backward. Invert the input binding when the physical wheel direction should behave differently.

**Item Category** is unassigned by default. An unassigned Item Set ability uses the first Item Set Group's category at runtime. Assign it explicitly whenever the character has more than one group so Equip Scroll finds the intended group and Equip Unequip row.

Equip Scroll allows duplicate types. Add separate rows with different Item Categories or input axes when primary weapons, grenades, or other equipment families need independent scroll controls.

## Choose the axis and cycle behavior

### Set the direction and threshold

Equip Scroll reads the raw value of the active axis:

- a value greater than **0** searches forward for the next eligible Item Set;
- a value less than **0** searches backward for the previous eligible Item Set; and
- an absolute value below **Scroll Sensitivity** is ignored.

With the default sensitivity of **0.1**, values from greater than **-0.1** to less than **0.1** form the ignored range. A value exactly equal to either threshold is accepted. Raising the setting requires a stronger scroll pulse; lowering it accepts smaller input noise.

The threshold is checked against each raw axis reading. Equip Scroll does not accumulate several small values into one switch.

### Order the Item Sets

For a positive value, Equip Scroll starts after the active Equip Unequip Item Set index and advances through the runtime list. For a negative value, it starts before that index and moves backward. Forward traversal wraps from the last index to **0**; reverse traversal wraps from index **0** to the final index.

The runtime Item Set order is generated by the group's rules and can change when inventory or rules change. Inspect the group in Play Mode when the scroll sequence does not match the order expected from the edit-time rule list.

### Decide which sets are eligible

Both directions skip an Item Set when any of these conditions applies:

- the set is disabled;
- **Can Switch To** is disabled;
- its Item Set Rule reports that the combination is invalid;
- a required Character Item is missing from its slot or the inventory does not contain the required count; or
- a usable item in the set currently cannot be equipped, such as an item with no usable supply remaining.

The default Item Set participates only when it is valid and **Can Switch To** is enabled. Keep **Can Switch To** disabled when the default represents a holstered state that should be reached only by [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) or another deliberate action.

### Prevent stacked scroll changes

An active Equip Unequip ability blocks Equip Scroll from starting. A second wheel pulse therefore cannot queue another scroll selection while the previous equip or unequip transition is still active.

With **Prevent Start Use Reload Active** enabled, any active Use or Reload item ability also prevents Equip Scroll from starting. This check is character-wide rather than limited to this category or slot.

## How it runs

1. A nonzero raw value from **Mouse ScrollWheel** or the configured axis attempts to start Equip Scroll.
2. The base axis input check records the raw value. Equip Scroll then rejects it when its absolute magnitude is below **Scroll Sensitivity**.
3. The shared start check rejects the request while Use or Reload is active when **Prevent Start Use Reload Active** is enabled. An active Equip Unequip transition also blocks the request.
4. Equip Scroll uses the sign of the axis value and the matched Equip Unequip ability's active Item Set index to request the next or previous eligible index.
5. The Item Set Manager traverses the list in that direction, wraps at the boundary, and skips every set that fails the eligibility checks above.
6. Equip Scroll refuses to start when no alternative is found, the resulting index is **-1**, or the result is already active.
7. For an accepted target, Equip Scroll temporarily applies its **Prevent Start Use Reload Active** value to the matching Equip Unequip call, requests the target index, restores the worker's setting, and immediately stops itself.
8. Equip Unequip performs the visible transition. The manager marks the target active as the new items reach their equip point, and Equip Unequip remains active until their equip-complete events finish.

Equip Scroll does not supply an Item State Index or item substate. Its position in the Item Abilities list therefore does not choose the equip animation. Equip Unequip supplies the default unequip and equip state indexes **5** and **4**; position that row above a persistent pose such as Aim when the equipment transition should win.

## Verify in Play Mode

1. Give one Item Set Group three ordered sets, such as Sword, Rifle, and Bow, and add all required Character Items to the Inventory.
2. Start with Rifle active and produce a positive axis value at or above **0.1**. Confirm **Equip Scroll (Active)** appears only briefly, **Equip Unequip (Active)** remains through the transition, and Bow becomes active.
3. Produce another positive value and confirm the cycle wraps to Sword. Produce a negative value and confirm it wraps back to Bow.
4. Remove Rifle's required Character Item or disable **Can Switch To** on that runtime set. Scroll backward from Bow and confirm the selector skips Rifle and chooses Sword.
5. Provide axis values whose absolute magnitude is below **0.1** and confirm the set does not change. Test values at both **0.1** and **-0.1** and confirm they are accepted.
6. Scroll again while Equip Unequip is still active. Confirm the second request is ignored until the current transition ends.
7. Start Use or Reload and scroll. With **Prevent Start Use Reload Active** enabled, confirm the active set does not change until the action stops.
8. If the character has two groups, operate each group's configured axis and confirm only the category assigned to that Equip Scroll row changes.

## Troubleshoot Equip Scroll

- **Equip Scroll is disabled at runtime:** check that an Item Set Manager group and an Equip Unequip ability use the same **Item Category**. A missing match logs an error and disables the selector.
- **The wheel never changes equipment:** inspect the raw axis value, confirm **Start Type** is **Axis**, and verify **Input Names** uses the correct mapping. Lower **Scroll Sensitivity** only when the value never reaches the current threshold.
- **The physical wheel direction feels reversed:** the code maps positive to next and negative to previous. Invert the input binding or processor so its sign matches the desired physical direction.
- **One wheel movement changes several sets:** confirm the input produces one pulse and that the matching Equip Unequip remains active for the intended transition. Equip Unequip blocks later Equip Scroll starts only while it is active.
- **A set is unexpectedly skipped:** inspect it in the runtime Item Set list. Check **Enabled**, **Can Switch To**, the Item Set Rule, required slots and counts, and whether every usable Character Item can currently equip.
- **The cycle starts in the wrong group:** assign **Item Category** explicitly. Leaving it empty selects the first Item Set Group.
- **Scrolling waits until firing or reloading ends:** this is the default **Prevent Start Use Reload Active** behavior. Disable it only after confirming that the item actions and transition animations support switching mid-action.
- **Equip Scroll flashes active but the item never changes:** check the matching Equip Unequip row and its Character Item **Equip Event**, **Equip Complete Event**, **Unequip Event**, and **Unequip Complete Event**.
- **The new item appears but the wrong animation remains visible:** move Equip Unequip above the active item ability whose pose should yield. Reordering Equip Scroll itself does not change Animator priority.

## Related tasks

- [Item Set abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/) explains the shared category, Item Set Manager, and Equip Unequip architecture.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs the transition selected by Equip Scroll.
- [Equip Next](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-next/) provides a dedicated forward button.
- [Equip Previous](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-previous/) provides a dedicated reverse button.
- [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) switches between a non-default set and the category's default set.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) explains generated sets, validity, **Can Switch To**, and the default Item Set.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) describes the Item State Index values supplied by Equip Unequip.

## Developer reference

Equip Scroll exposes **ScrollSensitivity** and inherits **ItemCategory**, **ItemSetCategoryID**, **PreventStartUseReloadActive**, and the resolved read-only **ItemSetGroupIndex**. The base Ability also exposes **InputAxisValue**, which is populated from the raw player input before `CanStartAbility()` evaluates the threshold and direction.

For programmatic switching, use `ItemSetManagerBase.NextActiveItemSetIndex(groupIndex, activeIndex, next)` to resolve a target and pass that result to the matching `EquipUnequip.StartEquipUnequip(itemSetIndex)`. This avoids depending on a stored axis value when no player input initiated the request.

Equip Scroll has no feature-specific event. Use the built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) to observe the resulting transition:

- **OnItemSetManagerUpdateNextItemSet** `(int groupIndex, int previousIndex, int nextIndex)` reports the pending target.
- **OnActiveItemSetChange** `(int groupIndex, ItemSet previousSet, ItemSet newSet)` reports the active-set change.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` reports Equip Scroll's brief start and stop and the longer Equip Unequip lifecycle.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-item-set-equip-unequip"></a>

# Equip Unequip

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/)

Equip Unequip turns a selected Item Set into the visible equipment on the character. Use one category-matched copy as the worker behind numbered loadout inputs, weapon cycling, pickups, holstering, and other Item Set changes.

Equip Unequip manages the complete set across every Inventory slot. It keeps an item that already matches, unequips items that must leave, and equips the target items only after all required unequips have completed.

## Before you begin

The character needs:

- an Inventory containing the Character Items used by the target sets;
- an **Item Set Manager** with the correct **Item Collection**;
- an **Item Set Group** with an **Item Category** and Item Set Rules, plus a valid default Item Set when the group needs a holstered or fallback state; and
- Character Items whose equip and unequip timing matches their animations.

![Item Set Manager with DemoItemCollection assigned to Item Collection](https://opsive.com/wp-content/uploads/2018/03/ItemSetManagerItemCollection.webp?v=095435c33d36)

Add one Equip Unequip row for each Item Set Group that needs independent control. Assigning the row's **Item Category** explicitly is especially important when a character has more than one group. If it is left unassigned, the ability uses the first Item Set Group's category at runtime.

## Configure Equip Unequip

1. Select the character and confirm **Item Set Manager > Item Collection** references the collection that defines its items and categories.
2. Expand **Item Set Groups**. Confirm the target group has the intended **Item Category**, its Item Set Rules generate the required slot combinations, and its default Item Set represents the group's unequipped or fallback state.
3. On **Ultimate Character Locomotion**, expand **Item Abilities**, select the plus button, and add **Equip Unequip**.
4. Assign **Item Category** to the same category as the Item Set Group. Keep **Prevent Start Use Reload Active** enabled when firing or reloading should finish before equipment changes. It is enabled by default.
5. For direct numbered selection, keep **Start Type** set to **Button Down** and map the default **Equip First Item** through **Equip Tenth Item** input names. Their positions map to Item Set indexes **0** through **9**. **Stop Type** is **Manual**; the ability stops itself after the transition completes.
6. Choose the **Auto Equip** cases that should react to pickups. The starting mask includes **Unequipped**, **Out Of Usable Item**, **Not Preset**, and **First Time**. **Always** is disabled by default.
7. Keep **Equip Item State Index 4**, **Unequip Item State Index 5**, and **Aim Item Substate Index Addition 100** unless the character's Animator uses a different item-state scheme.
8. On every Character Item involved, configure **Equip Event**, **Equip Complete Event**, **Unequip Event**, and **Unequip Complete Event**. Use durations for a simple timed setup or animation events when the visible item must change on exact frames.
9. Place Equip Unequip above a persistent item pose such as Aim when state indexes **4** and **5** should take Animator priority during the transition.

![Character Item Equip Event using a 0.3 second duration instead of waiting for an animation event](https://opsive.com/wp-content/uploads/2018/03/EquipTroubleshootingTimer.webp?v=9b6cb3e25771)

Equip Unequip allows duplicate types. Pair each selector row with the Equip Unequip row that has the same Item Category; list position does not create that pairing.

## Choose the transition behavior

### Select a set directly or through another ability

A numbered Equip Unequip input selects the runtime Item Set at the matching input position. The generated order can change when inventory or Item Set Rules change, so inspect the runtime list before relying on a numbered control.

[Equip Next](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-next/), [Equip Previous](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-previous/), [Equip Scroll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-scroll/), and [Toggle Equip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/) choose an eligible target and hand its index to the category-matched Equip Unequip row. Those selectors stop immediately; Equip Unequip remains active for the visible transition.

### Decide when a pickup changes equipment

The **Auto Equip** flags are evaluated when a Character Item in this ability's category is picked up:

| Option | Equip the picked-up item when |
| --- | --- |
| **Always** | Every qualifying pickup should request its matching Item Set. |
| **Unequipped** | The pickup's slot has no active item and no item waiting to equip. |
| **Out Of Usable Item** | An active usable item action reports that its item should be unequipped. |
| **Not Preset** | The pickup adds more of that item than the amount remembered before the pickup began. |
| **First Time** | The character did not previously own the item. |

Use **Always** sparingly when collecting ammunition or a secondary item should not replace the player's chosen loadout. Equip Unequip does not auto-equip during an active Use or Reload. It also respects active character abilities that restrict allowed equipment slots or Item Definitions.

When a parent Item Category contains the pickup but another Equip Unequip row exactly matches the Item Definition's category, the exact match handles the pickup. This prevents both rows from reacting to the same item.

### Coordinate categories and slots

Equip Unequip compares every Inventory slot in its target Item Set. If the active and target sets use the same Character Item in the same slot, that item stays equipped. If multiple Item Set Groups claim one slot, the earlier group in the Item Set Manager has priority and a lower-priority group will not replace its item.

Use separate groups and Equip Unequip rows for equipment families that should change independently. Adjust the Item Set Rules or group order when changing one category unexpectedly removes an item from another.

### Coordinate Use, Reload, Drop, and Pickup

With **Prevent Start Use Reload Active** enabled, an active [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) or [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) prevents a normal equipment change from starting. While Equip Unequip is actively removing an item, it also blocks a new Use or Reload from starting. A forced code request first stops active Use and Reload abilities.

[Drop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) can use **Wait For Unequip** to request each matching category's default Item Set before removing the item. Removing an item from Inventory also makes Equip Unequip find the closest valid replacement set; when another item remains in the active combination, that change can use the normal animated transition.

Pickup can start an Auto Equip transition as described above. An immediate pickup may establish the highest-priority valid set without waiting for an animation, such as during initialization.

## How it runs

1. Input, an Item Set selector, Auto Equip, or code supplies a target Item Set index for this ability's group. Index **-1** means unequip the group.
2. Equip Unequip rejects an unchanged, invalid, or disallowed target. Active character abilities can prevent individual Item Definitions or slots from being equipped.
3. The ability compares the active and target sets slot by slot. Matching active items stay in place; outgoing and incoming Character Items are recorded for the remaining slots.
4. Every outgoing item begins its **Unequip Event** wait. At `OnAnimatorItemUnequip`, or after the configured duration, the Inventory removes the visible active item from that slot.
5. Each outgoing item then waits for **Unequip Complete Event**. Equip Unequip does not begin any incoming item until every slot has completed this stage.
6. Every incoming item begins its **Equip Event** wait. At `OnAnimatorItemEquip`, or after the configured duration, the Character Item becomes active in its Inventory slot and the Item Set Manager records the target set as active.
7. Each incoming item waits for **Equip Complete Event**. Equip Unequip stops only when all pending equip and unequip items have cleared.

The Character Item provides four separate animation checkpoints:

| Character Item field | Starting setting | Animation event when enabled | Result |
| --- | --- | --- | --- |
| **Unequip Event** | Duration **0.3**, not waiting for an event | `OnAnimatorItemUnequip` | Removes the outgoing item from the active Inventory slot. |
| **Unequip Complete Event** | Duration **0**, not waiting for an event | `OnAnimatorItemUnequipComplete` | Finishes that slot's unequip; incoming items wait until every slot reaches this point. |
| **Equip Event** | Duration **0.3**, not waiting for an event | `OnAnimatorItemEquip` | Activates the incoming item in its Inventory slot. |
| **Equip Complete Event** | Duration **0**, not waiting for an event | `OnAnimatorItemEquipComplete` | Finishes that slot's equip and allows the ability to stop when all slots are complete. |

During those waits, an unequipping slot reports Item State Index **5** and an equipping slot reports **4**. The substate comes from that Character Item's corresponding Animator Audio State Set. Input-started Aim adds **100** by default.

On death, Equip Unequip remembers the active set and requests index **-1**. First-person equipment is allowed to animate off screen; other perspectives can unequip immediately. On respawn, the previous set is immediately restored only when the Inventory did not remove all items on death.

## Verify in Play Mode

1. Create one group with a valid default set and two equipped sets, such as Sword and Rifle. Give the Inventory all required Character Items.
2. Keep **Item Set Manager**, **Ultimate Character Locomotion**, and one Character Item visible. Trigger **Equip Second Item** and confirm the input selects runtime Item Set index **1**.
3. Confirm **Equip Unequip (Active)** remains visible while the old item reports Item State Index **5**, disappears at its Unequip Event, and completes before the new item begins equipping.
4. Confirm the new item reports Item State Index **4**, appears at its Equip Event, and the ability stops only after Equip Complete Event.
5. Change one Character Item to wait for the matching Animator events. Confirm all four callbacks occur and no pending transition remains.
6. Start Use or Reload and request another set. With **Prevent Start Use Reload Active** enabled, confirm the target does not change until the action stops.
7. Pick up an item covered by the selected **Auto Equip** cases and confirm only the exact category-matched Equip Unequip row responds.
8. Remove an equipped item and confirm the group moves to the closest valid Item Set or its valid default instead of retaining an impossible combination.

## Troubleshoot Equip Unequip

- **The ability logs a missing Item Set Group error or disables at runtime:** check that **Item Set Manager** exists and that one group has the same **Item Category** as the Equip Unequip row. Assign the category explicitly instead of relying on the first-group fallback.
- **A numbered input equips the wrong combination:** inspect the generated runtime Item Set order. The input's position maps directly to that runtime index, not to an Item Set Rule's edit-time position.
- **Equip Unequip starts but the old item never disappears:** check the outgoing Character Item's **Unequip Event**. Add `OnAnimatorItemUnequip` to the clip when it waits for an animation event, or test with a verified duration.
- **The old item disappears but the new item never starts:** check **Unequip Complete Event** on every outgoing slot. One missing `OnAnimatorItemUnequipComplete` holds all incoming items.
- **The new item appears but Equip Unequip remains active:** check **Equip Complete Event** on every incoming Character Item. One missing `OnAnimatorItemEquipComplete` keeps the transition pending.
- **The item never equips when the character owns it:** confirm the target set is valid, the Character Item occupies the expected slot, and no active character ability's allowed-slot mask or allowed Item Definitions exclude it.
- **A pickup does not auto-equip:** confirm the item belongs to this group, **Auto Equip** includes the intended case, Use and Reload are inactive, and another Equip Unequip row does not own a more exact category match.
- **Switching waits until firing or reloading ends:** this is the default **Prevent Start Use Reload Active** behavior. Disable it only after verifying that the item actions and animations support changing equipment mid-action.
- **The transition animation is hidden by Aim or another pose:** move Equip Unequip above the competing active item ability so state indexes **4** and **5** take priority.
- **Changing one category changes another category's slot:** inspect overlapping Item Set Rules and group order. The earlier Item Set Group owns the slot when the groups conflict.
- **A dropped or removed item leaves an invalid active set:** verify a valid default or replacement set exists for the group and that the remaining Character Items are still in Inventory.

## Related tasks

- [Item Set abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/) explains the shared manager, group, category, and selector architecture.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) explains generated combinations, validity, defaults, and group priority.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) covers the four equip and unequip timing fields and visible item object.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) covers owned items, slots, death settings, and item removal.
- [Drop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) explains the **Wait For Unequip** handoff to the default Item Set.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) describes Item State Index and Item Substate Index.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains choosing between animation callbacks and durations.

## Developer reference

`StartEquipUnequip(itemSetIndex)` requests the supplied runtime index. The overload with `forceEquipUnequip` stops active Use and Reload abilities before starting; the overload with `immediateEquipUnequip` also bypasses the four animation waits. Use **-1** to unequip the group. The read-only `ActiveItemSetIndex` reports the index tracked by this category's Equip Unequip ability.

When a character has multiple Equip Unequip rows, select the row whose `ItemSetCategoryID` or `ItemCategory` matches the intended Item Set Group before calling the API. `UltimateCharacterLocomotion.GetAbility<EquipUnequip>()` returns only one copy and is therefore ambiguous on a multi-category character.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) coordinates the important runtime points:

- **OnEquipUnequipItemSetIndexChange** `(int itemSetIndex)` is sent on this Equip Unequip ability when its requested index changes.
- **OnItemSetIndexChange** `(int groupIndex, int itemSetIndex)` keeps the ability synchronized with its Item Set Group.
- **OnAbilityWillEquipItem** `(CharacterItem, int slotID)` is sent before an incoming Character Item begins its equip wait.
- **OnAbilityUnequipItemComplete** `(CharacterItem, int slotID)` is sent after an outgoing Character Item completes its unequip. Drop uses this when **Wait For Unequip** is enabled.
- **OnAnimatorItemEquip**, **OnAnimatorItemEquipComplete**, **OnAnimatorItemUnequip**, and **OnAnimatorItemUnequipComplete** complete Character Item timing fields configured to wait for animation events; slot-specific animation event routing is handled internally.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` reports Equip Unequip starting and stopping like other item abilities.

Equip Unequip also listens for Inventory pickup and removal, Aim, death, respawn, and Item Set Manager changes so its category stays synchronized without custom polling.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-item-set-toggle-equip"></a>

# Toggle Equip

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/toggle-equip/)

Toggle Equip switches one equipment category between its default Item Set and the last valid non-default set. Use it for a holster button, a show-or-hide equipment control, or any input that should restore the player's previous loadout with one press.

Toggle Equip only chooses the target. A matching [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) ability performs the visible multi-slot transition.

## Before you begin

The character needs:

- an Inventory containing the Character Items used by the category;
- an **Item Set Manager** with an **Item Set Group** for that **Item Category**;
- an Item Set Rule that produces a predictable default when the category should holster to a defined combination;
- at least one valid non-default Item Set; and
- an **Equip Unequip** item ability with the same **Item Category**.

The default Item Set does not have to be empty. Toggling away from a weapon set equips whatever combination the group marks as default. If the group has no default Item Set, Toggle Equip hands index **-1** to Equip Unequip and the category is unequipped instead.

## Configure Toggle Equip

1. Select the character and expand the target group under **Item Set Manager > Item Set Groups**.
2. Confirm the group's **Item Category** and Item Set Rules generate the equipped combinations you want to restore. Configure one rule to produce the intended default combination and enable **Default** on that rule.
3. On **Ultimate Character Locomotion**, expand **Item Abilities** and add **Equip Unequip** if this category does not already have one. Assign the same **Item Category**.
4. Add **Toggle Equip** to **Item Abilities** and assign that **Item Category**.
5. Keep the normal input defaults: **Start Type** is **Button Down**, **Stop Type** is **Manual**, and **Input Names** contains **Toggle Item Equip**. Toggle Equip stops itself immediately after handing off the target.
6. Keep **Prevent Start Use Reload Active** enabled when firing or reloading should finish before the category changes. It is enabled by default. Keep the matching Equip Unequip row consistent with this setting.
7. Leave **Toggle Default Item Set On Start** disabled for the normal player-controlled workflow. Enable it only when this row should make one conditional toggle request during startup if the Item Set Manager still reports no active set.
8. Map **Toggle Item Equip** to the intended player control and configure the visible timing on each Character Item's equip and unequip events or durations.

**Item Category** is unassigned by default. An unassigned Item Set ability uses the first Item Set Group's category at runtime. Assign it explicitly whenever the character has multiple groups so Toggle Equip finds the intended Equip Unequip row.

Toggle Equip allows duplicate types. Add one row per independently toggled category, such as a primary weapon and a shield, and give each row its own Item Category and input when needed.

## Choose the toggle behavior

### Define the default state

Use the group's default Item Set as the state reached when equipment is put away. An empty default holsters everything in that category. A non-empty default can keep a baseline item equipped, such as unarmed hands or a permanent tool.

Toggle Equip can select the default even when that set's **Can Switch To** option is disabled. This is useful when cycling abilities should skip the holstered set but the dedicated toggle should still reach it.

If the default set is invalid or disabled, Toggle Equip can briefly start and stop without a visible change because Equip Unequip rejects the target. Keep the default valid for the inventory state in which the player may holster.

### Understand the remembered set

Whenever this category changes to a non-default Item Set, Toggle Equip remembers both that set and its current index. A press from the non-default set requests the default. A later press from the default restores the remembered set when it is still valid.

The remembered Item Set object survives list reordering. If the Item Set Manager rebuilds the group and the same set moves to another index, Toggle Equip resolves its new index before restoring it.

If the remembered set becomes invalid or is removed, Toggle Equip clears that memory and searches forward from the current active index for the next valid, switchable Item Set. It wraps through the group and refuses to start when no alternative exists. **Can Switch To** is checked during this fallback search; it does not block a still-valid remembered set from being restored.

### Decide whether to toggle during startup

**Toggle Default Item Set On Start** is disabled by default. When enabled, the ability checks the Item Set Manager during `Start`. It only requests a toggle when that group still reports active index **-1**; it does nothing when the manager has already established an active set.

That startup request uses the same remembered-set and next-valid-set rules as a button press. It is not an unconditional "equip the default" command. For predictable starting equipment, configure the Inventory, default Item Set, and Item Set Rules so the manager can establish the intended active set; use this option only for the conditional toggle behavior.

### Coordinate Use and Reload

The inherited **Prevent Start Use Reload Active** setting is checked by Toggle Equip before it hands off. Equip Unequip performs its own check afterward. Unlike the cycling selectors, Toggle Equip does not temporarily copy its prevention setting to Equip Unequip, so keep the two rows aligned.

With both defaults enabled, any active [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) or [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) prevents the toggle. Toggle Equip never cancels those actions. While Equip Unequip is removing an item, the worker also prevents a new Use or Reload from starting.

## How it runs

1. Toggle Equip listens to the category-matched Equip Unequip ability and Item Set Manager for active-index changes.
2. When a non-default set becomes active, it stores that Item Set and index. When the default becomes active, it keeps the stored set only while it remains valid.
3. The **Toggle Item Equip** input attempts to start the ability. The shared category and **Prevent Start Use Reload Active** checks run first.
4. If there is no valid remembered set, Toggle Equip asks the manager for the next valid, switchable set after the active index. The search wraps at the end of the group.
5. Otherwise, it chooses the default when a non-default set is active, or the remembered non-default set when the default is active.
6. Toggle Equip calls `StartEquipUnequip` on the matching worker and stops immediately. It does not stay active for an animation and does not supply Item State Index or Item Substate Index values.
7. Equip Unequip compares the active and target sets across every slot, completes all outgoing unequips, then equips the incoming items. Its default Animator state indexes are **5** for unequip and **4** for equip.

When **Unequip All On Death** is enabled on the Inventory, Toggle Equip clears its remembered set on death. When it is disabled, the memory remains available while Equip Unequip handles the normal death and respawn equipment lifecycle.

## Verify in Play Mode

1. Create one Item Set Group with a valid empty default plus two valid non-default sets, such as Sword and Rifle. Give the Inventory the required Character Items.
2. Start with Sword active and press **Toggle Item Equip**. Confirm **Toggle Equip (Active)** appears only briefly, **Equip Unequip (Active)** remains through the transition, and the default set becomes active.
3. Press again. Confirm Sword, not simply the next list entry, is restored.
4. Equip Rifle through another selector, then toggle to the default and back. Confirm Toggle Equip now restores Rifle.
5. While the default is active, remove the remembered Rifle or make its set invalid. Press Toggle and confirm the next valid, switchable alternative is selected; if none exists, confirm the ability does not start.
6. Reorder the runtime sets while the remembered set still exists. Toggle away and back, then confirm the same combination returns at its new index.
7. Start Use or Reload and press the toggle. With prevention enabled on both rows, confirm the set does not change until the action stops.
8. If testing **Toggle Default Item Set On Start**, begin with no active set and inspect the runtime group. Confirm the option makes only one startup request and that the resulting set follows the normal selection rules.

## Troubleshoot Toggle Equip

- **Toggle Equip is disabled at runtime:** check that an Item Set Manager group and an Equip Unequip ability use the same **Item Category**. A missing worker logs an error and disables the selector.
- **Pressing the input does nothing:** confirm **Toggle Item Equip** is mapped, the active index is not **-1**, and the group contains a valid alternative. With no remembered set, the fallback search needs at least two generated sets and skips sets that are invalid or cannot be switched to.
- **The row flashes active but equipment does not change:** check that the target default or remembered set is valid, then inspect the matching Equip Unequip row and Character Item timing events.
- **The wrong category changes:** assign **Item Category** explicitly on both Toggle Equip and Equip Unequip. Leaving it empty selects the first Item Set Group.
- **The toggle restores the wrong set after another equipment change:** inspect which non-default set most recently became active in this category. Every accepted active-index change updates the remembered set.
- **The remembered set is skipped after inventory changes:** confirm the same Item Set still exists and is valid. If it was removed or became invalid, Toggle Equip deliberately searches for the next valid, switchable set.
- **The default does not look holstered:** inspect the items generated for the group's default Item Set. Toggle Equip equips that combination; it does not assume the default is empty.
- **Toggling waits while firing or reloading:** check **Prevent Start Use Reload Active** on both Toggle Equip and Equip Unequip. Both are enabled by default and either row can block the handoff.
- **Toggle Default Item Set On Start appears to do nothing:** the option only acts when the manager reports active index **-1** during `Start`. If the manager already established its default, no startup toggle is requested.
- **The toggle animation is hidden by Aim or another pose:** move Equip Unequip above the competing active item ability. Reordering Toggle Equip does not change Animator priority because the selector supplies no item state.

## Related tasks

- [Item Set abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/) explains the shared manager, category, worker, and selector architecture.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs the multi-slot transition requested by Toggle Equip.
- [Equip Next](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-next/), [Equip Previous](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-previous/), and [Equip Scroll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-scroll/) cycle through sets that are valid and switchable.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) explains generated sets, defaults, validity, and **Can Switch To**.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) covers owned items and **Unequip All On Death**.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains shared input, concurrency, and ability-order behavior.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the Equip Unequip item-state defaults used for the visible transition.

## Developer reference

Toggle Equip adds the public `ToggleDefaultItemSetOnStart` property to the inherited `ItemSetAbilityBase` members. Its remembered Item Set, previous index, and next index are internal runtime state.

Call `StartAbility()` on the category-matched Toggle Equip instance to request the same validated toggle used by input. On a character with duplicate Toggle Equip rows, select the copy whose `ItemSetCategoryID` or `ItemCategory` matches the intended group before starting it.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) keeps the selector synchronized:

- **OnEquipUnequipItemSetIndexChange** `(int itemSetIndex)` is received from the matching Equip Unequip ability and updates the remembered set.
- **OnItemSetIndexChange** `(int groupIndex, int itemSetIndex)` updates the same state when the Item Set Manager changes or rebuilds the group.
- **OnDeath** clears the remembered set only when the Inventory's **Unequip All On Death** option is enabled.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` reports Toggle Equip's brief start and stop like other item abilities; the matching Equip Unequip row reports the longer transition separately.

Toggle Equip emits no unique gameplay event. Listen to the Item Set Manager's active-set events or the matched Equip Unequip lifecycle when code needs to observe the resulting equipment change.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-reload"></a>

# Reload

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/)

The Reload item ability moves available ammunition into an equipped item's clip and keeps the reload animation active until its completion point. Use it for manually or automatically reloading a Shootable Action, including full-magazine and round-by-round workflows.

Reload selects an equipped Character Item by slot and Item Action ID. The Shootable Action's Ammo, Clip, and Reloader modules decide whether it can reload, how much ammunition moves, and when the visible animation advances.

## Before you begin

The character needs:

- an Inventory containing the weapon and, when using **Item Ammo**, the matching ammo Item Definition and amount;
- an equipped Character Item with a **Shootable Action**;
- an enabled Ammo module, Clip module, and Reloader module on that Shootable Action; and
- an Animator with the reload states and events expected by the Reloader module.

Reload has no **Item Category** field. It acts on the Character Item currently equipped in **Slot ID**, then selects that item's Item Action by **Action ID**. Item Set categories matter only indirectly because they determine which item is equipped in the slot.

## Configure Reload

1. Create or select the Character Item and open its **Shootable Action**.
2. Confirm the action's **ID**. This is the value the Reload ability must use as **Action ID**; it is not a module ID.
3. In the Shootable Action, keep one intended module enabled first in each single-choice group:
   - **Ammo**: use **Item Ammo** when ammunition comes from Inventory, or **Infinite Ammo** when no inventory item should be consumed.
   - **Clip**: use **Simple Clip** for a fixed capacity and set **Clip Size**. Its starting value is **50**.
   - **Reloader**: use **Generic Reloader** for the built-in animated workflow.
4. For **Item Ammo**, assign **Ammo Item Definition** and give the character that Item Definition in Inventory. **Shared Ammo Item Identifier** is disabled by default; enable it only when multiple active weapons should draw from and balance the same inventory pool.
5. On **Ultimate Character Locomotion**, expand **Item Abilities**, select the plus button, and add **Reload**.
6. Keep the normal ability defaults: **Start Type Button Down**, **Stop Type Manual**, **Input Names Reload**, and **Item State Index 3**.
7. Leave **Slot ID -1** to reload every eligible equipped slot together, or enter one Inventory slot. Set **Action ID** to the Shootable Action's ID; its default is **0**.
8. On **Generic Reloader**, choose **Reload Type Full** for one magazine transfer or **Single** to add one round per reload cycle. **Full** is the default.
9. Configure **Reload Event** and **Reload Complete Event**. Both wait for animation events by default with duration **0**. Add `OnAnimatorItemReload` and `OnAnimatorItemReloadComplete` to the clips, or disable event waiting and use tested durations.
10. Keep Reload above Aim or any other active item ability whose Animator state should yield while reloading.

Reload allows duplicate types. Use separate rows when primary and secondary slots need different inputs, or when one Character Item exposes more than one reloadable Action ID. Avoid duplicate rows that target the same slot, action, and input.

## Choose the reload behavior

### Reload one slot or every equipped slot

With **Slot ID -1**, Reload checks the active Character Item in every Inventory slot. Each item must have the selected Action ID, that action must implement the reloadable workflow, its clip must not be full, and its Ammo module must report ammunition remaining. The ability starts when at least one slot qualifies, ignores the others, and stops only after every participating slot completes.

With a specific **Slot ID**, only that active Character Item is checked. This is the clearest setup for different reload inputs or animations on primary and off-hand weapons.

Reload selects by **Action ID**, not by action type or Item Category. A missing action logs a warning. A Shootable Action without an active Ammo, Clip, or Reloader module cannot complete the normal workflow.

### Use Inventory ammo or infinite ammo

**Item Ammo** reads its **Ammo Item Definition** amount from Inventory. At the Reload Event, the Clip module moves up to the needed amount into the clip and subtracts that amount from Inventory. Reload cannot start when the clip is full, the ammo count is zero, or the weapon itself is no longer present in Inventory.

**Infinite Ammo** always reports ammunition available and does not remove an Inventory item when the clip fills. The Clip module still limits how many rounds the weapon can hold.

When **Shared Ammo Item Identifier** is enabled on Item Ammo, active shootable items using the same ammo definition share that pool. The Simple Clip module distributes a limited amount across those active shared instances instead of allowing the first item to take every round needed by all clips.

### Choose automatic reload cases

**Auto Reload** lives on Generic Reloader, not on the Reload ability. Its starting selection is **Pickup** and **Empty**; **Equip** is disabled.

| Option | Runtime result |
| --- | --- |
| **Pickup** | Picking up the matching ammo Item Definition attempts a reload. An equipped item can use the normal animation; an unequipped item or immediate pickup reloads without one. |
| **Empty** | When the Shootable Action completes a use with an empty clip, it requests Reload. |
| **Equip** | Equipping the Character Item reloads its clip immediately without starting the animated Reload ability. |

On the first equip, Generic Reloader performs one immediate full reload whenever any Auto Reload option is selected and the item can reload. Clear the entire Auto Reload mask when a weapon must begin with an empty clip and wait for a deliberate manual reload.

### Reload a full magazine or one round at a time

**Reload Type Full** transfers as much ammunition as the clip can accept at the first Reload Event, then waits for Reload Complete Event.

**Reload Type Single** transfers one round at each Reload Event. If the clip still has space and Inventory still has ammo, Generic Reloader begins another reload cycle and chooses the next Animator Audio State. After the last available or required round, it waits for Reload Complete Event.

The default **Substate Index Data** uses index **0**, priority **100**, and is not additive. The active Animator Audio State supplies the visible reload substate until the ammunition transfer finishes; the post-transfer value returns to **0**.

### Coordinate Aim, Use, and equipment changes

Reload and [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) can be active together, but list order decides which row supplies the Animator values. Keep Reload above Aim so Item State Index **3** and the Reloader substate win. First-person Aim re-establishes its perspective state after Reload stops.

An active [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) has priority over an input-started Reload for the same Character Item. If Use starts while that item is reloading, it cancels that item's reload; an all-slot Reload may continue for other slots. A full reload, or a single-round reload with an empty clip, also prevents that Shootable Action from firing. A single-round reload may allow use once the clip already contains ammunition.

Reload also keeps dominant and non-dominant item flows separated. While one side is reloading, a Use request whose items have the opposite **Dominant Item** status is blocked so incompatible Animator states do not run together.

[Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) blocks equipment changes while Reload is active when **Prevent Start Use Reload Active** is enabled. If that option is disabled, starting Equip Unequip cancels the pending reloads and allows the equipment transition.

Generic Reloader exposes **Reload Can Camera Zoom**, enabled by default. In the released Version 3 runtime, that value is not queried by the Camera Controller or Aim ability, so do not rely on it as the only zoom rule. Verify the Character Item's camera-zoom setting and actual Aim behavior in Play Mode.

## How it runs

1. Input or an automatic request asks Reload to start for a slot and Action ID.
2. Reload finds the active Character Item in each targeted slot and asks its reloadable Item Action whether the clip has space, ammunition remains, the item is owned, and shared-ammo equip rules allow the reload.
3. For every qualifying item, Generic Reloader starts its Animator Audio State, applies crosshair spread when **Reload Crosshairs Spread** is enabled, forces the item Animator parameters to update, and begins waiting for **Reload Event**.
4. `OnAnimatorItemReload`, or the configured duration, transfers ammunition through the Ammo and Clip modules. A Full reload fills as far as possible; a Single reload transfers one round and repeats while another round can load.
5. After the last transfer, the item waits for **Reload Complete Event**. `OnAnimatorItemReloadComplete`, or its duration, ends that item's reload state and plays its completion audio.
6. Reload clears each completed item and stops only when no targeted slot remains pending. A forced stop reports the unfinished reload as unsuccessful and cleans up its Reloader state.

The two checkpoints have different jobs: **Reload Event** changes the ammunition counts, while **Reload Complete Event** ends the ability. Keep both even when they occur close together in the animation.

For a detachable magazine, Generic Reloader can additionally wait for `OnAnimatorItemReloadDetachClip`, `OnAnimatorItemReloadDropClip`, `OnAnimatorItemReloadAttachClip`, and `OnAnimatorItemReactivateClip`. Use these only after assigning reloadable clip and attachment transforms. The reloadable clip must be a movable object with a MeshRenderer, not a SkinnedMeshRenderer or rig bone.

## Verify in Play Mode

1. Give a Shootable Action **Item Ammo**, a **Simple Clip** smaller than the available Inventory amount, and **Generic Reloader**. Confirm the Reload row's Action ID matches the action.
2. Fire until the clip is partly empty. Keep the Inventory, Shootable Action, and **Ultimate Character Locomotion** visible, then press **Reload**.
3. Confirm **Reload (Active)** appears, Item State Index **3** is supplied for the targeted slot, and Inventory ammo does not change before Reload Event.
4. At `OnAnimatorItemReload`, confirm the clip count increases and the matching Inventory ammo count decreases by the same amount.
5. Confirm Reload stays active after that transfer and stops only at `OnAnimatorItemReloadComplete`.
6. Change **Reload Type** to **Single**, empty several rounds, and reload again. Confirm one round transfers per Reload Event until the clip is full or Inventory ammo runs out.
7. Set **Slot ID -1** with two eligible equipped items. Confirm both can reload together and the ability remains active until both report completion.
8. Hold Use on the same weapon and press Reload; confirm manual reload waits. Start Use during a permitted reload and confirm only the matching Character Item's reload is cancelled.
9. Begin Reload, then request Equip Unequip with prevention enabled and disabled. Confirm the first setting delays the switch and the second cancels Reload before switching.

## Troubleshoot Reload

- **Pressing Reload does nothing:** check that the selected slot contains an active Character Item, **Action ID** matches its Shootable Action, the clip is not full, Inventory has the required ammo, and the weapon itself is still owned.
- **A warning says the item needs an Item Action:** the active Character Item has no action with the selected ID. Correct **Action ID** or add the intended Shootable Action.
- **The Shootable Action exists but cannot reload:** confirm its first enabled Ammo, Clip, and Reloader modules are valid. Reload uses those active single-choice modules, not a disabled or later alternative.
- **Item Ammo never becomes available:** assign **Ammo Item Definition** on Item Ammo and add that exact definition to Inventory. A pickup with another definition does not trigger or supply the reload.
- **Reload becomes active but ammo never moves:** **Reload Event** is waiting. Add `OnAnimatorItemReload` for the correct slot or disable **Wait For Animation Event** and use a verified duration.
- **Ammo moves but Reload never stops:** **Reload Complete Event** is waiting. Add `OnAnimatorItemReloadComplete` or configure its duration.
- **Only one of two slots reloads:** the other active item may use a different Action ID, have a full clip, have no available ammo, or fail the shared-ammo equip check. Inspect each Shootable Action separately.
- **Reload takes ammunition from the wrong pool:** check the active Item Ammo module's **Ammo Item Definition** and **Shared Ammo Item Identifier**. Only enable sharing on every weapon intended to use the same definition.
- **The weapon starts with a full clip unexpectedly:** any nonempty **Auto Reload** mask performs one immediate reload on first equip. Clear all Auto Reload choices when the initial clip must remain empty.
- **The reload animation is hidden by Aim:** move Reload above Aim in **Item Abilities**. Reload logs an editor warning when Aim has higher Animator priority.
- **Manual reload cannot start while firing:** this is the built-in Use priority for the same Character Item. Wait for Use to complete; an all-slot Reload can still process another eligible slot.
- **Reload cannot start near an obstacle:** [Third Person Item Pullback](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/third-person-item-pullback/) can deliberately block shootable Use and Reload while its collision volume is obstructed.
- **A detachable magazine stays in the hand or weapon:** verify **Reload Detach Attach Clip**, both perspective-specific reloadable clip and attachment transforms, and every detach, drop, attach, and reactivate event used by the animation.
- **Disabling Reload Can Camera Zoom does not change zoom:** this is a released-Version-3 limitation; the runtime does not read that Generic Reloader value. Configure and verify zoom through the Character Item, Aim, camera, or states instead.

## Related tasks

- [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) explains the Ammo, Clip, Reloader, projectile, and effect module groups.
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) explains how Action ID connects an item ability to Character Item behavior.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) covers weapon and Item Ammo ownership.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) covers the pickup that can trigger **Auto Reload Pickup**.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) explains the item action that has priority over Reload for the same Character Item.
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) covers the concurrent aiming state and item-ability list order.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) explains the equipment transition and **Prevent Start Use Reload Active**.
- [Animation Slot Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/animation-slot-event-trigger/) explains per-slot animation events and duration fallbacks.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists Reload's Item State Index **3**.

## Developer reference

Reload exposes **SlotID**, **ActionID**, the read-only **ReloadableItems** array, and `StopItemReload(int)`. With **Slot ID -1**, a ReloadableItems index matches the Inventory slot. With a slot-specific Reload row, its single internal entry is index **0**, so pass **0** to `StopItemReload` rather than the configured Inventory slot number.

Call `StartAbility()` on the selected Reload row for a code-driven request. It still runs the item, clip, and ammo checks, but its Input Index remains **-1**, so it does not enter Use's player-input-specific Reload block; other ability and module rules still apply. `ShootableAction.ReloadClip(instantly, fullClip)` reloads directly when `instantly` is `true`; when it is `false`, it finds the Reload ability matching the Character Item's slot and Action ID, and the Generic Reloader's **Reload Type** controls the animated Full or Single behavior.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) coordinates the runtime flow:

- **OnItemTryReload** `(int slotID, IItemIdentifier weapon, IItemIdentifier ammo, bool immediateReload, bool equipCheck)` requests an automatic or targeted reload.
- **OnItemReload** `(IReloadableItem)` is raised by the Reloader's Reload Event and tells the active Reload ability to transfer ammunition.
- **OnItemReloadComplete** `(IReloadableItem)` is raised by Reload Complete Event and clears that item from the active ability.
- **OnStartReload** `(ShootableReloaderModule)` reports that Generic Reloader began its animation workflow.
- **OnShootableItemAmmoChange** `(CharacterItem, ShootableAmmoModule)` and **OnShootableItemClipChange** `(CharacterItem, ShootableClipModule)` report the two ammunition counts independently.
- **OnCharacterItemAbilityActive** `(ItemAbility, bool)` reports Reload starting and stopping like other item abilities.

The Animator callbacks `OnAnimatorItemReload` and `OnAnimatorItemReloadComplete` are routed by slot through each active Generic Reloader. Optional magazine callbacks are registered directly on the character for the detach, drop, attach, and reactivate sequence.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-third-person-item-pullback"></a>

# Third Person Item Pullback

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/third-person-item-pullback/)

Third Person Item Pullback keeps an aimed shootable item from clipping through nearby geometry. Use it when the character should leave the aimed pose and stop shooting or reloading while a wall or other obstruction occupies the space in front of the weapon.

![Third-person character's rifle intersecting a wall without pullback protection](https://opsive.com/wp-content/uploads/2018/04/ThirdPersonWeaponClipping.png?v=40444aec8511)

The ability uses one or more capsule or sphere probes around the character. It starts automatically when a probe overlaps an allowed obstruction and stops automatically after every probe is clear.

## Before you begin

Third Person Item Pullback requires the Third Person Controller code and a character with **Ultimate Character Locomotion**. The relevant held item should use a **Shootable Action** when its Use input needs to be blocked.

The ability has no **Slot ID**, **Action ID**, or **Item Category** setting. One active pullback row affects every Reload ability and every Use ability that targets a Shootable Action, regardless of slot, action ID, or Item Set group. Use carefully when the character can operate independent primary and secondary equipment close to geometry.

## Configure Third Person Item Pullback

1. Select the character and expand **Item Abilities** on **Ultimate Character Locomotion**.
2. Select the plus button and add **Third Person Item Pullback**.
3. Confirm the editor creates an **ItemPullbackCollider** object and assigns its Collider to the ability's **Colliders** array. When the character has Animator Monitor models, the drawer creates one probe for each monitor; otherwise it creates one under the character.
4. Select each ItemPullbackCollider in the Scene view and place its capsule or sphere over the volume that the aimed weapon must keep clear.
5. Leave the generated Collider component disabled. The ability reads the shape and performs its own non-allocating overlap query; the probe does not need to participate in normal Rigidbody collision.
6. Set **Collision Layers** to the world geometry that should cause pullback. The starting mask excludes Ignore Raycast, TransparentFX, SubCharacter, Overlay, VisualEffect, and Water.
7. Keep **Max Collision Count 5** for a simple probe area. Increase it when the volume can overlap more than five colliders at once.
8. Enter Play Mode and adjust the probe position, capsule height, and radius until it activates before the visible item reaches a wall without triggering during ordinary open-space movement.

![Capsule-shaped ItemPullbackCollider positioned in front of a third-person character](https://opsive.com/wp-content/uploads/2018/04/ItemPullbackCollider.png?v=64cf2955529d)

The generated capsule starts at local position **(0, 1.5, 0.65)** with **Radius 0.25** and **Height 1**. Treat those values as a starting point, not a universal weapon size. Long rifles, short pistols, crouched poses, and non-humanoid models need their own measured volume.

The custom drawer also provides **Add Colliders** and **Remove Colliders** controls. Use them when the assigned probe objects were removed or the character's model setup changed, then recheck the complete **Colliders** array.

## Choose the obstruction volume

### Use only capsule or sphere colliders

Third Person Item Pullback supports **Capsule Collider** and **Sphere Collider** shapes. Other Collider types log an error and are not initialized for the overlap calculation.

Every assigned probe must have a radius greater than zero. A zero-radius probe causes the collision check to return clear immediately, so an earlier invalid entry can prevent later probes from being evaluated.

The ability calculates each probe in world space using its Transform, rotation, and scale. Moving or scaling the ItemPullbackCollider therefore changes the tested region even though its Collider component stays disabled.

### Match Collision Layers to real obstructions

The query uses **Collision Layers** and ignores trigger colliders. Colliders on the character or its children are also ignored, as are GameObjects with a Projectile component. This keeps the character's own body, held objects, and projectiles from activating pullback.

Include walls, cover, doors, and other solid level geometry. Exclude pickups, detection triggers, effects, and any helper layer that should not change the weapon pose.

**Max Collision Count** sizes the reusable results buffer. If more colliders overlap than the buffer can hold, later results are not inspected. Increase the value in crowded modular environments, especially when several ignored child or projectile colliders can occupy the probe alongside a real wall.

### Adapt the probe with States

The generated object includes an **Item Pullback Collider** State Behavior. Its **Local Position Offset** and **Radius Offset** both start at zero and can be changed by State presets.

Use those offsets when one probe should move or resize for crouching, a different weapon family, or another character state. The offsets are applied relative to the position and radius recorded when the component awakens. Use separate probe objects when the required shape or placement differs substantially.

## How it interacts with item abilities

### Aim stays active but yields its output

Third Person Item Pullback does not stop the [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) ability itself. When pullback activates, Aim suppresses its item substate and sends its aim signal as inactive; when the obstruction clears, Aim sends the signal as active again. This allows held aim input to resume without another button press.

Item Pullback has no Item State Index of its own; its starting value remains **-1**. It does not select a dedicated pullback animation. The visible result comes from removing the aimed output and stopping incompatible Use or Reload states. Add a separate State or custom animation workflow if the design needs a distinct weapon-compressed pose.

### Shootable Use is stopped and blocked

When pullback starts, it force-stops active [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) abilities whose targeted Item Action is a Shootable Action. While the obstruction remains, it blocks those Shootable Use abilities from starting again.

Use abilities for non-shootable actions are not blocked by this check. A melee or throwable action can continue unless its own modules or another ability prevent it.

### Every Reload is stopped and blocked

When pullback starts, it force-stops every active [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) ability. While active, it blocks any Reload row from starting, without checking Slot ID or Action ID. This global rule prevents a reload animation from pushing a shootable item back into the obstruction, but it also affects an independent off-hand reload.

### First-person views disable the ability

Third Person Item Pullback listens for perspective changes. It disables itself before a first-person view becomes active and enables itself for third-person views. The probe therefore does not interfere with first-person item positioning or animation.

## How it runs

1. The automatic ability evaluates each active assigned probe using an overlap capsule or overlap sphere query.
2. It ignores triggers, character-child colliders, projectiles, and layers outside **Collision Layers**.
3. The first accepted obstruction allows Item Pullback to start. Active Shootable Use and all active Reload abilities are force-stopped.
4. Aim remains active but clears its aiming output, so the item returns to its non-aim presentation instead of clipping farther into the obstruction.
5. While any accepted overlap remains, Item Pullback blocks new Shootable Use and Reload starts.
6. Its **Stop Type Automatic** repeatedly checks the probes. After every probe is clear, the ability stops and Aim restores its output when it is still active.

**Start Type** uses the inherited **Automatic** default, and the ability has no input name. Do not map a player button; size and layer the probe so collision alone controls the lifecycle.

## Verify in Play Mode

1. Equip a Character Item with a Shootable Action and hold Aim in third person while standing in open space. Confirm Third Person Item Pullback is inactive and the weapon uses its normal aimed pose.
2. Walk toward a wall slowly. Confirm **Third Person Item Pullback (Active)** appears before the visible weapon intersects the wall and Aim's visible output yields.
3. Hold the Use input while moving into the probe. Confirm the active Shootable Use stops and cannot restart while the wall remains inside the volume.
4. Begin Reload in open space, then move the probe into the wall. Confirm Reload stops. Try Reload again while obstructed and confirm it cannot start.
5. Back away from the wall. Confirm Item Pullback stops automatically and held Aim resumes without another press.
6. Walk through a trigger volume, past the character's own colliders, and near a projectile. Confirm none of those activate pullback.
7. Test the left and right edges, crouched height, every equipped weapon length, and each third-person model. Adjust or add probes until the visual clearance is consistent.
8. Switch to first person near the wall. Confirm Item Pullback disables, then switch back to third person and confirm collision control returns.

## Troubleshoot Third Person Item Pullback

- **The ability is disabled immediately:** check that **Colliders** is assigned. A null array disables the ability during initialization.
- **An error says only capsule and sphere colliders are supported:** replace every Box, Mesh, or other unsupported entry with a Capsule Collider or Sphere Collider, then rebuild the probe assignment before Play Mode.
- **The probe never detects a wall:** confirm its GameObject is active, its radius is greater than zero, the wall's layer is included in **Collision Layers**, and the wall uses a non-trigger Collider.
- **Only the first model works:** inspect the **Colliders** array and active model hierarchy. Each Animator Monitor model normally receives its own ItemPullbackCollider, and inactive model probes are skipped.
- **Detection works only from some directions:** inspect the probe's Transform, rotation, scale, capsule height, and center in Scene view. The overlap uses the actual world-space shape rather than the visible weapon mesh.
- **Pullback misses walls in crowded spaces:** increase **Max Collision Count**. A full non-allocating buffer can omit an accepted wall after ignored results occupy the available entries.
- **Pullback activates near harmless objects:** remove their layers from **Collision Layers**. Trigger colliders are already ignored, but solid pickup or effect colliders still count when their layers are included.
- **Aim remains listed as active:** this is expected. Item Pullback suppresses Aim's output rather than stopping the Aim ability, which lets held aim resume when the probe clears.
- **A melee action is still usable:** only Use abilities targeting Shootable Action are blocked. Add a separate rule when melee or throwable actions also need obstruction handling.
- **An off-hand reload is blocked by the primary weapon's wall probe:** Reload blocking is global and has no Slot ID filter. Use a customized ability when independent per-slot obstruction behavior is required.
- **No distinct pullback animation plays:** Item Pullback supplies Item State Index **-1**. Its built-in result is the non-aim pose; use a State or custom Animator workflow for a dedicated compressed-weapon pose.
- **The probe physically pushes other objects:** leave its Collider component disabled. The ability queries its geometry directly and does not require normal collision participation.

## Related tasks

- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) explains the aiming state that yields while Item Pullback is active.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) explains Slot ID, Action ID, and Shootable Action selection.
- [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) explains the reload workflow that Item Pullback stops and blocks.
- [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) covers the action type checked by the Use restriction.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains concurrency and Animator list order.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains presets that can drive Item Pullback Collider offsets.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) describes the standard layers excluded from the starting collision mask.
- [Third Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/) covers the visible held item whose clearance the probe protects.

## Developer reference

Item Pullback exposes the `Colliders` array and `CollisionLayers` mask. **Max Collision Count** is serialized with a starting value of **5**, but has no public property. `ItemPullbackCollider` exposes `LocalPositionOffset` and `RadiusOffset` for State-driven geometry changes.

Configure the Colliders array before `Awake`. Item Pullback caches the probe Transforms and allocates its hit buffer only during initialization; assigning a different array at runtime does not rebuild those caches.

The ability listens for **OnCameraWillChangePerspectives** `(bool firstPersonPerspective)` to enable or disable its third-person-only behavior. Normal **OnCharacterItemAbilityActive** `(ItemAbility, bool)` notifications report its start and stop; Aim uses those notifications to clear and restore its aim output.

Item Pullback emits no unique gameplay event. Query the ability's `IsActive` state or listen to the standard item-ability lifecycle when another system needs to react to an obstruction.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-use"></a>

# Use

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)

The Use item ability turns character input into an equipped item's action, such as firing a weapon, swinging a sword, throwing an object, casting a spell, or running a custom effect. Use selects the equipped Character Item by **Slot ID** and its Item Action by **Action ID**; the selected Usable Action and its modules decide what actually happens.

## Before you begin

The character needs:

- an Inventory with the Character Item owned and equipped;
- a Look Source attached to the character;
- a Character Item with a **Usable Action**, **Shootable Action**, **Melee Action**, **Throwable Action**, **Magic Action**, or another Item Action that implements the usable workflow;
- at least one enabled **Trigger** module on that action; and
- when the action uses animation, an Animator and event timing that match the item's visible use sequence.

Use has no **Item Category** field. Item Set categories decide what is equipped, but Use only examines the active Character Item in **Slot ID** and asks that item for **Action ID**.

## Configure Use

1. Select the Character Item and add or open the Item Action that should run.
2. Set the Item Action's **ID**. Keep **0** for a single action, or give each action on the same Character Item a unique ID. The action ID is not a module ID.
3. Configure the action's module groups. Every usable action needs an enabled main **Trigger** module. The **Usable** modules and the action-specific groups decide eligibility, timing, projectiles, collisions, impacts, effects, ammunition, or other results.
4. Configure the action's **Use Event** and **Use Complete Event** to match its animation. The released defaults wait for `OnAnimatorItemUse` to perform the use, then complete after **0.05** seconds rather than waiting for `OnAnimatorItemUseComplete`.
5. Select the character, expand **Item Abilities** on **Ultimate Character Locomotion**, select the plus button, and add **Use**.
6. Keep the normal ability defaults for a player-controlled action: **Start Type Button Down**, **Stop Type Button Up**, **Input Names Fire1**, **State Use**, and **Item State Index 2**.
7. Leave **Slot ID -1** to use every eligible equipped slot together, or enter one Inventory slot. Set **Action ID** to the matching Item Action ID; its default is **0**.
8. Leave **Rotate Towards Look Source Target** enabled when the character should face the look direction during use. Leave **Block Over UI** enabled when clicking interface controls must not fire or attack. Both settings are enabled by default.
9. Place Use above Aim in the **Item Abilities** list so Use's Animator values take priority while both abilities are active.
10. Enter Play Mode and confirm the intended action—not merely the Use ability—runs at the configured animation event or duration.

Use allows duplicate types. Add a separate row when another input, slot, or Action ID should run a different action. For example, one row can fire a rifle action while a second row uses another Action ID on that same Character Item for a melee strike.

## Choose which item action runs

### Use one slot or every equipped slot

With **Slot ID -1**, Use checks the active Character Item in every Inventory slot for the selected Action ID. Each matching action must implement the usable workflow and pass its module checks. The ability can start when at least one slot qualifies, and every qualifying slot participates.

Use a specific Slot ID when primary and off-hand items need different inputs, actions, or timing. It also makes troubleshooting clearer because only one equipped Character Item can answer the request.

In the released Version 3 runtime, a **Slot ID -1** action that fails its initial module eligibility check remains assigned when another slot qualifies. It can therefore enter the Use lifecycle and Animator state even when its modules prevent the gameplay result. Prefer separate slot-specific Use rows when the equipped items can differ in ammunition, charge, cooldown, or another start condition.

Two Use rows cannot operate on the same Character Item at the same time, even when they reference different Action IDs. Use rows can run together when they resolve to different Character Items, which supports independent equipment such as dual weapons or a primary item plus a secondary throwable.

### Select an action by ID, not by type or category

**Action ID** selects the component attached to the active Character Item. Use then requires that component to implement the usable-item contract. It does not search by action type, module type, Item Definition, or Item Category.

Choose the action architecture that matches the result:

- [Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) provides the shared Trigger and Usable module flow for a custom interaction.
- [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) fires hitscan or projectile weapons and coordinates ammunition, clips, and reloading.
- [Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) runs attacks, collision detection, impacts, and recoil.
- [Throwable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/) throws and re-equips inventory-backed projectiles.
- [Magic Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/) coordinates a caster and modular spell effects.

The Use row does not need to change when modules inside the selected action change. Keep its Slot ID, Action ID, and input stable while configuring the gameplay result on the Item Action.

## Control timing, repetition, and animation

The Use ability owns input and the broad Animator state. The selected Usable Action owns the detailed action cycle:

- **Use Rate** starts at **0.1** seconds and sets the earliest time another completed use can begin.
- **Use Event** starts by waiting for the `OnAnimatorItemUse` event. Its stored duration is **0.2** seconds and becomes the timer when event waiting is disabled.
- **Use Complete Event** starts as a timed event with a **0.05** second duration. Enable event waiting and add `OnAnimatorItemUseComplete` when completion must follow an exact animation frame.
- **Stop Use Ability On Complete Delay** starts at **1** second. A value of **0** allows an immediate stop after completion, a positive value delays the stop, and a negative value does not release the ability on completion.
- **Force Root Motion Position** and **Force Root Motion Rotation** are disabled by default. Enable them on the action only when its animation must own character motion during use.

The first enabled **Trigger** module is the main trigger. A Simple trigger performs one use, while Repeat, Burst, Charged, and combo triggers change when another cycle starts or when releasing input completes the action. The trigger still respects Use Rate, module eligibility, and both event triggers.

Use supplies **Item State Index 2** to participating slots. The selected action's enabled modules combine their data to supply the **Item Substate Index**. When the expected animation does not play, inspect both the ability's list priority and the action's active trigger or Animator Audio State rather than changing Action ID.

For facing, both **Rotate Towards Look Source Target** on Use and **Face Target** on the Usable Action must allow rotation. A Movement Type that uses independent look keeps control of facing even when both settings are enabled.

## Coordinate Use with other item abilities

### Aim

[Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) can stay active while Use runs. The Usable Action receives Aim's active state so its modules can select aimed behavior, and Use should remain above Aim when Item State Index **2** must win during the action. Aim resumes its normal Animator values after Use stops.

### Reload

Use has priority over [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) for the same Character Item. Starting Use stops that item's reload; an all-slot Reload can continue for other items. While Use is still performing an action, an input-started Reload removes matching items and starts only when another eligible reloadable item remains.

Reload can also keep dominant and non-dominant item flows apart. If an active Reload and a requested Use target items with opposite **Dominant Item** status, Reload blocks the Use request so incompatible item animation sets do not run together.

### Equip Unequip

With **Prevent Start Use Reload Active** enabled on [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/), a normal equipment change waits for Use to finish. A forced equipment request stops active Use, and an item that is already being unequipped blocks a new Use request.

### Third Person Item Pullback

[Third Person Item Pullback](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/third-person-item-pullback/) force-stops and blocks Use rows that target the built-in Shootable Action while an obstruction occupies the configured probe. It does not apply that check to Melee, Throwable, Magic, or a general Usable Action.

## How it runs

1. The configured input or an API request asks Use to start.
2. Use rejects the request when **Block Over UI** is enabled and the pointer is over UI, no Look Source is attached, another ability blocks the start, or no targeted action can begin.
3. It reads each targeted active Character Item, finds **Action ID**, confirms it is usable, and asks the action's enabled modules whether use can start.
4. The ability activates the **Use** State and supplies Item State Index **2**. Each participating action begins its trigger and supplies its module-composed Item Substate Index.
5. `OnAnimatorItemUse`, or the configured timer, tells the main Trigger module to perform the action. All enabled modules that participate in use receive that stage.
6. While the ability remains active, the action can repeat according to its Trigger module, Use Rate, input state, ammunition, combo state, and other module rules.
7. `OnAnimatorItemUseComplete`, or the configured completion timer, marks that cycle complete. The action decides when it can stop, and Use stops after every participating item has completed and released it.
8. Disabling gameplay input force-stops an active Use ability.

## Verify in Play Mode

1. Equip the target Character Item and keep **Ultimate Character Locomotion > Item Abilities** visible.
2. Press **Fire1**. Confirm **Use (Active)** appears and only the Character Item in the intended Slot ID supplies the configured Action ID.
3. Watch the animation and gameplay result together. Confirm the shot, hitbox, throw, spell, or custom effect occurs at **Use Event**, not when the button is merely pressed.
4. Confirm the Animator reports Item State Index **2** for the participating slot and the Item Substate Index expected from the selected action's modules.
5. Hold and release the input. Confirm Simple, Repeat, Burst, Charged, or combo behavior matches the main Trigger and that the ability stops only after the action's completion rules allow it.
6. Aim, then use the item. Confirm Use's animation takes priority and Aim returns afterward.
7. Start a reload for the same item, then press Use. Confirm that item's reload stops while other eligible reload slots can continue.
8. Attempt an equipment change during Use and approach a wall with a third-person shootable item. Confirm Equip Unequip and Item Pullback apply the intended restrictions.
9. Place the pointer over UI and press the Use input. Confirm nothing happens while **Block Over UI** remains enabled.
10. If using **Slot ID -1** or duplicate Use rows, test every equipment combination and confirm only the intended items participate.

## Troubleshoot Use

- **Use never becomes active:** check that the Character Item is equipped in **Slot ID**, its Item Action **ID** matches **Action ID**, the action implements the usable workflow, a Look Source is attached, and another ability is not blocking it.
- **Pressing Use over UI does nothing:** check **Block Over UI**. Disable it only when a new world action should be allowed to start through interface input; moving over UI does not stop an action that is already active.
- **Use becomes active but no shot, strike, throw, or effect occurs:** check the first enabled Trigger module and **Use Event**. Add `OnAnimatorItemUse` to the correct clip or disable event waiting and use a tested duration.
- **The animation finishes but Use remains active:** check **Use Complete Event**, `OnAnimatorItemUseComplete`, **Stop Use Ability On Complete Delay**, and any module that prevents the item or ability from stopping.
- **The wrong action runs:** inspect the Character Item's action IDs. Set the Use row's **Action ID** to the component ID, not a module index.
- **Both hands act when only one should:** replace **Slot ID -1** with the intended Inventory slot, or use separate slot-specific rows.
- **A repeated action is too fast or does not repeat:** check the main Trigger type and **Use Rate**, then check ammunition, charge, combo, and other action-specific module conditions.
- **The gameplay result works but the wrong animation plays:** keep Use above Aim, confirm **Item State Index 2**, and inspect the substate emitted by the selected action's modules.
- **The character does not turn toward the target:** enable **Rotate Towards Look Source Target** on Use and **Face Target** on the action, then check whether the active Movement Type uses independent look.
- **Reload or equipment changes do not start:** finish the active use, then inspect the Reload item match and Equip Unequip's **Prevent Start Use Reload Active** setting.
- **A shootable action stops near a wall:** inspect [Third Person Item Pullback](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/third-person-item-pullback/). Its obstruction handling deliberately blocks Shootable Use.
- **A custom Shootable Action subclass is not stopped by Item Pullback:** the released Version 3 type check recognizes the built-in Shootable Action but does not treat a derived action type as a match. Add a project-specific obstruction rule and verify it in Play Mode.

## Specialized Use abilities

- [In Air Melee Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/in-air-melee-use/) adds airborne force, landing behavior, and a grounded substate to a melee use sequence.
- [Melee Counter Attack](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/melee-counter-attack/) starts a dedicated melee response after a valid block within its distance and timing window.

These are separate Use subclasses. Add them only for those scenarios; keep the normal Use ability for general grounded item actions.

## Related tasks

- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains list order, concurrency, and the shared ability workflow.
- [Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) explains Trigger and Usable module groups in depth.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains Item State Index and Item Substate Index.
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/), [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/), [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/), and [Third Person Item Pullback](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/third-person-item-pullback/) describe the abilities coordinated with Use.

## Developer reference

Use exposes **SlotID**, **ActionID**, **RotateTowardsLookSourceTarget**, and **BlockOverUI** as writable properties. **UsableItems** returns the current participating `IUsableItem` array, **AIAgent** reports whether the attached look source is local, and **FaceTargetCharacterItem** returns the item currently asking the character to face its target.

`UsesItemActionType(Type)` checks whether the current row targets a requested action type. `IsUseInputTryingToStop()` exposes the continuous stop-input check, and `SetCanStopAbility(IUsableItem, bool)` lets a usable action release its participating slot after completion.

The built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) uses these Use lifecycle events:

- **OnUseAbilityStart** `(bool active, Use useAbility)` reports the overall Use start and stop.
- **OnUseAbilityUsedItem** `(IUsableItem usableItem)` reports each actual use attempt after its trigger becomes ready.
- **OnItemStartUse** `(IUsableItem usableItem, bool active)` reports an individual item's use lifecycle.
- **OnItemUse** `(IUsableItem usableItem)` fires when the configured Use Event becomes ready.
- **OnItemUseComplete** `(IUsableItem usableItem)` fires when the configured Use Complete Event becomes ready.

The animation event names are `OnAnimatorItemUse` and `OnAnimatorItemUseComplete`. Configure them per Character Item slot through the action's **Use Event** and **Use Complete Event** rather than calling the action modules directly.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-use-in-air-melee-use"></a>

# In Air Melee Use

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/in-air-melee-use/)

In Air Melee Use performs a dedicated melee attack after the character has left the ground, then drives a controlled rise, fall, and landing response. Use it for an aerial slash, downward strike, or ground-slam sequence that should not be available while grounded.

## Before you begin

The character needs:

- an Inventory with the melee Character Item owned and equipped;
- a Character Item with a [Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/);
- a melee Animator state that is allowed while airborne;
- a Look Source and normal [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) prerequisites; and
- for a typical player-controlled sequence, Jump and Fall configured on the character.

In Air Melee Use resolves the equipped item by **Slot ID** and its component by **Action ID**, then discards every selected action that is not a `MeleeAction`. Shootable, Throwable, Magic, and general Usable Actions cannot run through this ability.

## Configure In Air Melee Use

1. Select the melee Character Item and add or open the **Melee Action** intended for the airborne attack.
2. Give the action a unique **ID**. Use a separate action when the aerial attack needs a different animation, hitbox, impact, or damage setup from the grounded attack.
3. Configure an enabled Trigger module and its Animator Audio State. Disable **Require Grounded** for the airborne state.
4. Use the **In Air** Trigger when the same action must reject the normal Use ability while the character is airborne. Keep **Require In Air Ability In Air** enabled; it starts enabled in the released Version 3 source.
5. Configure the Melee Action's **Use Event**, **Use Complete Event**, attack timing, collision module, and impact modules. The actual hit still occurs through the action's normal module flow.
6. Select the character, expand **Item Abilities** on **Ultimate Character Locomotion**, select the plus button, and add **In Air Melee Use**.
7. Keep the inherited player defaults unless another input is intended: **Start Type Button Down**, **Stop Type Button Up**, **Input Names Fire1**, **State Use**, and **Item State Index 2**.
8. Set **Slot ID** and **Action ID** to the equipped Melee Action. **Slot ID** starts at **-1** and **Action ID** starts at **0**; a specific slot is safer when the two hands have different airborne attacks or eligibility.
9. Start with the built-in force values, then tune them against the character's gravity, jump height, animation, and desired landing time.
10. Set **On Grounded Substate Index** to the Animator substate that represents the landing phase. Its starting value is **11**.
11. Optionally assign **Ground Impact** and tune the positional and rotational camera recoil for the landing.
12. Keep this ability above Aim in the Item Abilities list when Item State Index **2** should control the aerial animation, then verify the complete takeoff-to-landing sequence in Play Mode.

The ability allows duplicate rows but cannot receive another start while it is already active. Use separate rows for different slots, Action IDs, or inputs, not to restart one aerial attack in mid-sequence.

## Tune the airborne motion

The ability applies its forces relative to the character rather than in fixed world axes.

| Setting | Starting value | Runtime effect |
| --- | --- | --- |
| **Upward Force** | `(0, 1, 0)` | Begins the aerial attack with a small local upward push. |
| **Upward Force Frames** | `4` | Spreads the upward force across four frames. |
| **Downward Force** | `(0, -15, 0)` | Pulls the character down after the local vertical velocity becomes negative. |
| **Downward Force Frames** | `4` | Spreads that one downward-force request across four frames. |
| **Allow In Air Stop** | Disabled | Keeps the attack active until landing unless it is force-stopped. |
| **On Grounded Substate Index** | `11` | Selects the landing animation while the Melee Action still needs time to complete. |
| **Ground Impact** | Unassigned | Plays no Surface Impact until an asset is assigned. |
| **Ground Position Camera Recoil** | Zero | Adds no positional camera force by default. |
| **Ground Rotation Camera Recoil** | Min `(-40, -40, 0)`, max `(40, 40, 0)`, minimum magnitude `(20, 20, 0)` | Adds a randomized rotational landing response. |

The downward force is applied once, on the first Late Update where local vertical velocity is below zero. It is not a continuous gravity replacement. Tune it after the normal Jump and gravity settings so the character does not hover at the apex or snap unnaturally to the ground.

Both the ability and the Melee Action start with root-motion position and rotation disabled. Leave them disabled when the Upward and Downward Force fields define the trajectory. Enable the Melee Action's **Force Root Motion Position** or **Force Root Motion Rotation** only for an airborne clip authored to control that motion, then retest the force values and landing detection together.

### Common scenarios

- **Aerial slash:** keep a modest upward force, use a lighter downward force, and let the normal melee Use and Use Complete events end the hit before landing.
- **Downward strike:** reduce or remove the upward push, use a stronger downward force after the apex, and keep a distinct landing substate.
- **Ground slam:** assign a Ground Impact, retain noticeable rotational recoil, and time the attack collision separately from the landing effect. Ground Impact is visual and audio feedback; the Melee Action's impact modules still own damage.
- **Different attacks per weapon or hand:** use a slot-specific row and matching Action ID so one equipped item cannot accidentally supply another item's aerial action.

## Coordinate Jump, Use, and the melee action

In Air Melee Use can start only while **Grounded** is false. When it starts, it stops an active [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) and an active normal Use ability. While the aerial ability remains active, it blocks another Jump or Use from starting.

The Melee Action is still responsible for whether its modules can begin, when the hitbox becomes active, which targets are impacted, and when use completes. The ability only adds the airborne eligibility, force arc, landing substate, Ground Impact, and camera response.

With **Slot ID -1**, the inherited Use lookup checks every active slot before this subclass removes non-melee actions. The released Version 3 runtime can retain a Melee Action that failed its initial module eligibility check when another slot qualified. Prefer separate slot-specific rows when the equipped melee items can differ in cooldown, combo state, or another start condition.

## How it runs

1. Input asks In Air Melee Use to start after the character is no longer grounded.
2. The inherited Use checks UI blocking, the Look Source, equipped Slot ID, Action ID, and each action's module conditions.
3. In Air Melee Use removes every selected action that is not a Melee Action. It starts only when at least one Melee Action remains.
4. Starting the ability stops an active Jump or normal Use, activates the **Use** State, supplies Item State Index **2**, begins the selected melee module flow, and applies Upward Force over the configured frames.
5. The Melee Action performs its attack at Use Event and supplies its normal module-composed Item Substate Index.
6. After local vertical velocity drops below zero, the ability applies Downward Force once over Downward Force Frames.
7. With the starting **Allow In Air Stop** value disabled, a normal stop request cannot end the ability while airborne.
8. When the grounded event becomes true, the ability asks any still-waiting Use Event to invoke its slot event, spawns Ground Impact, and sends the configured secondary camera forces.
9. If the Melee Action can stop, the ability ends immediately. Otherwise it supplies **On Grounded Substate Index** until the action completes and releases the ability.

The landing fallback in step 8 invokes the slot-specific Use Event. It resolves a waiting event only when **Wait For Slot Event** is enabled on that action's Use Event. With animation-event-only timing, make sure `OnAnimatorItemUse` occurs before landing or use a tested timed event so a short fall cannot leave the action waiting.

## Verify in Play Mode

1. Stand on the ground and press the In Air Melee Use input. Confirm the ability does not start.
2. Jump, wait until the character is airborne, and press **Fire1**. Confirm **In Air Melee Use (Active)** appears and the active Jump ability stops.
3. Confirm the selected component is the intended Melee Action ID. A Shootable, Throwable, Magic, or general Usable Action with the same ID must not participate.
4. Watch the trajectory frame by frame. Confirm the upward force begins at ability start and the downward force is applied once after the local vertical velocity becomes negative.
5. Confirm the melee hitbox and damage occur at the Melee Action's configured attack timing, not merely when the airborne ability starts.
6. Try Jump and normal Use again while the ability is active. Confirm both are blocked.
7. Land before the action has fully completed. Confirm Item Substate Index changes to **On Grounded Substate Index**, then returns after the action releases the ability.
8. Confirm the assigned Surface Impact appears at the grounded raycast hit and the camera receives the expected positional or rotational recoil.
9. Repeat from a very short drop and a tall jump. Confirm Use Event, Use Complete Event, landing substate, and stop behavior remain consistent.
10. Test every supported weapon, slot, perspective, gravity direction, and time scale used by the project.

## Troubleshoot In Air Melee Use

- **The ability will not start:** confirm the character is not grounded, the Character Item is equipped in **Slot ID**, **Action ID** matches a Melee Action, a Look Source is attached, and the pointer is not over UI while **Block Over UI** is enabled.
- **The normal Use ability performs the aerial action instead:** use the Melee Action's **In Air** Trigger and keep **Require In Air Ability In Air** enabled, then target the intended Action ID from this ability.
- **The ability becomes active but no attack occurs:** disable **Require Grounded** on the selected Animator Audio State and check the Melee Action's main Trigger, Use Event, attack timing, collision module, and impact modules.
- **A gun, throwable, spell, or custom action does nothing through this row:** this is expected. In Air Melee Use filters for Melee Action instances after the inherited Use lookup.
- **The character rises or falls too sharply:** adjust force magnitude and frame count together, then retest with the actual gravity, Jump, time scale, and root-motion settings.
- **The downward force never applies:** confirm the character's local vertical velocity becomes negative before landing. A short fall or root-motion clip can reach ground before that Late Update condition occurs.
- **The attack never stops after landing:** check Use Complete Event and whether the Melee Action can stop. If the action may land before Use Event, enable **Wait For Slot Event** or use reliable animation/timed event placement.
- **The landing animation is wrong:** confirm Item State Index **2**, the aerial action's normal substate, **On Grounded Substate Index 11**, and this ability's priority above Aim.
- **No landing effect appears:** assign **Ground Impact**, confirm the grounded raycast hits a configured surface, and verify the [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) setup.
- **The camera does not react on landing:** check both recoil ranges and confirm the active camera listens for the secondary camera-force event. Positional recoil starts at zero.
- **Jump or normal Use stops when the aerial attack begins:** this is expected. In Air Melee Use explicitly stops and then blocks both ability types while active.
- **Enabling Allow In Air Stop does not let the attack stop:** the released Version 3 condition is inverted. When Jump is inactive, enabling this field prevents a normal stop both in the air and after grounding. Leave it disabled and use a force-stop or a project-specific subclass when the attack must end before landing.

## Related tasks

- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) explains Slot ID, Action ID, input, Animator timing, and the shared usable-action lifecycle.
- [Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) explains attack, collision, impact, recoil, and Trigger modules.
- [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) and [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/) explain the locomotion abilities surrounding the aerial sequence.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains Item State Index and Item Substate Index.
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) explains the optional Ground Impact response.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains list order and ability concurrency.

## Developer reference

The writable public properties are **UpwardForce**, **UpwardForceFrames**, **DownwardForce**, **DownwardForceFrames**, **AllowInAirStop**, **GroundPositionCameraRecoil**, and **GroundRotationCameraRecoil**. **On Grounded Substate Index** and **Ground Impact** are serialized protected fields without public properties in the released class.

In Air Melee Use inherits the Use properties and events described on the [Use page](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/). It cannot receive multiple starts. Its `CanStartAbility` override requires an airborne character and at least one selected `MeleeAction`; `ShouldStopActiveAbility` and `ShouldBlockAbilityStart` coordinate Jump and normal Use.

The ability listens for **OnCharacterGrounded** `(bool grounded)`. On landing it calls the Surface Manager and sends **OnAddSecondaryCameraForce** `(Vector3 position, Vector3 rotation, float)` with a duration value of `0`. It does not emit a unique In Air Melee Use event; use the standard character item-ability lifecycle or inherited Use events when another system needs to observe it.

---

<a id="page-ultimate-character-controller-character-abilities-item-abilities-use-melee-counter-attack"></a>

# Melee Counter Attack

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/melee-counter-attack/)

Melee Counter Attack lets a character answer a recently blocked melee strike with a dedicated attack while the original attacker is still directly in front. Use it for a short, deliberate counter window after either a block or parry reaction.

## Before you begin

The defending character needs:

- a [Block](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/) item ability and an equipped Shield Action capable of starting it;
- an equipped Character Item with a [Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) dedicated to the counter attack;
- a counter animation and Melee Action timing, collision, and impact modules;
- the attacker included in **Character Layer Manager > Enemy Layers**; and
- an attacking opponent whose active Use ability is using the same Melee Action that produced the blocked impact.

Block and parry are both valid entry reactions. Block chooses its parry state when the defending Shield item also has a Melee Action, but Melee Counter Attack does not inspect that parry choice. It only requires that Block started from an impact whose source Item Action was a Melee Action.

## Configure Melee Counter Attack

1. Configure the defending item's Shield Action and the character's Block ability first. Confirm a melee hit starts Block before adding the counter.
2. On the countering Character Item, add or open a **Melee Action** for the counter. Give it a unique **ID** so the normal attack and counter can use different animation, collision, damage, and impact modules.
3. Configure the counter Melee Action's Trigger, Animator Audio State, Use Event, Use Complete Event, attack timing, collision, and impact modules. A new Usable Action waits for `OnAnimatorItemUse`, uses a timed **0.05** second Use Complete Event, and starts with **Stop Use Ability On Complete Delay 1**; align those settings with the counter clip. The action's use substate becomes the final part of the counter Animator value.
4. Select the character, expand **Item Abilities** on **Ultimate Character Locomotion**, select the plus button, and add **Melee Counter Attack**.
5. Keep the inherited player defaults unless a separate counter input is intended: **Start Type Button Down**, **Stop Type Button Up**, **Input Names Fire1**, **State Use**, and **Item State Index 2**. **Rotate Towards Look Source Target** and **Block Over UI** also start enabled.
6. Set **Slot ID** and **Action ID** to the equipped counter Melee Action. **Slot ID** starts at **-1** and **Action ID** starts at **0**.
7. Keep **Attack Distance** at its starting value of **0.6** while validating close melee range, then tune it against the character colliders and desired spacing.
8. Keep **Counter Attack Time Frame** at its starting value of **1** second, or shorten it for a strict timing challenge.
9. Confirm **Enemy Layers** includes the attacker's character collider layer. The forward check must hit the same character whose Melee Action caused the block.
10. If Counter Attack and normal Use share **Fire1**, place Melee Counter Attack above normal Use in the Item Abilities list. Also keep it above Aim when Item State Index **2** should control the counter animation.
11. Enter Play Mode and verify the entire sequence: active melee Use on the opponent, Shield impact, Block activation, counter input inside the window, forward range check, and counter hit.

The ability allows duplicate rows but cannot receive another start while active. Use separate rows only for different slots, Action IDs, or inputs.

## Understand the counter conditions

Every condition below must be true when the counter input is evaluated:

1. Block previously activated from a Shield impact whose **Source Item Action** is a Melee Action.
2. At that moment, the opponent had an active Use ability whose participating items included that exact Melee Action.
3. No Use ability was active on the defending character when Block activated.
4. No other item ability has started on the defending character since the valid Block activation.
5. The current time is still inside **Counter Attack Time Frame**.
6. The counter's Slot ID and Action ID resolve to at least one Melee Action that can start.
7. A forward Single Cast reaches a collider in **Enemy Layers** within **Attack Distance**.
8. That collider belongs to the same Ultimate Character Locomotion captured from the blocked Melee Action.

The opponent does not need to remain in its Use ability until the button is pressed. The active Use requirement is checked when Block starts; the later input checks the stored time, forward range, layer, and captured opponent.

Melee Counter Attack stops another active Use ability when it begins and blocks another Use from starting while the counter remains active. This prevents the normal attack assigned to the same button from running over the counter animation.

### Block versus parry

The defending Shield item determines whether Block displays Item State Index **8** or Parry Item State Index **9**. That presentation does not change counter eligibility. A normal shield block can arm the counter when the incoming source is a Melee Action, and a parry cannot arm it when the incoming source is non-melee.

The released Version 3 Melee Counter Attack class does not notify a separate **Counter Attack Response** ability; that legacy ability is not present in the released package. Use the counter Melee Action's collision and Impact modules, or a project-specific reaction system, when the opponent should play a special response.

## Choose the counter animation

Melee Counter Attack supplies **Item State Index 2** and composes a more specific **Item Substate Index** from three values:

```text
(opponent Animator Item ID * 1,000,000)
+ (opponent melee use substate * 1,000)
+ counter Melee Action use substate
```

For example, opponent Animator Item ID `22`, opponent use substate `1`, and counter action substate `2` produce `22001002`.

Keep each segment between `0` and `999` when the Animator decodes this as three three-digit groups. The opponent use substate is accepted only when it is positive, and the last positive value observed during this counter is cached. Before one is observed, the middle segment remains `0`; a later zero or negative value does not replace an already cached positive value.

Create Animator transitions for the combinations the game actually supports. A generic middle segment of `000` is a useful fallback when the attacker completes its use before the counter reads the substate.

## How it runs

1. The character's Shield Action receives an impact and starts Block.
2. Melee Counter Attack observes the Block activation through the standard item-ability event. It rejects a non-melee impact source and verifies that the opponent is actively using the exact source Melee Action.
3. A valid block stores the impact time, opponent Melee Action, opponent locomotion, and matching opponent Use ability.
4. The player presses the counter input. The inherited Use checks UI blocking, Look Source, Slot ID, Action ID, and module eligibility, then this subclass removes every selected action that is not a Melee Action.
5. The ability rejects an expired window or a forward cast that does not hit the stored opponent on **Enemy Layers** within **Attack Distance**.
6. On success, the counter stops another active Use, activates the **Use** State, supplies Item State Index **2** and the composed substate, and runs the selected Melee Action's normal Use, attack, collision, and impact flow.
7. Use Event and Use Complete Event control the visible counter timing. When the action releases the ability, the stored opponent, time, and substate are cleared.

Starting any other item ability after Block activation clears the stored counter time. If Counter Attack and normal Use share an input, the counter row must therefore be checked first; outside a valid window it returns false and normal Use can proceed.

## Verify in Play Mode

1. Equip the defender's Shield and counter Melee Action, and keep both characters' **Ultimate Character Locomotion** components visible.
2. Make the opponent start a melee Use and strike the Shield Collider. Confirm **Block (Active)** appears and the source action is the opponent's active Melee Action.
3. Press the counter input within one second while the opponent remains directly ahead and within **0.6** units. Confirm **Melee Counter Attack (Active)** appears and normal Use does not start.
4. Confirm the counter Animator uses Item State Index **2** and the expected composed Item Substate Index.
5. Confirm the counter hitbox and impact occur at the counter Melee Action's configured timing.
6. Repeat after waiting longer than **Counter Attack Time Frame**. Confirm normal Use can proceed but Counter Attack does not.
7. Repeat with the opponent outside Attack Distance, behind the defender, outside Enemy Layers, and with another enemy collider in front. Confirm every invalid arrangement is rejected.
8. Repeat with a shootable or other non-melee impact. Confirm Block may react according to the Shield setup but no counter opportunity is armed.
9. Start another item ability after the melee block but before pressing counter. Confirm the stored counter opportunity is canceled.
10. Test both a defending block item and a defending item that also has a Melee Action and therefore displays the parry state. Confirm both can arm the counter from a valid melee source.

## Troubleshoot Melee Counter Attack

- **Block works but Counter Attack never starts:** confirm Block's Impact Source contains a Melee Action, that exact action belonged to an active opponent Use ability at impact time, and the counter input occurs inside **Counter Attack Time Frame**.
- **The input performs the normal attack instead:** move Melee Counter Attack above normal Use when they share an input. Starting normal Use first clears the stored counter window.
- **The opponent is close but the range check fails:** face the captured opponent directly, include its collider layer in **Enemy Layers**, remove intervening enemy-layer colliders, and tune **Attack Distance** from its starting value of **0.6**.
- **A different nearby enemy prevents the counter:** the forward Single Cast must hit the captured attacker. Reposition the characters or correct the extra collider's layer.
- **The counter row selects a gun, spell, throwable, or general action:** it will be discarded. Set Action ID to a Melee Action on the active Character Item.
- **The wrong counter animation plays:** verify the opponent's Animator Item ID, its positive melee use substate, the counter Melee Action's use substate, Item State Index **2**, and the counter row's list priority.
- **The middle three digits are `000`:** the opponent Melee Action did not return a positive use substate when the counter queried it. Add the generic fallback transition or keep the opponent's attack substate available through the counter start.
- **The counter becomes unavailable after Aim, Reload, or another item ability starts:** this is expected in the released logic. Any later item-ability activation clears the stored impact time.
- **A non-melee block occurs during a prior valid window:** wait for another valid melee block before pressing counter. Released Version 3 clears the stored melee source for the non-melee impact but can leave the earlier timestamp, so mixed impact sources should not share one counter window.
- **The opponent does not play a special response:** configure that behavior through the counter Melee Action's Impact modules or project code. There is no released Version 3 Counter Attack Response ability notification.
- **The attack starts but never completes:** check the counter Melee Action's Use Event, attack timing, Use Complete Event, and Stop Use Ability On Complete Delay exactly as for normal [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/).

## Related tasks

- [Block](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/) explains Shield impacts, block-versus-parry presentation, and the captured Impact Sources.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) explains Slot ID, Action ID, input ordering, Animator timing, and the shared action lifecycle.
- [Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) explains Trigger, attack, collision, impact, and recoil modules.
- [Shield Item Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/shield/) explains the defensive impact that starts Block.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains Item State Index and Item Substate Index.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the supplied item-state conventions.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) explains the Enemy Layers mask used by the forward cast.
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/) explains list order and concurrency.

## Developer reference

**Attack Distance** and **Counter Attack Time Frame** are protected serialized fields with starting values of `0.6f` and `1f`; the released class does not expose public properties for them. Melee Counter Attack inherits Use's Slot ID, Action ID, rotation, UI blocking, participating actions, and lifecycle APIs.

The class cannot receive multiple starts. It overrides `CanStartAbility`, `ShouldStopActiveAbility`, `ShouldBlockAbilityStart`, and `GetItemSubstateIndex` to add the counter window, Melee Action filtering, opponent cast, Use exclusivity, and composite Animator value.

It listens for **OnCharacterItemAbilityActive** `(ItemAbility itemAbility, bool active)` to capture Block activation and clear invalid windows. It emits no unique counter event. Observe its standard item-ability lifecycle or inherited [Use events](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/), and handle opponent reactions through the Melee Action impact flow.

---

<a id="page-ultimate-character-controller-character-abilities-ability-starter"></a>

# Ability Starter

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/ability-starter/)

An Ability Starter lets an ability wait for a reusable custom input condition, such as a timed button sequence. Use it when the standard **Start Type** choices do not describe the input you need. Ultimate Character Controller includes one starter, **Combo Timeout**, and also discovers custom starter classes in your project.

## Before you begin

- Add or select the ability in the character's **Ultimate Character Locomotion** component.
- Configure each input name in the input system used by the project. See [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) for the controller's input workflow.
- Decide whether the requirement is an input sequence or an ability-specific world condition. For example, proximity and trigger checks normally belong to an ability such as [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/), while an Ability Starter answers when custom input is ready.

## Configure a timed combo

1. Select the ability in the **Abilities** list.
2. Set **Start Type** to **Custom**. The **Starter** field appears.
3. Select **Combo Timeout** from **Starter**.
4. In **Combo 1**, enter the first input name in the text field and choose **Button Down** or **Axis**.
5. Select **+** to add the next combo entry, then enter its input name and input type.
6. For every entry after **Combo 1**, enter the maximum time allowed after the previous input in the timeout field at the right. The first entry does not use its timeout value.
7. Configure **Stop Type** separately. The starter decides when the ability may start; it does not decide when the ability stops.

New combo entries start with an empty input name, **Button Down**, and a timeout of `0`. Fill in every input name and give later entries a practical positive timeout. In the example below, pressing `Action` and then `Fire1` within 0.2 seconds requests the ability start.

![Ability Inspector configured with Custom Start Type and a two-input Combo Timeout starter](https://opsive.com/wp-content/uploads/2019/02/ComboTimeoutStartType.webp?v=9cc8efcc9d1b)

## Key choices

### Standard input or a starter

Use the normal **Start Type** options for one common condition: **Automatic**, **Manual**, **Button Down**, **Button Down Continuous**, **Double Press**, **Long Press**, **Tap**, or **Axis**. Choose **Custom** only when an Ability Starter needs to combine or replace those input checks. Changing away from **Custom** removes the assigned starter from the ability.

### Button Down or Axis

**Button Down** advances the sequence only on the frame that the named button is pressed. **Axis** advances whenever the absolute raw axis value is nonzero, so an axis that is already held can satisfy its entry immediately. Use **Button Down** for deliberate taps and **Axis** for directional or analog steps.

### One input or a sequence

A single combo entry acts as one custom input check, and its timeout is unused. With two or more entries, the timeout on each later entry controls how long that entry may take after the preceding input.

### Trigger or external signal

**Combo Timeout** reads player input only. For an ability-specific proximity or trigger requirement, use an ability designed to detect the scene object. A custom starter can instead subscribe to a reusable game signal during `Initialize` and return whether that signal is ready. An `AbilityStarter` is a serializable helper rather than a component, so it does not receive Unity trigger messages by itself.

## How it runs

When **Start Type** is **Custom**, the locomotion handler asks the selected starter whether the input condition is ready. **Combo Timeout** advances through its entries in order. If the next entry is not received within its timeout, progress returns to **Combo 1**.

Returning `true` requests a start; it does not force one. The ability must still be enabled, pass `CanStartAbility`, and satisfy the normal priority and active-ability rules. After a successful start, **Combo Timeout** resets its sequence. The starter also receives the ability's start, stop, and destroy lifecycle callbacks. The ability's configured State, Animator behavior, and other start effects follow the usual ability lifecycle.

Calling `TryStartAbility` from code is a manual request and does not poll the starter first. By default, the normal start checks and starter lifecycle callbacks still run.

## Verify in Play Mode

1. Enter Play Mode with the character and ability visible in the **Ultimate Character Locomotion** Inspector.
2. Perform only the first combo input. The ability should remain inactive.
3. Perform the next input before its timeout. The ability should become active and show its expected animation or State.
4. Let the timeout expire and then press only the later input. The ability should remain inactive because the sequence has returned to **Combo 1**.
5. Repeat the full sequence after the ability stops. It should start again from the first entry.

## Troubleshooting

### The combo never starts the ability

**Check:** Confirm **Start Type** is **Custom**, **Starter** is **Combo Timeout**, every input name matches the project's input mapping, and the combo contains at least one entry.

**Fix:** Correct the input names and add a positive timeout to every entry after **Combo 1**. The editor keeps one entry in the list; a custom or programmatic configuration must also provide at least one entry.

### The second input is rejected immediately

**Check:** Look at the timeout value on the second entry, not the first. A new entry defaults to `0`.

**Fix:** Set the second entry to the time allowed after the first input, such as `0.2`. Each later entry owns its own waiting window.

### An axis step advances without a new press

**Check:** The entry uses **Axis**, and that axis is already held away from zero.

**Fix:** Return the axis to zero before that step or use **Button Down** when the sequence requires a new press.

### The first press after a timeout appears to do nothing

**Check:** **Combo Timeout** resets an expired sequence on that update and does not reuse the same input as a new **Combo 1** press.

**Fix:** Press the first input again after the reset, or increase the timeout if players should have a larger window.

### The sequence completes but the ability stays inactive

**Check:** Inspect whether the ability is enabled, whether `CanStartAbility` succeeds, and whether a higher-priority or active ability blocks it.

**Fix:** Resolve the ability requirement or ordering conflict. Do not use the starter to bypass the normal ability rules; see [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) for lifecycle and priority guidance.

## Create a custom starter

Create a serializable class derived from `AbilityStarter`. The Inspector discovers non-abstract starter types in the project's loaded assemblies and adds them to the **Starter** dropdown. `CanInputStartAbility` should report only whether the custom input or signal is ready; leave the ability's gameplay requirements in `CanStartAbility`.

```csharp
using Opsive.Shared.Input;
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Character.Abilities.Starters;
using System;
using UnityEngine;

[Serializable]
public class MyAbilityStarter : AbilityStarter
{
    public override void Initialize(GameObject character, Ability ability)
    {
        base.Initialize(character, ability);
        // Subscribe to a custom signal if needed.
    }

    public override bool CanInputStartAbility(IPlayerInput playerInput)
    {
        return false;
    }

    public override void AbilityStarted() { }

    public override void AbilityStopped() { }

    public override void OnDestroy()
    {
        // Unsubscribe from custom signals here.
    }
}
```

`Initialize` supplies the character and owning ability through the protected `m_GameObject` and `m_Ability` fields. Reset temporary input progress in `AbilityStarted` or `AbilityStopped` as appropriate, and release event subscriptions in `OnDestroy`. For standard active/inactive notifications, locomotion abilities use `OnCharacterAbilityActive` and item abilities use `OnCharacterItemAbilityActive`. See [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) and [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) for the surrounding extension points.

## Related tasks

- [Configure character input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Understand ability lifecycle and priority](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Create a new ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)
- [Use States with an active ability](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

---

<a id="page-ultimate-character-controller-character-abilities-move-towards-location"></a>

# Move Towards Location

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/)

Use **Move Towards Location** to define where a character must stand and face before Interact, Drive, Ride, or another location-aware ability begins.

The component defines an arrival pose and its acceptable position and rotation range. It does not move the character by itself; the character's **Move Towards** ability performs the approach and hands control to the requested ability after arrival.

## Before you begin

- Add [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) to the character's **Ultimate Character Locomotion** component.
- Keep one Move Towards ability on the character. The controller stores a single special Move Towards reference for this handoff.
- Place Move Towards above the ability it prepares in the **Abilities** list. If pathfinding is used, place [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) above Move Towards.
- Confirm that the waiting ability actually returns Move Towards Location components. Interact reads locations from the exact Interactable GameObject; Drive and Ride read locations from their source hierarchies.

## Place an arrival location

This example positions the character for a button interaction:

1. Select the same GameObject that contains **Interactable**. Interact does not search its children for Move Towards Location.
2. Add the **Move Towards Location** component.
3. Position and rotate the GameObject as a stable reference for the button. Alternatively, keep the existing Transform and use **Offset** and **Yaw Offset** to place the arrival pose relative to it.
4. Select the component and inspect its Scene view gizmo. The green arrow shows the target facing direction. Move the orange arrival point in front of the button and point the arrow toward the button.

![Move Towards Location Scene view gizmo positioned in front of an interaction target](https://opsive.com/wp-content/uploads/2018/04/AbilityStartLocationGizmoLocation.png?v=689bdc9de85e)

5. Increase **Size** when the character may arrive anywhere inside an area instead of at one exact point. The orange wire box represents that area.
6. Set **Distance** for the remaining positional tolerance and **Angle** for the accepted facing arc. The translucent green arc represents the full Angle value around the target direction.

![Move Towards Location gizmo with orange Size bounds and a green Angle arc for valid arrival variance](https://opsive.com/wp-content/uploads/2018/04/AbilityStartLocationGizmoVariance.png?v=3a4087c8bde5)

7. Keep **Require Grounded** enabled for a normal floor interaction. Disable it only when an airborne or freely positioned character must match the vertical target too.
8. Keep **Precision Start** enabled when the next animation must begin from a settled pose. Disable it when the immediate handoff matters more than waiting for the final Animator transition.
9. Add another Move Towards Location component when the object has several valid approach points. Move Towards chooses the closest returned location when none is already valid.

For Drive or Ride, a dedicated child GameObject is often clearer because those abilities collect locations below their source. Follow the owning ability's page for its exact source hierarchy and any collider-clearance requirements.

## Connect the character ability

1. Select the character and expand **Ultimate Character Locomotion > Abilities**.
2. Add **Move Towards** if it is missing.
3. Keep its **Start Type** set to **Manual**. The controller or gameplay code starts it; it is not a player-input ability.
4. Order optional pathfinding above Move Towards, Move Towards above Interact or another waiting ability, and lower-priority actions below them.
5. Trigger the waiting ability normally. When that ability returns one or more Move Towards Location components, the controller starts Move Towards first if the character is not already inside a valid arrival pose.

### There are no location IDs to match

Released UCC Version 3.2.0 has no ID field on Move Towards Location and no matching location ID on Move Towards. The handshake uses component references returned by `Ability.GetMoveTowardsLocations()`.

Do not match the Interact ability's **Interactable ID**, inherited **Object ID**, **Ability Index**, or an Object Identifier to Move Towards Location. Those values select targets or animation branches; they do not connect an arrival location. For Interact, the connection is the location component being on the same GameObject as the selected Interactable. For a custom ability, the connection is its `GetMoveTowardsLocations()` return value.

Ability-list position is an index used for priority, not a location ID. Move Towards warns when it is below the waiting ability because that higher-priority ordering can interrupt the intended handoff.

## Choose the arrival settings

| Setting | Version 3.2.0 default | Result |
| --- | --- | --- |
| **Offset** | `(0, 0, 1)` | Target position in the component GameObject's local space. Moving or rotating that GameObject moves the target pose. |
| **Yaw Offset** | `180` | Target facing around the component's local Y axis. This replaces the stale **Rotation Offset** name from older documentation. |
| **Size** | `(0, 0, 0)` | Acceptable box centered on Offset. Zero means no sized arrival area. |
| **Distance** | `0.01` | Positional tolerance after the Size allowance is applied. The Inspector range is `0.0001` to `100`. |
| **Angle** | `0.5` | Full accepted facing arc in degrees. Runtime validation allows half this value to either side of the target direction. `360` accepts any facing. |
| **Require Grounded** | Enabled | Requires the locomotion controller to be grounded. With this enabled, grounded state replaces the vertical Distance check; horizontal arrival is still checked. |
| **Precision Start** | Enabled | Stops residual movement and waits for the base Animator layer to leave transitions before the waiting ability starts. |
| **Movement Multiplier** | `1` | Scales only this location's approach input. It combines with Move Towards **Input Multiplier** and an active Speed Change multiplier. |

Start with the defaults for a tightly aligned interaction, then widen **Size**, **Distance**, or **Angle** only as far as the following animation allows. A button press may need a narrow facing arc; a pickup without a contact animation can usually accept a larger area and angle.

When **Size** is nonzero, its box is the main positional allowance and **Distance** is the remaining tolerance. Use Size to describe a deliberate standing region rather than making Distance large enough to start from visibly incorrect positions.

## How the handoff runs

1. The player or code tries to start Interact, Drive, Ride, or another ability.
2. Ultimate Character Locomotion asks that ability for `GetMoveTowardsLocations()`.
3. With no returned location, the requested ability continues normally. If any returned location already accepts the character's position and rotation, Move Towards also stays inactive and the requested ability continues.
4. Otherwise, Move Towards selects the closest returned location. It records the requested ability as **On Arrive Ability** and starts its own manual ability lifecycle.
5. If an active Pathfinding Movement ability is configured above it, Move Towards supplies the destination to pathfinding. Otherwise it generates direct positional input. It rotates the character toward **Target Rotation** and temporarily forces independent look control.
6. Position is accepted from **Size**, **Distance**, and **Require Grounded**. Rotation is accepted inside half the configured **Angle** on each side of **Yaw Offset**.
7. With **Precision Start** enabled, Move Towards resets remaining movement and rotation and waits for the final settling frames, Animator layer-zero transitions, and Item Equip Verifier handoff.
8. Move Towards stops, releases look and optional input control, stops its active pathfinding ability, and then starts the waiting ability.

Move Towards records the target position when it begins. Its **Moving Target Distance Timeout** can stop the approach when the location moves farther than that configured limit. If the character makes no movement or rotation progress for **Inactive Timeout**, the same early-stop path runs. **Teleport On Early Stop** decides whether the character is placed at the target and the waiting ability starts, or whether the pending action is cancelled.

If Move Towards is forcibly stopped for another reason, it clears the pending **On Arrive Ability** rather than starting it.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the character has exactly one enabled Move Towards ability;
- optional pathfinding is above Move Towards and Move Towards is above the waiting ability;
- the location is on the exact GameObject or hierarchy returned by that ability;
- the Scene view arrow faces the direction the character should face;
- the orange Size box and green Angle arc allow the intended approach without overlapping an unrelated interaction;
- **Distance**, **Require Grounded**, and **Precision Start** match the animation; and
- no target, ability, or Object Identifier ID is being used as a nonexistent location-ID link.

## Verify in Play Mode

1. Start outside the orange Size box and trigger the waiting ability.
2. Select the character and confirm **(Active)** appears beside Move Towards while Interact or the other requested ability remains pending.
3. Confirm the character approaches the selected location and faces the Scene view arrow direction.
4. Enter the valid position but face outside the green arc. Confirm the waiting ability does not begin until the character finishes turning.
5. With **Precision Start** enabled, confirm movement settles before the next animation begins. Disable it and repeat only if the design needs an immediate handoff.
6. When several locations exist, approach from different sides and confirm the closest valid location is selected.
7. For a grounded location, step or fall near the target and confirm the handoff waits until the character is grounded.
8. Block the route longer than Move Towards **Inactive Timeout** and confirm the result matches **Teleport On Early Stop**.
9. If the target can move, move it beyond **Moving Target Distance Timeout** and verify the same early-stop policy.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The requested ability starts immediately without moving. | It may return no locations, or the character may already satisfy one location's position and rotation. | Put the component in the hierarchy that the ability returns, then tighten Size, Distance, or Angle if the current pose should not count as arrived. |
| Interact finds the object but ignores its location. | Interact reads Move Towards Location components from the exact Interactable GameObject. | Move or duplicate the component onto that GameObject instead of a child. |
| The character moves toward the wrong side. | Check the component Transform, **Offset**, and **Yaw Offset** in the Scene view. | Reposition the Offset and point the green arrow toward the intended facing direction. |
| The character reaches the point but the next ability never starts. | Check **Angle**, **Require Grounded**, **Precision Start**, the base Animator layer for a continuing transition, and Item Equip Verifier. | Widen only the necessary threshold, restore a grounded pose, fix the transition, or disable Precision Start when a settled animation pose is not required. |
| The character uses the wrong one of several locations. | Move Towards chooses the closest target direction, not a location ID. | Reposition the locations or return only the locations that are valid for the current action. |
| The character walks directly through obstacles. | No Pathfinding Movement ability is active above Move Towards. | Add and configure NavMeshAgent Movement, bake the NavMesh, and keep it above Move Towards. |
| The character unexpectedly teleports to the target. | It stopped making progress for **Inactive Timeout** or the target exceeded **Moving Target Distance Timeout**, while **Teleport On Early Stop** was enabled. | Correct the obstruction or timeout, or disable teleporting so the pending action is cancelled. |
| Player input fights the automatic approach. | Move Towards **Disable Gameplay Input** is disabled. | Enable it when the approach should exclusively control movement; input is restored when Move Towards stops. |
| Adding matching IDs has no effect. | Move Towards Location has no location ID in Version 3.2.0. | Remove the assumed ID link and return the actual component from `GetMoveTowardsLocations()`. |

## Related tasks

- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/) configures movement, pathfinding, timeouts, input control, and independent destinations.
- [Interact](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/) returns locations from the exact Interactable GameObject.
- [Drive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/) uses child locations as vehicle entry points.
- [Ride](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/ride/) uses child locations for mounting and dismount clearance.
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) adds obstacle-aware routing before final alignment.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains list priority and the shared ability lifecycle.
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) shows how to add a custom ability that can return arrival locations.

## Developer reference

Override `Ability.GetMoveTowardsLocations()` when a custom ability needs a prepared pose. Return `null` or an empty array when no approach is required. Return several components when Move Towards should choose the closest one.

```csharp
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Objects.CharacterAssist;
using UnityEngine;

public class UseConsoleAbility : Ability
{
    [SerializeField] private GameObject m_Console;

    public override MoveTowardsLocation[] GetMoveTowardsLocations()
    {
        return m_Console != null
            ? m_Console.GetComponents<MoveTowardsLocation>()
            : null;
    }
}
```

`MoveTowardsLocation` exposes `Offset`, `YawOffset`, `Size`, `Distance`, `Angle`, `RequireGrounded`, `PrecisionStart`, and `MovementMultiplier`. Runtime values include `TargetPosition`, `TargetRotation`, `StartOffset`, and `StartYawOffset`. `GetTargetDirection`, `IsPositionValid`, and `IsRotationValid` expose the same checks used by Move Towards.

`MoveTowards` exposes `StartMoving(MoveTowardsLocation[], Ability)`, `MoveTowardsLocation(Vector3)`, `MoveTowardsLocation(Vector3, Quaternion)`, `StartLocation`, `OnArriveAbility`, and its Inspector settings. `UltimateCharacterLocomotion.MoveTowardsAbility` returns the controller's cached Move Towards instance.

The position-only `MoveTowardsLocation(Vector3)` overload creates an independent runtime location when needed, sets **Offset** and **Yaw Offset** to zero, disables **Precision Start**, sets **Distance** to `1`, and sets **Angle** to `360`. The position-and-rotation overload uses the same runtime location but keeps its current Angle.

When **Disable Gameplay Input** is enabled, Move Towards sends `OnEnableGameplayInput` with `false` on start and `true` on stop. It sends `OnCharacterForceIndependentLook` with `true` while it owns final facing and `false` on stop. It also listens to `OnCharacterAbilityActive` so an active Speed Change multiplier contributes to its generated input.

In multiplayer builds, `StartMoving` rejects a non-authoritative, non-local character. Destination selection and the waiting-ability handoff therefore begin on the character owner or authority path rather than independently on every observer.

---

<a id="page-ultimate-character-controller-character-abilities-animator-motion"></a>

# Animator Motion

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/animator-motion/)

Animator Motion gives an active ability a timed movement or rotation curve when its animation does not provide suitable [root motion](https://docs.unity3d.com/Manual/RootMotion.html). Use it for a short, authored motion such as stepping through a door or turning during a first-person animation; prefer animation root motion when the clip already contains the movement you need.

## Before you begin

- Add or select the ability that should own the motion.
- Decide which local axes the ability needs. X moves right or left, Y moves up or down, and Z moves forward or backward relative to the character.
- Confirm how the ability starts and stops. The Animator Motion asset supplies deltas only while the ability is active; its **Duration** does not start or stop the ability.

## Create and assign the motion

1. In the Project window, select **Assets > Create > Opsive > Ultimate Character Controller > Animator Motion**.
2. Choose a filename and save the new `.asset` inside the project's `Assets` folder.
3. Select the new asset. A new Animator Motion starts with a **Duration** of `5`, and all six curves are flat at `0`.
4. Set **Duration** to the final time shared by the position and rotation curves.
5. Expand **Delta Position** and edit **X Position**, **Y Position**, or **Z Position** for translation.
6. Expand **Delta Rotation** and edit **X Rotation**, **Y Rotation**, or **Z Rotation** for Euler rotation in degrees.
7. Select the character, open the ability in the **Ultimate Character Locomotion** component, and expand **General**.
8. Assign the asset to **Animator Motion**.
9. Set **Use Root Motion Position** to **True** when the asset supplies position, and set **Use Root Motion Rotation** to **True** when it supplies rotation. An individual ability may already have a different default, so verify both fields instead of assuming the asset enables them.

![Ability General settings with Use Root Motion Position set to True and OpenDoorAnimatorMotion assigned to Animator Motion](https://opsive.com/wp-content/uploads/2018/05/AnimatorMotionField.png?v=592dcf191672)

The example asset below lasts 1.883 seconds. X and Y position remain at zero, Z begins contributing after about one second, and all rotation curves remain at zero.

![Animator Motion asset with a 1.883-second duration, a delayed Z position curve, and zero X, Y, and rotation curves](https://opsive.com/wp-content/uploads/2018/05/AnimatorMotion.png?v=7d71c9e10dfe)

## Shape the curves

The horizontal axis is elapsed time since the ability started. The vertical value is the position or rotation delta contributed on that controller update; it is not the character's total displacement or angle from the start.

For a motion that pauses and then steps forward, keep **Z Position** at zero during the pause, raise it during the step, and return its final key to zero. Keep every unused curve flat at zero. Use a small, visible test curve first, then tune it while watching the result in Play Mode.

Changing **Duration** moves the final key of each curve to the new time. It does not proportionally retime intermediate keys, so inspect and reposition those keys after changing the duration of an established motion.

## Key choices

### Animator Motion or animation root motion

Animator Motion is added to the root-motion position already collected for the update, and its rotation is composed with the collected root-motion rotation. If the animation clip already moves or turns the character, a nonzero Animator Motion curve adds a second contribution. Remove one source or keep the overlapping Animator Motion curves at zero unless the additive result is intentional.

### Position, rotation, or both

Enable only the root-motion channels needed by the ability. A position-only asset can keep all rotation curves at zero; a turn-only asset can keep all position curves at zero. **No Override** uses the character's existing root-motion setting, **True** forces that channel on while the ability is active, and **False** prevents that channel from being consumed.

### One asset or several variants

Animator Motion is a shared `ScriptableObject`. Reusing one asset gives multiple abilities the same curve data, and editing it changes every reference. Duplicate the asset before tuning a variant that should behave differently.

## How it runs

When the ability starts, its elapsed motion time begins at zero. On each active update, the ability evaluates all six curves at that elapsed time. Position is transformed from the character's local axes and added to the pending root-motion position; Euler rotation is converted to a quaternion and multiplied into the pending root-motion rotation.

The character controller applies a channel only when root-motion position or rotation is enabled. Other active abilities can also add motion or disable a channel, so compatible abilities should not carry overlapping Animator Motion assets unless their combined result is intentional.

Stopping the ability stops further curve evaluation. Starting it again resets elapsed time to zero. Reaching **Duration** alone does not stop the ability, activate a State, or send an Animator Motion event; those remain part of the owning ability's normal lifecycle.

## Verify in Play Mode

1. Give one curve a clearly visible interval and return its final value to zero.
2. Enter Play Mode and start the ability while viewing the character from an angle that makes the chosen axis clear.
3. Confirm the character remains still where the curve is zero, moves or rotates during the nonzero interval, and stops receiving motion when the curve returns to zero.
4. Confirm the ability stops through its configured stop condition. If the ability remains active after the asset duration, that is expected until its own stop rule succeeds.
5. Start the ability again and confirm the curve begins from time zero rather than continuing from the previous run.

## Troubleshooting

### The curve is visible but the character does not move or rotate

**Check:** Confirm the ability is active, the asset is assigned to **Animator Motion**, the relevant curve is nonzero, and **Use Root Motion Position** or **Use Root Motion Rotation** is **True** or otherwise enabled on the character.

**Fix:** Enable the required root-motion channel. If it is already enabled, check whether another active ability sets that channel to **False**.

### The character moves or turns too far

**Check:** Determine whether the animation clip already supplies root motion on the same channel. Animator Motion is additive rather than a replacement.

**Fix:** Remove the Animator Motion contribution, remove the duplicate animation root motion, or reduce the corresponding curve values.

### The character keeps drifting after the intended motion

**Check:** Inspect the last value of each position and rotation curve. The ability continues evaluating the curve while it remains active.

**Fix:** Return the final delta values to zero and configure the ability's stop condition. Do not rely on **Duration** to stop the ability.

### Changing Duration gives uneven timing

**Check:** **Duration** changes the final key time, but intermediate keys keep their existing times.

**Fix:** Reposition the intermediate keys after changing **Duration**, or author the intended duration before shaping the detailed curve.

### Editing one motion changes another ability

**Check:** Both abilities reference the same Animator Motion asset.

**Fix:** Duplicate the asset and assign the copy before creating a separate variation.

## Developer details

`AnimatorMotion` derives from `ScriptableObject`. It exposes `XPosition`, `YPosition`, `ZPosition`, `XRotation`, `YRotation`, and `ZRotation` as `AnimationCurve` properties. `EvaluatePosition(float time, ref Vector3 position)` writes the sampled local position delta, while `EvaluateRotation(float time, ref Quaternion rotation)` writes the sampled Euler curves as a quaternion. The owning ability exposes the asset through `Ability.AnimatorMotion`.

The base `Ability.Update()` performs this evaluation for every active ability with an assigned asset. Multiple active assets therefore add their position contributions and compose their rotations in ability update order. The character's **Root Motion Speed Multiplier** scales animation-provided root motion when it enters the controller; it does not scale the curve contribution that `Ability.Update()` adds directly. Adjust the Animator Motion curves when only this asset should change.

Animator Motion has no dedicated start, stop, State, or event API. Use the owning ability's `OnCharacterAbilityActive` notification, or `OnCharacterItemAbilityActive` for an item ability, when code needs to observe its lifecycle. See [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) and [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) for those extension points.

## Related tasks

- [Configure abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Configure the character Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/)
- [Use States with an active ability](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Create a new ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)

---

<a id="page-ultimate-character-controller-character-abilities-new-ability"></a>

# New Ability

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)

Create a custom Ability when a character behavior must participate in the Ultimate Character Controller's input, priority, movement, State System, item, or Animator lifecycle. Use an [included ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/) when it already provides the behavior; custom code is most useful for a new gameplay rule or a project-specific combination of those systems.

## Before you begin

- Start with a working Version 3 character and decide what starts and stops the behavior: player input, an environmental condition, another script, or custom logic.
- Store project scripts outside the UCC package so package updates do not overwrite them. If your scripts use an assembly definition, add a reference to `Opsive.UltimateCharacterController`.
- If input starts the ability, create the matching action or input name in the input integration used by the character.
- Only prepare an Animator branch when the behavior needs a different animation. An Ability can run without setting an Animator parameter.

## Create the smallest useful ability

This example creates a hold-to-crawl Ability. While it is active, UCC exposes a `Crawl` State and sends `101` through the Animator's `AbilityIndex` parameter.

1. Create `Crawl.cs` in a project script folder.
2. Add the following class:

```csharp
using Opsive.UltimateCharacterController.Character.Abilities;

[DefaultInputName("Crawl")]
[DefaultStartType(AbilityStartType.ButtonDown)]
[DefaultStopType(AbilityStopType.ButtonUp)]
[DefaultAbilityIndex(101)]
[DefaultState("Crawl")]
[System.Serializable]
public class Crawl : Ability
{
}
```

3. Let Unity compile without errors.
4. Select the character root and open **Ultimate Character Locomotion**.
5. In **Abilities**, select the add button and choose **Crawl**.
6. Confirm these values on the new entry:
   - **Start Type**: **Button Down**
   - **Stop Type**: **Button Up**
   - **Input Names**: **Crawl**
   - **State**: **Crawl**
   - **Ability Index Parameter**: **101**

The default attributes are read when UCC creates a new Ability entry. Changing an attribute later does not rewrite an entry that is already serialized on a character; update that entry in the Inspector or remove and add it again.

The class can remain empty because the base `Ability` handles input, activation, State System changes, Animator parameter selection, and cleanup. Add overrides only for behavior that is specific to the new Ability.

## Choose how the ability starts and stops

Choose the simplest lifecycle that represents the gameplay rule:

| Use case | Start and stop choice |
| --- | --- |
| Active while a button is held | **Button Down** and **Button Up**, with the same **Input Names** value |
| Toggle on and off | **Button Down** and **Button Toggle** |
| Continuously test an environmental condition | **Automatic** start and usually **Automatic** or **Manual** stop; `CanStartAbility()` and `CanStopAbility(bool)` must provide the gates |
| Start from another system | **Manual**, then call `TryStartAbility` and `TryStopAbility` |
| Use a reusable project-specific rule | **Custom**, then assign a **Starter** or **Stopper** |

**Automatic** start is evaluated repeatedly, so an Ability that always returns `true` from `CanStartAbility()` will start whenever its other constraints permit it. **Manual** does not react to **Input Names**.

Ability list order is also priority: a lower list index has higher priority. A non-concurrent Ability normally cannot start while a higher-priority non-concurrent Ability is active, and starting a higher-priority Ability stops lower-priority non-concurrent Abilities. Override `IsConcurrent`, `IgnorePriority`, `ShouldBlockAbilityStart`, or `ShouldStopActiveAbility` only when the behavior deliberately needs different conflict rules.

## Connect State and Animator behavior

**State** and **Ability Index Parameter** serve different purposes:

- **State** enables the named UCC State while the Ability is active and disables it when the Ability stops. Use it for State presets or for another system that observes the State.
- **Ability Index Parameter** supplies the Animator's `AbilityIndex` value. Leave it at `-1` when the Ability does not need its own Animator branch.
- When `AbilityIndex` changes, the Animator Monitor also sets the `AbilityChange` trigger. Animator transitions can combine that trigger with `AbilityIndex`, `Moving`, `AbilityIntData`, or `AbilityFloatData`.

Give each Animator-routed behavior a value that is unique within that character's controller. The number does not need to match an Object Identifier or any other ID.

## Choose movement, root motion, and item behavior

The **General** section contains the settings that change how the Ability participates in locomotion:

- Turn off **Allow Positional Input** when player movement input should not reach the locomotion system during the Ability. Turn off **Allow Rotational Input** when look or turn input should be ignored.
- Use `UpdateRotation()` or `UpdatePosition()` to contribute movement. Use `ApplyRotation()` or `ApplyPosition()` to validate or limit movement just before UCC applies it. `UpdateDesiredMovement()` runs after `DesiredMovement` is set.
- Leave **Use Gravity**, **Use Root Motion Position**, **Use Root Motion Rotation**, and the collision fields at **No Override** unless the Ability must force or suppress that locomotion feature.
- Under **Allow Equipped Items**, choose which item slots may stay equipped. If the character must unequip disallowed items before starting, add **Item Equip Verifier** and ensure the character also has its normal **Equip Unequip** Ability. **Reequip Slots** restores the previous items when the Ability stops.

> **Version 3.2.0 root-motion note:** the released `Ability` start/stop implementation checks **Use Root Motion Position** in the `False` branch that controls root-motion rotation. As a result, **Use Root Motion Rotation = False** does not independently suppress root rotation, while **Use Root Motion Position = False** can also affect rotation. Verify both axes in Play Mode and use a package version with the correction or a balanced custom lifecycle override when independent rotation control is required.

## Worked example: crawl through a tunnel

The original Crawl example combines trigger detection, item restrictions, limited turning, and a full-body animation. It is intentionally more involved than the minimal input-driven Ability above.

### Build the trigger volume

1. Build a tunnel and place a trigger collider across the complete crawl area.
2. Put the trigger on a layer included by the Ability's **Detect Layers**.
3. Add **Object Identifier** to the trigger or one of its parents and set **ID** to `101`.

![A simple crawl tunnel built from three scaled cubes with a trigger volume covering the crawl area](https://opsive.com/wp-content/uploads/2018/03/CrawlTunnel.png?v=aa0a53ec45b9)

![Object Identifier on the crawl tunnel trigger with ID 101](https://opsive.com/wp-content/uploads/2018/03/CrawlObjectIdentifier.webp?v=fac83bb5bb92)

The legacy example uses `101` for both **Object ID** and **Ability Index Parameter**, but these are separate values. **Object ID** filters detected scene objects; **Ability Index Parameter** routes Animator transitions. They only need to match their own consumers.

### Extend the class

Derive from `DetectObjectAbilityBase` so the Ability can validate a trigger. This complete version starts automatically while a valid trigger is detected, stops after the final valid trigger is exited, limits the frame's requested rotation, and blocks Item Abilities while crawling:

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Character.Abilities.Items;

[DefaultStartType(AbilityStartType.Automatic)]
[DefaultStopType(AbilityStopType.Manual)]
[DefaultObjectDetection(ObjectDetectionMode.Trigger)]
[DefaultAbilityIndex(101)]
[DefaultState("Crawl")]
[DefaultEquippedSlots(0)]
[DefaultReequipSlots(true)]
[System.Serializable]
public class Crawl : DetectObjectAbilityBase
{
    [Tooltip("The maximum number of degrees the character can rotate per update.")]
    [SerializeField] private float m_MaxRotationAngle = 0.5f;

    public override void ApplyRotation()
    {
        base.ApplyRotation();

        var angle = Quaternion.Angle(
            Quaternion.identity,
            m_CharacterLocomotion.DesiredRotation);

        if (angle > m_MaxRotationAngle) {
            m_CharacterLocomotion.DesiredRotation = Quaternion.Slerp(
                Quaternion.identity,
                m_CharacterLocomotion.DesiredRotation,
                m_MaxRotationAngle / angle);
        }
    }

    public override bool ShouldBlockAbilityStart(Ability startingAbility)
    {
        return startingAbility is ItemAbility ||
               base.ShouldBlockAbilityStart(startingAbility);
    }

    public override void OnTriggerExit(Collider other)
    {
        base.OnTriggerExit(other);

        // Keep crawling if another valid, overlapping trigger is still detected.
        if (IsActive && m_DetectedObject == null) {
            StopAbility();
        }
    }
}
```

After Unity recompiles, add or re-add **Crawl** so its default attributes are applied. Add **Item Equip Verifier** to the same **Abilities** list if it is not already present.

![Ultimate Character Locomotion ability list containing Crawl and Item Equip Verifier](https://opsive.com/wp-content/uploads/2018/03/CrawlAbilityListInspector-e1526999077476.webp?v=ce7f9148ff3c)

Select **Crawl** and confirm:

- **Start Type** is **Automatic** and **Stop Type** is **Manual**.
- **Object Detection** includes **Trigger**.
- **Object ID** is `101` and **Detect Layers** includes the tunnel trigger's layer.
- **Ability Index Parameter** is `101`.
- All slot toggles under **Allow Equipped Items** are off, and **Reequip Slots** is on.

### Prepare the legacy animation

The legacy example uses a [Crawling animation from Mixamo](https://www.mixamo.com/#/?page=1&query=Crawling). A project-owned crawling clip works as well.

![Mixamo Crawling search with a crawling animation selected for download](https://opsive.com/wp-content/uploads/2018/03/MixamoCrawlingDownload.png?v=f5ebcb9087c2)

For the legacy clip:

1. In the FBX **Rig** tab, set **Animation Type** to **Humanoid**.
2. In the **Animation** tab, create an `Idle` clip from frames 0-1.
3. On both `Idle` and `Crawling`, enable **Loop Time**, **Loop Pose**, and **Bake Into Pose** for **Root Transform Rotation**.
4. On `Idle`, also enable **Bake Into Pose** for **Root Transform Position (Y)** and **Root Transform Position (XZ)** so the idle clip does not move the character.

![Idle crawl clip with loop and root-transform position settings configured in the Animation Importer](https://opsive.com/wp-content/uploads/2018/03/CrawlIdleProperties-e1527006144975.webp?v=1e550e36599f)

![Moving crawl clip with loop and root-transform rotation settings configured in the Animation Importer](https://opsive.com/wp-content/uploads/2018/03/CrawlCrawlingProperties.webp?v=cec3ea24d70c)

### Add the Animator branch

Create a `Crawling` sub-state machine on the **Full Body** layer when the crawl animation should replace the complete body pose. Add `Idle` and `Crawl` states.

![Full Body Animator layer with a Crawling sub-state machine containing Idle and Crawl states](https://opsive.com/wp-content/uploads/2018/03/CrawlAnimator-e1527004829854.png?v=0419b0214d64)

Configure the transitions:

- **Any State -> Idle**: `AbilityIndex Equals 101`, `AbilityChange`, and `Moving` is false.
- **Any State -> Crawl**: `AbilityIndex Equals 101`, `AbilityChange`, and `Moving` is true.
- **Idle -> Crawl**: `Moving` is true.
- **Crawl -> Idle**: `Moving` is false.
- Each exit transition: `AbilityIndex NotEqual 101`.

![Animator transition conditions using AbilityIndex 101, AbilityChange, and Moving false for the crawl Idle state](https://opsive.com/wp-content/uploads/2018/03/CrawlAnimatorIdleConditions.webp?v=f19c6c83be31)

`AbilityChange` is set when the Animator Monitor changes `AbilityIndex`; it is not a general notification for every field on the Ability.

The original [Crawl video walkthrough](https://www.youtube.com/watch?v=MFVrmmhZGh0) demonstrates the same scenario, while the labels and API guidance on this page are aligned with UCC 3.2.0.

## Editor checkpoint

Before entering Play Mode, verify:

- `Crawl` appears once in **Ultimate Character Locomotion > Abilities** and is enabled.
- The chosen **Start Type**, **Stop Type**, and **Input Names** agree with the code path that should activate it.
- Any default attributes added after the Ability entry was created have also been applied to the existing Inspector entry.
- The **State** and **Ability Index Parameter** have consumers when you expect a visible State or animation change.
- For the tunnel version, the trigger layer, **Object ID**, **Object Identifier > ID**, and **Object Detection** agree.
- Any disallowed equipped slots have a working **Item Equip Verifier** and **Equip Unequip** setup.

## Verify in Play Mode

For the minimal input-driven version:

1. Hold the `Crawl` input.
2. Confirm the Crawl State is active and, when configured, the Animator's `AbilityIndex` changes to `101`.
3. Release the input. Confirm the State turns off and the Animator returns to the next active Ability index or `0`.

For the tunnel version:

1. Approach the tunnel with an item equipped.
2. Confirm the item is unequipped before Crawl becomes active.
3. Enter the trigger and move. The Animator should select `Idle` while still and `Crawl` while moving, and rotation should be limited.
4. Leave the final crawl trigger. Crawl should stop, the Animator should exit the sub-state machine, normal turning should return, and the previous item should re-equip.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The custom type is missing from the Ability add menu | Check the Console, confirm the file and class are both named `Crawl`, and inspect the script's assembly definition | Fix compile errors; if an assembly definition is used, reference `Opsive.UltimateCharacterController`, then let Unity recompile |
| The Ability never starts from input | Check **Enabled**, **Start Type**, **Input Names**, and the active input integration | Add the exact input/action name and use an input-driven **Start Type**; **Manual** ignores input |
| An Automatic Ability starts everywhere | Check whether `CanStartAbility()` always returns true | Add a real start condition or derive from an appropriate base such as `DetectObjectAbilityBase` |
| The tunnel Ability does not start | Check the trigger layer, **Detect Layers**, **Object Detection**, **Object ID**, and **Object Identifier > ID** | Include **Trigger**, make the layer detectable, and make the two object IDs match |
| The tunnel Ability does not stop | Check whether the override calls `base.OnTriggerExit(other)` and whether another valid trigger is still overlapping | Keep the base call and stop only after `m_DetectedObject` becomes null |
| The animation does not change | Check **Ability Index Parameter**, Animator parameter spelling, transition conditions, and whether the Animator Monitor is present | Use the same unique value in the Ability and transitions; leave the value at `-1` only when no Animator branch is needed |
| Items remain equipped or can be used | Check **Allow Equipped Items**, **Item Equip Verifier**, **Equip Unequip**, and `ShouldBlockAbilityStart` | Disallow the intended slots, add the verifier dependencies, and block the relevant `ItemAbility` types while active |
| An Ability is blocked by another Ability | Compare their order in the **Abilities** list and whether either is concurrent | Move the higher-priority behavior earlier or override conflict rules only for the intended pair |
| Root-motion rotation ignores **Use Root Motion Rotation = False** | Confirm the package is UCC 3.2.0 and test **Use Root Motion Position** independently | Account for the 3.2.0 false-branch defect described above; use a corrected package or a balanced custom override |

## Related tasks

- [Abilities overview](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Included abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/)
- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/)
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/)
- [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/)
- [Animator parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/)
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)

## Developer reference

### Start and stop from code

Use the locomotion component so priority, conflict checks, item verification, events, and active lists remain consistent:

```csharp
using Opsive.UltimateCharacterController.Character;

var locomotion = character.GetComponent<UltimateCharacterLocomotion>();
var crawl = locomotion.GetAbility<Crawl>();

if (crawl != null) {
    locomotion.TryStartAbility(crawl);
    // Later:
    locomotion.TryStopAbility(crawl);
}
```

`Ability.StartAbility()` and `Ability.StopAbility()` route through the same locomotion controller and are convenient from inside the Ability.

### Lifecycle hooks

- `CanStartAbility()` is the normal start gate. `AbilityWillStart()` is the final gate after conflict checks and before UCC completes Move Towards or Item Equip Verifier preparation.
- `AbilityStarted()` applies the configured State, input, attribute, gravity, root-motion, collision, audio, and inventory behavior. Call `base.AbilityStarted()` when overriding it.
- `Update()` runs before movement. Then UCC calls the rotation and position hooks; `LateUpdate()` runs after movement. `UpdateAnimator()` is obsolete in 3.2.0, so update Animator data from `Update()`.
- `CanStopAbility(bool force)` can delay a non-forced stop. `AbilityStopped(bool force)` restores base state and overrides; call `base.AbilityStopped(force)`.
- `ShouldBlockAbilityStart(Ability)` is asked of an active Ability. `ShouldStopActiveAbility(Ability)` is asked of the Ability that is trying to start.
- Call base implementations when overriding a base type's trigger, initialization, update, stop, or destruction hooks. In particular, `DetectObjectAbilityBase.OnTriggerExit` maintains its detected-trigger list, and `Ability.OnDestroy` releases Starter, Stopper, and model-switch registrations.

The character publishes `OnCharacterAbilityActive` with the signature `Ability, bool` when an Ability starts or stops. Use the [event system](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) when another component needs to observe activation without coupling itself to the custom class.

---

<a id="page-ultimate-character-controller-character-effects"></a>

# Effects

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/)

Use a Character Effect for short, lightweight feedback such as a camera shake, item jolt, stomp, or sound. Effects run alongside locomotion without driving the Animator; use an [Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) when the behavior needs animation, input, interruption rules, or networked gameplay ownership.

## Add a damage-feedback effect

This example starts a **Shake** whenever Character Health reports damage:

1. Select the character root and open **Ultimate Character Locomotion > Effects**.
2. Select the add (`+`) button and choose **Shake**.
3. Leave the row's **Enabled** toggle on. Select the row to edit the effect.
4. Choose **Target** values. For presentation-only damage feedback, **Camera** and **Item** avoid adding force to the character. The released default enables **Camera**, **Item**, and **Character**.
5. Adjust **Force** and **Duration**. Their defaults are `(0.4, 0.4)` and `7` seconds.
6. Select **Character Health** and set **Damaged Effect** to **Shake**. Leave **Damaged Effect Index** at `-1` to use the first Shake in the Effects list.
7. Enter Play Mode and damage the character once.

While the effect runs, its list label ends with **(Active)**. The label should return to its normal name after **Duration** elapses.

## Configure the Effects list

Ultimate Character Locomotion owns the list, initializes each effect, and updates active effects during the character update. Select an effect row to configure its shared settings and effect-specific fields.

| Setting | Default | Use |
| --- | --- | --- |
| **Enabled** | On | Allows the effect to start. Turning this off while the effect is active stops it. |
| **Start When Enabled** | Off | Starts the effect when its **Enabled** property changes from off to on during Play Mode. It does not mean "start when the scene loads." |
| **State** | Empty | Activates the named character state while the effect is active and deactivates it when the effect stops. |
| **Inspector Description** | Empty | Adds an editor-only note to the list label, which is useful when the same effect type appears more than once. |
| **States** | `Default` | Uses the standard State System list to change effect values while other states are active. |

Duplicate effect types are allowed. **Start Effect Index** and **Damaged Effect Index** refer to the effect's zero-based position in this list; `-1` selects the first effect of the chosen type. After reordering effects, update every explicit index that points into the list.

## Choose how the effect starts

| Trigger | Setup | Stop ownership |
| --- | --- | --- |
| Character damage | On **Character Health**, choose **Damaged Effect** and optionally **Damaged Effect Index**. | The chosen effect must stop itself or be stopped by code. |
| Ability start | Select an ability and choose **Start Effect Name**. Use **Start Effect Index** only when selecting a specific duplicate. | Stopping the ability does not stop its effect. Built-in timed effects stop themselves. |
| Runtime enable | Turn the effect's **Enabled** property from off to on with **Start When Enabled** selected. | Turning **Enabled** off stops the active effect. |
| Script or custom system | Retrieve the effect from Ultimate Character Locomotion, then call `TryStartEffect` or `TryStopEffect`. | The calling system or the effect controls when it stops. |

An effect cannot restart while it is already active. A start request also fails when **Enabled** is off or the effect-specific `CanStartEffect` check fails.

## Included effects

The [Included Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/) section contains all three built-in Character Effects:

| Effect | Best for | Important released defaults and requirements |
| --- | --- | --- |
| [Shake](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/earthquake/) | Impacts, damage, explosions, or environmental vibration. | Targets Camera, Item, and Character; **Force** `(0.4, 0.4)`; **Smooth Horizontal Force** on; **Vertical Force Probability** `0.3`; **Fade Out Duration** `4`; **Positional Factor** `1`; **Rotational Factor** `3`; **Duration** `7`. At least one **Target** flag is required. |
| [Boss Stomp](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/boss-stomp/) | A repeated downward camera impulse. | Requires an attached Camera Controller. Positional direction is down with strength `0.5` to `1`; rotational direction is forward with strength `10` to `15`; **Repeat Count** is `0`; **Repeat Delay** is `1`. The initial stomp always occurs, so `0` produces one stomp and `-1` repeats until stopped. |
| [Play Audio Clip](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/play-audio-clip/) | A sound tied to the character without an animation. | **Audio Clip Set** starts empty. Assign an Audio Config or at least one clip before using the effect. It stops after the returned Audio Source's clip length. |

## Understand the runtime lifecycle

1. Ultimate Character Locomotion initializes every serialized effect and assigns its list index.
2. `TryStartEffect` rejects an active, disabled, or unavailable effect. A successful start adds it to the active list and calls `EffectStarted`.
3. Ultimate Character Locomotion calls `Update` on each active effect every character update.
4. The effect calls `StopEffect`, its owner calls `TryStopEffect`, or **Enabled** is turned off.
5. Ultimate Character Locomotion removes it from the active list and calls `EffectStopped`.

The base `Effect` type does not expose a dedicated start or stop UnityEvent, and the Ultimate Character Locomotion **Events** foldout has no Character Effect event. A custom effect can override `EffectStarted` and `EffectStopped`; call the base implementation so the configured **State** is activated and cleared.

## Multiplayer considerations

Character Effects are not synchronized by Ultimate Character Controller. Replicate the gameplay event through the project's networking layer, then start the corresponding visual or audio effect on the intended local player or observer.

Keep authoritative movement outside an effect. In particular, **Shake > Target > Character** adds force to locomotion, but that force is not network-owned or replicated by the Effect system. Camera and item feedback should normally run only for the client that owns or observes that presentation.

## Released Version 3 limitations

- The active-effect list assigns a one-based active index but uses it as a zero-based removal position. When effects overlap, stopping an effect other than the most recently started one can remove the wrong active entry and leave the stopped entry updating. Avoid overlapping Character Effects in released Version 3; if overlap is unavoidable, stop them in reverse start order.
- **Start When Enabled** reacts only to a runtime transition of **Enabled** from off to on. An effect that begins the scene enabled does not start merely because this option is selected.
- **Play Audio Clip** allows a start even when its Audio Clip Set produces no Audio Source. In that case it has no clip length with which to schedule its stop and remains active until stopped or disabled. Always assign playable audio and verify that the **(Active)** label clears.
- An ability's **Start Effect Name** starts the effect when the ability begins but establishes no stop relationship. Use a self-terminating effect or stop it explicitly.
- Character Effects do not modify Animator parameters and have no built-in network synchronization. Use an Ability or another gameplay system when either behavior is required.

## Check the editor setup

Before Play Mode, confirm:

- the effect row is enabled and its **Inspector Description** clearly distinguishes any duplicates;
- every explicit effect index still matches the intended row after reordering;
- the chosen ability or Character Health trigger points to a type that exists in the Effects list;
- Camera-targeted effects have a Camera Controller attached to the character; and
- every timed custom effect has a definite stop path.

## Verify in Play Mode

1. Trigger the effect once and confirm the intended row shows **(Active)**.
2. Observe only the configured target: camera, item, character, or audio.
3. Confirm the effect clears its **(Active)** label at the expected duration or repeat count and that its configured **State** is no longer active.
4. Trigger it again after it stops. It should start normally; a request made while it is already active should be ignored.
5. In multiplayer, test the owner and a remote observer separately. Only instances explicitly triggered by the networking layer should show the effect.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The trigger does nothing. | Check the row's **Enabled** toggle, selected effect type and index, and the effect-specific start requirement. | Enable the effect, correct the index, select at least one Shake target, or attach a Camera Controller for Boss Stomp. |
| **Start When Enabled** does not run at scene start. | Check whether **Enabled** actually changed from off to on during Play Mode. | Start the effect from an ability, Character Health, or code, or toggle **Enabled** at runtime. |
| An ability starts the effect but it continues after the ability stops. | Check whether the effect has its own duration, repeat limit, audio length, or custom stop call. | Configure a self-terminating built-in effect or stop it explicitly when the ability ends. |
| Play Audio Clip remains **(Active)** without sound. | Check whether **Audio Clip Set** returned a playable Audio Source. | Assign an Audio Config or clip, or stop the effect explicitly after a failed play request. |
| The wrong duplicate effect starts. | Compare **Start Effect Index** or **Damaged Effect Index** with the current Effects list order. | Set the zero-based list index, or use `-1` when the first effect of that type is intended. |
| One of several overlapping effects stops incorrectly. | Check whether effects were stopped in a different order from which they started. | Avoid overlap in released Version 3 or stop active effects in reverse start order. |
| A remote player does not show the effect. | Check whether the project's network message starts it on that client. | Replicate the trigger and run the presentation locally; Character Effects are not synchronized automatically. |

## Related tasks

- [Included Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)

## Developer details

Guard every lookup because `TryStartEffect` and `TryStopEffect` expect a non-null Effect reference:

```csharp
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Effects;
using UnityEngine;

public static class CharacterEffectExample
{
    public static bool StartShake(GameObject character)
    {
        var locomotion = character != null ? character.GetComponent<UltimateCharacterLocomotion>() : null;
        var shake = locomotion != null ? locomotion.GetEffect<Shake>() : null;
        return shake != null && locomotion.TryStartEffect(shake);
    }

    public static bool StopShake(GameObject character)
    {
        var locomotion = character != null ? character.GetComponent<UltimateCharacterLocomotion>() : null;
        var shake = locomotion != null ? locomotion.GetEffect<Shake>() : null;
        return shake != null && shake.IsActive && locomotion.TryStopEffect(shake);
    }
}
```

For duplicate types, `GetEffect<T>(index)` uses the effect's absolute list index. Calling `Effect.StartEffect()` and `Effect.StopEffect()` routes through Ultimate Character Locomotion so its active list stays informed.

A custom effect normally overrides `EffectStarted`, `Update`, and `EffectStopped`. This three-second camera pulse uses the [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/) and cancels its pending event if stopped early:

```csharp
using Opsive.Shared.Game;
using Opsive.Shared.Utility;
using Opsive.UltimateCharacterController.Character.Effects;

public class CameraPulseEffect : Effect
{
    private ScheduledEventBase m_StopEvent;

    protected override void EffectStarted()
    {
        base.EffectStarted();
        m_StopEvent = Scheduler.ScheduleFixed(3, StopEffect);
    }

    public override void Update()
    {
        if (m_CameraController != null) {
            m_CameraController.AddPositionalForce(SmoothRandom.GetVector3Centered(0.1f));
        }
    }

    protected override void EffectStopped()
    {
        Scheduler.Cancel(m_StopEvent);
        m_StopEvent = null;
        base.EffectStopped();
    }
}
```

---

<a id="page-ultimate-character-controller-character-effects-included-effects"></a>

# Included Effects

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/)

Ultimate Character Controller Version 3 includes three Character Effects for lightweight feedback: **Shake**, **Boss Stomp**, and **Play Audio Clip**. Choose one when the result does not need Animator control or built-in network synchronization.

## Choose an effect

| Goal | Effect | What it changes |
| --- | --- | --- |
| Add continuous vibration after damage, an impact, or an explosion | [Shake](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/earthquake/) | Any combination of camera force, equipped-item secondary force, and character locomotion force. |
| Add one or more distinct heavy camera impacts | [Boss Stomp](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/boss-stomp/) | Secondary positional and rotational camera force at a fixed repeat delay. |
| Play a character-centered sound | [Play Audio Clip](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/play-audio-clip/) | An Audio Clip selected from an **Audio Clip Set** on the character. |

Use an [Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) instead when the response must control animation, input, movement rules, or interruption. Character Effects do not update Animator parameters and are not synchronized over the network.

## Compare all three in Play Mode

This route lets you test the effects one at a time without writing a trigger:

1. Select the character root and open **Ultimate Character Locomotion > Effects**.
2. Use the add (`+`) button to add **Shake**, **Boss Stomp**, and **Play Audio Clip**.
3. Give each row an **Inspector Description**, such as `Comparison`, so it is easy to identify.
4. Turn each row's **Enabled** toggle off, select each row, and enable **Start When Enabled**.
5. On Shake, select **Camera** under **Target**. On Boss Stomp, set **Repeat Count** to `1`. On Play Audio Clip, expand **Audio Clip Set** and assign one **Audio Clip** or an **Audio Config** containing a clip.
6. Confirm that a Camera Controller is attached to the character.
7. Enter Play Mode. Turn on one row, wait until its **(Active)** label disappears, then turn on the next row.

Do not start the rows together in released Version 3. The active-effect removal limitation described below makes overlapping Character Effects unsafe.

## Shared settings

Every included effect inherits the same controls:

| Setting | Default | Behavior |
| --- | --- | --- |
| **Enabled** | On | Allows the effect to start. Turning it off stops an active effect. |
| **Start When Enabled** | Off | Starts only when **Enabled** changes from off to on during Play Mode. It does not start an already-enabled effect when the scene loads. |
| **State** | Empty | Activates this character state when the effect starts and clears it when the effect stops. |
| **Inspector Description** | Empty | Adds an editor-only description to the row label. |
| **States** | `Default` | Uses State System presets to vary the effect's fields. |

The row displays **(Active)** while Ultimate Character Locomotion owns and updates the effect. After a self-terminating effect stops, its **Enabled** toggle remains on. To repeat the **Start When Enabled** comparison, turn the row off and on again.

## Shake

[Shake](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/earthquake/) is the flexible choice for a sustained impact or environmental vibration.

| Field | Released default | Runtime effect |
| --- | --- | --- |
| **Target** | Camera, Item, Character | Applies the same generated shake to each selected destination. At least one flag is required for the effect to start. |
| **Force** | `(0.4, 0.4)` | Sets the horizontal and vertical magnitude. |
| **Smooth Horizontal Force** | On | Uses smooth random horizontal motion. When off, the effect alternates sharper random impulses. |
| **Vertical Force Probability** | `0.3` | Gives each update a 30% chance of adding vertical force. |
| **Fade Out Duration** | `4` | Reduces the force during the end of the effect. |
| **Positional Factor** | `1` | Scales camera position force and character locomotion force. |
| **Rotational Factor** | `3` | Scales camera rotation force. |
| **Duration** | `7` | Stops the effect after seven seconds of unscaled time. |

**Camera** requires an attached Camera Controller to produce visible camera movement, but its absence does not prevent Shake from starting. **Item** is visible only when a listening equipped item is present. **Character** calls `AddForce` on locomotion; leave it off for presentation-only or networked feedback whose movement must remain authoritative elsewhere.

## Boss Stomp

[Boss Stomp](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/boss-stomp/) produces discrete camera impulses rather than continuous noise. It refuses to start until a Camera Controller is attached.

| Field | Released default | Runtime effect |
| --- | --- | --- |
| **Positional Stomp Direction** | Down `(0, -1, 0)` | Direction of the secondary positional camera force. |
| **Positional Strength** | `0.5` to `1` | Random positional strength for each stomp. |
| **Rotational Stomp Direction** | Forward `(0, 0, 1)` | Axis of the secondary rotational camera force. |
| **Rotational Strength** | `10` to `15` | Random rotational strength, with direction chosen in either sign. |
| **Repeat Count** | `0` | The initial stomp always runs. Both `0` and `1` produce one stomp; `-1` repeats until stopped or disabled. |
| **Repeat Delay** | `1` | Schedules the next stomp one second later. |

Stopping or disabling Boss Stomp cancels its pending scheduled repeat. Use `-1` only when another system has a definite stop path.

## Play Audio Clip

[Play Audio Clip](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/play-audio-clip/) plays one entry from its **Audio Clip Set** on the character, then normally stops the Character Effect after the returned Audio Source's clip length.

| Field | Released default | Runtime effect |
| --- | --- | --- |
| **Audio Clip Set > Audio Config** | None | Uses the selected Audio Config and its clips when assigned. |
| **Audio Clip Set > Audio Clips** | Empty | Chooses a clip from this list when no Audio Config supplies the selection. |

Assign playable audio before selecting a trigger. The effect's `CanStartEffect` check always succeeds, even when the set cannot return an Audio Source. A missing source leaves the effect active because no stop can be scheduled.

Use a non-looping Audio Config. Play Audio Clip schedules the Character Effect to stop after one clip length but does not stop the Audio Source in `EffectStopped`; looping audio can continue after the row is no longer **(Active)**.

## Lifecycle and overlap

Ultimate Character Locomotion starts each effect, stores it in an active list, calls its `Update` method, and removes it when stopped. Each included type owns its normal completion:

- Shake calls `StopEffect` after **Duration**.
- Boss Stomp calls `StopEffect` after its final stomp and cancels its schedule when stopped early.
- Play Audio Clip schedules `StopEffect` from the returned clip length.

An effect cannot start again while it is active. Turning **Enabled** off stops it immediately. Starting an effect from an ability does not connect their stop lifecycles; the ability may end while the effect continues.

> **Released Version 3 overlap limitation:** the controller stores a one-based active index but uses it as a zero-based removal index. If effects overlap, stopping any effect other than the most recently started one can remove the wrong active entry and leave a stopped entry updating. Avoid overlap. If an existing system already overlaps effects, stop them in reverse start order.

## Check the editor setup

Before Play Mode, verify:

- every row is clearly named with **Inspector Description** when duplicate types exist;
- each effect has its required target, camera, or audio assignment;
- no two triggers are expected to make Character Effects overlap;
- an indefinite Boss Stomp has an explicit stop owner; and
- every Play Audio Clip uses playable, non-looping audio.

## Compare the Play Mode result

1. Turn on Shake and confirm continuous camera motion followed by a smooth stop at **Duration**.
2. After its **(Active)** label clears, turn on Boss Stomp and count the distinct impulses. A **Repeat Count** of `1` should produce one.
3. After Boss Stomp clears, turn on Play Audio Clip. Confirm one clip plays and the row clears after the clip length.
4. Turn each row off and on once more to confirm **Start When Enabled** repeats it.
5. If the project is multiplayer, verify that no remote copy plays unless the project's networking layer explicitly starts that local effect.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Shake does not start. | Check whether **Target** has at least one selected flag. | Select Camera, Item, Character, or an appropriate combination. |
| Shake is **(Active)** but the camera does not move. | Check **Target > Camera** and whether a Camera Controller is attached. | Select Camera and attach the controller, or test the configured Item or Character target instead. |
| Boss Stomp does not start. | Check whether the character currently has an attached Camera Controller. | Attach the character to the intended camera before starting the effect. |
| Boss Stomp runs only once at **Repeat Count** `0`. | Check the initial-stomp behavior. | Use a value greater than `1` for several finite stomps, or `-1` with an explicit stop owner. |
| Play Audio Clip has no sound and stays **(Active)**. | Check **Audio Config**, **Audio Clips**, and whether a playable Audio Source was returned. | Assign valid audio, then disable the stuck effect before testing again. |
| Looping audio continues after the effect clears. | Check the Audio Config's loop override. | Use non-looping audio or stop the Audio Source through the audio-owning system. |
| One overlapping effect stops or updates incorrectly. | Check whether several Character Effects were active together. | Avoid overlap in released Version 3 or stop them in reverse start order. |
| A remote player does not show the effect. | Check whether the network layer invoked it on that client. | Replicate the trigger and play the local presentation explicitly. |

## Related tasks

- [Effects overview](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/)
- [Shake](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/earthquake/)
- [Boss Stomp](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/boss-stomp/)
- [Play Audio Clip](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/play-audio-clip/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/)

## Developer details

The concrete runtime types are `Shake`, `BossStomp`, and `PlayAudioClip`, all derived from `Effect`. Shake rejects `Target == 0`; Boss Stomp rejects a missing `CameraController`; Play Audio Clip currently returns `true` from `CanStartEffect` without checking its audio.

Use `UltimateCharacterLocomotion.GetEffect<T>()` to retrieve the first matching type, or `GetEffect<T>(index)` for an exact zero-based Effects-list position. Start and stop through `TryStartEffect` and `TryStopEffect` so Ultimate Character Locomotion can maintain its active list.

---

<a id="page-ultimate-character-controller-character-effects-included-effects-boss-stomp"></a>

# Boss Stomp

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/boss-stomp/)

Use Boss Stomp to add one or more heavy, discrete camera impulses, such as footsteps from a nearby boss or the impact of a large object. The Effect belongs to the character, but it always sends its force to that character's currently attached Camera Controller.

## Before you begin

- Configure a character with **Ultimate Character Locomotion**.
- Attach the intended Camera Controller to the character. Boss Stomp has no target field and cannot start without an attached camera.
- Keep other Character Effects inactive while Boss Stomp runs in released Version 3.
- Ensure the Opsive Scheduler is active when **Repeat Count** is greater than `1` or is `-1`. The first stomp is immediate, but later stomps use `Scheduler.ScheduleFixed`.

## Add and test Boss Stomp

1. Select the character root and open **Ultimate Character Locomotion > Effects**.
2. Select the add (`+`) button and choose **Boss Stomp**.
3. Set **Inspector Description** to a useful editor label such as `Heavy Footsteps`.
4. Set **Repeat Count** to `3` and **Repeat Delay** to `0.6` for a clear test with one immediate stomp and two scheduled stomps.
5. Leave the direction and strength fields at their defaults for the first test.
6. Turn the Boss Stomp row's **Enabled** toggle off, select the row, and enable **Start When Enabled**.
7. Enter Play Mode and turn the row on.

The row should show **(Active)** between the first and final stomp, then clear after the third. Once the tuning is approved, turn **Start When Enabled** off, leave the row enabled, and connect the intended ability, damage response, or script trigger.

## Choose the impulse

| Field | Released default | Behavior |
| --- | --- | --- |
| **Positional Stomp Direction** | Down `(0, -1, 0)` | Direction of the secondary positional force sent to every View Type on the attached Camera Controller. |
| **Positional Strength** | `0.5` to `1` | Chooses a random positional magnitude within this range for each stomp. |
| **Rotational Stomp Direction** | Forward `(0, 0, 1)` | Axis of the secondary rotational force. |
| **Rotational Strength** | `10` to `15` | Chooses a random magnitude within this range. Each stomp also randomly chooses the positive or negative direction. |
| **Repeat Count** | `0` | Intended total stomp count, with the mandatory initial stomp counted immediately. Both `0` and `1` produce one stomp; `-1` repeats until explicitly stopped or disabled. |
| **Repeat Delay** | `1` | Delay in seconds before each later stomp is invoked from the Scheduler's FixedUpdate queue. |

The Effect does not move the character or select a world-space target. It adds secondary camera position and rotation forces with zero rest accumulation. Camera View Types decide how those forces appear, so first- and third-person results can feel different even with the same values.

## Choose how it starts and stops

Boss Stomp uses the shared Character Effect lifecycle:

- The first stomp occurs immediately in `EffectStarted`.
- A finite **Repeat Count** stops the Effect immediately after the final stomp.
- `-1` keeps scheduling stomps until another system calls `StopEffect` or `TryStopEffect`, or turns **Enabled** off.
- Stopping the Effect cancels the pending scheduled stomp and clears its configured **State**.
- Starting it from an ability's **Start Effect Name** does not make it stop when that ability ends.

The base Effect exposes no dedicated start or stop UnityEvent, and Boss Stomp declares none. Use a finite count for a self-contained response. For an indefinite sequence, make the same gameplay system that starts the Effect responsible for stopping it.

## Camera and multiplayer ownership

Boss Stomp listens for the character's camera-attachment notification. When a camera attaches, that Camera Controller becomes the Effect's destination; when it detaches, the destination becomes empty and `CanStartEffect` returns false.

Character Effects are not network synchronized. In multiplayer, replicate the boss-step or impact event through the project's networking layer, then start Boss Stomp only for the local camera that should perceive it. Starting the Effect on a remote character without an attached camera fails, and starting it on another local character targets whichever camera is attached to that character.

## Released Version 3 limitations

- **Repeat Count** `0` and `1` both produce one stomp because the initial stomp runs before the repeat comparison.
- **Repeat Delay** is passed to the Scheduler without validation. A finite count with delay `0` collapses every stomp into the same call; combining delay `0` with **Repeat Count** `-1` recursively schedules without yielding. Scheduler delay `-1` has separate recurring-event semantics and can leave a callback that Boss Stomp no longer tracks. Use a positive delay.
- If a later stomp cannot be scheduled because the Scheduler is unavailable or disabled, the first stomp still occurs but a finite multi-stomp Effect can remain active without reaching its stop condition. Restore the Scheduler or disable the Effect.
- The released controller assigns active effects a one-based index but removes them as though the index were zero-based. Avoid overlapping Boss Stomp with any other Character Effect; if an existing system overlaps effects, stop them in reverse start order.
- Boss Stomp does not affect the Animator and has no built-in network synchronization or start/stop UnityEvents.

## Check the editor setup

Before Play Mode, confirm:

- the intended Camera Controller is attached to this character;
- **Repeat Delay** is greater than `0`;
- a **Repeat Count** of `-1` has a definite stop owner;
- no other Character Effect will overlap this sequence; and
- **Inspector Description** and any configured **State** identify the intended use.

## Verify in Play Mode

1. Trigger a finite sequence with **Repeat Count** `3` and count one immediate impulse plus two delayed impulses.
2. Confirm that the row shows **(Active)** between stomps and clears after the third.
3. Verify that each positional magnitude remains within **Positional Strength** and that rotational direction can vary between stomps.
4. For a character with both perspectives, test first and third person. Both use the attached Camera Controller, but their View Types can respond differently.
5. Start an indefinite sequence with **Repeat Count** `-1`, then invoke its planned stop. Confirm no later stomp occurs and its configured **State** clears.
6. In multiplayer, verify the effect independently on the owning client and every observer that receives the replicated trigger.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Boss Stomp does not start. | Check whether a Camera Controller is currently attached to the character and the effect row is enabled. | Attach the intended camera and enable the row before triggering it. |
| The wrong camera moves. | Check which character the Camera Controller currently owns. Boss Stomp has no camera selector. | Attach the intended Camera Controller to this character before starting the Effect. |
| **Repeat Count** `0` produces one stomp. | Check the immediate-first-stomp semantics. | This is expected; use a value greater than `1` for multiple finite stomps. |
| All finite stomps happen together or Play Mode hangs. | Check for **Repeat Delay** `0`, especially with count `-1`. | Stop Play Mode if necessary and use a positive delay. |
| The first stomp occurs but the Effect never finishes. | Check the Opsive Scheduler and whether a later callback was registered. | Restore or enable the Scheduler, then disable the stuck Effect before testing again. |
| An indefinite sequence continues. | Check whether the owning system called `StopEffect`, `TryStopEffect`, or turned **Enabled** off. | Add and verify an explicit stop path. |
| Another active Character Effect stops or updates incorrectly. | Check whether the effects overlapped. | Avoid overlap in released Version 3 or stop them in reverse start order. |
| A remote player does not see the stomp. | Check whether the network layer started it for that client's local camera. | Replicate the trigger and invoke Boss Stomp locally for each intended observer. |

## Related tasks

- [Included Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/)
- [Effects overview](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/)
- [Shake](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/earthquake/)
- [Play Audio Clip](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/play-audio-clip/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/)

## Developer details

`BossStomp.CanStartEffect` returns true only when the inherited `m_CameraController` reference is non-null. `EffectStarted` resets the internal count and calls the first stomp synchronously. Each stomp calls `CameraController.AddSecondaryPositionalForce` and `AddSecondaryRotationalForce`, increments the count, then either schedules the next FixedUpdate callback or calls `StopEffect`.

Retrieve the configured instance with `UltimateCharacterLocomotion.GetEffect<BossStomp>()`. Start and stop it through `TryStartEffect` and `TryStopEffect`; both expect a non-null Effect reference. `EffectStopped` cancels the pending `ScheduledEventBase`, then clears it.

---

<a id="page-ultimate-character-controller-character-effects-included-effects-play-audio-clip"></a>

# Play Audio Clip

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/play-audio-clip/)

Use Play Audio Clip to start a sound through the character's Opsive Shared Audio group without coupling it to an animation. The Character Effect tracks an active state for the raw clip length; Shared Audio owns the Audio Source and the actual playback.

## Before you begin

- Configure a character with **Ultimate Character Locomotion**.
- Import at least one playable Audio Clip, or create an Audio Config that contains one.
- Ensure the Shared Audio Manager and Opsive Scheduler are active.
- Use non-looping audio with no delay and pitch `1` for the first test. The released Effect's stop timing does not account for loop, delay, or pitch.
- Keep other Character Effects inactive while Play Audio Clip runs in released Version 3.

## Add and test a character sound

1. Select the character root and open **Ultimate Character Locomotion > Effects**.
2. Select the add (`+`) button and choose **Play Audio Clip**.
3. Set **Inspector Description** to a useful label such as `Damage Voice`.
4. Expand **Audio Clip Set**, leave **Audio Config** empty, and add one non-looping clip to **Audio Clips**.
5. Turn the Effect row's **Enabled** toggle off, select the row, and enable **Start When Enabled**.
6. Enter Play Mode and turn the row on.

The Shared Audio source should appear beneath the character, and the row should show **(Active)** until the clip's raw length elapses. Once the setup is approved, turn **Start When Enabled** off, leave the row enabled, and connect the intended ability, damage response, or script trigger.

## Configure the Audio Clip Set

Play Audio Clip has one effect-specific foldout. Its fields are empty by default:

| Field | Released default | Behavior |
| --- | --- | --- |
| **Audio Clip Set > Audio Config** | None | When assigned, the Audio Config supplies clip selection and Audio Source settings. Its clips take precedence over the inline **Audio Clips** list. |
| **Audio Clip Set > Audio Clips** | Empty | When no Audio Config is assigned, one non-null entry is selected randomly on each successful start. Shared Audio's default Audio Config supplies the Audio Source settings. |

Do not populate both as fallback choices. Assigning **Audio Config** causes the inline list to be ignored, even when that config has no usable clip.

A newly created Audio Config has these relevant source defaults:

| Audio Config choice | Default | Effect on ownership |
| --- | --- | --- |
| **Clip Selection** | Random | Selects among the config's Audio Clips. Sequence and Index are also available. |
| **Audio Source Prefab** | None | Falls back to the Audio Manager Module's default Audio Source prefab. |
| **Share Audio Source** | On | Reuses an available shared source in the character's audio group. |
| **Replace Previous Audio Source** | Off | Creates or selects another available source instead of deliberately replacing the currently playing one. |
| **Copy Existing Audio Source Properties** | On | Copies settings from an Audio Source already on the character when Shared Audio creates a source. |
| **Audio Modifier** | No overrides | Leaves output, loop, volume, pitch, stereo pan, spatial blend, reverb, and delay at the source/config values. |

Continue with [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/) when spatial blend, mixer routing, source prefabs, or config selection needs broader setup.

## Understand Audio Source ownership

The Effect always calls `AudioClipSet.PlayAudioClip` with the character root. Shared Audio creates or retrieves an Audio Source group for that GameObject, chooses an available shared or config-reserved source, and parents newly instantiated `SharedAudioSource` or `ReservedAudioSource` objects beneath the character.

Play Audio Clip receives a `PlayResult`, reads its Audio Source, and schedules the Character Effect's stop. It does not retain the `PlayResult`, own the source, or stop the source when the Effect stops. This separation matters:

- stopping or disabling the Character Effect clears its active state but does not stop the sound;
- a looping source can continue after the Effect becomes inactive;
- a delayed or pitch-adjusted source can finish at a different time from the Effect; and
- a config with **Replace Previous Audio Source** enabled may reuse an active source and interrupt another sound without changing that other Effect's lifecycle.

## Start, stop, loop, delay, and fade

`CanStartEffect` always returns true. On start, the Effect activates its configured **State**, requests audio from Shared Audio, then calls `Scheduler.ScheduleFixed(audioSource.clip.length, StopEffect)` when an Audio Source is returned.

That duration is the Audio Clip asset's raw length:

- **Pitch** is not applied to the scheduled length. A lower pitch can leave sound playing after the Effect stops; a higher pitch can leave the Effect active after the sound ends.
- **Delay** is not added. The Effect can stop before delayed playback finishes.
- **Loop** is not considered. The Effect stops after one raw clip length while the source continues looping.
- **Fade** is not implemented by Play Audio Clip or its base Effect. Stopping the Effect neither fades nor stops its Audio Source.

For a normal one-shot, use pitch `1`, no delay, and loop off. For delayed, pitched, looped, or faded sound, let a dedicated audio-owning system control both playback and completion rather than treating this Effect as the source owner.

An active Play Audio Clip Effect cannot be retriggered. Repeated start requests do not select another clip, restart the sound, or extend the Effect duration.

## States, events, and multiplayer

The shared **State** field is activated when the Effect starts and cleared when the Effect stops. **Start When Enabled** starts only when **Enabled** changes from off to on during Play Mode; it does not start an already-enabled Effect when the scene loads.

Play Audio Clip exposes no dedicated start, stop, fade, or completion UnityEvent. Starting it from an ability's **Start Effect Name** does not stop it when the ability ends.

Character Effects are not network synchronized. Replicate the gameplay event through the project's networking layer, then start the sound once on each client that should hear it. Shared Audio's spatial settings and that client's Audio Listener determine audibility; do not start both a replicated world sound and a duplicate local Effect for the same event.

## Released Version 3 limitations

- With no Audio Config and no usable inline clip, Shared Audio returns no Audio Source. The Effect still becomes **(Active)**, but no stop is scheduled, so it remains active until explicitly stopped or disabled.
- An assigned Audio Config with no usable clip can still return an Audio Source whose `clip` is null. Play Audio Clip then reads `audioSource.clip.length`, which can raise a `NullReferenceException`.
- Stop timing uses raw clip length and ignores pitch, delay, loop, and any desired fade. Stopping the Effect never stops the Audio Source.
- The scheduled stop handle is not stored or canceled. If the Effect is stopped early and restarted before the old raw clip length elapses, the old callback can stop the new run prematurely.
- If the Scheduler is unavailable or disabled, playback can start but no Effect stop is scheduled.
- The released controller assigns active effects a one-based index but removes them as though the index were zero-based. Avoid overlapping Play Audio Clip with another Character Effect; if an existing system overlaps effects, stop them in reverse start order.
- Play Audio Clip does not affect the Animator and has no built-in network synchronization or lifecycle UnityEvents.

## Check the editor setup

Before Play Mode, confirm:

- exactly one source of clips is authoritative: a populated Audio Config or the inline Audio Clips list;
- every selectable entry is non-null;
- the chosen Audio Source prefab or Shared Audio default contains an Audio Source;
- loop is off, pitch is `1`, and delay is zero for a self-contained one-shot;
- the trigger points to the intended list index when duplicate Play Audio Clip Effects exist; and
- no other Character Effect will overlap this one.

## Verify in Play Mode

1. Trigger the Effect and confirm the intended row shows **(Active)**.
2. Inspect the character hierarchy and identify the Shared Audio source created or reused beneath the character.
3. Confirm the selected clip plays once with the intended spatial blend and mixer output.
4. Verify that the **(Active)** label and configured **State** clear at the raw clip length.
5. Stop the Effect early once and confirm that the sound continues; then use the audio-owning system to stop the source when early audio termination is required.
6. In multiplayer, test each client separately and confirm that the event produces exactly one audible playback per intended listener.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The row becomes **(Active)** but no sound plays. | Check whether **Audio Config** or **Audio Clips** contains a non-null playable clip. | Assign a valid source of clips, then disable the stuck Effect before retesting. |
| A null-reference exception occurs on start. | Check for an assigned Audio Config with an empty or null clip selection. | Populate the config with valid clips or clear it and use the inline Audio Clips list. |
| The Effect never clears. | Check for a missing Audio Source or unavailable Scheduler. | Repair Shared Audio or the Scheduler, then stop or disable the Effect. |
| Sound continues after the Effect stops. | Check loop, low pitch, delay, or an early Effect stop. | Use a normal one-shot configuration or stop the Audio Clip Set/source explicitly through the audio-owning system. |
| The Effect stays active after a short, high-pitched sound ends. | Compare raw clip length with pitch-adjusted playback time. | Use pitch `1` or manage completion outside Play Audio Clip. |
| A restarted run ends too soon. | Check whether the same Effect was stopped early and restarted before its original scheduled callback. | Wait for the original raw length to pass, or use a custom Effect that stores and cancels its schedule. |
| Another sound is interrupted. | Check the Audio Config's **Replace Previous Audio Source** and source-sharing choices. | Leave replacement off or reserve a source for that config. |
| Another Character Effect stops or updates incorrectly. | Check whether the Effects overlapped. | Avoid overlap in released Version 3 or stop them in reverse start order. |
| Remote clients hear nothing or hear the sound twice. | Check the replicated trigger and any separate world-audio path. | Invoke one local playback path per intended client. |

## Related tasks

- [Included Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/)
- [Effects overview](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/)
- [Shake](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/earthquake/)
- [Boss Stomp](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/boss-stomp/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/)

## Developer details

The runtime type is `Opsive.UltimateCharacterController.Character.Effects.PlayAudioClip`. Its only effect-specific public property is `AudioClipSet`; `AudioClipSet.AudioConfig` and `AudioClipSet.AudioClips` expose the two clip sources.

Retrieve the configured Effect with `UltimateCharacterLocomotion.GetEffect<PlayAudioClip>()`, then use `TryStartEffect` and `TryStopEffect` with a non-null reference. To stop both an early sound and its Character Effect while the set's last PlayResult still refers to that playback, call `effect.AudioClipSet.Stop(character)` before `TryStopEffect(effect)`. A shared Audio Source can be reused, so do not use that shortcut after another sound has taken over the source. The released Effect's previously scheduled callback also remains, so avoid restarting that same instance until the original raw clip length has passed.

---

<a id="page-ultimate-character-controller-character-effects-included-effects-earthquake"></a>

# Shake

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/earthquake/)

Use Shake for continuous impact feedback such as damage, an explosion, recoil, or environmental vibration. It can drive the attached camera, equipped-item springs, character locomotion, or any combination for a fixed duration.

The URL retains the historical `earthquake` slug, but the released Version 3 type, Inspector entry, and page title are **Shake**. There is no current `Earthquake` Effect class.

## Before you begin

- Configure a character with **Ultimate Character Locomotion**.
- Attach a Camera Controller when **Target > Camera** should be visible.
- Equip a supported first-person item or use Character IK when **Target > Item** should move the item or hands.
- Decide whether the result is presentation-only. **Target > Character** adds locomotion force and should not be used as an unsynchronized gameplay force in multiplayer.
- Keep other Character Effects inactive while Shake runs in released Version 3.

## Add a short damage shake

1. Select the character root and open **Ultimate Character Locomotion > Effects**.
2. Select the add (`+`) button and choose **Shake**.
3. Set **Inspector Description** to `Damage Feedback`.
4. Under **Target**, select **Camera** and **Item** and clear **Character**.
5. Keep **Force** at `(0.4, 0.4)`, **Smooth Horizontal Force** on, **Vertical Force Probability** at `0.3`, **Positional Factor** at `1`, and **Rotational Factor** at `3`.
6. Set **Fade Out Duration** to `1` and **Duration** to `2` for a shorter first test.
7. On **Character Health**, set **Damaged Effect** to **Shake** and leave **Damaged Effect Index** at `-1` when this is the first Shake in the Effects list.
8. Enter Play Mode and damage the character once.

The `Shake (Damage Feedback)` row should show **(Active)** for about two real-time seconds. The camera and supported item should move, while the character's world movement remains unchanged.

## Choose the destinations

**Target** is a flags field and defaults to Camera, Item, and Character.

| Target | Runtime destination | Required setup |
| --- | --- | --- |
| **Camera** | Calls positional and rotational force methods on every View Type in the character's attached Camera Controller. | An attached Camera Controller. Without one, the camera branch is skipped. |
| **Item** | Sends a global secondary-force message with Slot ID `-1`, allowing first-person item springs and Character IK hand springs to respond. | A listening first-person item or Character IK setup. Without a listener, the branch has no visible result. |
| **Character** | Removes the generated vertical component, then calls `AddForce` on Ultimate Character Locomotion with the horizontal force. | Ultimate Character Locomotion, already required by the Effect. |

At least one target flag is required. With no flags selected, `CanStartEffect` returns false. If Camera is the only selected target but no Camera Controller is attached, Shake still starts and remains **(Active)** for its duration even though nothing moves.

## Tune the motion

| Field | Released default | Runtime behavior |
| --- | --- | --- |
| **Target** | Camera, Item, Character | Selects the destinations described above. |
| **Force** | `(0.4, 0.4)` | Base horizontal and vertical force before the remaining-time fade factor and target-specific scaling. |
| **Smooth Horizontal Force** | On | Uses smooth random horizontal force and multiplies it by global and character time scale. When off, a random impulse is flipped when its sign matches the accumulated horizontal force. |
| **Vertical Force Probability** | `0.3` | Gives each update a 30% chance of adding vertical force. An impulse is flipped when its sign matches the accumulated vertical force. |
| **Fade Out Duration** | `4` | Caps the remaining-time multiplier applied to horizontal and vertical force, then reduces that multiplier to zero near the end. |
| **Positional Factor** | `1` | Scales camera positional force and Character locomotion force. It does not scale Item force. |
| **Rotational Factor** | `3` | Scales only Camera rotational force; the camera receives twice this factor multiplied by the negative generated force. |
| **Duration** | `7` | Stops the Effect after seven seconds measured with `Time.unscaledTime`. |

First- and third-person Camera View Types receive the same generated force but may render it differently because each View Type owns its spring response. Test every supported perspective instead of assuming one set of factors will feel identical.

## Understand start and stop behavior

When Shake starts, it activates its configured **State**, records `Time.unscaledTime`, and clears its accumulated-force history. Ultimate Character Locomotion then calls `Update` while the Effect is active.

Shake stops itself after **Duration**. It can also be stopped early through `StopEffect`, `TryStopEffect`, or by turning its **Enabled** row toggle off. Stopping clears the configured **State**. Starting Shake from an ability's **Start Effect Name** does not connect the two stop lifecycles; Shake continues until its own duration or another explicit stop.

A second start request while the same Shake is active is rejected. Repeated damage therefore does not stack the force, restart the timer, or extend the duration.

The base Effect provides no dedicated start or stop UnityEvent. The Item destination does publish the internal `OnAddSecondaryForce` event used by the supported item and IK listeners, but that is a per-update force message rather than a Shake lifecycle event.

## Multiplayer behavior

Character Effects are not synchronized by Ultimate Character Controller. Replicate the damage, explosion, or other source event through the project's networking layer, then start Shake locally for each intended observer.

Use Camera and Item for client-side presentation. **Target > Character** applies locomotion force locally without Effect-level network ownership or replication; authoritative displacement belongs in a networked Ability or gameplay system.

## Released Version 3 limitations

- **Fade Out Duration** is used directly as a force-multiplier cap rather than as a normalized `0` to `1` fade. Values above `1` can increase the initial force as well as extend the fade. Tune **Force** and **Fade Out Duration** together.
- **Duration** always uses unscaled time, so Shake expires while the game is paused or slowed. The smooth horizontal branch applies global and character time scale, but the sharp horizontal and vertical branches do not. Test every pause or slow-motion mode used by the game.
- A Camera-only Shake with no attached Camera Controller still starts but produces no visible result. The same applies to an Item-only Shake when no supported listener exists.
- An active Shake cannot be retriggered. Rapid repeated impacts use the existing motion and duration rather than stacking or restarting it.
- The released controller assigns active effects a one-based index but removes them as though the index were zero-based. Avoid overlapping Shake with another Character Effect; if an existing system overlaps effects, stop them in reverse start order.
- Shake does not modify Animator parameters and has no built-in network synchronization or dedicated start/stop UnityEvents.

## Check the editor setup

Before Play Mode, confirm:

- at least one **Target** flag is selected;
- Camera and Item destinations have their required attached components or listeners;
- **Character** is off when the shake should be presentation-only;
- **Force**, **Fade Out Duration**, and **Duration** form a deliberate combination;
- the trigger points to the intended Shake index when duplicate Shake rows exist; and
- no other Character Effect will overlap this one.

## Verify in Play Mode

1. Trigger Shake once and confirm the intended row shows **(Active)**.
2. Observe each selected destination independently. Clear one Target flag at a time if the sources are difficult to distinguish.
3. Confirm the effect fades and its **(Active)** label clears after **Duration**, even when no camera or item is attached.
4. Test first and third person and retune the positional and rotational factors if their View Types feel different.
5. Pause or slow the game and confirm the unscaled duration and time-scale differences are acceptable.
6. In multiplayer, verify the local owner and each observer separately; only clients receiving the replicated trigger should shake.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Shake does not start. | Check whether **Target** has at least one flag and the row is enabled. | Select a destination and enable the Effect. |
| Shake is **(Active)** but nothing moves. | Check for a Camera-only target without an attached camera or an Item-only target without a supported listener. | Attach the required component, add another valid target, or select Character for a local single-player test. |
| The character drifts during a visual-only shake. | Check **Target > Character**. | Clear Character and use Camera and Item only. |
| The initial motion is much stronger after increasing **Fade Out Duration**. | Check the direct remaining-time multiplier used by that field. | Reduce **Force** or keep **Fade Out Duration** at or below `1` for a normalized-looking first pass. |
| Pause or slow motion produces uneven axes. | Check **Smooth Horizontal Force** and the unscaled **Duration** behavior. | Tune for the game's time modes or use a project-specific Effect with consistent time scaling. |
| Repeated hits do not restart or strengthen Shake. | Check whether the row already shows **(Active)**. | Wait for it to stop, stop and restart it deliberately, or use a custom Effect when stacking is required. |
| The wrong duplicate Shake starts. | Compare **Damaged Effect Index** or **Start Effect Index** with the zero-based Effects-list position. | Correct the index, or use `-1` for the first Shake of that type. |
| Another Character Effect stops or updates incorrectly. | Check whether the effects overlapped. | Avoid overlap in released Version 3 or stop them in reverse start order. |
| Remote players do not shake. | Check whether the network layer invoked Shake locally on their clients. | Replicate the source event and start the presentation for each intended observer. |

## Related tasks

- [Included Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/)
- [Effects overview](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/)
- [Boss Stomp](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/boss-stomp/)
- [Play Audio Clip](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/included-effects/play-audio-clip/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer details

The current runtime type is `Opsive.UltimateCharacterController.Character.Effects.Shake`. Its `ShakeTarget` flags are `Camera = 1`, `Item = 2`, and `Character = 4`. The public properties match the Inspector fields: `Target`, `Force`, `SmoothHorizontalForce`, `VerticalForceProbability`, `FadeOutDuration`, `PositionalFactor`, `RotationalFactor`, and `Duration`.

Retrieve a configured instance with `UltimateCharacterLocomotion.GetEffect<Shake>()`, then start and stop it through `TryStartEffect` and `TryStopEffect`. Both controller methods expect a non-null Effect reference. For duplicate Shake rows, `GetEffect<Shake>(index)` uses the absolute zero-based Effects-list position.

---

<a id="page-ultimate-character-controller-character-generic-character"></a>

# Generic Character

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/generic-character/)

Use a generic character for a creature, robot, first-person arm rig, or other model that does not use Unity's Humanoid Avatar. Ultimate Character Controller can drive its movement and gameplay, but its animations, collider fit, feet, and item attachment points must be configured for that model instead of being inferred from humanoid bones.

## Before you begin

- Import the model and its animations with a consistent generic skeleton. Preview the clips on the model before adding Ultimate Character Controller.
- Create an Animator Controller and clips made for that hierarchy. A generic rig cannot retarget the included humanoid animations.
- Place a model instance in the scene. Character Manager cannot build directly onto a prefab asset or build while Unity is in Play Mode.
- Complete the scene managers and camera steps in [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/).
- Decide whether the character needs items and footsteps. Generic rigs require manual item-slot and foot-transform assignments.

## Build the generic character

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Drag the scene model into **Character**.
3. Choose **Perspective** and the matching **First Person Movement** and/or **Third Person Movement**.
4. Leave **Animator** enabled, confirm **Character Model 1**, and set **Model Type** to **Generic**.
5. Assign the model-specific controller to **Animator Controller**. Changing **Model Type** from **Humanoid** to **Generic** clears the supplied controller selection intentionally.
6. Leave **Unity IK** and **Ragdoll** off. Character Manager turns both off when it detects or selects a generic model.
7. If **Items** is enabled, assign **Item Collection** and **Item Set Rule**, then use **Adjust Slots** to add the model's attachment transforms and slot IDs.
8. Leave **Foot Effects** on only when footsteps are needed. The feet will be assigned after the build.
9. Resolve every error in Character Manager, then select **Build Character**.

![Character Manager configured for the Blitz generic model with Third perspective, its custom Animator Controller, Foot Effects enabled, and Unity IK and Ragdoll disabled](https://opsive.com/wp-content/uploads/2018/03/GenericCharacterSetup.png?v=114f8b556609)

For the complete manager workflow and optional systems, see [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/).

## Configure animation and movement

Character Manager adds an Animator and Animator Monitor to the model, assigns the selected controller, and adds the required Ultimate Character Controller parameters to that controller. It does not create locomotion states, transitions, or generic animation clips. Build those for the model's own hierarchy, using [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) and [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) as the compatibility contract.

Generic rigs do not have to use root motion. Choose the movement source that matches the clips:

| Animation style | Character setup |
| --- | --- |
| In-place clips | Leave **Use Root Motion Position** and **Use Root Motion Rotation** off on Ultimate Character Locomotion. The selected Movement Type supplies movement and rotation. |
| Root-motion clips | Enable the matching root-motion option and verify both translation and rotation. Animator Monitor forwards the Animator's delta position and rotation to character locomotion. |
| Mixed behavior | Keep the character defaults appropriate for normal locomotion and use an ability's root-motion overrides only for the actions that need them. |

Use a movement type that fits the body plan. [Third Person Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/), for example, rotates into the travel direction and is designed for four-legged generic characters.

## Fit the generated collider

Build Character creates `Colliders/CapsuleCollider` for every model. Its released defaults are center `(0, 1, 0)`, height `2`, and radius `0.4`.

A humanoid receives a Capsule Collider Positioner that uses mapped head and hip bones. A generic model does not, so the default capsule is not resized from its skeleton. Select the generated Capsule Collider and adjust its center, height, radius, and local orientation to enclose the body without including large visual-only parts such as tails, wings, or weapons.

Keep the collider beneath the generated `Colliders` object and on the Character layer. Test low ceilings, slopes, steps, doorways, and turning in place after changing it.

## Assign feet and item slots

When **Foot Effects** is enabled, Character Manager adds Character Foot Effects to each animated model. It can fill the **Feet** list from humanoid foot or toe bones, but a generic model has no humanoid mapping and must be configured manually:

1. Select the model beneath the generated character root and open **Character Foot Effects > Footprint**.
2. Choose the intended **Footstep Mode**. **Body Step** uses the **Feet** list and animation motion; **Trigger** uses a Footstep Trigger on each foot.
3. Add every foot or contact transform to **Feet**. Each transform should face in the character's forward direction.
4. Set **Group** values to match the gait. For a four-legged example, the left feet can use group `0` and the right feet group `1`.
5. Set **Flipped Footprint** only for feet whose decal should be mirrored, then tune **Foot Offset** against the actual animations.

![Character Foot Effects Footprint inspector with four generic toe transforms assigned to left and right foot groups](https://opsive.com/wp-content/uploads/2018/03/BlitzFootEffects.png?v=af511fb50841)

Continue with [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) for placement modes and Surface Impact setup.

Generic models also have no automatic humanoid hand mapping. With **Items** enabled, open **Adjust Slots** in Character Manager and choose each attachment parent explicitly. Give corresponding first- and third-person attachment points the same slot ID. The item system attaches to those transforms; it does not require the transform to represent a human hand.

## Understand IK, ragdoll, and camera boundaries

- **Unity IK:** Character IK uses Unity's humanoid bone API, so Character Manager cannot add it to a generic model. Use animation authored for the rig or a separately supported IK solution instead of enabling **Unity IK**.
- **Ragdoll:** the built-in automatic ragdoll workflow uses Unity's humanoid Ragdoll Builder. Character Manager cannot create it for a generic model.
- **Mixed model sets:** **Unity IK** and **Ragdoll** are character-wide manager toggles. If any configured model is generic, enabling either prevents the build. Build with them off, then configure supported humanoid models separately if the character switches between rig types.
- **Camera:** Character Manager does not create a Camera Controller for any rig type. Use **Setup Manager > Scene > Camera Setup** and test the camera against the generated character root. **Auto Anchor** searches a humanoid bone and falls back to the controller root when that bone is unavailable, so keep it off or assign **Anchor** explicitly for a generic model and tune **Anchor Offset**. For first person, assign **First Person Arms** and **Third Person Objects** manually; separate arms commonly use their own generic rig and Animator Controller.

See [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/), [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/), and [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/) for those systems.

## Check the generated character

Before Play Mode, confirm:

- the new controller root contains Ultimate Character Locomotion and the generated `Colliders` hierarchy;
- the model is a child of that root and contains Animator plus Animator Monitor;
- **Animator Controller** is the project controller made for this generic skeleton;
- the capsule fits the model in the Scene view;
- Character IK and the built-in Ragdoll ability were not added to the generic model;
- every required foot and item attachment transform is assigned; and
- a Camera Controller is configured separately for a player character.

## Verify in Play Mode

1. Move and turn the character. The controller root, model, and capsule should remain aligned, and the model should enter the expected locomotion states.
2. Open **Window > Animation > Animator** and confirm the UCC movement parameters change and select the intended generic states.
3. Test an idle-to-move transition, a turn, a jump or other enabled ability, and a stop. Watch for sliding, unexpected root rotation, or a return to the bind pose.
4. Walk through narrow spaces and beneath a low obstacle to confirm the manually fitted capsule matches gameplay clearance.
5. If Foot Effects is enabled, confirm the correct transform produces each footprint or sound once per contact.
6. Equip one item in every configured slot and verify its position in every supported perspective.
7. Confirm the separately configured camera follows the intended **Anchor**. Its framing should remain correct during animation and movement without relying on a humanoid head bone.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The model stays in its bind pose. | Check **Model Type**, **Animator Controller**, and whether the controller contains states and clips made for this skeleton. | Select **Generic**, assign the correct controller, and build the locomotion states described in [Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/). |
| **Build Character** throws an invalid-cast error while adding Animator parameters. | Check whether **Animator Controller** contains an Animator Override Controller rather than a concrete Animator Controller asset. | Build with the underlying Animator Controller, ensure it contains the UCC parameters, then assign the override after the character is built and retest. |
| The model moves twice or slides. | Compare the clips' root motion with **Use Root Motion Position** and **Use Root Motion Rotation**. | Enable root motion only for clips that supply it, or use in-place clips with motor-driven movement. |
| The character collides too early or passes through visible body parts. | Inspect the generated capsule; generic rigs do not receive the humanoid Capsule Collider Positioner. | Fit the capsule manually and test the gameplay spaces that constrain the character. |
| Footsteps never occur or appear beneath the model origin. | Check the **Feet** entries, groups, transform forward directions, and selected **Footstep Mode**. | Assign the actual contact transforms and tune **Foot Offset** against the animation. |
| An item appears at the character origin or on the wrong limb. | Check **Adjust Slots**, attachment parents, and matching IDs across perspectives. | Assign the intended generic bones or mount transforms and keep corresponding slot IDs consistent. |
| **Build Character** is disabled after enabling IK or ragdoll. | Check whether any **Character Model** is **Generic**. | Turn off **Unity IK** and **Ragdoll** for the manager build. |
| The camera does not follow the character. | Check for a Camera Controller and its **Character** assignment; Character Manager creates neither. | Complete **Setup Manager > Scene > Camera Setup** and point it at the generated controller root. |
| The camera follows at the wrong height. | Check **Auto Anchor**, **Anchor**, and **Anchor Offset**. A generic rig cannot resolve the default humanoid Head bone. | Turn off **Auto Anchor** and assign a stable model transform, or use the controller root with a tuned **Anchor Offset**. |

## Released Version 3 constraints

- Selecting **Generic** clears the included humanoid Animator Controller because its clips cannot be retargeted to the generic hierarchy.
- **Build Character** adds parameters by casting the assigned runtime controller to Unity's concrete Animator Controller type. An Animator Override Controller in the manager field can raise an `InvalidCastException`; build with its base controller first.
- The default generic capsule is fixed-size and has no bone-driven Capsule Collider Positioner.
- Character Manager cannot automatically map generic feet or item slots, and its built-in Unity IK and ragdoll setup require humanoid bones.
- The manager configures the character only. Camera creation, animation state design, and project-specific IK or ragdoll behavior remain separate tasks.

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/)
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/)
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)

## Developer details

Character Manager identifies a humanoid only when `Animator.isHuman` is true and Unity returns a Head transform. Other models are treated as **Generic**. `CharacterBuilder.AddAnimator` adds Animator Monitor, and `AnimatorMonitor.OnAnimatorMove` forwards delta position and rotation to `CharacterLocomotion.UpdateRootMotion`.

`CharacterBuilder.AddCollider` always creates the default capsule, but it adds Capsule Collider Positioner only when the Animator is humanoid. `CharacterBuilder.AddUnityIK` skips non-humanoid models. `CharacterBuilder.AddFootEffects` still adds Character Foot Effects to an animated generic model, but `InitializeHumanoidFeet` cannot populate its feet, leaving the user-facing list to be assigned explicitly.

---

<a id="page-ultimate-character-controller-character-time"></a>

# Time

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/time/)

Use the character's local **Time Scale** to slow or pause one UCC character while the rest of the scene continues. Use Unity's global time scale only when the entire scaled simulation should change together.

## Choose local or global time

| Goal | Control | Result |
| --- | --- | --- |
| Slow one character for an effect, status condition, or replay | **Ultimate Character Locomotion > Physics > Time Scale** | Scales that character's locomotion, Animator, attached UCC camera, and supported owned effects without slowing other characters or ordinary scene physics. |
| Pause one character while the world continues | Set the character **Time Scale** to `0` | Stops UCC locomotion and animation, disables gameplay input for that character, and freezes its attached Camera Controller updates. |
| Slow or pause the whole game | Unity [Time Manager](https://docs.unity3d.com/Manual/class-TimeManager.html) or `Time.timeScale` | Changes Unity's scaled time for the scene. UCC's global-time calculations and the shared Scheduler follow it. |

The two values work together. A character **Time Scale** of `0.5` cannot make the character move while Unity's global time scale is `0`, and setting the local value above `1` does not opt the character out of a global pause.

## Configure character-local time

1. Select the character root and open **Ultimate Character Locomotion**.
2. Expand **Physics** and set **Time Scale**. The released Version 3 Inspector allows values from `0` to `4` and defaults to `1`.
3. Select the attached camera and open **Camera Controller > Zoom**. Keep **Adjust With Timescale** enabled when camera rotation should slow with the character; it is enabled by default.
4. If another component must react, connect **On Change Time Scale Event** under the locomotion component's **Events** foldout or subscribe to `OnCharacterChangeTimeScale` in code.
5. When a gameplay [State](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) owns the effect, add the public `TimeScale` property to that State's [Preset](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/). Activating and deactivating the State then uses the same property and notifications as a direct runtime change.

Do not use a negative value. The Inspector prevents it, while the runtime property itself is not clamped and several systems either divide by the value or deliberately ignore negative notifications.

### Editor checkpoint

Before Play Mode, confirm that the local **Time Scale** is `1` for normal play, the attached camera has **Adjust With Timescale** set intentionally, and every State or script that changes the value has a clear path back to `1`.

## Common scenarios

| Scenario | Recommended setup | Important boundary |
| --- | --- | --- |
| Character-only slow motion | Set the affected character to `0.25`-`0.75`; leave global time at `1`. | Other characters, ordinary Rigidbodies, UI, and unscaled systems continue normally. |
| Character-only pause | Set the character to `0`, then restore its previous positive value. | Generic Scheduler callbacks and unrelated scene objects do not pause with this local value. |
| Whole-game pause | Set Unity's global time scale to `0` and restore it from the system that owns the pause. | Audio and code using unscaled time need separate pause handling. |
| Bullet-time scene | Lower Unity's global value when every scaled object should slow. Use a local value only for characters that need an additional multiplier. | Test the fixed-step simulation, camera, audio, UI, and networking together. |
| Slow projectile from a slowed character | Use a UCC [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) with the character as its root owner. | Arbitrary spawned prefabs do not inherit local time automatically. |

## What character Time Scale affects

- **Locomotion and abilities:** `0` prevents the character locomotion update. Positive values scale controller movement, gravity, forces, damping, and many built-in ability calculations.
- **Animation and items:** the main and child Animator speeds follow the local value. Item animation and use cadence therefore slow with the character, but a custom timer or generic Scheduler delay does not automatically become character-local.
- **Input:** crossing from a nonzero value to `0` sends `OnEnableGameplayInput(false)`. Restoring a nonzero value sends `OnEnableGameplayInput(true)`.
- **Camera:** the attached Camera Controller stops rotating and moving while the character value is `0`. With **Adjust With Timescale** enabled, look rotation uses both the character and global values.
- **Supported owned objects and effects:** a UCC Trajectory Object copies its root owner's value and listens for later changes. UCC muzzle-flash fading, first-person item springs, and surface effects also receive the local scale where their implementations support it.
- **Audio:** UCC surface-effect audio uses the supplied local and global values when setting pitch. This is not a blanket rule for every `AudioSource` or item audio module; pause or retune other audio explicitly.
- **The rest of the scene:** another character, a normal Rigidbody, a moving world object, UI, and custom code remain on their own timing unless they explicitly read this character's value.

The shared Scheduler compares its events against global `TimeUtility.Time`. A local pause therefore does not guarantee that every delayed callback owned by the character is suspended. Custom character-local timers should stop accumulating while `TimeScale` is `0`, or cancel and reschedule their callbacks.

## How it runs

Changing `UltimateCharacterLocomotion.TimeScale` in Play Mode sends the `OnCharacterChangeTimeScale` event and invokes **On Change Time Scale Event**. The Animator monitors, player input, supported first-person item effects, muzzle flashes, and owned Trajectory Objects listen to that change.

At `0`, locomotion returns before applying input or movement, the Animators run at speed `0`, and gameplay input is disabled. The attached Camera Controller also skips rotation, movement, and Late Update. Restoring a positive value resumes those systems and enables gameplay input.

The serialized value is the character's starting value. Runtime changes are local runtime state: if the value must survive a save or agree across a multiplayer session, save and restore it through the same property and replicate the intended value from the gameplay authority. Do not use a client-only global time change to alter an authoritative shared simulation.

## Verify in Play Mode

1. Leave Unity's global time scale at `1`, move the character, and confirm normal locomotion, animation, item use, and camera response at local `1`.
2. Set the local value to `0.5`. The character, Animator, and timescale-adjusted camera should visibly run at half speed while an unaffected character or ordinary scene object continues normally.
3. Launch a UCC Trajectory Object, then change the owner from `0.5` to `0.25`. Its movement should follow the new owner value rather than keeping only its launch value.
4. Set the local value to `0`. Confirm that character movement, animation, gameplay input, and the attached camera stop while the rest of the scene continues.
5. Restore the previous positive value. Confirm that the character resumes and that any separate menu, dialogue, or cutscene input lock is still enforced by its owning system.
6. Schedule or observe a delayed action during the local pause. Confirm whether it is intentionally global or has its own character-local pause handling.
7. Test footsteps, impacts, weapons, and other important audio. Confirm that each sound either follows the intended pitch/pause behavior or is handled separately.
8. Finally, set Unity's global time scale to `0`. The character must remain paused regardless of its local value, and global Scheduler delays should wait until global scaled time resumes.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The whole scene slows instead of one character. | Unity's global time scale was changed. | Restore global time to `1` and change **Ultimate Character Locomotion > Physics > Time Scale** on the intended character. |
| The character does not resume. | Either the local or global value may still be `0`. | Restore both owners deliberately; a positive local value cannot override a global pause. |
| A delayed action completes during a character-only pause. | The callback is probably using the shared Scheduler or another global-time source. | Cancel and reschedule it, or implement a timer that accumulates only while the character's local value is positive. |
| A grenade or projectile keeps normal speed. | It may be an ordinary Rigidbody/prefab, or its UCC Trajectory Object may not resolve the character as its root owner. | Use the UCC Trajectory Object ownership path or add explicit local-time support to the custom projectile. |
| The camera feels too slow. | **Adjust With Timescale** multiplies look rotation by both local and global values. | Disable it only when camera look should remain responsive during slow motion; the camera still stops when local time is exactly `0`. |
| Audio keeps playing at its normal pitch. | Only systems that explicitly apply the local value are adjusted; UCC surface effects are one supported path. | Pause, pitch, or mix other AudioSources through the audio system that owns them. |
| Input becomes enabled while a menu or cutscene is still active. | Restoring a local value from `0` sends `OnEnableGameplayInput(true)`. | Coordinate pause ownership and reapply the independent input lock instead of letting multiple systems restore input blindly. |
| A listener receives `-1` while **Time Scale** is edited during Play Mode. | The released Version 3 Inspector uses `-1` as an internal sentinel before applying the selected value. | Do not drive production time changes by editing the live Inspector. Ignore negative diagnostic notifications and change the property through gameplay code or a State. |

## Related tasks

- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Presets](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/)
- [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/)

## Developer reference

Set the local value through `UltimateCharacterLocomotion.TimeScale` so the built-in event, UnityEvent, input, Animator, camera, and supported owned-object listeners are notified. This component must be placed on the same character root as `UltimateCharacterLocomotion`:

```csharp
using UnityEngine;
using Opsive.Shared.Events;
using Opsive.UltimateCharacterController.Character;

public class CharacterTimeControl : MonoBehaviour
{
    private UltimateCharacterLocomotion m_CharacterLocomotion;

    private void Awake()
    {
        m_CharacterLocomotion = GetComponent<UltimateCharacterLocomotion>();
        EventHandler.RegisterEvent<float>(gameObject, "OnCharacterChangeTimeScale", OnChangeTimeScale);
    }

    public void SetSlowMotion(bool active)
    {
        m_CharacterLocomotion.TimeScale = active ? 0.5f : 1f;
    }

    public void SetPaused(bool paused)
    {
        m_CharacterLocomotion.TimeScale = paused ? 0f : 1f;
    }

    private void OnChangeTimeScale(float timeScale)
    {
        Debug.Log("New time scale: " + timeScale);
    }

    private void OnDestroy()
    {
        EventHandler.UnregisterEvent<float>(gameObject, "OnCharacterChangeTimeScale", OnChangeTimeScale);
    }
}
```

The event argument is the new value. In the released Version 3 setter, the notification is sent before the backing value is assigned, so use the argument rather than reading `m_CharacterLocomotion.TimeScale` from inside the callback. Changing Unity's global time scale does not send `OnCharacterChangeTimeScale` or invoke the character's **On Change Time Scale Event**.

---

<a id="page-ultimate-character-controller-character-model-switch"></a>

# Model Switch

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/)

Use Model Manager to change the character's visible rig, collider, animation, first-person objects, and item attachment points while keeping one locomotion, ability, inventory, health, and camera setup.

Model switching works best for skins, alternate forms, or interchangeable characters that share the same controller rules. Use separate characters when the alternatives need unrelated locomotion, inventory, or camera ownership.

## Before you begin

- Build from scene model instances, not prefab assets or already configured Ultimate Character Controller characters.
- Prepare an Animator Controller for every model. The runtime switch copies animation data between Animation Monitors, so every entry needs an **Animator** and **Animator Monitor**, including a generic model.
- Use compatible root orientation and scale. Each model can have its own collider shape, but all models move through the same character root.
- Leave every configured model active in Edit Mode. Model Manager deactivates the alternatives during its Start phase; pre-disabling one can prevent Character Manager and model-level systems from discovering it.
- Decide whether the character uses first person, third person, or both. Model switching does not change the active Perspective, Movement Type, or camera View Type.
- When items are enabled, plan equivalent slot roles across every model and first-person arm rig.

For representative hierarchy layouts, see [Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/).

## Build a character with multiple models

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Assign the first scene model to **Character**, then choose **Perspective**, the required Movement Types, and the normal character options.
3. Keep **Animator** enabled. Configure **Character Model 1**, **Model Type**, and **Animator Controller** for the first rig.
4. Assign the second scene model in the empty **Character Model 2** row. Another empty model row appears after it; use those rows for any additional models.
5. For every model, select its own **Model Type** and **Animator Controller**.
6. For a first-person or Both character, configure each model's **First Person Arms** and **Third Person Objects**. These references are model-specific.
7. When **Items** is enabled, select **Adjust Slots** for each model. Use the same slot ID for equivalent attachment roles, such as right hand ID `0`, across every full-body model and arm rig.
8. Enable **Unity IK** or **Ragdoll** only when every model is a valid humanoid. Configure **Foot Effects** for the feet available on each model.
9. Resolve every Character Manager error, then select **Build Character**.

To add a model to an existing character, assign the controller root to **Character**, fill the next empty **Character Model** row, complete that model's settings, and select **Update Character**.

## Check the generated setup

With two or more models, Character Manager adds one **Model Manager** to the character root. **Available Models** contains the model GameObjects in their selection order. If **Active Model** is unassigned before Play Mode, the first available model becomes active during initialization.

![Model Manager Inspector with Atlas and Rhea in Available Models and Atlas assigned as the active model](https://opsive.com/wp-content/uploads/2022/11/ModelManager.png?v=8433b4c59510)

Each model should be a sibling beneath the controller root and should contain its own Animator, Animator Monitor, and generated collider hierarchy. Model-specific arms, hidden third-person objects, item slots, Character IK, Character Foot Effects, and ragdoll objects also belong with their corresponding model. Root systems such as Ultimate Character Locomotion, Abilities, Inventory, Item Set Manager, attributes, and health exist only once.

> **Released Version 3 update boundary:** When an existing character already has **Ragdoll**, adding another humanoid model does not add ragdoll colliders to that model because the update check sees the existing root Ragdoll ability. Foot Effects detection is also based on valid humanoid models, so a new generic model or a mixed rig list can be skipped or reported incorrectly. Inspect both groups after **Update Character**. For Ragdoll, turn the option off and update once, then turn it on and update again to rebuild the group across all models. Configure missing generic foot transforms directly if Character Manager does not retain the **Foot Effects** choice. Keep a recoverable scene or prefab version before a subtractive update.

## Switch models at runtime

Connect a menu, customization screen, trigger, or other gameplay choice to `ChangeModels`. Validate the index so only a configured **Available Models** entry can be selected.

```csharp
using Opsive.UltimateCharacterController.Character;
using UnityEngine;

public class CharacterModelSelector : MonoBehaviour
{
    [SerializeField] private ModelManager m_ModelManager;

    public void SwitchModel(int index)
    {
        var availableModels = m_ModelManager != null ? m_ModelManager.AvailableModels : null;
        if (availableModels == null ||
            index < 0 ||
            index >= availableModels.Length ||
            availableModels[index] == null) {
            return;
        }

        m_ModelManager.ChangeModels(availableModels[index]);
    }
}
```

The public `ActiveModel` property also calls `ChangeModels`. The serialized **Active Model** field in Unity's default Inspector is a starting-value field, not a runtime switch button. Changing that field directly during Play Mode bypasses the property and does not run the switch lifecycle.

## What changes during a switch

| Area | Runtime result |
| --- | --- |
| Model and collider | Model Manager deactivates the previous model and activates the target. Ultimate Character Locomotion ignores colliders on inactive model hierarchies, so only the active model's generated collider shape participates. |
| Animation | The target Animation Monitor receives the current animation parameters from the previous monitor. Only the active monitor continues updating from locomotion, and first-person child monitors receive matching values. |
| Abilities and root motion | Ultimate Character Locomotion resets accumulated root motion. Abilities begin using the new model's Animation Monitor while the same active abilities and root controller remain in place. |
| Items | Perspective items respond to the switch, find the matching slot on the new model, reparent their visible object, and refresh IK or holster references. Equivalent slots must use matching IDs. |
| First-person objects | The first-person hierarchy associated with the active model becomes available, and the previous model's hierarchy is hidden. Separate arms and hidden full-body objects therefore need per-model setup. |
| IK, feet, and ragdoll | Model-level components and colliders activate with their model. They are not copied from the previous model at switch time. |
| States and event | The State named after the previous model GameObject is disabled, the State named after the new model is enabled, and `OnCharacterSwitchModels` sends the active model GameObject. |
| Camera and perspective | The same Camera Controller, View Type, Perspective, and Movement Type remain active. First-person view logic updates its model anchor; a model switch is not a perspective switch. |

## Key choices

### Keep one shared controller contract

All available models share the root Movement Types, Abilities, Item Abilities, Effects, Inventory, attributes, and health. Use States named exactly after the model GameObjects to change supported root component values for a form or skin. Give the models unique, stable names so those State names remain unambiguous.

If two forms need different controls or entirely different ability sets, separate character roots are usually clearer than making one Model Manager list responsible for both designs.

### Match model-specific references

- Give every model an Animator Monitor and a controller containing the required UCC parameters.
- Fit and test the generated collider for each body. Different heights or radii are supported because inactive model colliders are ignored.
- Reuse item slot IDs by role, not by bone name. The right hand should retain the same ID even when the rigs use different transform names.
- Configure first-person arms and **Third Person Objects** for each model rather than sharing transforms from the first rig.
- Use only humanoid models when **Unity IK** or **Ragdoll** is enabled through Character Manager. A mixed humanoid/generic list cannot use those global options.
- Confirm feet, ragdoll colliders, IK, and model-specific integration components exist on every model that needs them; Model Manager does not create missing components while switching.

### Keep camera ownership on the root

The Camera Controller follows the character root and does not select a new View Type when the model changes. When models have different heights, use compatible head or neck bones for the first-person view and test the camera anchor for every model.

The released Version 3 Camera Controller does not re-run its general **Auto Anchor** selection in response to `OnCharacterSwitchModels`. If a third-person or custom view remains framed at the first model's bone height, turn **Auto Anchor** off and assign a stable root child to **Anchor**, then tune **Anchor Offset** for the shared framing.

### Plan persistence and networking explicitly

Model Manager does not save a runtime selection by itself. On a new scene load it uses the serialized **Active Model**, or the first **Available Models** entry when that field is empty. Store a stable model identifier in the project's save data and call `ChangeModels` after the character has initialized. Avoid relying only on a numeric index when later releases may reorder the list.

With a supported multiplayer integration, an authoritative switch is sent through `INetworkCharacter.ChangeModels` as an index. Every peer therefore needs the same **Available Models** entries in the same order. Let the integration deliver remote switches instead of changing the serialized field locally.

Model Manager is excluded from Character Manager template copying. Configure the target character's models separately after using a [Character Template](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/templates/).

## Verify in Play Mode

1. Enter Play Mode and inspect **Model Manager**. The expected starting model should be active and every other **Available Models** GameObject should be inactive.
2. Move, rotate, jump, and start one representative ability, then switch models through the gameplay control. The root should not move unexpectedly, animation parameters should continue, and the Console should remain clear.
3. Walk against a wall and across a step with every model. Only the active model's collider should determine clearance and grounding.
4. Equip one item in each configured slot, switch models, and switch perspectives when supported. The visible item should move to the equivalent slot; arms and hidden objects should match the active model.
5. Exercise **Unity IK**, **Foot Effects**, and **Ragdoll** on every model for which they are enabled.
6. Test the shortest and tallest models with every camera View Type. The framing and first-person anchor should remain intentional.
7. Save and reload the selected model through the project's persistence layer. In multiplayer, repeat the switch from the owning client and confirm all peers show the same model.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Changing **Active Model** in the Inspector does not switch the visible model | The default Inspector writes the serialized backing field and does not call the public property setter. | Trigger `ChangeModels` or assign the public `ActiveModel` property from code. Use the Inspector field only to configure a valid starting entry before Play Mode. |
| Switching throws an exception | Check **Available Models** for nulls, duplicate entries, objects outside the character, or a model without Animator Monitor. The released Version 3 switch path assumes valid source and target Animation Monitors. | Rebuild or update through Character Manager, remove invalid list entries, and ensure every model has Animator and Animator Monitor. |
| Both models remain visible, or the wrong model starts | Check whether the list was edited at runtime and whether **Active Model** belongs to **Available Models**. | Configure the complete list before Play Mode. Assign a valid starting model in Edit Mode or leave it empty to use the first entry. |
| The new model has the wrong collision height | Inspect that model's generated collider hierarchy rather than the root or previous model. | Fit the active model's Capsule, Sphere, or Box Collider and retest stairs, slopes, and obstacles. |
| An equipped item disappears or attaches to the wrong bone | Compare the Character Item **Slot ID** with every model and first-person arm slot. | Use **Adjust Slots** and assign the same ID to equivalent attachment roles, then update and retest the character. |
| A newly added model lacks footsteps or ragdoll behavior | The Version 3 update path checks Ragdoll only through the root ability and counts Foot Effects through valid humanoid models. | Rebuild Ragdoll with the two-update off/on workflow described above. Inspect and configure Character Foot Effects directly for a generic or mixed rig list. |
| The camera stays at the first model's height | Check Camera Controller **Auto Anchor**, **Anchor**, and **Anchor Offset**, plus the active View Type's head-anchor requirements. | Use compatible humanoid anchors or disable **Auto Anchor** and assign a stable root child as the shared anchor. |
| A model-specific Ability State remains active after switching during that ability | In released Version 3, the active-ability switch path writes the State-off request against the new model name instead of the previous one. | Stop the affected ability before switching, or explicitly clear the old model-prefixed State in the switching workflow. Plain States named after each model still switch correctly. |
| A saved or networked selection restores the wrong model | Check whether **Available Models** order changed, whether the runtime choice was saved, and whether every peer uses the same list. | Resolve a stable saved ID to the current model, and keep identical model order across networked builds. |

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) covers the complete manager workflow and generated hierarchy.
- [Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/) shows a representative multi-model configuration.
- [Item Support](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/) configures equivalent item slots and first-person objects.
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/) configures View Types, anchors, and perspective ownership.
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/) explains Animator Monitor and the required controller parameters.
- [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) configures the humanoid IK path used by each model.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) configures feet and surface responses.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) uses model-named States to adjust shared controller values.

## Developer details

`ModelManager.ChangeModels(GameObject)` disables the previous model State and GameObject, activates the target, enables its model-named State, sends `OnCharacterSwitchModels`, and copies animation parameters from the original Animation Monitor. Setting the public `ActiveModel` property delegates to this method. `ActiveModelIndex` and `ModelIndexMap` expose the initialized index mapping.

The runtime method deliberately does not validate the target. Pass only a non-null member of `AvailableModels`; nulls, duplicates, missing Animation Monitors, or arbitrary external GameObjects can fail during initialization or switching. Assigning a new array through `AvailableModels` after `Awake` also does not rebuild `ModelIndexMap`. Prefer a complete Character Manager build before Play Mode.

Under `ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER`, a character with network information accepts a local request only when it has authority and asks `INetworkCharacter` to replicate the selected index. The networking integration calls the server-originated switch path for remote changes.

The component has no built-in save record for a runtime selection. Persist the project's stable model identifier separately, wait until Model Manager has initialized its index map, resolve the intended GameObject, and then call `ChangeModels`.

---

<a id="page-ultimate-character-controller-character-minimum-component-setup"></a>

# Minimum Component Setup

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/character/minimum-component-setup/)

Build the smallest Ultimate Character Controller character that can move and collide correctly, then add input, animation, items, health, and presentation systems only when the game needs them.

## Before you begin

- Complete the project layers and scene services in [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/). Those services are not character components, but the generated layer assignments and supported scene setup prevent avoidable collisions and missing-manager errors.
- Import the first-person or third-person controller that supplies the intended Movement Type.
- Decide whether this is a player, an AI agent, or a character controlled by a networking integration. That choice determines the input and look-source route; it does not change the collision core.
- Use a scene instance. The Character Manager does not build directly onto a prefab asset and does not run in Play Mode.

## Build the practical minimum with Character Manager

The Character Manager is the safest way to create a minimal character because it builds the layers, collider hierarchy, Movement Type, input or AI route, and initialization dependencies together.

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Assign a scene model to **Character**. For a bodyless first-person character, leave **Character** empty and disable **Animator**.
3. Choose **Perspective** and select the corresponding **First Person Movement** and/or **Third Person Movement**.
4. Keep **Animator** enabled only when a visible model needs animation or root motion. Assign the model and Animator Controller when it is enabled.
5. For a minimal player, leave **AI Agent** off and choose the project's input route. For an AI character, enable **AI Agent** instead.
6. Disable optional systems that are not needed: **Standard Abilities**, **NavMeshAgent**, **Items**, **Health**, **Unity IK**, **Foot Effects**, and **Ragdoll**.
7. Resolve every validation error and select **Build Character**.
8. For a player, configure the separate Camera Controller through **Setup Manager > Scene > Camera Setup**. The Character Manager does not create the camera.

The example below keeps both perspectives and animation but disables every optional gameplay and presentation group. A bodyless first-person character can be smaller by also disabling **Animator**.

![Character Manager configured for both perspectives with an animated Atlas model while Standard Abilities, AI Agent, NavMeshAgent, Items, Health, Unity IK, Foot Effects, and Ragdoll are disabled](https://opsive.com/wp-content/uploads/2018/03/MinimumCharacterSetup.png?v=52cb9382a187)

## Understand the runtime minimum

The collision core is small, but a Movement Type is also required for a character that updates successfully. Character Manager creates the following arrangement:

| Location | Required part | Why it is required |
| --- | --- | --- |
| Character root | **Ultimate Character Locomotion** | Owns movement, collision queries, Movement Types, Abilities, Item Abilities, and Effects. |
| Character root | **Rigidbody** | Supplies the position and rotation used by the locomotion motor. Character Manager sets **Use Gravity** off, **Is Kinematic** on, damping to `0`, interpolation to **None**, and mass to `80`. |
| Character root | **Character Layer Manager** | Supplies the character, solid-object, and invisible-object layer masks used by locomotion. |
| Character root or descendant | One enabled, non-trigger **Capsule Collider**, **Sphere Collider**, or **Box Collider** on a layer included by **Collider Layer Mask** | Defines the character shape used by the controller's casts and overlap checks. Character Manager creates `Colliders/CapsuleCollider` on the Character layer. |
| Inside Ultimate Character Locomotion | At least one configured and active **Movement Type** | Converts the control route into movement and rotation. The runtime update expects an active Movement Type even when no optional Abilities are present. |

Keep the root on the Character layer. Character Manager places normal model children on the SubCharacter layer and keeps the generated collision objects on the Character layer, preventing model colliders from accidentally becoming locomotion colliders.

After a build, check that the root contains the three core components, `Colliders/CapsuleCollider` exists beneath the model or root, and the intended Movement Type is active in Ultimate Character Locomotion.

## Add the control route

The core can simulate with zero input, but a useful character needs one control route.

| Character | Add or keep | Keep separate or omit |
| --- | --- | --- |
| Player | **Ultimate Character Locomotion Handler**, a root **Player Input Proxy**, and the matching child input provider. With the Input System, the child also has Unity's **Player Input** with the selected Input Actions and the `Gameplay` default action map. | Configure a Camera Controller separately. It supplies the player's look source when attached to the character. |
| AI | **Local Look Source** plus the AI or navigation integration that drives movement and abilities. Character Manager removes the player input route when **AI Agent** is enabled. | Do not keep Ultimate Character Locomotion Handler or player input unless the design deliberately switches between player and AI control. |
| Networked | The handler, look source, and synchronization components required by the selected networking integration. | Do not add the local player route merely to satisfy the minimum list. Remote and locally owned characters have different responsibilities. |

A look source is not needed to construct the Rigidbody-and-collider core, but normal player cameras, AI aiming, perspective selection, and several Movement Types or Abilities depend on one. Test the chosen route rather than treating a bare `ILookSource` implementation as a substitute for the integration setup.

## Choose what remains optional

| System | Add it when |
| --- | --- |
| **Animator** and **Animator Monitor** | A visible model must animate or provide root motion. Animator Monitor bridges UCC runtime values and root-motion deltas to the Animator. They are not required for a bodyless or deliberately non-animated motor. Character Manager requires animation for its normal third-person model workflow. |
| **Abilities**, **Item Abilities**, and **Effects** | The character needs behaviors beyond its Movement Type. **Standard Abilities** is a convenience set, not part of the collision minimum. |
| **Character Attribute Manager**, **Character Health**, and **Character Respawner** | The character needs attributes, damage, death, or respawning. Add the complete Health group when those behaviors are required. |
| Inventory, Item Set, item-handler, placement, and item-ability components | The character can own or use items. Enable **Items** in Character Manager instead of adding only part of the item-support group. |
| **Character IK**, **Character Foot Effects**, and **Ragdoll** | The intended rig and presentation need them. Humanoid-only features do not belong on a generic model. |
| **Camera Controller** | A player needs a view and look source. It belongs to the scene camera rather than the character's minimum hierarchy. |
| Scene managers | The scene uses the corresponding services. Add them through Setup Manager; do not place them on the character root. |

For a deeper explanation of each group, see [Component Overview](https://opsive.com/support/documentation/ultimate-character-controller/component-overview/).

## Build the core manually

Manual setup is useful for a generated or runtime-created character, but it bypasses Character Manager validation.

1. Create the character root on the Character layer.
2. Add **Character Layer Manager**, a **Rigidbody**, and **Ultimate Character Locomotion** to that same root. Configure the Rigidbody as kinematic with Unity gravity disabled.
3. Add an enabled, non-trigger Capsule, Sphere, or Box Collider on the root or a child included by **Collider Layer Mask**. Use the Character layer for locomotion colliders and the SubCharacter layer for normal model children.
4. Add at least one Movement Type to Ultimate Character Locomotion and make it active. Follow [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) for the perspective-specific choices.
5. Add exactly one player, AI, or network control route as described above.
6. Add **Animator** and **Animator Monitor** to each animated model, then assign an appropriate Animator Controller. A generic model requires its own animation setup; see [Generic Character](https://opsive.com/support/documentation/ultimate-character-controller/character/generic-character/).
7. Create and attach the camera separately when this is a player character.
8. Finish all dependencies before enabling or initializing the character.

Leave **Character Initializer > Auto Initialization** enabled for an ordinary scene character. At scene load, locomotion caches its Rigidbody, Character Layer Manager, colliders, Movement Types, and handlers before simulation begins. When intentionally using delayed initialization, create the full hierarchy first and invoke the initializer's `OnAwake`, `OnEnable`, and `OnStart` phases in that order.

## Verify in Play Mode

1. Select the character root and enter Play Mode. Ultimate Character Locomotion should show the intended active Movement Type, and the Console should remain free of null-reference, missing-collider, and missing-look-source messages.
2. Move the character through the selected player, AI, or networking route. The Rigidbody should remain kinematic and be moved by Ultimate Character Locomotion rather than Unity gravity or another motor.
3. Walk into a wall, across a slope, and off a ledge. The configured locomotion collider should define the contacts without colliding with the model's SubCharacter-layer colliders.
4. For an animated character, watch the Animator parameters and root motion while moving. Animator Monitor should update the model without a second script moving the root.
5. For a player, rotate the camera and move in several directions. The camera should remain attached as the look source and the Movement Type should respond consistently.
6. Exercise one enabled optional group. If all optional groups were disabled, confirm that no health, item, IK, foot-effect, or ragdoll components were generated.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Play Mode reports a null reference immediately | Check the character root for both **Rigidbody** and **Character Layer Manager**. Ultimate Character Locomotion does not declare Unity `RequireComponent` attributes for these dependencies in released Version 3. | Add both components before locomotion initializes, or rebuild the character through Character Manager. |
| The character does not move and the active Movement Type is empty | Check the **Movement Types** list and the active movement selection in Ultimate Character Locomotion. | Add the perspective-appropriate Movement Type and make it active before entering Play Mode. |
| A collider is visible but locomotion reports that the character has no collider | Check that it is an enabled, non-trigger Capsule, Sphere, or Box Collider and that its layer is included by **Collider Layer Mask**. | Use a supported collider and correct its layer. Keep decorative, hitbox, and model colliders on an excluded layer such as SubCharacter. |
| Player input has no effect | Check **Player Input Proxy**, its referenced input provider, and **Ultimate Character Locomotion Handler**. The handler caches the input route during initialization. | Configure the complete route before initialization, or rebuild/update through Character Manager instead of adding the input provider afterward. |
| An AI character without an Animator throws an exception in **Local Look Source** | In released Version 3, an empty **Look Transform** makes Local Look Source search for an Animation Monitor before falling back to the root. | Assign **Look Transform** explicitly to the root, head, or intended aim transform on an animationless AI character. |
| The camera does not follow a minimal player | Check for a Camera Controller and its **Character** assignment. The Character Manager builds only the character. | Use **Setup Manager > Scene > Camera Setup**, then assign the character or enable the supported automatic player lookup. |
| The character jitters or moves twice | Check for a dynamic Rigidbody, Unity gravity, a Character Controller, NavMesh movement outside the UCC integration, or another script moving the root. | Keep the Rigidbody kinematic, disable Unity gravity, and let one UCC control route own movement. |

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) covers every Character Manager choice and the generated hierarchy.
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) configures the movement model required by the core.
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) selects and configures the player's input implementation.
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/) creates the player's Camera Controller and look-source route.
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/) connects an AI solution without adding player input.
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/) adds the complete item-support group.
- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/) adds attributes, health, damage, death, and respawning.

## Developer details

`CharacterLocomotion.AwakeInternal` caches the same-root Rigidbody and Character Layer Manager, forces the Rigidbody to kinematic with zero damping and no interpolation, and scans descendants for supported colliders. `UltimateCharacterLocomotion.InitializeMovementTypes` initializes the serialized Movement Types and selects the configured type before simulation uses `ActiveMovementType`.

Colliders added after locomotion has initialized are not discovered by another hierarchy scan. Call `CharacterLocomotion.AddCollider` after creating a runtime collider and `RemoveCollider` before removing one. Likewise, construct the Player Input Proxy and its provider before `UltimateCharacterLocomotionHandler` initializes, because the handler caches that input reference in its awake phase.

`CharacterBuilder.AddEssentials` is the supported source-level equivalent of the minimal Character Manager build. It assigns the layers, creates the Rigidbody and core components, adds a generated capsule hierarchy, configures input or Local Look Source, and coordinates delayed initialization when called during Play Mode.

---

<a id="page-ultimate-character-controller-camera"></a>

# Camera

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/)

The Camera Controller connects a local player character to the camera, while the active View Type decides the camera's position, rotation, and look direction. Configure it after the scene managers and character exist, then choose a first-person, third-person, or switchable perspective that matches the game.

A player-controlled character needs a Camera Controller so character facing and item use can follow the camera's look direction. AI agents and remote network characters do not need their own player camera.

## Start with a working camera

1. Follow [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) to add the scene managers, select a camera perspective, and create the camera.
2. On **Camera Controller**, assign **Character**, or leave **Init Character On Awake** enabled and ensure the intended character has the **Player** tag.
3. Choose the active first-person or third-person View Type. When both perspectives are installed, choose both defaults and enable **Can Change Perspectives** only if the player should switch between them.
4. Configure the horizontal and vertical look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).
5. Enter Play Mode and verify the camera before adding fading, post processing, split screen, or project-specific states.

If **Init Character On Awake** is enabled without an assigned character, the Camera Controller searches for a GameObject with the **Player** tag. It disables itself when it cannot find one.

## Choose a perspective and View Type

- **First person:** Use a first-person View Type when the camera should represent the character's own view. First-person arms and items may use a separate child camera, which affects post-processing choices.
- **Third person:** Use a third-person View Type when the character should remain visible and the camera needs an offset, orbit, or fixed movement style.
- **Both perspectives:** Add a valid first-person and third-person View Type, choose each default, and enable **Can Change Perspectives**. Test the transition in both directions with the character's items equipped.

A View Type calculates where the camera should move and which direction the character or an item should look; the Camera Controller applies that result and coordinates the character assignment. Start with [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/), then compare the [included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/). For an external camera workflow, use the supported [Cinemachine integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/cinemachine/) rather than replacing the character-camera connection.

## Configure the important choices

| Choice | Use it when |
| --- | --- |
| **Init Character On Awake** and **Character** | The camera should attach automatically at startup or follow an explicitly assigned local character. Assigning `null` to **Character** at runtime disables the controller. |
| **Anchor**, **Auto Anchor**, and **Auto Anchor Bone** | The camera should be positioned relative to a particular Transform or humanoid bone. A moving body-part anchor introduces more visible motion than the character root. |
| **Anchor Offset** | The selected anchor needs a stable positional offset before the View Type applies its own movement. |
| **First Person View Type** and **Third Person View Type** | The project includes the corresponding perspectives and needs a default for each one. |
| **Can Change Perspectives** | Both first-person and third-person View Types exist and the player is allowed to switch between them. |
| **Can Zoom** | The camera may enter its zoom behavior. The active View Type and equipped items can still reject zoom. |
| **Zoom State** | Zoom should activate a named state on the camera and character, such as the default `Zoom` state. |

## Configure look controls and zoom

View Types read horizontal and vertical look values from the character's Player Input implementation. Use the [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) guide to choose the input implementation, mapping names, sensitivity, smoothing, controller behavior, and cursor handling.

For zoom, enable **Can Zoom** and keep **Zoom State** aligned with the state presets that change the camera, character, or item. In Play Mode, test zoom with no item and with each relevant equipped item: the Camera Controller, active View Type, and active item must all allow it.

## Continue by camera workflow

- **Camera motion and aiming:** [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/) explains how the active View Type supplies rotation, position, and look direction.
- **Character or obstacle visibility:** [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) covers fading the character when the camera is close and fading geometry that blocks the view.
- **Rendering effects:** [Post Processing](https://opsive.com/support/documentation/ultimate-character-controller/camera/post-processing/) explains the different camera targets used by first-person and third-person rendering.
- **Local multiplayer and mirrors:** [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/) covers per-player cameras, material swapping, viewports, UI, and input assignment.

## Verify in Play Mode

1. Confirm that the camera remains enabled and the Console does not report a missing character or a character without **Ultimate Character Locomotion**.
2. Move the look input. The active View Type should rotate or position the camera, and character facing or item aiming should use the expected look direction.
3. If both perspectives are configured, switch in both directions and confirm that the intended first-person and third-person View Types become active.
4. Start and stop zoom. Confirm that the expected field of view or offset changes occur and that the configured **Zoom State** activates and clears.
5. Walk near walls and through tight spaces. Confirm that the camera does not clip or reveal unwanted character geometry; add Object Fader only when the selected View Type needs it.
6. For split screen, confirm that each camera follows its assigned character, renders only its viewport, and responds to the correct player's input.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Camera Controller disables itself at startup. | **Character** is empty and no valid character has the **Player** tag. | Assign the local character or correct its tag before entering Play Mode. |
| Look input does not move the camera. | The character's Player Input implementation, horizontal or vertical look mappings, or cursor state may not match the project. | Follow [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) and verify the configured mapping values in Play Mode. |
| Perspective switching does nothing. | One perspective View Type is missing or **Can Change Perspectives** is disabled. | Add valid defaults for both perspectives and enable switching. |
| Zoom input does nothing. | **Can Zoom**, the active View Type, or an equipped item may reject zoom. | Test without an item, verify **Can Zoom**, then check the selected View Type and item zoom settings. |
| The camera has excessive motion. | **Anchor** or **Auto Anchor Bone** may follow an animated body part. | Use a more stable anchor or tune **Anchor Offset** for the intended view. |

## Developer reference

Set `Character` to change the followed character, call `SetPerspective` when both perspective defaults exist, or call `SetViewType` for a View Type already added to the Camera Controller:

```csharp
using UnityEngine;
using Opsive.Shared.Camera;
using Opsive.Shared.Utility;
using Opsive.UltimateCharacterController.Camera;

public class MyObject : MonoBehaviour
{
    [Tooltip("The character that should be assigned to the camera.")]
    [SerializeField] private GameObject m_Character;

    /// <summary>
    /// Assigns the character and switches to the third-person Combat View Type.
    /// </summary>
    private void Start()
    {
        var camera = CameraUtility.FindCamera(null);
        if (camera == null) {
            return;
        }

        var cameraController = camera.GetComponent<CameraController>();
        cameraController.Character = m_Character;
        cameraController.SetPerspective(false);

        var viewTypeName = "Opsive.UltimateCharacterController.ThirdPersonController.Camera.ViewTypes.Combat";
        cameraController.SetViewType(TypeUtility.GetType(viewTypeName), false);
    }
}
```

The Camera Controller also exposes Unity events and events through the built-in [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/):

```csharp
using Opsive.Shared.Events;
using Opsive.UltimateCharacterController.Camera.ViewTypes;

EventHandler.RegisterEvent<ViewType, bool>(cameraGameObject, "OnCameraChangeViewTypes", OnChangeViewType);
EventHandler.RegisterEvent<bool>(character, "OnCameraChangePerspectives", OnChangePerspective);
EventHandler.RegisterEvent<bool>(cameraGameObject, "OnCameraZoom", OnZoom);
```

`OnCameraChangeViewTypes` supplies the View Type and whether it was activated, `OnCameraChangePerspectives` supplies whether the new perspective is first person, and `OnCameraZoom` supplies whether zoom is active. Unregister each listener when its subscribing object is destroyed.

---

<a id="page-ultimate-character-controller-camera-view-types"></a>

# View Types

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)

A View Type determines the camera's rotation, position, field of view, and look direction. The Camera Controller owns the available View Types and activates one of them; the active View Type then turns look input and character state into the view seen in Play Mode.

Choose the View Type together with its recommended character Movement Type. That pairing determines whether the camera and character rotate together, move independently, follow a path, or use a fixed composition.

## Configure the Camera Controller

1. Select the camera with the **Camera Controller** component.
2. Expand **View Types** in the Inspector.
3. Use the add control under the **View Types** list to add the required concrete View Type, then select it to configure its fields.
4. In the **Active** column, select the View Type that should start active.
5. When both first-person and third-person View Types are present, choose **First Person View Type** and **Third Person View Type**, then enable **Can Change Perspectives** only when the player should switch between them.
6. Configure horizontal and vertical look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/), then test the camera with the paired [Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/).

![Camera Controller Inspector showing the View Types list, active selection, and View Type settings](https://opsive.com/wp-content/uploads/2018/03/CameraControllerViewType.png?v=aa00a146a75e)

Use [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) when the camera has not been created yet. It can configure the initial perspective and View Type before this Inspector-level customization.

## Choose first person, third person, or both

- **First person:** Add a first-person View Type when the camera should represent the character's own view. Verify first-person arms, item rendering, field of view, and look input together.
- **Third person:** Add a third-person View Type when the character should remain visible. Choose the orbit, alignment, path, or fixed-angle behavior that matches the movement design.
- **Both perspectives:** Add at least one valid View Type for each perspective, set both default dropdowns, and add **Transition** when the switch should blend instead of snapping. Do not select Transition as the normal active View Type; the Camera Controller activates it while changing between other View Types.

The [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/) section contains the supplied options. Start with an included pairing before creating a custom View Type.

## Choose an included first-person View Type

- [First Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/) contains the common first-person camera, overlay rendering, field-of-view, head-bob, and spring settings inherited by the concrete first-person options.
- [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) is the usual mouse-look or controller-look camera whose yaw follows first-person input.
- [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/) lets the camera look independently of the character; items continue to use their intended facing behavior instead of automatically firing along the camera direction.
- [First Person Transform Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person-transform-look/) follows a specified Transform and is useful for a temporary view such as looking from the character's head after death.

## Choose an included third-person View Type

- [Third Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/) contains the shared orbit, collision, offset, smoothing, field-of-view, zoom, and spring settings inherited by the concrete third-person options.
- [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) supports a freely rotating camera within configured yaw limits.
- [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) keeps the character's forward direction aligned with the camera's local yaw.
- [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) normally follows behind the character and allows free yaw while its camera-free-movement input is held.
- [Pseudo3D (2.5D)](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/) presents the character from the side and can follow the path used by the paired Pseudo3D Movement Type.
- [Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/) keeps the character in a top-down composition.
- [Third Person Look At](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-look-at/) points toward a target, or toward the character when no target is assigned, for views such as a death camera.

## Configure transitions between View Types

[Transition](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/transition/) blends between the outgoing and incoming View Types. Configure its first-to-third, third-to-first, and third-to-third durations according to the transitions the game uses. A duration of `0` changes immediately.

Test a transition with the character standing, moving, aiming, and holding an item. The camera should preserve a sensible pitch, yaw, and character-facing direction throughout the blend.

## Verify in Play Mode

1. Confirm that the intended row is selected in the **Active** column before entering Play Mode.
2. Move the horizontal and vertical look controls. The active View Type should rotate and position the camera without losing its character assignment.
3. Move, stop, turn, jump, and aim. Character facing, item direction, and camera look direction should match the selected View Type and paired Movement Type.
4. Test close walls, corners, slopes, and moving platforms. Confirm that collision, obstruction, offset, and smoothing settings do not produce clipping or sudden jumps.
5. For first person, verify the arms and visible items at the near clip boundary and during field-of-view changes.
6. For both perspectives, switch in both directions and confirm that the selected first-person and third-person defaults activate, the transition completes, and input still controls the new view.
7. For Pseudo3D, Top Down, Look At, or Transform Look, exercise the specific path or target behavior rather than testing only ordinary movement.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Look input does not affect the camera. | Horizontal or vertical look mappings may be missing, or the wrong Player Input implementation may be active. | Verify [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) and watch its look values in Play Mode. |
| The character faces a different direction from the camera design. | The View Type and Movement Type may not be a recommended pair. | Select the matching Movement Type, then retest movement, aim, and item use. |
| Perspective switching does nothing. | A first-person or third-person default may be missing, or **Can Change Perspectives** may be disabled. | Add a concrete View Type for each perspective, set both dropdowns, and enable switching. |
| A View Type is shown as **Unknown View Type**. | Its class may no longer compile or its defining package or integration may be missing. | Restore the dependency or resolve compiler errors, then remove and re-add the resolved View Type if needed. |
| `SetViewType` logs that it cannot find the type. | The requested type is not in the Camera Controller's **View Types** list. | Add that View Type in the Inspector before selecting it from code. |
| The camera clips or snaps around obstacles. | Collision radius, offsets, smoothing, or the chosen special-purpose View Type may not match the scene. | Tune the active View Type in the problem location and retest at normal gameplay speed. |

## Retrieve a View Type in code

`GetViewType<T>` returns a View Type already added to the Camera Controller. `ActiveViewType` returns the currently active instance.

```csharp
using UnityEngine;
using Opsive.Shared.Camera;
using Opsive.UltimateCharacterController.Camera;

public class MyObject : MonoBehaviour
{
    /// <summary>
    /// Retrieves the first-person Combat View Type.
    /// </summary>
    private void Start()
    {
        var camera = CameraUtility.FindCamera(null);
        if (camera == null) {
            return;
        }

        var cameraController = camera.GetComponent<CameraController>();
        var combatViewType = cameraController.GetViewType<Opsive.UltimateCharacterController.FirstPersonController.Camera.ViewTypes.Combat>();
        if (combatViewType != null) {
            Debug.Log("Found the Combat View Type.");
        }
    }
}
```

## Create a custom View Type

Create a custom View Type only when none of the included options or supported integrations provide the required behavior. A concrete `ViewType` must identify its perspective and current rotation state, rotate and move the camera, and return the look direction used by character and item systems.

The current required members are:

```csharp
public abstract bool FirstPersonPerspective { get; }
public abstract float Pitch { get; }
public abstract float Yaw { get; }
public abstract Quaternion BaseCharacterRotation { get; }
public abstract float LookDirectionDistance { get; }

public abstract Quaternion Rotate(float horizontalMovement, float verticalMovement, bool immediateUpdate);
public abstract Vector3 Move(bool immediateUpdate);
public abstract Vector3 LookDirection(
    Vector3 lookPosition,
    bool characterLookDirection,
    int layerMask,
    bool includeRecoil,
    bool includeMovementSpread);
```

This stationary third-person example keeps the camera at its current Transform while reporting the character's forward direction for gameplay look queries:

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Camera.ViewTypes;

[System.Serializable]
public class MyViewType : ViewType
{
    private float m_Pitch;
    private float m_Yaw;
    private Quaternion m_BaseCharacterRotation;

    public override bool FirstPersonPerspective => false;
    public override float Pitch => m_Pitch;
    public override float Yaw => m_Yaw;
    public override Quaternion BaseCharacterRotation => m_BaseCharacterRotation;
    public override float LookDirectionDistance => 100;

    public override void ChangeViewType(bool activate, float pitch, float yaw, Quaternion baseCharacterRotation)
    {
        base.ChangeViewType(activate, pitch, yaw, baseCharacterRotation);

        if (activate) {
            m_Pitch = pitch;
            m_Yaw = yaw;
            m_BaseCharacterRotation = baseCharacterRotation;
        }
    }

    public override Quaternion Rotate(float horizontalMovement, float verticalMovement, bool immediateUpdate)
    {
        return m_Transform.rotation;
    }

    public override Vector3 Move(bool immediateUpdate)
    {
        return m_Transform.position;
    }

    public override Vector3 LookDirection(Vector3 lookPosition, bool characterLookDirection, int layerMask, bool includeRecoil, bool includeMovementSpread)
    {
        return CharacterRotation * Vector3.forward;
    }
}
```

After the class compiles, add it through the Camera Controller's **View Types** list and verify it with the same Play Mode checks as an included View Type.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types"></a>

# Included View Types

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)

Ultimate Character Controller includes camera View Types for common first-person, third-person, fixed-target, side-view, and top-down designs. Choose the camera behavior together with its recommended character Movement Type, then compare the result in Play Mode before tuning offsets, collision, field of view, or smoothing.

The **First Person** and **Third Person** entries below document settings shared by their families. They are abstract bases, so add one of their concrete options, such as first-person Combat or third-person Adventure, to the Camera Controller.

## Add and select an option

1. Select the camera with the **Camera Controller** component.
2. Expand **View Types** in the Inspector.
3. Use the add control under the **View Types** list and select a concrete View Type.
4. Select its row to configure the option, then select its radio button in the **Active** column when it should start active.
5. When both perspectives are installed, set **First Person View Type** and **Third Person View Type** to the desired defaults. Enable **Can Change Perspectives** only when the player should switch between them.
6. On the character, select a recommended [Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/), then verify the pair in Play Mode.

See [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/) for the full Camera Controller workflow and [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) for horizontal and vertical look controls.

## Choose a first-person option

[First Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/) explains the camera, first-person object rendering, field-of-view, head-bob, and spring settings shared by the concrete first-person options.

| Scenario | Choose | Pair with | What to compare in Play Mode |
| --- | --- | --- | --- |
| A conventional first-person game where look input controls camera yaw | [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) | First Person Combat Movement Type | Turn, move, aim, and use an item; camera direction and character/item behavior should stay coordinated. |
| The camera can look independently while the character or weapon keeps its own facing | [Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/) | First Person Free Look Movement Type | Rotate the camera away from the character's forward direction and verify movement and item direction deliberately remain independent. |
| A temporary camera should follow a specified Transform, such as the character's head after death | [First Person Transform Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person-transform-look/) | A project-specific state or ability transition | Enter and leave the special view and confirm the camera follows the assigned Transform without a jump when the normal View Type returns. |

For every first-person option, also inspect near-wall item clipping, first-person arms, overlay rendering, field-of-view changes, and head motion.

## Choose a third-person option

[Third Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/) explains the orbit, collision, offset, smoothing, field-of-view, zoom, and spring settings shared by the orbit-based third-person options.

| Scenario | Choose | Pair with | What to compare in Play Mode |
| --- | --- | --- | --- |
| Exploration with a camera that can orbit within yaw limits | [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) | Adventure Movement Type | Orbit while moving and stopping; confirm the character does not inherit camera yaw unless the design calls for it. |
| Over-the-shoulder or action combat where the character faces with the camera | [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) | Combat Movement Type | Move, strafe, aim, and attack; character forward and camera local yaw should remain aligned. |
| An RPG camera that follows behind but allows temporary free yaw | [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) | RPG Movement Type | Hold and release the configured camera-free-movement input; verify free yaw and the return behind the character. |
| A side-view or 2.5D game, optionally following a path | [Third Person Pseudo3D (2.5D)](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/) | Pseudo3D Movement Type | Traverse bends and path changes; confirm the camera stays on the intended side and follows the referenced path. |
| An overhead game with Top Down, Four Legged, or Point Click movement | [Third Person Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/) | Top Down, Four Legged, or Point Click Movement Type | Move beneath foreground geometry and around scene edges; verify framing, look direction, and obstruction behavior. |
| A camera should continuously frame a target, such as a death or ragdoll view | [Third Person Look At](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-look-at/) | A project-specific state or ability transition | Assign and remove the target, then verify the fallback view toward the character and the transition back to gameplay. |

## Blend between options

[Transition](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/transition/) blends from one View Type to another. Add it when first-to-third, third-to-first, or third-to-third changes should take time. A duration of `0` changes immediately.

Do not select Transition as the normal active option. The Camera Controller activates it while moving between the outgoing and incoming View Types.

## Compare options in Play Mode

Keep the character, input, scene, and test route unchanged while comparing View Types. This makes differences in camera behavior easier to identify.

1. Start with idle, forward movement, strafing, turning, jumping, and stopping. Confirm that character rotation matches the intended camera relationship.
2. Aim and use at least one item. Confirm that gameplay look direction matches what the camera composition communicates to the player.
3. Walk toward walls, pass behind foreground objects, and move through corners. Compare clipping, collision radius, obstruction recovery, and position smoothing.
4. Test minimum and maximum pitch or yaw, then release the look input. Confirm that the camera settles where the option's design expects.
5. Start and stop zoom and compare field-of-view or distance changes without changing the character's facing unexpectedly.
6. Exercise the option-specific dependency: free-look input, an assigned Transform or target, a Pseudo3D path, or a perspective transition.
7. Repeat at gameplay speed. A camera that looks correct while stationary may still feel wrong during rapid input, item use, or state changes.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **First Person** or **Third Person** cannot be added directly. | These entries are abstract base types. | Add a concrete option from the corresponding table and use the base page only for shared settings. |
| A supplied option is missing from the add menu. | Its first- or third-person controller may not be installed, or the project may have compiler errors. | Install the required perspective and resolve compilation before reopening the add menu. |
| The character rotates differently from the camera design. | The selected Movement Type may not be recommended for that View Type. | Choose the pairing in the comparison table, then retest movement, aim, and item use. |
| Look input does not move an orbit or first-person camera. | Player Input mappings or cursor state may be incorrect. | Verify the horizontal and vertical look setup in [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/). |
| Perspective switching uses the wrong camera or does nothing. | The first-person or third-person default is missing, or **Can Change Perspectives** is disabled. | Set both dropdowns to concrete View Types and enable switching. |
| Look At, Transform Look, or Pseudo3D does not frame the expected subject. | Its target, Transform, or path dependency may be empty or inactive. | Assign the required reference and test both entry into and exit from the special View Type. |
| A transition snaps or takes too long. | The corresponding Transition duration may be `0` or unsuitable for the action. | Tune the relevant direction while testing standing, movement, aim, and equipped items. |

## Developer note

The package marks the shared `FirstPerson` and `ThirdPerson` classes as abstract and exposes the scenario-specific classes as serializable View Types. Recommended Movement Type attributes provide the intended pairings shown above. When no included option or supported integration matches the design, follow [Create a custom View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/#create-a-custom-view-type) after the gameplay requirements are defined.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-first-person"></a>

# First Person

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)

First Person is the shared baseline for Ultimate Character Controller's normal first-person camera options. It supplies rendering, field-of-view, spring, bob, pitch-limit, and head-tracking behavior; the selectable [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) and [Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/) View Types decide how yaw and character facing behave.

The First Person base is abstract and does not appear as a selectable camera option. Use this page to configure the fields inherited by Combat and Free Look.

## Choose Combat or Free Look

| Scenario | Choose | Pair with | Expected relationship |
| --- | --- | --- | --- |
| A conventional first-person game where look input turns the view and character together | [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) | [First Person Combat Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/) | Camera yaw, character facing, aiming, and item use remain coordinated. |
| The camera can look independently while the character or weapon keeps its own facing | [Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/) | [First Person Free Look Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/) | Camera yaw can separate from character and item direction within the configured yaw limits. |

For a Transform-driven special view rather than normal player look input, return to the [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/) catalog.

## Set up the Camera Controller

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **First Person Combat** or **First Person Free Look**.
3. Select the new row to show its inherited First Person settings.
4. Select its radio button in the **Active** column. When the camera also has third-person View Types, choose it in **First Person View Type** and enable **Can Change Perspectives** only when switching is allowed.
5. On the character, select the matching first-person Movement Type.
6. Configure horizontal and vertical look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).
7. Choose **Object Overlay Render Type** for the project's render path, then verify arms and items near a wall before tuning camera motion.

## Choose how first-person objects render

Hands and items rendered by the same camera as the scene can intersect nearby geometry:

![First-person arms and an assault rifle clipping through a nearby wall](https://opsive.com/wp-content/uploads/2018/04/ItemClipping.png?v=2590bcc6e7fa)

Separating first-person objects from scene rendering prevents that visual overlap:

![First-person arms and an assault rifle rendered without wall clipping](https://opsive.com/wp-content/uploads/2018/04/ItemNotClipping.png?v=bccf617c6b71)

Choose **Object Overlay Render Type** by scenario:

| Choice | Use it when | Important checks |
| --- | --- | --- |
| **Second Camera** | A child camera should render only first-person objects. Selecting this mode adds the first-person camera when it does not already exist. | Verify **First Person Camera**, both culling masks, field of view, and the child camera's position and rotation offsets. |
| **Render Pipeline** | URP or HDRP should render first-person overlay objects through the active render-pipeline integration. | Verify **First Person Culling Mask** and the imported render-pipeline integration in [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/). |
| **None** | Arms and items should share normal scene depth and are intentionally allowed to intersect scene geometry. | Test every close interaction and item animation because the overlay no longer prevents clipping. |

With **Second Camera**, enable **Synchronize Field Of View** when the child camera should follow the main camera's field of view. Otherwise, tune **First Person Field Of View** and **First Person Field Of View Damping** separately. **First Person Position Offset** and **First Person Rotation Offset** place the child camera relative to the main camera.

## Configure framing and head tracking

- **Look Offset** positions the view relative to the character anchor; **Look Down Offset** moves it while looking down so the camera does not enter the body.
- **Culling Mask** controls what the main camera renders. Keep it consistent with the first-person overlay choice.
- **Field Of View** and **Field Of View Damping** control the main camera's framing and transition speed.
- **Position Lower Vertical Limit** prevents the view from moving too far into the character.
- **Pitch Limit** sets the minimum and maximum vertical look angles; **Look Direction Distance** limits gameplay look queries.
- **Smooth Head Offset Steps** averages recent humanoid head offsets. Set it to `0` to disable head-position tracking.
- **Rotate With Head** includes animated head rotation. **Vertical Offset Lerp Speed** smooths vertical movement when the character does not have a head bone.
- **Collision Radius** helps keep the camera from clipping scene geometry.

Use fewer **Smooth Head Offset Steps** for a more responsive view and more steps for a smoother result. Test crouching, height changes, steep look angles, and strongly animated head motion rather than judging this setting while the character is idle.

## Configure camera motion

Tune these groups after rendering and head tracking work:

- **Primary Spring:** Position Spring and Rotation Spring handle regular responsive motion. Position and rotation fall-impact values react to landings, while **Rotation Strafe Roll** leans with sideways velocity. **Secondary Rotation Speed** smooths override or gravity-alignment rotation.
- **Secondary Spring:** Secondary Position Spring and Secondary Rotation Spring return short forces such as recoil toward equilibrium.
- **Bob:** Positional and roll rates set frequency; amplitudes set strength. Input velocity scale and maximum input velocity keep speed changes controlled. Trough offset and force add a reaction at the low point. **Bob Require Ground Contact** prevents normal bob while airborne.
- **Shake:** **Shake Speed** and **Shake Amplitude** add continuous rotational variation.

See [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) for stiffness, damping, and force behavior. Minimize springs, bob, and shake first, then enable one source at a time so authored animation and head tracking are not mistaken for procedural motion.

## Configure Free Look limits

Free Look adds these choices to the shared First Person settings:

- **Yaw Limit** sets the allowed horizontal range.
- **Yaw Limit Lerp Speed** controls how quickly the camera returns inside that range.
- **Rotate With Character** determines whether character rotation also rotates the independent view.

Test Free Look at both yaw limits while moving, aiming, using an item, and rotating the character. The camera's independent direction must not imply an item direction that the gameplay does not use.

## Verify in Play Mode

1. Look through the full pitch range, crouch, stand, jump, and land. The camera should stay outside the character mesh and settle after head or fall motion.
2. Walk into a wall with a first-person item equipped. With **Second Camera** or **Render Pipeline**, the arms and item should remain visible without being cut by the wall.
3. Change field of view or zoom. The main and first-person object rendering should stay visually aligned for the selected synchronization choice.
4. Move at slow and fast speeds, strafe, jump, and land. Bob, roll, fall impact, and springs should remain controlled and return toward rest.
5. In Combat, turn and use an item; camera, character, and item direction should agree.
6. In Free Look, rotate away from character forward and verify the yaw limits, return speed, movement, and item direction.
7. If both perspectives are present, switch to third person and back. The configured first-person default, overlay rendering, pitch, and field of view should restore correctly.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **First Person** cannot be added from the View Type menu. | First Person is an abstract family, not a concrete option. | Add Combat or Free Look and use this page for their inherited settings. |
| Arms or items clip through walls. | **Object Overlay Render Type** may be **None** or its render setup may be incomplete. | Choose **Second Camera** or **Render Pipeline**, then verify culling masks and the active pipeline integration. |
| Arms or items disappear. | The main and first-person culling masks may exclude the wrong layers. | Compare **Culling Mask** with **First Person Culling Mask** and verify which camera renders the overlay layer. |
| Main and first-person object framing do not match during zoom. | Field-of-view synchronization or damping may differ. | Enable **Synchronize Field Of View**, or deliberately match the two field-of-view values and damping. |
| The camera enters the head or body. | Head tracking, look-down offset, lower vertical limit, or collision radius may not fit the model. | Tune those fields while crouching and looking through the full pitch range. |
| Motion feels noisy or causes discomfort. | Head tracking, authored animation, springs, bob, and shake may all contribute at once. | Minimize procedural groups, establish a stable baseline, then restore one source at a time. |
| Free Look points beyond its intended range. | **Yaw Limit** or **Yaw Limit Lerp Speed** may be unsuitable. | Tune the range and return speed while testing movement and character rotation. |

## Developer note

The package defines `FirstPerson` as an abstract `ViewType`. Combat and Free Look derive from it and inherit the rendering, spring, bob, limit, and head-tracking fields described above. Selecting **Second Camera** invokes the editor builder that creates the child first-person camera when needed; changing to **Render Pipeline** or **None** removes that child-camera setup from the View Type.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-first-person-combat"></a>

# Combat

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/)

Choose the first-person Combat View Type for a conventional first-person camera where look input turns the camera and the character faces the same direction. Pair it with the First Person Combat Movement Type so forward, backward, and strafe input remain relative to the camera.

Combat is appropriate for first-person shooters, melee games, and interactions where the visible reticle, character facing, and item-use direction should agree. Use [Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/) instead when the camera must look independently of the character or weapon.

## Set up the camera and character

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **First Person Combat**.
3. Select its radio button in the **Active** column. When the camera also has third-person View Types, select Combat in **First Person View Type**.
4. Select the character and open **Ultimate Character Locomotion > Movement Types**.
5. Add **First Person Combat** if it is not already present, select its radio button in the **Active** column, and choose it in **First Person Movement Type** when both perspectives are available.
6. Configure horizontal and vertical look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).
7. Enter Play Mode and compare look, facing, strafing, aiming, and item use before tuning inherited camera motion.

The [First Person Combat Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/) leaves the input vector unchanged: forward moves forward, left and right strafe, and backward moves backward. Its rotation follows the Camera Controller's gameplay look direction.

## Choose settings by gameplay scenario

Combat does not add its own serialized Inspector fields. Configure the settings inherited from the [First Person family](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/):

| Scenario | Focus on | Expected result |
| --- | --- | --- |
| Fast mouse-look or controller-look combat | Input sensitivity and smoothing, **Pitch Limit**, and the character's rotation speed | The camera responds quickly while the character remains aligned with its horizontal look direction. |
| A reticle or weapon should indicate the true gameplay direction | **Look Direction Distance**, camera anchor and offsets, and item aim setup | The reticle, character facing, and item use point toward the same intended target. |
| Weapons and hands must remain visible near walls | **Object Overlay Render Type**, culling masks, and first-person field-of-view settings | First-person objects remain visible without being cut by nearby scene geometry. |
| Crouching, height changes, or animated head motion | **Smooth Head Offset Steps**, **Look Down Offset**, **Position Lower Vertical Limit**, and **Collision Radius** | The view follows the character without entering the head or body mesh. |
| Recoil, landing, and movement should affect the view | Primary and Secondary Springs, Bob, Shake, fall-impact, and strafe-roll settings | Motion reacts to gameplay and returns toward rest without obscuring aim. |
| Zoom changes the combat framing | **Can Zoom** and **Zoom State** on Camera Controller plus inherited field-of-view settings | Zoom starts and stops without changing the character's facing or leaving mismatched first-person object framing. |

Tune from a stable baseline. Minimize spring, bob, shake, and head-rotation contributions first; establish look and aim behavior; then restore each motion source one at a time.

## How Combat behaves in Play Mode

- Horizontal look input changes camera yaw, and the matching Movement Type rotates the character toward the Camera Controller's look direction.
- Forward and backward movement do not require the character to turn away from the view; left and right input strafe.
- Pitch changes the vertical camera angle without changing the character's horizontal forward direction.
- When root-motion rotation controls the character, Combat follows that character rotation instead of competing with it.
- While the Move Towards ability positions and rotates the character for an interaction, Combat follows the character so the camera does not apply a conflicting yaw.

## Compare with sibling options

| Option | Camera and character relationship | Choose it when |
| --- | --- | --- |
| **Combat** | Camera yaw and character facing remain coordinated. | Reticle, movement, aim, and item use should feel like a conventional first-person game. |
| [Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/) | Camera yaw can move within limits independently of character and item facing. | Looking around should not automatically turn the character or redirect the weapon. |

For a camera driven by a Transform during a special state, such as a death view, choose [First Person Transform Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person-transform-look/) from the broader catalog rather than replacing the normal Combat camera.

## Verify in Play Mode

1. Move the look input through the full pitch range and a complete horizontal turn. Camera yaw should remain aligned with character forward while pitch stays camera-only.
2. Hold forward, backward, left, and right in turn. The character should move relative to the camera, with left and right producing strafing rather than a turn toward the travel direction.
3. Aim and use each relevant item at close and distant targets. Reticle, projectile or hit direction, and character facing should communicate the same target.
4. Trigger an interaction that uses Move Towards. The character may rotate into position, and the camera should follow without a yaw snap or input fight.
5. Test an animation or ability that uses root-motion rotation. Camera orientation should follow the character until normal look control resumes.
6. Start and stop zoom, jump and land, crouch and stand, and approach a wall. Framing, first-person object rendering, and inherited camera motion should remain controlled.
7. If the game supports both perspectives, switch away and back. Combat and First Person Combat should return as the active first-person View Type and Movement Type.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The camera turns but the character does not face with it. | First Person Combat may not be the active Movement Type. | Add and select First Person Combat under **Movement Types**, then set **First Person Movement Type**. |
| Left or right input turns toward the travel direction instead of strafing. | The character may be using a non-Combat Movement Type. | Activate the matching First Person Combat Movement Type and retest all four movement directions. |
| The reticle and item-use direction disagree. | The active camera, character look source, item aim setup, or paired Movement Type may not match. | Confirm Combat is active on both camera and character, then verify the item without procedural recoil before restoring effects. |
| The camera snaps when an interaction starts or ends. | A custom positioning ability may rotate the character differently from Move Towards. | Compare the behavior with the built-in Move Towards path and ensure the custom ability and camera do not both force conflicting yaw. |
| Look input does not rotate the camera. | Player Input mappings, cursor state, or the active View Type may be incorrect. | Verify [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) and confirm Combat is selected in the **Active** column. |
| Arms, items, or the body clip into the view. | The inherited overlay, head tracking, offsets, or collision settings may not fit the character. | Follow the rendering and head-tracking checks on [First Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/). |

## Related pages

- [First Person family settings](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [First Person Combat Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-combat/)
- [Free Look View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)

## Developer details

`Combat` is a serializable `FirstPerson` View Type with a recommended First Person Combat Movement Type and the default `Zoom` state. It adds no serialized settings of its own.

During normal look input, `Rotate` accumulates horizontal yaw before applying the inherited First Person rotation. If Ultimate Character Locomotion is using root-motion rotation, Combat bases the view on the character rotation instead. It also listens for `OnCharacterAbilityActive`; while the built-in `MoveTowards` ability is active, it clears local yaw and follows the character's rotation until that positioning step ends.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-first-person-free-look"></a>

# Free Look

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/)

Choose the first-person Free Look View Type when the player should look around without automatically rotating the character or redirecting the character's item. Pair it with the First Person Free Look Movement Type so movement and character rotation remain independent of camera yaw.

Free Look works well for observation, body-aware interaction, mounted movement, and games where the weapon or character keeps its own forward direction while the player glances elsewhere. Use [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) when the camera, character facing, reticle, and item-use direction should stay aligned like a conventional first-person game.

## Set up the camera and character

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **First Person Free Look**.
3. Select its radio button in the **Active** column. When the camera also has third-person View Types, select Free Look in **First Person View Type**.
4. Select the character and open **Ultimate Character Locomotion > Movement Types**.
5. Add **First Person Free Look** if it is not already present, select its radio button in the **Active** column, and choose it in **First Person Movement Type** when both perspectives are available.
6. Configure horizontal and vertical look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).
7. Enter Play Mode and compare camera yaw, character facing, movement, aiming, and item direction before tuning inherited camera motion.

The [First Person Free Look Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/) leaves the movement input vector unchanged and reports that the character can look independently of its Transform rotation.

## Configure yaw limits and correction

- **Yaw Limit** sets the minimum and maximum camera yaw relative to the current base rotation. A range narrower than 360 degrees constrains the view; a full 360-degree range allows unrestricted yaw.
- **Yaw Limit Lerp Speed** controls how quickly the camera is corrected toward the nearest valid limit when input would move it out of range.
- **Base Rotation Type** determines what rotates the frame used by the yaw limits.

**Yaw Limit Lerp Speed** does not automatically recenter the view to zero. It corrects an out-of-range yaw back to the configured boundary. Character-relative recentering comes from the selected base rotation, while aim-relative character alignment is controlled separately by the Movement Type.

## Choose a base rotation by scenario

| Base Rotation Type | Use it when | Observable result |
| --- | --- | --- |
| **None** | The permitted look arc should remain in its current world-relative orientation. | Character or platform rotation does not rotate the camera's yaw baseline. |
| **Rotate With Character** | The player should keep the same relative glance direction as the character turns. | Character rotation moves the yaw baseline while the camera retains its local Free Look offset. |
| **Rotate With Moving Platform** | The view should stay relative to a platform while the character stands on it. | Platform rotation moves the camera baseline; off the platform, the previous base remains until another change affects it. |

Use a narrow **Yaw Limit** for a head-turn or glance mechanic. Use a wide or full range for free observation. Increase **Yaw Limit Lerp Speed** for a firmer boundary and reduce it for a softer correction, then test rapid input at both ends of the range.

## Choose aiming behavior

The matching First Person Free Look Movement Type adds **Rotate With Camera On Aim**:

- Leave it disabled when aiming should preserve the character's independent forward direction.
- Enable it when input-started Aim should rotate the character toward the Camera Controller's gameplay look direction.

This option changes the character only while the Aim ability is active from player input. It does not turn ordinary look input into Combat behavior.

Free Look item direction is based on the first-person objects when they exist, or the Camera Controller anchor otherwise, rather than automatically using the freely rotated camera Transform. Test the actual item, reticle, and animation together; the visible camera can point somewhere different from the item's forward direction by design.

## Configure inherited first-person settings

Free Look inherits its overlay rendering, field-of-view, springs, bob, shake, pitch limits, and head tracking from [First Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/).

| Scenario | Inherited settings to check |
| --- | --- |
| Arms and items must stay visible near walls | **Object Overlay Render Type**, culling masks, and first-person field of view |
| Crouching or animated head motion changes the camera height | **Smooth Head Offset Steps**, **Look Down Offset**, **Position Lower Vertical Limit**, and **Collision Radius** |
| Movement, landing, or recoil should affect the view | Primary and Secondary Springs, Bob, Shake, fall impact, and strafe roll |
| Pitch should remain comfortable while yaw is independent | **Pitch Limit**, head rotation, and camera offsets |

Establish independent yaw and item direction with procedural motion minimized. Restore springs, bob, shake, and head rotation one at a time after the gameplay relationship is correct.

## Compare with Combat

| Option | Camera relationship | Character rotation | Item and gameplay look |
| --- | --- | --- | --- |
| **Free Look** | Camera yaw can move independently within its limits. | Ordinary look input does not rotate the character; optional Aim alignment can do so. | Uses the first-person object or anchor direction, so it may differ from camera forward. |
| [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) | Camera yaw and character facing stay coordinated. | The matching Combat Movement Type rotates the character toward camera look. | Reticle, facing, and item-use direction are intended to agree. |

If a player expects every centered reticle action to follow camera forward, Combat is usually the clearer choice. If looking and acting in different directions is intentional, communicate both directions through the reticle, item pose, or other game feedback.

## Verify in Play Mode

1. Stand still and rotate to both yaw limits. The camera should stop or ease back at each boundary without rotating the character.
2. Move forward, backward, left, and right while looking to the side. Movement should remain relative to the character's orientation rather than the freely rotated camera.
3. Set **Base Rotation Type** to each mode the project uses, then rotate the character or a moving platform. Confirm that only the selected source rotates the yaw baseline.
4. Aim with **Rotate With Camera On Aim** disabled and enabled. Confirm that input-started Aim aligns the character only in the enabled case.
5. Equip and use each relevant item while looking away from its facing direction. Confirm that project feedback communicates the actual item-use direction.
6. Look through the full pitch range, crouch, jump, land, zoom, and approach a wall. Inherited rendering, head tracking, and camera motion should remain controlled.
7. If both perspectives are present, switch away and back. Free Look, its local yaw, and the configured first-person Movement Type should resume without an unexpected snap.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character turns whenever the camera turns. | Combat may be active, or **Rotate With Camera On Aim** may be enabled during Aim. | Activate Free Look on both camera and character; disable the Aim option when alignment is not wanted. |
| The camera rotates beyond the intended arc. | **Yaw Limit** may span 360 degrees or use the wrong minimum and maximum. | Set the intended range, then test both boundaries with rapid input. |
| The camera hits a yaw boundary too sharply or too slowly. | **Yaw Limit Lerp Speed** controls boundary correction. | Tune the speed at both limits; do not expect it to recenter to zero. |
| Character rotation unexpectedly changes the camera's look arc. | **Base Rotation Type** may be **Rotate With Character**. | Choose **None** for a world-relative base or the platform mode for platform-relative behavior. |
| A rotating platform leaves the camera behind. | The base may not follow the moving platform. | Choose **Rotate With Moving Platform** and verify the character is detected on that platform. |
| The item fires somewhere other than camera center. | Free Look intentionally separates camera forward from item or anchor direction. | Use Combat when camera-centered firing is required, or adjust the project's reticle and feedback to show the true direction. |
| Look input does not rotate the camera. | Player Input mappings, cursor state, or the active View Type may be incorrect. | Verify [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) and confirm Free Look is selected in the **Active** column. |
| Arms, items, or the body clip into the view. | Inherited overlay, head tracking, offsets, or collision settings may not fit the character. | Follow the rendering and head-tracking checks on [First Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/). |

## Related pages

- [First Person family settings](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [First Person Free Look Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/first-person-free-look/)
- [Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)

## Developer details

`FreeLook` is a serializable `FirstPerson` View Type with a recommended First Person Free Look Movement Type and the default `Zoom` state. The current API uses `BaseRotationType` with `None`, `RotateWithCharacter`, and `RotateWithMovingPlatform`; the old `RotateWithCharacter` Boolean is obsolete.

When Free Look activates, `ChangeViewType` calculates yaw relative to the character so switching into the option preserves the current view. `Rotate` constrains yaw only when the configured span is less than 360 degrees, then updates the base from the character or moving platform when requested. `LookDirection` raycasts along the first-person object rotation, falling back to the Camera Controller anchor when no first-person objects exist.

The paired Movement Type returns independent look behavior and listens for input-started Aim. With **Rotate With Camera On Aim** enabled, it rotates the character toward the Camera Controller look direction only while that Aim state is active.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-first-person-transform-look"></a>

# First Person Transform Look

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person-transform-look/)

Use First Person Transform Look when a special first-person camera should follow the position and rotation of scene Transforms, such as a view attached to the character's head after death. It is intended for a transform-driven view, not ordinary first-person movement and aiming.

Unlike [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) and [Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/), Transform Look does not have a matching Movement Type. Keep the first-person Movement Type required by the rest of the game and let the gameplay state or ability decide whether the character can move or act while this camera is active.

## Set up Transform Look

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **First Person Transform Look**.
3. Select the new row to show its settings.
4. Assign **Move Target** to the Transform that should position the camera and **Rotation Target** to the Transform whose orientation the camera should follow. When the camera is already attached to a humanoid character, adding the View Type assigns the head as the move target and the hips as the rotation target automatically. Confirm both references instead of assuming they were found.
5. Set **Offset** in the Move Target's local space, then tune **Collision Radius**, **Position Smoothing**, and **Rotational Lerp Speed** while the target moves.
6. Enable **Restrict Pitch** and **Restrict Yaw** when the camera should follow the Rotation Target without player look offsets. Disable an axis only when look input should adjust that axis.
7. For a temporary view, keep Combat or Free Look selected in the **Active** column and as **First Person View Type** for normal play. Have the project's death, cutscene, or other special flow activate Transform Look and restore the normal View Type afterward. Select Transform Look as active only when it should be the starting camera.
8. On the character, keep a valid option selected under **Ultimate Character Locomotion > Movement Types** and in **First Person Movement Type**. Transform Look does not stop locomotion, aiming, or item use by itself.

See [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/) for the shared Camera Controller workflow and [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) for horizontal and vertical look mappings.

## Choose the target Transforms

| Scenario | Move Target | Rotation Target | Result |
| --- | --- | --- | --- |
| Follow a humanoid after death | Head | Hips | The camera inherits animated head position while using the more stable body orientation. |
| Follow a vehicle seat or mounted viewpoint | A seat or camera socket | A stable vehicle or mount Transform | The camera follows the seat's local position while its base direction follows the mount. |
| Follow a scripted prop or rig | A dedicated position Transform | A dedicated orientation Transform | Animation can control position and orientation independently. |

**Offset** is transformed by **Move Target**, so the same values produce different world positions when the target rotates. Use a target with intentional local axes and test the full animation. The **Rotation Target** supplies its complete rotation, including roll, so use a stable Transform when animated tilt should not reach the camera.

If either target is missing when the character is attached, Transform Look tries to populate both. It uses the humanoid head and hips when available; otherwise it falls back to the character Transform. Assign both fields explicitly for a non-humanoid rig or a viewpoint that should not use those defaults.

## Choose rotation and look input

| Desired behavior | Restrict Pitch | Restrict Yaw | Additional choice |
| --- | --- | --- | --- |
| The target controls the entire view | Enabled | Enabled | Player look input adds no pitch or yaw offset. |
| The target controls facing but the player can look up and down | Disabled | Enabled | Set **Pitch Limit** to the permitted vertical range. |
| The target supplies a base orientation while the player looks around | Disabled | Disabled | Set **Pitch Limit**; yaw remains unrestricted. |

When **Restrict Pitch** is disabled, **Pitch Limit** clamps the player-controlled pitch if its span is less than 180 degrees. A full 180-degree span permits unrestricted pitch. Transform Look has no yaw-limit field: disabling **Restrict Yaw** permits unrestricted player-controlled yaw around the Rotation Target.

When the View Type activates or its rotation is reset, each restricted axis starts at zero relative to the Rotation Target. An unrestricted axis receives the incoming pitch or yaw, so only player-controlled axes carry their orientation into Transform Look.

## Tune position, rotation, and collision

- **Position Smoothing** controls how quickly the camera follows the target position after activation. Set it to `0` for no positional smoothing; increase it when animated target motion should be softened.
- **Rotational Lerp Speed** controls how closely the camera follows changes to the Rotation Target. A value of `1` follows the target rotation on each normal update, while lower values add rotational lag.
- **Collision Radius** is the radius of the sphere cast from the Move Target toward the offset camera position. When that path is obstructed, the camera moves inward to avoid clipping.
- **Field Of View** and **Field Of View Damping** come from the View Type base settings. Test them separately from Transform movement so framing changes are easy to identify.

Smoothing affects continued target motion. Switching between Transform Look and another first-person View Type does not use the included perspective Transition because that transition has no first-person-to-first-person mode. Add project-specific transition handling when entering or leaving the view must blend.

## Compare the first-person options

| Option | What drives the camera | Movement Type expectation | Gameplay look direction |
| --- | --- | --- | --- |
| **Transform Look** | Move and Rotation Target Transforms, plus optional player pitch and yaw offsets | No dedicated pairing; the current first-person Movement Type remains responsible for character movement | Character forward, even when the Rotation Target or player offset points the camera elsewhere |
| [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/) | Standard first-person look input and inherited camera motion | First Person Combat | Camera, character facing, reticle, and item direction are intended to stay coordinated |
| [Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/) | Independent camera input within its yaw configuration | First Person Free Look | First-person object or camera-anchor direction, which can differ from the visible camera direction |

Choose Combat for normal camera-centered aiming and Free Look for an input-driven independent view. Choose Transform Look when an animated or scripted Transform should own the composition. Do not assume an equipped item will act along the visible Transform Look camera direction; test or disable gameplay actions during the special view.

## Verify in Play Mode

1. Start with the normal gameplay View Type, trigger the special state, and confirm that First Person Transform Look becomes active only when intended.
2. Move and rotate both targets through their full animation. The camera should follow the Move Target's local offset and the Rotation Target's orientation without using the wrong bone or object.
3. Place a wall between the Move Target origin and the offset position. The camera should move inward instead of clipping through the obstruction, then return as the path clears.
4. Test vertical and horizontal look input with each required restriction enabled and disabled. Restricted axes should follow the target; unrestricted pitch should respect **Pitch Limit**; unrestricted yaw should rotate freely.
5. Move, aim, and use an item if those actions are allowed in this state. The character should follow its existing Movement Type, and gameplay look queries should remain character-forward rather than camera-forward.
6. Repeat with rapid target motion, animated roll, a low ceiling, and close walls. Tune smoothing, target choice, offset, and collision independently.
7. Leave the special state and confirm that the intended normal View Type and first-person Movement Type are restored with working input.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The camera stays at the character origin or reports a missing target. | **Move Target** or **Rotation Target** may be empty, especially on a non-humanoid character. | Assign both Transforms explicitly and retest after the camera attaches to the character. |
| The camera is offset in an unexpected direction. | **Offset** uses the Move Target's local axes. | Inspect the target orientation and tune the local offset while the target is selected. |
| Head animation creates unwanted tilt or roll. | The Rotation Target may be the animated head or another rolling Transform. | Use a more stable Rotation Target, such as the hips or a dedicated orientation Transform. |
| Look input does nothing on one axis. | **Restrict Pitch** or **Restrict Yaw** may be enabled. | Disable only the axis that the player should control; keep the other axis target-driven. |
| Player yaw rotates farther than intended. | Transform Look has no yaw-limit setting when **Restrict Yaw** is disabled. | Enable **Restrict Yaw**, or choose Free Look when a configurable yaw range is required. |
| The camera trails or appears frozen while the target moves. | **Position Smoothing** may be too high, or **Rotational Lerp Speed** may be too low. | Reduce position smoothing or increase rotational lerp speed, then compare fast target motion. |
| The camera pulls inward too early or clips near a wall. | **Collision Radius**, **Offset**, or the target-to-camera path may not fit the space. | Tune the radius and offset in the problem location and verify the target origin is appropriate. |
| A weapon, raycast, or interaction does not follow the visible camera. | Transform Look reports character forward as its gameplay look direction. | Disable those actions for the special state, or use Combat when camera-forward gameplay is required. |
| The character continues moving during a death or cutscene view. | Transform Look does not select or disable a Movement Type. | Make the state or ability that activates the camera also control locomotion and actions. |
| Entering or leaving the view snaps. | The included Transition does not blend between two first-person View Types. | Add project-specific first-person transition handling when a blended switch is required. |

## Related pages

- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)
- [First Person Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/combat/)
- [First Person Free Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/free-look/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)

## Developer details

`TransformLook` is a serializable `ViewType` that reports a first-person perspective. It does not inherit the standard `FirstPerson` View Type and has no `RecommendedMovementType` attribute. On attachment, missing target references are resolved to the humanoid head and hips when possible, or to the character Transform otherwise.

`Move` transforms **Offset** through the Move Target, sphere casts along that offset using **Collision Radius**, and applies `Vector3.SmoothDamp` with **Position Smoothing**. `Rotate` follows the Rotation Target with `Quaternion.Slerp`, then applies the optional pitch and yaw offsets. **Pitch Limit** is enforced only when pitch is unrestricted and the configured range spans less than 180 degrees.

Both `LookDirection` overloads return the Ultimate Character Locomotion rotation multiplied by forward. They do not return the Rotation Target or visible camera forward direction. Runtime selection uses `CameraController.SetViewType(System.Type, bool)`, and the target View Type must already exist in the Camera Controller's **View Types** list.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-third-person"></a>

# Third Person

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)

The Third Person View Type is the shared orbit, framing, collision, zoom, and spring baseline for Adventure, Combat, and RPG cameras. Use this family when the character should remain visible behind or beside the camera, then choose the concrete option that matches how camera yaw and character facing should interact.

**Third Person** is abstract and cannot be added directly to the Camera Controller. Add [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/), [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/), or [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/); each option inherits the shared settings on this page.

## Set up a third-person camera

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **Third Person Adventure**, **Third Person Combat**, or **Third Person RPG**. Do not look for the abstract **Third Person** baseline in the add list.
3. Select the new row to configure it, then select its radio button in the **Active** column. When both perspectives are installed, choose the same option in **Third Person View Type**.
4. On the character, expand **Ultimate Character Locomotion > Movement Types**, add a compatible third-person Movement Type, select it in the **Active** column, and choose it in **Third Person Movement Type** when both perspectives are available.
5. On **Camera Controller**, confirm **Character**, **Anchor**, **Auto Anchor**, **Auto Anchor Bone**, and **Anchor Offset** before tuning the selected View Type's **Look Offset**.
6. Configure horizontal and vertical look controls through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).
7. Enter Play Mode and establish orbit, character-facing, and aiming behavior before adding procedural springs, step zoom, or project-specific camera states.

See [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/) for the complete Camera Controller workflow and [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) for the character side of each pairing.

## Choose Adventure, Combat, or RPG

| Scenario | Concrete View Type | Recommended Movement Type | What to observe |
| --- | --- | --- | --- |
| Exploration needs a camera that can orbit independently within a configured yaw range | [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) | Third Person Adventure or Four Legged | Rotate around a standing and moving character; the camera should keep its permitted yaw without forcing Combat-style facing. |
| Aiming or action gameplay should keep character forward coordinated with camera yaw | [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) | Third Person Combat or Four Legged | Move, strafe, aim, and use an item; character facing and camera-local yaw should remain coordinated. |
| The camera should normally follow behind the character but allow temporary free movement or forced alignment | [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) | Third Person RPG or Four Legged | Move with free movement released, then test **Camera Free Movement Input Name** and **Character Forced Rotation Input Name** when **Allow Free Movement** is enabled. |

Keep the scene, input, character, and test route unchanged while comparing these options. Choose the camera and Movement Type as a pair; changing only one side can make movement direction, character rotation, and aiming disagree.

## Choose another third-person composition

The following supplied View Types are third person but do not inherit this Third Person orbit baseline, so their settings and verification differ:

- [Third Person Pseudo3D (2.5D)](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/) presents a side view and can follow the path used by the Pseudo3D Movement Type.
- [Third Person Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/) provides an overhead composition for Top Down, Point Click, or Four Legged movement.
- [Third Person Look At](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-look-at/) continuously frames a target, or the character when no target is assigned, for a special view such as a death camera.

Use those pages instead of applying the offset, pivot-freedom, or step-zoom guidance below to a camera with a different positioning model.

## Frame the character around the anchor

Configure the Camera Controller's anchor first, then use the concrete View Type's shared framing fields:

| Choice | Use it when | Play Mode check |
| --- | --- | --- |
| **Anchor**, **Auto Anchor**, and **Auto Anchor Bone** | The orbit should originate from the character root, a child Transform, or a humanoid bone. | Animate the character and confirm the anchor does not add unwanted head or body motion. |
| **Anchor Offset** | The entire camera family needs a stable adjustment before View Type framing. | Change the character stance and verify the orbit center remains appropriate. |
| **Look Offset** | The camera needs a shoulder-side, vertical, or behind-character offset. The `x` value moves along camera right, `y` follows character up, and `z` moves along camera forward. | Compare both shoulders, slopes, crouching, and equipped items without moving the anchor. |
| **Look Offset Smoothing** | State-driven offset changes should ease instead of snap. Set it to `0` for no smoothing. | Change every state that modifies the offset and confirm the camera settles quickly enough. |
| **Horizontal Pivot Freedom** | The character may move a limited horizontal distance on screen before the camera follows. | Strafe in both directions and confirm the delayed follow is intentional, not input lag. |

**Forward Axis** rotates the final camera orientation toward a chosen local forward vector. Keep the default unless the project intentionally uses another camera-forward convention. **Look Direction Distance** controls how far gameplay look raycasts search ahead; it does not change the visible camera distance.

## Configure rotation and collision

- **Pitch Limit** is the minimum and maximum vertical look range. A span narrower than 180 degrees constrains pitch; a full 180-degree span allows unrestricted pitch.
- **Rotation Speed** controls how quickly the camera rotation follows its calculated target. Higher values follow more closely; lower values add lag.
- **Secondary Rotation Speed** controls rotational overrides and alignment to the character's gravity direction. Test it on moving platforms or custom gravity when the project uses either feature.
- **Collision Radius** sets the camera obstruction sphere size.
- **Collision Anchor Offset** moves the start of the obstruction check relative to the camera anchor. Use it to keep the cast clear of the character without hiding real wall collisions.

The shared Third Person camera sphere casts from the anchor area toward the desired offset position and moves inward when an obstacle blocks the character. Test this separately from [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/), which handles visibility rather than calculating the orbit position.

## Configure field of view, step zoom, and springs

**Field Of View** and **Field Of View Damping** control the lens angle and how quickly a changed value settles. Camera Controller **Can Zoom** and **Zoom State** govern state-based zoom, which can change field of view or other preset values.

The **Step Zoom** foldout provides a separate distance adjustment:

- **Step Zoom Input Name** selects the axis mapping.
- **Step Zoom Sensitivity** controls how quickly input changes the offset. A value greater than `0` enables the step-zoom input event for the active View Type.
- **Step Zoom Limit** clamps the minimum and maximum amount added to the Look Offset's `z` distance.

Test the mapping direction and both limits with each concrete View Type. Step zoom and state-based zoom solve different problems, so verify them independently.

Use **Primary Spring** for ongoing position and rotation response. Use **Secondary Spring** for forces that return toward equilibrium, such as recoil or a brief camera shake. Follow [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) for stiffness, damping, and force behavior; establish stable framing first, then introduce one spring source at a time.

## Verify in Play Mode

1. Confirm that the intended concrete row and matching Movement Type are active before moving the character.
2. Stand still, orbit through the full pitch and yaw behavior, then walk, strafe, turn, aim, and use an item. Verify the Adventure, Combat, or RPG relationship selected above.
3. Move through doorways, close walls, corners, low ceilings, and foreground objects. The camera should move inward without clipping, losing the character, or remaining stuck after the path clears.
4. Compare shoulder and vertical framing while standing, crouching, jumping, and changing items. **Anchor Offset**, **Look Offset**, and **Horizontal Pivot Freedom** should produce deliberate screen placement.
5. Test ordinary and custom gravity, slopes, and moving platforms if the game uses them. Camera up alignment and rotation smoothing should remain controlled.
6. Exercise state-based zoom and step zoom separately. Confirm field of view, distance, input direction, and limits all return to their expected defaults.
7. Apply recoil or another camera force only after the base view is stable. Primary and Secondary Springs should settle without a permanent offset or repeated oscillation.
8. If both perspectives are installed, switch away and back. The selected **Third Person View Type** and **Third Person Movement Type** should return with working input and framing.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Third Person** is absent from the add menu. | The baseline is abstract. | Add Adventure, Combat, or RPG, or choose another concrete option from the third-person composition list. |
| Character facing does not match the camera design. | The View Type and Movement Type may not be a recommended pair. | Select the pairing in the comparison table, then retest movement, aiming, and item use. |
| The character appears on the wrong shoulder or too high or low. | **Anchor Offset** and **Look Offset** may both be shifting the frame. | Establish the anchor first, then tune the View Type offset one axis at a time. |
| Strafing feels like delayed input. | **Horizontal Pivot Freedom** may allow the character to move across the frame before the camera follows. | Reduce the freedom, then compare left and right movement at gameplay speed. |
| The camera clips, moves inward too early, or catches on corners. | **Collision Radius**, **Collision Anchor Offset**, or **Look Offset** may not fit the environment. | Tune them in the exact problem space and verify that the cast still keeps the character visible. |
| Rotation feels delayed or unstable. | **Rotation Speed**, **Secondary Rotation Speed**, springs, or an animated anchor may be contributing motion. | Test with a stable anchor and neutral springs, then restore one motion source at a time. |
| Pitch stops too early or flips farther than intended. | **Pitch Limit** may have an unsuitable range. | Set the intended minimum and maximum and test both ends with rapid input. |
| Step zoom does not respond. | **Step Zoom Sensitivity** may be `0`, the input mapping may be missing, or the limits may allow no useful range. | Set a positive sensitivity, verify [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/), and test distinct minimum and maximum limits. |
| Zoom changes field of view but not distance, or changes distance but not field of view. | State-based zoom and Step Zoom are separate systems. | Configure and test **Can Zoom** and **Zoom State** separately from the **Step Zoom** foldout. |
| A foreground object hides the character even though collision works. | Camera positioning and object fading solve different obstruction cases. | Configure [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) for the remaining visibility problem. |

## Related pages

- [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/)
- [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/)
- [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/)
- [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/)

## Developer details

`ThirdPerson` is a serializable abstract `ViewType`. `Adventure`, `Combat`, and `RPG` inherit it and add their yaw behavior; their current recommended Movement Type attributes also accept Four Legged. Pseudo3D, Top Down, and Look At derive directly from `ViewType` and do not share this field set.

`Rotate` applies moving-platform rotation, optional alignment to the character's up direction, **Pitch Limit**, **Forward Axis**, and primary and secondary rotation springs. `Move` calculates the Camera Controller anchor, smooths **Look Offset**, applies step zoom and position springs, honors **Horizontal Pivot Freedom**, and sphere casts from the collision anchor toward the desired camera position.

Gameplay look direction can account for crosshairs, recoil, moving-platform rotation, and a raycast up to **Look Direction Distance**. Step zoom registers an axis input event only when **Step Zoom Sensitivity** is greater than `0`, then clamps the accumulated amount to **Step Zoom Limit**.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-third-person-adventure"></a>

# Adventure

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/)

Choose Third Person Adventure for exploration where the player can orbit the camera while the character turns toward movement rather than permanently facing the camera. Pair the View Type with the Third Person Adventure Movement Type so camera-relative input produces forward-facing travel instead of a Combat strafe stance.

Use [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) when the character should keep facing the camera's gameplay look direction, or [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) when the camera should normally follow behind and offer temporary free-movement controls.

## Set up the Adventure pair

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **Third Person Adventure**.
3. Select the Adventure row to show its inherited and yaw settings, then select its radio button in the **Active** column. When both perspectives are installed, choose **Adventure** in **Third Person View Type**.
4. Select the character and expand **Ultimate Character Locomotion > Movement Types**.
5. Add **Third Person Adventure**, select its radio button in the **Active** column, and choose **Adventure** in **Third Person Movement Type** when both perspectives are available.
6. Configure horizontal and vertical look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).
7. Enter Play Mode and verify independent orbit, movement-facing, aiming, and item use before tuning framing or procedural motion.

The Adventure View Type also accepts Four Legged as a recommended Movement Type. Use the standard Third Person Adventure pair for a humanoid exploration setup and Four Legged only when that movement model matches the character.

## Configure the Adventure yaw range

- **Yaw Limit** sets the minimum and maximum orbit angle relative to the camera's base rotation. A range narrower than 360 degrees constrains the orbit; the full `-180` to `180` range allows unrestricted yaw.
- **Yaw Limit Lerp Speed** controls how quickly the camera corrects toward the nearest valid boundary when input would move it outside a limited range.

Use a full range when the player should inspect the character and surroundings from any side. Use a narrower range when the camera may glance around but should remain within a designed rear or shoulder arc. Increase **Yaw Limit Lerp Speed** for a firmer boundary and reduce it for a softer correction.

Boundary correction does not automatically recenter the camera behind the character. Choose [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) when follow-behind recentering is a core requirement.

## Understand Adventure movement

The matching Movement Type turns the character toward the movement direction relative to the camera. During ordinary movement, it converts the two-axis input into forward magnitude, so left, right, and backward input make the character turn and travel forward rather than play strafe or backward movement.

While input-started Aim is active, or while a Use ability has a **Face Target Character Item**, Adventure preserves the original input vector. Those target-facing states can then strafe or move backward while another system keeps the character oriented toward the target.

The observable result is independent camera orbit while idle, forward-facing travel during exploration, and target-facing movement only when the active aim or item-use setup requests it.

Adventure adds only **Yaw Limit** and **Yaw Limit Lerp Speed** to the shared settings documented by [Third Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/).

## Frame and protect the orbit

| Choice | Use it when | What to verify |
| --- | --- | --- |
| Camera Controller **Anchor** and **Anchor Offset** | The orbit needs a stable origin on the character. | Animate, crouch, and change stance; the camera should not inherit unwanted bone motion. |
| **Look Offset** | The character should sit left or right of center, above the anchor, or at another follow distance. | Orbit through the full yaw range and confirm the framing works from the front, sides, and rear. |
| **Look Offset Smoothing** | State-driven offset changes should ease instead of snap. | Enter and leave every camera state and confirm the offset settles quickly enough. |
| **Horizontal Pivot Freedom** | The character may move across part of the frame before the camera follows. | Move in both directions at each orbit angle and distinguish intentional freedom from input lag. |
| **Collision Radius** and **Collision Anchor Offset** | Walls or corners can block the desired camera position. | Orbit near tight geometry and confirm the camera moves inward without losing the character. |

Set the anchor first, then tune **Look Offset** one axis at a time. A shoulder offset that works behind the character may feel reversed or obstructed from the front, so test every permitted yaw angle.

## Tune rotation, pitch, zoom, and springs

- **Pitch Limit** sets the minimum and maximum vertical look angle.
- **Rotation Speed** controls how closely the visible camera follows the calculated Adventure rotation. Higher values reduce lag; lower values add smoothing.
- **Secondary Rotation Speed** controls rotational overrides and alignment to the character's gravity direction. Test it with custom gravity and moving platforms when the project uses them.
- **Forward Axis** applies a final orientation adjustment. Keep the default unless the project intentionally uses another camera-forward convention.
- **Look Direction Distance** controls how far gameplay look raycasts search ahead; it does not change camera follow distance.

Use **Field Of View** and **Field Of View Damping** for the normal lens. Adventure includes the default `Zoom` state, while Camera Controller **Can Zoom** and **Zoom State** determine whether state-based zoom can activate.

The inherited **Step Zoom** foldout adjusts distance separately. Set **Step Zoom Input Name**, use a **Step Zoom Sensitivity** greater than `0` to enable its axis event, and clamp the added distance with **Step Zoom Limit**. Verify state zoom and step zoom independently.

Tune **Primary Spring** and **Secondary Spring** only after the orbit and framing are stable. Follow [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) when adding regular response, recoil, or a brief camera force.

## Compare Adventure, Combat, and RPG

| Option | Camera and character relationship | Movement feel | Choose it when |
| --- | --- | --- | --- |
| **Adventure** | Camera yaw orbits within its configured range while character facing follows travel input. | The character normally turns and moves forward in the requested camera-relative direction. | Exploration should allow looking around without holding a combat-facing stance. |
| [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) | The paired Movement Type turns the character toward the camera look direction. | Forward, backward, and strafe input preserve camera-facing orientation. | Aiming and action should remain coordinated with an over-the-shoulder camera. |
| [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) | The camera normally follows behind, with optional free-movement and forced-rotation inputs. | Directional travel leads the camera until another relationship is requested. | The project needs automatic follow-behind behavior rather than a freely retained orbit. |

Use the same character, scene route, input device, and **Look Offset** while comparing. Test both idle orbit and movement, because Adventure's difference is clearest when the camera changes without character input and then travel begins.

## Verify in Play Mode

1. Stand still and orbit left and right. The camera should move independently while the character keeps its current facing.
2. Press forward, backward, left, and right at several orbit angles. The character should turn toward each camera-relative travel direction and use forward movement rather than a permanent strafe or backward stance.
3. Test both ends of a limited **Yaw Limit** with rapid input. The camera should remain inside the configured arc and correct according to **Yaw Limit Lerp Speed**.
4. Test input-started Aim and each Use ability whose item has **Face Target Character Item**. Target-facing states should preserve the movement vector required for strafing or moving backward.
5. Orbit near walls, corners, doorways, low ceilings, and foreground objects. Collision should move the camera inward without losing the character; use [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) for separate fading needs.
6. Test both pitch limits, slopes, custom gravity, moving platforms, and rapid changes of travel direction. Rotation should stay controlled without unwanted roll or lag.
7. Exercise state-based zoom, step zoom, recoil, and other camera forces separately. Each should settle without changing Adventure's orbit and movement relationship.
8. If both perspectives are present, switch away and back. **Third Person Adventure** should return as both the View Type and Movement Type with working look input.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Orbiting while idle turns the character with the camera. | Combat, RPG, or another Movement Type may be active. | Activate Third Person Adventure for both camera and character, then retest without movement input. |
| Left or right input always strafes instead of turning the character to travel. | A different Movement Type may be selected, or Aim or a target-facing Use ability may be active. | Restore Third Person Adventure and test with Aim and item use stopped before checking those states separately. |
| Aim or target-facing item use cannot strafe or move backward. | Aim may not have started from player input, or the Use ability may not have **Face Target Character Item** assigned. | Verify the active ability and item-facing setup, then test one action at a time. |
| The camera rotates beyond the intended arc. | **Yaw Limit** may span 360 degrees or use unsuitable minimum and maximum values. | Set the intended range and test both boundaries with rapid input. |
| The yaw boundary feels too hard or too soft. | **Yaw Limit Lerp Speed** controls correction toward the valid range. | Tune the speed at both ends; do not expect it to recenter behind the character. |
| The camera never returns behind the character. | Adventure retains its orbit instead of providing RPG-style follow behavior. | Choose RPG when automatic follow-behind behavior is required. |
| The character is framed incorrectly at some orbit angles. | **Look Offset** may have been tested only from behind. | Orbit through the full permitted yaw and tune anchor and offset for the complete range. |
| Rotation feels delayed or unstable. | **Rotation Speed**, **Secondary Rotation Speed**, springs, or an animated anchor may all add motion. | Test with a stable anchor and neutral springs, then restore one source at a time. |
| The camera clips or moves inward too early. | **Collision Radius**, **Collision Anchor Offset**, or **Look Offset** may not fit the space. | Tune them in the exact problem location and retest from several orbit angles. |
| Step zoom does not respond. | **Step Zoom Sensitivity** may be `0`, the mapping may be missing, or the limits may have no useful range. | Set a positive sensitivity, verify [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/), and test distinct limits. |

## Related pages

- [Third Person family settings](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)
- [Third Person Adventure Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-adventure/)
- [Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/)
- [RPG View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/)

## Developer details

`Adventure` is a serializable `ThirdPerson` View Type with recommended Movement Type attributes for Third Person Adventure and Four Legged, plus the default `Zoom` state. The current Inspector adds **Yaw Limit** and **Yaw Limit Lerp Speed** to the shared Third Person controls.

`Rotate` adds horizontal input to yaw, or lerps toward the clamped value when the configured span is less than 360 degrees, before using the shared Third Person rotation path. The runtime type also exposes `RotateWithCharacter`; the current Third Person Inspector control does not draw that property with the Adventure yaw fields.

The paired Adventure Movement Type calculates character yaw from the camera-relative movement direction. It normally replaces lateral input with forward magnitude, but preserves the original vector during input-started Aim or while a Use ability with `FaceTargetCharacterItem` is active.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-third-person-combat"></a>

# Combat

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/)

Choose Third Person Combat for an over-the-shoulder or action camera where the character should face the camera's gameplay look direction while moving forward, backward, or sideways. Pair the View Type with the Third Person Combat Movement Type so camera yaw, character facing, strafing, aiming, and item use share the same orientation.

Use [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) when the camera should orbit without always turning the character, or [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) when the camera should normally follow behind and provide optional free-movement controls.

## Set up the Combat pair

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **Third Person Combat**.
3. Select the Combat row to show its inherited settings, then select its radio button in the **Active** column. When both perspectives are installed, choose **Combat** in **Third Person View Type**.
4. Select the character and expand **Ultimate Character Locomotion > Movement Types**.
5. Add **Third Person Combat**, select its radio button in the **Active** column, and choose **Combat** in **Third Person Movement Type** when both perspectives are available.
6. Configure horizontal and vertical look mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).
7. Enter Play Mode and verify camera yaw, character facing, strafing, aiming, and item direction before tuning framing or procedural motion.

The Combat View Type also accepts Four Legged as a recommended Movement Type for a four-legged character. For the standard humanoid combat setup, use the Third Person Combat pair documented above.

## Understand how Combat moves

The View Type receives horizontal look input and maintains the camera's local yaw relationship with the character. The matching Movement Type rotates the character toward the Camera Controller's character look direction, while leaving the movement input vector unchanged.

The observable result is a character that keeps facing with the camera while forward input moves forward, left and right input strafe, and backward input moves backward. Travel direction does not independently turn the character away from the camera-facing direction.

Third Person Combat has no Combat-specific Inspector fields. It inherits framing, pitch, collision, field-of-view, step-zoom, and spring settings from [Third Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/). Configure those shared choices around the paired rotation behavior.

## Frame an over-the-shoulder view

| Choice | Use it when | What to verify |
| --- | --- | --- |
| Camera Controller **Anchor** and **Anchor Offset** | The whole orbit needs a stable origin near the character's upper body. | Animate, crouch, and change stance; the camera should not inherit unwanted bone motion. |
| **Look Offset** | The character should sit left or right of center, above the anchor, or at a different follow distance. | Compare both shoulders and every equipped item without changing character scale. |
| **Look Offset Smoothing** | State-driven shoulder or distance changes should ease instead of snap. | Enter and leave aim or zoom states and confirm the offset settles quickly enough. |
| **Horizontal Pivot Freedom** | The character may move a limited distance across the frame before the camera follows. | Strafe left and right; delayed camera follow should be intentional and symmetric. |
| **Collision Radius** and **Collision Anchor Offset** | Walls and corners can block the desired over-the-shoulder position. | Approach tight geometry from both shoulders and confirm the camera moves inward without losing the character. |

Set the anchor first, then tune **Look Offset** one axis at a time. Establish a clear reticle and item sightline before adding pivot freedom or offset smoothing, because both can change the character's screen position while the player aims.

## Tune rotation, pitch, and aiming

- **Pitch Limit** sets the minimum and maximum vertical look angle. Test both limits while close to the character and while zoomed.
- **Rotation Speed** controls how closely the visible camera follows its calculated Combat rotation. Higher values reduce lag; lower values add smoothing.
- **Secondary Rotation Speed** controls rotational overrides and alignment to the character's gravity direction. Test it on moving platforms or custom gravity when the project uses them.
- **Forward Axis** applies a final orientation adjustment. Keep the default unless the project intentionally uses another camera-forward convention.
- **Look Direction Distance** controls how far gameplay look raycasts search ahead; it does not change camera follow distance.

The shared Third Person look direction can account for crosshairs, recoil, moving-platform rotation, and a raycast from the camera. Test the reticle, character pose, and each item together rather than judging alignment from the camera Transform alone.

When the character's **Move Towards** ability becomes active, the Combat View Type temporarily follows character rotation and resets its local yaw to prevent a snap while the ability positions the character. After the ability stops, ordinary Combat look input resumes.

## Configure zoom and camera motion

Use **Field Of View** and **Field Of View Damping** for the normal lens. The Combat View Type includes the default `Zoom` state, while Camera Controller **Can Zoom** and **Zoom State** control whether that state can activate.

The inherited **Step Zoom** foldout changes camera distance separately:

- Set **Step Zoom Input Name** to the distance-control axis.
- Set **Step Zoom Sensitivity** above `0` to enable its input event.
- Use **Step Zoom Limit** to clamp the amount added to the Look Offset's `z` distance.

Verify state zoom and step zoom independently. Tune **Primary Spring** and **Secondary Spring** only after facing and framing are stable; use [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) when configuring regular response, recoil, or a brief camera force.

## Compare Combat, Adventure, and RPG

| Option | Camera and character relationship | Movement feel | Choose it when |
| --- | --- | --- | --- |
| **Combat** | The paired Movement Type turns the character toward the camera look direction. | Forward, backward, and strafe input preserve camera-facing orientation. | Aiming and action should stay coordinated with an over-the-shoulder camera. |
| [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) | Camera yaw can orbit within its configured range without always forcing character facing. | Travel and camera orbit can feel more independent. | Exploration benefits from looking around without adopting a permanent combat stance. |
| [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) | The camera normally follows behind, with optional free-movement and forced-rotation inputs. | Directional movement leads the camera until the player requests another relationship. | The project needs a follow-behind RPG scheme rather than constant camera-facing strafing. |

Use the same character, scene route, input device, and **Look Offset** while comparing. A different offset or smoothing value can hide the rotation difference between the three options.

## Verify in Play Mode

1. Stand still and move horizontal look input. The camera should rotate and the character should turn toward the same gameplay look direction.
2. Hold forward, backward, left, and right in turn. The character should move in each direction while continuing to face with the camera rather than turning toward the travel vector.
3. Aim and use every relevant item from idle, movement, and strafe. Reticle, character pose, and item result should agree with the intended look direction.
4. Trigger **Move Towards** through every ability that uses it. The camera should follow the character's positioning rotation without a yaw snap, then return to ordinary look control.
5. Test both pitch limits, rapid yaw, slopes, custom gravity, and moving platforms. Rotation should remain stable without unwanted lag or roll.
6. Walk into walls, corners, doorways, and foreground objects from both shoulders. Collision should preserve the character in view, and [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) should handle any separate fading requirement.
7. Test state-based zoom, step zoom, recoil, and other camera forces independently. Each should settle without changing the Combat facing relationship.
8. If both perspectives are present, switch away and back. **Third Person Combat** should return as both the View Type and Movement Type with working look input.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The camera rotates but the character does not face with it. | A different Movement Type may be active, or the character may have no Camera Controller look source. | Activate Third Person Combat and confirm the player character is attached to the Camera Controller. |
| Left or right input turns the character instead of strafing. | The character may be using Adventure, RPG, or another Movement Type. | Select Third Person Combat under **Movement Types** and retest all four movement directions. |
| The camera follows character rotation instead of accepting yaw input. | **Move Towards** may be active while an ability positions the character. | Let the ability finish, or inspect why Move Towards remains active before changing camera settings. |
| Character facing and item results disagree. | The View Type and Movement Type may be mismatched, or the reticle and item configuration may use different feedback. | Restore the Combat pair, then test one item at a time from idle and strafe. |
| The character is framed on the wrong shoulder or too high or low. | Camera Controller **Anchor Offset** and Combat **Look Offset** may both shift the frame. | Establish the anchor first, then tune the inherited offset one axis at a time. |
| Rotation feels delayed or unstable. | **Rotation Speed**, **Secondary Rotation Speed**, springs, or an animated anchor may all add motion. | Test with a stable anchor and neutral springs, then restore one source at a time. |
| The camera clips or moves inward too early. | **Collision Radius**, **Collision Anchor Offset**, or **Look Offset** may not fit the space. | Tune them in the exact problem location and retest from both shoulders. |
| Pitch stops too early. | **Pitch Limit** may use an unsuitable range. | Set the intended minimum and maximum, then verify them while standing and zoomed. |
| Step zoom does not respond. | **Step Zoom Sensitivity** may be `0`, the mapping may be missing, or the limits may have no useful range. | Set a positive sensitivity, verify [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/), and test distinct limits. |
| Zoom changes field of view but not distance, or changes distance but not field of view. | State zoom and Step Zoom are separate systems. | Configure Camera Controller zoom and the **Step Zoom** foldout independently. |

## Related pages

- [Third Person family settings](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)
- [Third Person Combat Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-combat/)
- [Adventure View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/)
- [RPG View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/)

## Developer details

`Combat` is a serializable `ThirdPerson` View Type with recommended Movement Type attributes for Third Person Combat and Four Legged, plus the default `Zoom` state. It adds no serialized Inspector fields beyond the shared Third Person controls.

During ordinary rotation, the View Type adds horizontal input to local yaw before calling the Third Person rotation path. While `MoveTowards` is active, it instead updates its base from the character rotation and resets yaw to `0` when the ability starts so the camera can follow the positioning turn without snapping.

The paired Combat Movement Type calculates character yaw from the Camera Controller look direction relative to the current Ultimate Character Locomotion rotation. Its input-vector method returns the original vector unchanged, which produces forward, backward, and strafe movement while character rotation continues to follow the look source.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-third-person-rpg"></a>

# RPG

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/)

Choose Third Person RPG for a follow-behind camera where character movement normally leads the view, while held inputs can temporarily orbit the camera or align the character with it. Pair the View Type with the Third Person RPG Movement Type so recentering, free camera movement, turning, and auto move use the same control scheme.

Use [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) when the player should retain an independent orbit without follow-behind recentering, or [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) when the character should continuously face the camera's gameplay look direction.

## Set up the RPG pair

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **Third Person RPG**.
3. Select the RPG row to show its inherited and RPG settings, then select its radio button in the **Active** column. When both perspectives are installed, choose **RPG** in **Third Person View Type**.
4. Select the character and expand **Ultimate Character Locomotion > Movement Types**.
5. Add **Third Person RPG**, select its radio button in the **Active** column, and choose **RPG** in **Third Person Movement Type** when both perspectives are available.
6. Configure all referenced button and axis names through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).
7. Enter Play Mode and test ordinary follow-behind movement before enabling free movement, forced rotation, auto move, zoom, or procedural camera motion.

The RPG View Type also accepts Four Legged as a recommended Movement Type, but RPG-specific character alignment calls into the RPG Movement Type. Use the complete RPG pair when the control scheme below is required.

## Configure follow-behind recentering

During ordinary movement, RPG derives camera yaw from the character rotation plus any stored free-movement offset. When free movement is released and the character moves, that offset returns to zero so the camera settles behind the character.

- **Yaw Snap Damping** controls the recenter duration. Lower values produce a quicker return; higher values produce a slower return.
- Recenter begins only while the character is moving. Releasing free movement while stationary leaves the current offset in place until movement resumes.
- Normal horizontal and vertical look input does not orbit the camera unless free movement, forced rotation, or the RPG Movement Type's rotate mode is active.

Test recentering from both sides and from a nearly rear-facing angle. Tune damping while walking and running, because the return is tied to the moving state rather than elapsed time after button release alone.

## Configure the RPG camera inputs

The RPG View Type adds four visible choices:

| Choice | What it does | Observable result |
| --- | --- | --- |
| **Allow Free Movement** | Enables the View Type's free-camera and forced-rotation inputs. | With it disabled, both input names below are ignored. |
| **Camera Free Movement Input Name** | While held, horizontal input changes the stored camera yaw offset and vertical input changes pitch. | The camera orbits independently; after release, it recenters when the character moves. |
| **Character Forced Rotation Input Name** | While held, asks the RPG Movement Type to turn the character with the look source and enables free camera rotation. | The camera resets its yaw offset immediately, then character facing and camera rotation operate together. |
| **Yaw Snap Damping** | Smooths the stored yaw offset back to zero during movement. | The camera returns behind the character at the selected pace. |

The matching RPG Movement Type adds its own controls:

- **Rotate Input Name** enters a mode where the character turns with the look source and the View Type accepts camera yaw and pitch.
- **Turn Input Name** selects the axis that turns the character, and **Turn Multiplier** scales that value.
- **Auto Move Input Name** toggles forward input while RPG is the active Movement Type.

Keep these mappings distinct while testing so a single button does not accidentally request two rotation modes.

## Frame and protect the follow camera

RPG inherits its framing controls from [Third Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/):

| Choice | Use it when | What to verify |
| --- | --- | --- |
| Camera Controller **Anchor** and **Anchor Offset** | The follow camera needs a stable origin on the character. | Animate, crouch, and change stance; the camera should not inherit unwanted bone motion. |
| **Look Offset** | The character should sit left or right of center, above the anchor, or at another follow distance. | Move, turn, orbit, and recenter; framing should remain intentional throughout the cycle. |
| **Look Offset Smoothing** | State-driven offset changes should ease instead of snap. | Enter and leave camera states without masking the separate yaw recenter behavior. |
| **Horizontal Pivot Freedom** | The character may move across part of the frame before the camera follows. | Strafe and turn in both directions; distinguish screen-space freedom from slow recentering. |
| **Collision Radius** and **Collision Anchor Offset** | Walls or corners can block the desired follow position. | Move and recenter near tight geometry; the camera should move inward without losing the character. |

Set the anchor first, then tune **Look Offset** one axis at a time. A large shoulder offset can make the camera's return behind the character appear incomplete even when yaw offset has reached zero.

## Tune rotation, pitch, zoom, and springs

- **Pitch Limit** sets the minimum and maximum vertical look angle used when an RPG camera mode accepts vertical input.
- **Rotation Speed** controls how closely the visible camera follows its calculated rotation. Higher values reduce lag; lower values add smoothing.
- **Secondary Rotation Speed** controls rotational overrides and alignment to the character's gravity direction. Test it with custom gravity and moving platforms when the project uses them.
- **Forward Axis** applies a final orientation adjustment. Keep the default unless the project intentionally uses another camera-forward convention.
- **Look Direction Distance** controls how far gameplay look raycasts search ahead; it does not change camera follow distance.

Use **Field Of View** and **Field Of View Damping** for the normal lens. Camera Controller **Can Zoom** and **Zoom State** can activate a configured state, but RPG does not add a default `Zoom` state preset of its own. Confirm that the RPG View Type has the state the project expects before relying on state-based zoom.

The inherited **Step Zoom** foldout adjusts camera distance separately. Set **Step Zoom Input Name**, use a **Step Zoom Sensitivity** greater than `0` to enable its axis event, and clamp the added distance with **Step Zoom Limit**.

Tune **Primary Spring** and **Secondary Spring** only after following and recentering are stable. Follow [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) when adding regular response, recoil, or a brief camera force.

## Compare RPG, Adventure, and Combat

| Option | Camera and character relationship | Movement feel | Choose it when |
| --- | --- | --- | --- |
| **RPG** | Camera normally follows character rotation; held modes permit free orbit or camera-aligned character rotation. | Character turning and optional auto move lead the view, with recenter during movement. | A follow-behind RPG scheme needs temporary camera control rather than permanent free orbit or strafing. |
| [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/) | Camera yaw can remain independent within its configured range while character facing follows travel. | The character normally turns and moves forward in the requested camera-relative direction. | Exploration should retain the chosen orbit without automatically returning behind. |
| [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/) | The paired Movement Type continuously turns the character toward camera look direction. | Forward, backward, and strafe input preserve camera-facing orientation. | Aiming and action should remain coordinated with an over-the-shoulder camera. |

Use the same character, scene route, input device, and **Look Offset** while comparing. RPG's behavior is clearest when testing the full sequence: move, hold free movement, orbit, release, remain still, then move again.

## Verify in Play Mode

1. Move and turn without holding an RPG camera input. The camera should follow the character rather than accepting ordinary free orbit.
2. Enable **Allow Free Movement**, hold **Camera Free Movement Input Name**, and test yaw and pitch. The camera should orbit without forcing the character to face with it.
3. Release free movement while stationary. The offset should remain; begin moving and confirm it returns behind according to **Yaw Snap Damping**.
4. Hold **Character Forced Rotation Input Name**. The camera should reset to the character immediately, then the RPG Movement Type should turn the character with the look source until the input is released.
5. Test the Movement Type's **Rotate Input Name**, **Turn Input Name**, **Turn Multiplier**, and **Auto Move Input Name** separately. Each mapping should produce only its intended rotation or movement result.
6. Move, orbit, and recenter near walls, corners, doorways, low ceilings, and foreground objects. Collision should move the camera inward without losing the character; use [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) for separate fading needs.
7. Exercise configured state zoom, step zoom, recoil, and other camera forces independently. Each should settle without changing RPG's follow and recenter relationship.
8. Trigger every ability that uses **Move Towards**. The camera should follow the character's positioning rotation without carrying an old local yaw.
9. If both perspectives are present, switch away and back. **Third Person RPG** should return as both the View Type and Movement Type with working input mappings.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The free-camera or forced-rotation input does nothing. | **Allow Free Movement** may be disabled, the mapping may be missing, or a different View Type may be active. | Enable the option, verify [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/), and confirm Third Person RPG is active. |
| The camera does not recenter after free movement is released. | The character may be stationary. | Begin moving; RPG recenters the stored yaw offset only while the character is moving. |
| Recenter is too fast or too slow. | **Yaw Snap Damping** controls the return duration. | Reduce it for a quicker return or increase it for a slower return, then test walking and running. |
| Ordinary look input does not change pitch or yaw. | RPG only accepts camera input during free movement, forced rotation, or the Movement Type's rotate mode. | Hold the intended mapped input instead of changing shared Third Person rotation settings. |
| Forced rotation resets the camera abruptly. | The mode intentionally clears yaw and positions the camera immediately before aligning the character. | Use Camera Free Movement when independent orbit is intended, or design the project's transition around the immediate alignment. |
| Forced rotation moves the camera but not the character. | A non-RPG Movement Type may be active; Four Legged does not receive the RPG-specific `TurnWithLookSource` call. | Activate Third Person RPG when the character must follow this input mode. |
| Turn or auto move does not respond. | The RPG Movement Type mapping may be missing, or RPG may not be the active Movement Type. | Verify **Turn Input Name** or **Auto Move Input Name** and confirm the RPG row is active. |
| The camera appears off-center after recentering. | **Look Offset** or **Horizontal Pivot Freedom** may still place the character away from screen center. | Verify yaw with a neutral offset, then restore intentional framing. |
| The camera clips or moves inward too early. | **Collision Radius**, **Collision Anchor Offset**, or **Look Offset** may not fit the space. | Tune them in the exact problem location and retest during orbit and recenter. |
| State-based zoom does nothing. | RPG may not have a matching `Zoom` state preset, or Camera Controller zoom may be disabled. | Configure the required state and verify **Can Zoom** and **Zoom State**, or use Step Zoom for distance control. |
| Step zoom does not respond. | **Step Zoom Sensitivity** may be `0`, the mapping may be missing, or the limits may have no useful range. | Set a positive sensitivity, verify the axis mapping, and test distinct limits. |

## Related pages

- [Third Person family settings](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)
- [Third Person RPG Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-rpg/)
- [Adventure View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/)
- [Combat View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/)

## Developer details

`RPG` is a serializable `ThirdPerson` View Type with recommended Movement Type attributes for Third Person RPG and Four Legged. Unlike Adventure and Combat, it has no `AddState("Zoom")` attribute. Its current Inspector adds **Yaw Snap Damping**, **Allow Free Movement**, **Camera Free Movement Input Name**, and **Character Forced Rotation Input Name** to the shared Third Person controls.

`Rotate` tracks free, forced, and Movement Type rotation flags. It stores free-camera yaw in `m_YawOffset`, smooths that offset toward zero only while the character is moving, and suppresses vertical input outside those active modes. `LookDirection(true)` returns character forward, while non-character look queries can use the inherited Third Person raycast.

The paired Movement Type registers rotate, turn-axis, and auto-move inputs; reports independent look behavior; and can be told to turn with the look source by the View Type. Auto move sets both processed and raw forward input while RPG is active. The View Type also follows character rotation and clears yaw while `MoveTowards` is active.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-third-person-look-at"></a>

# Third Person Look At

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-look-at/)

Use Third Person Look At when a temporary camera should keep a Transform framed, such as a character's head during a death animation or ragdoll reaction. It continuously turns toward the target and only repositions when the camera leaves a configured distance band, making it different from a normal orbit camera or a camera rigidly attached to a Transform.

Look At does not have a recommended Movement Type and does not stop character movement, abilities, or item use. Let the state or ability that activates this special view control gameplay and restore the normal View Type afterward.

## Set up the Look At view

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **Third Person Look At**.
3. Select the new row to show its settings.
4. Assign **Target** to the Transform that should remain framed. When a humanoid character is already attached and a valid Animator is found, the editor or runtime can assign the head automatically. Confirm the reference instead of relying on fallback behavior.
5. Set **Offset**, **Look Distance Limit**, **Position Smoothing**, **Rotational Lerp Speed**, and **Collision Radius** for the complete target animation or ragdoll motion.
6. Keep the normal gameplay View Type selected in the **Active** column and as **Third Person View Type** when Look At is temporary. Select Look At as active only when it should be the starting view.
7. Have the project's death, cutscene, or other special flow activate Look At and restore the previous View Type afterward. Add [Transition](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/transition/) when a third-person-to-third-person switch should blend.
8. Enter Play Mode and verify the target, distance band, collision, character visibility, and return to gameplay before adding rotational spring forces.

Do not clear **Target** while Look At is active. Automatic target resolution occurs when the character attaches, not every frame. Assign a replacement before removing the current target.

## Choose a target and offset

| Scenario | Target | Offset approach | What to verify |
| --- | --- | --- | --- |
| Death animation | A stable humanoid head or upper-body Transform | Frame the complete animation without placing the camera inside the character | The target remains valid until the view returns to gameplay. |
| Ragdoll reaction | A ragdoll Transform that follows the visible body | Leave enough space for large physics motion | The camera tracks rotation toward the target without violent position changes. |
| Scripted subject view | A dedicated scene or character Transform | Compose the subject from the intended character-relative direction | The target stays active and the framing works throughout the scripted sequence. |

**Offset** defines the correction position from **Target**, but its orientation uses the character rotation rather than the Target's local rotation. Rotating a ragdoll bone therefore changes the point the camera looks at without rotating the offset around that bone.

For non-humanoid characters or scene targets, assign **Target** explicitly. The current runtime fallback for a non-humanoid attachment is the camera Transform, which is not a useful subject for a Look At composition.

## Configure the distance band

**Look Distance Limit** contains the minimum and maximum permitted camera-to-target distance:

- When the camera is farther than the maximum, it moves toward the position derived from **Target** and **Offset**.
- When the camera is closer than the minimum, it moves outward toward a corrected offset position.
- While the camera remains inside the band, Look At keeps its current position and continues rotating toward the target.

This behavior allows a target to move within the frame without forcing the camera to copy every positional change. Use a narrow band when distance should remain consistent and a wider band when the camera may hold its position while the target moves.

**Position Smoothing** controls how quickly an out-of-band camera moves toward its correction position. Set it to `0` for no positional smoothing. It does not make the camera continuously follow **Offset** while already inside the distance band.

## Configure rotation, collision, and lens

- **Rotational Lerp Speed** controls how closely the camera faces the target. A value of `1` uses the target-facing rotation on each normal update; lower values add rotational lag.
- **Collision Radius** sets the sphere cast from the Target toward the candidate camera position. An obstruction moves the camera to the hit surface instead of allowing it to clip through geometry.
- **Field Of View** controls the lens angle, and **Field Of View Damping** controls how quickly a changed value settles.
- **Rotation Spring** adds temporary rotation on top of the target-facing result. Establish stable tracking before applying recoil or camera-shake forces.

The player look axes do not rotate this View Type. Look At calculates rotation from the camera position, Target, and character up direction. Use [Adventure](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/adventure/), [Combat](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/combat/), or [RPG](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/rpg/) when ordinary camera input should control the view.

See [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) before tuning **Rotation Spring**, and use [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) when visibility still needs fading after camera collision is correct.

## Compare target-driven camera options

| Option | Position behavior | Rotation behavior | Best fit |
| --- | --- | --- | --- |
| **Third Person Look At** | Holds its current position inside a distance band and corrects when too near or far | Continuously faces Target | Death, ragdoll, or scripted views where the subject should stay framed |
| [First Person Transform Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person-transform-look/) | Follows a Move Target plus local offset every update | Follows a separate Rotation Target with optional player pitch and yaw | A transform-driven first-person viewpoint rather than an external subject view |
| [Third Person](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/) concrete options | Orbits from the Camera Controller anchor with shared offset and collision | Uses Adventure, Combat, or RPG input and facing rules | Normal player-controlled third-person gameplay |

Look At reports character-forward gameplay look direction rather than the visible camera-to-target direction. Disable aiming, firing, or interactions during a noninteractive special view, or choose a gameplay View Type whose look direction matches the camera feedback.

## Verify in Play Mode

1. Start with the normal gameplay View Type, activate Look At, and confirm that the intended **Target** remains assigned.
2. Move or animate the Target through the complete sequence. The camera should keep facing it without responding to horizontal or vertical look input.
3. Place the camera inside, within, and outside **Look Distance Limit**. It should move outward when too close, hold position within the band, and move toward the offset-derived position when too far.
4. Compare **Position Smoothing** and **Rotational Lerp Speed** during fast target motion. Position correction and target-facing rotation should settle independently.
5. Move the Target near walls, corners, low ceilings, and foreground objects. Collision should prevent clipping without permanently losing the subject; use Object Fader for separate visibility cases.
6. Apply each project-used rotational spring force. The camera should return to target-facing rotation without a permanent offset or repeated oscillation.
7. Attempt movement, aiming, and item use only if the special state permits them. Confirm that gameplay direction remains character-forward rather than camera-to-target.
8. Activate Look At from both supported perspectives. It preserves the character locomotion's current perspective, so explicitly change perspective or model visibility when the sequence requires a third-person character model.
9. Restore the normal View Type. Input, Movement Type, model visibility, and framing should return as expected, with the configured third-to-third transition when applicable.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The camera does not face the intended subject. | **Target** may be empty, inactive, destroyed, or assigned to the wrong Transform. | Assign a stable Transform before activation and keep it valid until Look At stops. |
| A non-humanoid character produces an unusable view. | The automatic fallback can resolve to the camera Transform. | Assign an explicit character or scene Target instead of relying on fallback. |
| Clearing Target while active causes tracking to stop or an error. | Target fallback is not reevaluated every frame. | Assign the next Target before clearing or destroying the current one. |
| The camera does not copy the Target's position. | It may already be inside **Look Distance Limit**. | Narrow the distance band, or use Transform Look when the camera must follow a Transform position every update. |
| The offset moves in an unexpected direction when the target rotates. | **Offset** uses character rotation rather than Target local rotation. | Tune the offset in character-relative axes or use a different camera option for target-local attachment. |
| The camera moves too near or too far. | **Look Distance Limit**, **Offset**, or the current starting distance may conflict. | Test the minimum and maximum separately, then tune the offset-derived correction position. |
| Position or rotation trails too far behind the target. | **Position Smoothing** may be too high or **Rotational Lerp Speed** too low. | Reduce position smoothing or increase rotational lerp speed, then retest fast motion. |
| The camera clips or moves inward too early. | **Collision Radius** or the path from Target to candidate position may not fit the environment. | Tune the radius in the exact problem location and verify the Target is a sensible cast origin. |
| Look input does not rotate the camera. | Look At ignores horizontal and vertical camera input. | Use a player-controlled View Type when manual orbit is required. |
| A weapon or interaction does not follow the visible camera. | Look At reports character forward as its gameplay look direction. | Disable those actions for the special state or return to an appropriate gameplay View Type. |
| The first-person model remains active during the special view. | Look At preserves the locomotion's current perspective. | Make the activating flow switch perspective or model visibility when a visible third-person body is required. |
| Entering or leaving the view snaps. | A third-to-third Transition may be missing or its duration may be `0`. | Add and configure [Transition](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/transition/), then test both directions. |

## Related pages

- [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Third Person family settings](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)
- [First Person Transform Look](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person-transform-look/)
- [Transition](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/transition/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/)

## Developer details

`LookAt` is a serializable direct `ViewType` with no recommended Movement Type. Its perspective property reports the attached Ultimate Character Locomotion's current perspective rather than always returning third person. Both `LookDirection` overloads return character rotation multiplied by forward, not the visible camera-to-target vector.

When the character attaches and **Target** is empty, Look At searches the active humanoid model or Animator Monitor and assigns the head. If no humanoid Animator is available, the current runtime assigns the camera Transform. The editor's add control also assigns the head when it finds a humanoid Animator directly on the attached character.

`Move` derives a correction position by transforming **Offset** from the target position with character rotation, applies **Position Smoothing** only outside **Look Distance Limit**, and sphere casts from Target toward that position. `Rotate` uses `Quaternion.LookRotation` toward Target with character up, applies **Rotational Lerp Speed**, then adds **Rotation Spring** relative to the Camera Controller anchor.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-third-person-pseudo3d-2-5d"></a>

# Third Person Pseudo3D (2.5D)

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/)

Use Third Person Pseudo3D when gameplay should remain readable from the side while the character moves across a straight stage or around a curved 2.5D route. The camera holds a configured distance from the character, limits vertical following with a dead zone, and can rotate with the path used by the paired Pseudo3D Movement Type.

## Before you begin

Pair this View Type with the [Third Person Pseudo3D Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/) for camera-relative side movement and path support. The source also recommends Third Person Four Legged, but path-based camera rotation is available only while the active Movement Type is Pseudo3D with a **Path** assigned.

A curved route also needs the [Follow Pseudo3D Path](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/follow-pseudo3d-2-5d-path/) ability. The Movement Type supplies the path tangent that orients the camera; the ability keeps the character at a consistent horizontal offset from the curve.

## Set up the Pseudo3D view

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **Third Person Pseudo3D**. Select its row, then select its radio button in the **Active** column. When both perspectives are installed, also select it as **Third Person View Type**.
3. Select the character and expand **Ultimate Character Locomotion > Movement Types**. Add and activate **Third Person Pseudo3D**, then select it as **Third Person Movement Type** when both perspectives are installed.
4. For a straight side view, leave the Movement Type's **Path** empty and use **Forward Axis** to choose the camera-facing direction.
5. For a curved route, build and assign a **Path** on the Pseudo3D Movement Type, then add **Follow Pseudo3D Path** to the character's **Abilities** list.
6. Set **View Distance** for the side-view composition. Tune **Vertical Dead Zone**, **Move Smoothing**, and **Rotation Smoothing** while testing the fastest movement and largest jump in the level.
7. If mouse aiming must reach targets at different depths, enable **Depth Look Direction** and test it against the project's actual collision layers. Leave it disabled for aiming constrained to the character's side-view plane.
8. Enter Play Mode and verify movement, framing, aiming, and every path bend before adding secondary spring forces or state-driven field-of-view changes.

## Choose a side-view scenario

| Scenario | Movement and path setup | Camera choices | What to verify |
| --- | --- | --- | --- |
| Straight side-scroller | Pseudo3D Movement Type with **Path** empty; usually disable depth movement | Set **Forward Axis** for the intended side and use a stable **View Distance** | Left and right movement stay in the gameplay plane and the camera remains on the chosen side. |
| 2.5D lanes | Pseudo3D Movement Type with depth movement enabled | Use **Depth Look Direction** only when visible-cursor aiming should use scene depth | Forward and backward input change depth without making aiming or framing ambiguous. |
| Curved 2.5D route | Assign a **Path** and add **Follow Pseudo3D Path** | Test **Forward Axis**, rotation response, and **View Distance** through every tangent change | The camera turns with the path while the character keeps a consistent offset from it. |
| Four-legged side view | Third Person Four Legged Movement Type; no Pseudo3D path integration | Configure a fixed **Forward Axis** and side composition | Turning and forward movement remain readable without expecting path-driven camera rotation. |

The camera does not travel along the Path independently. It positions itself from the Camera Controller anchor and uses the active Pseudo3D path tangent to calculate its side-facing rotation. The character's position along a curved route is handled separately by **Follow Pseudo3D Path**.

## Configure framing and response

- **Forward Axis** adjusts the camera's facing direction. With no active Pseudo3D Path, it defines the fixed target rotation; with a Path, it is combined with the side direction calculated from the current tangent. Use the default negative forward axis as a starting point, then test path direction and every bend.
- **View Distance** positions the camera away from the anchor along the camera's forward direction. Tune it with the final aspect ratio and the widest gameplay area visible.
- **Vertical Dead Zone** holds the camera's vertical framing while the character remains within the permitted band. Once the character moves beyond it, the camera follows enough to keep the character at the edge of the band.
- **Move Smoothing** controls the time used to settle toward a new position. A value of `0` applies positional changes immediately.
- **Rotation Smoothing** is the fraction of the target rotation applied during a normal update. A value of `1` applies the target rotation immediately; lower positive values add lag. A value of `0` prevents normal rotation from advancing, so it is not the no-smoothing setting for rotation.
- **Field Of View** and **Field Of View Damping** control the lens angle and how quickly state-driven field-of-view changes settle.

Pseudo3D does not perform the third-person orbit camera's obstruction sphere cast. Keep the camera corridor clear through the full route, reduce **View Distance** where necessary, and use [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) only for remaining foreground-visibility cases.

## Configure aiming and camera forces

With a visible mouse cursor, the camera casts a ray through the cursor. When **Depth Look Direction** is disabled, it resolves that ray against the side-view plane through the look position. When enabled, a physics hit can provide a direction with depth; if nothing is hit, the calculation falls back to the plane.

When the cursor is hidden, horizontal and vertical look axes set the look direction instead. **Depth Look Direction** does not change that controller or virtual-input path. **Look Direction Distance** limits the visible-cursor physics ray; the View Type's reported look distance starts at that value and then reflects an accepted cursor direction.

Use **Secondary Position Spring** and **Secondary Rotation Spring** for temporary forces such as recoil or camera shake. Establish a stable route, dead zone, and aiming direction first, then add one force source at a time. See [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) for the shared spring controls.

## Verify in Play Mode

1. Confirm that **Third Person Pseudo3D** is active on both the camera and character before applying input.
2. On a straight section, move left and right. The character should stay readable from the selected side and the camera should hold **View Distance** from its anchor.
3. Jump and change elevation by amounts smaller and larger than **Vertical Dead Zone**. Small changes should stay inside the held framing; larger changes should make the camera follow while retaining the configured band.
4. If depth movement is enabled, move toward and away from the camera. Verify that the character follows the intended lanes and that the level remains readable at both depth limits.
5. If a Path is assigned, traverse the complete route in both directions. The camera should rotate with path tangents, while **Follow Pseudo3D Path** keeps the character's horizontal offset consistent through bends.
6. Test visible-cursor aiming with **Depth Look Direction** disabled and enabled. Plane-constrained aiming should remain on the 2.5D plane; depth aiming should use valid scene hits and fall back predictably when the ray misses.
7. Test controller or virtual look input with the cursor hidden. The look axes should update direction independently of **Depth Look Direction**.
8. Compare abrupt direction changes with several **Move Smoothing** and **Rotation Smoothing** values. Position and rotation should settle deliberately without drift, a frozen camera, or excessive lag.
9. Traverse foreground geometry, route corners, and the complete camera corridor. No wall or prop should clip through the view; Pseudo3D does not move inward automatically around an obstruction.
10. Apply each project-used secondary spring and state-driven field-of-view change, then switch away from and back to Pseudo3D. Framing, aim, and input should return to their expected values.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Movement direction and camera orientation disagree. | The camera and character may not both have Pseudo3D active. | Select **Third Person Pseudo3D** in both active lists and dual-perspective dropdowns, then retest input. |
| The camera does not rotate at a path bend. | The active Movement Type may not be Pseudo3D, or its **Path** may be empty. | Activate Pseudo3D and assign the intended Path to that Movement Type. |
| The character drifts across or away from a curved path. | **Follow Pseudo3D Path** may be missing, unable to start, or below an unexpected movement modifier. | Add the ability, keep the Path assigned, and place the concurrent ability near the bottom of the ability list. |
| The camera faces the wrong side or flips at part of the route. | **Forward Axis**, path point order, or a path tangent may oppose the intended view. | Test the fixed axis first, then inspect path direction and tangents at the exact bend. |
| Forward and backward input do nothing. | **Allow Depth Movement** may be disabled on the Pseudo3D Movement Type. | Enable it only when the game supports depth lanes, then verify both depth limits. |
| Mouse aiming cannot select a target at another depth. | **Depth Look Direction** may be disabled, or the cursor ray may not hit the target's layer. | Enable the option and verify colliders, layers, and **Look Direction Distance** with the actual target. |
| Changing Depth Look Direction has no effect with a controller. | The option is used only while the mouse cursor is visible. | Configure and test the horizontal and vertical look input axes for the cursor-hidden path. |
| The camera never turns after changing Rotation Smoothing. | A value of `0` applies none of the target rotation during normal updates. | Use a positive value; use `1` when the target rotation should be applied immediately. |
| Position snaps or follows too slowly. | **Move Smoothing** may be `0` or too large for the character speed. | Increase it slightly to soften a snap, or reduce it to follow faster. |
| Jumps move the camera too much or leave the character too far from center. | **Vertical Dead Zone** may be too small or too large. | Test the smallest and largest expected elevation changes, then set a band that keeps both readable. |
| Foreground geometry clips through the camera. | This View Type has no camera-obstruction sweep. | Clear the route's camera corridor, reduce **View Distance**, or handle foreground visibility separately. |
| The camera rotates with the path but the character does not stay aligned to it. | Camera path rotation and character path constraint are separate responsibilities. | Add and verify **Follow Pseudo3D Path** instead of relying on the View Type alone. |

## Related pages

- [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Third Person Pseudo3D Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-pseudo3d-2-5d/)
- [Follow Pseudo3D Path](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/follow-pseudo3d-2-5d-path/)
- [Third Person Four Legged Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/)

## Developer details

`Pseudo3D` is a direct third-person `ViewType` whose recommended Movement Types are `Pseudo3D` and `FourLegged`. It reports zero pitch and yaw, uses character rotation as its base rotation, and always reports a third-person perspective.

`Rotate` uses **Forward Axis** directly when there is no active Pseudo3D Path. With a Path, it takes the cross product of the current path tangent and camera up to calculate the side direction, then applies **Forward Axis**. Normal updates use `Quaternion.Slerp` with **Rotation Smoothing**; immediate updates bypass it.

`Move` starts from the Camera Controller anchor, applies the vertical-band correction captured when the View Type activates, subtracts camera forward multiplied by **View Distance**, and uses `Vector3.SmoothDamp` with **Move Smoothing**. It then adds **Secondary Position Spring** and does not perform a collision cast.

The detailed `LookDirection` overload uses a cursor ray and optional physics hit for visible-cursor input, or the configured look axes when the cursor is hidden. The simple overload returns character forward. Secondary spring rest values can accumulate force, and state changes preserve the previous field-of-view damping for the active camera update.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-third-person-top-down"></a>

# Third Person Top Down

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/)

Use Third Person Top Down when the character should remain visible beneath an overhead or high-angle camera, with movement driven directly, by twin-stick input, or by point-and-click navigation. The View Type follows the Camera Controller anchor, supports cursor and controller aiming, and can raise its pitch to avoid an obstruction between the anchor and camera.

## Before you begin

Choose the character behavior before tuning the camera. Top Down currently recommends three Movement Types:

- [Third Person Top Down](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-top-down/) for direct movement relative to the camera, with either movement-facing or independent aim.
- [Third Person Point & Click](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/) for click-to-move navigation. It also requires a Pathfinding Movement ability and [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/).
- [Third Person Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/) for a non-strafing animal or creature viewed from above.

## Set up the Top Down view

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **Third Person Top Down**. Select its row, then select its radio button in the **Active** column. When both perspectives are installed, also select it as **Third Person View Type**.
3. Select the character and expand **Ultimate Character Locomotion > Movement Types**. Add and activate the Movement Type chosen above, then select it as **Third Person Movement Type** when both perspectives are installed.
4. For Point & Click, add a Pathfinding Movement ability such as [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) above **Move Towards**, and keep the mouse cursor available for selecting destinations.
5. Configure the Camera Controller **Anchor** and **Anchor Offset** before the View Type. Place the anchor above the character's head when **Vertical Look Direction** must cover targets at different heights.
6. On Third Person Top Down, set **Forward Axis**, **Up Axis**, **Pitch Limit**, and **View Distance** for the intended level framing.
7. Set a positive **Collision Radius** and **View Step** when the camera should increase its pitch around non-fadeable obstructions. Add [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) when supported foreground materials should fade instead.
8. Configure look direction for the selected input scheme, then enter Play Mode and verify framing, movement, aiming, and obstruction handling before adding dynamic state transitions or springs.

## Choose a movement and input scenario

| Scenario | Character setup | Look behavior | What to verify |
| --- | --- | --- | --- |
| Mouse-aimed action game | Top Down with **Relative Camera Movement** enabled and **Look In Move Direction** disabled | Cursor position controls character aim; optionally enable **Vertical Look Direction** | The character moves relative to the screen while aiming independently at valid targets. |
| Twin-stick action game | Top Down with **Relative Camera Movement** enabled and **Look In Move Direction** disabled | A connected controller uses horizontal and vertical look axes relative to the camera | Movement and aim remain independent in every camera orientation. |
| Movement-facing game | Top Down with **Look In Move Direction** enabled | The character's forward direction replaces cursor or stick aim | Turning follows movement without aim jitter near the character. |
| Point-and-click game | Point Click plus Pathfinding Movement and Move Towards | The click ray selects a destination; the Point Click Movement Type does not use direct movement input | Clicking valid ground starts navigation while clicks over UI or too close to the character do not. |
| Four-legged overhead game | Four Legged | Character turning follows the selected Four Legged rotation behavior | Forward, reverse, and turning remain readable without expecting strafing. |

Keep the camera settings unchanged while comparing Movement Types. A camera problem can appear to be an input problem when the active View Type and Movement Type are not the intended pair.

## Configure framing and obstruction handling

- **Forward Axis** chooses the horizontal direction used to compose the view. **Up Axis** supplies the camera's reference up direction when the character is not aligning the camera to its own up direction.
- **Pitch Limit** is a minimum-and-maximum range. The minimum is the normal camera pitch. When an obstruction is found, the camera increases the pitch by **View Step** until the route is clear or the maximum is reached.
- **View Distance** places the camera away from the anchor along the calculated view ray.
- **Rotation Speed** controls how quickly the camera faces back toward the anchor. A value of `0` prevents normal rotation from advancing; higher values follow more quickly.
- **Move Smoothing** controls the time used to settle toward the calculated camera position. A value of `0` applies positional changes immediately.
- **Collision Radius** sets the obstruction sphere radius. A value of `0` disables the obstruction check. Keep **View Step** greater than `0` whenever collision is enabled so the camera can advance through its pitch search.

If Object Fader is present and every material on the hit object can fade, Top Down leaves the selected pitch unchanged and lets the object fade. Otherwise it tries progressively steeper angles. The camera does not shorten **View Distance**, and reaching the maximum pitch does not guarantee that a crowded camera corridor is clear, so test the complete level route.

## Configure look direction

When **Look In Move Direction** is enabled on an installed Top Down Movement Type, character aim follows character forward. Disable it when the cursor or right stick should aim independently.

For mouse input, Top Down normally projects the cursor onto a horizontal plane through the requested look position. At lower camera angles, a second plane supplies a fallback when the cursor ray is above the horizon. Enable **Vertical Look Direction** when a physics hit should provide height as well as horizontal direction. **Look Direction Distance** limits that ray, and the target must have a collider on a permitted layer.

For a connected controller with the cursor hidden, the horizontal and vertical look axes produce an aim direction relative to the camera. Configure those mappings through [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/). **Vertical Look Direction** does not change this controller path.

## Change the composition with states

The dynamic controls animate Top Down settings when the [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) changes:

- **Allow Dynamic Camera Rotation** transitions the horizontal **Forward Axis** toward **Desired Angle** using **Change Angle Speed** and **Rotation Transition Curve**.
- **Allow Dynamic Pitch Adjustment** transitions the minimum value of **Pitch Limit** toward **Desired Pitch** using **Change Pitch Speed**. Enable **Use Independent Pitch Transition** to use **Pitch Transition Curve**; otherwise it reuses the rotation curve.
- **Allow Dynamic Distance Adjustment** transitions **View Distance** toward **Desired Distance** using **Change Distance Speed**. Set this speed above `0`. Enable **Use Independent Distance Transition** to use **Distance Transition Curve**; otherwise it reuses the rotation curve.

Set the desired values in the state preset, then test the transition into and out of that state. These transitions start during a state change; changing a desired value alone does not continuously trigger a new transition.

Use **Secondary Position Spring** and **Secondary Rotation Spring** for temporary forces such as recoil or camera shake. Establish stable movement, aiming, collision, and state transitions first, then add one force source at a time. See [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) for the shared spring controls.

## Verify in Play Mode

1. Confirm that **Third Person Top Down** and the intended Movement Type are selected in their active lists and dual-perspective dropdowns.
2. Move through the full input range. Screen-relative directions, character facing, and independent aim should match the selected scenario.
3. Test the final aspect ratio at the level edges, in corners, and at the highest and lowest elevations. **Forward Axis**, **Pitch Limit**, and **View Distance** should keep the playable area readable.
4. Pass the camera beneath non-fadeable ceilings, arches, and foreground props. It should increase pitch in **View Step** increments without clipping or exceeding the maximum pitch unexpectedly.
5. Repeat with a fadeable foreground object and Object Fader enabled. The material should fade while the camera retains its selected pitch.
6. Test mouse aim near the character, at the screen edges, and above the horizon. With **Vertical Look Direction** enabled, test targets below, level with, and above the look position.
7. Test a connected controller with the cursor hidden. Both look axes should remain camera-relative and should not depend on **Vertical Look Direction**.
8. For Point & Click, click valid ground, invalid layers, UI, and positions inside the minimum click distance. Only a valid destination should start movement.
9. Activate every state that changes angle, pitch, or distance. Each value should reach its desired result, follow the chosen curve, and restore correctly when the state ends.
10. Apply every project-used secondary spring, then switch away from and back to Top Down. Framing, collision, movement, and aim should return without drift or a persistent force.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Movement direction does not match the screen. | The wrong Movement Type may be active, or **Relative Camera Movement** may be disabled. | Activate the intended pairing and enable camera-relative movement for screen-relative direct control. |
| The character faces movement instead of the cursor or right stick. | **Look In Move Direction** may be enabled on the installed Top Down Movement Type. | Disable it for independent aim and retest both mouse and controller input. |
| Point-and-click input does nothing. | Pathfinding Movement or Move Towards may be missing, the cursor may be over UI, or the click ray may miss **Solid Object Layers**. | Add the required abilities in the correct order and test a valid collider outside **Min Point Click Distance**. |
| The camera stays on the wrong side of the character. | **Forward Axis** may not match the intended screen orientation. | Set the axis for the desired level direction, then retest input and aiming together. |
| The camera does not turn toward the anchor. | **Rotation Speed** may be `0`. | Use a positive speed and compare immediate and gradual response during rapid movement. |
| The camera snaps or follows too slowly. | **Move Smoothing** may be `0` or too large. | Increase it slightly to soften snapping, or reduce it to follow faster. |
| Play Mode stalls when an obstruction is present. | **Collision Radius** may be positive while **View Step** is `0`. | Set a positive View Step so the obstruction search can advance toward the maximum pitch. |
| The camera still clips at its steepest angle. | The route may remain blocked at the maximum **Pitch Limit**, or **View Distance** may extend into geometry. | Clear the camera corridor, raise the maximum pitch carefully, reduce distance, or use a fadeable foreground material. |
| A fadeable object makes the camera change pitch anyway. | Object Fader may be absent or one of the hit object's materials may not support fading. | Add and configure Object Fader, then verify every Renderer material on that object. |
| Mouse aim stays on one height. | **Vertical Look Direction** may be disabled, the target ray may miss, or the anchor/look position may be too low. | Enable it, place the anchor above head height, and verify target colliders, layers, and distance. |
| Controller aiming ignores Vertical Look Direction. | That option is only used by the cursor ray. | Configure the horizontal and vertical look axes for the controller path. |
| A dynamic distance state does not move the camera. | **Allow Dynamic Distance Adjustment** may be disabled, **Change Distance Speed** may be `0`, or no state change occurred. | Enable it in the relevant preset, set a positive speed and desired distance, then enter the state again. |

## Related pages

- [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Third Person Top Down Movement Type](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-top-down/)
- [Third Person Point & Click](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-point-click/)
- [Third Person Four Legged](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/included-movement-types/third-person-four-legged/)
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/)

## Developer details

`TopDown` is a direct third-person `ViewType` whose recommended Movement Types are `TopDown`, `FourLegged`, and `PointClick`. It reports zero pitch and yaw, uses character rotation as its base rotation, and always reports a third-person perspective.

`Move` builds a ray from the Camera Controller anchor using **Forward Axis**, **Up Axis**, and the minimum **Pitch Limit**. With collision enabled, it disables the character collider layer and sphere casts along that ray. Non-fadeable hits increase pitch by **View Step** up to the maximum; the target position remains the ray origin plus direction multiplied by **View Distance**, then uses `Vector3.SmoothDamp` and the secondary position spring.

`Rotate` looks back along the view ray using character up when **Align To Up Direction** is enabled, otherwise **Up Axis**. It uses a time-scaled `Quaternion.Slerp` with **Rotation Speed**, then adds the secondary rotation spring.

The detailed `LookDirection` overload returns character forward when the cached Top Down Movement Type has **Look In Move Direction** enabled. Otherwise it uses cursor raycasts and planes, or camera-relative controller axes. State changes start the optional angle, minimum-pitch, and distance interpolations and preserve the prior field-of-view damping for the active camera update.

---

<a id="page-ultimate-character-controller-camera-view-types-included-view-types-transition"></a>

# Transition

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/transition/)

Add Transition when switching between configured View Types should move smoothly instead of cutting immediately. The Camera Controller invokes it automatically for first-to-third, third-to-first, and third-to-third changes; do not select Transition as the normal active View Type.

## Before you begin

Configure and verify every source and destination View Type before adding a blend. Transition interpolates toward the destination's current position and rotation, so it cannot correct a bad anchor, offset, collision setup, or look direction.

For perspective switching, the Camera Controller needs a valid **First Person View Type**, **Third Person View Type**, and **Can Change Perspectives** enabled. A Transition row is not a perspective default and is excluded from both dropdowns.

## Set up camera transitions

1. Select the camera with the **Camera Controller** component and expand **View Types**.
2. Use the add control and select **Transition**. Add one Transition row; its three duration categories apply to every matching View Type pair.
3. Select the Transition row to show its settings, but leave a playable first-person or third-person row selected in the **Active** column.
4. Set **First To Third Transition Duration**, **Third To First Transition Duration**, and **Third To Third Transition Duration** for the switches the game uses. Use `0` when that category should cut immediately, and do not use negative durations.
5. Tune **Start First Person Camera Offset** for the beginning of a first-to-third blend and **End First Person Camera Offset** for the end of a third-to-first blend.
6. Enter Play Mode and switch in every supported direction while standing still. Establish clean camera and model handoffs before testing movement, items, slow motion, or rapid repeated switches.

## Choose settings for each switch

| Switch | Duration field | Offset and model timing | Typical use |
| --- | --- | --- | --- |
| First person to third person | **First To Third Transition Duration** | The blend begins at the outgoing camera plus **Start First Person Camera Offset**. Third-person visibility is requested when the blend starts. | Pulling from the character's head into an Adventure, Combat, or RPG view without beginning inside the visible model. |
| Third person to first person | **Third To First Transition Duration** | The blend approaches the first-person destination plus **End First Person Camera Offset**. First-person visibility is requested when the blend completes. | Moving toward the head while keeping the third-person model visible until the camera reaches the handoff. |
| Third person to third person | **Third To Third Transition Duration** | No first-person offset or perspective-visibility handoff is used. | Switching from gameplay to [Look At](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-look-at/), [Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/), or another third-person composition. |
| First person to first person | Not supported | Transition returns control directly to the destination View Type. | Use an immediate switch or project-specific first-person blending when two first-person options must transition. |

These durations are global by direction, not configurable per View Type pair. If a short gameplay-to-gameplay blend and a long cutscene blend need different timing, change the Transition setting through a controlled state or script before switching, or implement project-specific transition handling.

## Tune offsets and duration

**Start First Person Camera Offset** uses the outgoing first-person camera's transform. Its default negative `z` offset starts the blend slightly behind that camera before the third-person model becomes visible. Tune it with the complete character body, equipped items, crouching, and the widest first-person field of view.

**End First Person Camera Offset** is applied to the first-person destination using the Camera Controller anchor's rotation. It keeps the moving camera short of the exact first-person position until the perspective handoff completes. Tune it with the final anchor, model, and first-person item setup rather than copying the start offset without testing.

Transition does not expose a custom blend curve. Rotation uses a spherical interpolation from the starting camera rotation, while each position axis uses a smooth step from the starting position toward the destination's live position. The destination View Type is evaluated immediately on every update, so a moving character or changing destination can move the end point during the blend.

Field of view is controlled by the destination View Type and its **Field Of View Damping**, independently of the Transition duration. Test lens and position changes together when the two View Types use different fields of view.

## Decide when to cut instead

Set the matching duration to `0` for a deliberate cut, such as a teleport, respawn, camera reset, or switch whose two views already share the same pose. Project code can also bypass a blend; see Developer details for the interruption behavior.

## Verify in Play Mode

1. Confirm that a playable View Type, not Transition, is selected as active and that the intended source and destination rows both work independently.
2. Switch from first person to third person. The model should become visible at the start, and **Start First Person Camera Offset** should prevent the blend from beginning inside the head or equipped geometry.
3. Switch from third person to first person. The model should remain in its third-person presentation until the camera reaches the handoff, without crossing visible head or item geometry.
4. Switch between every third-person pair used by the game. The camera should follow a continuous route without applying either first-person offset.
5. Switch between two first-person View Types if the project has them. Confirm the expected immediate change; the included Transition does not blend this direction.
6. Repeat all supported switches while walking, turning, jumping, aiming, zooming, and changing items. The live destination should remain stable while the transition follows it.
7. Compare View Types with different fields of view. Position, rotation, and destination **Field Of View Damping** should settle without an unintended double ease or lens pop.
8. Lower and restore the character time scale. The transition duration should scale with the character and pause while its time scale is `0`.
9. Request another non-immediate View Type before the first blend completes. The new blend should restart from the current visible camera pose; verify perspective visibility and input through the interruption.
10. Test each intentional `0`-duration or immediate API switch from a stable state. The camera, perspective model, look direction, and equipped items should all arrive in the same update sequence expected by the game.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Every switch snaps. | Transition may be missing, the matching duration may be `0`, or code may request an immediate switch. | Add one Transition row, set a positive duration for the required direction, and pass `false` for the API's immediate flag. |
| Transition appears as the active or default camera. | The Transition row may have been selected instead of only configured. | Select a playable View Type as active and choose valid first- and third-person defaults; never use Transition as either default. |
| First-to-third uses the unexpected duration. | The legacy page previously described this field in the wrong direction. | Use **First To Third Transition Duration** only when leaving first person for third person. |
| The blend never completes. | A duration may be negative, or the character time scale may be `0`. | Use `0` for a cut or a positive duration for a blend, then restore a positive character time scale. |
| The third-person model appears inside the camera at the start. | **Start First Person Camera Offset** may be too small or point toward the model. | Tune the offset in the outgoing camera's local axes with the largest model and item combination. |
| The camera crosses the head before first person becomes active. | **End First Person Camera Offset**, the Camera Controller anchor, or first-person destination may be unsuitable. | Tune the end offset relative to the anchor rotation and verify the destination View Type independently. |
| A third-to-third switch still snaps. | **Third To Third Transition Duration** may be `0`, or one of the views may be selected through an immediate API call. | Set a positive duration and use a non-immediate View Type change. |
| Two first-person views do not blend. | First-to-first transitions are not supported. | Use a direct cut or add project-specific first-person transition handling. |
| Aim direction feels unexpected while moving into first person. | The detailed look direction deliberately remains on the outgoing View Type until the transition completes. | Avoid precision actions during the handoff or provide project-specific input handling for that sequence. |
| Field of view settles before or after the camera position. | Destination **Field Of View Damping** is independent of the Transition duration. | Tune the destination damping and transition duration together for the intended visual timing. |
| A rapid switch uses unexpected model timing. | A new non-immediate blend starts from the visible pose but selects its category from the logical source and destination View Types. | Test all interruption paths, or lock perspective input until the current transition completes. |
| An immediate switch during a blend resumes the old motion. | The existing Transition may still be active. | In custom code, call `StopTransition()` before issuing the immediate View Type or perspective change. |

## Related pages

- [Camera Controller](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)
- [First Person View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [Third Person View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)
- [Third Person Look At](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-look-at/)
- [Third Person Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/)

## Developer details

`Transition` is stored separately by `CameraController.InitializeViewTypes` and excluded from the selectable first-person, third-person, and active View Type maps. The Camera Controller uses it automatically when `SetViewType` receives `immediateTransition == false`.

`CameraController.SetPerspective(firstPersonPerspective, true)` and `CameraController.SetViewType(type, true)` bypass a new blend. Make that immediate call from a stable camera state: the immediate branch does not stop a Transition that is already running. Custom interruption code can retrieve the Transition View Type, call `StopTransition()`, and then perform the immediate switch.

`StartTransition` supports first-to-third, third-to-first, and third-to-third pairs. A duration exactly equal to `0` declines the transition, and first-to-first always declines it. A new non-immediate transition captures the current camera position and rotation; the special first-person start offset is skipped when another transition is already active.

`Rotate` calculates a clamped linear transition value from `TimeUtility.Time`, duration, and the Ultimate Character Locomotion time scale, then uses `Quaternion.Slerp` toward the destination's immediate rotation. `Move` recalculates the destination's immediate position, applies the end offset when entering first person, and uses `Mathf.SmoothStep` per axis.

When leaving first person, `OnCameraChangePerspectives` is sent at transition start so the third-person model is available. When entering first person, it is sent by `StopTransition` after the handoff. During a transition into first person, the detailed `LookDirection` overload uses the outgoing View Type because the moving camera is not yet at the first-person head position; other transitions use the destination look direction.

---

<a id="page-ultimate-character-controller-camera-object-fader"></a>

# Object Fader

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)

Use Object Fader to keep a third-person character readable when the camera moves inside the model or when foreground geometry blocks the view. Character fading and obstructing-object fading can be enabled independently, and both require materials whose shaders actually respond to alpha transparency.

## Before you begin

Object Fader belongs on the same camera GameObject as **Camera Controller**. The Setup Manager adds it automatically when creating a camera with third-person support; add **Object Fader** manually if an existing camera does not have it.

The component disables itself in first person and restores all tracked fades during the perspective handoff. Configure it for the third-person View Types that the camera uses, then verify perspective switching separately.

## Set up Object Fader

1. Select the camera with the **Camera Controller** component and locate **Object Fader**. If it is absent, use **Add Component** and add **Object Fader** to that camera GameObject.
2. Match **Color Property Name**, **Mode Property Name**, and **Mode Transparent Value** to the materials that should fade. Use the Setup Manager values as a starting point, then confirm any custom shader properties directly.
3. Enable **Character Fade** when the visible third-person body should disappear near the camera.
4. Enable **Obstructing Objects Fade** when walls, roofs, foliage, or props between the character and camera should become transparent.
5. Set **Transform Offset** to a stable point on the character, normally around the upper torso. This shared point controls both camera-to-character distance and the start of the obstruction cast.
6. Enter Play Mode with one known-compatible character material and one simple foreground object. Verify each fade separately before enabling broad automatic material conversion or testing a dense scene.

## Match the material properties

| Render setup | Color Property Name | Mode Property Name | Mode Transparent Value |
| --- | --- | --- | --- |
| Built-in render pipeline defaults | `_Color` | `_Mode` | `2` |
| URP or HDRP camera created by the current Setup Manager | `_BaseColor` | `_Surface` | `1` |
| Custom shader | The shader's alpha-bearing color property | The shader's surface or blend-mode property, when it has one | The value that selects transparent rendering |

The property names are converted to shader property IDs when Object Fader awakens, so configure them before entering Play Mode. A material can expose the expected property and still fail visually if its shader does not render alpha transparency.

**Auto Set Mode** controls obstructing-object eligibility only. A tracked character material that exposes **Mode Property Name** is temporarily placed in the configured transparent mode whenever character fading begins.

For HDRP setup context, see [High Definition Render Pipeline](https://opsive.com/support/documentation/ultimate-character-controller/integrations/high-definition-render-pipeline/).

## Choose a fade scenario

| Scenario | Recommended modes | Important choice | What to verify |
| --- | --- | --- | --- |
| Close third-person orbit or shoulder camera | **Character Fade** | Set **Start Fade Distance** above **End Fade Distance** | The body fades before the camera enters it and restores when the camera pulls away. |
| Top-down view beneath roofs or arches | **Obstructing Objects Fade** | Keep its **Collision Radius** at least as large as the Top Down View Type's collision radius | A supported foreground material fades instead of making Top Down raise its pitch. |
| Fixed 2.5D or Pseudo3D camera | **Obstructing Objects Fade** | Keep the cast corridor and material limits representative of the whole route | Foreground walls reveal the character without changing the fixed composition. |
| Third-person camera that can move very close and pass behind props | Both modes | Tune character distance and obstruction response independently | The character and foreground restore their original materials and colliders after each case. |
| First-person gameplay | Neither mode runs while first person is active | Let the perspective event disable Object Fader | No third-person material remains faded after the switch. |

Object Fader handles visibility; it does not replace the active View Type's camera-position collision. Configure [third-person camera collision](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/) first, then fade only the remaining visibility obstructions.

## Configure character fading

![Close third-person camera view through the partially transparent upper body and helmet of the character](https://opsive.com/wp-content/uploads/2018/03/CharacterFade.png?v=05db04891b87)

**Start Fade Distance** is where character alpha begins decreasing. **End Fade Distance** is where the tracked materials reach zero alpha. Keep Start greater than End; character alpha is calculated directly from the current distance and does not use **Fade Speed**.

**Cache Character Materials** controls when original material values are saved. Leave it enabled when materials keep the same values during play. Disable it when the same Material instances change values and the current values should be captured each time fading begins. Replacing a Material reference still requires that the new material be registered; newly added third-person Character Items and visible projectiles are handled by built-in events, while custom material replacement can use the runtime update method described in Developer details.

**Character Fade State Change Cooldown** delays character-fade reevaluation after a state changes. Use it when leaving aim or zoom briefly moves the camera through the fade distance and would otherwise flash the body transparent.

Materials are collected from child Renderers, including inactive children, when the character attaches. A material must expose **Color Property Name** to be included. Add **Ignore Fade Identifier** to a Renderer GameObject that should remain visible during character fading.

## Configure obstructing-object fading

![Top-down camera view with a foreground wall faded transparent to reveal the character in the room below](https://opsive.com/wp-content/uploads/2018/03/ObjectFading.png?v=a6e252027ae9)

Object Fader sphere casts from **Transform Offset** toward the current camera position. It ignores triggers and uses the Character Layer Manager's obstruction layers while temporarily excluding the character. The hit Collider and Renderer must be on the same GameObject for the current lookup to find that object's materials.

- **Collision Radius** controls the thickness of the obstruction-detection cast. Use a value large enough to catch the same foreground edges that block the active View Type.
- **Fade Speed** is the amount alpha moves on each update. Keep it greater than `0`; a value of `0` prevents a newly faded material from progressing or restoring.
- **Fade Color** supplies the target alpha for obstruction fading. The current implementation preserves each material's RGB values, so changing the Fade Color's RGB channels does not tint the obstruction.
- **Auto Set Mode** allows a hit material with the configured color property to be switched into transparent rendering. Leave it disabled when only deliberately prepared transparent materials should fade; enable it only after testing every likely foreground material.
- **Disable Collider** disables a qualifying faded obstruction's Collider so later physics queries do not keep treating the invisible object as solid. Leave it disabled when gameplay still needs that Collider, but understand that Top Down will then treat the object as an unresolved obstruction and may raise camera pitch.
- **Max Obstructing Collider Count** sizes the non-allocating sphere-cast result buffer. Extra hits beyond that capacity are not processed.
- **Max Obstructing Material Count** must cover all unique materials that can fade at once, not just the number of Colliders. Keep it greater than the Collider count when one obstruction can use multiple materials.

With **Auto Set Mode** disabled, an obstruction material must already use the transparent render queue as well as expose **Color Property Name**. Disabling its Collider additionally requires **Mode Property Name** and a mode equal to **Mode Transparent Value**. With Auto Set Mode enabled, Object Fader can set the configured mode while fading and restore the saved material state afterward.

## Verify in Play Mode

1. Start in a third-person View Type with a character attached to Camera Controller. Object Fader should be enabled and all tracked materials should begin at their original values.
2. Move the camera from outside **Start Fade Distance** to inside **End Fade Distance**, then back out. The character should fade continuously to invisible and restore without a color, render-queue, or blend-mode change remaining.
3. Repeat while crouching, aiming, zooming, equipping items, showing a projectile, changing states, and respawning. **Transform Offset** and **Character Fade State Change Cooldown** should prevent unwanted flashes.
4. Place one compatible foreground object between **Transform Offset** and the camera. It should approach the **Fade Color** alpha at **Fade Speed** and restore after leaving the cast.
5. Test an obstruction with several Colliders and materials, then test several simultaneous obstructions. Every expected material should fade without exceeding either maximum count.
6. If **Disable Collider** is enabled, inspect gameplay collision and raycasts while the object is faded and after it restores. The Collider should return when it is no longer obstructing.
7. Test the same object with **Auto Set Mode** disabled and enabled. Only deliberately transparent materials should fade in the first case; compatible hit materials may be converted temporarily in the second.
8. With [Third Person Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/), pass under fadeable and non-fadeable foreground geometry. Fadeable hits should retain the camera pitch only when the mode and Collider requirements are satisfied.
9. Switch to first person and back. Character and obstruction fades should clear on entry to first person and resume only after returning to third person.
10. Repeat the busiest obstruction route at the project's minimum and maximum target frame rates. Fade timing, material restoration, and processed object counts should remain acceptable.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Object Fader is disabled or nothing updates. | No character may be attached, or the active View Type may be first person. | Assign the Camera Controller character and test a third-person View Type. |
| The character does not fade near the camera. | **Character Fade** may be disabled, the material may lack **Color Property Name**, or **Ignore Fade Identifier** may exclude its Renderer. | Enable the mode, correct the shader property, and inspect the Renderer GameObject. |
| Character alpha changes in the wrong distance range. | **Start Fade Distance** may be less than or equal to **End Fade Distance**, or **Transform Offset** may be misplaced. | Keep Start greater than End and place the offset at the intended visual center. |
| Character fading flashes after aim or zoom. | A state change may move the camera through the threshold immediately. | Increase **Character Fade State Change Cooldown** enough for that camera state to settle. |
| A replaced character material does not fade or restore correctly. | Disabling **Cache Character Materials** does not discover a new Material reference. | Use the runtime replacement hook described in Developer details, or reattach/reinitialize the character after the custom swap. |
| An obstruction is detected but does not fade. | Its material may lack the color property or transparent queue, the layer may be ignored, the Collider may be a trigger, or its Renderer may be on another GameObject. | Correct the shader and hierarchy, use a processed solid layer, and keep the hit Collider with the Renderer. |
| A foreground object fades but Top Down still raises its pitch. | **Disable Collider** may be off, or the material may not expose the configured mode property and transparent value. | Enable collider disabling only when safe, then correct the mode mapping or enable **Auto Set Mode**. |
| The faded object still blocks gameplay queries. | **Disable Collider** may be off, or the material may fail the mode check. | Verify the mode property/value and enable collider disabling only if the object's gameplay collision may disappear. |
| Some simultaneous obstructions never fade. | The Collider hit buffer or unique-material buffer may be too small. | Raise both maximum counts for the worst camera corridor and keep the material count above the Collider count. |
| An obstruction fades but never restores. | **Fade Speed** may be `0`, or another Collider using the same material may still be inside the cast. | Use a positive speed and test every object sharing that Material. |
| Auto Set Mode changes more objects than intended. | Any hit material with the configured color property can qualify. | Disable it and prepare only the intended obstruction materials for transparency. |
| Fade Color does not tint the obstruction. | The current obstruction path preserves the material's RGB channels. | Use Fade Color to choose alpha; implement a custom fade override when a colored or dissolve effect is required. |
| Fading stops after switching to first person. | This is the intended perspective behavior. | Return to a third-person View Type; do not use Object Fader for first-person visibility. |

## Related pages

- [Camera Controller](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Third Person View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)
- [Third Person Top Down](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-top-down/)
- [Third Person Pseudo3D](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person-pseudo3d-2-5d/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [State Presets](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/)
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/)
- [High Definition Render Pipeline](https://opsive.com/support/documentation/ultimate-character-controller/integrations/high-definition-render-pipeline/)

## Developer details

`Awake` caches shader property IDs, allocates the obstruction buffers for modes enabled at startup, listens for Camera Controller character attachment, and disables the component until a third-person character is attached. Perspective changes restore all tracked fades and disable the component in first person.

Character fading registers unique materials from child Renderers that expose the configured color property, skipping Renderer GameObjects with `IgnoreFadeIdentifier`. Alpha is `Clamp01((distance - EndFadeDistance) / (StartFadeDistance - EndFadeDistance))`. Inventory-add and visible-projectile events add third-person materials; `UpdateMaterials(previousMaterial, targetMaterial)` supports a custom reference replacement. `OnCharacterIndependentFade` lets another system temporarily take control of character fading.

Obstruction fading uses `Physics.SphereCastNonAlloc` from the offset point toward the camera with `QueryTriggerInteraction.Ignore` and `IgnoreInvisibleCharacterWaterLayers`. Eligibility is cached per Material. `FadeMaterial` moves each channel by **Fade Speed** per update rather than per second, and obstruction calls preserve RGB while changing alpha.

`CanMaterialFade` returns true only when **Disable Collider** is enabled, the Material has **Mode Property Name**, and **Auto Set Mode** is enabled or the current mode equals **Mode Transparent Value**. The Top Down View Type calls this method to decide whether Object Fader can handle an obstruction instead of increasing pitch.

Maximum-count arrays are allocated during `Awake` or when a state first enables obstruction fading. Changing those counts after allocation does not resize existing arrays. Disabling a fade, changing to first person, changing character, or respawning restores saved material values and re-enables tracked Colliders.

---

<a id="page-ultimate-character-controller-camera-post-processing"></a>

# Post Processing

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/post-processing/)

Use post-processing to grade or stylize the gameplay view after deciding whether an effect should include the first-person arms and items. Ultimate Character Controller does not supply the effects; it controls which camera or render-pipeline pass draws those first-person objects.

## Before you begin

- Configure and verify the [Camera Controller](https://opsive.com/support/documentation/ultimate-character-controller/camera/) before adding effects.
- Decide whether the project uses the Built-in Render Pipeline, Universal Render Pipeline (URP), or High Definition Render Pipeline (HDRP). Do not mix one pipeline's post-processing package or setup with another pipeline.
- For URP or HDRP, install the pipeline package first. Then open **Tools > Opsive > Ultimate Character Controller > Setup Manager**, select **Project**, choose the matching **Render Pipeline**, and select **Import**. The Setup Manager will not import the UCC integration until it can detect the selected pipeline.
- On every first-person View Type, expand **Rendering** and confirm **Overlay Render Type**. Use **Second Camera** for the Built-in Render Pipeline, or **Render Pipeline** after the matching URP/HDRP integration is configured.

Version 3 supports Unity 2021.3 or newer, but the included Demo has a narrower requirement: URP 14.0.11 or newer. That URP version is a Demo requirement, not a requirement for a custom Built-in or HDRP scene. Use the render-pipeline package version supported by the project's Unity editor, then import the matching UCC integration. The URP 14 post-processing system is integrated with URP and is not compatible with Post Processing Stack v2.

## Set up the effect

1. Select the GameObject with both **Camera** and **Camera Controller**.
2. Configure the post-processing system for the active render pipeline:
   - **Built-in Render Pipeline:** Install a compatible post-processing solution. When using Post Processing Stack v2, configure its **Post-process Layer** and **Post-process Volume** components for the camera that should execute the effect.
   - **URP:** On the main camera, enable **Post Processing**. Select **GameObject > Volume > Global Volume**, create or assign a **Profile**, add the required overrides, and ensure the camera's **Volume Mask** includes the Volume GameObject's layer. See Unity's [URP 14 post-processing setup](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/integration-with-post-processing.html).
   - **HDRP:** Create or select a Global Volume and assign a Volume Profile. Confirm that **Post-process** is enabled in the camera's effective Frame Settings. See Unity's [HDRP Volumes](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@14.0/manual/Volumes.html) and [Frame Settings](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@14.0/manual/Frame-Settings.html).
3. If the camera has a first-person View Type, select that View Type under **Camera Controller > View Types**, expand **Rendering**, and choose the required **Overlay Render Type**.
4. Use the placement table below to decide which camera evaluates the effect.
5. Start with one obvious effect, such as a strong color adjustment or vignette. Verify its scope in Play Mode before adding the final effect stack.

## Choose which objects the effect includes

| Camera setup | Where to configure the effect | Expected result |
| --- | --- | --- |
| Third person | Main camera with **Camera Controller** | The effect applies to the complete gameplay frame. |
| First person with **Second Camera**; scene only | Main camera | The effect applies to the scene. The child **FirstPersonCamera** draws the arms and items afterward, so they are not processed by that effect. |
| First person with **Second Camera**; scene and first-person objects | Child **FirstPersonCamera** | The child camera processes the composed image, so the effect includes the scene, arms, and items. Do not duplicate the same full-screen effect on both cameras unless the double application is intentional. |
| First person with **Render Pipeline** | Main camera's post-processing and Volume setup | UCC draws the first-person overlay through the active URP or HDRP integration before normal full-frame post-processing, so the effect includes both the scene and first-person objects. |
| First person with **None** | Main camera | The effect includes everything rendered by the main camera, but this mode does not prevent arms or items from intersecting nearby geometry. |

This placement controls full-screen effects. A local Volume can still change by position, layer, priority, and blend distance according to the active render pipeline.

## Configure URP or HDRP overlay rendering

Post-processing can be configured correctly while first-person overlay rendering is still incomplete. Verify the UCC integration before judging the effect:

- **URP:** The imported integration supplies **OverlayForwardRendererData**. Add it to the active Universal Render Pipeline Asset's Renderer List and select that Renderer on the main Camera. The renderer draws opaque and transparent objects on UCC's Overlay layer before URP's post-processing pass.
- **HDRP:** Add the imported **Overlay Pass** prefab to the scene, then set the first-person View Type's **Overlay Render Type** to **Render Pipeline**. Follow the [High Definition Render Pipeline](https://opsive.com/support/documentation/ultimate-character-controller/integrations/high-definition-render-pipeline/) page for the remaining material and shadow setup.

If a project has several first-person View Types, keep **Overlay Render Type** consistent. Changing the setting on one View Type updates the other first-person View Types between **Second Camera** and **Render Pipeline**, and changing away from **Second Camera** removes the generated child-camera reference.

## Verify in Play Mode

1. Enter Play Mode in third person and pass through every local Volume used by the scene. The effect should blend at the intended position and should not change simply because the character moves while the camera remains outside the Volume.
2. Switch to first person with a visible item equipped. Compare the scene, hands, and item against the chosen scope in the table above.
3. Move the item close to a wall. With **Second Camera** or a configured **Render Pipeline** integration, the item should remain visible without clipping, and the post-processing scope should remain unchanged.
4. Trigger aim, zoom, recoil, damage, underwater, or other states that alter the camera or effect profile. Each transition should settle once and restore the previous effect when it ends.
5. If both perspectives are supported, switch between them repeatedly. The intended effect should remain active without a second application, flash, or stale Volume blend.
6. Verify the Game view and a player build on each target graphics API. The Scene view uses a different camera and is not proof that the gameplay camera is configured correctly.
7. Profile the final effect stack on the lowest supported hardware. Post-processing cost and feature support come from Unity and the selected pipeline, not from Camera Controller.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The effect works in third person but changes or disappears in first person. | **Overlay Render Type** or the effect's camera placement may not match the intended scope. | Choose **Second Camera** or **Render Pipeline** deliberately, then place the effect using the scope table. |
| The scene is processed but first-person arms and items are not. | With **Second Camera**, the effect is probably on the main camera. | Move the full-frame effect to **FirstPersonCamera** when it should include the final composite, or use the configured **Render Pipeline** mode. |
| The effect is much stronger in first person. | The same full-screen effect may run on both the main camera and **FirstPersonCamera**. | Keep it on only the camera responsible for the intended final scope. |
| URP shows no post-processing. | **Post Processing** may be disabled, the Global Volume may have no Profile or overrides, or **Volume Mask** may exclude its layer. | Enable the camera setting, assign the Profile, enable its overrides, and correct **Volume Mask**. |
| URP processes the scene but first-person objects clip or render in the wrong order. | The main Camera may not use **OverlayForwardRendererData**, or the UCC UniversalRP integration may be missing. | Import the URP integration, add its renderer data to the active pipeline asset, select that Renderer on the camera, and use **Render Pipeline**. |
| HDRP shows no effect. | The Volume may be excluded or **Post-process** may be disabled in the effective Camera Frame Settings. | Correct the Volume layer/profile and enable the Frame Setting before changing UCC fields. |
| HDRP first-person objects render incorrectly. | The **Overlay Pass** prefab, integration, or **Overlay Render Type** may be missing. | Import the HDRP integration, add **Overlay Pass**, and select **Render Pipeline**. |
| A URP project uses Post Processing Stack v2 components but has no result. | URP's integrated post-processing is not compatible with Stack v2. | Remove the Stack v2 camera setup and use URP's **Post Processing**, **Volume**, and **Volume Profile** workflow. |
| The Scene view and Game view do not match. | Each view is rendered by a different camera and can evaluate different Volumes. | Validate the configured Camera Controller in the Game view and a build. |
| An effect fails only on a device or graphics API. | The selected pipeline or effect may not support that target; for example, URP 14 does not support post-processing on OpenGL ES 2.0. | Check the matching Unity pipeline documentation, choose a supported graphics API, or replace the unsupported effect. |

## Related pages

- [Camera Controller](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [First Person View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [Included View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Importing and Demo requirements](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/)
- [High Definition Render Pipeline](https://opsive.com/support/documentation/ultimate-character-controller/integrations/high-definition-render-pipeline/)

## Developer details

With **Second Camera**, UCC creates a child GameObject named `FirstPersonCamera`. At runtime its Camera clears depth, renders after the main Camera, and uses **First Person Culling Mask**. This ordering is why a full-screen effect on the main camera excludes the later first-person overlay, while the equivalent effect on the child camera can process the composed frame.

With **Render Pipeline**, UCC does not use that child camera. While first person is active, the runtime adds **First Person Culling Mask** to the main Camera's culling mask; it removes that mask after returning to third person. The bundled URP renderer data schedules its overlay opaque pass before normal opaques and its overlay transparent pass after normal transparents but before URP's post-processing event. The bundled HDRP integration uses a Custom Pass Volume for the Overlay layer.

Pipeline detection is capability-based: the editor checks for URP renderer types or HDRP's `CustomPassVolume` and adds the matching compile symbol. There is no separate UCC post-processing component or effect API; effect availability, Volume behavior, injection points, and platform limits belong to the installed Unity render pipeline or third-party post-processing solution.

---

<a id="page-ultimate-character-controller-camera-split-screen"></a>

# Split Screen

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)

Use split screen when two or more local players need independent characters, cameras, controls, and HUDs in the same scene. Each player requires a complete camera-to-character assignment, while **Material Swapper** keeps a first-person player's third-person body visible to the other cameras.

Without per-camera material swapping, another player's view can render the materials intended only for the local first-person camera:

![Two-player split screen before Material Swapper coordinates the first- and third-person materials, causing an incorrect character render in the other camera.](https://opsive.com/wp-content/uploads/2020/03/SplitScreenNoSwap.png?v=b6e93d4335d0)

With Material Swapper on the required camera GameObjects, each view renders the correct body and first-person objects:

![Two-player split screen after Material Swapper coordinates both players' camera renders, with the intended character bodies and first-person weapon visible.](https://opsive.com/wp-content/uploads/2020/03/SplitScreen.png?v=7d722d9eca06)

## Before you begin

- Follow [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) so the scene managers, render-pipeline integration, first camera, and one character work before duplicating anything.
- Create a separate playable character for every local player with [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/). Test each character's Movement Type, View Types, inventory, and input separately first.
- Decide the number of players, viewport layout, input-device ownership, and HUD layout before building the duplicates.
- Treat this as a local multiplayer setup. UCC does not use this workflow to provide network spawning, ownership, replication, device joining, or synchronized game state.

## Set up the player cameras

1. Select the working camera GameObject that contains **Camera**, **Camera Controller**, and **Camera Controller Handler**.
2. Duplicate the complete camera GameObject once for each additional local player. Keep any child **FirstPersonCamera** with its parent when the first-person View Type uses **Overlay Render Type > Second Camera**.
3. Give every camera a clear player-specific name, such as `Player 1 Camera` and `Player 2 Camera`.
4. Keep exactly one enabled **Audio Listener** in the scene. Remove or disable it on the other cameras. UCC does not split or mix listener output per viewport.
5. On the first **Camera Controller**, expand **Character**, keep **Init Character On Awake** enabled, and assign Player 1 to **Character**. Assign Player 2 to the second Camera Controller, and repeat for additional players. Do not leave **Character** empty and rely on the shared **Player** tag in a multi-character scene.

![Camera Controller Character settings with Init Character On Awake enabled and the second player's character assigned.](https://opsive.com/wp-content/uploads/2020/02/SplitScreenCameraCharacter.webp?v=ad0eae8b8753)

6. Confirm that each camera has the intended first-person or third-person View Types and that each View Type uses the correct Movement Type on its assigned character.
7. Set each Camera's **Viewport Rect** to a unique normalized screen region using **X**, **Y**, **W**, and **H**.

![Camera Viewport Rect configured with X 0.5, Y 0, W 0.5, and H 1 for the right half of a two-player split.](https://opsive.com/wp-content/uploads/2020/02/SplitScreenCameraViewport.webp?v=495d15847d76)

## Add Material Swapper

Add **Material Swapper** to every main camera GameObject that contains **Camera Controller**. Assign **Invisible Material** to the pipeline-compatible invisible shadow caster used by the characters, and leave **Manual Swap** disabled for automatic per-camera rendering.

| Active rendering path | Required Material Swapper locations |
| --- | --- |
| **Overlay Render Type > Second Camera** | Main Camera Controller GameObject and its child **FirstPersonCamera**, for every local player |
| **Overlay Render Type > Render Pipeline** | Main Camera Controller GameObject only; the URP or HDRP integration must already be configured |
| **Overlay Render Type > None** | Main Camera Controller GameObject only, although first-person objects can intersect scene geometry in this mode |
| Third-person-only local player | Material Swapper is not required; omit it unless a first-person View Type is added to that camera before Play Mode |

The Built-in Render Pipeline normally uses **Second Camera**. URP and HDRP normally use **Render Pipeline**, but the component requirement follows **Overlay Render Type**, not the pipeline name.

![Hierarchy with left and right Camera Controller GameObjects and their child First Person Cameras, while the selected main camera has Material Swapper and Invisible Material assigned.](https://opsive.com/wp-content/uploads/2020/02/MaterialSwapper.webp?v=f2f716fa5ef7)

The component restores the character's normal third-person materials when its own camera is not rendering, then applies the correct first-person visibility only for that camera's render. This allows another player's camera to see the complete body.

### First-person-only character packages

When Character Manager creates a first-person-only character without a third-person Movement Type, it replaces the selected third-person Renderer materials with the invisible shadow caster. Material Swapper cannot restore materials that were already invisible when it cached them. Restore the real body, head, arms, and item materials on those Renderers before testing split screen.

![Renderer Materials list with Element 0 restored to the Helmet material instead of an invisible shadow caster.](https://opsive.com/wp-content/uploads/2020/08/FirstPersonSplitScreenRendererMaterial.webp?v=226edda01255)

Do not remove the **Third Person Object** identifiers. They tell the perspective and material systems which Renderers belong to the visible third-person body.

## Choose a viewport layout

Camera **Viewport Rect** values are normalized from `0` to `1`, with the origin at the bottom-left of the screen:

| Layout | Player | X | Y | W | H |
| --- | --- | ---: | ---: | ---: | ---: |
| Two players, left and right | Player 1 | 0 | 0 | 0.5 | 1 |
|  | Player 2 | 0.5 | 0 | 0.5 | 1 |
| Two players, top and bottom | Player 1 | 0 | 0.5 | 1 | 0.5 |
|  | Player 2 | 0 | 0 | 1 | 0.5 |
| Four equal quarters | Player 1, top-left | 0 | 0.5 | 0.5 | 0.5 |
|  | Player 2, top-right | 0.5 | 0.5 | 0.5 | 0.5 |
|  | Player 3, bottom-left | 0 | 0 | 0.5 | 0.5 |
|  | Player 4, bottom-right | 0.5 | 0 | 0.5 | 0.5 |

Choose the split direction around the game's sight lines and interface. A horizontal split gives each player more width; a vertical split gives each player more height. Test the final target aspect ratios rather than judging only one Game view size.

## Assign player-specific input

Each character must resolve a different `IPlayerInput` implementation. A second camera does not separate controls by itself.

- **Unity Input System:** Give every character its own **Player Input Proxy** and child input GameObject with both Opsive's **Unity Input System** component and Unity's **Player Input** component. On **Player Input Proxy**, assign **Player Input** to that same character's Opsive input component. Pair a distinct device or control scheme with each Unity Player Input; sharing the same unpaired action asset is not device ownership.
- **Rewired:** Give every character its own **Rewired Input** component and unique Rewired player assignment, then point that character's **Player Input Proxy > Player Input** to it. See [Rewired](https://opsive.com/support/documentation/ultimate-character-controller/integrations/rewired/).
- **Legacy Input Manager:** Global axis names are not player identities. Use separate mappings and a player-specific input implementation, or choose the Input System/Rewired when devices must join and pair dynamically.

Follow [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) for the UCC input layer. Device pairing, local-player joining, and per-player UI navigation remain responsibilities of the chosen input system.

## Assign a HUD to each player

1. In **Setup Manager > Scene**, use **UI Setup > Add UI** to create the first HUD if the scene does not already have one.
2. Duplicate the player HUD hierarchy for each additional player.
3. On every **Character Monitor**-derived component in the first HUD, assign Player 1 to **Character**. Assign Player 2 throughout the second HUD, and repeat for the other players. Leave **Attach To Camera** enabled when the monitor should follow later Camera Controller character changes; disable it when the HUD must remain locked to its explicit Character.

![Attribute Monitor Inspector with its Character field assigned to the second player's character.](https://opsive.com/wp-content/uploads/2020/04/SplitScreenUI.webp?v=36a47e812961)

4. Constrain each HUD root to the same screen region as its camera. For a Screen Space - Overlay Canvas, anchor and clip each player's root panel to that player's half or quarter. For a Screen Space - Camera Canvas, assign the corresponding player camera and confirm the Canvas fills only that camera's viewport.
5. Test crosshairs, damage indicators, item monitors, menus, and pointer input separately. Interactive per-player menus may need the input system's multiplayer UI/Event System setup; duplicating Character Monitors only separates the UCC data source.

## Key multiplayer constraints

- Use one local Camera Controller, character, input instance, and HUD assignment per player. Remote network characters normally do not receive a local Camera Controller or local input.
- Keep only one Audio Listener unless a separate audio solution explicitly supports multiple listeners.
- Material Swapper handles first-/third-person Renderer materials. It does not divide culling layers, post-processing Volumes, UI canvases, audio, or input devices.
- Every gameplay camera renders its own viewport, so rendering cost grows with the number of cameras. Profile the final scene with all players active.
- Camera-relative effects can differ because each camera evaluates its own culling mask, View Type, post-processing, Object Fader, and Volume position. Configure shared effects deliberately; see [Post Processing](https://opsive.com/support/documentation/ultimate-character-controller/camera/post-processing/).
- Runtime joining requires the spawning system to create or assign the character, camera, viewport, input, HUD, and Material Swapper relationship. UCC does not automatically rearrange existing viewports when a player joins or leaves.

## Verify in Play Mode

1. Start with all local players visible. Each viewport should occupy only its assigned rectangle, without gaps or unintended overlap.
2. Move and look with one device at a time. Only the intended character and its camera should respond.
3. Equip a visible first-person item for every player. In each player's own view, arms and items should render correctly; in every other view, that character's complete third-person body and item should remain visible.
4. Switch each supported character between first and third person. No body, head, arms, item, muzzle flash, or shadow material should remain in the wrong state after the switch.
5. Damage, heal, equip, reload, aim, and kill one character at a time. Only that player's HUD should update.
6. Verify that only one Audio Listener is enabled and that no multiple-listener warning appears in the Console.
7. Test local Volumes, Object Fader, camera collision, zoom, and screen-space effects in every viewport.
8. Respawn or replace each character. Its Camera Controller, Material Swapper, input proxy, and Character Monitors should attach to the replacement without changing the other players.
9. Test the target display resolutions and profile CPU/GPU frame time with the maximum supported player count.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Both cameras follow the same character. | One **Character** field may be empty, duplicated, or falling back to the shared **Player** tag. | Keep **Init Character On Awake** enabled and explicitly assign a different Character on every Camera Controller. |
| One device moves both characters. | The characters may share the same input component, device pair, control scheme, or legacy mapping. | Give each character its own Player Input implementation and pair distinct devices or player IDs. |
| Another viewport sees a headless or armless character. | Material Swapper may be missing from a main camera, its child **FirstPersonCamera**, or its **Invisible Material** may be wrong. | Add the component at every location required by **Overlay Render Type** and assign the matching pipeline material. |
| A first-person-only character remains invisible to other players. | Its original third-person Renderer materials may already have been replaced by the invisible shadow caster during character creation. | Restore the real Renderer materials while keeping the Third Person Object identifiers. |
| Unity reports multiple Audio Listeners. | Duplicating the camera also duplicated Audio Listener. | Keep one enabled listener and remove or disable the others. |
| One camera covers the entire screen. | Its **Viewport Rect** may still be X `0`, Y `0`, W `1`, H `1`, or its render order may hide the other view. | Apply the complete layout table to every camera and check for other full-screen cameras. |
| A HUD shows the wrong health, item, or crosshairs. | One or more Character Monitors may reference the wrong **Character**, or **Attach To Camera** may follow another Camera Controller assignment. | Audit every monitor in that HUD and choose either one explicit Character or the intended camera-follow behavior. |
| Both HUDs render over the full display. | Their Canvas or root RectTransforms may not match the player viewports. | Anchor/clip Overlay HUD roots or assign each Screen Space - Camera Canvas to its player camera. |
| First-person materials flicker or stay swapped. | **Manual Swap** may be enabled, a required child swapper may be absent, or a character/camera may have been replaced without reattachment. | Disable Manual Swap for the automatic workflow, complete the component layout, and reassign Camera Controller **Character** after runtime replacement. |
| Performance drops sharply with more players. | Every camera repeats scene culling and rendering, and each HUD/effect can add work. | Profile per camera, reduce expensive effects and visible geometry, and set a supported local-player limit. |

## Related pages

- [Camera Controller](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Rewired](https://opsive.com/support/documentation/ultimate-character-controller/integrations/rewired/)
- [First Person View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [Post Processing](https://opsive.com/support/documentation/ultimate-character-controller/camera/post-processing/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)

## Developer details

`MaterialSwapper` listens to the Camera Controller's `OnCameraAttachCharacter` event. For the Built-in Render Pipeline it wraps its Camera's render through `OnPreRender` and `OnPostRender`; for URP and HDRP it filters `RenderPipelineManager.beginCameraRendering` and `endCameraRendering` to that same Camera. It shows the assigned character's first-person materials and hides the appropriate third-person materials only while that camera renders, then restores the third-person state for other cameras.

On a main camera, the swap mask depends on the first First Person View Type. A single-camera or render-pipeline path swaps both first- and third-person Renderers. With **Second Camera**, the main camera swaps the third-person Renderers and the child camera swaps first-person Renderers. The editor warns when a referenced child First Person Camera does not have Material Swapper.

The component caches Renderers under `FirstPersonBaseObject` and `ThirdPersonObject`, updates its cache when inventory items are added, cooperates with Object Fader during multi-camera renders, and restores materials on perspective changes and respawn. **Manual Swap** disables automatic callbacks; a custom system must call `EnableFirstPersonMaterials` and `EnableThirdPersonMaterials` at the correct render boundaries.

Camera Controller initializes a serialized **Character** only when **Init Character On Awake** is enabled. If that field is enabled and Character is empty, it searches the **Player** tag; if it is disabled, the serialized Character is cleared so a runtime manager can assign `CameraController.Character` later. Character Monitor can either hold its explicit **Character** or update it from its associated camera when **Attach To Camera** is enabled.

When a networking integration defines multiplayer support, Perspective Monitor keeps remote non-spectator characters in third-person materials and applies first-person visibility only to local players or spectators. That network rule does not create local split-screen cameras, inputs, viewports, or HUDs.

---

<a id="page-ultimate-character-controller-items-inventory"></a>

# Items & Inventory

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)

The built-in Ultimate Character Controller inventory keeps track of the item types and amounts a character owns, then coordinates pickups, equipment combinations, visible Character Items, Item Actions, and their animation. Use it when the inventory exists mainly to support character-controlled weapons, ammo, consumable amounts, and other usable equipment.

An Item Type is both an Item Definition and an Item Identifier in the built-in workflow. The definition identifies what the item is, while the Character Item GameObject supplies the perspective visuals, actions, equip behavior, and animation used by the character.

## Choose the built-in inventory or Ultimate Inventory System

Use the built-in inventory when the character needs to pick up, equip, use, unequip, and drop items without a full inventory interface or item database.

Use [Ultimate Inventory System](https://opsive.com/support/documentation/ultimate-inventory-system/) when the project needs features such as a player-facing inventory UI, multiple unique instances with dynamic attributes, inventory-size rules, or skinned clothing and equipment. The [UCC integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) lets Ultimate Inventory System own the inventory data while UCC Character Items continue to handle equipped visuals, actions, and character animation.

## Recommended workflow

1. Define the Item Type and any Categories in **Tools > Opsive > Ultimate Character Controller > Item Type Manager**.
2. Create the Character Item with **Tools > Opsive > Ultimate Character Controller > Item Manager**, including the required first-person, third-person, or combined perspective setup.
3. Add an Item Pickup so the character can acquire the item during gameplay.
4. Configure Inventory ownership, Item Slots, and Item Set Rules so the item can be equipped in valid combinations.
5. Add the Character Item Action that performs the item's work, such as a shootable, melee, shield, magic, or throwable action.
6. Configure the Animator Audio State Set and Animator values that coordinate equip, use, and unequip timing.

Complete and verify each stage before moving to the next. A missing Item Type or slot can look like an action or animation problem later in the workflow.

## Define item data

- [Item Type, Definition & Category](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/) explains the relationship between definitions, identifiers, Item Types, and Categories. Read this first when deciding how an item should be identified or grouped.
- [Item Type Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-types/) uses the Item Type Manager to create the Item Collection, Item Types, and Categories needed by the built-in inventory.

## Create and collect an item

- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) uses the Item Manager to build a new Character Item prefab or attach an item to a character, including perspective visuals, actions, slots, and loadout choices.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) configures a world object that gives item amounts to a character through trigger or input-driven pickup behavior.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) covers item ownership, default loadouts, amounts, pickup and drop behavior, and the runtime API.

## Equip and use items

- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) explains why each equipped item needs a logical slot and how slots map equipped combinations to Animator item IDs.
- [Item Set & Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) defines which item combinations are valid, which group can be active, and which states an equipped set activates.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) covers the GameObject that is equipped, its first- and third-person visuals, and the Character Item Actions that perform gameplay behavior.

## Coordinate animation and audio

- [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/) coordinates animation-event timing, delays, audio clips, and states for an item action.
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/) explains the character Animator parameters and events that the item setup must match.

## Editor checkpoints

Before entering Play Mode, confirm that:

- The Item Type Manager lists the intended Item Type and Categories in an Item Collection.
- The Item Manager produces a Character Item or prefab with the expected Item Type, slot, perspective objects, and Character Item Action.
- The character has an Inventory and Item Set Manager with rules that can form the intended equipment combination.
- The Animator Item ID and Animator Audio State Set match the character and item animation setup.
- A runtime pickup references the same item definition and a positive amount.

## Verify in Play Mode

1. Approach or activate the Item Pickup and confirm that the Inventory amount increases.
2. Equip the item and confirm that the Item Set Manager activates the expected set and slot.
3. Confirm that the correct visible item appears for the active perspective. In a character with both perspectives, switch views and check both objects.
4. Trigger the item's action and confirm that its gameplay result, animation, and audio occur once at the configured timing.
5. Unequip or drop the item and confirm that the visible object and Inventory amount update as expected.

If pickup succeeds but equip does not, inspect the slot and Item Set Rules before changing the action. If equip succeeds but use does not, inspect the Item Ability, Character Item Action, Animator Item ID, and Animator Audio State Set.

## Key terminology

- **Inventory:** Tracks the item identifiers and amounts owned by the character.
- **Item Type:** The built-in ScriptableObject that acts as both an Item Definition and Item Identifier.
- **Item Identifier:** Identifies the item instance used by Inventory, pickups, slots, and Character Items.
- **Character Item:** The GameObject the character equips, uses, unequips, and can drop.
- **First Person Perspective Item:** Supplies the visuals rendered for the first-person view.
- **Third Person Perspective Item:** Supplies the visuals rendered for the third-person view.
- **Character Item Action:** Performs a usable behavior such as shooting, melee, blocking, magic, or throwing.
- **Item Set:** A valid combination of items that can be equipped together.
- **Item Set Rule:** Produces valid Item Sets from the available items and slots.
- **Item Set Group:** Allows one Item Set in that group to be active while other groups may remain active in parallel.

## Related tasks

- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)

---

<a id="page-ultimate-character-controller-items-inventory-item-types"></a>

# Item Type Creation

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-types/)

Use the Item Type Manager to create the shared identities, categories, capacities, and Character Item prefab references used by the built-in UCC Inventory.

## Before you begin

This workflow applies when the standard Ultimate Character Controller Version 3 Inventory owns the items. If [Ultimate Inventory System](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) owns the inventory, create UIS Item Categories and Item Definitions instead, then connect their Character Item prefabs through that integration. Do not maintain a duplicate UCC Item Type for the same UIS-owned item.

Save the collection in a project-owned folder outside the Opsive package. Standard UCC characters that exchange items should use the same Item Collection so their Item Type and Category IDs resolve consistently.

## Create an Item Collection

1. Open **Tools > Opsive > Ultimate Character Controller > Item Type Manager**.
2. In **Item Collection**, select an existing project collection or select **Create**.
3. Save the new asset as `ItemCollection.asset` in a project-owned folder.
4. Keep that collection selected while creating Categories and Item Types.

![Item Type Manager with an empty Item Collection field and the Create button available.](https://opsive.com/wp-content/uploads/2022/10/ItemTypesNoCollection.png?v=cf0aaf188896)

The new collection contains an **Items** Category. The manager also creates an **Individual Item Set Rule** asset beside the collection as a starting rule. Item Types and Categories are stored as sub-assets of the collection, so create and edit them through this manager rather than as unrelated assets in the Project window.

## Create Categories

Categories group Item Types for Item Set groups and category-based Item Set Rules.

1. Select the **Categories** tab.
2. Enter `Weapons` in **Name**, then select **Add**.
3. Add `Ammo` for inventory-only ammunition.
4. Add another Category only when a rule or equipment group needs that distinction.
5. Select a Category row to rename it. Names must be nonempty and unique within the collection.

![Categories tab listing the Categories stored in the selected Item Collection.](https://opsive.com/wp-content/uploads/2022/10/ItemTypeCategories.png?v=988408b7b6f2)

Each Category row provides **Duplicate** and **Remove** controls. Duplicating creates a new Category with a newly generated ID and a numbered name. Removing is blocked while any Item Type still selects that Category.

![Category row controls for duplicating and removing the selected Category.](https://opsive.com/wp-content/uploads/2022/10/ItemTypeCategoryOptions.png?v=7f814ddc6995)

The Version 3 manager presents a flat Category list; it does not provide an editor-authored parent hierarchy. An Item Type may select multiple Categories. At runtime UCC represents those selections through a temporary composite Category so category membership checks can match each selected Category.

## Create Item Types

Create one Item Type for each distinct built-in inventory identity.

1. Select the **Item Types** tab.
2. Enter `Rifle` in **Name**, then select **Add**.
3. Select the Rifle row to expand **Name**, **Category**, **Capacity**, and **Prefabs**.
4. Set **Category** to Weapons.
5. Set **Capacity** to `1` when the character may own only one Rifle.
6. Leave **Prefabs** empty until the Character Item prefab exists. Return after completing [Item creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) and assign the Rifle Character Item prefab.
7. Repeat the workflow for `Iron Sword` with Category Weapons and Capacity `1`.
8. Create `Rifle Ammo`, select Category Ammo, set an appropriate reserve Capacity such as `120`, and leave **Prefabs** empty when ammunition never appears on the character.

A new Item Type selects the collection's first Category, defaults Capacity to `2,147,483,647`, and starts without Prefabs. Review all three defaults for every new type.

![Item Types tab listing Item Types in the selected Item Collection.](https://opsive.com/wp-content/uploads/2018/03/ItemTypesSetup.png?v=4d9881d2723f)

An Item Type row provides three controls: **Identify** selects and pings the sub-asset, **Duplicate** copies its configuration under a unique numbered name, and **Remove** deletes it.

![Item Type row controls for identifying, duplicating, and removing the Item Type asset.](https://opsive.com/wp-content/uploads/2022/10/ItemTypeOptions.png?v=be3dd7f24a27)

![Expanded Assault Rifle Item Type showing its Name, Category, Capacity, and Prefabs fields.](https://opsive.com/wp-content/uploads/2022/10/ItemTypeAssaultRifle.png?v=0bea076d72e7)

## Choose the important Item Type settings

### Name

The name must be nonempty and unique within the collection. The manager compares names without regard to case, while runtime name lookup is exact. Use serialized asset references inside Unity. If external data must use IDs, keep the collection stable and migrate changes; reserve names for readable editor workflows.

### Category

**Category** is a multi-select field. A Rifle can belong to Weapons and another project Category when both memberships have a real rule purpose.

Assign a Category even to count-only resources such as Rifle Ammo. In the current runtime, an Item Definition with no resolved Category is treated as a member of every Item Set group by `ItemSetManagerBase.IsCategoryMember`, which is broader than most projects intend.

### Capacity

**Capacity** is the maximum amount the standard Inventory accepts for that Item Type. New Item Types default to `2,147,483,647`. Replace that default with a deliberate nonnegative value:

- use `1` for one unique Rifle or Iron Sword;
- use at least `2` when one Item Type represents two identical equipped pistols; and
- use the intended reserve limit for Rifle Ammo.

The Inventory clamps additions to Capacity. Capacity belongs to the built-in Item Type model; an integrated inventory can enforce its own amount rules instead.

### Prefabs

**Prefabs** contains optional Character Item prefabs. Add one tested prefab for a normal visible or equippable item. Add separate prefabs when the same Item Type needs different slot-specific Character Items, such as right- and left-hand pistol prefabs. Leave the list empty for an identity that exists only as an Inventory amount, such as reserve ammunition.

The prefab is not the Item Type. Its **Character Item > Item Definition** must point back to this Item Type, and its slot, perspective objects, actions, Animator values, and drop settings remain part of the [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/).

## Editor checkpoint

Before entering Play Mode, confirm that:

- the manager shows the intended project-owned **Item Collection**;
- Rifle and Iron Sword select Weapons, while Rifle Ammo selects Ammo;
- every Item Type has a deliberate Capacity;
- each visible or equippable Item Type references the correct Character Item prefab;
- each prefab's **Item Definition** points back to the same Item Type; and
- the character's **Item Set Manager > Item Collection** uses this collection.

## Understand how Item Types are used

An Item Type is both UCC's built-in Item Definition and its Item Identifier. Calling `CreateItemIdentifier()` on an Item Type returns the Item Type itself. The standard Inventory therefore stores one amount for Rifle Ammo, not one runtime identifier per round.

The surrounding systems use that identity in different ways:

- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) stores amounts, enforces Capacity, and can spawn the Character Item prefabs.
- [Character Items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) use **Item Definition** to connect visible objects and Item Actions to the identity.
- [Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) match exact Item Types, Categories, slots, or supported combinations to generate valid equipment sets.
- [Item Pickups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) grant **Item Definition Amounts**.
- Loadouts store an Item Definition and amount.
- Action modules may consume another definition. For example, **Item Ammo > Ammo Item Definition** can point to Rifle Ammo while the Rifle Character Item owns the [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/).

The Item Type does not decide whether an item is shootable, melee-capable, throwable, or magic. That behavior belongs to the Character Item's actions and modules.

## Know the Version 3 manager limits

The released Version 3 Item Type Manager does not provide search, filtering, folders within a collection, Item Type parent inheritance, or arbitrary attributes. `ItemType.GetParent()` returns `null`, and exact Item Type matching compares an identifier's definition directly with the Item Type.

Use clear, unique names and deliberate Categories to keep a larger flat collection understandable. Use Character Item components, Item Actions, states, and modules for controller behavior. Use [Ultimate Inventory System](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) when definitions need inherited categories, attributes, mutable per-item data, inventory UI, shops, crafting, or richer persistence.

## Verify in Play Mode

1. Give the character one Rifle, one Iron Sword, and Rifle Ammo through **Inventory > Default Loadout** or scene pickups.
2. Expand **Inventory > Current Inventory**. Confirm each Item Type appears with the expected amount.
3. Collect enough Rifle Ammo to exceed its Capacity. Confirm only the amount up to Capacity is accepted.
4. Equip Rifle, then Iron Sword. Confirm the correct Character Item prefab appears and the intended Item Set becomes active.
5. Fire and reload Rifle. Confirm Rifle Ammo decreases while the Rifle amount remains unchanged.
6. Test any Item Type with multiple Categories against each intended category-based rule and confirm it does not create an invalid equipment combination.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Add** is disabled | **Item Collection**, **Name**, and duplicate names | Select a collection and enter a nonempty name that is unique without regard to case. |
| A character cannot resolve an Item Type | The manager and character may use different Item Collections | Assign the same project collection to the character's Item Set Manager and rebuild any mismatched loadout or rule references. |
| The character owns an item but no object appears | Item Type **Prefabs**, Character Item **Item Definition**, slot, and Inventory **Auto Spawn Destroy Runtime Character Items** | Assign the correct prefab and make its definition and slot agree with the Item Type and Item Set Rule. |
| The amount stops increasing | Item Type **Capacity** and current Inventory amount | Raise the intended Capacity or reduce the granted amount. Do not create a duplicate Item Type to bypass the limit. |
| An item matches an unrelated Item Set group | Item Type **Category**, group Category, and rule | Assign a deliberate Category and narrow the rule to the required Category, Item Type, or slot combination. |
| A Category cannot be removed | One or more Item Types still select it | Move those Item Types to valid Categories before removing it. |
| Rifle will not reload | Shootable Action's **Ammo Item Definition** and Rifle Ammo amount | Assign the exact Rifle Ammo Item Type and confirm the Inventory owns a positive amount. |
| A duplicated Item Type behaves like the original | Duplicate copies Category, Capacity, and Prefabs | Give it the intended name and review every copied field before using it as a distinct identity. |

## Protect saved and networked identities

Item Type IDs are unique only within their Item Collection. A new Item Type receives the next array index as its ID. Removing an Item Type causes the manager to reassign the remaining Item Type IDs from their current indexes. Do not remove a shipped Item Type without migrating saved or networked IDs.

The standard Inventory does not provide a complete general-purpose save file. A save integration should record the Item Type ID and amount, restore them against the same Item Collection, and then restore the intended Item Set. Category IDs are generated independently, but recreating a Category creates a different identity.

UCC's conditional multiplayer inventory hooks pass Item Identifiers, and `ItemIdentifierTracker` maps built-in Item Type IDs through an Item Collection. Every peer must use matching collection data, and mutations should occur on the authoritative instance. These hooks do not supply a networking transport or a complete replication layer.

When UIS owns the inventory, save and replicate UIS Items and collections through the [UIS integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/), then let its bridge create the UCC Character Item representation.

## Related tasks

- [Item Type, Definition, and Category](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/) explains the complete data-model relationship.
- [Create a Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds the prefab referenced by **Prefabs**.
- [Configure Character Items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) covers slots, perspective objects, actions, and runtime behavior.
- [Configure Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) maps slot-specific Character Item prefabs.
- [Configure Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) controls owned amounts and loadouts.
- [Configure Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) uses Item Types and Categories to generate valid equipment.
- [Configure Item Pickups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) grants Item Definitions and amounts from world objects.
- [Connect Ultimate Inventory System](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) replaces built-in identity and inventory ownership with UIS.

## Developer reference

`ItemCollection` exposes `GetItemType(uint)`, `GetItemType(string)`, `GetCategory(uint)`, and `GetCategory(string)`. The built-in `ItemType` derives from `ItemDefinitionBase`, implements `IItemIdentifier`, and returns itself from both `CreateItemIdentifier()` and `GetItemDefinition()`.

```csharp
using Opsive.Shared.Inventory;
using Opsive.UltimateCharacterController.Inventory;

public static class ItemTypeExample
{
    public static int AddRifleAmmo(
        ItemCollection itemCollection,
        InventoryBase inventory,
        int amount)
    {
        if (itemCollection == null || inventory == null) {
            return 0;
        }

        var ammoType = itemCollection.GetItemType("Rifle Ammo");
        if (ammoType == null) {
            return 0;
        }

        IItemIdentifier ammoIdentifier = ammoType.CreateItemIdentifier();
        return inventory.AddItemIdentifierAmount(ammoIdentifier, amount);
    }
}
```

`AddItemIdentifierAmount` returns the amount actually accepted after Capacity is applied. Query the current amount with `GetItemIdentifierAmount`, remove it with `RemoveItemIdentifierAmount`, or use `PickupItem` when the operation should also send pickup notifications and participate in Character Item spawning.

Amount changes send `OnInventoryAdjustItemIdentifierAmount` with `(IItemIdentifier, int previousAmount, int newAmount)`. Pickups send `OnInventoryPickupItemIdentifier` with `(IItemIdentifier, int amount, bool immediatePickup, bool forceEquip)`. Spawning a Character Item also participates in the Character Item add, pickup, equip, unequip, and remove events. Editing Item Type or Category asset data does not itself send an Inventory runtime event.

---

<a id="page-ultimate-character-controller-items-inventory-item-creation"></a>

# Item Creation

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)

The Item Manager turns an Item Definition, optional visible models, and one or more actions into a Character Item that the Inventory can spawn, equip, use, and drop. For most projects, build a reusable Character Item prefab and let each character's Inventory create it at runtime.

## Before you begin

Prepare these parts before opening the Item Manager:

- A character with item support, an **Inventory**, an **Item Set Manager**, and the required first- and third-person [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/).
- An **Item Collection** assigned to that Item Set Manager.
- An Item Type in that collection, with the categories and capacity required by its Item Set Rules. See [Item Type, Definition, and Category](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/).
- Scene instances of any visible model or prefab variant that the builder will copy. The **Item** field does not accept a persistent prefab asset directly; drag the asset into the scene first.
- Animator Controllers and animation clips when the item has its own animation. The builder can add required parameters to an assigned controller, but it does not create the item's animation states or clips.

A Character Item can be invisible, such as a Body or unarmed action, but the Item Manager still requires at least one perspective to be enabled.

## Choose where the Character Item lives

| Route | Choose it when | Result | Important limit |
| --- | --- | --- | --- |
| **Reusable prefab — recommended** | Multiple characters, runtime pickups, model switching, or a growing item library | A saved Character Item prefab is added to the Item Type's prefab list and spawned by Inventory | References back into a character hierarchy must use stable identifiers such as [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/), not a scene-only reference. |
| **Directly on one character** | A one-off character or a scene-specific item that needs easy drag-and-drop references | The Character Item is created under that character's Item Placement and its visible objects are placed in the selected slots | It does not scale well across characters and should not be used for a character that switches among multiple models. |

Both routes may be used in one project. Do not build both versions for the same definition and slot on the same character unless that duplication is intentional.

## Build a reusable Character Item prefab

### Open the Item Manager and identify the item

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**.
2. Drag a scene instance of the visible model or model prefab variant into **Item**. The manager copies its name into **Name** and assigns it to both visible-item fields.
3. Give the item a clear **Name**. The field is required even when the item has no visible model.
4. Leave **Character** empty. This selects the prefab route and displays **Slot ID**.
5. Assign **Item Definition**. For the built-in Inventory this is the Item Type created in the Item Type Manager.

![Item Manager with required Name and Item Definition empty and both perspective options enabled](https://opsive.com/wp-content/uploads/2022/11/ItemEditorManagerEmpty.png?v=130f0c571e39)

![Item Manager after selecting the AssaultRifle scene model, with its name and visible-item fields populated and the missing Item Definition warning shown](https://opsive.com/wp-content/uploads/2022/11/AssaultRifleItem.png?v=ebf3cbaabd85)

### Set the slot and Animator identity

1. Set **Slot ID** to the Character Item Slot that should hold this item. The starting value is **0**.
2. Keep **Add Item Prefab to Item Definition** enabled. It is enabled by default and adds the saved prefab to the selected Item Type's **Prefabs** list.
3. Set **Animator Item ID** to the unique item ID expected by the character's Animator Controller. The field starts at **0**; changing the number does not create matching animation states.

The same Item Type can reference more than one Character Item prefab, such as left- and right-hand pistol prefabs. Each prefab must use its own Slot ID even though both share the same definition. Follow [Dual Wielding](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/dual-wielding/) for that setup.

![AssaultRifle prefab route with Character empty, Slot ID 0, the AssaultRifle Item Type, Add Item Prefab to Item Definition enabled, and Animator Item ID 1](https://opsive.com/wp-content/uploads/2022/11/AssaultRifleItemPrefabSettings.png?v=0d7f207b6377)

### Choose the perspectives

**Add First Person Item** and **Add Third Person Item** both start enabled.

For a first-person item:

- Assign **First Person Visible Item** to the held model. Leave it empty for an item that uses no separate visible object.
- A runtime prefab normally leaves **First Person Base** empty and lets the spawned perspective resolve the character's first-person objects and matching slot.
- Assign **Animator Controller** only when the visible item has its own Animator.

For a third-person item:

- Assign **Third Person Visible Item** to the world-space held model.
- Assign its **Animator Controller** only when the item model has its own animation.
- Keep the third-person item for AI or multiplayer characters even when the local player uses a first-person camera, because other observers need a world-space item.

![First- and third-person AssaultRifle visible items and Animator Controllers assigned for a prefab build](https://opsive.com/wp-content/uploads/2022/11/AssaultRifleItemPrefabVisibleItem.png?v=f16721ffd5e2)

### Add the starting actions

Use the plus button under **Actions** to add **Shootable**, **Melee**, **Shield**, **Magic**, **Throwable**, or **Usable**. No action is added by default. Give each action a descriptive name when one Character Item has more than one action.

For example, add **Shootable** for an assault rifle. The builder creates the Character Item Action and its starter module groups; configure ammunition, firing, impact, audio, and effects on the generated action after the build. Adding an action type does not make a complete weapon by itself.

![Actions list containing a Shootable action named Shootable 1](https://opsive.com/wp-content/uploads/2022/11/ShootableItemAction.png?v=799abc7e5291)

To start from a configured item, assign **Action Template** instead of adding rows manually. The template replaces the new item's action list and may open the Reference Resolver for references that cannot be mapped safely. See [Templates](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/templates/).

### Build and save the prefab

1. Confirm no red validation message remains, then select **Build Item**.
2. In **Save Item**, save the prefab inside the project's item content folder.
3. Select the Item Type in **Item Type Manager** and confirm the new Character Item appears in its **Prefabs** list.
4. Configure the generated Character Item, perspective components, action modules, equip timing, UI, and **Drop Prefab** as required.
5. Add the definition to a character's Inventory or an Item Pickup, and ensure an Item Set Rule can create a valid set for its slot.

The Item Manager removes temporary scene copies that were outside the target character after a successful build. Keep the source model or prefab variant as the maintained visual asset; do not treat the temporary scene instance as the source of truth.

### Editor checkpoint

The saved prefab should have one **Character Item** root with the correct **Item Definition**, **Slot ID**, and **Animator Item ID**; one component for every selected perspective; and the requested Character Item Actions. Its Item Type should reference the prefab exactly once.

## Build the item directly on a character

Use this branch only when the item belongs to one scene character and does not need to survive model switching.

1. Open the Item Manager, assign the scene model to **Item**, and assign the scene character to **Character**.
2. Assign **Item Definition**. If the character's Item Set Manager has an Item Collection, the adjacent **Create** button can create a definition in that collection from the item name.
3. Keep **Add to Default Loadout** enabled when the built-in Inventory should begin with one of this definition. It is enabled by default for this route.
4. Set **Animator Item ID** to the value implemented by the character's Animator Controller.

![On-character AssaultRifle route with Atlas assigned, Add to Default Loadout enabled, and the warning that a First Person Base is still required](https://opsive.com/wp-content/uploads/2022/11/AssaultRifleItemCharacter.png?v=371df5c5f1fa)

### Assign the first-person hierarchy

1. Keep **Add First Person Item** enabled when the character supports first person.
2. Assign the character's separated arms to **First Person Base**. This must be a scene object, not a prefab asset or the UCC character root.
3. Assign **First Person Visible Item**.
4. Set **Item Parent** to the child GameObject with the matching Character Item Slot. If the chosen parent has no unambiguous slot, use **Add ItemSlot**.
5. Assign **Animator Controller** to the base or visible item only when that object needs its own controller.

![AtlasFirstPersonArms selected as First Person Base and its Items slot selected as Item Parent](https://opsive.com/wp-content/uploads/2022/10/ItemSetupAssaultRIfleFirstPersonBase.png?v=9016e90e330a)

### Assign the third-person hierarchy

1. Keep **Add Third Person Item** enabled for third person, AI, or multiplayer visibility.
2. Assign **Third Person Visible Item**.
3. For a humanoid character, choose **Hand**; **Right** is the starting choice. For a non-humanoid character, assign **Item Parent** to the intended Character Item Slot.
4. Assign an **Animator Controller** only when the visible third-person item animates independently.
5. Confirm the first- and third-person Character Item Slots have the same ID. The Item Manager blocks the build when their IDs differ.

Add the actions, then select **Build Item**. The Character Item root is created under the character's Item Placement, while each visible object is copied under its perspective-specific slot.

![Completed Atlas AssaultRifle Item Manager configuration with matching first- and third-person objects, Animator Item ID 1, and a Shootable action](https://opsive.com/wp-content/uploads/2022/11/AssaultRifleItemCharacterBuild.png?v=4e6e69c4b45d)

![Atlas and its separated first-person arms in the Scene view with the newly built AssaultRifle visible before alignment](https://opsive.com/wp-content/uploads/2022/10/ItemSetupAssaultRifleBuilt.png?v=233ee1ae1ef3)

## Align the visible objects

The builder starts copied objects at their parent origin. Align the item while it is equipped in Play Mode so the animation pose, camera, and active perspective are visible, then copy the tested values back before leaving Play Mode.

### Align a runtime prefab

For a first-person prefab without a fixed base object, enter the tested local values in **First Person Perspective Item > Render > Local Spawn Position**, **Local Spawn Rotation**, and **Local Spawn Scale**. Do the same in the third-person perspective component. These values are applied when the visible object is spawned under the character's slot.

![First Person Perspective Item Render fields with the AssaultRifle visible item and its tested local spawn position and rotation](https://opsive.com/wp-content/uploads/2022/11/FirstPersonPerspectiveAssaultRifleSpawn.png?v=10bd765075cf)

![Third Person Perspective Item Render fields with the AssaultRifle object and its tested local spawn position and rotation](https://opsive.com/wp-content/uploads/2022/11/ThirdPersonPerspectiveAssaultRifleSpawn.png?v=281cabe525fd)

### Align an item built on the character

Adjust the local Transform of each copied visible object under its Character Item Slot. Copy the Play Mode values and paste them onto the same object after Play Mode ends.

![First-person AssaultRifle local Transform position and rotation used for the Atlas hand slot](https://opsive.com/wp-content/uploads/2022/10/FirstPersonAssaultRifleLocation.png?v=422eeb538eac)

![Third-person AssaultRifle local Transform position and rotation used for the Atlas right-hand slot](https://opsive.com/wp-content/uploads/2022/10/ThirdPersonAssaultRifleLocation.png?v=2fd5cb18a8bb)

Weapon alignment and first-person arm framing are separate. If the model sits correctly in the hand but the whole first-person base is framed incorrectly, adjust **First Person Perspective Item > Position Spring > Position Offset** and **Position Exit Offset**.

![First Person Perspective Item Position Spring offsets used to frame the AssaultRifle view](https://opsive.com/wp-content/uploads/2022/10/FirstPersonAssaultRiflePositionSpring.png?v=a77bd3f1cb8c)

The example values in these images belong to the Atlas assault-rifle fixture. Copy the workflow, not the numbers, for a different model, rig, or animation set.

## Complete the gameplay loop

Building the Character Item creates the object structure; the surrounding systems make it playable:

1. The [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) owns the Item Definition amount. A prefab is spawned from the Item Type's **Prefabs** list when automatic runtime Character Item spawning is enabled; an item built on the character is initialized from the Item Placement.
2. [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) creates a valid slot combination. [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) activates the Character Item at its equip event and waits for its completion timing.
3. A Use, Reload, or another matching item ability drives the selected [Character Item Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) and its modules.
4. An [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) adds the Item Definition amount and can request an Item Set to equip.
5. The [Drop ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) removes the active amount. When the Character Item has a valid **Drop Prefab** containing an Item Pickup component, that object becomes collectible again.

The Item Manager does not create Item Set Rules, pickups, drop prefabs, input bindings, or finished animation state machines. Treat each as a separate checkpoint rather than debugging all of them at once.

## Update an existing Character Item

1. Assign a GameObject that already has **Character Item** to the Item Manager's **Item** field.
2. Change **Name**, **Item Definition**, **Animator Item ID**, or the action list.
3. Select **Update Item**.

The update route does not rebuild perspective objects, slots, local spawn values, or their Animator Controllers. Edit those components directly, or rebuild a controlled copy when the hierarchy must change.

Changing or removing an action type can replace its component and discard that action's module configuration. Back up the prefab before a structural action change. An **Action Template** replaces all existing actions; resolve every object listed by the Reference Resolver before accepting the result.

## Verify in Play Mode

1. Select the character's Inventory and confirm the Item Definition appears with the expected amount.
2. Select the Item Set Manager and confirm a valid set contains the Character Item in its intended slot.
3. Equip the set. Confirm the correct perspective activates, the model is aligned, and `SlotXItemID` changes to the configured **Animator Item ID**.
4. Use the item. Confirm the intended Character Item Action runs and its ammunition, hit, audio, or other modules produce the expected result.
5. Switch perspective, or observe the character as AI or a remote player, and confirm the third-person object is present only when intended.
6. Unequip and re-equip. Confirm all four equip and unequip checkpoints complete without leaving the ability active.
7. Pick up a second copy and confirm the Inventory amount changes without spawning a duplicate Character Item for the same definition and slot.
8. Drop the item and confirm the Inventory amount decreases, the visible Character Item leaves through the Item Set transition, and the dropped pickup can be collected again.

## Troubleshoot item creation

- **Build Item stays disabled:** check the visible validation message. Fix the missing **Name** or **Item Definition**, assign a scene character rather than a prefab character, enable at least one perspective, and make the first- and third-person slot IDs match.
- **The Item field rejects the model or prefab:** drag an instance into the scene, then assign that scene GameObject. The manager intentionally blocks a persistent asset because it needs to add and copy scene-side objects safely.
- **A first-person on-character build requires a base:** assign the separated arms scene object to **First Person Base**. Do not assign the UCC character root or a prefab asset.
- **The item is in Inventory but no Character Item appears:** check the Item Type's **Prefabs** list and **Add Item Prefab to Item Definition**. Confirm the prefab uses the same Item Definition and that automatic Character Item spawning is enabled on Inventory.
- **The Character Item appears but no Item Set is valid:** check its **Slot ID**, Item Type category, Item Set Rule, and Item Set Group. The first- and third-person slots must identify the same logical slot.
- **The item equips but is invisible:** check the active perspective component, its visible object, local spawn scale and position, and whether the object is parented to the expected Character Item Slot.
- **The model is aligned but the first-person arms are not:** leave the model's local spawn transform alone and tune **Position Offset** and **Position Exit Offset** on the First Person Perspective Item.
- **The equip or unequip ability never finishes:** check **Equip Event**, **Equip Complete Event**, **Unequip Event**, and **Unequip Complete Event** on the Character Item. Supply the expected animation events or use tested durations.
- **The item equips but cannot be used:** confirm the Character Item has the intended action, the character has the matching item ability, and the generated action modules have been configured after the build.
- **Update Item removed custom action settings:** restore the prefab, then update only safe identity fields or action names. Changing an action type recreates the action component.

For a longer diagnostic sequence, use [Item Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-troubleshooting/).

## Related tasks

- [Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/) shows starting configurations for firearms, swords, Body, magic, and multiple actions.
- [Dual Wielding](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/dual-wielding/) creates two slot-specific Character Items and a combined Item Set.
- [Templates](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/templates/) explains Action Template copying and Reference Resolver decisions.
- [Item Tips](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-tips/) covers state, action, and module organization after the initial build.
- [Item Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-troubleshooting/) provides a deeper runtime checklist.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) documents the generated root component, equip timing, UI, and drop settings.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the Animator Item IDs implemented by the supplied controller.

## Developer reference

### What the builder generates

For either route, the builder creates a root GameObject with **Character Item**, the selected first- and third-person perspective components, and the requested Character Item Actions. It adds an Audio Source to a visible object when needed. When an Animator Controller is assigned, it adds or updates an Animator, a Child Animator Monitor, and the required UCC Animator parameters.

With **Character** empty, the perspective objects are saved under the Character Item prefab. The saved prefab is appended to the built-in Item Type when **Add Item Prefab to Item Definition** is enabled. With **Character** assigned, the root is parented to the character's Item Placement and the copied visible objects are parented to the selected Character Item Slots.

For a first-person-only build, the builder uses immediate equip visibility with a timed completion. A normal new Character Item otherwise starts with duration-based timing: **Equip Event** 0.3 seconds, **Equip Complete Event** 0 seconds, **Unequip Event** 0.3 seconds, and **Unequip Complete Event** 0 seconds. Configure animation-event waits only after the matching clip events exist.

### Runtime ownership

At initialization, Character Item turns its Item Definition into an Item Identifier and connects to the character's Inventory and Item Set Manager. Pickup initializes both perspective objects and every Character Item Action. Equip changes the active slot and visible perspective at the configured event; Use or another item ability drives the action; unequip reverses the visible state; and drop asks Inventory to remove the amount and instantiate the Character Item's Drop Prefab.

A reusable prefab must not retain direct references to one scene character. Use UCC object identifiers, module reference resolution, or another runtime lookup for objects owned by the character. Review every unresolved Action Template reference before saving the prefab.

---

<a id="page-ultimate-character-controller-items-inventory-item-creation-dual-wielding"></a>

# Dual Wielding

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/dual-wielding/)

Dual wielding equips two Character Items as one Item Set while allowing the right and left items to animate, use, reload, and render together or independently. The examples use the common convention of slot **0** for the right hand and slot **1** for the left hand; use different IDs if the character's Item Slots use a different mapping.

## Before you begin

Prepare the character and data before building either item:

- Add matching first- and third-person [Character Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) for the two hands. The right-hand first- and third-person slots must share one ID, and the left-hand slots must share the other.
- Assign an **Inventory**, an **Item Set Manager**, and an Item Collection. The Item Set Group's **Item Category** must contain the definitions that will be equipped.
- Decide whether the pair uses one Item Type with two slot-specific Character Item prefabs or two separate Item Types.
- Decide whether one input operates both hands or each hand has its own Use and Reload abilities.
- Prepare Animator states for the pair. The supplied controller includes Dual Pistols and Sword/Shield examples, but not a complete two-sword animation set.

For reusable pairs, build prefabs with **Character** empty in **Tools > Opsive > Ultimate Character Controller > Item Manager**. This lets Inventory choose the slot-specific prefab at runtime and supports characters that switch models.

## Choose one or two Item Types

| Data setup | Use it when | Inventory amount | Item Set Rule |
| --- | --- | ---: | --- |
| One Item Type with right- and left-slot prefabs | The two swords or firearms are the same owned item | `2` of that Item Type | Put the same Item Type in slots 0 and 1 |
| Separate right and left Item Types | Each hand needs different statistics, pickups, icons, actions, or restrictions | `1` of each | Put the right definition in slot 0 and the left definition in slot 1 |

With one Item Type, its **Prefabs** list must contain one Character Item with **Slot ID 0** and another with **Slot ID 1**. Inventory uses the slot to choose between them. Do not create two identical prefabs for the same definition and slot.

A **Category Item Set Rule** can permit flexible combinations, such as any one-handed melee item in each hand. Start with an explicit **Item Type Item Set Rule** for a known pair; category rules can generate more combinations than expected and should use exceptions where needed.

## Build the two Character Item prefabs

1. Build the right-hand item with **Slot ID 0**, the intended **Item Definition**, and **Add Item Prefab to Item Definition** enabled.
2. Enable every perspective that must render the item. Assign a right-hand first-person visible object and a right-hand third-person object.
3. Add the primary action. A sword normally starts with **Melee** and a firearm with **Shootable**. The first generated action has action ID `0`.
4. Set **Animator Item ID** to the value implemented by the character's controller.
5. Save the prefab, then repeat the build for the left hand with **Slot ID 1** and left-hand visible objects.
6. Open both saved prefabs and configure their action modules, equip timing, local spawn transforms, hitboxes or muzzle origins, and drop settings independently.

The two Character Items may use the same Animator Item ID. Slot parameters keep the values separate: a pair of supplied swords would report `Slot0ItemID = 22` and `Slot1ItemID = 22`, while supplied pistols use `2` in both slots. Setting these numbers does not create the paired animation states.

### Two-sword variant

- Give the right and left prefabs **Melee** action ID `0` and separate hitboxes on their own visible models.
- Use **Animator Item ID 22** only when retaining the supplied Sword item mapping. Add a custom `DualSwords` state and transitions that recognize both slot values.
- Use separate first-person base objects for independent attacks: the Demo convention is base ID `2` for the right arm and `1` for the left arm.
- For alternating attacks, configure two Use abilities, one per slot. For a simultaneous strike, use one all-slot Use ability and provide animation and collision timing for both actions.

The Version 3 Demo does not supply a finished `DualSwords` controller branch. The Inventory and Item Set can equip two swords, but a convincing result still requires project-specific left-hand clips, substates, hitboxes, and transitions.

### Two-firearm variant

- Give both prefabs **Shootable** action ID `0`; configure each weapon's clip, muzzle, projectile or hitscan origin, effects, and reload modules separately.
- Use **Animator Item ID 2** when retaining the supplied Pistol mapping.
- Use first-person base ID `2` for the right pistol and `1` for the left pistol in the Demo hierarchy.
- Use one all-slot Use ability to fire both eligible pistols together, or two slot-specific Use abilities for independent triggers. Apply the same choice to Reload.

Reserve ammunition remains an Inventory definition separate from the count of owned pistols. A rule that requires two Pistol Character Items still needs an owned Pistol amount of at least two.

## Create the dual Item Set Rule

1. In the Project window choose **Assets > Create > Opsive > Ultimate Character Controller > Inventory > Item Type Item Set Rule**.
2. Give **State** an explicit name such as `DualSwords` or `DualPistols`. A `{0}` placeholder concatenates definition names in slot order, but an explicit name is easier to reuse in State System presets and Animator transition setup.
3. Keep **Enabled** and **Can Switch To** enabled. Mark **Default** only when this pair should be the group's fallback Item Set.
4. Set **Item Type Slots** element 0 to the right-hand Item Type and element 1 to the left-hand Item Type. Repeat the same Item Type in both elements for two identical items.
5. Enable **Exact Amount Validation** only when the Inventory must contain exactly the number used by the set. For one repeated Item Type, a two-slot set is invalid when the owned amount is anything other than `2`; leave it disabled when extra copies are allowed.
6. Add the rule under **Item Set Manager > Item Set Groups > Item Set Rules** for the matching **Item Category**.

![Item Type Item Set Rule with Sword in slot 0 and Shield in slot 1, illustrating the two-slot rule layout](https://opsive.com/wp-content/uploads/2022/10/ItemTypeItemSetRule.png?v=ca9234570436)

At runtime the rule creates a set only when matching Character Items and Inventory amounts exist for both required slots. Add separate single-item rules if the character should equip one hand before acquiring the second item.

## Configure first-person hand ownership

Each **First Person Perspective Item** resolves a **First Person Base Object ID**. Items that resolve different objects are independent; items that resolve the same object share its first-person motion and activation.

The supplied Demo uses these IDs:

- `0`: both arms
- `1`: left arm
- `2`: right arm

For independent two-sword or two-firearm control, set the right item to `2` and the left item to `1`. Configure the value on **First Person Perspective Item > Render > First Person Base Object ID** after building the prefabs.

![Right Pistol First Person Perspective Item using base object ID 2, visible pistol spawn values, and additional control object ID 0](https://opsive.com/wp-content/uploads/2022/10/FirstPersonRightPistolInspector.png?v=ef9e691d4f38)

![Left Pistol First Person Perspective Item using base object ID 1 with no additional control objects](https://opsive.com/wp-content/uploads/2022/10/FirstPersonLeftPistolInspector.png?v=7a5f122f3e03)

The right-pistol example also adds base ID `0` under **Additional Control Objects** so the shared arms remain controlled when only the right pistol is equipped. When the dual set is active, deactivate duplicate renderers on that shared base so the separate left and right arm meshes are not drawn twice.

Use the current **Game Object Activator** component on each duplicate renderer GameObject. Add `DualPistols`, `DualSwords`, or another Item Set State and assign a preset with **Active** disabled. The older screenshots on this page used the retired **Object Activator** label, so those images are no longer shown.

### Shared-base alternative

A paired animation can intentionally use the shared base ID `0` for its main item and a separate base ID `1` for the offhand. The legacy Sword/Shield fixture demonstrates this layout:

![First-person hierarchy with the shield visible object under the separate Atlas left-arm base and Items slot](https://opsive.com/wp-content/uploads/2022/10/ShieldFirstPersonHierarchy_edited.png?v=3d981acde90b)

![Sword First Person Perspective Item using shared first-person base object ID 0](https://opsive.com/wp-content/uploads/2022/10/SwordFirstPersonInspector.png?v=44ca91561492)

![Shield First Person Perspective Item using separate left-arm base object ID 1](https://opsive.com/wp-content/uploads/2022/10/ShieldFirstPersonInspector.png?v=89c1eba8d62a)

This is appropriate when one animation set coordinates both arms. For two items that must attack, recoil, or reload independently, prefer separate right- and left-arm bases.

Third-person objects do not use First Person Base Object IDs. Each visible object resolves the Character Item Slot matching its Character Item's **Slot ID**, so verify that the right model reaches the right-hand slot and the left model reaches the left-hand slot.

## Choose simultaneous or independent controls

| Desired behavior | Use ability setup | Reload ability setup |
| --- | --- | --- |
| Both hands together | One ability with **Slot ID -1** and the shared **Action ID** | One ability with **Slot ID -1** reloads every eligible equipped action |
| Separate hand inputs | Duplicate Use abilities: right **Slot ID 0**, left **Slot ID 1**, each with its own input | Duplicate Reload abilities for slots 0 and 1, or keep one all-slot reload input |
| One primary hand, passive offhand | Use only the primary slot; drive the offhand through its Shield, state, or project-specific behavior | Configure only actions that implement reload |

`Slot ID -1` means all Inventory slots, not “always both.” Use and Reload still ask each action whether it can start. If one pistol is empty, blocked, or already complete, the other can fire or reload alone. Enforce strict synchronization in the action modules or a project-specific ability when both hands must succeed or fail as one operation.

Use has priority over Reload for the same Character Item. Starting Use can stop that item's reload; test this separately for each slot.

## Coordinate Item Set State and Animator values

Three layers of runtime state have different owners:

- The active Item Set turns on its **State** name, such as `DualPistols` or `DualSwords`. Use that State for presets on Character Items, perspective items, Use abilities, and Game Object Activators.
- `Slot0ItemID` and `Slot1ItemID` identify which Character Item mapping is equipped in each hand.
- The active item ability owns `ItemStateIndex`: the released defaults are Use `2`, Reload `3`, Equip `4`, and Unequip `5`. Each Character Item action or equip/unequip state set supplies the per-slot `ItemSubstateIndex`.

The [Equip Unequip ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) transitions every changed slot in the chosen Item Set and remains active until all equip and unequip checkpoints finish. A missing animation event or duration on either Character Item can therefore hold the whole transition open.

## Configure the loadout and pickups

1. For one repeated Item Type, add an amount of `2` to **Inventory > Default Loadout** or grant `2` from an [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/). For separate definitions, add or grant one of each.
2. To begin with the pair equipped, set **Inventory > Loadout Equip** to **Item Set Name** and enter the rule's State, such as `DualPistols`.
3. When items are collected separately, keep single-hand rules if the first item should be usable before the pair is complete.
4. Configure each Character Item's **Drop Prefab**. Decide whether dropping one hand removes one amount or whether a project-specific action should drop the pair.

## Editor checkpoint

Before entering Play Mode, confirm:

- Both perspectives have matching Character Item Slots for IDs 0 and 1.
- Inventory can resolve one Character Item prefab for each required definition and slot.
- The dual Item Set Rule appears in the correct Item Set Group and its two slot entries are ordered correctly.
- Both Character Items use the expected Animator Item ID and action ID.
- Independent first-person items resolve different base objects; duplicate shared-arm renderers have Game Object Activator states.
- The Animator Controller contains pair-specific transitions, ability state indices, and per-slot substates.

## Verify in Play Mode

1. Inspect Inventory and confirm the expected amount: two of a shared definition or one of each separate definition.
2. Inspect Item Set Manager and confirm the `DualSwords` or `DualPistols` set is valid with the right item in slot 0 and the left item in slot 1.
3. Equip the set. Confirm both Character Items complete their equip events and `Slot0ItemID` and `Slot1ItemID` show the intended values.
4. Test the right and left inputs separately. Confirm only the selected action, first-person base, hitbox or muzzle, and substate react.
5. Test the simultaneous input. Confirm every eligible action starts and that an ineligible hand produces the intended fallback.
6. For firearms, reload with one clip partly full and the other empty, then test Use during reload.
7. Switch perspective or observe the character remotely. Confirm both third-person models occupy the correct hands and no first-person arm mesh is duplicated.
8. Remove or drop one owned item. Confirm the dual set becomes invalid and the intended single-hand or empty set takes over.

## Troubleshoot dual wielding

| Symptom | Check | Fix |
| --- | --- | --- |
| The dual Item Set never appears | Check Inventory amounts, Item Type prefab entries, slot IDs, the Item Set Group category, and **Exact Amount Validation** | Supply the second Character Item, correct the slot/category, or disable exact validation when extra copies are valid. |
| Both models appear in one hand | Check the Character Item **Slot ID** and matching first- and third-person Character Item Slots | Rebuild or edit the left prefab for slot 1 and confirm both perspective hierarchies use the same mapping. |
| One first-person item moves both hands | Both items resolve the same **First Person Base Object ID** | Use separate right- and left-arm base IDs for independent motion. |
| Arms or weapons are drawn twice | A shared base and separate hand bases are active together | Add current **Game Object Activator** states that disable only the duplicate renderers while the dual Item Set State is active. |
| One input fires both items unexpectedly | The Use ability has **Slot ID -1** | Use duplicate slot-specific abilities and distinct inputs. |
| Only one item fires from an all-slot input | The other action cannot start, has a different action ID, or has no usable ammunition | Match **Action ID**, configure both actions, and decide whether partial success is acceptable. |
| Reload never finishes or Use interrupts it | Check each action's reload events and remember that Use has priority over Reload | Supply valid events or durations, then test each slot before testing all-slot reload. |
| Equip Unequip remains active | One Character Item has not reached an equip or unequip completion checkpoint | Correct that item's animation event or duration; the ability waits for every changed slot. |
| The items equip but animation remains single-wield | The pair-specific Animator transitions or Item Set State are missing | Add transitions for both `SlotXItemID` values and the required ability state/substate combinations. |

## Related tasks

- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds and validates each slot-specific Character Item.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) explains the first- and third-person slot mapping.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) covers groups, rule order, category matching, and runtime sets.
- [First Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) documents base-object IDs and additional control objects.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) and [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) configure slot and action targeting.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) covers Default Loadout, Loadout Equip, pickup, and amount ownership.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the supplied item IDs.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains the presets driven by the active Item Set State.

## Developer notes

`ItemTypeItemSetRule` matches a Character Item by its slot and Item Type. With **Exact Amount Validation** enabled, it counts each identifier used by the generated set and requires Inventory to hold exactly that amount. `ItemSetGroup` activates the new Item Set State and deactivates the previous one when the active set changes.

`FirstPersonPerspectiveItem` considers items independent when their resolved **Object** references differ. **Additional Control Objects** are resolved by First Person Base Object ID and follow the main first-person object. `Use` and `Reload` iterate all Inventory slots when **Slot ID** is `-1`; duplicate abilities target one slot when given `0` or `1`. `EquipUnequip` tracks equip and unequip work per slot and stops only after every pending Character Item completes.

---

<a id="page-ultimate-character-controller-items-inventory-item-creation-common-setups"></a>

# Common Setups

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/)

Use these Item Manager configurations as starting points for a firearm, melee weapon, invisible Body action, magic anchor, multi-action item, or item-specific first-person base. Choose the scenario by how the item looks and runs; do not copy an example's Animator ID unless the same value exists in your Animator Controller.

## Before you begin

Complete the shared preparation in [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/): create the Item Definition, add the required Character Item Slots, and decide whether to save a reusable prefab or build directly on one scene character.

The examples below use the reusable-prefab route:

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**.
2. When **Item** or **First Person Base** is used, assign a scene object that the manager can copy or modify. The visible-item fields may use model assets or scene objects; the builder instantiates them into the generated item.
3. Leave **Character** empty, choose **Slot ID**, assign **Item Definition**, and keep **Add Item Prefab to Item Definition** enabled.
4. Set **Animator Item ID** to a value implemented by the character's Animator Controller. The values shown here match the supplied controller; see [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/).
5. Enable at least one perspective and add the action that represents the gameplay. Both **Add First Person Item** and **Add Third Person Item** begin enabled.
6. Select **Build Item**, save the prefab, and configure the generated action modules, Item Set Rules, pickups, and animation states that the scenario needs.

The Item Manager adds required Animator parameters to an assigned visible-object controller, but it does not create animation clips or states. Leave **Animator Controller** empty when the visible mesh has no independent animation.

## Choose a starting setup

### Assault rifle

Use this setup when the first- and third-person weapon models each have an Animator Controller for moving weapon parts or item-specific animation.

- Assign the rifle model to both visible-item fields and assign the matching controller beneath each field.
- Add a **Shootable** action, then configure its ammunition, shooter, clip, reload, fire-effect, and impact modules after the build.
- Use **Animator Item ID 1** only with the supplied Assault Rifle Animator states. A custom controller may use a different unique value.
- Keep the third-person item for AI, multiplayer, or any camera that can observe the character from outside first person.

![Item Manager configured for an AssaultRifle prefab in slot 0 with Animator Item ID 1, first- and third-person visible models and controllers, and a Shootable action](https://opsive.com/wp-content/uploads/2022/10/AssaultRifleItemSetup.png?v=9f0f72804ae2)

Runtime result: equipping the matching Item Set activates the correct perspective model, writes the rifle ID to `SlotXItemID`, and lets the matching Use and Reload abilities drive the Shootable action. The starter action still needs project-specific ammunition, effects, audio, and animation timing.

### Sword

Use this setup when the character Animator supplies the attack animation and the sword meshes do not animate independently.

- Assign the sword model to both visible-item fields.
- Leave both visible-item **Animator Controller** fields empty.
- Add a **Melee** action and configure its attack, collision, impact, and recoil modules after the build.
- **Animator Item ID 22** matches the supplied Sword states; choose the ID implemented by a custom controller instead.

![Item Manager configured for a Sword prefab with Animator Item ID 22, first- and third-person visible models without separate Animator Controllers, and a Melee action](https://opsive.com/wp-content/uploads/2022/10/SwordItem.png?v=cf136d57b78a)

Runtime result: the character Animator supplies the equipped and attack poses while the Melee action tests the configured hitboxes. An empty visible-item Animator Controller does not remove the character's Animator.

### Invisible Body or unarmed action

Use an invisible Character Item when an action needs the item and Item Set lifecycle but does not need a separate held model, such as a punch or Body action.

- Leave **Item** and both visible-item fields empty, but provide the required **Name** and **Item Definition**.
- Keep the perspectives needed by the character enabled. The Item Manager requires at least one perspective even when neither has a visible object.
- Add **Melee** for an unarmed attack, then configure its collision and animation behavior after the build.
- **Animator Item ID 21** matches the supplied Body states.

![Item Manager configured for an invisible Body prefab with both perspectives enabled, no visible objects, Animator Item ID 21, and a Melee action](https://opsive.com/wp-content/uploads/2022/10/BodyItem.png?v=3d77474540af)

Runtime result: the Character Item can equip and drive the action without spawning a held mesh. Invisible is intentional; verify the action, animation, and collision rather than looking for an item model.

### Magic with transform anchors

Use empty visible GameObjects when a magic action needs stable first- and third-person transforms for effects, audio, or cast origins but no permanent mesh.

- Create named empty scene GameObjects at the intended cast origins and assign them as the first- and third-person visible items.
- Leave their **Animator Controller** fields empty unless the anchors contain animated children.
- Add a **Magic** action and configure its start, cast, stop, and effect modules after the build.
- **Animator Item ID 66** matches the supplied Teleport states; use the value implemented by your spell animation instead.

![Item Manager configured for a Teleport magic prefab with empty first- and third-person visible anchors, Animator Item ID 66, and a Magic action](https://opsive.com/wp-content/uploads/2022/10/MagicItem.png?v=8ef73cecf574)

Runtime result: the empty objects follow the correct perspective slots and give the Magic modules a predictable transform. They remain invisible until configured effects or child renderers are spawned or enabled.

### Multiple actions on one Character Item

Use multiple actions when one equipped object has genuinely different operations, such as a rifle that can shoot and perform a melee strike. The screenshot demonstrates three action rows; it is not a finished recommendation for combining those three behaviors.

1. Add each required row under **Actions** and give it a descriptive name.
2. Build the item and inspect the generated Character Item Action components and their IDs.
3. Configure each action's module groups independently.
4. Configure the matching Use or Reload ability to target the intended **Action ID**. Adding several actions does not run all of them from one input automatically.

![AssaultRifle Item Manager setup with Shootable, Melee, and Throwable action rows on one Character Item](https://opsive.com/wp-content/uploads/2022/10/AssaultRifleItemMultipleActions.png?v=7cb62c71b91f)

Runtime result: one Character Item remains equipped while the selected item ability drives one action component. If two actions should share a complex configuration, start from an [Action Template](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/templates/) and resolve its references carefully.

A generated **Throwable** action sets the Character Item to drop its full Inventory amount. Do not use that action merely to launch a detachable rifle attachment unless that full-item lifecycle is intended; use a Shootable or custom module for a projectile that should leave the rifle equipped.

### Item included in the first-person base

Use this setup when an item-specific first-person base already contains the visible weapon mesh, such as a dedicated arms-and-rifle object. The whole base becomes the first-person object, so a separate visible-item reference would duplicate the model.

- Assign the combined scene object to **First Person Base**.
- Leave **First Person Visible Item** empty.
- Assign the base's **Animator Controller** when the combined object animates.
- Disable **Add Third Person Item** only for a truly first-person-only character. For AI, multiplayer, or an external camera, enable it and provide a separate third-person visible item.

![First-person-only Assault Rifle setup using AssaultRifleArms as the First Person Base, no separate First Person Visible Item, and a Shootable action](https://opsive.com/wp-content/uploads/2022/10/AssaultRifleFirstPersonItem.png?v=9f46443e3a69)

Runtime result: the builder clones the base into the Character Item prefab, configures it as the first-person object, and adds a Character Item Slot when no separate visible item exists. Use a separate visible item instead when the weapon must switch independently of shared arms.

## Check the generated item

After **Build Item** completes, verify the saved prefab before configuring gameplay:

- The root has **Character Item** with the intended **Item Definition**, **Slot ID**, and **Animator Item ID**.
- Every enabled perspective has its matching perspective component. Its object or visible-item reference matches the chosen scenario, including deliberate empty references.
- Every selected action exists once, has a distinct purpose and name, has a unique generated action ID, and contains the expected module groups.
- Visible objects with an assigned controller have an Animator and Child Animator Monitor. The required UCC parameters exist in that controller.
- The Item Type's **Prefabs** list contains the saved Character Item exactly once.

The builder creates the item structure, not a finished gameplay loop. It does not create Item Set Rules, complete action-module values, input bindings, pickups, drop prefabs, or Animator states and clips.

## Connect inventory, equipment, and pickups

1. Give the character's Inventory the Item Definition amount, or place an [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) that grants it.
2. Create an [Item Set Rule](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) that permits the definition in the Character Item's slot.
3. Configure the character's item abilities to equip and use the intended set and Action ID.
4. To drop and collect the item again, assign a **Drop Prefab** with an Item Pickup to the Character Item.

A pickup grants the Item Definition amount; it does not contain the visible setup. Inventory uses the Item Type's prefab list to create the Character Item for the correct slot.

## Verify in Play Mode

1. Confirm the Inventory receives the expected Item Definition amount and creates one Character Item for its definition and slot.
2. Equip its Item Set and confirm only the active perspective object is visible.
3. Watch `SlotXItemID` and confirm it changes to the configured **Animator Item ID**.
4. Use every configured action separately and confirm the matching action modules, animation, audio, effects, and collision run.
5. Switch perspective or observe an AI or remote character and confirm the third-person object is present when required.
6. Collect and drop the item once. Confirm the Inventory amount, equipped set, visible object, and pickup remain synchronized.

## Troubleshoot a common setup

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Item** is disabled | Read the manager's validation message; check **Name**, **Item Definition**, enabled perspectives, scene objects, and matching slot IDs | Supply the missing value or correct the slot. Keep at least one perspective enabled. |
| The item equips but is invisible | Check whether the scenario deliberately leaves a visible field empty and whether the active perspective has an object | Assign a visible object, or keep it empty only for Body/unarmed or an integrated first-person base. |
| The first-person base appears but the weapon does not | Check whether the weapon renderer is actually inside **First Person Base** when **First Person Visible Item** is empty | Put the mesh inside the item-specific base or assign it separately as **First Person Visible Item**. |
| The local player sees the item but AI or remote players do not | Check **Add Third Person Item** and **Third Person Visible Item** | Enable the third-person perspective and assign a world-space model. |
| The correct item equips with the wrong animation | Compare **Animator Item ID** with the implemented `SlotXItemID` states | Use the controller's real ID and add the required animation states; the manager adds parameters, not states. |
| A generated action does nothing | Check its modules and the **Action ID** selected by the matching item ability | Configure the starter modules and point Use or Reload at that action. |
| A pickup grants the amount but nothing equips | Check the Item Type's prefab list, Character Item **Slot ID**, and Item Set Rules | Add the saved prefab once and create a valid set for that definition and slot. |

For a deeper diagnostic path, use [Item Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-troubleshooting/).

## Related tasks

- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) covers the complete prefab and direct-on-character workflows.
- [Templates](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/templates/) copies a configured action setup into a new Character Item.
- [Item Tips](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-tips/) covers organization and follow-up configuration.
- [Character Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) explains the generated action components and module groups.
- [Use ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) selects and runs a Character Item Action.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the IDs implemented by the supplied controller.

## Developer notes

The Item Builder creates a Character Item root, adds one perspective component for each enabled perspective, clones the selected scene objects into the generated hierarchy, and adds the selected Character Item Action components. A visible object receives an Audio Source, and an assigned Animator Controller receives an Animator, Child Animator Monitor, and the standard UCC parameters.

When **First Person Base** is supplied without **First Person Visible Item**, the builder uses the cloned base as the perspective object and adds a Character Item Slot to it. With multiple actions, generated action IDs distinguish the components that Use and Reload select. Inspect those IDs after building rather than depending on the order shown in an old screenshot.

---

<a id="page-ultimate-character-controller-items-inventory-item-creation-item-tips"></a>

# Item Tips

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-tips/)

Use these patterns after one item equips and performs its main action correctly. They keep a growing item library predictable without duplicating an entire Character Item whenever one value, animation, slot, or fire mode changes.

## Start with one working prefab

Stabilize the smallest useful version before adding variants:

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**.
2. Assign the maintained **Item Definition**. With the built-in Inventory, this is the Item Type that the Inventory counts and the Item Set Manager categorizes.
3. Leave **Character** empty for a reusable Character Item prefab. Set **Slot ID** to the matching Character Item Slot and keep **Add Item Prefab to Item Definition** enabled.
4. Give the item an **Animator Item ID** that the character's Animator Controller implements.
5. Add one primary action, such as **Melee** for an Iron Sword or **Shootable** for a rifle. Configure enough modules for one complete use cycle.
6. Select **Build Item**, save the prefab, and confirm it appears once in the Item Type's **Prefabs** list.
7. Add the Item Definition to a test character's Inventory and create an Item Set that can equip it.

Do not start by combining alternate fire, dual wielding, several skins, and multiple perspectives. First confirm that one prefab spawns, equips, uses, unequips, and equips again without errors. That working prefab becomes the baseline for every later choice.

## Separate inventory identity from equipped presentation

These objects answer different questions:

| Object | What it controls | Change it when |
| --- | --- | --- |
| **Item Type / Item Definition** | What the Inventory owns and counts, its capacity, categories, and Character Item prefab list | The item needs a separate inventory identity or different category/capacity behavior |
| **Character Item prefab** | Slot, Animator Item ID, equip/unequip timing, actions, perspective items, and drop prefab | The equipped behavior or slot-specific setup differs |
| **First- or Third-Person Perspective Item** | Which visible object, base object, matching slot resolution, and local offsets are used for that view | Only presentation or perspective ownership differs |
| **Item Set** | Which Character Items may be equipped together and which State is active for that combination | The loadout or paired-item behavior differs |

For example, two identical pistols can share one Item Type while using right- and left-slot Character Item prefabs. Inventory spawns the matching prefab for each available slot. Create separate Item Types when the two pistols must be owned, limited, picked up, or categorized separately.

Keep first- and third-person **Character Item Slot** IDs aligned. One Character Item has one **Slot ID**, and both perspectives must resolve that same slot. Avoid adding two prefabs with the same Item Definition and Slot ID unless the custom Inventory has an intentional way to choose between them.

## Reuse a tested action configuration

Use **Action Template** in the Item Manager when several items share a tested action stack. The template copies Character Item Actions; it does not replace the new item's visible-model setup.

1. Choose a working Character Item as **Action Template**.
2. Build the new item with its own Item Definition, slot, visible objects, and Animator Item ID.
3. If the **Reference Resolver** opens, map every unresolved object deliberately. A reference into the template's hierarchy is not automatically valid on the new prefab.
4. Inspect the generated action modules before saving. Replace projectile origins, hitboxes, audio sources, attachment points, and perspective references that still belong to the template.
5. Test the new item independently before editing the template or creating another variant.

Use [Templates](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/templates/) for the complete template and Reference Resolver workflow.

## Use States for focused variants

A State preset is a good fit when the same item needs a small, temporary configuration change. It can override serialized values without creating another Item Type or copying the entire Character Item prefab. A State does not create Animator states, clips, or transitions; configure those separately when the visual motion must also change.

### Create item-specific ability States

Every ability has a **State** field. Enabling **Append Item** also activates a State made by joining that base State with the active Item Definition name. For example, a `Use` State with a `Katana` definition activates `Use` and `UseKatana` while the ability is active.

![Use ability configured with State Use and its enabled Append Item option outlined in orange for slot 0 and action 0](https://opsive.com/wp-content/uploads/2022/10/Use_appendItem_StateName_edited.webp?v=f73904e2e5f4)

The names are concatenated without an automatic separator. Create the preset with the exact resulting name, and treat Item Definition renames as a State-name migration. Use this pattern when an ability-wide option changes for one equipped item, such as rotation, movement, or camera behavior.

### Apply a State for an equipped combination

An active Item Set enables its **State** on the character and disables the previous Item Set State when the active set changes. This is useful for adjustments that belong to a loadout rather than a single action, such as `DualPistols` or `SwordShield`.

![Item Set Manager in Play Mode showing the active AssaultRifle set, enabled SinglePistol set, invalid DualPistols set, and default Body set](https://opsive.com/wp-content/uploads/2022/10/ItemSetManagerAtRuntime.png?v=f3f02215df7f)

Use the runtime Item Set status before blaming an action module: an item cannot receive its equipped-combination State when its Item Set is invalid or never becomes active.

### Change States from an item action

Add **Activate States** to a Usable Action Module Group when a State should be active while the item is equipped, between start use and use, or between use and use complete. The module applies its listed States to the character for the selected phases.

![Activate States module enabling the AssaultRifle State while equipped, during start use, and during use](https://opsive.com/wp-content/uploads/2022/10/ActivateStatesInspector.png?v=f4c2fa4c5e3e)

Use **Module State Switcher** when the player selects among named modes. Its current index activates one configured State and deactivates the other entries on both the character and the Character Item. The supplied assault-rifle configuration demonstrates Repeat, Simple, and Burst modes.

![Module State Switcher mapping Repeat, Simple, and Burst indices to AssaultRifle trigger States](https://opsive.com/wp-content/uploads/2022/10/ModuleStateSwitcherInspector.png?v=1c0df526eb94)

Keep each State responsible for a focused change. If several active States override the same value, inspect State priority and active status instead of adding another preset to hide the conflict.

## Keep actions and modules identifiable

A Character Item can contain more than one action of the same type. **ID** is the runtime contract used by Use, Reload, and other Item Abilities. **Action Name** and **Action Description** are for making the Inspector understandable.

![Shootable Action with ID 0, the name Shootable, and a description of its projectile and hitscan role](https://opsive.com/wp-content/uploads/2022/10/ItemActionID_Name_Desription.png?v=c0fdaad70444)

Use these rules:

- Keep action IDs unique on one Character Item and make the Item Ability's **Action ID** match the intended action.
- Name actions by purpose, such as `Primary Fire`, `Alternate Fire`, or `Charged Cast`, rather than leaving several rows named `Shootable`.
- Name repeated modules by their result, such as `Primary Muzzle Flash` or `Heavy Hit Damage`.
- Treat a module's **ID** as a code-facing lookup value, not as its list position. Reordering rows does not renumber IDs.
- Review module IDs after removing a row. The current Inspector decrements the later IDs, so stored code references may need to change.
- Keep IDs unique within a module group when code calls `GetModuleByID`; the first matching module is returned.

## Keep Animator and slot contracts aligned

The Animator, Character Item, Item Ability, and action modules each own part of the result:

- **Animator Item ID** becomes `SlotXItemID` for the Character Item's slot.
- An active Item Ability supplies `SlotXItemStateIndex`, such as Use, Reload, Equip, or Unequip.
- Trigger, reload, recoil, and related modules contribute the winning `SlotXItemSubstateIndex` for the current action phase.
- `SlotXItemStateIndexChange` lets the Animator re-enter or change an item state when the state index itself stays the same.

The Item Manager can add required parameters to an assigned Animator Controller, but it does not create the transitions or clips for a new Animator Item ID or substate. When a new mode changes timing, verify the matching transition and animation event or duration before tuning gameplay modules around it.

Keep the same slot mapping in first and third person. A right-hand item in slot `0` should resolve slot `0` in both hierarchies; the corresponding `Slot0...` Animator parameters then describe the same equipped item in every view.

## Treat prefabs and pooled objects as reusable

The built-in Inventory spawns reusable Character Item prefabs under the character's Item Placement through the Opsive object pool. It may reactivate a previously unavailable Character Item instead of creating a fresh one. Supplied modules also use the pool for projectiles, thrown objects, tracers, muzzle flashes, shells, clips, and impact particles.

Follow these safe patterns:

- Edit the prefab asset, not a Play Mode instance. Runtime changes disappear and a pooled instance may later represent another use of the same prefab.
- Reset temporary values, event subscriptions, visual effects, and cached targets when a custom module or spawned object is disabled, removed, or reused.
- Pair `ObjectPoolBase.Instantiate` with `ObjectPoolBase.Destroy` in custom item code. Do not assume Unity `Destroy` participates in the Opsive pool.
- Store scene-independent references on reusable prefabs. When an item must find part of a character hierarchy, use a stable resolver such as [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) instead of a reference to the test character.
- Cycle the item through pickup, equip, use, unequip, removal, and pickup again. A bug that appears only on the second cycle usually indicates retained pooled state or an unremoved listener.

## Example: one rifle with three fire modes

This pattern adds Repeat, Single, and Burst behavior without creating three inventory definitions:

1. Build one rifle Character Item prefab with one Item Type, the correct Slot ID and Animator Item ID, and a tested Shootable action with **ID 0**.
2. Set the character's Use and Reload abilities to **Action ID 0**.
3. Give repeated trigger, shooter, and effect modules descriptive names. Keep their module IDs unique if code or another module refers to them.
4. Add a **Module State Switcher** with indices named `Repeat`, `Single`, and `Burst`. Assign exact State names such as `AssaultRifle_Trigger_Repeat`, `AssaultRifle_Trigger_Single`, and `AssaultRifle_Trigger_Burst`.
5. Add State presets to only the modules that differ between modes. Each preset should enable or configure the intended trigger path without changing unrelated ammunition, impact, or perspective settings.
6. Add Animator transitions or substates only when a mode needs different motion or timing. The three modes can otherwise share the rifle's Animator Item ID.
7. Enter Play Mode, switch each index, fire several times, reload, unequip, and re-equip. Confirm only the selected State and intended modules are active after every transition.

## Editor checkpoint

Before entering Play Mode, confirm:

- The Item Type references the intended Character Item prefab once for each supported slot.
- The Character Item's Item Definition, Slot ID, Animator Item ID, actions, perspectives, and Drop Prefab belong to the new item rather than its template.
- Action IDs match the Item Abilities that should operate them.
- Module names explain repeated rows, and any code-facing module IDs are unique and still current.
- Every State name exactly matches its preset, Item Set, ability-appended result, or Module State Switcher entry.
- The Animator Controller contains the parameters, states, transitions, and events or durations required by the selected action modules.

## Verify in Play Mode

1. Inspect Inventory and confirm the expected Item Definition amount and spawned Character Item slot.
2. Inspect Item Set Manager. Confirm the intended set is valid, becomes active, and enables its State.
3. Equip the item and confirm the expected `SlotXItemID` value and visible object in both supported perspectives.
4. Use and reload the item. Confirm the correct action ID, item state index, substate, and animation completion path.
5. Switch every configured mode or State and inspect the affected module values. Confirm the previous State is no longer active.
6. Unequip and re-equip, then remove and pick up the item again. Confirm pooled effects, ammunition displays, hitboxes, and event-driven behavior start from a clean state.
7. Repeat with rapid input. The action must still reach use complete and release the Item Ability.

## Troubleshoot an item configuration

| Symptom | Check | Fix |
| --- | --- | --- |
| The definition is owned but no Character Item appears | The Item Type's **Prefabs** list, prefab Item Definition, and Slot ID | Add the saved prefab once, correct its definition and slot, then update Item Sets. |
| The wrong action starts | Character Item action IDs and the Item Ability's **Action ID** | Assign unique action IDs and target the intended one from Use or Reload. |
| An appended State never activates | The ability's base **State**, **Append Item**, and exact current Item Definition name | Set a nonempty base State and create the exact concatenated preset name. |
| A mode leaves old settings active | Module State Switcher index, overlapping active States, and preset priority | Correct the switch entries, deactivate the unintended State, and keep overlapping overrides intentional. |
| The item equips but plays the wrong animation | Slot ID, Animator Item ID, item state/substate values, and matching Animator transitions | Align the slot contract and add the missing transition, clip, event, or duration. |
| Code finds the wrong module after editing the group | Duplicate IDs or IDs renumbered after a removal | Restore unique IDs and update stored lookups; use names only as Inspector documentation. |
| An effect or projectile behaves correctly once but not after reuse | Cached runtime values, subscriptions, and pooled-object reset behavior | Reset the object on reuse and use the Opsive pool's instantiate/destroy pair. |
| The item works in one perspective only | Matching Character Item Slots, perspective visible objects, local offsets, and layers | Make the slot IDs agree and configure each supported perspective separately. |

For a broader diagnostic route, continue with [Item Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-troubleshooting/).

## Related tasks

- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) covers the complete prefab and on-character build workflows.
- [Item Type, Definition, and Category](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/) explains inventory identity and grouping.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) defines the first- and third-person slot contract.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) configures valid equipment combinations and Item Set States.
- [Action Modules and Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/) explains module order, IDs, States, bindings, and runtime status.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) covers the slot item, state, and substate parameters.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains State activation and preset priority.

## Developer notes

`ItemType.GetPrefabs()` supplies the Character Item prefab list used by the built-in Inventory. `InventoryBase.SpawnItemIdentifiersCharacterItem` selects those prefabs by slot, reuses a matching unavailable pooled Character Item when possible, and otherwise calls `ObjectPoolBase.Instantiate` under Item Placement.

`CharacterItem.GetItemAction(int)` resolves an action by ID; Use and Reload pass their configured **Action ID** to that lookup. `ActionModuleGroup<T>.GetModuleByID(int)` returns the first matching module, so duplicate module IDs are ambiguous even though the Inspector allows them.

`ActivateStates` applies its State names to the character according to the equipped/start-use/use phase toggles. `ModuleStateSwitcher` applies its selected State to both the character and Character Item. Ability **Append Item** joins the base State with each active equipped Item Definition name.

For custom behavior, choose the smallest current extension point: an [Action Module](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/) for an item-action stage, an [Item Effect](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/) for a result that needs item context but no hit, or an [Impact Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) for a result that needs collision or damage context.

---

<a id="page-ultimate-character-controller-items-inventory-item-creation-templates"></a>

# Templates

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/templates/)

Use an **Action Template** to give a new Character Item the complete, tested action stack from another item. The new item keeps its own identity, slot, models, perspective setup, and prefab choices while reusing the template's actions and modules.

## Choose the right template workflow

Ultimate Character Controller has two separate template workflows:

| Workflow | Use it for | What remains target-specific |
| --- | --- | --- |
| **Action Template** in Item Manager | Build a new Character Item from the actions on an existing Character Item | Item Definition, Slot ID, Animator Item ID, Character Item settings, models, perspective objects, spawn parents, offsets, Animator Controllers, prefab registration, and loadout |
| **Template Character** in Character Manager | Copy selected controller components, abilities, item abilities, effects, and Character Items to a new or existing character | Target models, perspective choices, Animator Controllers, first-person arms, third-person objects, item slots, and camera |

This page focuses on Action Template. Follow [Character Templates](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/templates/) for the separate Character Manager workflow, including its released Version 3 **Copy Items** limitation.

## Prepare a reliable Action Template

An Action Template is an ordinary, configured Character Item; there is no separate template asset to create.

1. Finish one source Character Item and verify that it equips, performs every action, completes its animation events or durations, and can be reused after unequip.
2. Keep only the actions that every destination item should receive. Item Manager copies the whole action list, not selected rows.
3. Give each action a deliberate **ID**, **Action Name**, and module configuration. Use unique module IDs wherever another module or custom code performs an ID lookup.
4. Identify action-owned helper objects such as muzzle transforms, projectile origins, melee hitboxes, lights, Audio Sources, Attribute Managers, or effect anchors. The destination needs an equivalent object or an intentional shared asset reference.
5. Save the source prefab before using it as a template. Future source edits do not automatically update items that were already built from it.

Use a small dedicated template when several items share only one action. A Character Item containing unrelated alternate actions will copy all of them.

## Build a new item from an Action Template

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**.
2. Configure the new item's **Item**, **Name**, **Character**, **Item Definition**, **Animator Item ID**, and supported perspective fields. These values belong to the new item and are not read from the template.
3. Leave **Character** empty and enter **Slot ID** when creating a reusable prefab. Assign an existing scene character and choose its matching first- and third-person Item Parents when building directly into that character's Item Placement hierarchy.
4. Under **Actions**, assign the tested source Character Item to **Action Template**. The field is empty by default.
5. Confirm that the displayed action rows match the source. The list is read-only while an Action Template is assigned because the template supplies the complete stack.
6. Select **Build Item**. If **Reference Resolver** opens, resolve its fields before completing the inspection described below.

![Item Manager configured to build SuperAssaultRifle with AssaultRifleWeapon assigned as the Action Template and the copied Shootable and Melee rows locked](https://opsive.com/wp-content/uploads/2022/10/TemplateItem.png?v=574a0e0726dd)

### Choose a reusable prefab or a character-specific item

| Target | Generated result |
| --- | --- |
| **Character** is empty | Item Manager asks where to save the Character Item prefab. **Slot ID** is entered directly. For a built-in Item Type, **Add Item Prefab to Item Definition** is enabled by default and adds the saved prefab to that Item Type's **Prefabs** list. |
| **Character** references an existing scene character | Item Manager builds the Character Item for that character and uses its matching Character Item Slots. If the character has the built-in Inventory, **Add to Default Loadout** initially appears enabled. |
| The character supports multiple models | Prefer a reusable Character Item prefab and test its perspective parents on every model; Item Manager warns against building the item directly onto a multi-model character. |

The visible Action Template workflow is a new-item build workflow. Selecting an existing Character Item changes the button to **Update Item** and hides the build-only template and perspective fields. If an existing item needs a different action stack, duplicate it or build a controlled replacement first. Template application is a one-time replacement, not a merge or live synchronization.

## Understand what is copied

Item Manager removes the destination's action components, sorts the template actions by ID, creates matching built-in action types, and resolves the template's serialized action data onto them. This includes:

- action IDs, names, descriptions, States, timing, and other serialized action settings;
- every action module group, module type, order, ID, enabled state, bindings, and serialized module value; and
- action-owned perspective reference properties, which Reference Resolver attempts to map to the new item's hierarchy.

Action Template does not copy:

- Character Item root settings such as Item Definition, Slot ID, Animator Item ID, equip and unequip triggers, State presets, UI monitoring, or Drop Prefab;
- First Person or Third Person Perspective Item components, visible models, spawn parents, local offsets, materials, or Animator Controllers;
- the source item's Inventory amount, Item Set, default loadout entry, or prefab registration; or
- custom helper GameObjects that exist only beneath the template and have no equivalent in the destination hierarchy.

Configure those choices on the destination item. This separation allows a rifle and a turret, for example, to share a tested Shootable action without sharing a hand slot, visible model, or Animator Item ID.

## Resolve destination references

Reference Resolver tries to replace references into the template with equivalent destination objects. It can map the target root, matching relative child paths, Animator hierarchies, and Humanoid bones. Project assets and prefab references outside the template hierarchy can remain shared.

When a reference cannot be mapped safely, the modal **Reference Resolver** window lists the action, module group, module, and field path that still points to the template.

![Reference Resolver listing five flashlight action fields whose Light and Attribute Manager references still point to children of the template item](https://opsive.com/wp-content/uploads/2022/10/ReferenceResolver-1.png?v=752d7a603e4d)

For every listed field:

1. Read the full field path to identify the copied module and perspective value.
2. Create the required destination helper object when it does not exist, or decide that the optional reference should be **None**.
3. Assign the equivalent object from the destination item, character, or perspective hierarchy.
4. Confirm that the warning stating that the destination is a child of the template item disappears.
5. Select **Close**, then inspect the copied action in its normal Inspector.

Object-field changes are applied immediately; there is no separate Apply button. **Close** does not require every warning to be cleared. Closing while a field still selects a child of the template leaves an unwanted cross-item reference, so resolve or deliberately clear every warning first.

## Check the generated result

Before entering Play Mode, select the new Character Item and confirm:

- its Item Definition, Slot ID, Animator Item ID, first- and third-person objects, and local offsets belong to the destination;
- its action types, IDs, names, descriptions, module groups, module order, and module IDs match the intended template stack;
- Use, Reload, Block, or another Item Ability targets the copied **Action ID**;
- every projectile origin, hitbox, light, effect, audio, Attribute Manager, and perspective property resolves to the destination or an intentional shared asset;
- no field references the template scene object or template prefab instance; and
- the saved prefab appears once in the intended Item Type and Item Set workflow.

Save the destination as a separate prefab. Editing it later does not edit the source template, and editing the source does not propagate to the destination.

## Verify in Play Mode

1. Inspect Inventory and Item Set Manager. Confirm that the destination Item Definition is owned, its Character Item spawns in the intended slot, and its Item Set becomes active.
2. Equip the item in every supported perspective. Confirm that the destination models and spawn parents are used rather than the template's hierarchy.
3. Run every copied action separately. Confirm that the matching Item Ability starts the intended Action ID and that each module reaches its expected runtime state.
4. Observe projectiles, hits, lights, effects, audio, ammunition, attributes, and animation events. Confirm that helper objects belong to the destination and that no template object becomes active or moves.
5. Unequip, re-equip, remove, and grant the item again. Confirm that pooled Character Items and module helpers reset correctly.
6. Check the Console and the action Debug foldout for missing references, blocked modules, and incomplete use or reload events.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Item** is disabled | Check Name, Item Definition, supported perspectives, matching first- and third-person Slot IDs, and whether the template is the same item being edited. | Complete the required target fields and choose a different Character Item as the template. |
| The action rows cannot be edited | Check whether **Action Template** is assigned. | This is expected. Clear Action Template to construct the destination action list manually, or edit the source template first and build again. |
| A copied action starts from the wrong input | Compare the copied action IDs with the Use, Reload, Block, or other Item Ability **Action ID**. | Point the ability to the intended copied ID; do not assume every template begins with action ID `0`. |
| A projectile, hitbox, light, or effect uses the template object | Inspect Reference Resolver warnings and every perspective-aware module property. | Create or select the destination helper and replace the template-child reference before saving. |
| The action works, but the item is invisible or misplaced | Inspect the destination's perspective objects, layers, spawn parents, and local offsets. | Configure the destination perspective setup; Action Template does not copy it. |
| Custom actions on a destination disappear | Check whether an Action Template was applied to an item that already had actions. | Restore the prefab from version control or a duplicate, then use a dedicated template containing the complete desired stack. The operation is a replacement, not a merge. |
| Reference Resolver closes with warnings still visible | Reopen the copied action and look for fields that still reference the template. | Assign the destination object or **None** manually. The **Close** button does not validate completion. |
| A custom CharacterItemAction becomes a Usable action | Check whether the source action is one of the exact built-in types recognized by Item Manager. | Do not clone a custom CharacterItemAction subclass with Action Template in released Version 3; add and configure that component through its supported custom workflow. |

For runtime equip, animation, perspective, or pooling problems after the copy is structurally correct, continue with [Item Troubleshooting](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-troubleshooting/).

## Related tasks

- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)
- [Common Item Setups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/)
- [Item Tips](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-tips/)
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/)
- [Character Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)
- [Action Modules and Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)
- [First Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/)
- [Third Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/)
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/)
- [Character Templates](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/templates/)

## Developer details

`ItemManager.AddTemplateActions` removes every existing `CharacterItemAction`, creates each template action in ID order, initializes matching module groups and module types, then passes the serialized fields to `ReferenceResolverWindow.ResolveFields`. Because the field copy includes the serialized action and module data, IDs and module settings come from the template even though the newly created components begin with builder defaults.

Reference Resolver keeps shared `ScriptableObject`, Sprite, Material, AudioClip, and persistent prefab references. For hierarchy objects, it attempts Humanoid-bone, Animator-hierarchy, and relative-path mapping before reporting a conflict. A custom helper object is not cloned merely because a module references it.

Released UCC Version 3.2.0 recognizes the exact built-in Shootable, Melee, Magic, Throwable, Shield, and Usable action classes in Item Manager. Any other `CharacterItemAction` type falls through to the Usable builder path, so custom action subclasses require their own copy or construction workflow.

---

<a id="page-ultimate-character-controller-items-inventory-item-creation-item-troubleshooting"></a>

# Item Troubleshooting

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-troubleshooting/)

Use this guide when an item is owned but does not appear, equip, use, reload, or return to a ready state. Work through the checks in order: Inventory, Item Set, Character Item, perspective object, action, and animation each depend on the previous stage.

## Reproduce the problem before changing settings

Use one Play Mode run to identify where the item stops progressing:

1. Select the character and expand **Inventory > Current Inventory**. Record the Item Identifier, amount, and equipped slot.
2. Open the **Item Set Manager** and find the group that contains the item. Record whether its Item Set is Active, Invalid, Enabled, or Disabled.
3. Expand the runtime Character Item and its Item Action. Enable the action's **Debug** foldout and record the first rejected or waiting state.
4. In the Animator, record `SlotXItemID`, `SlotXItemStateIndex`, `SlotXItemSubstateIndex`, and `SlotXItemStateIndexChange` for the affected slot.
5. Reproduce equip, use, reload, perspective switching, and pickup or re-equip as separate tests. This distinguishes a setup problem from a reuse or timing problem.

Changes made to runtime clones are lost when Play Mode ends. Copy any useful transform values, then make the fix on the prefab or serialized component in Edit Mode.

## The item is not in the Inventory

**Check:** In Play Mode, expand **Current Inventory** and look for the expected Item Identifier and amount. A bold entry followed by `(Slot X)` is currently equipped in that slot.

![Inventory Current Inventory list showing AssaultRifle active in slot 0 and the owned ammunition counts](https://opsive.com/wp-content/uploads/2022/10/InventoryAtRuntime_edited.png?v=e099815b708f)

**Fix:** Add the item through the character's default loadout, an Item Pickup, or the intended inventory workflow. If the entry is present with an amount of zero, fix the source that grants the item rather than changing its equip settings.

**Retest:** Confirm that the amount increases and remains correct after picking up, dropping, and reacquiring the item.

## Inventory owns the item but no Character Item appears

**Check:** While the Item Identifier is present, inspect the character's Item Placement hierarchy for a Character Item in the required Slot ID. On the Inventory component, confirm that **Auto Spawn Destroy Runtime Character Items** is enabled when the character should create Character Items from the Item Type's prefab list.

**Fix:** Assign a valid Character Item prefab for each slot the item can use. The prefab needs the correct Item Definition, Slot ID, perspective objects, and actions. Remove duplicate prefabs that resolve to the same item and slot. If automatic spawning is disabled intentionally, create and manage the Character Item through your own inventory flow.

**Retest:** Start with no runtime clone, grant the item, and confirm that one Character Item is created under Item Placement. Remove and grant the item again to verify that the pooled instance is restored correctly.

## The Item Set is missing, invalid, or never becomes active

**Check:** Inspect the relevant Item Set group in Play Mode. Its status identifies whether the set is Active, Invalid, Enabled, or Disabled. Then confirm that the set contains the expected Item Identifier in the correct slot and that its rule accepts the current inventory amounts.

![Item Set Manager in Play Mode showing active AssaultRifle, enabled SinglePistol, invalid DualPistols, and default Body Item Sets](https://opsive.com/wp-content/uploads/2022/10/ItemSetManagerAtRuntime.png?v=f3f02215df7f)

**Fix:** Correct the Item Set Rule, category, slot assignment, or required amount. If a State disables the set, inspect the active States and presets before changing the rule. An Item Set can be valid without being active, so also confirm that the intended equip input or default selection requests it.

**Retest:** Equip the set and confirm that it becomes Active, its Character Items receive their equip request, and the previous Item Set's active State is released as expected.

## Equip or unequip starts but never completes

**Check:** On the Character Item, inspect **Equip Event**, **Equip Complete Event**, **Unequip Event**, and **Unequip Complete Event**. For each checkpoint, note whether it waits for an animation event, a slot event, or a duration. Then inspect the animation clip that actually plays.

![Character Item Equip and Unequip event settings mixing animation-event waits with duration fallbacks](https://opsive.com/wp-content/uploads/2022/10/EquipUnequipAnimationEventTrigger.webp?v=659c33c2a759)

![Animation clip event calling ExecuteEvent with the OnAnimatorItemEquip event name](https://opsive.com/wp-content/uploads/2022/10/EquipAnimationEvent.webp?v=b74bcaf2840d)

**Fix:** Make the clip and trigger agree. Use the exact event expected by the checkpoint, such as `OnAnimatorItemEquip`, `OnAnimatorItemEquipComplete`, `OnAnimatorItemUnequip`, or `OnAnimatorItemUnequipComplete`. If the controller deliberately has no matching event, configure a tested duration fallback instead. Do not simply disable every wait: equip and unequip must still tell the ability when the visible object and Item Set can advance.

**Retest:** Equip and unequip at normal speed and during a rapid Item Set change. Verify that every requested slot completes and that the Equip Unequip ability stops.

## The equipped item is invisible

**Check:** Focus the runtime perspective object in the Scene view. Confirm that it is active, has a visible scale, uses the expected renderer, and is under the correct first- or third-person hierarchy.

![Atlas third-person hierarchy with ThirdPersonAssaultRifle under the right-hand AssaultRifleParent](https://opsive.com/wp-content/uploads/2022/10/AtlasAssaultRifleThridPersonHierarchy.png?v=05d856183a61)

![Atlas first-person hierarchy with FirstPersonAssaultRifle under the arms Items hierarchy](https://opsive.com/wp-content/uploads/2022/10/Atlas_AssaultRifle_FirstPerson_Hierarchy_edited.png?v=15612f4774de)

For a first-person object, check the Overlay layer. For a third-person object, check the SubCharacter layer. If a skinned mesh is visible in the Scene view but disappears only at particular poses or camera angles, inspect its renderer bounds.

![AssaultRifle Skinned Mesh Renderer Bounds showing the center and extent controls](https://opsive.com/wp-content/uploads/2022/10/SkinedMeshBounds.png?v=533862800bbc)

**Fix:** Correct the hierarchy, layer, local scale, renderer state, or bounds that caused the observable failure. Avoid changing global camera clipping planes as a routine item fix; UCC's first-person rendering mode and the active render pipeline determine how Overlay objects are drawn.

**Retest:** Rotate the character and camera through the full gameplay range, switch perspectives, and verify that only the intended perspective object is visible.

## The item is in the wrong location

**Check:** On the First Person or Third Person Perspective Item, verify **Spawn Parent**, **Local Spawn Position**, **Local Spawn Rotation**, and **Local Spawn Scale**. If **Spawn Parent** uses an Object Identifier, confirm that the target identifier exists on this character model and that its ID matches.

![Atlas AssaultRifleParent selected with Object Identifier ID 50001001 named Assault Rifle Spawn Point](https://opsive.com/wp-content/uploads/2022/10/ItemParentObjectIdentifier_edited.png?v=773122308689)

**Fix:** Enter Play Mode, equip the item, pause, and position the visible object or its intended parent. Copy the useful local transform values, exit Play Mode, and apply them to the serialized perspective-item fields or prefab. Use a model-specific parent identified by an Object Identifier when characters have different proportions. If Material Swapper hides first-person objects while positioning them, temporarily enable its manual swap option, then restore the intended automatic runtime behavior.

**Retest:** Equip the same item on every supported model and perspective. Verify the result after a fresh scene load, not only on the edited runtime clone.

## Use starts but the item does nothing

**Check:** First confirm that the Use ability targets the equipped Slot ID and the intended Action ID. In the Character Item action's **Debug** foldout, attempt one use and read the first failure or wait reason. Then check whether the required action modules are enabled and active.

![Shootable Action Debug foldout reporting a blocked start while waiting for the Use Complete event and showing fire and impact data](https://opsive.com/wp-content/uploads/2022/10/ShootableItemActionDebugInspector-595x1024.png)

**Fix:** Resolve the first blocked stage rather than changing several settings at once. Common fixes are selecting the correct action, enabling the required module, aligning the Trigger module with the Animator substate, or adding the configured **Use Event** and **Use Complete Event** to the clip. If the action uses duration triggers instead, verify those durations against the animation.

**Retest:** Press and release Use once. Confirm that the action enters its use state, performs its effect, receives its completion checkpoint, and returns to idle.

## Use completes visually but the item or abilities remain locked

**Check:** Keep the action Debug foldout open after the visible effect. Look for **Waiting for Use Event**, **Waiting for Use Complete Event**, **Waiting for Next Allowed Use Time**, a module blocking start, or a module blocking the item from stopping. Compare the event timing with the clip that actually ran.

**Fix:** Add or move the missing animation event, or configure an intentional duration. Ensure the completion event occurs after the action begins waiting for it. If a module blocks stopping, correct that module's stop condition. Treat a configured next-use delay as expected cooldown behavior rather than an animation lock.

**Retest:** Use once, wait for completion, and start an unrelated ability. Both the action and Use ability should be idle before the next input unless the design intentionally keeps them active.

## Reload does not start or finish

**Check:** Confirm that the Reload ability's Slot ID and Action ID point to the equipped action. In the action's reload modules, verify that the item can reload: the clip is not already full, reserve ammunition exists, and the selected reloader accepts the request. If reload starts, identify whether it waits for `OnAnimatorItemReload`, `OnAnimatorItemReloadComplete`, or an optional detach, drop, attach, or reactivate event.

**Fix:** Correct the slot or action target, ammunition relationship, module selection, or missing event. Test Reload without pressing Use; beginning a Use action can intentionally interrupt the matching item's reload.

**Retest:** Reload from a partially used clip, from a full clip, and with no reserve ammunition. Only the valid case should run, and it should return the action and Reload ability to idle.

## Rapid input causes an intermittent lock

**Check:** Reproduce the issue while watching `SlotXItemStateIndex`, `SlotXItemSubstateIndex`, and the `SlotXItemStateIndexChange` trigger. Confirm that every substate selected by the Trigger module has a valid Animator transition and that repeated uses can re-enter the intended state.

**Fix:** Add the missing transition or re-entry path and make the Trigger module's substate selection match the controller. Animation events must exist on every clip that can satisfy the transition, not only on the first variant.

**Retest:** Test a single press, press and release, and rapid repeated input. The Debug foldout should report a complete start-to-stop cycle each time.

## Changing perspective hides the item or shows both versions

**Check:** Identify which perspective object is active and inspect its layer. First-person item objects normally use Overlay; third-person item objects use SubCharacter. Also verify that the perspective item resolves the correct slot and spawn parent.

**Fix:** Assign each visible object to its intended perspective component and layer. Correct a missing parent, zero scale, or invalid local offset before changing camera settings. For multiplayer characters, diagnose the locally controlled character separately from remote characters because remote characters use the third-person representation.

**Retest:** Switch first to third person and back several times. Exactly one intended representation should remain visible after every switch.

## The arms or body rotate incorrectly while using an item

**Check:** Start with the animation, avatar, Character Item slot, and hand targets. Then inspect Character IK weights and any States or presets that override them while the item is equipped or used.

![Character IK Inspector showing look weights, upper-arm and hand weights, and item-specific State presets](https://opsive.com/wp-content/uploads/2022/10/CharacterIKInspector.png?v=c8650b172603)

If the gameplay should face the character toward the aim target, inspect **Rotate Towards Look Source Target** on the Use ability.

![Use ability with the enabled Rotate Towards Look Source Target option outlined in orange](https://opsive.com/wp-content/uploads/2022/10/UseAbilityRotateTowardsLookAtSource_edited.webp?v=f7352df19781)

Only inspect the action's root-motion options when the animation was authored to move or rotate the character.

![Shootable Action with the disabled Force Root Motion Position and Force Root Motion Rotation options outlined in orange](https://opsive.com/wp-content/uploads/2022/10/ForceRootMotion_Inspector_edited.webp?v=97a972de024f)

**Fix:** Correct the animation or target placement first, then tune the item-specific Character IK State. Enable facing or root-motion behavior only when the chosen animation and locomotion design require it; neither option is a general-purpose clipping fix.

**Retest:** Aim and use at the extreme camera angles supported by the game. The hands should remain on their targets without pulling the torso through itself or rotating the character unexpectedly.

## The item works once but fails after drop, pickup, or re-equip

**Check:** Compare the first use with the reused Character Item. Look for a module that remains in a waiting state, an event registered more than once, a stale target or ammunition reference, or a spawned effect that was never reset. Automatic Character Item spawning and several item modules reuse pooled objects.

**Fix:** Reset transient state whenever a pooled object is enabled or returned, unregister event listeners at the matching lifecycle point, and clear cached runtime references. Apply the correction to the prefab or module source rather than to the active clone.

**Retest:** Repeat grant, equip, use, unequip, drop, and pickup at least three times. The inventory amount, Item Set status, action result, and event count should match on every cycle.

## Related tasks

- [Create an item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)
- [Review current item setup tips](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/item-tips/)
- [Configure Item Pickups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/)
- [Understand Inventory ownership](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/)
- [Configure Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/)
- [Configure Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/)
- [Understand the Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/)
- [Configure Usable actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/)
- [Configure action module groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)
- [Configure Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/)
- [Configure the Use ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Configure the Reload ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/)
- [Verify item Animator parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/)
- [Configure UCC layers](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/)
- [Tune Character IK](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/)
- [Use the State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer debugging

### A custom module becomes null after a rename

Action modules use Unity's `[SerializeReference]` serialization. Renaming or moving the class without a migration hint can make existing serialized module entries resolve to `null`.

Add `[MovedFrom]` to the renamed class with its previous class and namespace:

```csharp
[UnityEngine.Scripting.APIUpdating.MovedFrom(
    true,
    sourceClassName: "MyPreviousClassName",
    sourceNamespace: "My.PreviousNamespace.Name")]
```

Load and reserialize every affected prefab and asset, then verify the migration on every maintained project branch. Keep the attribute while older serialized data can still enter the project; removing it immediately can break an asset that has not yet been migrated.

### Capture the first rejected runtime stage

When a custom item still fails, log or breakpoint the first stage that disagrees with the Inspector evidence: inventory amount, Character Item spawn, Item Set validity, Equip Unequip checkpoint, perspective activation, `CanStartUseItem`, module start, use completion, or pooled reset. Recording that boundary before stepping through source prevents a later waiting state from hiding the original cause.

---

<a id="page-ultimate-character-controller-items-inventory-item-type-definition-category"></a>

# Item Type, Definition & Category

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/)

Use the Item Collection, Categories, and Item Types to give every built-in UCC item a consistent identity, inventory capacity, equipment group, and optional Character Item prefab.

## Understand the item data model

The released Ultimate Character Controller Version 3 uses several related terms. They are not interchangeable:

| Term | What it represents | Built-in UCC behavior |
| --- | --- | --- |
| **Item Collection** | The project asset that contains Categories and Item Types | The Item Set Manager resolves its item and category IDs against this collection. |
| **Item Category** | A named group used for Item Set groups and category-based rules | An Item Type can select one or more Categories. The Item Type Manager presents a flat category list. |
| **Item Definition** | The shared data contract represented by `ItemDefinitionBase` | The built-in concrete definition is an Item Type. Character Items, pickups, loadouts, and modules serialize an Item Definition reference. |
| **Item Identifier** | The runtime identity used as an Inventory key | A built-in Item Type returns itself as its Item Identifier, so an amount of five bullets is one identifier with a count of five. |
| **Item Type** | UCC's built-in definition and identifier asset | It stores **Name**, **Category**, **Capacity**, and optional Character Item **Prefabs**. |

The **Character Item** is separate. It is the runtime object that appears on the character and contains slots, perspective objects, Item Actions, and animation settings. An Item Type named Rifle identifies how many rifles the character owns; the Rifle Character Item defines how the rifle equips, appears, and fires.

## Choose the built-in model or Ultimate Inventory System

Use the built-in UCC model for controller-focused equipment and count-based resources. It works well for a rifle, an Iron Sword, and a Rifle Ammo count when each Item Type has one shared definition.

Use the [Ultimate Inventory System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) when UIS should own mutable per-item data, inventory collections and UI, shops, crafting, or saved item instances. In that workflow, a UIS Item Definition replaces the UCC Item Type as the integrated item's identity, while the UCC Character Item prefab still supplies controller behavior. Do not create a duplicate UCC Item Type for the same UIS-owned item or run the standard UCC Inventory beside the UIS character bridge.

## Create the Item Collection

1. Open **Tools > Opsive > Ultimate Character Controller > Item Type Manager**.
2. In **Item Collection**, select a project-owned collection. If none exists, select **Create** and save `ItemCollection.asset` outside the Opsive package folders.
3. Keep one intended collection selected while creating Categories and Item Types.
4. Assign that same collection to every standard UCC character that exchanges items, and to the **Item Set Manager** on those characters.

Creating a collection also creates an **Items** Category and an **Individual Item Set Rule** asset beside the collection. The rule is a useful starting asset, but it still must be assigned and reviewed for the character's slots and equipment workflow.

## Add the Categories

1. Select the **Categories** tab.
2. Enter `Weapons` in **Name**, then select **Add**.
3. Add `Ammo` for count-only ammunition. Add other Categories only when they express an equipment group or rule the game actually uses.
4. Keep every Category name unique within the collection.

The current Item Type Manager does not author a Category hierarchy. It assigns a generated Category ID and exposes **Name**. When an Item Type selects multiple Categories, UCC creates a hidden composite Category at runtime whose parents are those selected Categories. This lets the same Item Type match more than one category-based check without creating a separate editor-authored parent Category.

Do not remove a Category while an Item Type uses it. The manager blocks that removal and identifies the dependent Item Type.

## Add the Item Types

1. Select the **Item Types** tab.
2. Enter `Rifle` in **Name**, then select **Add**.
3. Expand Rifle and set **Category** to Weapons.
4. Set **Capacity** to the maximum number the Inventory may own. Use `1` when the character may own only one Rifle.
5. Leave **Prefabs** empty until the Rifle Character Item prefab has been built, then return and add that prefab.
6. Repeat the workflow for `Iron Sword` with Category Weapons and Capacity `1`.
7. Create `Rifle Ammo`, select Category Ammo, set an appropriate reserve Capacity such as `120`, and leave **Prefabs** empty when ammunition never appears as a Character Item.

New Item Types initially use the first Category in the collection and default to a Capacity of `2,147,483,647`. Review both values instead of relying on those defaults.

### Editor checkpoint

Before creating pickups or loadouts, confirm that:

- the Item Type Manager shows the intended project-owned **Item Collection**;
- Rifle and Iron Sword select Weapons, and Rifle Ammo selects Ammo;
- each Item Type has a deliberate nonnegative **Capacity**;
- every visible or equippable Item Type references its tested Character Item prefab; and
- count-only Item Types such as Rifle Ammo have no unnecessary Character Item prefab.

## Connect the data to gameplay

### Character Items and actions

Create the visible item with the [Item Manager workflow](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) and set the Character Item's **Item Definition** to the corresponding Item Type. Add the completed Character Item prefab to the Item Type's **Prefabs** list. When one identity can equip in more than one slot, the list can contain a separate Character Item prefab for each supported slot.

The Item Type does not make an item shootable or melee-capable. Configure that behavior on the Character Item's Item Actions and modules. For example, a Rifle's Shootable Action can use **Item Ammo** with **Ammo Item Definition** set to Rifle Ammo. The module then consumes that identifier's Inventory amount. See [Shootable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/).

### Inventory and pickups

The standard [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) stores an integer amount for each Item Identifier. For the built-in model, the Item Type itself is that identifier. Adding an amount is clamped to the Item Type's **Capacity**. When runtime Character Item spawning is enabled, the Inventory uses the Item Type's **Prefabs** list to create the matching Character Items.

An [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) stores **Item Definition Amounts**. A Rifle pickup can grant Rifle with amount `1`, while an ammunition pickup can grant Rifle Ammo with amount `30`. An ammo-only pickup does not need a Character Item prefab and normally should not request an equipment change.

### Item Sets

The [Item Set Manager and rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) decide which owned Character Items may equip together:

- use an exact Item Type rule when only Rifle or only Iron Sword may occupy a position;
- use a Category rule when any Item Type assigned to Weapons may occupy that position; and
- use separate Item Set groups only when their sets must be active in parallel.

Assign a Category to every built-in Item Type, including count-only resources. In the current runtime, an Item Definition with no resolved Category is treated as a member of every Item Set group by `IsCategoryMember`, which is broader than most projects intend.

## Apply the model to common items

| Scenario | Item Type setup | Character Item and runtime result |
| --- | --- | --- |
| Rifle | Weapons; Capacity `1`; Rifle prefab | The Inventory owns one Rifle identity. Its Character Item supplies the Shootable Action and slot. |
| Iron Sword | Weapons; Capacity `1`; Iron Sword prefab | The same data model supports a Melee Action without changing the Item Type. |
| Rifle Ammo | Ammo; Capacity `120`; no prefab | Pickups and loadouts change one numeric amount. The Rifle's ammo module consumes that amount. |
| Two identical pistols | Weapons; Capacity at least `2`; right- and left-slot prefabs | One Item Type amount can supply two slot-specific Character Items. Item Set Rules decide whether one or both equip. |

Use separate Item Types when two items need separate ownership, capacity, prefab lists, or rule matching. Do not create a second Item Type only to represent another copy of the same count-based built-in item.

## Verify in Play Mode

1. Select the character and confirm its **Item Set Manager > Item Collection** is the project collection used in the Item Type Manager.
2. Give the character one Rifle, one Iron Sword, and Rifle Ammo through **Inventory > Default Loadout** or pickups.
3. Expand the Inventory's runtime list. Confirm each Item Type appears once with the expected amount rather than as one entry per copy.
4. Collect more Rifle Ammo than the remaining capacity. Confirm the Inventory accepts only the amount up to the Rifle Ammo Capacity.
5. Equip the Rifle and Iron Sword separately. Confirm each creates the intended Character Item and matches only the expected Item Set.
6. Fire and reload the Rifle. Confirm the module consumes Rifle Ammo, not the Rifle amount.
7. If an Item Type belongs to multiple Categories, test each category-based rule and confirm it matches the intended groups without producing an unintended combination.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character owns an item but no visible object appears | Item Type **Prefabs**, Character Item **Item Definition**, slot, and Inventory runtime-spawn setting | Assign the correct Character Item prefab, keep its definition on the same Item Type, and correct the slot or spawning setting. |
| The amount stops increasing | Item Type **Capacity** and the amount already owned | Raise the deliberate capacity or reduce the pickup/loadout amount. Do not create a duplicate Item Type to bypass the limit. |
| An item matches the wrong equipment group | Item Type **Category**, Item Set group Category, and the selected Item Set Rule | Assign the intended Category and narrow the rule to the correct Category, Item Type, or slot combination. |
| An uncategorized resource is considered by unrelated groups | The Item Type has no selected Category | Assign a dedicated Category such as Ammo even when the item has no Character Item prefab. |
| A weapon cannot reload | The Shootable Action's **Ammo Item Definition** and the Inventory amount | Assign the exact Rifle Ammo Item Type and confirm the character owns a positive amount. |
| A pickup grants an amount but also tries to equip | The pickup's **Equip**, **Item Set Name**, and Item Type prefab | Disable **Equip** for count-only resources such as ammo. |
| References resolve to the wrong item after a data change | Item Collection assignment and Item Type IDs | Restore the expected collection, then migrate saved or networked IDs before shipping the changed data. |

## Keep saved and networked identities stable

The Item Collection, its Categories, and its Item Types are project assets. Runtime Inventory amounts are separate and are not a general save file by themselves. A save integration should record an Item Type ID and amount, resolve the ID through the same Item Collection, restore the amount, and then restore the intended Item Set.

Item Type IDs are unique only within their Item Collection. The current Item Type Manager assigns IDs from the Item Type array and reassigns the remaining IDs when an Item Type is deleted. Avoid deleting a shipped Item Type without a save migration. Category IDs are generated independently, but recreating a Category still creates a different identity.

UCC's conditional multiplayer hooks use Item Identifiers, and `ItemIdentifierTracker` maps built-in Item Type IDs through an Item Collection. Every peer must therefore use matching collection data, and inventory changes should run on the authoritative instance. These hooks do not supply a networking transport or complete inventory replication by themselves.

UIS uses a different persistence and networking ownership model. When the [UIS integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) is active, save and replicate UIS Items and collections through that workflow, then let the bridge rebuild the UCC Character Item representation.

## Related tasks

- [Create Item Types and Categories](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-types/) covers the Item Type Manager controls.
- [Create a Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) connects an Item Type to visible objects, actions, slots, and prefabs.
- [Configure Character Items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) explains the runtime item object.
- [Configure Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) maps Character Items to right, left, and custom slots.
- [Configure Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) controls owned amounts, loadouts, pickups, drops, and death behavior.
- [Configure Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) turns Categories and Item Types into valid equipment combinations.
- [Configure Item Pickups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) grants Item Definitions and amounts from world objects.
- [Connect Ultimate Inventory System](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) uses UIS definitions and Items instead of built-in Item Types.

## Developer reference

`ItemType` derives from `ItemDefinitionBase` and implements `IItemIdentifier`. Its `CreateItemIdentifier()` and `GetItemDefinition()` methods both return the same Item Type instance. This is why built-in inventory amounts are aggregated by Item Type rather than represented as mutable per-copy objects.

Use the Item Collection to resolve assets and the Inventory API to change runtime amounts:

```csharp
using Opsive.Shared.Inventory;
using Opsive.UltimateCharacterController.Inventory;

public static class ItemDataExample
{
    public static bool AddRifleAmmo(
        ItemCollection itemCollection,
        InventoryBase inventory,
        int amount)
    {
        if (itemCollection == null || inventory == null) {
            return false;
        }

        var ammoType = itemCollection.GetItemType("Rifle Ammo");
        if (ammoType == null) {
            return false;
        }

        IItemIdentifier ammoIdentifier = ammoType.CreateItemIdentifier();
        return inventory.AddItemIdentifierAmount(ammoIdentifier, amount) > 0;
    }
}
```

The main identity and membership APIs are:

- `ItemCollection.GetItemType(uint|string)` and `GetCategory(uint|string)`;
- `ItemDefinitionBase.CreateItemIdentifier()`, `GetItemCategory()`, and `InherentlyContains(IItemIdentifier)`;
- `IItemIdentifier.GetItemDefinition()`, `GetItemCategory()`, and `InherentlyContainedByCategory(uint)`;
- `IItemCategoryIdentifier.InherentlyContains(...)`; and
- `InventoryBase.GetItemIdentifierAmount`, `AddItemIdentifierAmount`, `PickupItem`, and `RemoveItemIdentifierAmount`.

Inventory amount changes send `OnInventoryAdjustItemIdentifierAmount` with `(IItemIdentifier, int previousAmount, int newAmount)`. Pickups send `OnInventoryPickupItemIdentifier` with `(IItemIdentifier, int amount, bool immediatePickup, bool forceEquip)`. A spawned Character Item additionally participates in `OnInventoryAddItem`, `OnInventoryPickupItem`, and the slot-aware equip, unequip, and remove events. Categories and Item Types are static assets; changing their editor data does not send an Inventory amount event.

---

<a id="page-ultimate-character-controller-items-inventory-item-set-rules"></a>

# Item Set & Rules

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/)

Item Set Rules turn the Character Items in an Inventory into valid loadouts, such as a rifle, a sword and shield, or two pistols. Use them when the character must equip compatible items together and switch between those combinations predictably.

![Sword and shield equipped together as one two-slot Item Set in Play Mode](https://opsive.com/wp-content/uploads/2022/10/SwordAndShieldGameView-300x256.png)

## How Item Sets work

Three parts participate in every loadout:

1. An **Item Set Rule** examines the Character Items available in each Slot ID and generates matching combinations.
2. An **Item Set** records one generated combination, its State name, whether it is enabled, and how it participates in switching and fallback.
3. The character's **Item Set Manager** owns the groups, rebuilds their sets when Character Items change, and asks the matching [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) ability to activate a set.

Each **Item Set Group** is identified by one **Item Category**. More than one group can be active, which is useful when a main weapon and an independent utility item should not replace each other. Give every group a unique category and add a matching Equip Unequip ability for that category.

The character must own every required Item Definition, and it must have a Character Item with the exact Slot ID expected by the rule. Owning an item count without its slot-specific Character Item is not enough to make an equippable set valid.

## Configure the Item Set Manager

1. Select a UCC character with an [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/), Item Set Manager, and Ultimate Character Locomotion.
2. On **Item Set Manager**, assign the **Item Collection** that owns the Item Types and categories used by the character's Item Definitions.
3. Expand **Item Set Groups** and add one group for each independently equipped loadout family.
4. Set the group's **Item Category**. Avoid using the same category in two groups.
5. Create rule assets from **Assets > Create > Opsive > Ultimate Character Controller > Inventory**, then add them to the group's edit-time **Item Set Rules** list in the intended priority order.
6. Add or select an Equip Unequip ability and set its **Item Category** to the same category as the group. Add matching Equip Next, Equip Previous, or Toggle Equip abilities only when the player needs those controls.
7. Leave **On Add Item Update Item Sets Option** at its starting value, **Immediately**, for the simplest setup. Use **Schedule To Late Update** to combine several Character Item changes in one frame. Use **Manual** only when project code calls `UpdateItemSets()` after every relevant change.

![Item Set Manager edit-time Inspector showing Item Collection and Item Set Groups with their Item Category and Item Set Rules](https://opsive.com/wp-content/uploads/2022/10/ItemSetManagerInspectorEdittime.png?v=93d1f80aae95)

### Create one predictable default

A default gives the group a known unequipped fallback.

1. Create an **Item Type Item Set Rule** with no required Item Types in its slot list.
2. Keep **Allow Empty Item Set** enabled and enable **Default**.
3. In **Default Item Set**, set **State** to a stable name such as `Unequipped`, keep **Enabled** on, and disable **Can Switch To** if next/previous inputs should skip it.
4. Put this rule first in the group.

Use exactly one Default rule per group, and make that rule produce one predictable set. If several generated sets are marked Default, the later generated set becomes the group's default.

### Editor checkpoint

Before entering Play Mode, Item Set Manager should show the correct Item Collection, one unique Item Category per group, a matching Equip Unequip ability for each group, and the rules ordered from the most intentional combination to the broadest fallback.

## Choose a built-in rule

All built-in rules except Multi use the same template:

| Setting | Starting value | Effect |
| --- | --- | --- |
| **Allow Empty Item Set** | Enabled | Allows an all-empty set only when every slot in that rule is optional. Disable it on broad rules when a separate rule owns the empty fallback. |
| **Default Item Set > State** | `{0}` | Replaces `{0}` with the Item Definition names concatenated in slot order. Use a fixed, unique State name when code or a pickup selects the set by name. |
| **Default Item Set > Enabled** | Enabled | Lets generated sets pass the first validity check. A State can change this value at runtime. |
| **Default Item Set > Can Switch To** | Enabled | Includes generated sets in Equip Next and Equip Previous cycling. Direct equip requests do not use this filter. |
| **Default Item Set > Disabled Index** | `-1` | Uses the default set, or unequips if no valid default exists, when an active set becomes disabled. A nonnegative value requests that runtime Item Set index. |
| **Default** | Disabled | Marks the generated set as the group's default. Use it on only one single-result rule. |

![Generated Item Set template showing State, Enabled, Can Switch To, Disabled Index, and State presets](https://opsive.com/wp-content/uploads/2022/10/ItemSetInspector.png?v=e6dd8a01c414)

### Individual Item Set Rule

**Individual Item Set Rule** produces one single-item set for each matching Character Item and leaves the other slots empty. **Item Type Exceptions** and **Item Category Exceptions** exclude definitions that should be handled by a more specific rule. Both exception lists start empty.

Use Individual for a quick one-item-per-loadout setup. Place specific pair or dual-wield rules above it, and add their types or categories as exceptions when the individual alternatives should not exist.

![Individual Item Set Rule Inspector showing the shared Item Set template and Item Type and Item Category exception lists](https://opsive.com/wp-content/uploads/2022/10/IndividualItemSetRule.png?v=627a153188df)

### Item Type Item Set Rule

**Item Type Item Set Rule** matches an exact Item Type or one of its inherited definitions at each populated **Item Type Slots** position. A null position must remain empty; a populated position requires a matching Character Item with that same Slot ID. **Exact Amount Validation** starts disabled.

Enable **Exact Amount Validation** only when the Inventory amount must equal the number of occupied slots. For example, a two-pistol set using the same definition in two slots is valid only at an amount of exactly `2`; owning `3` also makes that exact rule invalid. Leave it off when the character may carry spare copies.

![Item Type Item Set Rule Inspector showing Exact Amount Validation and the Item Type Slots list](https://opsive.com/wp-content/uploads/2022/10/ItemTypeItemSetRule.png?v=ca9234570436)

### Category Item Set Rule

**Category Item Set Rule** accepts any Item Definition that belongs to the category assigned at the corresponding **Item Category Slots** position. Null positions remain empty. **Item Type Exceptions** and **Item Category Exceptions** remove special cases, and **Exact Amount Validation** has the same starting value and exact-equality behavior as the Item Type rule.

Use Category when many definitions can fill the same role, such as any `Sword` in one hand with any `Shield` in the other. Category membership includes inherited categories, so use the exception lists when a child category needs its own rule.

![Category Item Set Rule Inspector showing category slots, exact amount validation, and exception lists](https://opsive.com/wp-content/uploads/2022/10/CategorylItemSetRule.png?v=4ab6d16c420b)

### Multi Item Set Rule

**Multi Item Set Rule** contains an **Item Set Rules** array and returns the generated sets from every child rule. It is useful when several characters should share one organized rule asset. The array has no entries by default.

Multi does not provide its own Item Set template. Each child keeps its own State, empty-slot, validity, and Default choices. Include at most one Default child; the asset warns when multiple direct children are Default, but the runtime still resolves the later generated default.

![Multi Item Set Rule Inspector grouping several child Item Set Rule assets](https://opsive.com/wp-content/uploads/2022/10/MultiItemSetRule.png?v=e01226279adf)

## Build common loadouts

### Rifle with an unequipped fallback

1. Create the dedicated empty Default rule described above.
2. Create an Item Type rule for the rifle. Add the Rifle Item Type at the position matching the rifle Character Item's Slot ID and leave every other position null.
3. Give the template a unique **State**, or keep `{0}` when the generated Item Definition name is a suitable identifier.
4. Keep **Can Switch To** enabled so Equip Next and Equip Previous can select it.
5. Put the rifle rule before any broad Individual or Category rule that can also match the rifle.

### Sword and shield with a sword-only fallback

1. Create an Item Type or Category rule with Sword in the sword Character Item's slot and Shield in the shield Character Item's slot.
2. Create a second rule that requires only Sword and leaves the shield slot null.
3. Put the two-item rule first. When both are valid, first-match lookups prefer the sword-and-shield set; after the shield is removed, Equip Unequip can fall back to the closest valid sword-only set.
4. If an Individual rule is also present, exclude the Sword and Shield types unless separate one-item loadouts are intentional.

### Dual-wield pistols

1. Create two Character Item prefabs for the pistol definition, one for each required Slot ID. The rule cannot move one Character Item into a different slot.
2. Create an Item Type rule with the pistol type in both slot positions.
3. Keep **Exact Amount Validation** disabled when the Inventory may own more than two pistols. Base validity already requires enough quantity for both occupied slots.
4. Add a single-pistol rule after the dual rule when losing or dropping one pistol should preserve a valid one-handed loadout.

See [Dual Wielding](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/dual-wielding/) for the Character Item, action, and Animator setup beyond the rule itself.

## Understand selection and fallback

### Valid, enabled, active, and next

An Item Set is valid only when all of these checks pass:

- **Enabled** is on.
- Its rule accepts the combination and any exact amount requirement.
- Every nonempty position resolves to a Character Item with that exact Slot ID.
- The Inventory owns enough quantity for repeated definitions.
- Each usable Character Item reports that it can equip.
- Any ability-provided allowed-slot mask includes the required positions.

**Can Switch To** is checked by Equip Next and Equip Previous, not by every direct equip API. The active set is the loadout currently equipped; the next set is the target being equipped or unequipped.

![Item Set Manager in Play Mode showing generated Item Sets with active, enabled, disabled, and invalid status icons](https://opsive.com/wp-content/uploads/2022/10/ItemSetManagerInspectorRuntime.png?v=1c0fa0a829a7)

Select a runtime Item Set to inspect its rule, slot assignments, State, **Enabled**, **Can Switch To**, **Disabled Index**, and State presets.

![Expanded runtime Item Set showing its rule, slot objects, State, Enabled, Can Switch To, and Disabled Index](https://opsive.com/wp-content/uploads/2022/10/ItemSetManagerInspectorItemState.png?v=1e9866bc6401)

The inspect control beside a rule or slot opens that object without replacing the Item Set Manager selection.

![Item Set Rule opened from the Item Set Manager while the manager context remains available](https://opsive.com/wp-content/uploads/2022/10/ItemSetRuleOpenedwithButton.png?v=1e02dd8cabcf)

### Rule order is selection order

Item Set Manager appends generated sets in **Item Set Rules** order. First-match lookups and name lookups return the earliest matching set. Equip Next and Equip Previous walk the same runtime list, wrap at the ends, and skip sets that are invalid or have **Can Switch To** disabled.

Put exact combinations first, broad Category rules next, and Individual fallbacks last. Give every generated set a unique State name when a pickup or script selects it by name; duplicate State names resolve to the first match.

### Pickup, removal, and death

An [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) adds Character Items to the Inventory. The manager then rebuilds the sets according to **On Add Item Update Item Sets Option**, and Equip Unequip can select a valid set. A pickup with **Item Set Name** requests the first generated set with that exact State name.

When a Character Item is destroyed after a drop or removal, Item Set Manager rebuilds the list. If the active combination is no longer possible, Equip Unequip looks for the closest valid set by shared definitions and exact slot matches, then uses the default when no closer match exists.

On death, Equip Unequip moves away from the active set. When Inventory's **Unequip All On Death** is disabled, it remembers and restores the previous set after Inventory reports respawn. When items are removed or the default loadout is reloaded, the resulting Inventory contents determine which sets can be rebuilt.

### State-driven fallback

The Item Set's **State** becomes active on the character while that set is active. A State preset can disable the set for a restriction such as a gameplay mode. If an active set becomes disabled, **Disabled Index** requests a valid runtime set at that index. With `-1`, the manager uses the default when it is valid or unequips.

Runtime indices can change when the Inventory or rule order changes. Use **Disabled Index** only with a stable generated list; prefer a controlled State or a named equip request when dynamic rules make the index unreliable.

## Verify in Play Mode

1. Select the character and expand **Item Set Groups > Item Sets** on Item Set Manager.
2. Load or pick up the rifle. Confirm the rifle set appears as enabled and becomes active when its Equip Unequip policy allows it.
3. Add the sword and shield. Confirm the two-item set places each Character Item in its exact slot and appears before its one-item fallback.
4. Remove or drop the shield. Confirm the sword-only set remains valid and becomes the fallback without moving the sword to another slot.
5. Add two pistols and select the dual set. Remove one and confirm the dual set becomes invalid while the single-pistol fallback remains available.
6. Press Equip Next and Equip Previous. Confirm cycling follows the runtime list, wraps, and skips the empty default when its **Can Switch To** value is disabled.
7. Activate any State that disables the current set. Confirm **Disabled Index** or the default produces the intended fallback.
8. Kill and respawn the character with both **Unequip All On Death** choices tested. Confirm the resulting active set matches the Inventory's configured death and respawn behavior.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| No Item Sets appear in Play Mode. | Check **Item Collection**, the group's **Item Category**, **Item Set Rules**, the Inventory's Character Item prefabs, and **On Add Item Update Item Sets Option**. | Assign the collection containing those Item Types and categories, add a rule, and use **Immediately** or **Schedule To Late Update**. In **Manual**, call `UpdateItemSets()` after changes. |
| A set appears but is invalid. | Expand it and compare every rule position with the Character Item's Slot ID, Inventory amount, usable-item requirements, and **Enabled** value. | Create the Character Item for the required slot, correct the rule position, add the missing amount, or enable the set. |
| A sword cannot fill the other hand. | One Character Item has only one Slot ID. | Create a second Character Item prefab for the other slot and include that slot in the intended rule. |
| Equip Next skips a valid-looking set. | Check **Can Switch To** and the full validity checks, including exact amount and usable-item ammunition requirements. | Enable switching or correct the failed validity condition. |
| The wrong combination equips after pickup. | A broader rule or duplicate State name may appear before the intended rule. | Move the exact rule earlier, exclude its items from broader rules, and use unique State names. |
| The group logs that no matching Equip Unequip ability exists. | Its **Item Category** does not match an Equip Unequip ability, or no Equip Unequip ability exists. | Add one ability per independent group and assign the same category. |
| Initialization fails after adding a second group. | Two groups may use the same Item Category. | Assign a unique category to every group and match each with its own abilities. |
| A dual-wield set becomes invalid when a third copy is collected. | **Exact Amount Validation** requires equality, not a minimum. | Disable it when spare copies are allowed. |
| The fallback changes after inventory updates. | **Disabled Index** refers to the regenerated runtime list. | Stabilize rule order and contents, or replace the index-dependent design with a named/default workflow. |
| The wrong default equips. | More than one generated set is marked **Default**. | Keep one Default rule that produces one set; remove Default from every other rule and Multi child. |

## Persistence and multiplayer

Rule assets, their template fields, and the edit-time group list are serialized project data. Generated Item Sets, their runtime indices, and the active/next references are runtime state. A save workflow should restore the Inventory and Character Items, rebuild with `UpdateItemSets()`, and then restore the intended loadout. Prefer a unique State name over a saved runtime index.

Item Set Rules do not provide networking. In a multiplayer project, the supported integration must own Inventory changes and Equip Unequip authority. Each peer can generate the same sets only when it has the same Item Collection, rule assets, Character Items, and replicated Inventory state. Replicate any runtime rule changes before asking peers to rebuild.

## Related tasks

- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) configures Character Item prefabs, loadout amounts, death behavior, and runtime ownership.
- [Item Type, Definition, and Category](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/) explains the identities and inherited category matching used by rules.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) defines the positions that rule arrays must match.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) explains the slot-specific object required by a valid set.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) can add definitions and request a named Item Set.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs the actual loadout transition.
- [Equip Next](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-next/) and [Equip Previous](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-previous/) cycle switchable sets.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) controls State presets that can enable or disable a generated set.
- [Ultimate Inventory System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) uses its own equipment workflow and integration-specific rule boundary.

## Developer details

Use the manager for ordinary rebuilds, lookups, and equip requests:

```csharp
m_ItemSetManager.UpdateItemSets();

ItemSet itemSet = m_ItemSetManager.GetItemSet("SwordAndShield", groupIndex);
bool equipped = m_ItemSetManager.TryEquipItemSet(
    itemSet, forceEquipUnequip: false, immediateEquipUnequip: false);
```

The overloads of `GetItemSet` accept an Item Identifier, ordered identifiers, a State name, or a runtime index. `GetActiveItemSet`, `GetNextItemSet`, and their index forms expose the current transition state. A group can add, insert, remove, or replace runtime `IItemSetRule` instances; those methods schedule a rebuild.

The main events are:

- `OnItemSetGroupWillUpdate` `(ItemSetGroup, List<ItemSetStateInfo>)` before add, keep, and remove states are applied.
- `OnItemSetGroupUpdated` `(ItemSetGroup)` after the group finishes rebuilding.
- `OnItemSetIndexChange` `(int groupIndex, int activeItemSetIndex)` after a rebuild or active-set change.
- `OnActiveItemSetChange` `(int groupIndex, ItemSet previous, ItemSet current)` when the active set changes.
- `OnItemSetManagerUpdateNextItemSet` `(int groupIndex, int previousIndex, int nextIndex)` when Equip Unequip changes its target.

For a custom rule, implement `IItemSetRule` or derive from `ItemSetRuleBase` and provide `GetNextItemSetsStateInfo` plus `IsItemSetValid`. Deriving from `ItemSetRule` reuses permutation and template handling; implement `DoesCharacterItemMatchRule` and `CanSlotBeNull`. Review the four built-in rules before changing add/keep/remove behavior because Item Sets remain alive while equip and unequip animations are in progress.

Released Version 3.2.0 behaviors worth treating as design constraints are:

- **Exact Amount Validation** compares Inventory amount for equality with the number of repeated occupied slots; extra copies invalidate the set.
- The group's Default index is overwritten by each later generated set marked Default. Multi warns about multiple direct Default children, but the group still needs one single-result Default rule.
- State-name and item lookups return the first match in generated order, and **Disabled Index** refers to that mutable runtime order.

---

<a id="page-ultimate-character-controller-items-inventory-character-item"></a>

# Character Item

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/)

A Character Item is the character-side GameObject for equipment such as an Iron Sword, firearm, shield, grenade, flashlight, or book. The inventory records what the character owns; the Character Item supplies the slot, visible first- and third-person objects, animation values, equip and drop behavior, and actions that make the item usable.

![Character Item Inspector showing the Assault Rifle definition, slot and Animator IDs, equip settings, UI settings, events, and states](https://opsive.com/wp-content/uploads/2022/10/CharacterItemInspector.png?v=f34b1f714fc2)

## Understand the item parts

These parts work together, but they have different responsibilities:

| Part | Responsibility |
| --- | --- |
| **Item Definition** | Identifies what the inventory entry represents. With the built-in inventory, an Item Type acts as both the Item Definition and Item Identifier. |
| **Character Item** | Represents that definition in one character slot and coordinates equip, unequip, perspective, animation, UI, and drop behavior. The inventory looks it up by Item Identifier and Slot ID. |
| **Perspective Item** | Owns the object shown for a perspective and places it under the correct first- or third-person parent. |
| **Character Item Action** | Performs the gameplay operation, such as a melee attack, shot, block, spell, throw, or generic use. Item Abilities select actions by their action **ID**. |

Do not interchange **Slot ID**, **Animator Item ID**, and an action **ID**. The slot chooses where the item can be equipped, the Animator Item ID selects the item's animation data, and the action ID selects what the item does.

## Create a Character Item

Before building the item, create its [Item Definition](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/), prepare the visible object or objects, and make sure the character has the required [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/).

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**.
2. Assign the source **Item** object and enter a **Name**.
3. To build directly on a scene character, assign **Character**. To create a prefab that the inventory can add at runtime, leave **Character** empty and set **Slot ID**.
4. Assign **Item Definition** and enter the **Animator Item ID** used by the character's Animator Controller.
5. Under **First Person**, enable **Add First Person Item** when needed, then assign **First Person Base**, **First Person Visible Item**, and **Item Parent**. Use **Add ItemSlot** if the selected parent does not have one.
6. Under **Third Person (including AI and Multiplayer)**, enable **Add Third Person Item** when needed, then assign **Third Person Visible Item** and either the humanoid hand or **Item Parent**.
7. Under **Actions**, add the action type and name. Choose **Melee** for an Iron Sword or **Shootable** for a firearm. **Action Template** can copy an existing item's action setup when starting a new item.
8. For a scene character, leave **Add to Default Loadout** enabled when the item should be owned at startup. For a runtime prefab backed by an Item Type, **Add Item Prefab to Item Definition** associates the saved prefab with that type.
9. Select **Build Item**, choose the prefab location when prompted, and then inspect the created object. Select an existing Character Item in the manager and use **Update Item** for later structural changes.

The manager requires at least one perspective. When both perspectives are present, their Item Slots must use the same ID.

### Choose a build location

| Goal | **Character** field | Result |
| --- | --- | --- |
| The item always exists on this scene character | Assign the character | The Character Item is created below the character's Item Placement object and can be added to **Default Loadout**. |
| An item can be added to characters at runtime | Leave empty | The manager opens **Save Item** and creates a reusable prefab. An Item Type can keep that prefab in its **Prefabs** list. |

The complete [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) workflow covers source models, runtime prefabs, Animator setup, and common configurations.

## Check the generated hierarchy

The Character Item component belongs on the main item GameObject below the character's Item Placement object. This object remains the inventory-facing representation even when its visible models are parented elsewhere.

![Character hierarchy with Body, Assault Rifle, and two Pistol Character Items below the Items placement object](https://opsive.com/wp-content/uploads/2022/10/CharacterItemsHiearchy_edited.png?v=684cdfd010f8)

For third person, the visible object is placed under the selected character bone or Item Slot while the main Character Item stays below Item Placement.

![Third-person Assault Rifle visible object below the right-hand Items parent and its Character Item below the root Items placement object](https://opsive.com/wp-content/uploads/2022/10/CharacterThirdPerspectivesItemHiearchy.png?v=a26ddcd6ac65)

For first person, the visible object is placed below the first-person base or arms, normally beneath the camera's First Person Objects hierarchy.

![First-person Assault Rifle below the camera arms hierarchy and its Character Item below the character Items placement object](https://opsive.com/wp-content/uploads/2022/10/CharacterFirstPerspectivesItemHiearchy.png?v=3e3ae1f1348f)

Continue with the page for the perspective that needs detailed placement or motion settings:

- [First Person Perspective](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) covers the first-person base, visible object, spawn parent, control objects, and spring-driven motion.
- [Third Person Perspective](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/) covers hand parenting, IK targets, holstering, and third-person visibility.
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) covers action IDs, action modules, and multi-action items.

## Configure the Character Item Inspector

The Item Manager fills the structural references. Use the Character Item Inspector to make the gameplay-specific choices.

### Identity and animation

- **Item Definition** identifies the inventory entry. The runtime **Item Identifier** shown below it is read-only.
- **Slot ID** is the inventory slot and perspective spawn location.
- **Animator Item ID** selects the item in the slot-specific Animator parameter. It should match the Animator transitions created for this item.
- **Animator Movement Set ID** defaults to `0` and lets an equipped item select a different movement animation set.
- **Dominant Item** defaults to enabled. A dominant item controls movement animation values and item UI; an off-hand item commonly leaves this disabled.
- **Allow Camera Zoom** defaults to enabled.

### Equip, unequip, and drop

- **Drop Prefab** is the object spawned when the item is dropped.
- **Full Inventory Drop** defaults to disabled. Enable it only when dropping the item should remove the complete owned amount, as a throwable setup may require.
- **Equip Event** and **Unequip Event** each default to a `0.3` second duration on a newly added Character Item component.
- **Equip Complete Event** and **Unequip Complete Event** default to `0` seconds.
- Each trigger can wait for its matching Animator event instead of a duration. The Item Manager adjusts timing for some generated perspective configurations, so inspect the generated values rather than assuming the component defaults were retained.
- **Equip Animator Audio State Set** and **Unequip Animator Audio State Set** choose the animation substate and audio used during the transition. See [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/).

The **UI** foldout contains **UI Monitor ID**, the item **Icon**, aim crosshair controls, and optional full-screen UI. The **Events** foldout exposes **Pickup Item**, **Equip Item**, **Unequip Item**, and **Drop Item** UnityEvents. The **States** foldout can override settings while a named state is active.

## Add one or more actions

A Character Item can contain several Character Item Actions on the same GameObject. For example, a firearm can have a Shootable action for its primary use and a Melee action for a butt strike. Give every action a unique **ID**, then configure the corresponding Item Ability to use that ID.

![Character Item with first- and third-person perspective components plus Shootable and Melee actions](https://opsive.com/wp-content/uploads/2022/10/CharacterItemGameobjectComponents.png?v=bc5e5350a77e)

For a straightforward Iron Sword, start with one **Melee** action. For a firearm, start with one **Shootable** action. Add a second action only when the player must choose a genuinely different operation; different attack variations can often stay inside one action's modules instead.

## How it runs

1. When the inventory adds the Item Identifier, the Character Item initializes its perspective components and actions. Its pickup phase makes only the currently equipped item visible and invokes **Pickup Item**.
2. An Item Set and the Equip Unequip Item Ability choose the Character Item for the slot. The item starts its equip state set, prepares both perspective representations, and waits for the configured equip trigger when the transition is not immediate.
3. On equip, the active perspective object becomes visible, each action receives the equip notification, item UI is updated, and **Equip Item** is invoked.
4. A Use, Reload, Block, Drop, or other Item Ability selects the appropriate Character Item Action and coordinates its animation and modules.
5. On unequip, the item clears dominant animation data, hides its active visible object and UI, notifies its actions and perspectives, and invokes **Unequip Item**.
6. If a drop was requested while the item was equipped, the inventory finishes the drop after unequip. It removes the required amount, spawns **Drop Prefab** when assigned, and invokes **Drop Item**.

Use the corresponding Item Ability or Inventory API to request these operations. Do not call `Pickup`, `Equip`, `Unequip`, `Drop`, or action lifecycle methods directly from normal gameplay code; bypassing the ability flow also bypasses item sets, animation timing, and interruption rules.

## Editor checkpoint

Before entering Play Mode, verify all of the following:

- The main Character Item is below Item Placement or saved as the intended runtime prefab.
- **Item Definition**, **Slot ID**, and **Animator Item ID** are assigned deliberately.
- At least one Perspective Item has a valid visible object and spawn parent.
- First- and third-person Item Slots use the same ID when both perspectives exist.
- Every Character Item Action is on the main item GameObject and has a unique **ID**.
- The **Equip Event**, **Equip Complete Event**, **Unequip Event**, and **Unequip Complete Event** match the Animator events or durations used by this item.
- A dropped item has a valid **Drop Prefab** and the inventory contains an amount that can be removed.

## Verify in Play Mode

1. Acquire the item and confirm that the inventory amount changes without showing an unequipped visible object unexpectedly.
2. Equip it and watch the Animator parameters, transition timing, visible object, audio, and item UI.
3. If the character supports both perspectives, switch views while equipped. Only the correct perspective object should be visible, and both should represent the same slot.
4. Activate every configured action. A multi-action firearm should run the action selected by the Item Ability's action ID.
5. Unequip the item and confirm that its visible object, UI, and active action state stop at the expected animation point.
6. Drop it and verify the removed inventory amount, spawned prefab, and **Drop Item** UnityEvent.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Item** is disabled | Perspective selection and first-/third-person Item Slot IDs | Enable at least one perspective. If both are enabled, give both Item Slots the same ID. |
| The inventory owns the item but no model appears | Perspective **Object**, **Spawn Parent** or Item Parent, slot, and active perspective | Assign the visible object and a valid Item Slot parent. Confirm that the Character Item's Slot ID matches that slot. |
| The wrong item animation plays | **Animator Item ID**, **Animator Movement Set ID**, and controllers on the character or visible object | Match the IDs to the Animator transitions and ensure the manager-added parameters exist in each assigned controller. |
| Equip or unequip never completes | The four transition triggers and their Animator events | Add the matching animation event, or configure the trigger to use a duration. Verify both the action point and complete point. |
| The item equips but an action does nothing | Item Ability action selection and each Character Item Action **ID** | Point the Item Ability at an existing action ID and keep every ID on the item unique. |
| A runtime item prefab is not created for its Item Type | **Add Item Prefab to Item Definition** and the Item Type's **Prefabs** list | Rebuild or update the association, then confirm the saved prefab appears in the Item Type. |
| A Magic action combined with another action throws a duplicate-key error during initialization | Released Version 3's Item Manager builder leaves a newly added Magic action at its default action ID of `0`, while another first action may also use `0` | After building, inspect every Character Item Action and assign unique IDs before entering Play Mode. This limitation applies to the verified released-Version-3 builder path; do not rely on component order to resolve it. |
| A remote network character has no first-person item | Network ownership | This is expected: non-local players are forced to the third-person perspective. Configure a third-person item for anything other clients must see. |

## Saving and multiplayer boundaries

The Character Item's authored configuration lives on its scene object or prefab. Runtime ownership and amounts live in the Inventory, so the project's save integration must save and restore inventory data. If an action module contains custom runtime state, add explicit save support for that state rather than expecting the Character Item to serialize it automatically.

When multiplayer support is compiled, Character Item Actions use the network inventory bridge supplied by the installed multiplayer integration. Non-local characters use the third-person item. Custom modules, UnityEvent side effects, and project-specific spawned objects still need an authority and replication design; adding a Character Item alone does not synchronize them.

## Related tasks

- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) explains ownership, amounts, default loadout, and the runtime item collection.
- [Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) decide which Character Items can be equipped together.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) coordinates item-set transitions and Character Item timing.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) selects and runs a Character Item Action.
- [Drop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) removes an amount and creates the drop object.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains event- and duration-driven transition points.

## Developer reference

Retrieve the equipped Character Item for a slot through the Inventory:

```csharp
CharacterItem characterItem = m_Inventory.GetActiveCharacterItem(slotID);
```

Retrieve the action selected by an Item Ability:

```csharp
CharacterItemAction itemAction = characterItem.GetItemAction(actionID);
```

Inspect the currently rendered perspective and equipped state:

```csharp
PerspectiveItem perspectiveItem = characterItem.ActivePerspectiveItem;
bool isActive = characterItem.IsActive();
```

For reactions that do not need custom code, assign the Inspector UnityEvents **Pickup Item**, **Equip Item**, **Unequip Item**, and **Drop Item**. Code that must observe Animator timing can subscribe to `OnAnimatorItemEquipEvent`, `OnAnimatorItemEquipCompleteEvent`, `OnAnimatorItemUnequipEvent`, and `OnAnimatorItemUnequipCompleteEvent`; each reports the slot ID.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-first-person-perspective"></a>

# First Person Perspective

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/)

The First Person Perspective Item connects a Character Item to the arms and item model seen by the local player. It resolves the correct first-person base and Item Slot, controls which objects are visible, and adds procedural spring motion for movement, looking, landing, leaning, bob, and shake.

![First Person Perspective Item Inspector with Assault Rifle render references and the Position Spring controls expanded](https://opsive.com/wp-content/uploads/2022/10/FirstPersonPerspectiveItem.png?v=baaada8e295a)

## Understand the first-person hierarchy

The first-person setup is split across several objects so each part has one responsibility:

| Object or component | Responsibility |
| --- | --- |
| **FirstPersonObjects** | Follows the attached camera and activates the first-person base objects needed by equipped dominant items. Character Manager creates this container. |
| **First Person Base Object** | Usually the separate arms rig. Its ID lets a runtime Character Item find the correct arm set. At runtime it creates the pivot used by the perspective springs. |
| **Item Slot** | Marks the hand or other attachment point. Its ID must match the Character Item's **Slot ID**. |
| **First Person Perspective Item > Object** | References the base object controlled by the perspective, normally the arms. Several items can share this object. |
| **First Person Perspective Item > Visible Item** | References the actual firearm, Iron Sword, shield, or other model below the selected Item Slot. It can be empty when the base object already contains everything that should render. |
| **Character Item** | Owns the Item Definition, slot, equip timing, UI, and the first- and third-person perspective components. |
| **Character Item Actions** | Stay on the main Character Item GameObject and perform use, reload, melee, block, and other gameplay. They do not belong on the arms or visible item model. |

For a character that supports both perspectives, the [Third Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/) owns a separate world-visible model. Character Manager's **Third Person Objects** list identifies body renderers that should be hidden from the local first-person view; it is separate from the Character Item's first-person **Visible Item**.

## Prepare the character

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager** and select the character.
2. Set the character to a first-person or both-perspective configuration.
3. Under the model's first-person options, assign **First Person Arms** and their Animator Controller. Character Manager places each arm root below **FirstPersonObjects** and adds **First Person Base Object**.
4. Add or adjust an Item Slot below the correct hand. Decide its ID before creating items that use it.
5. If the full-body character contains a head, arms, held object, or other mesh that must not render for the local first-person camera, add the corresponding renderer object to **Third Person Objects**.
6. Select **Update Character**, then inspect the generated `FirstPersonObjects > arm base > Item Slot` hierarchy.

See [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) for arm-rig and Animator preparation. A generic arm rig uses its own matching animations rather than Unity humanoid retargeting.

## Add the perspective to an item

Use **Tools > Opsive > Ultimate Character Controller > Item Manager** for the supported setup path.

1. Select or create the [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/).
2. Enable **Add First Person Item**.
3. Assign **First Person Base** to the arm set that should hold the item.
4. Assign **First Person Visible Item** to the rendered model. For a firearm, use the first-person firearm model; for an Iron Sword, use the sword model aligned to the hand.
5. Assign **Item Parent** to the Item Slot below the intended hand. Select **Add ItemSlot** if the parent does not have one.
6. Assign an **Animator Controller** to the base or visible item when it has its own animation. The builder adds an Animator when needed, disables root motion, uses **Always Animate**, and adds a Child Animator Monitor.
7. Add the required action on the main Character Item: normally **Shootable** for the firearm or **Melee** for the Iron Sword.
8. Select **Build Item** or **Update Item**, then inspect the generated First Person Perspective Item component.

The manager puts the generated first-person hierarchy on the **Overlay** layer. It also adds a spatial Audio Source to a visible item that does not already have one. Configure firing, impacts, melee contact, ammo, and other behavior on [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/), not on this perspective component.

### Choose how the base and model are shared

| Setup | **Object** | **Visible Item** | Use it when |
| --- | --- | --- | --- |
| Shared arms with separate items | The common arms base | The firearm or Iron Sword model | Several items use the same arms and Item Slots. Equipping switches only the item model while keeping the shared base available. |
| One self-contained arm-and-item object | The dedicated base object | Optional | One arm rig is built specifically for one item. The complete base can activate and deactivate with that item. |
| No rendered item model | The shared or dedicated base | Empty | An action such as an invisible spell, body action, or interaction needs first-person ownership but no separate held model. |
| Runtime Character Item prefab using the character's arms | Resolved from **First Person Base Object ID** | Prefab model | The item is added after startup without bundling its own arms. The perspective resolves the character's base object and matching Item Slot, then reparents the visible model. |

Shared items are detected by comparing their **Object** references. When multiple Character Items use the same object, UCC keeps the shared base under `FirstPersonObjects` and toggles each **Visible Item** independently. A dedicated object is treated as independent and can be toggled as a unit. **Always Active** on the First Person Base Object overrides normal base activation and is intended for setups such as VR where the base must remain visible.

## Configure the Render foldout

The current First Person Perspective Item Inspector contains these render fields:

| Field | Purpose and starting value |
| --- | --- |
| **Spawn Parent** | Optional object identifier and Transform below the matching Item Slot. Use it when the visible model should spawn below a more specific child. |
| **Object** | The first-person base controlled by the perspective. If assigned manually, it must have First Person Base Object or be below an Item Slot. |
| **First Person Base Object ID** | Defaults to `0`. Runtime items use it to find the matching base on the active character model. |
| **Visible Item** | Defaults to empty. Assign the rendered weapon or item model when it is separate from **Object**. |
| **Local Spawn Position** and **Local Spawn Rotation** | Default to `(0, 0, 0)` and place a runtime-spawned object below its resolved parent. |
| **Local Spawn Scale** | Defaults to `(1, 1, 1)`. |
| **Additional Control Objects** | Starts empty. Add identified first-person base objects only when the item must drive another arm or base, such as a deliberate dual-wield setup. |

When a runtime item changes character model, the perspective repeats the lookup, reparents its visible item below the matching slot and optional spawn parent, reapplies the local transform, resolves additional control objects, and refreshes the Character Item's Animator monitors.

## Tune first-person motion

The motion foldouts combine regular animation with procedural response. Start with the generated values, test one group at a time, and use [States](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) when aiming, sprinting, or another mode needs different offsets.

| Foldout | What to tune |
| --- | --- |
| **Position Spring** | **Base Position Offset** adds a character-specific baseline to **Position Offset**. **Position Exit Offset** is the unequip target. Fall impact, movement slide, moving-platform slide, input scale, and maximum input velocity feed the spring. The default fall impact is `0.2`, softness is `10`, retract is `2`, and maximum input velocity is `25`. |
| **Rotation Spring** | **Rotation Offset** is the equipped rest angle and **Rotation Exit Offset** defaults to `(30, 0, 0)`. Look, strafe, vertical, and moving-platform sway feed the spring. The default fall impact is `10`, softness is `5`, ground sway multiplier is `0.5`, and maximum input velocity is `15`. |
| **Pivot Position Spring** and **Pivot Rotation Spring** | Move or rotate the runtime pivot without changing the authored arms hierarchy. These are also where secondary forces, landings, and lean contribute. |
| **Shake** | Adds continuous procedural rotation. **Shake Speed** starts at `0.15` and **Shake Amplitude** at `(4, 2, 1)`. Set the speed to `0` when no idle shake is wanted. |
| **Bob** | Adds movement-driven position and rotation. **Bob Require Ground Contact** defaults to enabled, and **Bob Max Input Velocity** defaults to `100`. |
| **Step** | Adds a small alternating footstep force while moving. **Step Min Velocity** is the squared-velocity threshold, **Step Softness** defaults to `4`, and **Step Force Scale** defaults to `1`. |

The component caps input before applying spring forces. If a high movement speed or mouse sensitivity makes an item unstable, lower **Position Input Velocity Scale** or **Rotation Input Velocity Scale** and set appropriate maximum input velocities before changing every spring coefficient.

## Configure overlay rendering

The Item Manager assigns first-person arms and visible items to UCC's **Overlay** layer. The active [First Person camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/) decides how that layer is drawn:

- **Second Camera** uses the generated child first-person camera and is the normal built-in-render-pipeline route.
- **Render Pipeline** uses the installed URP or HDRP integration and the main camera's **First Person Culling Mask**.
- **None** uses normal scene depth, so nearby world geometry can intersect the arms and item.

Match **Overlay Render Type** to the active render pipeline and keep **Overlay** in **First Person Culling Mask**. The perspective component does not create the URP renderer feature or HDRP custom pass. See [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) when the layer or collision setup has changed.

## How it runs

1. The Character Item initializes the perspective before its actions. A scene item uses its assigned **Object**; a runtime item can resolve the active model's First Person Base Object, matching Item Slot, and optional **Spawn Parent**.
2. When the Character Item starts, either at scene startup or during its first runtime pickup, the perspective determines whether its base object is independent or shared with another Character Item. The hierarchy and Animator references were prepared during initialization.
3. When a dominant item starts equipping, `FirstPersonObjects` activates every base object required by the equipped slots. The visible item becomes active, and a non-immediate equip moves from the exit offsets toward the regular spring offsets.
4. While equipped, the perspective combines character input, velocity, moving-platform motion, landings, lean, bob, shake, and secondary forces. A shared base object is updated only once per frame even if more than one active item refers to it.
5. Item Actions perform use and reload behavior. The perspective supplies their visible first-person object and Animator path but does not decide what the action does.
6. On perspective change, the Character Item selects its third-person counterpart and the first-person visible-item colliders are disabled. Returning to first person enables those colliders only while the item is active.
7. On unequip, the dominant item moves toward its exit offsets, the visible item is hidden, and `FirstPersonObjects` deactivates base objects no longer required by another equipped item.

## Editor checkpoint

Before entering Play Mode, confirm:

- The character contains one active **FirstPersonObjects** container for its current model.
- The intended arms have **First Person Base Object**, the correct ID, and a matching Item Slot.
- **Object** references those arms or the intended dedicated base.
- **Visible Item** is below the correct Item Slot and uses the **Overlay** layer.
- The Character Item **Slot ID** matches the first- and third-person slots when both perspectives exist.
- The arm and visible-item Animators have the required UCC parameters and Child Animator Monitor where applicable.
- Character Manager's **Third Person Objects** list hides only the full-body renderers that would obstruct the local first-person view.
- The camera's **Overlay Render Type** and **First Person Culling Mask** match the project's render pipeline.

## Verify in Play Mode

1. Equip the firearm or Iron Sword in first person. Confirm that the expected arms and visible item activate and attach to the correct hand.
2. Look, strafe, walk, jump, land, ride a moving platform, and lean. The item should return to its configured rest offsets without unstable spring motion.
3. Use and reload the item. Its Animator should remain synchronized with the character, and the action should operate on the intended first-person references.
4. Move close to a wall. With a configured overlay route, the arms and item should remain visible without being cut by scene depth.
5. Unequip and re-equip. Watch the exit offsets and confirm that a shared arm base remains available only when another equipped item needs it.
6. For a both-perspective character, switch to third person and back. Only the correct perspective model should render, and first-person visible-item colliders should follow the first-person state.
7. If the character can switch models, repeat the test on every model and confirm that each has equivalent base-object and slot IDs.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| No arms or item appear | **FirstPersonObjects**, **Object**, **First Person Base Object ID**, and the active model | Add or update the character's first-person arms, then point the item at the correct base or ID. |
| **Build Item** is disabled | **First Person Base**, **Item Parent**, and Item Slot | Use a scene instance of the arms, select a parent with Item Slot, and make its ID match the Character Item. The Item Manager cannot add components directly to an arm prefab asset. |
| The model appears at the origin or wrong hand | **Slot ID**, **Spawn Parent**, and local spawn transform | Match the slot IDs, correct the optional spawn-parent identifier, and reset or retune the local position, rotation, and scale. |
| The arms render but the weapon does not | **Visible Item**, its active state, and whether the item shares **Object** with another Character Item | Assign the weapon model to **Visible Item** and keep shared items pointed at the same base object. |
| The full-body head, arms, or held item blocks the view | Character Manager **Third Person Objects** and Material Swapper/Perspective Monitor setup | Add only the obstructing full-body renderers to **Third Person Objects**, select **Update Character**, and retest both perspectives. |
| Arms or items disappear, clip into walls, or render in the wrong order | **Overlay** layer, **Overlay Render Type**, **First Person Culling Mask**, and pipeline integration | Restore the Overlay layer and use the overlay route supported by the active pipeline before changing item offsets. |
| Item animation does not follow equip, use, or reload | Animator Controller and Child Animator Monitor on the base or visible item | Assign the intended controller through Item Manager and confirm it contains UCC's item parameters and clips. |
| A shared arm base turns off unexpectedly | **Object** references, **Dominant Item**, and First Person Base Object **Always Active** | Point all items that share arms at the same object. Use **Always Active** only when the base truly must remain on without a dominant equipped item. |
| Motion becomes extreme at high speed or sensitivity | Input scales, maximum input velocities, and spring values | Lower the position or rotation input scale, cap the corresponding velocity, then retune the affected spring. |
| Step motion is active even though the Inspector tooltip describes zero as the default | Released Version 3 initializes **Step Min Velocity** to `5`; the tooltip's default statement is stale | Set **Step Min Velocity** explicitly to `0` to disable step impacts. This is the verified released-Version-3 source behavior. |
| A remote player has no first-person arms or item | Network ownership and third-person setup | This is expected. UCC destroys first-person perspective objects for non-local, non-spectator characters; configure the third-person counterpart for remote visibility. |

## Saving and multiplayer boundaries

The component's authored render references, IDs, offsets, springs, and States live on the Character Item scene object or prefab. Its active visibility and current spring values are runtime presentation state; restore inventory ownership, equipped item sets, active character model, and camera perspective through the project's save flow, then let UCC rebuild the first-person presentation.

First-person objects exist for the local player or spectator only. When multiplayer support is compiled, initialization removes the first-person base and visible item from a non-local character, and `FirstPersonObjects` is disabled for that remote model. Network-visible equipment therefore requires a [Third Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/). Custom visual effects or action-module state still need explicit network authority and replication.

## Related tasks

- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) covers inventory identity, equip timing, actions, UI, and drop behavior shared by both perspectives.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds a complete item through Item Manager.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) defines the matching attachment IDs used by each perspective.
- [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) prepares arm rigs, controllers, base objects, and slots.
- [First Person camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/) configures overlay rendering, culling masks, field of view, and camera motion.
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) explains the spring controls shared across UCC motion systems.
- [Third Person Perspective](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/) configures the counterpart required for both-perspective, AI, and remote-player visibility.
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) configures what the equipped item does.

## Developer reference

Retrieve the first-person perspective from its Character Item and inspect the object that is actually rendered:

```csharp
using Opsive.UltimateCharacterController.FirstPersonController.Items;
using UnityEngine;

FirstPersonPerspectiveItem firstPersonItem =
    characterItem.FirstPersonPerspectiveItem as FirstPersonPerspectiveItem;

if (firstPersonItem != null) {
    GameObject visibleObject = firstPersonItem.GetVisibleObject();
    Transform springPivot = firstPersonItem.PivotTransform;
}
```

The component exposes properties such as `FirstPersonBaseObjectID`, `VisibleItem`, `BasePositionOffset`, `PositionOffset`, `RotationOffset`, and the spring groups. Setting an offset property during Play Mode refreshes the relevant spring rest value. Prefer changing authored values through States or presets when a gameplay mode such as aim or sprint owns the change, and leave pickup, equip, perspective, and unequip lifecycle calls to the Character Item and Item Abilities.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-third-person-perspective"></a>

# Third Person Perspective

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/)

The Third Person Perspective Item owns the world-visible model for a Character Item. It attaches that model to the correct character Item Slot, supplies third-person references to item actions, positions a two-handed grip with IK, and can move an unequipped item to a holster instead of hiding it.

![Third Person Perspective Item Inspector with its Render, IK, holster, and State controls](https://opsive.com/wp-content/uploads/2022/10/ThirdPersonPerspectiveItem.png?v=e771c7da8dce)

## Understand the third-person hierarchy

The inventory-facing Character Item and its rendered model live in different places:

| Object or component | Responsibility |
| --- | --- |
| **Item Placement** | Holds the main Character Item GameObjects on a scene character. |
| **Character Item** | Owns the Item Definition, Slot ID, equip timing, perspective components, and item actions. It stays below Item Placement. |
| **Character Item Slot** | Marks the hand or other attachment point below the active character model. Its ID must match the Character Item's **Slot ID**. |
| **Third Person Perspective Item** | Lives on the main Character Item and resolves the active model, Item Slot, visible object, optional spawn parent, IK targets, and holster. |
| **Object** | The firearm, Iron Sword, shield, or other model shown in the world. A scene-built item places it below the selected Item Slot; a runtime Character Item prefab stores it below the Character Item until initialization reparents it. |
| **Third Person Object** | Marks the visible object's root so Perspective Monitor can replace its materials in the local first-person view while keeping the world model available for third-person cameras, AI, and remote players. |
| **Character Item Actions** | Stay on the main Character Item. Their perspective properties point to third-person fire points, hitboxes, effects, and other children of the world model. |

The released Version 3 component does not use the old **Use Parent Humanoid Bone** or **Parent Humanoid Bone** fields. Choose the humanoid **Hand** or generic **Item Parent** in Item Manager; at runtime, the Character Item **Slot ID** and optional **Spawn Parent** identifier decide where the object attaches.

For a both-perspective character, the [First Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) owns a separate local arms/item representation. Both perspective components belong to the same Character Item, use the same slot ID, and share one set of actions.

## Build the perspective with Item Manager

1. Prepare the character with a [Character Item Slot](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) below the intended hand or attachment bone. Give it the Slot ID that the item will use.
2. Open **Tools > Opsive > Ultimate Character Controller > Item Manager** and select or create the [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/).
3. Under **Third Person (including AI and Multiplayer)**, enable **Add Third Person Item**. This toggle is enabled by default.
4. Assign **Third Person Visible Item** to the model that should be seen in the world. Select a model or model prefab, not an already-built Character Item.
5. For a Humanoid character, choose **Hand**; **Right** is the starting value. For a Generic character, assign **Item Parent** to a GameObject with the matching Character Item Slot.
6. Assign **Animator Controller** only when the visible item has its own animation, such as a firearm bolt or magazine. The character Animator still owns the character pose.
7. Add the item action on the main Character Item. Use [Shootable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) for a firearm or [Melee](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) for an Iron Sword.
8. When both perspectives are enabled, confirm that the first- and third-person Item Slots have the same ID.
9. Select **Build Item**, then inspect the generated hierarchy and Third Person Perspective Item component.

The builder clones the visible model, places its hierarchy on UCC's **SubCharacter** layer, and adds **Third Person Object** to its root when third-person, AI, or multiplayer visibility requires it. If the object has no Audio Source, the builder adds one with **Play On Awake** disabled, **Spatial Blend 1**, and **Max Distance 20**. When an Animator Controller is supplied, it adds or reuses an Animator, disables root motion, sets **Culling Mode** to **Always Animate**, and adds a **Child Animator Monitor**.

For a scene character, the builder places the visible object below the chosen Item Slot while the Character Item remains below Item Placement. For a reusable Character Item prefab, the visible object initially remains a child of the Character Item and is moved below the active model's matching slot when the inventory initializes it.

Released Version 3's **Update Item** path does not apply changes to **Add Third Person Item**, **Third Person Visible Item**, **Hand/Item Parent**, **Animator Controller**, or **Slot ID**. It updates only the item name, Item Definition, Animator Item ID, and action list or template. Make perspective changes directly on the existing component and hierarchy, or deliberately rebuild a replacement after preserving custom action and State settings.

## Configure the Render foldout

| Field | Released Version 3 starting value and purpose |
| --- | --- |
| **Spawn Parent** | ID `-1` and no object. Leave it unset to attach directly below the matching Item Slot. Assign an identified child below that slot when the model needs a more specific attachment transform. |
| **Object** | Empty on a newly added component. Assign the third-person model; leaving it empty is appropriate only for an intentionally invisible item whose actions do not need object-relative references. |
| **Local Spawn Position** | `(0, 0, 0)` for an object reparented from a runtime Character Item prefab. |
| **Local Spawn Rotation** | `(0, 0, 0)` for a runtime-reparented object. |
| **Local Spawn Scale** | `(1, 1, 1)` for a runtime-reparented object. |
| **Holster Target** | ID `-1` and no object. Assign an identified empty Transform below the active character model when an owned, unequipped item should remain visible. |

The Local Spawn fields are applied when the visible object begins below the Character Item and is reparented at runtime. A scene-built object that is already below a character Item Slot keeps its authored local Transform; reposition that scene object directly.

Both **Spawn Parent** and **Holster Target** use an ID/Object control, but their released Version 3 runtime lookups force a fresh search by ID. A direct Transform with ID `-1` is ignored. For either feature:

1. Create an empty GameObject below the Item Slot or active character model.
2. Add **Object Identifier** and give it a positive, unique ID.
3. Enter that same ID in **Spawn Parent** or **Holster Target**.
4. Repeat the same semantic target and ID on every model the character can switch to.

See [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) for the identifier component. Use positive IDs for model-resolved item-action references as well: released Version 3 resets cached third-person perspective properties on a model switch only when their ID is greater than `0`.

## Configure a firearm or Iron Sword

| Goal | Third-person model setup | Action references |
| --- | --- | --- |
| Two-handed firearm | Attach the firearm to the dominant-hand slot. Add a support-hand target at the foregrip and an optional elbow hint. Add identified children for the muzzle, fire point, shell, tracer, or other perspective-specific locations. | In the Shootable Action, assign each **Third Person** fire, muzzle, shell, tracer, projectile, reload, or scope property to the corresponding model child. Use positive IDs when the character can switch models. |
| One-handed Iron Sword | Attach the sword to the dominant-hand slot. Leave the non-dominant IK fields empty unless the animation deliberately uses a two-handed grip. Add a positive-ID holster target at the hip or back if the sword should remain visible when unequipped. | In the Melee Action, assign the third-person hitbox, trail, recoil, and effect references to the sword model. Let the action module control hit detection rather than leaving a presentation collider active continuously. |

Keep first-person and third-person references separate. A correct first-person muzzle or hitbox does not supply the third-person value automatically, and the third-person world model should not use the first-person **Overlay** layer.

## Position the non-dominant hand

Humanoid animation retargeting can put a support hand slightly away from an item's authored grip. **Non Dominant Hand IK Target** lets Character IK place the free hand on the visible object; **Non Dominant Hand IK Target Hint** optionally guides the elbow. If the item is attached to the right hand, the target controls the left hand, and vice versa.

![Third-person character holding an assault rifle before a non-dominant hand IK target is assigned, with the support hand missing the foregrip](https://opsive.com/wp-content/uploads/2018/05/ThirdPersonNoIKTarget.png?v=b3e29310684d)

1. Create an empty child on the visible item at the intended support-hand grip.
2. Rotate the child so its orientation matches the hand pose.
3. Assign it to **Non Dominant Hand IK Target**.
4. Optionally create an elbow guide and assign **Non Dominant Hand IK Target Hint**.
5. Confirm that the active Humanoid model has Character IK and that the relevant Animator layer has **IK Pass** enabled.
6. Equip, aim, use, reload, and unequip. Use a [State preset](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/) to reduce the relevant hand and elbow weights while an animation, such as reload, must release the grip.

![Third-person assault-rifle pose after a non-dominant hand IK target aligns the support hand with the foregrip](https://opsive.com/wp-content/uploads/2018/05/ThirdPersonIKTarget.png?v=c1bc28733a17)

The target should move with the item, so make it a child of the model rather than a scene-only helper elsewhere on the character.

![Assault-rifle hierarchy with a child Transform used as the non-dominant hand IK target](https://opsive.com/wp-content/uploads/2018/05/ThirdPersonIKTargetGameObject.png?v=9e4f5f5c315d)

The built-in Character IK route is for a Humanoid Animator. A Generic model needs matching authored animation or a project-specific IK solver. See [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) for character setup, layer indices, weights, and debugging.

## Holster an unequipped item

Without a Holster Target, the third-person Object deactivates when the item is unequipped. With a resolved target, an owned item that remains part of a valid Item Set is reparented to that target, reset to local position and rotation zero, and kept active. The perspective reports it as unequipped because its parent is now the holster.

![Third-person character with an unequipped assault rifle attached to a back holster](https://opsive.com/wp-content/uploads/2018/05/AssaultRifleHolster.png?v=da0f2f20c9f9)

Create a dedicated empty target at the back, hip, or other storage point. Do not use the hand, spine, or another functional rig bone itself: Third Person Perspective Item enables and disables the target GameObject during pickup, death, and respawn.

![Empty holster-target Transform positioned as a child of the character rig](https://opsive.com/wp-content/uploads/2018/05/ThirdPersonHolsterTarget.png?v=d1f38428f01c)

Add Object Identifier to that empty target and use its positive ID in **Holster Target**. The released Version 3 runtime does not honor the old direct-reference-only setup when the ID remains `-1`. For a [Model Switch](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/) character, create an equivalent target with the same ID on every model.

Holstering is presentation, not inventory storage. If the item is removed from the Inventory or no longer belongs to a valid Item Set, the object is deactivated instead. Pickup and drop prefabs are separate from the held model; configure them through [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) and [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/).

## Configure layers, renderers, and colliders

The Item Manager places the world model recursively on **SubCharacter**. Keep it off the character's own layer; the Perspective Item warns when the Object root uses the same layer as the character because that commonly causes collision problems. A manually created model should apply its intended non-colliding item layer to every child, not only the root.

**Third Person Object** belongs on the Object root. Perspective Monitor caches its child renderers and swaps them to the character's invisible material in the local first-person view, allowing the model to keep casting shadows. **Force Visible** and **First Person Visible On Death** are disabled by default. A runtime-added object's renderers are registered when Inventory adds the Character Item, so a missing or misplaced Third Person Object can leave the world model visible to the local first-person camera.

The third-person GameObject can remain active while its materials are hidden in first person. Keep presentation colliders non-interacting on the SubCharacter layer, and let the Shootable, Melee, Shield, or other action module explicitly control gameplay collision. Use separate pickup and drop objects when world physics are required.

Remote network characters are always treated as third person. Even a first-person-only local game needs this perspective when AI or other clients must see equipped items. The [First Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) handles the local Overlay model and procedural motion; do not move the third-person Object to Overlay to fix local visibility.

## How it runs

1. Inventory initializes the Character Item's perspective components before its actions. A runtime prefab finds the active model's non-first-person Item Slot by **Slot ID**, resolves an optional Spawn Parent ID below it, reparents the Object, and applies the Local Spawn transform.
2. The perspective caches the Object's equipped parent and local pose, the parent hand, active model's Character IK, and optional holster target. Item actions initialize their own first- and third-person references.
3. Pickup makes the empty holster-target GameObject available and marks the perspective as owned. It does not equip the model by itself.
4. Equip moves a holstered object back to its cached hand parent and pose, makes the Object active, and supplies the non-dominant targets to Character IK on the next update.
5. While equipped, Character Item Actions use their third-person perspective values. A Child Animator Monitor forwards character and item parameters to an Animator on the visible object.
6. In a local first-person view, Perspective Monitor replaces Third Person Object materials while the Character Item selects its first-person counterpart as the active perspective. Returning to third person restores the world model's materials.
7. Unequip clears the item IK targets. If a valid holster and owned Item Set remain, the Object moves to the holster; otherwise it deactivates.
8. Death temporarily disables an owned holster target, respawn enables it again, and removal deactivates the Object. A character model switch resolves the new model's slot and positive-ID targets, reparents the Object, and refreshes Animator monitors and IK.

## Editor checkpoint

Before entering Play Mode, confirm:

- the Character Item is below Item Placement or saved as the intended runtime prefab;
- **Object** is the world-visible model and does not itself contain another Character Item;
- the Character Item **Slot ID** matches the third-person Item Slot and, when present, the first-person Item Slot;
- the visible root and all children use the intended SubCharacter/non-colliding layer;
- **Third Person Object** is on the Object root and Perspective Monitor has a valid invisible material;
- any runtime Spawn Parent, Holster Target, or model-resolved action property uses a positive, unique Object Identifier ID present on every model;
- the optional item Animator has the intended controller and Child Animator Monitor;
- two-handed Humanoid items have a child grip target, optional elbow hint, Character IK, and IK Pass;
- firearm or Iron Sword actions have their own third-person transforms, hitboxes, and effects assigned; and
- pickup, held, holstered, and dropped objects are configured as separate roles when their physics differ.

## Verify in Play Mode

1. Add the item to Inventory without equipping it. Confirm no hand-held model appears unexpectedly; if it is part of a valid Item Set and has a holster, confirm the intended holstered result.
2. Equip the firearm or Iron Sword. Confirm the Object moves to the correct hand, uses the authored local pose, and drives the intended item Animator.
3. Aim, use, reload, block, or swing. Confirm every third-person muzzle, projectile, hitbox, trail, audio, and effect starts from the world model rather than a first-person reference.
4. For a two-handed firearm, aim across the character's full pitch range. Confirm the support hand reaches the grip and the elbow bends toward its hint. During reload, confirm the selected State releases and restores the appropriate IK weights.
5. Unequip and re-equip. Confirm the item moves to its identified holster only while the Inventory and Item Set still support it, then returns to the hand without changing scale.
6. Switch between first and third person. Confirm the local first-person camera does not render the third-person materials, while shadows and the first-person counterpart behave as intended.
7. Walk the character into walls and other colliders while equipped and holstered. Confirm the presentation model does not push the character or generate unintended impacts.
8. Switch every supported character model. Confirm each model has the matching Item Slot, Spawn Parent, Holster Target, and positive action-property IDs.
9. In multiplayer, compare owner, spectator, server, and remote clients. The remote player should show the third-person item and equivalent equip/use/holster results.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Item** is disabled | Perspective toggle, visible item validity, Item Parent, and first-/third-person slot IDs | Enable at least one perspective, select a model rather than a Character Item, choose a valid Item Slot parent, and make both perspective slots use the same ID. |
| **Update Item** does not change the third-person model, hand, controller, or slot | Released Version 3 Item Manager update path | Edit the existing Third Person Perspective Item and hierarchy directly, or preserve custom actions/States and deliberately rebuild a replacement. |
| A runtime item appears at the root or wrong hand | Character Item **Slot ID**, active model's Item Slot, and Spawn Parent ID | Add the matching non-first-person Item Slot. Leave Spawn Parent unset to use it directly, or add a positive-ID child below that slot. |
| Changing Local Spawn fields does not move a scene-built item | Current Object hierarchy | Those fields apply to an object reparented from a Character Item prefab. Move the scene object's Transform directly when it already lives below the character slot. |
| A directly assigned Spawn Parent or Holster Target is ignored | ID value and Object Identifier | Released Version 3 force-searches by ID. Add Object Identifier, use a positive unique ID, and enter the same ID in the perspective field; do not leave it at `-1`. |
| The item disappears instead of holstering | Holster ID, inventory amount, valid Item Set, and active model | Add the identified empty target to the active model and keep the Character Item owned and valid for an Item Set. Repeat the ID on every switchable model. |
| Holstering disables part of the character rig | Holster target object | Use a dedicated empty child. Do not assign a functional hand, spine, renderer, or other rig GameObject because the perspective toggles the target object. |
| The world model is visible in local first person | Third Person Object location, Perspective Monitor, and invisible material | Put Third Person Object on the visible root, update the character so its renderers are registered, and assign the monitor's invisible material. |
| The item pushes the character or hits world objects while merely equipped | Layers, Rigidbody, and colliders on the visible hierarchy | Restore the recursive SubCharacter/non-colliding setup, remove an unnecessary Rigidbody, and let action modules enable only deliberate hitboxes. |
| The support hand misses the firearm | Humanoid Avatar, Character IK, IK Pass, target, hint, and attachment hand | Repair the Humanoid setup, assign a child grip target and optional hint, and verify the item is parented below the intended hand's slot. |
| The hand remains locked during reload | Reload State and per-hand/per-elbow IK weights | Use a State preset to reduce the relevant weights during the release interval, then restore them after the animation. |
| A shot or melee effect comes from the wrong place | Action's **Third Person** perspective property and identifier | Assign the correct child transform. For model switching, use a positive ID present on every model instead of ID `0` or a cached direct reference. |
| Switching character models produces a null parent or stale reference | Item Slot and positive identifiers on the new model | Give every model an equivalent slot and unique matching Spawn Parent, Holster Target, and action-property IDs before allowing the switch. |
| A remote player has no visible held item | Third Person Perspective Item, replicated inventory/equip state, and model identifiers | Configure this perspective even for a local first-person design, then verify the multiplayer integration synchronizes ownership and active Item Sets. |

## Saving and multiplayer boundaries

The authored Object, local spawn transform, positive IDs, IK targets, holster, Animator, and States live on the Character Item scene object or prefab. Equipped state, current model, active camera perspective, holster parenting, and material swap are runtime presentation state. Save Inventory ownership and Item Sets, restore the active character model, and let UCC rebuild perspective placement rather than serializing the current hand or holster parent.

Non-local, non-spectator network characters use third person and discard first-person perspective references during Character Item initialization. Perspective Monitor also keeps remote characters in third-person materials. Inventory ownership, equipped Item Sets, and gameplay actions still need the installed multiplayer integration; custom action effects, arbitrary UnityEvents, or project-specific holster logic are not synchronized merely because the visible model exists.

## Related tasks

- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) covers Item Definition, slots, equip timing, actions, drop behavior, and perspective ownership.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds scene and runtime Character Items through Item Manager.
- [Common Item Setups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/) provides practical firearm and melee creation routes.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) defines the matching attachment IDs used by both perspectives.
- [First Person Perspective](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) configures the local arms/item counterpart and Overlay rendering.
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) configures what the equipped firearm, Iron Sword, shield, or other item does.
- [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) prepares Humanoid Character IK and per-limb weights.
- [State Presets](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/) changes IK weights or other fields during reload, aim, and additional modes.
- [Model Switch](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/) explains equivalent slots and identifiers across character models.
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) restores UCC's expected Character, SubCharacter, Overlay, and collision layers.

## Developer reference

`ThirdPersonPerspectiveItem` extends `PerspectiveItem`. `Object`, `LocalSpawnPosition`, `LocalSpawnRotation`, and `LocalSpawnScale` come from the base class. The third-person component exposes `NonDominantHandIKTarget`, `NonDominantHandIKTargetHint`, `HolsterTarget`, and `HolsterTargetIDObject`; `FirstPersonItem` is always `false`.

Retrieve it through `CharacterItem.ThirdPersonPerspectiveItem`. `CharacterItem.ActivePerspectiveItem` and `GetVisibleObject()` select the representation currently used by item actions. Leave `Initialize`, `Pickup`, `StartEquip`, `SetActive`, `Unequip`, `Remove`, and `OnCharacterSwitchModels` to the Inventory and item-ability lifecycle.

The perspective listens for `OnDeath`, `OnRespawn`, and `OnCharacterSwitchModels`. Character Item coordinates it through `OnInventoryAddItem` and `OnCharacterChangePerspectives`; Perspective Monitor listens to camera perspective and inventory events to register and swap third-person renderers.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions"></a>

# Item Actions

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)

A Character Item Action makes an equipped item do something: fire a projectile, swing an Iron Sword, cast a spell, throw an object, block damage, or run a project-specific interaction. Add actions to the main Character Item GameObject, then let an Item Ability select the intended action.

## Understand the action path

The visible first- and third-person objects present the item. The action supplies its gameplay behavior.

| Part | Responsibility |
| --- | --- |
| **Item Ability** | Starts an operation from player input, AI, or code. Use and Reload select an action by **Action ID**; Block responds to a Shield action in its configured slot. |
| **Character Item Action** | Owns the action identity and coordinates the action's modules. Every action on one Character Item must have a unique **ID**. |
| **Action Module Group** | Organizes one stage of an action, such as triggering, ammunition, collision, impact, effects, or reloading. |
| **Action Module** | Implements one option within its compatible group. Only enabled and active modules take part at runtime. |

An Item Ability's **Slot ID** first identifies the equipped Character Item. Its **Action ID** then identifies the component on that item. These values are independent of the Character Item's **Animator Item ID**.

## Choose an action family

Start with the action that matches the player's goal:

| Goal | Action | Next page |
| --- | --- | --- |
| Toggle a light, consume an attribute, or run another general interaction | **Usable** | [Usable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) |
| Fire a firearm or other ranged weapon | **Shootable** | [Shootable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) |
| Swing an Iron Sword or another close-range weapon | **Melee** | [Melee](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) |
| Spawn and release a grenade or another thrown object | **Throwable** | [Throwable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/) |
| Cast a spell through begin, cast, impact, and end stages | **Magic** | [Magic](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/) |
| Absorb damage with an equipped collider and optional durability | **Shield** | [Shield](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/shield/) |

Shootable, Melee, Throwable, and Magic inherit the common Usable flow. A plain Usable action is enough when the interaction does not need one of those specialized module sets.

## Add actions with the Item Manager

Use the Item Manager when creating or structurally updating an item. It creates the action components and, for most built-in types, a starter module configuration and required helper components.

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**.
2. Select the source item or an existing Character Item.
3. Under **Actions**, add an action type and give it a useful name, such as `Primary Fire`, `Sword Slash`, or `Flashlight`.
4. Add another row only when the same item needs a distinct operation. The first action normally receives ID `0`; subsequent generated actions receive the next available ID.
5. Select **Build Item** for a new item or **Update Item** for an existing item.
6. Select the generated main Character Item GameObject. Inspect every Character Item Action's **ID**, **Action Name**, and **Action Description**. Keep each ID unique.
7. On the character's Ultimate Character Locomotion component, add or configure the Item Ability that will drive the action. Match its slot and action selection to the item.

**Action Template** can reuse the action setup from another Character Item. After applying a template, inspect references and IDs on the generated item rather than assuming that every source-object reference can be reused.

![Item Manager showing Shootable and Melee actions on an Assault Rifle before Update Item](https://opsive.com/wp-content/uploads/2022/10/ItemExistingActions.png?v=9d93346ac6dc)

### Configure a firearm with a secondary melee strike

A multi-action firearm is a useful example because each operation is genuinely different:

1. Add **Shootable** as action ID `0` and **Melee** as action ID `1`.
2. Keep the normal Use Item Ability for slot `0`, action `0`, and its primary input.
3. Add a second Use Item Ability for slot `0`, action `1`, and a secondary input.
4. Give the two actions different Animator/audio state sets and modules as needed. Do not create a second action merely to select another animation in the same attack sequence; a module or state variation is usually a better fit.

![Two enabled Use Item Abilities selecting action 0 for primary use and action 1 for secondary use](https://opsive.com/wp-content/uploads/2022/10/UseItemAction1.webp?v=cdca13f3fb30)

For a single-action Iron Sword, one Melee action and one matching Use Item Ability are normally sufficient.

## Configure action modules

Select an action component to see its action-specific fields and module-group foldouts. Each foldout contains a **Modules** list. Use the add control to choose a compatible module type, then configure the selected module below the list.

The groups vary by action:

- Every Usable-based action has **Trigger** and **Usable** groups. The first enabled Trigger module is the main trigger and decides whether use is simple, repeated, charged, a combo, or another supported pattern.
- Shootable adds groups for the shooter, ammo, clip, projectile, fire and dry-fire effects, impacts, reloading, and extras.
- Melee adds attack, collision, attack-effect, impact, recoil, and extra groups.
- Throwable adds thrower, ammo, projectile, throw-effect, impact, re-equipper, and extra groups.
- Magic adds caster, begin, cast-effect, impact, end, and extra groups.

Use **Enabled** to remove a module from the runtime path without deleting its configuration. States and bindings can also make a module inactive while it remains enabled. Order matters when a group treats the first enabled module as its main option, so confirm the intended module is first.

See [Action Modules & Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/) for module selection, States, bindings, impact helpers, and custom modules.

## How it runs

1. The Character Item initializes every action on its main GameObject and builds an ID lookup. Each action initializes all of its module groups and modules, including modules that are currently disabled.
2. Pickup and equip notifications flow from the Character Item to each action. Enabled modules can prepare references during pickup, veto visibility or equip where supported, and register their runtime listeners when equipped.
3. An Item Ability looks up the active Character Item and selects its action. A Use Item Ability requires an action that implements the Usable flow; Reload requires a reloadable action. A Shield action instead raises an impact that the Block ability observes for the relevant slot.
4. A Usable action asks its enabled, active modules whether it can start. Its main Trigger module controls the start/use/complete sequence. The action can wait for the configured Animator event or duration at the use and completion points.
5. Specialized groups perform the operation. A Shootable action consumes ammo and fires its projectile or hitscan path, a Melee action checks its collision modules, and a Magic or Throwable action advances through its own stages. Impact modules apply the configured result to a hit target.
6. Animator/audio state sets select animation substates and clips at the relevant stage. The action asks the character to update item-ability Animator parameters when its state changes.
7. On stop, unequip, removal, or destruction, modules receive their lifecycle cleanup hooks. Built-in actions cancel their pending triggers and unregister their listeners at the appropriate stage.

Use Item Abilities and action modules to drive this lifecycle. Calling action lifecycle methods directly from normal gameplay code can bypass ability timing, interruption, Animator events, and network integration.

## Editor checkpoint

Before entering Play Mode, confirm all of the following:

- Every Character Item Action is on the main Character Item GameObject.
- Every action on that item has a different **ID**. **Action Name** and **Action Description** clearly distinguish multi-action setups.
- The Item Ability's slot and action selection point to an equipped item and an action of the required type.
- A Usable-based action has at least one active Trigger module. The intended main trigger is the first enabled Trigger module.
- Required references inside modules point to this item's first- or third-person objects, colliders, spawn locations, audio sources, attributes, ammunition, and effects.
- Animator/audio state sets and use/completion triggers match the Animator Controller's states and events.
- Modules controlled by States or bindings are active in the starting configuration.

## Verify in Play Mode

1. Equip the item and confirm that the expected visible object, Animator Item ID, and UI appear before testing the action.
2. Activate each input separately. For the firearm example, primary input should run Shootable action `0`; secondary input should run Melee action `1` without firing a shot.
3. Watch the action's **Debug** foldout while the Usable action is initialized. Confirm the use state, ability-active state, start checks, action count, substate index, and stop state advance as expected.
4. Verify the complete observable result: ammunition changes for a firearm, collision and damage occur for the Iron Sword, the intended animation/audio plays, and no disabled module contributes an effect.
5. Unequip during or after use. Pending action work should stop at the configured point, and the next equip should begin from a clean state.
6. If the game is networked, repeat the test as owner and remote observer. The owning character drives the action; every other client should see only the effects explicitly replicated by the installed integration or project code.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The item initializes with a duplicate-key exception | Character Item Action **ID** values | Assign a unique ID to every action on the same Character Item. Component order does not resolve duplicate IDs. |
| A newly added Magic action conflicts with another action at ID `0` | The IDs after an Item Manager build | Released Version 3's Item Manager does not assign the next ID in its Magic builder path. After every build or update, inspect the Magic action and assign a unique ID before entering Play Mode. |
| The correct item equips but nothing happens | Item Ability **Slot ID**, **Action ID**, and required action type | Point the ability to the active Character Item and an existing compatible action. With several actions, an action ID of `-1` is not a wildcard. |
| A single-action item works with action ID `-1`, but stops working after a second action is added | The Item Ability's action selection | `-1` can select the only action on a single-action item. Once multiple actions exist, assign the exact action ID. |
| A Usable action never starts | Trigger modules and runtime **Debug** checks | Add or enable a compatible Trigger module, make the intended module first, and inspect the first failed start check. |
| An action starts but never reaches use or completion | **Use Event**, **Use Complete Event**, and matching Animator events | Add the expected Animator event, or configure the trigger to wait for a duration. Check the selected animation substate. |
| A module is enabled but has no effect | Its State/binding activity, group order, and required references | Activate the controlling State or binding, place the main option first where required, and assign every location, collider, attribute, or effect reference. |
| A module cannot create its helper location objects on a prefab asset | Whether the module was added directly while editing a prefab asset | Released Version 3 does not automatically add those GameObjects to prefab assets. Add the required location objects manually and assign every module reference, or configure the item in the supported Item Manager workflow. |
| The local player sees the action, but remote clients do not | Authority and replication for custom module side effects | Use the installed multiplayer integration's inventory/action bridge and explicitly replicate project-specific spawned objects, UnityEvent effects, and custom module state. |

## Saving and multiplayer boundaries

Action and module configuration is serialized on the Character Item scene object or prefab. Runtime ownership, inventory amounts, and equipped item sets belong to the inventory and the chosen save integration. Custom counters, charge values, cooldowns, or other module runtime data need explicit save support when they must survive a load.

When multiplayer support is compiled, Character Item Actions receive the installed network information and network inventory bridge. This does not automatically replicate arbitrary custom module side effects. Decide which peer owns the action and synchronize any project-specific damage, spawned objects, audio, visual effects, or mutable module state that other clients must observe.

## Related tasks

- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) covers the item hierarchy, perspectives, equip lifecycle, and the boundary with Inventory.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds the complete Character Item through Item Manager.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) selects and coordinates Usable actions.
- [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) coordinates a reloadable action's modules and Animator timing.
- [Block](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/) responds to Shield impacts and controls block/parry animation values.
- [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/) selects item animation substates and audio clips.

## Developer reference

`CharacterItem.GetItemAction(actionID)` returns the action selected by an Item Ability. With one action, `-1` also returns that only action; with several actions, the method performs an exact ID lookup. `CharacterItemAction.GetFirstActiveModule<T>()` retrieves the first enabled, State-active module matching a type across the action's groups.

Useful runtime events include `OnItemUse` and `OnItemUseComplete` for Usable actions, `OnShieldImpact` for Shield impacts, and `OnCharacterUpdateItemAbilityParameters` when item-ability Animator parameters should refresh. Custom modules should use their module lifecycle and interfaces so they register listeners only while enabled and equipped, and clean up on unequip, removal, and destruction.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-usable"></a>

# Usable

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/)

A Usable Action turns the character's **Use** input into an item result. Use the base action for a switch, flashlight, scanner, or another custom interaction; use a specialized action when the item needs firearm, melee, throwable, or spell systems. Every Usable Action shares the same input selection, Trigger timing, animation events, and reusable module lifecycle.

## Choose the action that matches the result

| Goal | Action | What it adds |
| --- | --- | --- |
| Toggle a flashlight, play an effect, change a State, or spend an Attribute | **Usable Action** | The shared Trigger and Usable module groups without a weapon-specific pipeline. |
| Fire a firearm or other ranged weapon | [Shootable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) | Shooters, ammunition, clips, projectiles or hitscan, fire effects, impacts, and reloading. |
| Swing an Iron Sword or perform an unarmed attack | [Melee](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) | Attacks, hitbox collision, impacts, and recoil. |
| Throw a grenade or another inventory-backed object | [Throwable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/) | Throwing, projectile spawning, ammunition, impacts, trajectory preview, and re-equipping. |
| Cast a spell | [Magic](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/) | Casters and modular spell start, repeat, stop, and impact behavior. |

These four specialized actions inherit the shared Usable Action flow. Configure their action-specific groups on the linked pages, but use the Trigger and common fields on this page to decide when each cycle starts and completes.

## Build or update the item

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**.
2. Assign the Item Definition, perspectives, visible objects, Animator Item ID, and Character Item slot described in [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/).
3. In the action list, select the plus button and choose **Usable**, **Shootable**, **Melee**, **Throwable**, or **Magic**. Give the row a name that describes its result.
4. Select **Build Item** for a new Character Item or **Update Item** for an existing one.
5. Select the generated Character Item and inspect every Character Item Action. Each action on the same item needs a unique **ID**.
6. On the character, add or select the [Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/). Set its **Action ID** to the action's **ID**, and use **Slot ID -1** for all equipped slots or a specific Inventory slot.
7. Confirm that the action has at least one enabled Trigger module. A Usable Action without an enabled Trigger is invalid and cannot produce a result.

In released Version 3, choosing the base **Usable** type in the Item Manager creates the demo flashlight pattern: an item **Attribute Manager** with a `Battery` Attribute, a **Simple** Trigger, a **Use Attribute Modifier Toggle**, and Light children for the supplied perspective objects. It also changes **Use Event** and **Use Complete Event** to immediate timed triggers. Keep those generated parts for a flashlight, or replace them with the modules required by your interaction.

The following configured flashlight shows the two shared groups. Its values are an example, not the raw component defaults.

![Configured Usable Action for a flashlight with a Simple Trigger, Battery toggle, Light Effect, and audio effect modules](https://opsive.com/wp-content/uploads/2022/10/UsableActionInspector.png?v=99e637f5bf5b)

## Configure the shared action fields

Adding `UsableAction` directly as a component starts with empty Trigger and Usable groups. Its released Version 3 field defaults are:

| Inspector field | Default | Choose this based on |
| --- | ---: | --- |
| **ID** | `0` | The **Action ID** used by the character's Use ability. IDs must be unique on one Character Item. |
| **Use Rate** | `0.1` seconds | The minimum delay after completion before another cycle may start. A Repeat or combo Trigger still respects this delay. |
| **Face Target** | Enabled | Whether a non-independent-look Movement Type turns toward the Look Source while using the item. The Use ability's **Rotate Towards Look Source Target** must also allow rotation. |
| **Stop Use Ability On Complete Delay** | `1` second | `0` permits an immediate stop, a positive value holds the Use ability for that delay, and a negative value does not release it on completion. |
| **Use Event** | Wait for `OnAnimatorItemUse`; stored duration `0.2` seconds | The exact point when the main Trigger is allowed to perform the action. Disable event waiting to use the duration. |
| **Use Complete Event** | Timed; duration `0.05` seconds | The point when the cycle becomes complete. Enable event waiting to use `OnAnimatorItemUseComplete`. |
| **Force Root Motion Position** | Disabled | Whether the use animation must temporarily own positional root motion. |
| **Force Root Motion Rotation** | Disabled | Whether the use animation must temporarily own rotational root motion. |

Both event fields use an [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/). The Item Manager and action templates can replace component defaults, so inspect the generated values before editing Animator events.

## Choose one main Trigger

Only the first enabled module in **Trigger Action Module Group** is active. Reordering or disabling Trigger modules therefore changes the action's timing; adding several does not combine their behavior.

![Trigger Action Module Group with Simple selected and the seven built-in Trigger choices visible](https://opsive.com/wp-content/uploads/2022/10/TriggerModuleInspector_edited.png?v=da39ee8bb7c6)

| Trigger | Use it when |
| --- | --- |
| **Simple** | One press should produce one complete cycle. |
| **Repeat** | Holding input should start another cycle whenever the previous cycle and **Use Rate** allow it. |
| **Burst** | One press should perform a fixed group. **Burst Size** defaults to `5`, **Cancel Burst On Stop** is disabled, and **Burst Repeat Delay -1** prevents another burst. |
| **Charged** | Holding input should build a `TriggerData.Force` value and releasing should perform the action. Force defaults from `0.1` to `1` over a normalizer of `1` second; auto-fire and repeat-fire are disabled. |
| **Simple Combo** | Separate presses should move through Animator Audio States and may chain between use and completion. Add at least two states for an actual sequence. |
| **Repeat Combo** | Holding input should continue through the combo states. |
| **In Air** | A Simple-style action needs a separate airborne path. With **Require In Air Ability In Air** enabled by default, normal Use still works while grounded but airborne use must come from [In Air Melee Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/in-air-melee-use/). |

Simple, Repeat, Burst, Charged, and both combo triggers use an [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/) to supply audio and Item Substate Index data. The Trigger's **Substate Index Data** starts at index `0` with priority `100`; the selected Animator Audio State contributes its own state index.

## Add common Usable modules

The **Usable Action Module Group** can contain several enabled modules. Each module participates only in the lifecycle stages represented by its implemented interfaces, so one module can block the start while another supplies effects or animation data.

| Module | User-facing purpose |
| --- | --- |
| **Generic Item Effects** | Run an [Item Effect group](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/) on start, use, update, or completion. Only **On Use** is enabled by default. |
| **Use Attribute** | Spend an Attribute on the item GameObject per use and optionally drop the item when that Attribute reaches its destination. |
| **Character Use Attribute** | Spend an Attribute from the character per use. |
| **Aim Substate** | Add Item Substate Index data while Aim is active and optionally run effects when input-driven aiming starts or stops. Its default index is `100`, priority `150`, and additive mode is enabled. |
| **Use Attribute Modifier Toggle** | Toggle perspective GameObjects and an Attribute modifier each time the action is used. By default it prevents use when the configured Attribute is invalid and targets the `Battery` Attribute. |
| **Module State Switcher** | Select one named option and activate its State on both the character and Character Item. **Loop** is enabled and **Index** starts at `0`. |
| **Activate States** | Activate character States while equipped, between start and use, or between use and completion. All three phases are enabled by default. |
| **Enable Can Start Use** | Expose a **Can Start Use** boolean, enabled by default, that a State preset or project code can turn off. |
| **Debug Use** | Write a configured message when the action reaches Use. This is intended for diagnosis rather than final gameplay. |

Use Attribute reads the item's Attribute Manager; Character Use Attribute reads the character's Attribute Manager. Reversing those two is a common reason an action remains unavailable even though an Attribute with the same name exists elsewhere.

See [Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/) for enabling, ordering, State presets, and custom modules.

## How it runs

![Usable Action lifecycle from Start Use through Use and Use Complete to Stop Use](https://opsive.com/wp-content/uploads/2022/10/UsableAction.drawio.png?v=bf766b48a8af)

1. The Use ability finds the equipped Character Item by **Slot ID** and its component by **Action ID**. It also requires a Look Source and, by default, rejects a new input while the pointer is over UI.
2. The action checks **Use Rate**, pending Use or completion events, and every enabled module that can veto the ability or item start.
3. **Start Use** registers `OnAnimatorItemUse` and `OnAnimatorItemUseComplete`, applies the root-motion and facing choices, starts the main Trigger, and invokes start-stage modules.
4. **Use Event** releases the cycle at the selected animation event or duration. The first enabled Trigger performs its pattern, then all enabled modules that participate in Use receive the call.
5. **Use Update** runs while the ability is active. Repeat, Burst, Charged, combo, condition, and effect modules can use this stage to continue or delay the cycle.
6. **Use Complete Event** marks the cycle complete, calculates the next allowed time from **Use Rate**, invokes completion modules, and releases the ability according to **Stop Use Ability On Complete Delay**.
7. **Stop Use** cancels outstanding waits, stops participating modules, removes forced root motion, and unregisters the animation events.

Aim can remain active and feed aiming state to the action's modules. Use has priority over Reload for the same Character Item, and beginning Use can stop that item's reload. An **Equip Unequip** ability with **Prevent Start Use Reload Active** can keep Use from interrupting an equipment transition; otherwise a requested Use may stop the active equip change.

## Verify the result

### Editor checkpoint

Before Play Mode, confirm:

- the Character Item Action **ID** matches the Use ability's **Action ID**;
- every action on the Character Item has a unique ID;
- the intended Trigger is the first enabled module;
- **Use Event** and **Use Complete Event** match the animation clips or tested durations;
- the Trigger's Animator Audio States map to valid Item Substate Index transitions; and
- item and character Attributes exist on the GameObject read by their respective modules.

The Usable Character Item Action Inspector also exposes **Interfaces info** labels beside lifecycle interfaces. The label shows the matching module count. Hover it to list the matching modules. Right-click and choose an action such as **Log modules with interface 'IModuleUseItem'.** to print each matching module and its active/inactive and enabled/disabled state to the Console. This is a diagnostic command: it does not enable, reorder, or invoke a module. Use it together with the action's **Debug** foldout when one module is blocking or supplying a lifecycle stage.

### Play Mode checks

1. Equip the item, select its Usable Action, expand **Debug**, and press the configured Use input.
2. Confirm the expected action becomes active and the Debug section advances through start, use, completion, and stop.
3. Confirm the result occurs at **Use Event**, not merely when input begins, and that it does not repeat sooner than **Use Rate**.
4. Hold and release input. Compare the result with the chosen Simple, Repeat, Burst, Charged, or combo behavior.
5. Watch the Animator's Item State and Item Substate Index. Aim once and confirm an **Aim Substate** changes only the intended animation.
6. For a firearm, verify a shot and reload handoff; for an Iron Sword, verify the hitbox window; for a throwable, verify release and re-equip; for magic, verify the caster's start-to-stop sequence.
7. For a plain Usable Action, confirm each State, Attribute, GameObject toggle, audio clip, or other Item Effect changes once at the configured lifecycle stage.
8. Unequip and re-equip the item, then repeat the test to confirm toggles, States, pending events, and module conditions reset as intended.

## Troubleshoot a Usable Action

| Symptom | Check | Fix |
| --- | --- | --- |
| Use becomes active but nothing happens | **Trigger Action Module Group** | Enable at least one Trigger and move the intended Trigger to the first enabled position. |
| The wrong action runs | Character Item Action **ID**, Use **Action ID**, and Use **Slot ID** | Give every action a unique ID and match the correct Use row to that ID and slot. Module IDs do not select the action. |
| The action waits forever before its result | **Use Event** and `OnAnimatorItemUse` | Add the event to the correct animation and slot, or disable event waiting and use a tested duration. |
| The animation finishes but Use remains active | **Use Complete Event**, `OnAnimatorItemUseComplete`, stop delay, and modules that prevent stopping | Supply the event or duration, then use `0` for an immediate post-completion release or a tested positive delay. |
| Repeat, Burst, or combo timing is wrong | First enabled Trigger, **Use Rate**, Animator Audio States, and event timing | Test one Trigger at a time. Confirm each state reaches Use and completion before tuning the next cycle. |
| An Attribute module blocks use | Attribute owner and name | Put **Use Attribute** targets on the item and **Character Use Attribute** targets on the character; make the exact Attribute name and available value valid. |
| The character does not face the target | Use ability rotation, action **Face Target**, and Movement Type | Enable both rotation choices. An independent-look Movement Type keeps control of facing. |
| Aim plays the wrong use animation | **Aim Substate** index/priority and ability order | Verify the substate data and keep Use above Aim when Use's Item State should have priority. |
| Reload or Equip Unequip behaves unexpectedly | The interacting ability's target item and priority | Use stops Reload for the same item. Check **Prevent Start Use Reload Active** on Equip Unequip when equipment transitions must finish first. |
| A Magic action conflicts with another action ID | IDs after an Item Manager build | Released Version 3's Magic builder path leaves a new Magic Action at the default ID `0`. Assign a unique ID before Play Mode. |
| Replacing **Activate States > State Names** from code disables the wrong State or throws | Runtime array replacement | Released Version 3's runtime setter uses incorrect values while replacing an active array. Author the fixed list in the Inspector before Play Mode; if runtime replacement is unavoidable, first deactivate the module and its States, then manage the transition in project code. |

## Saving and multiplayer

Action fields and module configuration are serialized with the Character Item or prefab. The current use cycle, cooldown time, pending animation waits, charge progress, and active Trigger data are runtime state and are reinitialized; persist an Attribute or another gameplay value explicitly when it must survive a save and load.

The multiplayer integration supplies network ownership to Character Item Actions, and some built-in modules send explicit network calls, including the Generic Item Effects start stage and Use Attribute Modifier Toggle GameObject changes. Do not assume a custom module or every lifecycle stage is replicated automatically. Keep authoritative results in the networking integration and test start, repeated use, completion, perspective toggles, and interruption on owner and remote clients.

## Related tasks

- [Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) configures input, Slot ID, Action ID, and ability interactions.
- [Character Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) explains action ownership and unique IDs.
- [Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/) explains module ordering, States, and extension points.
- [Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/) lists reusable effects for a plain Usable Action.
- [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/) configures Trigger animation, audio, and substate selection.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains Item State Index and Item Substate Index.
- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/) explains the item and character values consumed by Attribute modules.

## Developer reference

`UsableAction` implements `IUsableItem` and exposes the shared values through `UseRate`, `FaceTarget`, `UseEvent`, `UseCompleteEvent`, `ForceRootMotionPosition`, `ForceRootMotionRotation`, `TriggerActionModuleGroup`, and `UsableActionModuleGroup`. `MainTriggerModule` returns the first enabled Trigger, and `TriggerData` carries `Force`, `Index`, and the use count into specialized action modules.

Custom common modules inherit `UsableActionModule` and implement only the lifecycle interfaces they need. Common choices include `IModuleCanStartUseItem`, `IModuleStartItemUse`, `IModuleUseItem`, `IModuleUseItemUpdate`, `IModuleItemUseComplete`, `IModuleTryStopItemUse`, `IModuleCanStopItemUse`, `IModuleStopItemUse`, `IModuleGetUseItemSubstateIndex`, and `IModuleOnAim`. Use the Inspector's Play Mode **Debug** foldout to see which module vetoed a stage before adding logs.

The [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) publishes `OnItemStartUse(IUsableItem, bool)`, `OnItemUse(IUsableItem)`, `OnUseAbilityUsedItem(IUsableItem)`, and `OnItemUseComplete(IUsableItem)` during the shared lifecycle. `OnAnimatorItemUse` and `OnAnimatorItemUseComplete` are the matching animation event names.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-usable-shootable"></a>

# Shootable

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/)

A Shootable Action turns a Character Item into a firearm, bow, launcher, or another ranged weapon. Configure it as a pipeline: input chooses when to fire, the Shooter chooses hitscan or a moving projectile, Ammo and Clip track rounds, effects provide feedback, Impact modules decide what a hit does, and the Reloader refills the clip.

## Create a working firearm

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager** and follow [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) to assign the Item Definition, perspectives, visible objects, slot, and Animator Item ID.
2. In the action list, add **Shootable**, give the row a descriptive name, and select **Build Item** or **Update Item**.
3. Select the generated Character Item. Confirm that the Shootable Action **ID** is unique on this item, then match it with **Action ID** on the character's [Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/). Use **Slot ID -1** for every equipped slot or select the weapon's exact slot.
4. In **Ammo Action Module Group**, select **Item Ammo** and assign an **Ammo Item Definition**. Add that definition to the character's inventory or Default Loadout. Use **Infinite Ammo** only when the weapon should not consume an inventory item.
5. Position the generated **Fire Point Location**, **Muzzle Location**, and **Shell Location** for every enabled perspective. If a Hitscan Shooter uses a Tracer, also assign **Tracer Location**; that transform is not created automatically.
6. Choose the firing recipe below, then configure the inherited **Use Event** and **Use Complete Event** to match the weapon animation. Configure reload timing on **Generic Reloader**.
7. In **Impact Action Module Group**, keep or add **Generic Shootable Impact** and configure its conditions and Impact Actions. A ray or projectile collision does not create gameplay damage by itself.

The Item Manager's released Version 3 Shootable recipe starts with **Repeat**, **Hitscan Shooter**, **Item Ammo**, a **Simple Clip** of `50`, **Basic Projectile**, common firing effects, **Generic Shootable Impact**, **Generic Reloader**, **Dry Fire Substate**, and **Slot Item Monitor Module**. These are useful starting values, not a finished weapon: the ammo definition, visuals, animations, audio, and target result still need to be assigned.

![Shootable Action Inspector with its Trigger, Shooter, Ammo, Clip, Projectile, effect, Impact, Reloader, and Extra module groups](https://opsive.com/wp-content/uploads/2022/10/ShootableActionInspector-449x1024.png)

## Choose a firing recipe

| Result | Main modules | Important choices |
| --- | --- | --- |
| Instant firearm | **Simple**, **Repeat**, or **Burst** Trigger; **Hitscan Shooter**; **Basic Projectile** | Use **Fire In Look Source Direction** for crosshair aiming. Set **Fire Count** above `1` for a pellet weapon, and tune **Spread**, **Impact Layers**, and range. |
| Moving bullet, rocket, or energy bolt | **Projectile Shooter**; **Spawn Projectile** | Assign a prefab with the UCC **Projectile** component, a perspective-aware **Fire Point Location**, velocity, fired layer, and collision settings on the projectile. |
| Bow or another visible loaded projectile | **Charged** Trigger; **Projectile Shooter**; **Spawn Projectile**; **Simple Clip** | A one-round clip and **Always** or **On Aim** projectile visibility can show the arrow before release. Use the visible-projectile and reload event fields to synchronize drawing and attaching it. |
| Shotgun or scatter weapon | A Hitscan or Projectile Shooter with **Fire Count** above `1` | One trigger cycle consumes one round from the clip, then produces the configured number of rays or projectiles. **Fire Count** is not a burst; use the **Burst** Trigger for several timed use cycles. |
| Weapon with no reserve-ammo limit | **Infinite Ammo**; **Simple Clip**; **Generic Reloader** | Infinite Ammo still feeds a clip. Keep an enabled Clip, Projectile, and Reloader module because Shootable Action validation requires each core group. |

Only the first enabled **Trigger**, **Shooter**, **Ammo**, **Clip**, **Projectile**, and **Reloader** module is active. Reorder or disable alternatives instead of expecting them to combine. Fire Effects, Dry Fire Effects, Impact, Usable, and Extra groups can run several enabled modules.

## Configure the firing pipeline

### Shooter and projectile

| Module or field | Released Version 3 default | What it controls |
| --- | --- | --- |
| **Hitscan Shooter > Fire In Look Source Direction** | Enabled | Uses the Look Source and crosshair direction. With a non-independent-look Movement Type, the ray begins from the Look Source position. |
| **Hitscan Fire Delay** | `0` seconds | Delays the raycast, but fire effects run when the weapon fires. Use animation timing deliberately if this is positive. |
| **Hitscan Fire Range** | Maximum float value | Maximum ray distance, multiplied by the Trigger's force. |
| **Max Hitscan Collision Count** | `15` | Size of the non-allocating raycast buffer. The editor warns when it fills. |
| **Hitscan Trigger Interaction** | **Ignore** | Whether trigger colliders may be detected. |
| **Hitscan Tracer** | None | Optional pooled tracer. **Tracer Default Length** is `100`, and **Tracer Spawn Delay** is `0`. Assign **Tracer Location** when using it. |
| **Hitscan Spread / Fire Count** | `0.01` / `1` | Random direction variation and rays produced by one consumed clip round. |
| **Projectile Shooter > Fire In Look Source Direction** | Disabled | Uses the Fire Point's forward direction until enabled. |
| **Use Look Source Position** | Disabled | Starts the projectile at the Look Source when the Movement Type does not use independent look. Otherwise it starts at **Fire Point Location**. |
| **Projectile Fire Velocity Magnitude** | `10` | Base launch speed, multiplied by Trigger force. **Inherit Character Velocity** is disabled. |
| **Projectile Fired Layer / Layer Change Delay** | **VisualEffect** / `0` | Layer applied after firing and the delay before it changes. |
| **Projectile Spread / Fire Count** | `0.01` / `1` | Random direction variation and projectiles produced by one consumed clip round. |
| **Spawn Projectile > Projectile Visibility** | **On Fire** | Choose **On Aim**, **On Reload**, or **Always** when a bow arrow, shell, or other loaded projectile should be visible before firing. |
| **Spawn Projectile > Projectile Start Layer** | **IgnoreRaycast** | Layer used while a visible projectile is attached to the item. |

For hitscan, **Impact Layers** determine what the ray can hit. For Projectile Shooter, the field helps choose the aim direction and prevent a pre-spawned projectile from crossing an obstruction; the projectile prefab's own collider, layers, and [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/) settings control the moving object's actual collisions.

### Ammo, clip, and reload

**Item Ammo** removes inventory ammo when it is loaded into the clip, not when the shot leaves the clip. Its **Drop Option** defaults to **Ammo Left**, and **Shared Ammo Item Identifier** is disabled. Enable sharing only when two active weapons that use the same Ammo Item Definition should redistribute a limited reserve.

**Simple Clip** defaults to **Clip Size 50**. Index `0` is the next round to fire. On the first equip, a valid Generic Reloader with any Auto Reload option enabled immediately fills the clip when ammo is available.

**Generic Reloader** defaults are:

- **Auto Reload**: **Pickup** and **Empty**;
- **Reload Type**: **Full** rather than one round per cycle;
- **Reload Can Camera Zoom** and **Reload Crosshairs Spread**: enabled;
- **Reload Event**: wait for the slot event `OnAnimatorItemReload`;
- **Reload Complete Event**: wait for the slot event `OnAnimatorItemReloadComplete`; and
- reload Item Substate Index: index `0`, priority `100`.

Change **Reload Type** to **Single** for a shotgun-style one-round loop. The reloader repeats its reload state while the clip has room and reserve ammo remains, then waits for the completion event. When using **Reload Detach Attach Clip**, move a separate MeshRenderer clip transform. Do not reparent a SkinnedMeshRenderer or a weapon-rig bone.

See [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/), [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/), and [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/) for the ability, timing, and reload substate setup.

### Feedback, impacts, and aiming

The generated Fire Effects group contains **Muzzle Effect**, **Shell Effect**, **Recoil Effect**, and **Crosshairs Spread**. Muzzle pooling is enabled by default; the muzzle and shell prefabs still need to be assigned. Add **Smoke Effect** or **Generic Item Effects** when the weapon needs additional feedback. The Dry Fire Effects group is separate, so an empty clip can use different audio or visuals.

**Generic Shootable Impact** evaluates its [Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/), then runs either its pass or fail [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/). Use this group for damage, force, surface effects, events, or other target results.

Useful Extra modules include:

- **Dry Fire Substate**, which defaults to index `11`, priority `200`, and prevents a held Repeat or Burst Trigger from cycling continually while dry;
- **Look Sensitivity**, which defaults to `0.97` in both perspectives and delays firing until the visible weapon points closely enough toward the Look Source. A value of `-1` effectively removes this restriction;
- **Prevent Dry Fire**, which prevents a use cycle only when both the clip and reserve are empty;
- **Scope**, whose **Disable Scope Camera On No Aim** option is disabled by default; enable it and assign perspective-specific scope camera objects when the scope should appear only during input-driven Aim; and
- **Slot Item Monitor Module**, which shows both loaded and unloaded counts by default.

The [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) ability supplies aiming state. [Third Person Item Pullback](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/third-person-item-pullback/) can move a third-person firearm away from walls before Use, Aim, or Reload continues.

## How it runs

![Shootable Action use and reload flow through Trigger, Shooter, Clip, Projectile, effects, Impact, and Reloader modules](https://opsive.com/wp-content/uploads/2022/10/Shootable.drawio.png?v=db04fc1c8c48)

1. The Use ability selects the equipped Character Item by **Slot ID** and its Shootable Action by **Action ID**. The inherited Trigger and Use Event determine when one fire cycle begins.
2. The first enabled Shooter reads round `0` from the first enabled Clip. If it is invalid, the action invokes Dry Fire Effects instead of firing.
3. A valid cycle removes one round from the clip. Hitscan schedules its ray or Projectile Shooter obtains objects from the Projectile module. **Fire Count** can produce several rays or projectiles from that one round.
4. Hitscan range, projectile velocity, and impact strength use the Trigger's force. This is what lets a Charged Trigger produce a stronger or faster result.
5. The action invokes every enabled Fire Effect once per fire cycle. A moving projectile then owns its flight; hitscan resolves its ray immediately or after **Hitscan Fire Delay**.
6. On collision, the Shootable Action invokes each enabled Impact module. Generic Shootable Impact evaluates conditions and applies the configured pass or fail actions.
7. Clip and reserve changes refresh their events and the Slot Item Monitor. If the clip becomes empty and Generic Reloader includes **Empty**, completion of Use asks the Reload ability to start.
8. Generic Reloader waits for the reload event, transfers inventory ammo into the clip, repeats for **Single** reloads when needed, then waits for the reload-complete event and releases the Reload ability.

## Verify the weapon

### Editor checkpoint

Before Play Mode, confirm:

- the Shootable Action **ID** matches Use **Action ID**, and every Character Item Action ID is unique;
- Shooter, Ammo, Clip, Projectile, and Reloader each have an enabled first module;
- Item Ammo has an Ammo Item Definition that exists in the inventory or Default Loadout;
- every perspective property points to the intended visible object's fire, muzzle, shell, tracer, scope, projectile, and reload transforms;
- Projectile Shooter uses **Spawn Projectile** and a prefab with a UCC Projectile component, while Hitscan uses **Basic Projectile**;
- Use, Use Complete, Reload, and Reload Complete events exist in the correct Animator clips or use tested durations; and
- Impact Layers and Generic Shootable Impact allow the intended target and result.

### Play Mode checks

1. Equip the weapon, expand the Shootable Action's **Debug** section, and note loaded and unloaded ammo.
2. Fire one cycle. Confirm the clip falls by one even when **Fire Count** produces several pellets, and confirm muzzle, shell, recoil, audio, and animation occur at the intended frame.
3. Fire at a valid target and an excluded target. Confirm the correct Impact Condition branch runs and that the target receives damage, force, surface feedback, or the configured alternative.
4. Aim and fire near an obstruction in first and third person. Confirm the shot direction, origin, crosshair alignment, visible projectile, muzzle, tracer, and scope all switch to the correct perspective.
5. Empty the clip. Confirm dry-fire feedback occurs once for held Repeat or Burst input, then confirm Empty auto-reload starts only while reserve ammo remains.
6. Test Full and Single reload timing. Watch Item State and Item Substate Index, clip attachment, ammo transfer, camera zoom, and crosshair spread through completion.
7. Unequip, re-equip, switch perspective, and repeat. Confirm pooled effects and visible projectiles are removed or reattached correctly.

## Troubleshoot a Shootable Action

| Symptom | Check | Fix |
| --- | --- | --- |
| Use starts but the weapon does not fire | Required first modules, clip count, reserve count, and **Look Sensitivity** | Enable a Shooter, Ammo, Clip, Projectile, and Reloader. Add the Ammo Item Definition to inventory, reload, and temporarily use `-1` Look Sensitivity while confirming alignment. |
| The wrong weapon action runs | Shootable Action **ID**, Use **Action ID**, and Use **Slot ID** | Give every action a unique ID and match the Use row to the intended action and slot. |
| Hitscan fires in the wrong direction | **Fire In Look Source Direction**, Movement Type, Fire Point, and Look Source | Enable look-source firing for crosshair aim, or rotate and position each perspective's Fire Point when muzzle-forward firing is intended. |
| A tracer throws an error or starts at the wrong place | **Tracer** and **Tracer Location** | Assign a perspective-specific Tracer Location whenever a tracer prefab is assigned. |
| The ray hits but nothing happens | **Impact Layers**, trigger interaction, Generic Shootable Impact, and target colliders | Include the target layer, choose trigger handling deliberately, and add pass/fail Impact Actions that produce an observable result. |
| A projectile is null, does not move, or never collides | Shooter/Projectile pairing and projectile prefab | Pair Projectile Shooter with Spawn Projectile, assign its prefab, and build that object with the UCC Projectile component, collider, layers, and impact settings. |
| A loaded bow arrow is missing or attached incorrectly | **Projectile Visibility**, Fire Point, reload attachment, and visible-projectile events | Use On Aim or Always as appropriate, assign both perspective transforms, and synchronize show/attach events with the bow animation. |
| The clip stays empty | Ammo Item Definition, inventory quantity, Clip Size, Auto Reload, and active item | Add reserve ammo, keep Clip Size positive, and enable a suitable Auto Reload flag or start Reload manually. Shared ammo does not let an unequipped item take the reserve. |
| Reload never transfers ammo or never ends | `OnAnimatorItemReload`, `OnAnimatorItemReloadComplete`, slot, and event-wait settings | Put both events in the matching slot animation, or disable event waiting and use tested durations. |
| A reload clip deforms or disrupts the rig | **Reloadable Clip** transform | Use a separate MeshRenderer object. Do not assign a SkinnedMeshRenderer or bone that belongs to the weapon rig. |
| One press creates too many shots | Trigger type and Shooter **Fire Count** | Use Fire Count for simultaneous pellets. Return it to `1` and use Burst when the shots should be separate timed cycles. |
| A projectile fails **Check Weapon Source Category** or **Check Weapon Source Definition** unexpectedly | Projectile Shooter impact context | In released Version 3, Projectile Shooter clears the Shootable Action reference before these two conditions evaluate, so the projectile is treated as a non-weapon source. Avoid those source-weapon filters for projectile shots unless **Allow Non Weapon Impact** matches the intended result; use projectile/target conditions or a project-fixed shooter module instead. |
| **Projectile Enable Delay After Other Use** has no effect | Projectile Shooter field | Released Version 3 serializes this default `0.4` field but never reads it at runtime. Coordinate dual-item timing with Use Rate, animation events, or project code instead. |

## Saving and multiplayer

The Character Item or prefab serializes the Shootable Action, module order, module fields, and perspective references. Item Ammo is an inventory amount and Simple Clip exposes its remaining count through the item-definition consumer interface, but an in-progress use, delayed hitscan, visible pre-spawned projectile, recoil, and reload event wait are runtime state. Save durable ammo and clip counts through the inventory/save integration and restart transient action timing after load.

The multiplayer integration explicitly routes built-in fire effects, dry-fire effects, and impact modules; Projectile Shooter also uses network ownership and server handling for spawned projectiles. A custom module, custom Item Effect, or arbitrary event is not replicated merely because it belongs to a Shootable Action. Test firing, impact authority, ammo, reload, visible projectiles, and first/third-person effects on the owner, server, and remote clients.

## Related tasks

- [Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) explains Trigger choices, Use timing, Action IDs, and the common module lifecycle.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/), [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/), and [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) configure the interacting item abilities.
- [Common Item Setups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/) provides practical creation routes for ranged items.
- [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/) configures a moving projectile object's collision and runtime behavior.
- [Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/) explains module order, States, and custom modules.
- [Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/), [Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/), and [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) configure feedback and hit results.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains Item State and Item Substate Index values.

## Developer reference

`ShootableAction` extends `UsableAction` and exposes `ShooterModuleGroup`, `AmmoModuleGroup`, `ClipModuleGroup`, `ProjectileModuleGroup`, `FireEffectsModuleGroup`, `DryFireEffectsModuleGroup`, `ImpactModuleGroup`, `ReloaderModuleGroup`, and `ExtraModuleGroup`. `MainShooterModule`, `MainAmmoModule`, `MainClipModule`, `MainProjectileModule`, and `MainReloaderModule` return each group's first enabled module. Runtime counters are available through `ClipSize`, `ClipRemainingCount`, and `AmmoRemainingCount`; `ReloadClip(bool instantly, bool fullClip)` provides the direct reload entry point.

The [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) publishes `OnShootableItemAmmoChange(CharacterItem, ShootableAmmoModule)`, `OnShootableItemClipChange(CharacterItem, ShootableClipModule)`, `OnStartReload(ShootableReloaderModule)`, `OnItemReload(IReloadableItem)`, `OnItemReloadComplete(IReloadableItem)`, and `OnShootableWeaponShowProjectile(GameObject, bool)`. The core animation event names are `OnAnimatorItemReload`, `OnAnimatorItemReloadComplete`, `OnAnimatorStartVisibleProjectile`, `OnAnimatorItemReloadShowProjectile`, and `OnAnimatorItemReloadAttachProjectile`; clip visuals also support detach, drop, attach, and reactivate events.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-usable-melee"></a>

# Melee

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/)

The Melee Action turns an equipped item, an unarmed Body action, or another close-range attack into timed collision checks, impacts, damage, recoil, and animation. Use it when an Iron Sword swing should be active only during a specific part of its animation and should react differently to characters, shields, and solid scenery.

## Before you begin

- Create the Character Item through **Tools > Opsive > Ultimate Character Controller > Item Manager**. The [Sword setup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/#sword) shows the usual visible-item arrangement; use the [invisible Body setup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/#invisible-body-or-unarmed-action) for fists or kicks.
- Confirm that the character has a [Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/). Its **Action ID** must match the Melee Action's **ID**, and its **Slot ID** must include the equipped item.
- Add the attack states and Item Substate Index values to the Animator before relying on animation events. See [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/).
- Decide whether movement comes from locomotion or the clip. **Force Root Motion Position** and **Force Root Motion Rotation** are both off by default and should be enabled only for an animation authored to own that motion.

## Build an Iron Sword attack

1. In the Item Manager, create or select the Iron Sword Character Item and add a **Melee** action. Select **Build Item** for a new item or **Update Item** for an existing one.
2. Select the generated Character Item. Confirm that the Melee Action has a unique **ID** and that the character's Use ability targets that ID and slot.
3. Inspect the generated starter modules: **Repeat Combo** Trigger, **Simple Attack**, **Hitbox Collision**, **Generic Melee Impact Module**, and **Simple Recoil**. The builder also sets **Face Target** off. Remove or replace a starter only when the attack needs different behavior.
4. In **Hitbox Collision**, configure the first- and third-person **Hitboxes** separately. Resize each generated Box Collider around the blade or striking limb; Box, Sphere, and Capsule Colliders are supported.
5. On each hitbox, keep **Damage Multiplier** at `1` initially, assign an optional **Surface Impact**, and decide whether minimum offsets, movement, or one-hit-per-use filtering should limit it.
6. In the Repeat Combo Trigger's **Animator Audio State Set**, add one state per combo step. Map each state to an Item Substate Index implemented by the Iron Sword Animator.
7. In **Simple Attack**, align **Active Attack Start Event Trigger**, **Active Attack Complete Event Trigger**, and **Allow Chain Attack Event Trigger** with the swing. Use animation events for authored contact windows or tested durations for a simple prototype.
8. In **Generic Melee Impact Module**, tune the successful [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) for damage, force, surface response, and target reactions. Its default filters accept every substate and Attack ID.
9. Keep **Simple Recoil** when the swing should stop and play recoil after hitting a valid shield or a `RecoilObject`. Add a **Trail Effect** or **Generic Item Effects** only after the attack window and collision are correct.
10. Save the Character Item prefab, then verify the same active window, hitbox placement, and impact result in both supported perspectives.

The registered legacy Inspector image identifies the Melee Action's Trigger, Usable, Attack, Collision, Attack Effects, Impact, Recoil, and Extra module groups.

![Melee Action Inspector with Trigger, Usable, Attack, Collision, Attack Effects, Impact, Recoil, and Extra module groups](https://opsive.com/wp-content/uploads/2022/10/MeleeActionInspector.png?v=bdb9fe59d6aa)

## Understand the module groups

| Group | Active-module rule | Responsibility |
| --- | --- | --- |
| **Trigger** | First enabled module | Chooses one use, held repeat, or a combo sequence and supplies the use substate. |
| **Usable** | Every enabled compatible module | Applies shared Attributes, States, effects, and other [Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) behavior. |
| **Attack** | First enabled module | Opens and closes one or more active attack windows. |
| **Collision** | First enabled module | Checks the current perspective's hitboxes or a character-centered sphere while the attack is active. |
| **Attack Effects** | Every enabled module | Runs item-side feedback at active-attack start or completion. |
| **Impact** | Every enabled module | Applies conditions and results after Collision reports a valid target. |
| **Recoil** | First enabled module | Decides whether a hit is solid enough to cancel the attack and select recoil animation/audio. |
| **Extra** | Every enabled module | Adds melee-specific behavior outside the main pipeline. Released Version 3 includes **Trail Effect**. |

Module IDs identify rows for States and networking. The Melee Action **ID** is the value selected by the Use ability; keep action IDs unique on one Character Item.

## How it runs

![Melee Action lifecycle from Start Use and the active attack window through collision, impact or recoil, completion, and Stop Use](https://opsive.com/wp-content/uploads/2022/10/Melee.drawio.png?v=413fd7bb8d0e)

1. The Use ability resolves the equipped item by **Slot ID** and the Melee Action by **Action ID**, then starts the first enabled Trigger and all applicable shared Usable modules.
2. **Use Event** releases the Trigger. The first enabled Attack module waits for **Active Attack Start Event Trigger**.
3. At active start, the Attack supplies `MeleeAttackData`, activates its optional State on the character and Character Item, and notifies every enabled melee module.
4. During the active window, the Collision module checks once per item update. A valid hit builds the melee impact context and sends it through every enabled Impact module.
5. A solid shield or `RecoilObject` can make Simple Recoil cancel the active attack, select its recoil substate/audio, and publish `OnMeleeRecoil`.
6. **Active Attack Complete Event Trigger** closes the collision window, removes the attack State, and runs completion-stage modules. **Use Complete Event** completes the shared use cycle.
7. Stop Use cancels pending attack events, clears recoil, stops participating effects, and releases the Use ability.

The active attack window, not the entire animation clip, controls damage. Place its start after the wind-up and its completion after the blade has passed the target.

## Choose attack and combo timing

**Simple Attack** performs one active window per use. Its released-Version-3 defaults are:

| Field | Default | Runtime purpose |
| --- | ---: | --- |
| **Active Attack Start Event Trigger** | Timed, `0` seconds | Opens collision checking. The matching event is `OnAnimatorActiveAttackStart`. |
| **Active Attack Complete Event Trigger** | Timed, `0.2` seconds | Closes collision checking. The matching event is `OnAnimatorMeleeAttackComplete`. |
| **Allow Chain Attack Event Trigger** | Timed, `0.2` seconds | Allows a Combo Trigger to accept the next use before the current use fully completes. The matching event is `OnAnimatorAllowChainAttack`. |
| **Single Hit** | Off | Intended attacker-level one-hit choice, but it is not consumed by the released collision code; use the working hitbox choice described below. |

Each attack carries **Attack ID** `0`, blank **State Name**, **Strength Multiplier** `1`, and a Single Hit value. **Attack ID** and the current use substate can filter Attack Effects and Impact modules. A nonempty State is active on both the character and Character Item only during that attack. Impact strength is Trigger force multiplied by **Strength Multiplier**, and Hitbox Collision multiplies it again by that hitbox's **Damage Multiplier**.

Use the Trigger and Attack modules for different jobs:

- **Simple Combo** or **Repeat Combo** advances through the Trigger's Animator Audio States across separate uses. **Allow Attack Combos** starts enabled.
- **Multi Attack** opens several active windows inside one use, each with its own attack data and start/complete timing. Use it for a rapid multi-slash move, not for a normal button-by-button combo.
- A Multi Attack resets the target hit list for each active subattack, so the same target can be damaged once by each subattack when the hitbox's own **Single Hit** is off.

## Choose collision detection

All three Collision modules share **Impact Layers**, **Trigger Interaction: Ignore**, **Max Collision Count: 20**, and **Forward Shield Sensitivity: -0.75**. The hit list resets at each active attack and excludes the attacking character and first-person camera children.

| Collision module | Use it for | Key settings and behavior |
| --- | --- | --- |
| **Hitbox Collision** | A sword, fist, foot, or another shape that follows animation | Uses separate first- and third-person `MeleeHitbox` arrays. Each hitbox can resolve a collider directly or through **Collider Object ID** (`-1` by default), has **Damage Multiplier** `1`, zero minimum Y/Z offsets, **Require Movement** off, **Single Hit** off, and an optional Surface Impact override. |
| **Lerped Hitbox Collision** | Intended to bridge fast motion between frames | Adds **Density**, but the released-Version-3 implementation does not retain the previous pose and therefore does not perform the intended interpolation. Use the limitation guidance below. |
| **Sphere Overlap Collision** | An unarmed or broad area attack that does not need weapon geometry | Checks a sphere centered at local `(0, 1, 1)` with radius `1`. It has no per-hitbox damage multiplier or Surface Impact override. |

Hitbox Collision supports Box, Sphere, and Capsule Colliders. It temporarily disables the attacking character's collision layer and the hitbox collider while performing its overlap, so the item does not detect itself. Keep hitbox colliders on an appropriate trigger or non-blocking layer rather than using their disabled state as the attack gate.

When a struck character has an equipped Shield Action, the collision module can redirect the target collider to the shield if the characters face each other closely enough for **Forward Shield Sensitivity**. A shield that requires Aim must also be actively aimed. The Shield Action then owns absorption and the [Block or parry reaction](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/).

## Configure effects, impacts, and recoil

Released Version 3 includes two Attack Effects:

- **Generic Item Effects** invokes an [Item Effect group](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/). **On Start Attack** is on, **On Complete Attack** is off, and **Substate Index** and **Attack ID** both start at `-1`, which matches every attack.
- **Enable Disable Effects** selects perspective objects to enable and disable around an active attack. Its released start filter is reversed; use the workaround in Troubleshooting instead of depending on it.

**Generic Melee Impact Module** is the only built-in Impact module. Its Substate and Attack ID filters start at `-1`, its Conditions use the default group, its success result uses the default damage Impact Action group, and its failure group is empty. Add separate rows when different attacks need distinct conditions or results.

**Simple Recoil** recognizes a `ShieldCollider` with durability remaining or a `RecoilObject`. It stops further collision checks for that attack, uses an Animator Audio State Set with substate priority `500`, and publishes `OnMeleeRecoil`. Recoil does not make arbitrary scenery solid automatically; add `RecoilObject` where that response is required.

**Trail Effect** can show a trail only during Attack or Always. It defaults to Attack visibility, no spawn delay, and a timed `0.5` second **Attack Stop Trail Event**. Assign a pooled trail prefab with a `Trail` component and perspective-specific **Trail Location** values.

## Coordinate special melee scenarios

- For an aerial slash or ground slam, configure a separate action and the [In Air Melee Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/in-air-melee-use/) ability. The **In Air** Trigger keeps normal Use from selecting that path while airborne when **Require In Air Ability In Air** is enabled.
- For a defender reaction, configure the Shield Action and [Block](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/). A defending item that contains both Shield and Melee actions uses the parry Item State Index; damage absorption still belongs to Shield.
- For a timed response after a valid block, configure [Melee Counter Attack](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/melee-counter-attack/) with its own action ID, range, input order, and collision/impact setup.
- For a root-motion lunge, enable only the root-motion axes authored by the attack clip, then retest hitbox timing and distance. Leave **Face Target** off when player or Movement Type rotation should remain in control.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the Melee Action has a unique **ID** and Use selects the correct ID and slot;
- the intended Trigger, Attack, Collision, and Recoil rows are first among their enabled groups;
- every combo state has a valid Item Substate Index and matching Animator state;
- Use, active-start, active-complete, chain, and Use-complete events exist on the correct slot or use tested durations;
- first- and third-person hitboxes resolve to correctly sized Box, Sphere, or Capsule Colliders;
- Impact Layers include the targets but exclude unintended item, UI, and effect layers;
- the Impact group contains the intended damage, force, surface, and reaction actions; and
- Trail, audio, Item Effect, State, Shield, recoil, and Surface Impact references are assigned where used.

## Verify in Play Mode

1. Equip the Iron Sword, select its Melee Action, expand **Debug**, and perform one attack away from a target.
2. Confirm the Debug state reaches active attack only between the configured start and complete points; collision checks should stop outside that window.
3. Strike one target. Confirm it receives one impact, the expected damage and force, and the correct Surface Impact. Watch the reported attack ID, hit count, and impact strength.
4. Repeat in first and third person. The visible hitbox should follow the correct blade and produce the same gameplay result.
5. Perform every combo step slowly, then at the intended chain timing. Confirm Item Substate Index changes in order and a late press restarts instead of skipping a step.
6. Test a Multi Attack against the same target. Confirm each configured subattack opens and closes once and may apply its own filtered effects and impacts.
7. Strike a `RecoilObject`, an unaimed shield, an aimed shield, and ordinary scenery. Confirm only configured solid targets cancel the attack and select recoil.
8. Test a miss, an airborne start, root-motion movement, perspective switching, and save/load or network boundaries used by the project.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The animation plays but no collision checks occur | **Active Attack Start Event Trigger**, **Active Attack Complete Event Trigger**, and first enabled Attack | Add the correct events or use tested durations. Keep the active window open across the visible contact frames. |
| A hitbox misses a fast target | Collision type and the released Lerped Hitbox implementation | Released Version 3 never clears its first-check flag, so Lerped Hitbox uses the current pose as both endpoints. Use ordinary Hitbox Collision or Sphere Overlap, or a project-fixed module that retains the previous pose and bounds its result count. |
| A project-fixed lerped hitbox throws when many colliders are crossed | **Density**, **Max Collision Count**, and unique results | The released union writes unique results into a fixed array without a bounds check. Clamp custom/interpolated results to the array capacity. |
| A hitbox collider becomes enabled after the first attack | Collider's initial enabled state | Released Hitbox Collision restores `enabled` to true rather than its previous value. Keep the configured collider enabled on a safe trigger/non-blocking layer, or restore its prior state in a custom module. |
| **Simple Attack > Single Hit** has no effect | Attacker field versus each `MeleeHitbox > Single Hit` | The attacker writes the value but released collision modules never read it. Use per-hitbox **Single Hit** for one accepted collision per use, or custom stop-on-first-impact logic. |
| The same target cannot take repeat damage during one active attack | **Multi Hit Frame Count** and the active-attack hit list | The released hit list suppresses that target until the next active attack, regardless of the frame count. Use Multi Attack for separate hit windows or a custom collision policy. |
| **Enable Disable Effects** does nothing at start or leaves objects reversed | Attack Effect filters | Its released start filter is inverted. Use Generic Item Effects with explicit start and completion groups, or Trail Effect, instead. |
| The sword hits itself or blocks movement | Collider layer, trigger choice, and Impact Layers | Put the hitbox on the intended non-blocking/trigger layer, exclude item layers from impacts, and verify each perspective reference. |
| Damage or force is wrong | Trigger force, attack **Strength Multiplier**, hitbox **Damage Multiplier**, and Impact Actions | Test all multipliers at `1`, then tune one layer at a time. Sphere Overlap has no hitbox multiplier. |
| The target takes no damage | Impact Layers, Collision hit, Generic Melee Impact filters, Conditions, and success group | First confirm Debug reports a collision. Reset filters to `-1`, verify Conditions, and configure the damage action in the success group. |
| Recoil never starts | Hit object, Shield durability, `RecoilObject`, Recoil row order, and Animator states | Add the required component or use a valid shield, keep Simple Recoil first enabled, and implement its recoil Item Substate Index. |
| A combo step is skipped or cannot chain | Trigger Animator Audio States and `OnAnimatorAllowChainAttack` timing | Use one state per step and place the chain event inside the intended input window. Do not use Multi Attack as a substitute for a combo. |

## Saving and multiplayer

The Melee Action, module rows, hitbox references, filters, perspective values, States, and event timing serialize with the Character Item or prefab. Treat the active use, combo step, pending animation waits, active attack State, hit list, collision data, recoil state, and spawned trail as transient runtime state. Finish or cancel an attack around a save/load boundary instead of resuming it midway.

With the multiplayer integration enabled, authority applies Impact modules and explicit calls replicate the main Attack, start-stage Attack Effects, impacts, and supported module results. Completion-stage Generic Item Effects, custom modules, trail lifecycle, and project-specific reactions are not automatically authoritative merely because they are in a Melee group. Test attack start/completion, hits, shields, recoil, trails, and perspective changes on owner, server, and remote clients.

## Related tasks

- [Create the Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)
- [Configure the shared Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/)
- [Configure the Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Configure Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/)
- [Configure Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/)
- [Configure Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Configure Block and parry](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/)
- [Configure In Air Melee Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/in-air-melee-use/)
- [Configure Melee Counter Attack](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/melee-counter-attack/)
- [Configure Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/)

## Developer reference

`MeleeAction` derives from `UsableAction`. Its action-specific bases are `MeleeAttackModule`, `MeleeCollisionModule`, `MeleeAttackEffectModule`, `MeleeImpactModule`, `MeleeRecoilModule`, and `MeleeExtraModule`. `MainMeleeAttackModule`, `MainMeleeCollisionModule`, and `MainMeleeRecoilModule` return the first enabled rows.

`MeleeUseDataStream` carries `TriggerData`, `MeleeAttackData`, and `MeleeCollisionData`. The collision module creates a `MeleeImpactCallbackContext`, assigns the hitbox index as `SourceID`, sets Impact Strength and optional Surface Impact, and sends the context to `MeleeAction.OnAttackImpact`. Custom attack modules should pair every `OnActiveAttackStart` with `OnActiveAttackComplete` so attack States and all module callbacks remain balanced.

The [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) publishes `OnMeleeRecoil(MeleeRecoilModule)` when Simple Recoil starts. The shared action and ability events are documented on [Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) and [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/). The attack timing events are `OnAnimatorActiveAttackStart`, `OnAnimatorMeleeAttackComplete`, and `OnAnimatorAllowChainAttack`, each with the configured slot-aware alternative.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-usable-throwable"></a>

# Throwable

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/)

A Throwable Action turns an inventory-backed Character Item into a physical object that the character can throw. Use it for a grenade, rock, potion, or another object that needs a trajectory, collision, and a fresh visible item after each throw; unlike a Shootable Action, it has no clip and re-equips the next inventory unit instead of reloading.

## Create a throwable grenade

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager** and follow [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) to assign the Item Definition, first- and third-person objects, Inventory slot, and Animator Item ID.
2. In the action list, add **Throwable**, give the row a descriptive name, and select **Build Item** or **Update Item**.
3. Select the generated Character Item. Confirm that the Throwable Action **ID** is unique on the item, then match it with **Action ID** on the character's [Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/). Use **Slot ID -1** for all equipped slots or choose the grenade's exact slot.
4. Keep an enabled first module in **Trigger**, **Thrower**, **Ammo**, **Projectile**, and **Re-Equipper**. The Item Manager recipe supplies **Simple**, **Projectile Thrower**, **Item Ammo**, **Spawn Projectile**, and **Simple Re-Equipper**.
5. Build the thrown prefab with **Tools > Opsive > Ultimate Character Controller > Object Manager**. Choose **Object Type Grenade** for a timed grenade. On its root, confirm that a Collider and the UCC **Grenade** component are present. A non-grenade throwable still needs a root Collider and a [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/).
6. In **Spawn Projectile**, assign the prefab to **Thrown Object**. For a Grenade prefab, add **Throwable Grenade** to the action's **Extra** group so use starts the fuse and can remove the pin.
7. Position **Throw Location** and **Trajectory Location** for every enabled perspective. If the grenade has a Pin, also assign each perspective's **Pin Attachment Location** and synchronize **Remove Pin Event** with the animation.
8. Set the Grenade's **Lifespan**, collision behavior, and **Spawned Objects On Destruction**. Put explosion damage and effects on the spawned [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) or on the thrown prefab's Projectile impact path.
9. Add the Character Item's Item Definition to the character's inventory or Default Loadout. **Item Ammo** uses that same inventory count and removes one unit when the object is actually thrown.
10. Match **Use Event**, **Use Complete Event**, and **Reequip Event** to the animation. The use event is the release frame; the re-equip event is when the next visible item returns to the hand.

The released Version 3 Item Manager recipe also adds **Generic Throwable Impact**, **Throwable Visualize Trajectory**, **Slot Item Monitor Module**, a Trajectory Object on the Character Item, and enables **Full Inventory Drop**. It sets **Can Equip Empty Item** on the generated Simple Re-Equipper, but it does not add **Throwable Grenade** or a Throw Effect. Treat the generated modules as a starting point and configure the thrown prefab, transforms, events, visuals, and target result before testing.

![Throwable Action Inspector with its Trigger, Thrower, Ammo, Projectile, Throw Effects, Impact, Re-Equipper, and Extra module groups](https://opsive.com/wp-content/uploads/2022/10/ThrowableInspector.png?v=65f78d868d25)

## Understand the module pipeline

| Module group | Active modules | Purpose |
| --- | --- | --- |
| **Trigger** | First enabled | Chooses Simple, Charged, Repeat, or another inherited input pattern. |
| **Usable** | All enabled | Runs common Usable modules such as States, Attributes, or Item Effects. |
| **Thrower** | First enabled | Calculates the origin, direction, velocity, and trajectory data, then releases the object. |
| **Ammo** | First enabled | Decides whether an object is available and removes its inventory amount. |
| **Projectile** | First enabled | Pre-spawns and supplies the actual GameObject that will be thrown. |
| **Throw Effects** | All enabled | Runs Item Effects at the moment the object is released. |
| **Impact** | Serialized but not called by the released Version 3 built-in throw path | Do not rely on this group for the thrown object's collision result; use the prefab path described below. |
| **Re-Equipper** | First enabled | Waits for the next-item animation and restores the next inventory unit. |
| **Extra** | All enabled | Adds trajectory display, grenade pin/fuse behavior, or the Slot Item Monitor. |

Only the first enabled Trigger, Thrower, Ammo, Projectile, and Re-Equipper participates. Reorder or disable alternatives instead of expecting modules in one of those groups to combine. The action is invalid without an enabled Thrower, Ammo, Projectile, and Re-Equipper; the inherited Usable flow also requires a Trigger.

## Configure the throw

### Origin, direction, and trajectory

| Projectile Thrower field | Released Version 3 default | What it controls |
| --- | --- | --- |
| **Impact Layers** | Every layer except IgnoreRaycast, TransparentFX, UI, and Overlay | Look-source aiming and the pre-throw obstruction linecast. The thrown prefab's Trajectory Object or Projectile layers control its later collisions. |
| **Projectile Thrown Layer** | VisualEffect | Layer assigned after the object has left the hand. |
| **Layer Change Delay** | `0.1` seconds | Time before the spawned object changes from its start layer. |
| **Throw In Look Source Direction** | Disabled | Uses the Look Source position as the origin for a non-independent-look Movement Type and changes the reported fire direction. The built-in Projectile Thrower still rotates its launch velocity toward the Look Source when this is disabled. |
| **Throw Location** | Perspective property | Where the pre-spawned object is held and released. The module creates a `ThrowLocation` child for each visible perspective when added outside a prefab. |
| **Trajectory Location** | Perspective property | Origin used to calculate and display the arc. The module creates a `TrajectoryLocation` child beside each Throw Location. |
| **Trajectory Offset** | `(0, 0, 0)` | Offset from the selected Trajectory Location. |
| **Velocity** | `(0, 5, 10)` | Local launch velocity. The actual throw rotates it toward the Look Source, multiplies it by the Trigger force, and adds the character's forward local velocity. |

Use **Simple** when one press should release at **Use Event**. Use **Charged** when holding input should change `TriggerData.Force`; the actual launch speed is multiplied by that force. **Throwable Visualize Trajectory** shows the Character Item's Trajectory Object while input-driven [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) is active and clears it when use begins. Match its mass, gravity, speed, collider, and other trajectory settings to the thrown prefab, and configure a Line Renderer when a visible arc is required.

The preview and live launch are not identical in released Version 3: the built-in preview does not apply Trigger force or add the character's forward velocity. Tune the displayed arc while stationary with a Simple Trigger. A charged or moving throw needs a custom preview module if the line must predict the landing point exactly.

### Spawn, inventory, and re-equip

| Module or field | Released Version 3 behavior |
| --- | --- |
| **Spawn Projectile > Thrown Object** | Starts unassigned. Assign a prefab whose root contains both a Collider and a Trajectory Object-derived component. |
| **Disable Visible Object** | Disabled. When enabled, the held object remains hidden until **Activate Throwable Object Event** or its duration calls `OnAnimatorActivateThrowableObject`. |
| **Start Layer** | IgnoreRaycast. The object uses this layer while attached to the hand. |
| **Item Ammo** | Has no separate ammo definition or clip. It reads the Character Item's own Item Identifier amount and removes one at release. |
| **Simple Re-Equipper > Can Equip Empty Item** | The module default is disabled; the Item Manager's generated Throwable recipe enables it. In released Version 3, the built-in flow does not call this check: reaching zero still reports that the action should unequip and requests the next Item Set. Treat the field as an extension point rather than the built-in zero-count control. |
| **Substate Index Data** | Index `10`, priority `150` while the next item is being re-equipped. |
| **Reequip Event** | Timed at `0.5` seconds by default. Enable event waiting to use `OnAnimatorReequipThrowableItem` in the matching slot animation. |
| **Slot Item Monitor Module > Show** | Enabled. Displays the remaining amount of the Character Item's Item Identifier. |

There is no Throwable clip and the [Reload ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/) is not part of this flow. When use completes and another inventory unit exists, Simple Re-Equipper waits for its event or duration, changes the Item Substate Index, and reveals the next object. When the count reaches zero, the action requests the next Item Set after use stops.

A thrown object is not automatically an inventory pickup. If the player should recover it, configure an [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/item-pickup/) as a separate result or add an appropriate pickup behavior to the object that remains after impact.

### Grenade, pin, impact, and feedback

The **Grenade** component is a Projectile-derived Trajectory Object. **Lifespan** defaults to `5` seconds and **Pin** is optional. Cooking starts when the item begins use, not when it leaves the hand, so the use animation and any time held before release count toward the fuse. Configure **Spawned Objects On Destruction** for an explosion prefab; use the Grenade/Projectile **Internal Impact** and Impact Action Group when the moving object itself should apply a collision result.

**Throwable Grenade** is an Extra module, not part of the generated recipe. Its released Version 3 defaults are **Animate Pin Removal** enabled and **Remove Pin Event** waiting for `OnAnimatorItemRemovePin` with a stored duration of `0.4` seconds. Assign **Pin Attachment Location** for both perspectives. The thrown prefab must use the **Grenade** component; this module starts cooking by treating the spawned Trajectory Object as a Grenade.

For release audio, particles, camera feedback, or States, add **Generic Item Effects** to **Throw Effects** and configure its [Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/). Those effects run when the object is actually thrown. Use the Trigger's Animator Audio State Set for the use animation and its synchronized audio, and use the Re-Equipper substate for the replacement animation.

The generated **Generic Throwable Impact** entry is not reached by the built-in released Version 3 Projectile Thrower or Throwable Action. Configure collisions, damage, force, surface response, and explosions on the thrown prefab's Trajectory Object, Projectile/Grenade **Internal Impact** path, spawned Explosion, or a custom caller. Adding [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) only to the Throwable Action's Impact group does not make them run.

## How it runs

![Throwable Action flow from starting use through spawning and releasing the object to re-equipping the next inventory unit](https://opsive.com/wp-content/uploads/2022/10/Throwable.drawio.png?v=bc25442e280d)

1. The Use ability finds the equipped Character Item by **Slot ID** and the Throwable Action by **Action ID**. The first enabled Trigger and inherited use fields control the timing.
2. On Start Use, **Spawn Projectile** creates the thrown prefab at the perspective's Throw Location, parents it under the visible item, places it on **Start Layer**, and disables its Trajectory Object. The original visible-object renderers are hidden so only the spawned object represents the item in hand.
3. If **Throwable Grenade** is enabled, it starts the Grenade's fuse immediately and schedules the configured pin event when the pin and visible object are available.
4. At **Use Event**, the Trigger tells Projectile Thrower to release. Spawn Projectile supplies the pre-spawned object, and Item Ammo removes one unit from the inventory.
5. Projectile Thrower detaches the object, enables its root Collider, applies the Trigger-scaled launch velocity plus character forward velocity, initializes the Trajectory Object, and changes the object's layer after **Layer Change Delay**.
6. The action invokes every enabled Throw Effect and raises its throw events. The thrown object's Trajectory Object, Projectile, Grenade, and spawned Explosion then own flight, collision, damage, and destruction.
7. At Use Complete, Simple Re-Equipper starts when another unit remains. It waits for **Reequip Event**, updates the Item Substate Index, and tells Spawn Projectile to show the next visible item.
8. When no unit remains, the action reports that it should unequip and requests the next Item Set after use stops. Item Set rules determine the resulting equipment.

Perspective changes select the matching Throw Location, Trajectory Location, Pin Attachment Location, and visible renderers. Test a throw in every perspective used by the item; a correct third-person origin does not prove that first-person arms are configured.

## Verify the throwable

### Editor checkpoint

Before Play Mode, confirm:

- the Throwable Action **ID** matches Use **Action ID**, and every action on the Character Item has a unique ID;
- Trigger, Thrower, Ammo, Projectile, and Re-Equipper each have an enabled first module;
- **Thrown Object** is assigned and its root has a Collider plus Trajectory Object, Projectile, or Grenade component;
- the Character Item inventory amount is positive;
- each perspective has the intended Throw Location, Trajectory Location, visible object, and optional Pin Attachment Location;
- **Use Event**, **Use Complete Event**, **Activate Throwable Object Event**, **Remove Pin Event**, and **Reequip Event** match their animation clips or use tested durations;
- the Character Item trajectory simulator matches the thrown prefab closely enough for the intended preview; and
- collision, damage, and explosion behavior is configured on the thrown prefab path rather than only in the inactive Throwable Impact group.

### Play Mode checks

1. Equip several copies of the item, expand the Throwable Action's **Debug** section, and record the remaining amount.
2. Start use without releasing immediately. Confirm the spawned object replaces the item mesh at the correct hand location. For a Grenade, confirm its fuse begins and the pin moves at the configured frame.
3. Release one throw. Confirm the inventory amount falls by exactly one at release, the object begins from the correct perspective, and its arc responds to the configured Velocity and Trigger force.
4. Aim while stationary and compare the displayed trajectory with the landing point. Then move or test a Charged Trigger to decide whether the released Version 3 preview limitation matters for the design.
5. Hit an allowed surface and an excluded surface. Confirm the thrown prefab bounces, settles, sticks, damages, or destructs according to its own Trajectory Object/Projectile settings, and confirm an Explosion appears only at the intended time.
6. Watch Item State and Item Substate Index after the throw. Confirm the next unit becomes visible at Reequip Event and that Use cannot begin another throw during re-equipping.
7. Throw the final unit. Confirm the next Item Set handoff matches the equipment rules, and verify any configured pickup can restore the inventory amount.
8. Switch perspective before use, while holding the object, and after re-equipping. Confirm origins, renderers, pin attachment, effects, and the Slot Item Monitor remain correct.

## Troubleshoot a Throwable Action

| Symptom | Check | Fix |
| --- | --- | --- |
| Use does not start | Required first modules, Character Item amount, action IDs, and slot | Enable a Trigger, Thrower, Ammo, Projectile, and Re-Equipper; add the Character Item's Item Identifier to inventory; and match Use **Action ID** and **Slot ID**. |
| The object is null, remains attached, or throws a component error | **Thrown Object**, root Collider, and Trajectory Object-derived component | Assign the prefab and put both a Collider and Trajectory Object, Projectile, or Grenade on its root. |
| The object begins in the wrong place | Perspective-specific **Throw Location**, visible-object hierarchy, and **Throw In Look Source Direction** | Position every Throw Location. Enable look-source origin only when that origin is wanted; the built-in launch velocity still aims toward the Look Source. |
| No trajectory line appears | Input-driven Aim, **Show Trajectory On Aim**, Character Item Trajectory Object, and Line Renderer | Start Aim from input, enable the module, and configure the simulator and Line Renderer on the Character Item. |
| The preview and landing point disagree | Charged Trigger force and character forward movement | Released Version 3 omits both from the built-in preview but applies them to the live throw. Tune while stationary with Simple, or use a custom preview module for exact charged/moving prediction. |
| The object collides while still in the hand or never changes layer | **Start Layer**, **Projectile Thrown Layer**, and **Layer Change Delay** | Keep the attached object on a non-colliding start layer such as IgnoreRaycast and choose an appropriate thrown layer and delay. |
| The object collides but causes no damage or explosion | Thrown prefab's Internal Impact, Impact Actions, destruction settings, and spawned Explosion | Configure the Trajectory Object/Projectile/Grenade path. The Throwable Action's built-in Impact group is serialized but is not called in released Version 3. |
| The pin never leaves the grenade | Grenade **Pin**, **Animate Pin Removal**, object visibility at Start Use, event, and attachment | Assign the Pin and both attachment locations, keep Animate Pin Removal enabled, and keep the spawned object visible when use starts. Supply `OnAnimatorItemRemovePin` or a tested duration. If the object must begin hidden or the built-in animation path is disabled, use a custom pin module or project code. |
| The grenade explodes before release | **Lifespan**, use timing, and time spent cooking | The fuse begins at Start Use. Lengthen Lifespan, shorten the pre-release animation, or make in-hand cooking an intentional part of the design. |
| Canceling use leaves an object in the hand or a fuse continues | Interruption between Start Use and the actual throw | In released Version 3, Spawn Projectile clears its reference on Stop Use without destroying the pre-spawned object, and a Grenade fuse already started keeps running. Prevent interruption during the cook/throw window or add project cleanup for the spawned object and fuse. |
| The next object never appears | Remaining inventory, **Reequip Event**, and Simple Re-Equipper state | Add another inventory unit and provide `OnAnimatorReequipThrowableItem` in the correct slot, or disable event waiting and use a tested duration. |
| The count reaches zero too early or a recovered object does not restore it | Item Ammo's Item Identifier and pickup behavior | Item Ammo consumes the Character Item's own Item Identifier at release. Configure a separate Item Pickup or inventory adjustment for recovery. |
| A first-person or third-person mesh disappears incorrectly | **Disable Visible Object**, activation event, and perspective properties | Assign both perspective objects and transforms. If the spawned object begins hidden, provide `OnAnimatorActivateThrowableObject` or a duration before the expected reveal. |

## Saving and multiplayer

The Character Item or prefab serializes the action, module order, thrown prefab, perspective properties, trajectory values, and event timing. Item Ammo is the Inventory amount of the Character Item's Item Identifier and can be persisted through the inventory/save integration. A pre-spawned held object, an active throw, a cooking fuse, pending animation events, and re-equip progress are transient runtime state; restore the durable inventory result and restart any interrupted presentation deliberately after load.

The multiplayer integration network-spawns the thrown prefab from the authority and lets the server manage the projectile. Built-in Throw Effects also have an explicit network invocation path. A custom impact caller, Item Effect, pickup, or grenade result is not replicated merely because it belongs to this action. Test inventory consumption, projectile authority, collision/explosion damage, pin and perspective visuals, re-equipping, and interruption on the owner, server, and remote clients.

## Related tasks

- [Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) explains Trigger choices, Use timing, Action IDs, and the shared module lifecycle.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/) and [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/) configure the interacting item abilities.
- [Common Item Setups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/) provides practical Character Item creation routes.
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) configures the simulated path and moving object's collision behavior.
- [Grenade](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/grenade/) configures the timed thrown prefab, pin, and destruction result.
- [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) configures the spawned overlap, damage, force, and effects.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/item-pickup/) returns an Item Identifier amount to an Inventory.
- [Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/) explains module order, States, and custom modules.
- [Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/) configures release feedback on the action.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains timed and Animator-event synchronization.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains the Item State and Item Substate Index used by the throw and re-equip animations.

## Developer reference

`ThrowableAction` extends `UsableAction` and exposes `ThrowerModuleGroup`, `AmmoModuleGroup`, `ProjectileModuleGroup`, `ThrowEffectGroup`, `ImpactModuleGroup`, `ReequiperModuleGroup`, and `ExtraModuleGroup`. `MainThrowerModule`, `MainAmmoModule`, `MainProjectileModule`, and `MainReequiperModule` return the first enabled module. Runtime state is available through `IsThrowing`, `WasThrown`, `IsReequipping`, `RemainingAmmoCount`, `InstantiatedTrajectoryObject`, and `ThrowableObjectIsVisible`; `GetThrowPreviewData()` returns the current preview data.

The action raises `OnThrowEvent(ThrowableThrowData)`, `OnThrowUnityEvent`, and `OnReequipThrowableItemEvent`. The [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) also publishes `OnThrowableItemAmmoChange(CharacterItem, ThrowableAmmoModule)`. The core animation event names are `OnAnimatorItemUse`, `OnAnimatorItemUseComplete`, `OnAnimatorActivateThrowableObject`, `OnAnimatorItemRemovePin`, and `OnAnimatorReequipThrowableItem`.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-usable-magic"></a>

# Magic

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/)

The Magic Action builds a spell from reusable casting, presentation, and impact modules. Use it for a Fire Wand projectile, a targeted effect, an area spell, a channeled beam, or a teleport instead of writing one item action for every spell.

## Before you begin

- Create the Character Item and add a **Magic** action through **Tools > Opsive > Ultimate Character Controller > Item Manager**. The [magic anchor setup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/#magic-with-transform-anchors) is useful when a spell has no visible held model.
- Add or select the character's [Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/). Its **Action ID** must match this Magic Action's **ID**, and its **Slot ID** must include the Character Item's slot.
- Add first- and third-person cast-origin transforms when effects should start from a hand, wand tip, or staff. **Character As Cast Origin** can be used for a body-centered spell.
- Add the required Animator states or use tested durations for the Use and cast event triggers. See [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/).
- If the spell spends mana, create the Attribute on the character before configuring **Character Use Attribute**. See [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/).

## Build a Fire Wand spell

1. In the Item Manager, add a **Magic** action named `Fire Wand`, then select **Build Item** or **Update Item**.
2. Select the generated Character Item. Give the Magic Action a unique **ID**, then point the character's Use ability at that value. Released Version 3 leaves an Item-Manager-created Magic Action at the default ID `0`, unlike the other generated actions.
3. In **Trigger Action Module Group**, add **Simple** and make it the first enabled Trigger. A generated Magic Action does not receive a Trigger automatically.
4. In **Usable Action Module Group**, add **Character Use Attribute** when the spell should spend mana. Set **Character Use Attribute Name** to the exact character Attribute name and choose the amount spent by one use cycle.
5. In **Caster Module Group**, add **Simple Caster**. Leave **Direction** at **Forward** for a wand projectile, keep **Use Look Source** enabled, and assign the first- and third-person **Cast Origin** values. Only the first enabled Caster is active.
6. In **Begin Module Group**, optionally add a short **Play Audio Clip**, **Spawn Particle**, **Fade Materials**, **Toggle GameObject**, or **Generic Item Effects** row for the wind-up. These rows start with item use and stop when casting begins.
7. In **Cast Effects Module Group**, add **Spawn Projectile**. Assign a pooled projectile prefab with a `Projectile` component, then set its **Speed**, offsets, and **Parent To Origin** choice. The default speed is `1`, so tune it for the scene scale.
8. In **Impact Module Group**, add **Generic Magic Impact Module**. Its released-Version-3 defaults include the standard conditions and a default damage Impact Action group; replace or tune those actions for the spell.
9. In **End Module Group**, add only feedback that belongs after casting, such as a stop sound or object toggle. End modules start when casting stops and stop when item use ends.
10. Save the Character Item prefab and confirm that the Use, cast-start, cast-repeat, cast-end, and completion timing matches the spell's animations.

The legacy Inspector below shows a Teleport example with Simple Trigger and Caster modules, Begin feedback, three Cast Effects, and an End fade. Empty Impact and Extra groups are valid when the spell does not use them.

![Teleport Magic Action with Simple Trigger and Caster modules, Begin particle fade and audio modules, Teleport particle and audio Cast Effects, and an End fade](https://opsive.com/wp-content/uploads/2022/10/TeleportInspector.png?v=11d4341dd568)

## Understand the module groups

| Group | Active-module rule | Responsibility |
| --- | --- | --- |
| **Trigger** | First enabled module | Decides whether one input performs a simple, repeat, burst, charged, or combo use cycle. |
| **Usable** | Every enabled compatible module | Applies shared item effects, Attributes, aiming substates, States, and other [Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) behavior. |
| **Caster** | First enabled module | Creates the cast origin, direction, target list, timing, and stop behavior. Released Version 3 includes **Simple Caster**. |
| **Begin** | Every enabled module | Runs presentation while the spell is winding up. |
| **Cast Effects** | Every enabled module | Produces the spell result and reports when its work is complete. |
| **Impact** | Every enabled module | Responds when a Cast Effect supplies an impact. Adding an Impact module does not detect a hit by itself. |
| **End** | Every enabled module | Runs presentation between the end of casting and the end of item use. |
| **Extra** | Every enabled module | Extension point for project-specific Magic modules. Released Version 3 has no concrete built-in Extra module. |

Module IDs identify rows for States and network bitmasks; the Magic Action **ID** is the value selected by the Use ability. Keep action IDs unique across one Character Item.

## How it runs

![Magic Action lifecycle from Start Use and Begin Cast through Cast Effects, completion, End Cast, and Stop Item Use](https://opsive.com/wp-content/uploads/2022/10/MagicAction.drawio-1024x215.png)

1. **Start Use** puts the Magic Action in its Begin phase and starts every enabled Begin module using preview cast data.
2. The shared Use and Trigger timing releases the action. **Simple Caster** checks grounding and target validity, creates `MagicCastData`, enters the Casting phase, and stops the Begin modules.
3. **Start Cast Event Trigger** releases every enabled Cast Effect. Each effect moves through pending, processing, and complete states while the Caster updates it.
4. A Physics Cast, Target Impact, projectile, or another impact-producing effect sends its hit through every enabled Impact module.
5. After the effects complete, the Caster waits for its selected stop timing. It marks the effects as about to stop, enters the End phase, and starts every enabled End module.
6. Item-use completion stops and resets the Cast Effects. **Stop Use** then stops the End modules and clears the current use cycle.

Begin and End use the same module types, but they run in separate phases. Keep the wind-up in Begin and recovery or cleanup in End so an interrupted spell has an understandable result.

## Choose the Simple Caster behavior

The action is invalid until at least one Trigger and one Caster are enabled. **Simple Caster** has the following important released-Version-3 defaults:

| Field | Default | Choose this based on |
| --- | ---: | --- |
| **Start Cast Event Trigger** / **Repeat Cast Event Trigger** / **End Cast Event Trigger** | Timed, `0` seconds | Whether an Animator event or duration controls each transition. The matching events are `OnAnimatorStartCast`, `OnAnimatorRepeatCast`, and `OnAnimatorEndCast`. |
| **Character As Cast Origin** | Off | Off uses the current perspective's **Cast Origin** and falls back to the character transform when it is unassigned. On always uses the character transform. |
| **Require Grounded** | On | Whether the spell may start in the air. |
| **Direction** | **Forward** | How the Caster creates its target position. |
| **Use Look Source** | On | Whether Forward casting follows the camera/look source instead of character forward. |
| **Max Distance** | `100` | Forward reach, Indicate reach, and the Target search radius. |
| **Radius** | `0.1` | Sphere-cast thickness for Forward and Indicate. |
| **Max Angle** | `30` degrees | Total forward target cone; the runtime checks half this value to either side. |
| **Max Collision Count** / **Max Target Count** | `100` / `1` | Search capacity and the maximum number of selected targets. |
| **Use Type** | **Single** | Single ends after one completed cast. Continuous remains active until it is allowed to stop. |
| **Minimum Continuous Use Duration** | `1` second | Minimum hold time for Continuous. Use `-1` to allow the first stop request immediately, or a positive duration. |
| **Continuous Cast** | Off | Whether completed Cast Effects continue receiving updates and can repeat during one cast. |
| **Interrupt Source** | **None** | Optionally force-stop on character movement, damage, or both. Jump and Fall count as movement. |
| **Cast Update On Cast** | Off | Off begins normal effect updates on the next item update; on performs the first update as soon as the start-cast event occurs. |

Choose the direction by the player-facing result:

| Direction | Use it for | Runtime result |
| --- | --- | --- |
| **None** | A body-centered aura or item-only effect | Uses character forward and position without searching for a surface or target. |
| **Forward** | Fireballs, rays, and look-directed spells | Sphere-casts from the look or character direction. With no hit, it uses the point at **Max Distance**. |
| **Target** | Lock-on or multi-target spells | Searches inside **Max Distance**, sorts candidates toward character forward, and supplies up to **Max Target Count** colliders. See the released-Version-3 targeting limitation below before using this for strict selection. |
| **Indicate** | Ground markers and teleport destinations | Requires a surface hit. An optional **Surface Indicator** follows the point and is hidden for remote players. |

For a single Fire Wand projectile, keep **Use Type** at **Single** and **Continuous Cast** off. For a held beam, use **Continuous**, turn on **Continuous Cast**, choose a positive minimum duration or `-1`, and give every repeated effect a deliberate interval. A **Character Use Attribute** charge occurs at the shared Use stage; it does not independently charge every Cast Effect update.

## Choose Cast Effects

Every Cast Effect has **Delay** `0`, **Initial Delay** `-1`, and, for multi-target effects, **Allow Multi Target** enabled by default. The runtime behavior is:

- **Initial Delay** controls the first cast when it is zero or positive. `-1` uses **Delay** for the first cast.
- **Delay** controls repeats after completion. A negative value prevents a repeat, `0` permits a repeat on the next eligible cast update, and a positive value waits that many seconds.
- Repeats require the Caster to keep updating the cast, normally with **Continuous Cast** enabled.

<div class="woocommerce-message docs-note">Released Version 3's serialized tooltips describe <strong>Delay</strong> and <strong>Initial Delay</strong> in the opposite order. Configure them according to the runtime behavior above.</div>

| Cast Effect | Use it for | Important choices and defaults |
| --- | --- | --- |
| **Physics Cast** | Immediate ray, sphere, or area hits | **Mode** defaults to Raycast; **Distance** and **Radius** both default to `5`; **Max Collision Count** is `50`; **Allow Self Impact** is off. Each hit enters the Impact group. |
| **Play Audio Clip** | Cast-stage audio, including a loop | **Play At Origin** is on, **Loop** is off, and fade-out defaults to `0.1` seconds in `0.05` steps. |
| **Spawn Object** | A temporary prop or persistent spell object | **Parent To Origin** is off and **Destroy On Stop** is on. |
| **Spawn Particle** | A burst, beam, trail, or perspective-aware visual | Can parent to the origin, project direction, clear its parent on stop, scale a renderer to target distance, and fade in or out. |
| **Spawn Projectile** | A moving projectile that reports collisions | Assign a prefab with `Projectile`; **Speed** defaults to `1` and **Parent To Origin** is off. Projectile impacts enter the Magic Impact group. |
| **Start Effect** | A Character Effect that should begin with a cast | Select the Effect and optionally enable **Stop Effect** so cast cleanup stops it. |
| **Target Impact** | Apply the Impact group to the Caster's selected target without another physics query | Uses the current Cast Target Position and target collider data. |
| **Teleport** | Move the character to an indicated valid surface | Rejects slopes beyond the locomotion slope limit and locations without standing space. **Snap Animator** is off. |
| **Cast Item Effects** | Invoke a reusable [Item Effect group](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/) | **Block Until Effects Can Be Used** is off. Enable it only when every contained effect must be available before the cast proceeds. |
| **Magic Cast Effect Nester** | Run a combination in parallel or sequence and repeat the combination | Parallel is the default; **Sequential** is off and **Repeat Count** is `0`. Nested effects keep their own timing. |

Use **Generic Magic Impact Module** to run [Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/), the successful [Impact Action group](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/), or a separate failure group. Use **Ricochet Impact** when the same cast should find another nearby object and immediately recast its enabled effects from the ricochet data.

## Choose Begin and End feedback

Begin and End both accept every released-Version-3 `MagicStartStopModule`:

| Module | Use it for | Important behavior |
| --- | --- | --- |
| **Generic Item Effects** | Local item-side presentation or a UnityEvent | **On Start** is on and **On Stop** is off by default. |
| **Fade Materials** | Fade character renderers during a phase | Targets `_Color` by default, fades toward alpha `0` at speed `0.02`, and does not revert on stop unless enabled. |
| **Play Audio Clip** | Wind-up or recovery audio | **Play At Origin** is on and **Loop** is off. Stop ends the active AudioSource. |
| **Spawn Particle** | Spawn one phase-start particle | Can parent the particle to the cast origin, but its Stop callback does not stop, unparent, or return the object; plan explicit particle cleanup. |
| **Toggle GameObject** | Show or hide perspective objects during the phase | Each row selects first- and third-person objects and an on/off result; choose **Toggle On Start**, **Toggle On Stop**, or both. |

Do not use the Start/Stop **Spawn Particle** module as the sole owner of a looping particle. Give the particle its own auto-stop and pool-return behavior, or use another module or project component that explicitly cleans it up.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the Magic Action has a unique **ID** and the Use ability selects it;
- the intended Trigger and Caster are the first enabled rows in their groups;
- each perspective has a valid **Cast Origin**, or the character fallback is intentional;
- **Direction**, grounding, layers, distance, target count, and surface indicator match the spell;
- every Cast Effect has its required prefab, Effect, Item Effect group, audio, or other reference;
- at least one impact-producing Cast Effect exists when the Impact group should run;
- Animator event waits have matching events on the correct slot, or use tested durations; and
- the mana Attribute exists on the owner read by **Character Use Attribute** or **Use Attribute**.

## Verify in Play Mode

1. Equip the Fire Wand, select its Magic Action, expand **Debug**, and press Use once.
2. Confirm Begin feedback starts first, stops at the start-cast event, and one projectile leaves the current perspective's wand-tip origin.
3. Confirm mana decreases by the configured amount once and the projectile's collision invokes the expected damage and surface response.
4. Watch the action move through Begin, Casting, End, and None. No particle, audio loop, temporary object, State, or collision-layer change should remain after Stop Use.
5. Switch perspectives and repeat. The projectile and feedback should use the matching first- or third-person origin without changing the gameplay target.
6. Test a miss, an obstructed target, an invalid teleport slope, an airborne start, movement interruption, and damage interruption for the settings that the spell enables.
7. For Continuous casting, hold longer than **Minimum Continuous Use Duration**, confirm the effect repeats at the configured **Delay**, then release and verify that End and Stop run once.
8. In multiplayer, repeat the test as owner, server, and remote observer, including a multi-target cast.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The generated Magic Action does nothing | Trigger and Caster groups | The Version 3 Item Builder creates the component but no starter modules. Add at least one enabled Trigger and **Simple Caster**. |
| Use runs the wrong action | Magic Action **ID**, Use **Action ID**, and other Character Item Action IDs | The Version 3 Magic builder leaves the ID at `0`. Assign a unique ID after every build or update and match the Use ability. |
| The first Cast Effect or its repeats occur at the wrong time | **Initial Delay**, **Delay**, and **Continuous Cast** | Ignore the reversed Version 3 tooltips. Use **Initial Delay** for the first cast and **Delay** for repeats; keep **Delay** negative when the effect must not repeat. |
| A Continuous cast never accepts release | **Minimum Continuous Use Duration** | Do not use exactly `0` in released Version 3. The stop condition accepts `-1` or a positive elapsed duration, but not zero. |
| Target mode reuses an old target or selects an occluded candidate | **Direction: Target** after a successful target, then an empty or obstructed scan | Released Version 3 does not clear the cached count on a zero-hit scan and counts in-angle candidates even when its line-of-sight test fails. Use Forward or Indicate when possible, or a custom validated Caster for strict targeting. |
| Character collision remains disabled after a rejected Forward or Indicate position | A Cast Effect validator such as Teleport rejects the candidate | Released Version 3 returns from that validation path before restoring the character collision layer. Avoid a rejecting validator in this path, or restore the collision layer explicitly in project code. |
| A Begin or End particle continues after its phase | Start/Stop **Spawn Particle** ownership | Its Stop callback only clears the cached transform. Configure the particle to stop and return itself, or use explicit cleanup. |
| The Inspector's **On Cast Event** never invokes | Magic Action event selection | Released Version 3 serializes the UnityEvent but never calls it. Register for Event System `OnMagicItemCast` instead. |
| Impact modules never run | Cast Effect type and enabled Impact rows | Add Physics Cast, Target Impact, Spawn Projectile, or another effect that actually calls the Magic Action's impact path; then enable the intended Impact modules. |
| A cast waits forever at start, repeat, or end | Animator events and slot mapping | Add `OnAnimatorStartCast`, `OnAnimatorRepeatCast`, or `OnAnimatorEndCast` to the correct animation, or disable event waiting and use tested durations. |
| A multi-target network cast invokes the wrong remote effect or throws an index error | More targets than Cast Effect modules in a networked cast | Released Version 3 builds the update-stage module bitmask with the target-loop index instead of the module-loop index. Keep authoritative spell results on the owner/server and replicate the result explicitly in project networking code; do not depend on the built-in update bitmask for multi-target spells. |

## Saving and multiplayer

Magic Action fields, module rows, perspective references, and State presets serialize with the Character Item or prefab. Treat the active Begin/Casting/End phase, current target slice, cast IDs and counters, pending timers, spawned transient effects, and current `MagicUseDataStream` as runtime state. Finish or cancel the cast around a save/load boundary instead of expecting it to resume midway.

With the multiplayer integration enabled, authority controls impacts and the action sends explicit network calls for Begin/End modules, Cast Effect start/update/end, impacts, projectiles, particles, and spawned objects where those modules implement support. Custom modules and arbitrary Item Effects are not automatically authoritative or replicated. Test each spell result, interruption, perspective change, and cleanup on every role; apply the multi-target update workaround in the table above.

## Related tasks

- [Create items and reusable magic anchors](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)
- [Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Configure the shared Usable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/)
- [Organize Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)
- [Configure Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/)
- [Configure Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/)
- [Configure Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Configure a Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/)
- [Map Animator parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/)

## Developer reference

`MagicAction` derives from `UsableAction`. Its action-specific extension bases are `MagicCasterModule`, `MagicStartStopModule`, `MagicCastEffectModule`, `MagicImpactModule`, and `MagicExtraModule`. A custom Caster supplies `MagicCastData`; the released type contains `CastOrigin`, `CastPosition`, `Direction`, `CastTargetPosition`, `StartCastTime`, `TargetIndex`, `Targets`, `CastID`, `CastNormal`, and `DetectLayers`.

`MagicAction.MainMagicCaster` is the first enabled Caster. `PerformImpact` builds or adopts an `ImpactCallbackContext`, assigns the cast ID as the source ID, and sends the context to enabled Impact modules. `MagicCastEffectModule` exposes `IsValidTargetPosition`, `StartCast`, `OnCastUpdate`, `OnCastLateUpdate`, `CastWillStop`, and `StopCast`; `MagicMultiTargetCastEffectModule` maintains one completion cache per supplied target.

The [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) publishes:

- `OnMagicItemCast(CharacterItem)` after all effects report a completed cast;
- `OnMagicItemStartStopBeginEndActions(CharacterItem, bool beginActions, bool start)` whenever a Begin or End group starts or stops; and
- `OnAnimatorStartCast`, `OnAnimatorRepeatCast`, and `OnAnimatorEndCast` for the Simple Caster's animation-event triggers.

Use those Event System callbacks for project integrations. The serialized **On Start Stop Begin End Actions Event** is invoked, but the serialized **On Cast Event** has the released-Version-3 limitation described above.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-shield"></a>

# Shield

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/shield/)

The Shield Action turns an equipped item's visible collider into physical protection. It can absorb all or part of eligible damage, spend item durability, and request a block or parry reaction from the character's Block ability.

## Before you begin

A Shield Action is different from the character Health component's **Shield Attribute**. The Shield Action protects only through its equipped **Shield Collider**; the Health shield is a general value consumed by the Health damage pipeline.

Prepare these parts:

- A Character Item with a visible first-person and/or third-person shield object.
- A Collider and **Shield Collider** on the same visible GameObject. Built-in Simple Damage looks for the Shield Collider on the reported impact Collider object, not on one of its parents.
- A character with Inventory and Ultimate Character Locomotion item support.
- A **Block** Item Ability when the character should play a reaction. Damage absorption itself does not require Block.
- Animator states for the supplied block/parry item state indexes when an animated reaction is required.
- An attacker whose impact uses the built-in **Simple Damage** action, or custom damage code that deliberately calls the Shield Action. Direct Health damage does not discover a Shield Collider automatically.

## Build a shield with the Item Manager

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**.
2. Create a Character Item or select an existing one. Assign the visible shield model for every supported perspective.
3. Under **Actions**, select **+**, choose **Shield**, and enter a useful action name.
4. Select **Build Item** for a new Character Item or **Update Item** for an existing one.
5. Select the main Character Item GameObject. Confirm it has a **Shield Action** with an **ID** that is unique among that item's actions. Block selects shields by item slot rather than Action ID, but the ID must still remain unique for the Character Item lookup.
6. Confirm the generated item has an **Attribute Manager** with a `Durability` Attribute. A fresh generated Attribute starts at minimum `0`, maximum `100`, current value `100`, and no automatic update.
7. Select each visible shield object. Confirm **Shield Collider > Shield Action** points to the generated action and a Collider is on that same GameObject. Resize the Collider to cover only the defensive surface.
8. Keep **Disable On Unequip** enabled unless a holstered shield should deliberately keep receiving hits.
9. If the item was built directly below a character, confirm Item Manager added **Block** to **Ultimate Character Locomotion > Item Abilities**. A reusable Character Item prefab has no parent character, so add Block to each character that equips it.

Item Manager adds a Box Collider when the visible shield object does not already have one. Replace or resize that starting collider when another shape matches the model better.

## Configure the Shield Action

Unlike Shootable, Melee, Throwable, and Magic actions, Shield Action has no Action Module Groups. Configure its protection fields directly on the component; the attacking action's Impact Action Group still determines how the hit and Simple Damage are reported.

| Field | Released-Version-3 default | Behavior |
| --- | --- | --- |
| **Require Aim** | Off | When on, protection and the reaction require an accepted Aim state. |
| **Absorption Factor** | `1` | `1` absorbs all eligible damage, `0` passes all damage through, and values between them split the amount. |
| **Absorb Explosions** | Off | When off, an impact whose source component is the built-in `Explosion` bypasses the shield. |
| **Apply Impact** | On | Starts the impact Animator/audio state and sends the event that asks Block to react. Absorption still works when this is off. |
| **Impact Animator Audio State Set** | Sequence selector | Selects the shield's Item Substate Index, State, and audio for each reaction. Add at least one configured state. |
| **Impact Complete Event > Wait For Animation Event** | Off | When off, Block completes the reaction after **Duration**. When on, an Animator event completes it. |
| **Impact Complete Event > Duration** | `0.2` seconds | Fixed-time fallback when not waiting for an Animator event. |
| **Impact Complete Event > Wait For Slot Event** | Off | Requests a slot-specific completion event. Keep this off in released Version 3; see the limitation below. |
| **Durability Attribute Name** | `Durability` | Exact name of an Attribute on an Attribute Manager on the Character Item. Empty or unresolved means the shield does not degrade. |
| **Drop When Durability Depleted** | Off | Removes one inventory amount and force-drops the Character Item when its durability reaches the minimum through damage. |

### Size and equip the Shield Collider

**Shield Collider** exposes two fields:

| Field | Default | Behavior |
| --- | --- | --- |
| **Shield Action** | None | Must reference the Shield Action on the main Character Item GameObject. |
| **Disable On Unequip** | On | Disables the Collider while this Character Item is not active. |

At runtime the component classifies itself as first person when it is on or below the visible first-person object; otherwise it is treated as third person. Only the Collider for the active perspective is enabled. Remote multiplayer characters are treated as third person by this component.

Keep **Disable On Unequip** on for normal equipment. Turning it off lets the Collider remain enabled while holstered whenever its perspective is active, so it may intercept damage even though the item is not equipped.

### Choose absorption and durability

For an eligible incoming amount, the Shield Action calculates:

```text
requested absorption = incoming damage * Absorption Factor
absorbed damage = minimum of requested absorption and current durability
damage passed to the character = incoming damage - absorbed damage
```

When **Durability Attribute Name** is empty or does not resolve, the shield is non-degrading and applies the absorption factor without spending a value. When the Attribute exists at its minimum, it absorbs nothing and the complete amount passes through. A partially depleted shield absorbs only the value it has left.

The generated `Durability` Attribute belongs to the Character Item, not the character. Configure its range and starting value on that item's Attribute Manager. Do not select the similarly named Health **Shield Attribute** unless the character also needs a separate general-purpose shield value.

### Configure the block or parry reaction

The **Impact Animator Audio State Set** starts when an eligible hit reaches a Shield Action with **Apply Impact** enabled. A new state row starts **Enabled**, allows movement, does not require grounded, has an empty **State Name**, uses **Item Substate Index** `0`, and has no selected Audio Config or clips. Configure the row to match the shield reaction implemented by the Animator.

The Block Item Ability starts and stops manually in response to Shield impacts. Its important defaults are:

| Block field | Default | Choice |
| --- | --- | --- |
| **Start Type** | Manual | Shield impacts start the ability; do not assign a player input. |
| **Stop Type** | Manual | The configured impact completion stops each reaction. |
| **Slot ID** | `-1` | Respond to shields in every inventory slot. Use one exact slot to limit this Block ability. |
| **Block Item State Index** | `8` | Item State Index used by a Shield-only defending item. |
| **Parry Item State Index** | `9` | Used when the defending Character Item also has a Melee Action. |

Parry is an animation choice, not a different damage rule. The same Shield Action performs absorption in both cases. Block does not filter by Action ID or item category, and it declines a new reaction while any Use Item Ability is active.

Use the shared **OnAnimatorItemImpactComplete** event when the animation should end the reaction, or leave event waiting off and tune the `0.2`-second duration. The Block guide covers the Animator parameter and ability-order details.

## How it runs

1. Equip activates the Shield Collider for the current perspective and disables the other perspective. Unequip disables it when **Disable On Unequip** is on.
2. A built-in Simple Damage impact checks the GameObject of its reported **Impact Collider** for **Shield Collider**.
3. Shield Action rejects protection when **Require Aim** is on but the accepted Aim state is absent, or when the source is a built-in Explosion and **Absorb Explosions** is off. The full amount then continues with no shield reaction.
4. With **Apply Impact** on, the action activates its selected State, advances the Animator/audio state set, plays audio on the visible item or character fallback, and sends `OnShieldImpact`.
5. The action applies **Absorption Factor**, subtracts the amount actually absorbed from durability, and returns the remaining damage to Simple Damage.
6. Block receives `OnShieldImpact`. A matching idle Block ability supplies Item State Index `8` for block or `9` for parry, plus the selected impact substate, then updates the Animator.
7. The configured duration or shared Animator event ends the reaction. Block calls `StopBlockImpact`, which clears the Shield Action's impact flag and deactivates its selected State.
8. At minimum durability, later hits pass through. When **Drop When Durability Depleted** is on, the item is removed and dropped when damage consumes the final value.

**Apply Impact** controls presentation, not protection. Turn it off for a shield that should absorb damage without playing a Block reaction.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the Shield Action is on the main Character Item GameObject and has a unique **ID**;
- exactly one intended Attribute Manager contains an Attribute whose name exactly matches **Durability Attribute Name**;
- every perspective's Collider and Shield Collider are on the same visible GameObject and reference this Shield Action;
- each Collider is sized and layered so attacks can report it as the **Impact Collider**;
- **Disable On Unequip** is on for ordinary held equipment;
- a Block ability exists and accepts the Character Item's slot when **Apply Impact** is on;
- the Animator implements item state `8` and/or `9`, the selected impact substate, and the chosen completion timing; and
- attackers use Simple Damage or another explicit Shield Action integration.

## Verify in Play Mode

Use a known `10`-damage hit, watch character Health and item Durability, and keep Block visible in the Ultimate Character Locomotion Inspector.

| Test | Expected result |
| --- | --- |
| **Absorption Factor** `1`, durability above `10` | Durability loses `10`; character Health loses `0`; the reaction runs when **Apply Impact** is on. |
| **Absorption Factor** `0.5`, durability above `5` | Durability loses `5`; character Health loses `5`. |
| Durability has only `3` remaining with factor `1` | Durability reaches its minimum and the remaining `7` damage reaches the character. |
| Durability is already at its minimum | The full `10` reaches the character. The impact reaction can still play because presentation is selected before the durability check. |
| **Require Aim** on | A local player is unprotected without input-started Aim and protected while holding the Aim input. |
| **Absorb Explosions** off, then on | A built-in Explosion bypasses the first test and is absorbed in the second. |
| Switch first/third person, then unequip | Only the active perspective Collider is enabled; both are disabled after unequip when configured normally. |
| Defending item also has a Melee Action | Block supplies parry state `9`; a Shield-only item supplies block state `8`. Absorption remains identical. |
| **Apply Impact** off | Damage is still absorbed, but no impact State, audio, `OnShieldImpact`, or Block reaction starts. |

Repeat the depletion test with **Drop When Durability Depleted** enabled only after the Character Item has a valid Drop Prefab and inventory setup.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The hit reaches the character instead of the shield | The reported Collider may not have Shield Collider on the same GameObject, or the wrong perspective/unequipped Collider is disabled. | Move Shield Collider onto the Collider GameObject, assign **Shield Action**, resize it, and test the active equipped perspective. |
| A custom attack ignores the shield | Shield absorption is called by built-in Simple Damage, not by Health or every damage source. | Use Simple Damage with a valid **Impact Collider**, or have the custom authoritative damage path call `ShieldAction.Damage` before applying the remainder. |
| Item Manager fails while building a first-person shield with no visible item | Released Version 3 can enter the Shield builder when only **First Person Base** exists, then tries to add Shield Collider to a null **First Person Visible Item**. | Supply a first-person visible shield object, or omit that perspective and add its Collider/Shield Collider manually after the build. |
| An updated item has two Attribute Managers or durability never decreases | Released Version 3 adds a new Attribute Manager for every newly built Shield Action instead of reusing an existing manager. Shield Action reads one manager from the Character Item. | Consolidate the values into one intended Attribute Manager, keep one exact `Durability` entry, and remove the duplicate after checking references. |
| A misspelled durability name makes the shield absorb forever | Empty and unresolved Attribute names are treated as no durability. A missing manager with a nonempty name also logs an initialization error. | Match the Attribute name exactly, or deliberately leave it empty for a non-degrading shield. |
| A non-degrading shield absorbs damage but the attacking melee item does not use its blocked recoil | `DurabilityValue` reports `0` when no Attribute is resolved, and the built-in attacker recoil test requires a value above zero. | Use a real non-depleting/high-value Durability Attribute when the attacker must recognize blocked recoil, or implement a custom recoil test. |
| A regenerating shield drops when durability becomes full | With **Drop When Durability Depleted** on, Shield Action listens to `OnAttributeReachedDestinationValue`; the Attribute sends that event at both minimum and maximum. | Do not combine built-in auto-increase with the drop toggle. Leave dropping off or restore durability through project code that checks the minimum explicitly. |
| The shield absorbs damage but Block never appears | **Apply Impact** may be off, Block may be absent or reject the slot, or Use may currently be active. | Enable **Apply Impact**, add/configure Block, test with Use idle, and verify the Animator state indexes. |
| The shield's impact State remains active | Shield Action activates it before sending `OnShieldImpact`, but only a successful Block completion calls `StopBlockImpact`. A missing/mismatched Block or a Block request rejected during Use can leave it active. | Disable **Apply Impact** when no reliable Block reaction exists, avoid requesting the reaction during conflicting Use flows, or explicitly call `StopBlockImpact` from project cleanup code. |
| Block never completes with a slot-specific event | Released Version 3's slot-event handler rejects the `-1` all-slot configuration and can index outside its one-element arrays for a nonzero fixed **Slot ID**. | Keep **Wait For Slot Event** off. Use **Duration** or the shared **OnAnimatorItemImpactComplete** event. |
| An area hit is absorbed even with **Absorb Explosions** off | The bypass checks whether **Source Component** is the built-in `Explosion` type; a positive impact radius or a custom explosion-like source is not enough. | Identify custom explosion sources before Simple Damage or route them through project code that applies the intended shield rule. |
| Missing Collider causes an exception during initialization | Shield Collider caches `GetComponent<Collider>()` and immediately controls its enabled state. | Put a Collider on the same GameObject before entering Play Mode. |
| The wrong block/parry animation plays | Block chooses parry whenever the defending Character Item also contains a Melee Action. | Remove the unintended Melee Action or configure the state `9` parry Animator path and the impact substate. |

## Saving and multiplayer boundaries

Shield configuration is serialized on the Character Item prefab or scene object. Runtime durability is an item-side Attribute value, while depletion can also change Inventory and drop state. Shield Action has no built-in save record for its current durability, selected impact state, or in-progress Block reaction. Make the chosen save integration persist and restore the relevant item Attribute and Inventory state, then resume from a neutral reaction state after load.

Shield Action and Block send local Opsive events and contain no damage-authority or replication call of their own. The multiplayer build uses the third-person Shield Collider for remote players, but the authoritative peer must still own the damage calculation, durability change, inventory removal, and drop. Replicate the resulting inventory/Attribute state and any reaction presentation required by other clients through the installed multiplayer integration or project code.

## Related tasks

- [Configure Block and parry](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/)
- [Create or update a Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)
- [Understand Character Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)
- [Configure the Character Item hierarchy](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/)
- [Configure Animator Audio State Sets](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/)
- [Configure item Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/)
- [Configure Simple Damage and other Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Configure a Melee Counter Attack](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/melee-counter-attack/)
- [Review default Animator values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/)

## Developer reference

`ShieldAction.Damage(ImpactCallbackContext ctx, float amount)` returns the amount that remains after shield absorption. `SimpleDamage` calls it when `ctx.ImpactCollisionData.ImpactCollider.gameObject` contains a Shield Collider. Custom callers must provide a complete impact context, including the source component when explosion rules matter.

Useful Shield Action members include **RequireAim**, **AbsorptionFactor**, **AbsorbExplosions**, **ApplyImpact**, **ImpactAnimatorAudioStateSet**, **ImpactCompleteEvent**, **DurabilityAttributeName**, **DropWhenDurabilityDepleted**, the read-only **DurabilityValue**, and `StopBlockImpact()`.

The reaction uses these local events:

- `OnShieldImpact` with `(ShieldAction, ImpactCallbackContext)` starts Block after the Shield Action has selected its impact state.
- `OnAimAbilityStart` with `(bool aim, bool inputStart)` updates **Require Aim** eligibility.
- `OnAnimatorItemImpactComplete` ends reactions that use the shared Animator event.
- `OnAnimatorItemImpactCompleteSlot<slotID>` is the intended slot-specific event, subject to the released-Version-3 limitation above.
- `OnInventoryEquipItem`, `OnInventoryUnequipItem`, and `OnCharacterChangePerspectives` control Shield Collider availability.

`WaitingForImpactCompleteEvent` exposes the trigger object's `IsWaiting` flag, but released Version 3 Block schedules its own duration or listens for Animator events without calling `ImpactCompleteEvent.WaitForEvent()`. Do not use that property as a reliable reaction-running indicator; inspect Block activity or maintain explicit project state instead.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-action-modules-groups"></a>

# Action Modules & Groups

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)

Action Modules let you change one stage of an item action without replacing the complete action. Use them to choose how a firearm fires, how an Iron Sword detects a hit, what an impact does, when an effect runs, or whether a use is allowed.

## Understand groups and modules

An Action Module is serialized inside a Character Item Action component; it is not another component on the item. Its Action Module Group determines which module types are valid and when they are called.

| Level | Responsibility |
| --- | --- |
| **Character Item Action** | Owns the complete operation, such as Shootable or Melee, and provides the Character Item, character, inventory, slot, and perspective context. |
| **Action Module Group** | Owns an ordered list for one stage, such as Trigger, Shooter, Collision, Impact, or Reload. The Inspector only offers module types compatible with that group. |
| **Action Module** | Implements one option in the stage. It can respond to lifecycle or action interfaces, use States and bindings, and access its owning action's context. |
| **Nested action/effect group** | Lets a module run an ordered set of Impact Actions, Impact Action Conditions, or Item Effects without turning each entry into another Action Module. |

The group owns the row order. Some stages invoke every enabled, active module that implements the requested interface. Others deliberately use the first enabled module as their main option. Order is therefore behavior, not just organization.

## Choose the right extension point

These related systems solve different problems:

| Goal | Use | Guide |
| --- | --- | --- |
| Change how an item starts, fires, collides, reloads, recoils, or performs another action stage | **Action Module** in the matching group | Continue on this page. |
| Apply damage, force, surface effects, events, or other results after a hit | **Impact Action** | [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) |
| Allow, reject, or branch an impact according to its source or target | **Impact Action Condition** | [Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/) |
| Play audio, toggle an object or light, spawn a prefab, or invoke a UnityEvent using item-action context but no hit context | **Item Effect** | [Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/) |

Use an Action Module when the logic must participate in the item's lifecycle or action sequence. Use the smaller nested types when a module only needs to execute a result or inspect an impact.

## Configure a module group

1. Select the main Character Item GameObject and open its Character Item Action component.
2. Expand the group for the stage you want to change. A Usable action always has **Trigger Action Module Group** and **Usable Action Module Group**; specialized actions add their own groups.
3. Under **Modules**, use the add control and choose a compatible module type. The type picker is constrained by the group, so a Collision module cannot be added to a Shooter group.
4. Select the new row to expose its settings below the list. A new Action Module starts **Enabled**, has an empty **Name**, and declares an **ID** default of `-1`; the released Version 3 Inspector assigns a newly added row the current last index as its ID.
5. Configure the module's required references and gameplay values. Expand **Bindings** when a property should follow an external runtime value, or **States** when named State presets should override values.
6. Drag rows to change their evaluation order. Use the row's **Enabled** toggle to keep a configuration without allowing it to participate.
7. Remove a row only after checking references to its module ID and any helper objects that its editor hook created.

![Selected Debug Use module showing ID, Name, Message, Bindings, and States in the Inspector](https://opsive.com/wp-content/uploads/2022/10/ItemActionModuleBindingsStates.png?v=252c50ea6f86)

### Understand IDs, order, and repeated types

Module IDs and row order are related when a row is first added, but they are not the same value:

- Adding through the Inspector assigns the new row's ID from its index.
- Reordering rows changes execution priority but does not renumber their IDs.
- Removing a row decrements the IDs of the rows that followed it.
- The Inspector allows more than one module of the same type when the group accepts it.
- Duplicate IDs are not rejected. `GetModuleByID` returns the first match, so keep IDs unique within a group whenever code looks modules up by ID.

Most no-code setups should select modules by their list order and type rather than editing IDs. Review IDs after a remove or reorder if project code stores them.

## Start from a built-in item

The Item Manager supplies a useful starting module set. Tailor that set instead of assembling every stage from an empty action.

| Stage | Firearm starting point | Iron Sword starting point |
| --- | --- | --- |
| Trigger | **Repeat** | **Repeat Combo** |
| Operation | **Hitscan Shooter**, **Item Ammo**, **Simple Clip**, and **Basic Projectile** | **Simple Attack** |
| Detection | Shooter and projectile configuration | **Hitbox Collision** |
| Result | **Generic Shootable Impact Module** | **Generic Melee Impact Module** |
| Feedback | **Muzzle Effect**, **Shell Effect**, **Recoil Effect**, and **Crosshairs Spread** | Attack, recoil, Animator/audio, and impact configuration |
| Follow-up | **Generic Reloader**, dry-fire effects, and slot monitoring | **Simple Recoil** and the next combo state |

For a firearm, first decide whether the shooter is hitscan or projectile based, then configure ammunition, clip, fire effects, impact, and reload around that choice. For an Iron Sword, confirm the hitbox belongs to the visible blade, then configure attack timing, impact results, recoil, and combo behavior.

Adding a second module does not automatically make it a fallback. Check how that group consumes its list: a main-module group may only use the first enabled row, while an interface-driven stage may invoke every matching enabled, active row.

## Use States and bindings

Every Action Module derives from the State and binding system:

- **States** apply serialized preset overrides while a named State is active. Use them for choices such as an alternate damage value, fire rate, effect, or enabled configuration.
- **Bindings** update a module property from an external runtime source. The built-in Attribute binding needs an Attribute Manager, an Attribute name, and a valid property path on the module.
- **Enabled** remains the basic participation gate. A module may also report inactive when its own rules require it to be the first enabled module.

In Play Mode the Inspector adds a status icon to each module row. Use its tooltip to distinguish **Active and Enabled**, **Enabled but Inactive**, and disabled states before changing gameplay values.

## Configure nested impact and effect lists

Impact Actions, conditions, and Item Effects use similar ordered Inspector lists, but their defaults and context differ.

### Impact Actions

An Impact Action starts **Enabled**, with **Delay** `0` and **Allow Multi Hits** disabled. The group invokes entries in list order. Each entry receives an `ImpactCallbackContext`: collision data is required and describes the source, target, hit, direction, strength, and related objects; damage data is optional.

With **Allow Multi Hits** disabled, one source ID cannot invoke the same Impact Action repeatedly on the same target until the group is reset. This is useful for casts that overlap the same collider across frames. A delayed action keeps a duplicate of the context until it runs and releases it during cleanup.

### Impact Action Conditions

Every enabled condition in a condition group must pass. A disabled condition is ignored. A **Conditional Impact Action** can run one Impact Action group on pass and another on failure; **Reset Damage Data On Fail** clears optional damage data before later processing continues.

Use source category or definition conditions when, for example, only an Iron Sword or only the Weapon category should damage a target. Use the target condition behavior when each target should own its acceptance rules.

### Item Effects

An Item Effect starts **Enabled** with **Delay** `0`. It receives the Character Item Action context but no collision context. The **Generic Item Effects** module can invoke its effect list at start use, use, use update, or use complete according to its toggles.

Choose Item Effects for feedback or simple item-side results. Choose Impact Actions when the result needs a hit target, damage data, surface information, or multi-hit control.

## How it runs

1. The Character Item Action collects its module groups in their declared order and assigns each group a runtime ID from that order.
2. Every module is initialized with its owning action and group, including disabled modules. This gives it access to the Character Item, character, Inventory, Slot ID, perspective, and installed network bridge before action execution begins.
3. Each group caches its enabled and disabled rows in list order. Changing **Enabled** in Play Mode refreshes those caches.
4. Pickup, equip, start-unequip, unequip, removal, and destruction notifications pass through the action to its modules. The base module registers runtime listeners only while it is both enabled and equipped.
5. During an action, the Character Item Action invokes modules by interface. Disabled modules are skipped; modules whose active rule fails are skipped; matching active modules run in group and row order unless the action explicitly asks for the first enabled option.
6. A collision module can pass an `ImpactCallbackContext` to an Impact Action group. Conditions inspect that context, then enabled Impact Actions run in order or after their configured delay.
7. A Generic Item Effects module invokes its enabled Item Effects at the configured use stage. Delayed built-in effects and impacts cancel scheduled work during destruction.

Do not call lifecycle hooks directly from ordinary gameplay code. Let the Character Item Action and its Item Ability coordinate them so equip state, Animator timing, interruption, and multiplayer integration remain consistent.

## Editor checkpoint

Before entering Play Mode, verify all of the following:

- Every module is in a compatible group and the intended main module is the first enabled row where that stage uses one main option.
- Repeated module types are deliberate, and no group contains duplicate IDs used by project code.
- Required first- and third-person locations, colliders, projectiles, attributes, audio, effects, and Item Identifiers are assigned.
- States have the intended presets and activation names. Bindings reference a valid source and writable module property.
- Impact lists place modifiers and conditions before the results that depend on them.
- **Allow Multi Hits**, **Delay**, and **Reset Damage Data On Fail** match the desired hit behavior.
- Animator/audio state sets and use events match the clips and event timing used by the item.

## Verify in Play Mode

1. Equip the item and confirm the intended module rows report active and enabled.
2. For a firearm, fire once with ammunition and once with an empty clip. Confirm the main Trigger, shooter, ammo, clip, fire or dry-fire effects, impact, and reload stages each produce the expected result.
3. For an Iron Sword, swing across one target and keep the hitbox overlapping for several frames. Confirm the attack produces the intended single impact when multi-hit is disabled and can hit again after the action resets.
4. Activate each relevant State or change the bound source. Confirm the visible module value and gameplay result change together.
5. Disable one feedback module at runtime. The action should continue without that module's audio, visual, recoil, or other contribution.
6. Unequip and re-equip. Event-driven modules should not react while unequipped and should register again after equip.
7. In multiplayer, repeat the visible result as owner and remote observer. Verify each custom effect, spawned object, and damage result that other peers must see is explicitly synchronized.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The desired type does not appear in the add menu | The selected Action Module Group | Add it to a group whose declared module base type accepts it, or create a wrapper module for that group. |
| The configured module never runs | **Enabled**, Play Mode status icon, State overrides, and list order | Enable it, make its controlling State valid, and move it before another module when the stage uses the first enabled row. |
| Two copies of a module produce duplicate results | Repeated types and whether the stage invokes every matching interface | Remove or disable the unintended row. Keep multiple copies only when both results should run. |
| Custom code retrieves the wrong module | Duplicate module IDs | Assign unique IDs within that group. ID lookup returns the first matching row. |
| Project code stops finding a module after list edits | IDs after remove or reorder | Review stored IDs. Removal decrements later IDs; reordering changes row priority without changing IDs. Prefer type-based lookup when a stable numeric contract is unnecessary. |
| A firearm or throwable prefab has empty fire, muzzle, throw, trajectory, or hitbox references | Whether the module was added to a GameObject that is part of a prefab | Released Version 3's built-in editor hooks do not automatically create those helper objects on prefab assets or instances. Add the locations or colliders manually and assign both perspective values, or configure a non-prefab item through Item Manager before saving it as a prefab. |
| A hit occurs but damage or an effect does not | Impact context, enabled conditions, action order, and optional damage data | Inspect the context with a debug Impact Action, correct the failed condition, and place modifiers before actions that consume their result. |
| The same cast never hits the target again | **Allow Multi Hits** and the source-ID reset point | Enable multi-hit only when repeated hits are intended, or ensure the owning collision/action module resets its Impact Action group between attacks. |
| A delayed custom result survives cleanup | The custom type's `OnDestroy` implementation | Cancel scheduled work and call the base cleanup where applicable. Built-in delayed Impact Actions and Item Effects already cancel their scheduled callbacks. |
| A custom result appears only for the owning player | Network authority and replication | Use the installed network bridge where the built-in module supports it, and explicitly synchronize project-specific damage, spawned objects, UnityEvents, and mutable state. |

## Saving and multiplayer boundaries

Module, State, binding, Impact Action, condition, and Item Effect configuration is serialized with the Character Item scene object or prefab. Runtime module values, delayed work, hit history, custom counters, and other transient state are not a general save record. Add explicit save/restore support for custom runtime data that must survive loading.

When multiplayer support is compiled, an Action Module can access the owning action's network information and network inventory bridge. The base module's `NetworkSync` value defaults to false, and serializing a module does not replicate its behavior. Built-in modules synchronize only the paths implemented by the installed integration; custom effects and state need a deliberate authority and replication design.

## Related tasks

- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) explains action IDs, Item Ability selection, and the complete action lifecycle.
- [Usable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) explains the common Trigger and Usable groups and their start/use/complete sequence.
- [Shootable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) covers firearm-specific module groups.
- [Melee](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) covers attack, collision, impact, and recoil groups for an Iron Sword.
- [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/) explains animation and audio selection used by many trigger and feedback modules.

## Developer reference

Choose the narrowest group base class and lifecycle interface for a custom module. For example, a Usable module that runs at the use point can implement `IModuleUseItem`:

```csharp
[Serializable]
public class DebugUse : UsableActionModule, IModuleUseItem
{
    [Tooltip("The message to print when the item is used.")]
    [SerializeField] private string m_Message = "Item used";

    public void UseItem()
    {
        Debug.Log(m_Message, CharacterItemAction);
    }
}
```

The type must be serializable for its fields to appear and persist. Use `InitializeInternal` for cached references, `UpdateRegisteredEventsInternal` for listeners that should exist only while enabled and equipped, and the pickup/equip/unequip/remove/destroy hooks only when that lifecycle stage is required. If one implementation must appear in several incompatible groups, keep the shared logic in a separate class and add a small group-specific module wrapper for each supported group.

`CharacterItemAction.GetFirstActiveModule<T>()` returns the first enabled, active match across groups. `InvokeOnModulesWithType<T>()` invokes every enabled, active module implementing the requested interface in group and row order. A group also exposes `GetModuleByID`, but IDs should remain unique when using that lookup.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-action-modules-groups-impact-actions"></a>

# Impact Actions

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)

Impact Actions turn one reported hit into gameplay results such as damage, force, particles, audio, states, or callbacks. Use an ordered Impact Action Group on a melee, shootable, throwable, or magic module so an Iron Sword, firearm, or explosion produces the same deliberate result every time.

## Configure an Impact Action Group

1. Select the Character Item and expand the module that reports the hit.
2. Expand **Impact Actions**. Use **Fail Impact Actions** only when the module's condition list needs a separate rejected-hit result.
3. Add actions with the **+** button and drag them into execution order.
4. Put gameplay changes first, presentation second, and callbacks last. A typical firearm order is **Simple Damage**, **Spawn Surface Effect**, **Spawn Particle** or **Play Audio Clip**, then **Impact Event**.
5. Configure the fields that the chosen action actually uses. An action with zero force, no prefab, an empty state name, or no event listener may run successfully without producing a visible result.

![Impact Action Group containing Simple Damage, Spawn Surface Effect, State Impact, and Impact Event, all enabled with zero delay](https://opsive.com/wp-content/uploads/2022/10/ImpactActionGroupInspector.png?v=f92f5b42d868)

The legacy Inspector image remains accurate for released Version 3. The list is configurable; it is not the default group created by current source.

## Shared controls and ordering

Most actions expose the same controls before their type-specific fields:

| Field | Default | Behavior |
| --- | --- | --- |
| **Enabled** | On | A disabled action is skipped. |
| **Delay** | `0` seconds | Zero runs immediately. A positive value schedules that action independently. |
| **Allow Multi Hits** | Off | When the caller honors repeat tracking, the action remembers each target by **Source ID** until that ID is reset. |
| **Bindings** and **States** | Empty/default | Optional property bindings and State System overrides inherited by the action. |

An Impact Action Group visits its actions from top to bottom. Immediate actions share the same mutable `ImpactCallbackContext`, so an earlier action or callback can affect what a later action reads. A delayed action takes its own pooled snapshot when its row is reached; the group does not wait for it, and later zero-delay rows can finish first. Use **Delay** as timing, not as a sequencing guarantee.

**Allow Multi Hits has an important released-Version-3 boundary:** the built-in generic Melee, Shootable, Throwable, and Magic impact modules call their groups with forced impact enabled. Their actions therefore bypass the repeat suppression even when **Allow Multi Hits** is off. Use the module's hit detection/cooldown rules for those standard weapon flows. The toggle still matters for callers that pass forced impact as false, including receiver, nested conditional, and custom flows.

## Choose actions by outcome

Released Ultimate Character Controller Version 3 provides 17 concrete Impact Action types. The catalog below covers every one.

### Apply damage, healing, attributes, or states

**Simple Damage**

Use **Simple Damage** for a firearm hit, Iron Sword strike, or explosion that should affect an `IDamageTarget` and optionally push a non-damageable physics object.

| Field | Default | Meaning |
| --- | --- | --- |
| **Use Context Data** | Off | When on and `ImpactDamageData` exists, reads its processor, damage, force, force frames, and radius instead of the local values. |
| **Set Damage Impact Data** | On | Displayed in the Inspector, but released Version 3 does not read this field or write damage data from it. |
| **Invoke On Object Impact** | Off | Sends `OnObjectImpact` callbacks to the hit collider object, its distinct Rigidbody object, and the restored target when applicable. |
| **Damage Processor** | None | Uses `DamageProcessor.Default` when no local or context processor is supplied. |
| **Damage Amount** | `10` | Local damage before shield and optional strength scaling. |
| **Impact Force** | `2` | Force magnitude multiplied by **Impact Strength**. |
| **Impact Force Frames** | `15` | Character force duration. |
| **Impact Radius** | `0` | A positive radius changes Rigidbody force to explosion force. |
| **Scale Damage By Impact Strength** | Off | Multiplies damage by **Impact Strength**; useful for explosion falloff. |

The action lets a `ShieldCollider` adjust the damage, resolves an `IDamageTarget`, then uses a source `DamageProcessorModule`, the selected **Damage Processor**, or the default processor. When no damage target exists, it applies force to a parent `IForceObject` or the reported non-kinematic Rigidbody.

Supply a valid **Impact Collider**. The released action reads its GameObject during the shield check even when the hit has no shield.

In released Version 3, **Set Damage Impact Data** is serialized but unused. Populate `ImpactDamageData` in the source module/custom context when later actions need shared values, or leave **Use Context Data** off and use this action's local fields.

When **Invoke On Object Impact** is enabled and the original target is also the collider's attached Rigidbody GameObject, that GameObject can receive the callback once as the Rigidbody and again as the restored target. Prefer a single **Impact Event** target callback when a receiver must run exactly once.

**Heal**

**Heal** searches the target and then its parents for `Health`.

- **Amount** defaults to `10`.
- **Interrupt Impact On Null Health** defaults to on.

When Health is missing or refuses the heal, released Version 3 emits the source event named `ImpactInteruptedCallback`. The Impact Action Group itself does not stop and the package contains no built-in listener that stops later rows. Put **Heal** last when later actions must not run on failure, or use a condition/custom flow to select the result.

**Modify Attribute**

**Modify Attribute** searches the target's parents for an `AttributeManager`, clones the configured modifier from a pool, and changes the named attribute.

| Attribute Modifier field | Default |
| --- | --- |
| **Attribute Name** | Empty |
| **Amount** | `0` |
| **Auto Update** | Off |
| **Auto Update Start Delay** | `1` second |
| **Auto Update Interval** | `0.1` seconds |
| **Auto Update Duration** | `-1` |

An empty or unknown name does nothing. For a one-time stamina, mana, or shield change, leave **Auto Update** off. Released Version 3 registers timed modifier cleanup with `OnAttributeModifierAutoUpdateEnable` but the modifier emits `OnAttributeModifierAutoUpdateEnabled`; positive-duration auto updates therefore miss the cleanup callback. Use an immediate change here or a purpose-built timed attribute workflow until that package behavior is corrected.

**State Impact**

**State Impact** activates a State on the character root containing the target, or on the target itself when it is not part of an Ultimate Character Locomotion object.

- **Use Context Data** defaults to off.
- **Impact State Name** defaults to empty.
- **Impact State Disable Timer** defaults to `10` seconds. Set it to `-1` for manual deactivation.

When **Use Context Data** is on and damage data exists, both the name and timer come from that data. An empty context state name does not fall back to the local name.

**Character Knock Back**

**Character Knock Back** finds the target's parent Ultimate Character Locomotion and starts its **Impact Knock Back** ability.

- **Impact Knock Back ID** defaults to `0` and selects the response animation/configuration.

It does nothing when the target is not a character or does not have the ability.

### Apply physical motion

**Add Force**

**Add Force** prefers the target's parent Ultimate Character Locomotion, then a parent `IForceObject`, then the reported non-kinematic Rigidbody.

| Field | Default |
| --- | --- |
| **Use Source Direction** | Off |
| **Amount** | `(0, 0, 0)` |
| **Frames** | `5` |
| **Mode** | `Force` |
| **Add Force At Position** | Off |

With **Use Source Direction** off, the action scales **Amount** component-by-component with **Impact Direction**. With it on, it transforms **Amount** through the source GameObject. In both cases **Impact Strength** scales the amount. When context damage data has a positive **Impact Radius**, the Rigidbody path uses the squared magnitude of the strength-scaled **Amount** as explosion force and does not use **Mode** or **Add Force At Position**.

**Frames** applies to character and `IForceObject` paths. **Mode** and **Add Force At Position** apply only to the ordinary, non-explosion Rigidbody path.

**Add Torque**

**Add Torque** applies angular force with:

- **Amount** `(0, 0, 0)` by default.
- **Mode** `Force` by default.

Unlike **Add Force**, it looks for a Rigidbody directly on **Impact GameObject**, does not use the reported **Impact Rigidbody**, and does not scale by **Impact Strength**. Place the Rigidbody on the reported target or use a custom action when the collider reports a child object.

### Spawn surface, visual, and audio feedback

**Spawn Surface Effect**

**Spawn Surface Effect** asks the Surface Manager to select the configured effect for the hit.

- **Use Context Data** defaults to off.
- **Surface Impact** defaults to None.

When context use is enabled, a non-null context **Surface Impact** overrides the local asset; otherwise the local value is the fallback. The action uses the collision's `RaycastHit`, the source character's gravity and time scale, and the visible source item or source GameObject as originator. It suppresses a non-shield surface effect when context damage is exactly zero.

Supply a valid `RaycastHit`; a context built only from **Impact Position** is not sufficient. Also supply **Impact Collider** when context damage exists with an amount of zero, because the released suppression check reads that collider.

**Spawn Particle**

**Spawn Particle** creates a pooled particle at **Impact Position**, oriented along **Impact Direction**.

| Field | Default |
| --- | --- |
| **Particle Prefab** | None |
| **Position Offset** | `(0, 0, 0)` |
| **Rotation Offset** | `(0, 0, 0)` |
| **Parent To Impacted Object** | Off |

The prefab must contain a `ParticleSystem`. A looping particle is cached per **Source ID**, repositioned on another invocation with that ID, and stopped when the action is reset. Provide a nonzero impact direction so the rotation is well-defined.

**Play Audio Clip**

**Play Audio Clip** contains one **Audio Clip Set**, which can reference an **Audio Config** or an **Audio Clips** list and selects a random clip from that set. A newly added set has no selected config or clips.

Released Version 3 plays at `RaycastHit.point`, not **Impact Position**. This works for normal raycast firearm/melee contexts. For a manually constructed explosion or trigger context without a valid raycast, use a custom audio action at **Impact Position** or supply a valid hit.

**Generic Item Effects**

**Generic Item Effects** owns one **Effect Group** and invokes each configured Item Effect. It does not pass the impact context into those effects. Use it when an existing item effect already expresses the feedback or item-side change; see the separate Item Effects catalog rather than duplicating that configuration here. The group is initialized against the owning Character Item Action, so effects that require an item owner are not suitable for a context with no item action.

### Send callbacks or debug the result

**Impact Event**

**Impact Event** sends Opsive events through the impact context:

- **Call Impact Callback On Originator** defaults to on and sends `OnObjectImpactSourceCallback` to **Source GameObject**.
- **Call Impact Callback On Target** defaults to on and sends `OnObjectImpact` to **Impact GameObject**.

The originator callback runs first. Put this action after damage and feedback when listeners should observe the completed immediate result. A target-side **Conditional Impact Receiver** depends on the target callback.

A missing source or target logs a warning and skips that callback.

**Impact Unity Event**

**Impact Unity Event** exposes one **On Impact Event** UnityEvent carrying the full `ImpactCallbackContext`. It starts with no persistent listeners. Use it for a local Inspector connection; use **Impact Event** when source or target components listen through the Opsive event system.

**Debug Impact Context**

**Debug Impact Context** has one **Message** field, empty by default. It logs that message followed by the complete context. Place it before and after a suspicious row to compare shared data; remove it from shipping configurations that should not log every impact.

### Branch, reuse, or create secondary hits

**Conditional Impact Action**

**Conditional Impact Action** contains **Conditions**, **Impact Actions On Pass**, **Impact Actions On Fail**, and **Reset Damage Data On Fail** (off by default). Conditions are ANDed and the action invokes exactly one nested group. The fail group is invoked before optional damage-data reset. See [Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/) for the complete condition catalog and released-Version-3 branch details.

**Use Impact Action Object**

**Use Impact Action Object** references one **Impact Action Object**, None by default. An `ImpactActionGroupObject` is a ScriptableObject containing a reusable group; create one with **Assets > Create > Opsive > Impact > Impact Action Group Object**. A new asset contains **Simple Damage**, **Spawn Surface Effect**, and **Impact Event**, with the first two configured to read context data.

In released Version 3 the wrapper overrides `TryInvokeOnImpact` and directly calls the asset. Its own displayed **Enabled**, **Delay**, and **Allow Multi Hits** values are not honored. Configure those controls on the actions inside the asset. The asset also owns one stateful set of action instances and reinitializes it for each call, so repeat maps, delayed work, and binding ownership are not isolated between simultaneous users. Use separate runtime assets/instances or a custom cloned group when concurrent characters require isolated state.

**Ricochet**

**Ricochet** finds nearby colliders and raises its C# `OnRicochet` event for each eligible secondary target.

| Field | Default |
| --- | --- |
| **Radius** | `10` |
| **Max Chain Count** | `1` (`-1` disables the limit) |
| **Max Collision Count** | `50` |
| **Merge Data Layers** | On |
| **Detect Layers** | Nothing |

With **Merge Data Layers** on, the local mask is ORed with the context's **Detect Layers**. With it off, a default Nothing mask finds nothing. Queries ignore trigger colliders and use a preallocated array sized by **Max Collision Count**.

The action centers its query on `RaycastHit.point` and raises data; it does not itself cast the next hit. In the released package, the built-in subscriber is the Magic **Ricochet Impact** module. A firearm needs a custom subscriber or its own ricochet module to turn that event into another shot. The implementation also accesses the owning Character Item Action while processing candidates without a null guard, so use this built-in only with an item action owner.

## Scenario recipes

### Firearm hit

1. Use **Simple Damage** with **Use Context Data** on when the shootable module supplies the shot's damage and force.
2. Add **Spawn Surface Effect** with context use on for material-specific feedback.
3. Add **Spawn Particle** for a dedicated impact particle, or **Play Audio Clip** when the hit has a valid raycast.
4. Add **Impact Event** last when the target or source needs a callback.

### Iron Sword strike

1. Use **Simple Damage** for health and force.
2. Add **State Impact** when the target should briefly enter a named hit state.
3. Add **Character Knock Back** only when the target character has the matching ability and ID.
4. Add audio/surface feedback, then **Impact Event**.

Use [Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/) when only selected definitions, categories, or targets should take the pass result.

### Explosion

1. Set **Simple Damage > Impact Radius** to a positive value, or enable **Use Context Data** and supply a positive context radius.
2. Enable **Scale Damage By Impact Strength** when the explosion creator supplies falloff as **Impact Strength**.
3. Set **Impact Force** and verify the reported **Impact Rigidbody** or damage target receives it.
4. Add a non-looping **Spawn Particle**. For positional audio from a manually built context, avoid the built-in **Play Audio Clip** raycast-point limitation.

Do not add **Add Force** merely to duplicate the force already applied by **Simple Damage** unless the extra push is intentional.

## Editor checkpoint

Before entering Play Mode, confirm that:

- every action needed for the result is enabled and has a visible, nonzero or assigned value;
- data-dependent actions agree on **Use Context Data** and the source actually supplies `ImpactDamageData`;
- damage actions have a valid **Impact Collider** and every action has a valid **Impact GameObject**;
- **Impact Event** is after immediate gameplay actions when listeners need the final result;
- surface/audio actions have a valid `RaycastHit`, while particles have a valid position and nonzero direction;
- looping particles and repeat-sensitive custom callers reset the same **Source ID** they used for the hit; and
- shared Impact Action Group Objects are not unintentionally serving concurrent owners with stateful actions.

## Verify in Play Mode

Use one known damageable target, one plain Rigidbody, and one target without the expected component.

| Test | Expected result |
| --- | --- |
| Firearm hits the damageable target | Health changes once per module hit, feedback appears at the raycast hit, then callbacks run. |
| Iron Sword hits the character | Damage applies; the configured State or knock-back response appears only when its requirement exists. |
| Explosion reaches near and far targets | Positive radius produces explosion force; strength-scaled damage is lower where the source supplies lower strength. |
| Same group hits a plain Rigidbody | Damage is skipped, but configured force/particle feedback still uses the reported physics data. |
| Heal or Modify Attribute hits a target without its component | No value changes; later rows still run unless the flow explicitly branches. |
| An action has a positive Delay | Later zero-delay rows run first; the delayed result uses its scheduled snapshot. |

Add **Debug Impact Context** temporarily when the observed position, target, source, strength, or optional damage data differs from the expected row.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| **Allow Multi Hits** off still permits repeated standard weapon hits | Generic Melee, Shootable, Throwable, and Magic modules force invocation. | Control repeats in the module's hit detection/cooldown, or use a custom caller that passes forced impact as false. |
| A delayed action sees damage data even though the original context had none | Delayed copies always obtain a pooled `ImpactDamageData`; copying null leaves that object at its current/default values. | Supply explicit damage data before scheduling, or keep actions that depend on optional-null semantics at **Delay** `0`. |
| **Set Damage Impact Data** changes nothing | The Simple Damage field is unused in released Version 3. | Supply context damage data from the source or use local Simple Damage fields. |
| A Conditional Impact Receiver runs twice for one Simple Damage hit | **Invoke On Object Impact** can notify the same attached Rigidbody and restored target twice. | Disable that field and use one **Impact Event** target callback when exactly-once delivery is required. |
| Heal failure does not stop later actions | **Interrupt Impact On Null Health** only emits `ImpactInteruptedCallback`; the group keeps iterating. | Put Heal last or select the result with a condition/custom group. |
| Timed Modify Attribute cleanup never completes | The registered and emitted event names differ by the `d` suffix. | Use an immediate modifier here or implement the timed change outside this action. |
| Audio plays at the world origin | **Play Audio Clip** uses `RaycastHit.point`. | Supply a valid hit or use a custom action at **Impact Position**. |
| Surface effect throws or appears at the wrong point in a manual context | **Spawn Surface Effect** reads **Impact Collider** and `RaycastHit`. | Initialize both values or use a context-appropriate custom effect. |
| Torque does nothing on a child collider | **Add Torque** checks only a Rigidbody directly on **Impact GameObject**. | Report the Rigidbody GameObject as target or use a custom action based on **Impact Rigidbody**. |
| **Use Impact Action Object** ignores its wrapper controls | Its override bypasses base action gating and timing. | Configure the contained actions or use a custom wrapper. |
| Ricochet finds targets but creates no new firearm shots | Only the Magic Ricochet Impact module subscribes in the released package. | Add a firearm-specific subscriber/module. |
| Ricochet throws in a non-item custom context | Candidate processing reads the owning Character Item Action without a null guard. | Invoke it with a valid Character Item Action or implement a context-safe custom ricochet. |
| A particle logs an error | **Particle Prefab** is missing or lacks `ParticleSystem`. | Assign a compatible pooled particle prefab. |

## Related tasks

- [Configure Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/)
- [Configure Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/)
- [Organize Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)
- [Configure a Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/)
- [Configure a Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/)
- [Configure a Damage Processor](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/)
- [Configure Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)
- [Configure Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/)
- [Configure States](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

### Impact callback data

Every action receives an `ImpactCallbackContext` containing:

- the owning **Character Item Action**, when one exists;
- required `ImpactCollisionData`; and
- optional `IImpactDamageData` for values supplied by a weapon, explosion, or custom source.

Current collision data includes **Source ID**, **Detect Layers**, `RaycastHit`, **Impact Position**, **Impact GameObject**, **Impact Rigidbody**, **Impact Collider**, **Impact Direction**, **Impact Strength**, damage target/source, source component/GameObject/character/item action, hit count/colliders, and **Surface Impact**. The old `SourceOwner` and `SourceRootOwner` fields are not members of released Version 3 `ImpactCollisionData`.

`IImpactDamageData` carries **Layer Mask**, **Damage Processor**, **Damage Amount**, **Impact Force**, **Impact Force Frames**, **Impact Radius**, **Impact State Name**, **Impact State Disable Timer**, and **Surface Impact**. The built-in actions consume only their documented subsets; in particular, the damage-data **Layer Mask** does not by itself filter **Simple Damage**.

A new `ImpactDamageData` uses damage `10`, force `2`, force frames `15`, radius `0`, an empty state name, state timer `10`, and no processor or surface. Its initial layer mask excludes Ignore Raycast, Water, SubCharacter, Overlay, and Visual Effect, but released built-in Impact Actions do not use that mask as a Simple Damage gate.

For positive **Delay**, the action duplicates collision and damage data from generic pools, schedules the duplicate, and returns it after invocation. Destroying the action cancels outstanding schedules and returns their contexts. Resetting a **Source ID** clears repeat tracking but does not cancel an already scheduled action.

### Create a custom action

Mark the class serializable, derive from `ImpactAction`, and override `OnImpactInternal`. The base class supplies enabled/timing/repeat handling unless you override `TryInvokeOnImpact`.

```csharp
using System;
using Opsive.UltimateCharacterController.Items.Actions.Impact;
using UnityEngine;

[Serializable]
public class LogImpactTarget : ImpactAction
{
    [SerializeField] private string m_Label = "Impact";

    protected override void OnImpactInternal(ImpactCallbackContext ctx)
    {
        var collision = ctx.ImpactCollisionData;
        Debug.Log($"{m_Label}: {collision.ImpactGameObject} at {collision.ImpactPosition}");
    }
}
```

Use `ImpactActionGroup.Initialize` before invoking a group that you own in custom code. Call `OnImpact(context, forceImpact)` with forced impact false when the contained actions should enforce their repeat maps, call `Reset(sourceID)` when that cast/use cycle ends, and call `OnDestroy()` so delayed contexts and nested resources are released.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-action-modules-groups-impact-action-conditions"></a>

# Impact Action Conditions

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/)

Impact Action Conditions let an item accept, reject, or branch an impact before it applies damage, effects, or target reactions. Use them when an Iron Sword should affect only particular targets, a firearm should react differently to projectile and non-projectile impacts, or the target should own the rule.

## Choose where the rule belongs

| Goal | Use | Why |
| --- | --- | --- |
| Choose different actions on the attacking item | **Conditional Impact Action** | The source evaluates one condition list, then runs either its pass or fail actions. |
| Let each target decide whether the source may affect it | **Impact Condition Behaviour** on the target plus **Check Target Impact Condition Behaviour** on the source | One sword or firearm can respect different target-owned rules without listing every target on the item. |
| Let the target run its own pass or fail response | **Conditional Impact Receiver** on the target | The target receives the impact callback, evaluates its rules, and owns both result branches. |
| Gate an entire impact module | The module's **Conditions** list | Melee, shootable, throwable, and magic impact modules use the same condition-group behavior. |

Conditions in one list are combined with **AND**. Put the cheapest, most general test first so a failed test can stop the remaining checks.

## Branch actions on the source

Add **Conditional Impact Action** to an Impact Actions list when the item should choose what happens next.

1. Add the required entries to **Conditions**.
2. Add damage or other successful results to **Impact Actions On Pass**.
3. Add feedback for a rejected impact to **Impact Actions On Fail**. This list may be empty.
4. Enable **Reset Damage Data On Fail** only when later actions in the surrounding list must not reuse damage data prepared before this branch. It is disabled by default.

![Conditional Impact Action with Check Target Impact Condition Behaviour, Simple Damage on pass, and Play Audio Clip on fail](https://opsive.com/wp-content/uploads/2023/04/Unity_sMg1BzE06v.png?v=8e4ef841787a)

The fail branch is invoked before **Reset Damage Data On Fail** clears the damage data. With the Conditional Impact Action's default **Delay** of `0`, the reset therefore affects later sibling Impact Actions, not the actions already invoked inside the fail branch. If the Conditional Impact Action itself has a delay, outer actions can run before the delayed branch and reset. A failed condition selects the fail branch; it does not stop later actions in the outer Impact Actions list.

## Put reusable rules on the target

Use **Impact Condition Behaviour** when a target should describe what is allowed. For example, a reinforced crate can accept only an Iron Sword definition while another crate accepts the broader weapon category.

1. Add **Impact Condition Behaviour** to the hit GameObject or its Rigidbody GameObject.
2. Add one or more entries to **Impact Action Conditions**.
3. On the weapon's condition list, add **Check Target Impact Condition Behaviour**.

The released Version 3 Inspector below shows the definition condition before its **Item Definitions** list is populated. Add at least one definition before testing a whitelist.

![Impact Condition Behaviour with an enabled Check Weapon Source Definition condition and an empty Item Definitions list](https://opsive.com/wp-content/uploads/2023/04/Unity_c2qdTX1nFn.png?v=1ae5cd720939)

**Check Target Impact Condition Behaviour** first looks on the reported impact GameObject, then on the impact Rigidbody GameObject. If neither has an `ImpactConditionBehaviourBase`, the check passes. It does not require every target to have the component and it does not search an arbitrary parent or child hierarchy.

### Let the target own the result

Use **Conditional Impact Receiver** when the target should run the result instead of merely approving a source-owned action.

1. Add **Conditional Impact Receiver** to the target.
2. Leave **Get Impact Conditions On Object** enabled to include other `IImpactCondition` components on the same GameObject. Add external components to **Impact Conditions Behaviours** only when needed.
3. Add local entries to **Impact Action Conditions**.
4. Configure **Impact Actions On Pass**, **On Object Impact Success**, **Impact Actions On Fail**, and **On Object Impact Fail**.
5. Make the attacking item send the target callback. An **Impact Event** does this when **Call Impact Callback On Target** is enabled; **Simple Damage** does it only when **Invoke On Object Impact** is enabled.

![Conditional Impact Receiver running Simple Damage on pass and separate success and fail events](https://opsive.com/wp-content/uploads/2023/04/Unity_HxGBQs8MH6.png?v=3a9943683492)

All discovered, assigned, and local conditions must pass. Do not assign the same behavior explicitly when **Get Impact Conditions On Object** already discovers it on the receiver GameObject, or the receiver will evaluate it twice.

## Built-in condition catalog

Every built-in condition has **Enabled**, **Bindings**, and **States**. **Enabled** defaults to on; turning it off makes that entry pass so the group ignores it.

### Respect target-owned rules

**Check Target Impact Condition Behaviour** has no additional fields. It evaluates an `ImpactConditionBehaviourBase` on the impact GameObject or, as a fallback, the impact Rigidbody GameObject. If no behavior is found, it returns true.

Use it on an Iron Sword or firearm when each target should define its own accepted weapon categories, definitions, or custom rules.

### Match a target by Object Identifier

**Object Identifier Impact Condition** accepts an impact only when it finds an `ObjectIdentifier` with the configured **Target ID**:

- **Target ID** defaults to `-1`, which matches nothing.
- **Search In Children** defaults to enabled. It searches the reported target and its children, including inactive children. Disable it to search the target and its parents instead.

This condition identifies the **target**, not the weapon or projectile source. In released Version 3 it forces an ID search, so assigning only the object-reference half of **Target ID** does not satisfy the condition. Add an `ObjectIdentifier`, give it the matching numeric ID, and choose the correct search direction.

### Filter by the source item

**Check Weapon Source Category** compares the source Character Item with **Item Categories**. Membership includes definitions inherited by a selected category.

- **Allow Non Weapon Impact** defaults to disabled. Enable it when impacts without a Character Item Action should pass.
- **Exclude Category** defaults to disabled. Disabled makes the list a whitelist: a matching category passes. Enabled makes it a blacklist: a matching category fails and a nonmatching category passes.
- **Item Categories** starts empty. With the default whitelist behavior, an empty serialized list accepts no weapon item.

Use a category rule when several definitions should share the result, such as every item in a melee-weapon category.

**Check Weapon Source Definition** applies the same logic to **Item Definitions** and inherited definition membership. Use it for a precise rule such as accepting Iron Sword but not every melee weapon.

- **Allow Non Weapon Impact** defaults to disabled.
- **Exclude Category** defaults to disabled and controls include-versus-exclude behavior.
- **Item Definitions** starts empty.

In released Version 3 the definition condition's include/exclude field is labeled **Exclude Category** even though it filters definitions. Treat that label as **Exclude Definition**; this is an Inspector-label mismatch, not a category filter.

### Filter projectile impacts

**Projectile Impact Action Condition** checks for a `Projectile` component directly on the impact context's source GameObject.

| Desired result | Allow Non Projectile Impact | Allow Projectile Impact |
| --- | --- | --- |
| Projectiles only | Off | On |
| Non-projectile impacts only | On | Off |
| Both | On | On |
| Neither | Off | Off |

Both fields default to off, so an unconfigured condition rejects every impact. The built-in check does not search the source's parents or children.

## Filters that need a different setup

Released Version 3 has no built-in Impact Action Condition for a layer, attribute, or surface. Use the closest source-owned setting when it expresses the rule, or add a custom condition when the decision must occur in this list.

| Filter | Practical choice |
| --- | --- |
| Target layer | Prefer the attack module's collision/detection layer controls so unwanted objects are never reported. A custom condition can instead inspect the layer of `ImpactGameObject`. `DetectLayers` in the context is the mask used for detection, not the target's layer. |
| Target attribute | Use a custom condition to find the target's attribute component from `ImpactGameObject` and evaluate the required value. |
| Surface | Use a custom condition to inspect `ImpactCollisionData.SurfaceImpact`. Surface-based effects do not by themselves accept or reject an impact. |
| Target identity | Use **Object Identifier Impact Condition** and a matching `ObjectIdentifier`. |
| Source category or definition | Use **Check Weapon Source Category** or **Check Weapon Source Definition**. |

## How evaluation runs

For every impact, the group checks its entries from top to bottom:

1. A disabled condition returns true and is skipped in practice.
2. The first enabled condition that returns false stops the group.
3. If every enabled condition passes, the group returns true. An empty condition list passes.
4. **Conditional Impact Action** runs one branch. **Conditional Impact Receiver** checks same-GameObject conditions first, then assigned behaviors, then its local condition group. It invokes the selected UnityEvent before the corresponding action branch.

There is no built-in OR mode within one group. To express OR, write one custom condition that owns the alternatives or restructure the outcome with separate conditional branches or receivers.

### Firearm example

To let a firearm run one impact result only for projectiles, add **Projectile Impact Action Condition**, enable **Allow Projectile Impact**, and leave **Allow Non Projectile Impact** disabled. Put the damage and surface effects in the pass branch and optional rejection feedback in the fail branch.

### Iron Sword example

To let each target decide whether Iron Sword may damage it, add **Check Target Impact Condition Behaviour** to the sword's condition list. On the protected target, add **Impact Condition Behaviour** with **Check Weapon Source Definition**, leave **Exclude Category** disabled, and add Iron Sword to **Item Definitions**. Targets without a behavior still pass, so add behaviors to every target that needs this policy or use an Object Identifier/custom requirement when the component must be present.

## Editor checkpoint

Before entering Play Mode, confirm that:

- every condition row is enabled and ordered from broad checks to specific checks;
- whitelist lists contain at least one category or definition;
- a projectile condition has at least one allow toggle enabled;
- target-owned rules are on the reported hit object or its Rigidbody GameObject; and
- a Conditional Impact Receiver has a source action that sends `OnObjectImpact` to the target.

## Verify in Play Mode

Test one passing and one failing case without changing the configuration between runs.

| Test | Expected result |
| --- | --- |
| Iron Sword hits a target whose definition whitelist includes it | Pass actions run; fail actions do not. |
| A different definition hits that target | The first failing definition condition stops the list and the fail result runs. |
| A projectile hits a projectiles-only branch | The projectile pass result runs. |
| A melee collider hits the same branch | The non-projectile fail result runs. |
| A source checks a target that has no Impact Condition Behaviour | **Check Target Impact Condition Behaviour** passes. |
| An Impact Event reaches a Conditional Impact Receiver | Exactly one of the receiver's success or fail events and action lists runs. |

When debugging a longer list, temporarily disable later entries. A disabled entry is ignored, so this isolates the first unexpected result without changing the list order.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Every impact takes the fail branch | A projectile condition may still have both allow toggles off, or a source whitelist may be empty. | Enable the intended projectile result or populate the category/definition list. |
| A definition filter appears to use categories | Released Version 3 labels the definition condition's toggle **Exclude Category**. | Interpret it as include/exclude definition; leave it off for a whitelist. |
| Object Identifier never passes | The condition requires a numeric ID match and forces a hierarchy search. | Add `ObjectIdentifier`, match **Target ID**, and set **Search In Children** for the actual hierarchy direction. Do not rely only on the mapped object field. |
| A target-owned rule is ignored | **Check Target Impact Condition Behaviour** only checks the reported target and its Rigidbody GameObject. | Move the behavior to one of those objects or use a custom hierarchy-aware condition. |
| Conditional Impact Receiver never runs | The source may not invoke the target impact callback. | Add **Impact Event** with **Call Impact Callback On Target**, or enable **Invoke On Object Impact** on **Simple Damage**. |
| A receiver evaluates a rule twice | The same behavior may be auto-discovered and listed in **Impact Conditions Behaviours**. | Keep only one route to that behavior. |
| Damage data remains available after rejection | **Reset Damage Data On Fail** may be off, or a fail action is reading the data before the reset. | Enable the field when later outer actions must not reuse the data; remember that fail-branch actions run before it is cleared. |

## Related tasks

- [Configure Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Configure Item Effects](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/)
- [Organize Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)
- [Configure a Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/)
- [Configure a Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/)
- [Understand Character Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)

## Developer reference

Create a serializable class derived from `ImpactActionCondition` and override `CanImpactInternal`. The context supplies the reported target, source, collider, Rigidbody, detection mask, surface data, Character Item Action, and any prepared damage data. Returning false stops the remaining conditions in that group.

This example adds the missing target-layer filter:

```csharp
using System;
using Opsive.UltimateCharacterController.Items.Actions.Impact;
using UnityEngine;

[Serializable]
public class TargetLayerImpactCondition : ImpactActionCondition
{
    [SerializeField] private LayerMask m_AllowedLayers = ~0;

    protected override bool CanImpactInternal(ImpactCallbackContext ctx)
    {
        var target = ctx.ImpactCollisionData?.ImpactGameObject;
        return target != null &&
               (m_AllowedLayers.value & (1 << target.layer)) != 0;
    }
}
```

Derive a reusable target component from `ImpactConditionBehaviourBase` when the rule belongs to the target rather than an item condition list. Implement `CanImpact(ImpactCallbackContext ctx)` and place the component where **Check Target Impact Condition Behaviour** can find it.

---

<a id="page-ultimate-character-controller-items-inventory-character-item-item-actions-action-modules-groups-item-effects"></a>

# Item Effects

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/item-effects/)

Item Effects add item-side feedback or changes at a chosen point in a Character Item Action, such as playing a firearm sound, showing a muzzle flash, toggling an Iron Sword object, or invoking a local callback. Use an **Effect Group** when the result depends on the owning item action and character; use [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) when the result must use the object that was hit.

## Configure an Effect Group

1. Select the Character Item and expand the Character Item Action that should produce the result.
2. Open the relevant Action Module Group. Add or select **Generic Item Effects**, **Cast Item Effects**, or another module that exposes an **Effect Group**.
3. Expand **Effect Group**, select **+**, and choose an Item Effect type.
4. Configure the selected row. For a perspective-aware field, assign both first-person and third-person values or their **Object Identifier** IDs when the item supports both perspectives.
5. Drag the rows into a readable order. Put the item-side change first, presentation next, and a callback or temporary debug row last.
6. Choose the containing module's start, update, complete, stop, fire, throw, or cast setting. This decides when the entire group is invoked.

![Effect Group containing Play Audio Clip, Enable Disable Object, Invoke Unity Event, and Debug Item Effect, with Debug Item Effect selected to show Enabled, Delay, Message, Bindings, and States](https://opsive.com/wp-content/uploads/2022/10/ItemEffectGroupInspector.png?v=af5d49948dc9)

The legacy Inspector image remains accurate for released Version 3. Each row belongs to the same owning Character Item Action; an Item Effect does not receive a shot, collision, or impact target.

## Choose the invocation point

An Item Effect is a one-shot operation. It has no continuous update or stop phase of its own. The module containing the **Effect Group** decides which item lifecycle event invokes it.

| Item workflow | Exact controls and released-Version-3 defaults | Invocation |
| --- | --- | --- |
| General usable action, **Generic Item Effects** | **On Start Use** off, **On Use** on, **On Use Update** off, **On Use Complete** off | At each enabled use stage. **On Use Update** may invoke the group repeatedly during one use. |
| Shootable **Fire Effects** or **Dry Fire Effects**, **Generic Item Effects** | One **Effect Group** | When the containing fire or dry-fire module is invoked. |
| Melee **Attack Effects**, **Generic Item Effects** | **On Start Attack** on, **On Complete Attack** off, **Substate Index** `-1`, **Attack ID** `-1` | At the active attack start and/or completion. Negative filters match every attack. |
| Throwable **Throw Effects**, **Generic Item Effects** | One **Effect Group** | When the throwable item is thrown. |
| Magic **Generic Item Effects** | **On Start** on, **On Stop** off | When the containing magic start/stop module starts and/or stops. |
| Magic **Cast Item Effects** | **Block Until Effects Can Be Used** off | During that cast. When blocking is on, every effect must report that it can run. |
| **Aim Substate** | Separate **On Start Aim Effect Group** and **On Stop Aim Effect Group** | When input starts or stops aiming. |
| **Generic Item Effects** Impact Action | One **Effect Group** | At impact, but the contained Item Effects still receive only the owning Character Item Action, not the impact context. |

Choose one deliberate lifecycle point first. For example, a muzzle flash belongs in **Fire Effects**, not **On Use Update**; a sword trail can start with the active attack and use a separate completion or stop group to turn it off.

## Shared controls and execution

| Field | Default | Behavior |
| --- | --- | --- |
| **Enabled** | On | Intended to gate the row. In released Version 3, only **Enable Disable Object** and **Spawn Prefab** honor this field; see the limitations below. |
| **Delay** | `0` seconds | Zero invokes immediately. A positive value schedules that row independently. |
| **Bindings** | Empty | Optional property bindings inherited from the bound State object. |
| **States** | Default/empty | Optional State System presets that can override serialized effect values on the owning action GameObject. |

The group visits rows from top to bottom. Immediate rows run in that order. A delayed row is scheduled and the group immediately continues, so a later zero-delay row runs before it. There is no group-level wait or parallel switch: delayed rows simply overlap subsequent work.

Every effect is initialized with a valid Character Item Action. Perspective-aware effects resolve their current first-person or third-person value when invoked. If a feature must change the hit target, apply force, modify a target attribute, activate a target State, or use impact data, configure an [Impact Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) instead.

## Built-in Item Effects

Released Ultimate Character Controller Version 3 contains six concrete Item Effect types. The sections below cover every built-in type.

### Change a perspective object

**Enable Disable Object** changes one GameObject on the current perspective item.

| Field | Default | Behavior |
| --- | --- | --- |
| **Object** | First- and third-person IDs `-1`; references unassigned | Resolves an assigned object or an **Object Identifier** below the current perspective item. A missing object is a no-op. |
| **Enable Object** | Off | Off deactivates the object; on activates it. |
| **Revert Time** | `-1` seconds | A positive value schedules the opposite active value. Zero or less leaves the requested value in place. |

Use separate start and stop groups when an object must follow a lifecycle precisely. For example, enable an Iron Sword trail at attack start and disable it at attack completion instead of relying on a timer.

### Spawn a visual object

**Spawn Prefab** creates a pooled object from the current perspective configuration.

| Field | Default | Behavior |
| --- | --- | --- |
| **Prefab** | First- and third-person references unassigned | Chooses the prefab for the active perspective. A missing prefab is a no-op. |
| **Origin** | First- and third-person IDs `-1`; references unassigned | Uses the selected perspective transform. With no resolved origin, it falls back to the character transform. |
| **Parent To Origin** | On | Keeps the spawned object under the origin. Off unparents it after creation. |
| **Local Position** / **Local Rotation** | `(0, 0, 0)` | Offsets the object from the chosen origin. |
| **Local Scale** | `(1, 1, 1)` | Applies the final local scale after parenting or unparenting. |
| **Life Time** | `-1` seconds | A positive value returns a pooled object to its pool, or destroys a non-pooled object. Zero or less leaves it alive. |

Use this effect for a short muzzle flash, cast ornament, or sword swipe that belongs to the item action. The effect uses the Opsive object pool when the prefab is pooled.

### Set light or audio feedback

**Light Effect** assigns one intensity value to a Light on the current perspective item.

| Field | Default | Behavior |
| --- | --- | --- |
| **Light** | First- and third-person IDs `-1`; references unassigned | Resolves the Light for the active perspective. |
| **Light Intensity Curve** | Unassigned | Supplies the intensity returned by the curve. |
| **Light Intensity Time** | `0` | Evaluates the curve once at this time and assigns the result to `Light.intensity`. |

This effect does not animate the curve over time and does not enable or disable the Light component or GameObject. Use two rows or lifecycle groups with different curve samples for an on/off change.

**Play Audio Clip** contains one **Audio Clip Set**. A new set has no **Audio Config** or **Audio Clips** selected. When invoked, it selects from the configured set and plays on the owning Character Item Action GameObject. It is a one-shot effect; the Item Effect does not expose a matching stop control. Use an [Audio Config](https://opsive.com/support/documentation/ultimate-character-controller/audio/) when the sound needs the shared audio settings rather than a local clip list.

### Invoke a callback or inspect the flow

**Invoke Unity Event** exposes **On Invoke Effect**, with no persistent listener by default. It invokes a no-argument UnityEvent; it does not pass the item action, character, or impact context to the listener.

**Debug Item Effect** exposes **Message**, blank by default. It logs the message followed by the owning Character Item Action and uses that action as the Unity Console context. Add it temporarily after another row to confirm that the group reached that point.

## Choose the correct target system

Item Effects are intentionally limited to the owning item action. Use the adjacent system when the desired result needs different data.

| Desired result | Use |
| --- | --- |
| Play item-side audio | **Play Audio Clip** Item Effect. |
| Toggle or inspect the current perspective item | **Enable Disable Object**, **Light Effect**, **Spawn Prefab**, or a local UnityEvent. |
| Damage, force, target attributes, target States, surface feedback, or a hit callback | [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/), which receive the impact context. |
| Camera shake or another camera response | A camera/view module, a deliberately wired UnityEvent, or a custom Item Effect. There is no built-in camera Item Effect. |
| Change an owning item or character State | The effect's inherited **States** can override its values; use the [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) or a custom effect when gameplay must explicitly activate a named State. There is no built-in set-state Item Effect. |

## Scenario recipes

### Firearm muzzle feedback

1. In the Shootable Action, add **Generic Item Effects** to **Fire Effects**.
2. Add **Spawn Prefab**. Assign first- and third-person muzzle-flash prefabs and origins, keep **Parent To Origin** on, and give the effect a short positive **Life Time**.
3. Add **Play Audio Clip** with the firearm's **Audio Config** or clip set.
4. Add **Invoke Unity Event** last only when another local component needs a fire callback.
5. Configure a separate **Dry Fire Effects** group for an empty-weapon click rather than branching inside this group.

The flash and sound are item-side presentation. Keep projectile hits, damage, force, and surface response in the Shootable Action's Impact module.

### Iron Sword attack feedback

1. In **Attack Effects**, add **Generic Item Effects**.
2. Leave **On Start Attack** on. Set **Attack ID** or **Substate Index** only when the effect belongs to one attack animation.
3. Add **Enable Disable Object** for a trail object, or **Spawn Prefab** for a short swipe effect, using perspective-aware origins.
4. Add **Play Audio Clip** for the swing sound.
5. Use **On Complete Attack** or another stop-stage group to turn a persistent trail off. Use Impact Actions for damage and the target's hit reaction.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the Effect Group is inside the module and lifecycle stage that actually runs for this item;
- every perspective-aware effect has a valid first-person and/or third-person reference or **Object Identifier** ID;
- **Spawn Prefab** has a prefab, a deliberate origin, and a positive **Life Time** when the object should be temporary;
- **Light Effect** has both a Light and an intensity curve;
- **Play Audio Clip** has an **Audio Config** or at least one clip;
- delayed rows do not depend on a later row waiting for them; and
- target-side gameplay remains in an Impact Action rather than an Item Effect.

## Verify in Play Mode

| Test | Expected result |
| --- | --- |
| Fire the configured firearm once | The item-side flash and audio occur once at the selected fire stage; impact damage remains independent. |
| Switch between first- and third-person views, then fire | Each view uses its own configured prefab, origin, object, or Light. |
| Dry-fire the weapon | Only the **Dry Fire Effects** result runs. |
| Perform the matching and nonmatching Iron Sword attacks | A filtered **Attack ID** or **Substate Index** invokes the group only for the matching attack. |
| Give one row a positive **Delay** | Later zero-delay rows run first; the delayed result appears after its own timer. |
| Strike two different targets | Item Effects repeat from the owning sword action but never read or alter either target unless an Impact Action does so. |

Use **Debug Item Effect** temporarily when you need to distinguish "the group did not run" from "the chosen object, clip, curve, or listener produced no visible result."

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| An effect never appears | Confirm that the containing module and its exact lifecycle toggle run for this item, then check the current perspective reference. | Move the group to the correct module/stage and assign the missing object, origin, prefab, Light, clip, or listener. |
| **Enabled** is off but an effect still runs | **Invoke Unity Event**, **Debug Item Effect**, **Light Effect**, and **Play Audio Clip** override the availability check and ignore **Enabled** in released Version 3. | Remove that row, clear its listener/data, or use a custom effect whose availability check calls the base implementation. |
| A magic cast remains blocked by a disabled row | **Enable Disable Object** and **Spawn Prefab** do honor **Enabled**, so **Cast Item Effects > Block Until Effects Can Be Used** reads them as unavailable. | Remove the disabled row or turn blocking off; do not use **Enabled** as a temporary mixed-type group switch in this flow. |
| A delayed effect fires more times than expected | The same row was invoked again before its delay elapsed, commonly through **On Use Update**. Released Version 3 tracks only the most recently scheduled delay handle even though earlier callbacks remain scheduled. | Invoke the group once per intended event, keep the row at **Delay** `0`, or implement explicit repeat/cancellation control in a custom module. |
| **Revert Time** restores the wrong active value | **Enable Disable Object** schedules the opposite of **Enable Object**, not the GameObject's actual prior `activeSelf` value. Its revert schedule is also separate from the effect's normal destroy cleanup. | Start from a known object state or use explicit start and stop groups instead of **Revert Time**. |
| **Light Effect** throws or does nothing | The Light or **Light Intensity Curve** is unassigned, or the curve sample equals the current intensity. The released effect has no null guard and performs only one assignment. | Assign both fields and test a clearly different curve value at **Light Intensity Time**. |
| A spawned object remains in the scene | **Life Time** is `0` or negative. The positive-lifetime callback is scheduled separately and is not canceled when the effect is destroyed. | Use a positive lifetime for temporary feedback and make the spawned prefab safe to return later, or manage its lifecycle in a custom effect. |
| Audio comes from the wrong place | **Play Audio Clip** plays on the owning Character Item Action GameObject, not the hit point or the selected perspective origin. | Use an impact audio action for hit-position audio, or a custom item effect when another item transform must own the sound. |
| Force, damage, an attribute, a target State, or camera shake is missing | No built-in Item Effect performs those target/camera operations. | Use Impact Actions, a camera/view module, a wired UnityEvent, or a focused custom effect. |

## Related tasks

- [Configure Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Configure Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/)
- [Organize Action Module Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)
- [Configure a Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/)
- [Configure a Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/)
- [Configure a Throwable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/)
- [Configure a Magic Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/)
- [Configure Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/)
- [Configure States](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

`ItemEffect` derives from `BoundStateObject` and is initialized with a non-null `CharacterItemAction`. The base implementation gates with **Enabled**, schedules **Delay** through the Opsive Scheduler, and clears its tracked delay when `InvokeEffectInternal` runs. `ItemEffectGroup` initializes every row against the same action, checks availability with `CanInvokeEffects`, invokes every row with `TryInvokeEffect`, and forwards `OnDestroy` for cleanup.

A group does not stop when one row returns false; it continues to later rows. If a custom Item Effect adds a condition, combine it with `base.CanInvokeEffect()` so the shared **Enabled** control still works. Call `base.InvokeEffectInternal()` before the custom result so the base delay tracking is cleared, and call the base cleanup when overriding `OnDestroy`.

Mark a custom Item Effect serializable so its values appear and persist in the Inspector:

```csharp
using System;
using Opsive.UltimateCharacterController.Items.Actions.Effect;
using UnityEngine;

[Serializable]
public class LogItemUseEffect : ItemEffect
{
    [SerializeField] private string m_Message = "Item effect";

    protected override void InvokeEffectInternal()
    {
        base.InvokeEffectInternal();
        Debug.Log($"{m_Message}: {m_CharacterItemAction}", m_CharacterItemAction);
    }
}
```

When custom code owns an `ItemEffectGroup`, initialize it with the relevant Action Module or Character Item Action before invocation, and call `OnDestroy()` when its owner is destroyed so tracked delayed work is canceled.

---

<a id="page-ultimate-character-controller-items-inventory-inventory"></a>

# Inventory

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/)

The Inventory records which items a character owns, how many of each item are available, and which Character Item is active in each slot. Use the built-in Inventory for controller-focused loadouts, pickups, equipment, ammunition, and drops.

## How the inventory fits together

The built-in inventory separates the item data from the object that appears on the character:

- An **Item Collection** contains the project's item categories and Item Types.
- An **Item Type** is the built-in Item Definition and Item Identifier. It supplies the identity, capacity, categories, and Character Item prefab references; the Inventory stores the owned amount.
- A **Character Item** is the runtime item object for one Item Definition and slot. It contains the visible first- or third-person item, item actions, equip timing, and optional **Drop Prefab**.
- The **Inventory** owns Item Identifier amounts, maps each Item Identifier to its Character Items, and records the active Character Item in each slot.
- The **Item Set Manager** uses Item Set Rules to decide which owned Character Items form valid equipment combinations. Equip and unequip requests should normally go through this manager rather than changing an Inventory slot directly.

An item such as an Iron Sword therefore has an Item Type that identifies the owned count, a Character Item for the sword held in a hand slot, and an Item Set that makes the sword an equippable choice. A consumable identifier such as Bullet can exist only as an Inventory amount when it does not need its own visible Character Item.

## Before you begin

The character needs item support created by the Character Manager, an Item Collection, and at least one Item Set Rule for anything that can be equipped. Create the Item Types and Character Items first by following [Item creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/).

Use the built-in Inventory only when UCC owns the item data. If Ultimate Inventory System owns the inventory, follow the [Ultimate Inventory System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) instead; that integration replaces the standard Inventory and Item Set Manager with bridge components.

## Add inventory support to a character

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the character. Enable **Items**, assign the character's **Item Collection**, and assign an **Item Set Rule**.
3. Select **Build Character** for a new character or **Update Character** for an existing one.
4. Confirm that the character has an **Inventory** and **Item Set Manager**, and that its hierarchy contains the **Items** object used for Character Items. A player-controlled character also receives the item input handling and standard item abilities.
5. Select the Inventory. Expand **Default Loadout** and confirm that every entry belongs to the same Item Collection assigned to the Item Set Manager. The Inspector reports an error when a loadout definition comes from another collection.

### Editor checkpoint

Before entering Play Mode, the character should have one Inventory, one Item Set Manager using the intended Item Collection, and a Character Item prefab for every visible or equippable item. Each Character Item's **Slot ID** must match the slot used by its Item Set Rule. Count-only definitions such as ammunition do not need a Character Item prefab.

## Create useful starting loadouts

### Start with an Iron Sword

1. Create an **Iron Sword** Item Type in **Tools > Opsive > Ultimate Character Controller > Item Type Manager**.
2. Open **Tools > Opsive > Ultimate Character Controller > Item Manager**. Build the sword for the character with **Item Definition** set to Iron Sword and the intended hand **Slot ID**. Keep **Add to Default Loadout** enabled when the character should begin with it.
3. On the Inventory, expand **Default Loadout** and set Iron Sword to an amount of **1**.
4. Configure the Item Set Rule so the sword produces a valid set in that slot.
5. Set **Loadout Equip** to **First Loadout Item** for a simple one-item loadout, or choose **Item Set Name** when a named combination such as Sword and Shield must be selected.

The first loadout entry matters when **First Loadout Item** is selected. The Inventory adds the definitions first, then asks the first Item Set Group to equip the set that contains that entry. **Item Set Index** also addresses the first group; prefer **Item Set Name** when the project has multiple groups or the generated order can change.

### Start with a firearm and ammunition

Create one Item Type and Character Item for the firearm. When its Shootable Action uses an **Item Ammo** module, create a separate ammunition Item Type, assign it as that module's **Ammo Item Definition**, and add the starting ammunition amount to **Default Loadout**. The firearm needs a Character Item prefab; ammunition usually remains a count-only Inventory entry.

For example, add Rifle with amount **1** and Bullet with the desired reserve amount. The Rifle's Character Item can be spawned and equipped, while reload removes Bullet amounts from the Inventory. The Bullet Item Type's **Capacity** limits how much reserve ammunition the Inventory can accept.

See [Shootable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) for the clip, ammo, and reload module workflow.

## Add a pickup and a drop

### Place a pickup in the scene

1. Create an Item Pickup with **Tools > Opsive > Ultimate Character Controller > Object Manager**, or add **Item Pickup** and a trigger Collider to a suitable prefab.
2. Add Iron Sword, Rifle, Bullet, or another definition to **Item Definition Amounts** and set the amount the object grants.
3. Keep **Pickup On Trigger Enter** enabled for automatic collection. Disable it when the Pickup ability or another interaction should initiate collection.
4. Enable **Equip** when collecting the object should request an equipment change. Set **Item Set Name** and **Item Set Group** when a particular set must be selected; otherwise the pickup tries a valid set containing one of the collected Character Items.
5. Set **Trigger Enable Delay** deliberately for dropped physics objects. A scene pickup without a Rigidbody is available immediately on its first initialization; a dropped Rigidbody waits until it settles and the delay expires.

On collection, the pickup adds each definition to the Inventory, spawns any configured Character Item prefabs, updates the Item Sets, and optionally requests an equip. The definition's capacity can reduce the amount accepted.

### Make an item drop and become collectible again

Assign a **Drop Prefab** on the Character Item. That prefab must contain an **Item Pickup**-based component so the Inventory can place the dropped definition and amount on it. Add the [Drop ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) to remove the active Character Item and spawn that prefab. Use **Wait For Unequip** when the visible item should finish its unequip transition before it leaves the character.

A shootable Character Item can also contribute related identifiers, such as its ammunition, to the dropped pickup. Test the exact amount you want to transfer rather than assuming all reserve ammunition should leave with one weapon.

## Choose the Inventory behavior

### Choose what loads and equips

- **Default Loadout** adds Item Definitions and amounts when the Inventory initializes. It runs again after respawn only when **Load Default Loadout On Respawn** is enabled.
- **Loadout Equip** defaults to **First Loadout Item**. **None** unequips the groups, **Item Set Name** or **Item Set Index** selects a specific set, and **Do Nothing** leaves the existing equipment unchanged.
- **Auto Spawn Destroy Runtime Character Items** is enabled by default. Adding an identifier spawns the Character Item prefabs referenced by its Item Type; removing the last amount can destroy runtime-spawned Character Items.
- **Auto Remove Character Items** is enabled by default. When an amount reaches zero, the corresponding Character Items leave the valid Inventory and an equipped item is handed back through the normal Item Set transition.

Use **Loadout Equip > Item Set Name** instead of a generated index when a stable, meaningful Item Set state name is available. Runtime Item Set indexes can change as the owned items and rules change.

### Choose what happens on death and respawn

- **Unequip All On Death** is disabled by default. Enable it to unequip every active slot when the character dies.
- **Remove All On Death** is disabled by default. Enable it to remove the removable Character Items and their amounts and attempt to drop them with their configured drop prefabs. Add definitions to **Remove Exceptions** when they must survive this removal. A count-only identifier that is not associated with a Character Item is not enumerated by `RemoveAllItems`; clear it explicitly when that resource must also be lost on death.
- **Load Default Loadout On Respawn** is disabled by default. Enable it to add the configured default amounts again and then apply **Loadout Equip**.

Avoid using **Remove All On Death** and a persistent save restore as two independent authorities. Decide whether death, the save system, or another game system owns the final restored amount, then apply that state once.

### Use the Unequipped state

**Unequipped State Name** defaults to `Unequipped`. The Inventory activates this state while no Character Item is active and deactivates it when an item is equipped. Leave the field empty only when the project intentionally does not use an inventory-wide unequipped state.

## Verify in Play Mode

1. Select the character and expand **Inventory > Current Inventory**. Confirm the Iron Sword or Rifle and its expected count appear. Active entries are bold and show their slot numbers.
2. Confirm the Item Set Manager creates a valid set for the visible Character Item and that **Loadout Equip** activates the intended set.
3. Collect an Item Pickup. Confirm the count increases only up to the Item Type's capacity, its Character Item appears when required, and the configured equipment change occurs.
4. For a firearm, fire and reload. Confirm the reserve Bullet amount decreases while the firearm remains owned and active.
5. Drop the active item. Confirm its Inventory amount decreases, the Character Item is removed or replaced through the Item Set Manager, and the spawned object can be collected again after its trigger delay.
6. Test death and respawn. Confirm only the selected unequip, remove, exception, loadout, and re-equip behavior occurs.

## Troubleshoot inventory items

- **The Current Inventory is empty:** check that you are in Play Mode, the definition is in **Default Loadout** or is actually collected, and the Inventory component is enabled. The Current Inventory foldout is read-only runtime information.
- **The amount does not increase:** check the Item Type's **Capacity**, the pickup's **Item Definition Amounts**, and whether the character is entering the trigger with its main collider. Fix the capacity or pickup definition rather than adding a duplicate Item Type.
- **The character owns an item but no Character Item appears:** check that the Item Type references a Character Item prefab and **Auto Spawn Destroy Runtime Character Items** is enabled. Also confirm the prefab has the same Item Definition and a valid Slot ID.
- **The item appears but does not equip:** inspect the Item Set Manager in Play Mode. Fix the Item Set Rule, Item Category, slot mapping, or disabled Item Set, then confirm the matching [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) ability can run.
- **A pickup adds ammunition but equips the wrong weapon:** disable **Equip** for an ammo-only pickup, or assign the intended **Item Set Name** and **Item Set Group**. Also check the Equip Unequip ability's Auto Equip choices.
- **Dropping removes the item but spawns nothing:** check the Character Item's **Drop Prefab** and confirm that prefab contains an Item Pickup component. A null or incompatible prefab cannot receive the dropped Item Definition amounts.
- **The dropped object cannot be collected immediately:** check **Trigger Enable Delay**, the trigger Collider, and the object's velocity. Dropped Rigidbody objects deliberately wait until they settle and the configured delay completes.
- **Items duplicate after respawn or load:** check **Load Default Loadout On Respawn** and the order of the project's save restore. Make one system responsible for adding the final amounts.

## Persistence, multiplayer, and UIS ownership

The built-in UCC Inventory does not include a general persistence component that saves arbitrary inventory amounts. A project save system should record each stable Item Type ID and amount, resolve those IDs through the same Item Collection, restore them with the Inventory API, and then restore or request the intended Item Set after the Character Items have been created.

UCC includes conditional multiplayer hooks for authoritative item addition, removal, equipment, pooling, and dropped-object spawning. Those hooks do not provide a transport or complete inventory replication layer by themselves; use the supported networking integration and perform mutations on the authoritative instance.

Ultimate Inventory System is a different ownership model. It provides collections, mutable item data, equipment UI, shops, crafting, and its own saving workflow. In the UCC integration, UIS owns those items and the bridge presents them to UCC as Character Items and Item Sets. Do not keep both the standard UCC Inventory and the UIS character inventory bridge active on the same character.

## Related tasks

- [Item creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds Item Types and Character Item prefabs.
- [Item Type, Definition, and Category](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/) explains the identifiers, capacity, and category data used by Inventory.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) configures slots, visible objects, item actions, and drop prefabs.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) controls valid equipment combinations.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) covers pickup object settings.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) controls animated equipment transitions.
- [Drop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) removes equipped items and spawns their pickup prefabs.
- [Ultimate Inventory System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) replaces built-in inventory ownership with UIS.

## Developer reference

Depend on `InventoryBase` when code should work with the standard Inventory or a supported inventory bridge. The standard `Inventory` implementation stores the amounts, active items, default loadout, removal exceptions, and loadout-equip behavior.

### Query and change amounts

`GetAllItemIdentifiers()` returns the identifiers currently owned. `GetAllCharacterItems()` returns the spawned Character Items, which is a different collection and can contain the slot-specific objects for an identifier.

```csharp
using Opsive.Shared.Inventory;
using Opsive.UltimateCharacterController.Inventory;
using UnityEngine;

public static class InventoryExample
{
    public static void AddAndRemove(GameObject character, IItemIdentifier itemIdentifier)
    {
        var inventory = character.GetComponent<InventoryBase>();
        if (inventory == null || itemIdentifier == null) {
            return;
        }

        var amountBefore = inventory.GetItemIdentifierAmount(itemIdentifier);
        var amountAdded = inventory.AddItemIdentifierAmount(itemIdentifier, 1);
        var amountRemoved = inventory.RemoveItemIdentifierAmount(itemIdentifier, 1);
        Debug.Log($"{amountBefore} before, {amountAdded} added, {amountRemoved} removed.");
    }
}
```

`AdjustItemIdentifierAmount(itemIdentifier, amount)` accepts a positive amount to add or a negative amount to remove. The returned value is the actual adjustment, so capacity and removal rules can make it smaller than the request.

Call `PickupItem` when the caller must supply a slot, immediate-pickup choice, or force-equip choice. The two-argument `AddItemIdentifierAmount` follows the Inventory's automatic Character Item spawning setting; with automatic spawning enabled, it routes through `PickupItem` and sends pickup notifications. The overload that accepts `spawnCharacterItems` performs the amount and optional spawn change without those pickup notifications.

### Equip and drop through the owning systems

Use `ItemSetManagerBase.TryEquipItemSet` for normal equipment requests:

```csharp
var itemSetManager = character.GetComponent<ItemSetManagerBase>();
var equipped = itemSetManager != null &&
               itemSetManager.TryEquipItemSet("IronSword", -1, true, false);
```

The group index **-1** searches the groups for a matching Item Set name. The final two arguments request a forced transition and a non-immediate transition. Use the Character Item Drop Prefab and the Drop ability for a player-facing drop. Lower-level code can use `RemoveItemIdentifierAmount(itemIdentifier, slotID, amount, true)` or `DropCharacterItem`, but it is then responsible for the intended authority and animation timing.

### Listen for inventory events

The Inventory Inspector exposes Unity Events for add, pickup, equip, amount adjustment, unequip, and remove. The Opsive Event System provides the corresponding runtime messages, including:

- `OnInventoryAdjustItemIdentifierAmount` with `(IItemIdentifier, int previousAmount, int newAmount)`;
- `OnInventoryPickupItemIdentifier` with `(IItemIdentifier, int amount, bool immediatePickup, bool forceEquip)`;
- `OnInventoryPickupItem` with `(CharacterItem, int amount, bool immediatePickup, bool forceEquip)`;
- `OnInventoryWillAddItem` and `OnInventoryAddItem` with `(CharacterItem)`;
- `OnInventoryEquipItem` and `OnInventoryUnequipItem` with `(CharacterItem, int slotID)`;
- `OnInventoryRemoveItem` with `(CharacterItem, int slotID)`; and
- `OnInventoryLoadDefaultLoadoutComplete` and `OnInventoryRespawned` without parameters.

Register and unregister the same signature on the character GameObject. See [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) for the shared registration pattern.

---

<a id="page-ultimate-character-controller-items-inventory-item-slots"></a>

# Item Slots

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/)

Item Slots give each equipment location a stable ID so Inventory, Item Sets, visible models, abilities, and animation all agree about where an item belongs. The normal humanoid mapping is right hand **0** and left hand **1**.

## Understand the slot map

Four similar values have different jobs:

| Value | What it controls |
| --- | --- |
| **Character Item Slot > ID** | Identifies an attachment location on a character model or first-person arm rig. |
| **Character Item > Slot ID** | Selects the Inventory position and the matching first- or third-person attachment location. |
| **Character Item > Animator Item ID** | Identifies the item's animation family. It is written to `Slot<ID>ItemID`; it is not a Slot ID. |
| An Item Set Rule's array position | Specifies which Item Definition is allowed in that Slot ID. |

Inventory scans every Character Item Slot below the character, including inactive objects. Its slot count is the highest nonnegative ID plus one, with a minimum of one. Keep IDs contiguous: IDs `0` and `3` create four Inventory positions even when `1` and `2` are unused.

Several available Character Items can be assigned to one slot, but only one can be active in that slot at a time. A second hand, independent utility location, or another simultaneously equipped item therefore needs another Slot ID.

## Configure slots in Character Manager

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select or configure the scene character and enable **Items**.
3. Assign the full-body model and any **First Person Arms** that will display held items.
4. Select **Adjust Slots** beside **Item Slots**.
5. Under **Model**, add the transform that should own each attachment point. For a humanoid, use the right hand as **Right** ID `0` and the left hand as **Left** ID `1`.
6. Choose **Other** and enter `2` or higher for a project-specific location. Keep IDs nonnegative and contiguous unless an empty Inventory position is intentional.
7. Under every **First Person Arms** entry, add the equivalent attachment transforms and reuse the same logical IDs.
8. Resolve every validation message. A parent must be below the displayed model or arm rig, and each parent and ID must be unique within that hierarchy.
9. Select **Close**, then **Build Character** for a new character or **Update Character** for an existing one.

Character Manager creates a child named `Items` under each selected attachment transform and adds **Character Item Slot** with the chosen **ID**. This is different from the controller-level `Items` object: the controller-level object has **Item Placement** and stores Character Item roots, while the hand-level objects mark where their visible models attach.

![Character Item Slot Inspector showing the ID field for an attachment's Items child](https://opsive.com/wp-content/uploads/2022/10/CharacterItemSlot-e1666797322749.png?v=f96dd1aefaca)

### Editor checkpoint

Before creating an item, expand every model and arm rig in the Hierarchy. Each intended attachment transform should contain one `Items` child with one Character Item Slot. Right-hand locations should use the same ID in every relevant perspective and model, as should left-hand and custom locations.

## Match first- and third-person slots

A Character Item has one Slot ID even when it renders different objects in first and third person. Each perspective therefore needs a Character Item Slot with that same ID:

- The third-person perspective searches the active character model for its matching slot.
- The first-person perspective searches the selected First Person Base Object and its arm hierarchy.
- Item Manager blocks an on-character build when the selected first- and third-person slots use different IDs.
- A character that switches models needs the same logical slot map on every model that can display the item.

The transforms do not need identical names or positions. They represent the same logical location: for example, a third-person right hand and the corresponding first-person right arm can both be slot `0`.

![Third-person hierarchy with a Character Item root under Item Placement and its visible model below a hand slot](https://opsive.com/wp-content/uploads/2022/10/CharacterThirdPerspectivesItemHiearchy.png?v=a26ddcd6ac65)

![First-person hierarchy with a Character Item root under Item Placement and its visible model below the camera arms slot](https://opsive.com/wp-content/uploads/2022/10/CharacterFirstPerspectivesItemHiearchy.png?v=3e3ae1f1348f)

Keep a third-person representation for AI or multiplayer characters that other cameras must see, even when the local player uses a first-person view. A first-person representation is only needed for a first-person camera path.

## Assign a Character Item to a slot

Use **Tools > Opsive > Ultimate Character Controller > Item Manager** after the character's slot map is stable.

### Build a reusable prefab

1. Leave **Character** empty so Item Manager shows **Slot ID**.
2. Assign **Item Definition** and enter the Slot ID that the prefab can occupy.
3. Set **Animator Item ID** to the animation mapping implemented by the character's Animator Controller. Do not copy the Slot ID into this field unless that happens to be the intended animation mapping.
4. Enable **Add First Person Item** and **Add Third Person Item** only for the perspectives the prefab supports.
5. Keep **Add Item Prefab to Item Definition** enabled so Inventory can find this slot-specific prefab at runtime.
6. Build the item, then inspect its **Character Item > Slot ID** before adding it to a loadout.

One Item Definition can reference more than one Character Item prefab. For example, a pistol definition can reference a right-hand prefab with Slot ID `0` and a left-hand prefab with Slot ID `1`. Inventory uses the definition and slot together; do not add two prefabs with the same definition and Slot ID.

### Build directly on a character

When **Character** is assigned, Item Manager derives the Slot ID from the selected perspective parents. Choose the first-person **Item Parent** and the humanoid third-person **Hand**, or select an **Item Parent** for a custom rig. The manager requires the two selected Character Item Slots to have the same ID before it enables the build.

Changing **Animator Item ID** through **Update Item** does not move an existing item to another slot. When the slot must change, update the Character Item's Slot ID, both perspective parents, its Item Set Rules, and its Animator setup as one controlled change; rebuilding a copy is safer for a complex item.

## Build common equipment layouts

| Scenario | Slot map | Character Items and Item Set |
| --- | --- | --- |
| Rifle or one-handed firearm | Right hand `0`; left hand `1` may stay empty | Build the firearm for slot `0`. The Item Set Rule places its definition at array position `0`. |
| Sword and shield | Sword/right hand `0`; shield/left hand `1` | Build separate Character Items for the two definitions and place each at its exact Item Set position. Their Animator Item IDs normally differ. |
| Two matching pistols or swords | Right hand `0`; left hand `1` | Add two slot-specific Character Item prefabs to the same definition, require an Inventory amount of two, and put that definition in both Item Set positions. Both Character Items may use the same Animator Item ID. |
| Independent utility item | Existing hand slots plus a contiguous custom ID | Add the same custom ID to every perspective that displays it, create a Character Item for that ID, and give it an Item Set Group or rule that can stay active with the main equipment. |

A holster is not usually another Inventory slot. Use the third-person item's **Holster Target** when one Character Item should move between its equipped and holstered positions without becoming an independently equipped item.

## Connect Item Sets, actions, and abilities

The Slot ID follows the item through the complete runtime flow:

1. An Item Definition owns one or more slot-specific Character Item prefabs.
2. Inventory creates the matching Character Items and stores them by Slot ID.
3. An Item Set Rule places definitions at exact slot positions. It cannot move a Character Item from one slot into another.
4. Equip Unequip activates the Character Item selected for each changed slot.
5. The Character Item Action belongs to that slot-specific Character Item. Its **ID** selects an action on the item; it does not select a slot.
6. Use and Reload can target **Slot ID -1** for every eligible equipped item or a specific Slot ID for independent hand controls.
7. Drop uses **Slot ID -1** to target all slots by default; enter one Slot ID when the ability should drop only that position.

An Item Pickup adds an Item Definition amount. Its Character Item prefabs and the Item Set Rules decide which slot-specific representations become available and which combination equips. A pickup does not relocate one Character Item between hands.

## Add Animator parameters for custom slots

The supplied Animator setup covers slots `0` and `1`. For every additional slot `X`, add this complete group to each Animator Controller that needs to animate it:

- `SlotXItemID` (**Int**)
- `SlotXItemStateIndex` (**Int**)
- `SlotXItemStateIndexChange` (**Trigger**)
- `SlotXItemSubstateIndex` (**Int**)

Animator Monitor considers a slot supported when it finds `SlotXItemID`, then writes all four values for that slot. Keep the group together. Adding the parameters does not create animation states or transitions; add conditions for the new item's Animator Item ID, item ability state, and substate.

For dual pistols, `Slot0ItemID` and `Slot1ItemID` can contain the same Animator Item ID because the parameter names keep the two hands separate. For a sword and shield, the two parameters normally contain different Animator Item IDs.

## Verify in Play Mode

1. Open the runtime **Item Set Manager** and confirm each generated set places its Character Items in the intended array positions.
2. Equip a single right-hand item. Confirm only slot `0` becomes active and the visible object appears under the correct third-person or first-person attachment.
3. Switch perspective. Confirm the same Character Item resolves the equivalent slot instead of moving to another hand or disappearing.
4. Equip a sword and shield or another two-item set. Confirm one active Character Item occupies each slot.
5. Test a dual-wield definition with an Inventory amount of two. Confirm the right and left prefabs resolve independently and both Slot Item ID parameters show the intended Animator value.
6. Run slot-specific Use, Reload, and Drop inputs. Confirm only the requested hand responds; then test an all-slot value of `-1` deliberately.
7. Pick up, unequip, re-equip, and drop the item. Confirm the Item Set becomes valid or invalid without changing the Character Item's assigned slot.
8. For a custom slot, watch its four Animator parameters and confirm its states enter and leave cleanly.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The item appears in the wrong hand. | Compare **Character Item > Slot ID** with the Character Item Slot ID on every active model and arm rig. | Give corresponding attachment points the same ID and rebuild or correct the Character Item's perspective parents. |
| **Build Character** or **Update Character** is disabled. | Open **Character Item Slots** and look for an invalid parent, duplicate parent, or duplicate ID within one model or arm group. | Assign a child of the displayed hierarchy and keep every parent and ID unique in that group. |
| **Build Item** reports that perspective slots do not match. | Compare the selected first- and third-person Character Item Slot IDs. | Select the equivalent locations or correct their IDs in Character Manager. |
| Inventory has more slots than expected. | Find the highest Character Item Slot ID and look for gaps or an obsolete component in an inactive hierarchy. | Remove the obsolete slot or make the intended IDs contiguous, then rebuild or reload the character before testing again. |
| The character owns the definition but no valid Item Set appears. | Check whether the definition has a Character Item prefab for the rule's exact array position and whether Inventory owns enough copies. | Add the missing slot-specific prefab, correct the rule position, or add the required amount. |
| The item is visible in one perspective only. | Check the active model or First Person Base Object for a matching Character Item Slot. | Add the missing logical slot and update the character, or remove support for the unused perspective from the Character Item. |
| The item equips but the Animator does not change. | Distinguish Slot ID from Animator Item ID and inspect the full four-parameter group. | Use the Animator Item ID expected by the controller and add the exact parameters and transitions for that slot. |
| One input uses or reloads both hands. | Inspect the ability's **Slot ID**. | Replace `-1` with the intended slot, or use separate slot-specific abilities and inputs. |
| Drop removes more equipment than intended. | Inspect **Drop > Slot ID**. | Replace the default `-1` with the one slot that the ability should drop. |

## Persistence and multiplayer

Treat Slot IDs as stable project data. A save system should restore Item Definition amounts and the intended Item Set, then let Inventory rebuild its slot-specific Character Items. Do not save scene Transform references or assume that a generated runtime Item Set index remains stable after its rules change.

The base Inventory forwards authoritative equip and unequip changes to a supported multiplayer integration with the Item Identifier and Slot ID. Every peer still needs the same slot map, Character Item prefabs, Item Definitions, and Item Set Rules. Keep third-person objects configured for remote observers; first-person objects remain a local-view concern unless the integration documents another ownership model.

## Related tasks

- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds a slot-specific Character Item prefab or an item directly on a character.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) owns Item Definition amounts and creates Character Items for their slots.
- [Item Type, Definition, and Category](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-type-definition-category/) explains the data identity shared by slot-specific Character Item prefabs.
- [Item Set and Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) defines the combinations that may occupy the slot array.
- [Dual Wielding](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/dual-wielding/) configures two hand slots, two Character Items, abilities, and animation together.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) explains Slot ID, Animator Item ID, perspective objects, and equip timing.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) adds definitions and can request a named Item Set.
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/), [Reload](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/), and [Drop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) explain slot-specific ability targeting.
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/) performs Item Set transitions across the changed slots.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) documents the four per-slot parameters and their runtime values.

## Developer details

Use Inventory's slot-aware methods when code needs to inspect or change equipment:

```csharp
int slotCount = inventory.SlotCount;
CharacterItem activeItem = inventory.GetActiveCharacterItem(slotID);
CharacterItem item = inventory.GetCharacterItem(itemIdentifier, slotID);

inventory.EquipItem(itemIdentifier, slotID, immediateEquip: false);
inventory.UnequipItem(slotID);
```

Ordinary player equipment changes should still go through Item Sets and item abilities so animation, State System, timing, and networking remain coordinated.

The main slot-aware Inventory events are `OnInventoryEquipItem` and `OnInventoryUnequipItem`, each with `(CharacterItem, int slotID)`, plus `OnInventoryRemoveItem` with the removed Character Item and its Slot ID. Character Item registers `OnAnimatorItemEquip`, `OnAnimatorItemEquipComplete`, `OnAnimatorItemUnequip`, and `OnAnimatorItemUnequipComplete` as slot-filtered animation events.

In released Version 3.2.0, Inventory determines its array size from Character Item Slot components during initialization. The count can grow when a higher ID is discovered, but the same initialized Inventory instance does not reduce its stored count after a high-ID component is removed. Configure slots before Play Mode and recreate or reload the character after reducing the highest ID.

Runtime lookup does not enforce the Character Manager's uniqueness rules. Manually added duplicate IDs can make a perspective resolve the first matching component, and negative Character Item Slot IDs are not valid array positions. Prefer Character Manager, contiguous nonnegative IDs, and one component per logical location.

---

<a id="page-ultimate-character-controller-items-inventory-animator-audio-state-set"></a>

# Animator Audio State Set

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/)

An Animator Audio State Set lets an item action choose an animation variation, an optional UCC State, and audio as one coordinated result. Use it when equipping, using, reloading, recoiling, or impacting should not always produce the same presentation.

## Before you begin

- Create a working Character Item and the action that owns the behavior. The state set does not start an item action by itself.
- Confirm that the character Animator has transitions for the intended `Slot<ID>ItemSubstateIndex` values. See [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/).
- Decide which consumer owns this choice. **Equip Animator Audio State Set** and **Unequip Animator Audio State Set** belong to the Character Item; use, reload, melee recoil, and shield impact sets belong to their corresponding action or module.
- Keep the optional **State Name** separate from the Animator state. It names a UCC State to activate on the character while this entry is selected.

## Configure an Iron Sword attack sequence

This example alternates an Iron Sword between a right slash and a left slash. The example substate values `2` and `3` must correspond to transitions in your Animator Controller.

1. Select the Iron Sword Character Item and expand its Melee Action.
2. In **Trigger Modules**, select the enabled combo trigger and expand **Use Animator Audio State Set**.
3. Set **Selector** to **Sequence**.
4. Leave **Reset Delay** at `-1` when the sequence should continue across uses. Set a positive delay when the next attack after a pause should return to the first entry.
5. Add two entries to **Animator Audio States** and keep both **Enabled**.
6. Select the first entry and set **Item Substate Index** to `2`. Select the second and set it to `3`.
7. Leave **Allow During Movement** enabled unless a slash must be skipped while moving. Enable **Require Grounded** only for an attack that cannot run in the air.
8. Expand **Audio Clip Set**, assign its **Audio Config**, and add the clips that may accompany that entry. Multiple clips let the audio set choose a clip without changing the selected animation entry.
9. Leave **State Name** empty for a normal slash. Assign a State only when that variation must temporarily change another property, such as the attack's damage preset.
10. On the trigger module, choose whether **Play Audio On Start Use** should play the clip as the use begins or whether the owning use timing should play it when the item is used.

A Simple Combo or Repeat Combo trigger advances the set for each chained use. The state set selects the variation; the trigger and [animation event timing](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) still decide when the attack starts, is applied, and completes.

### Editor checkpoint

Before entering Play Mode, the enabled trigger should show **Selector: Sequence**, two enabled entries, substate values `2` and `3`, and Animator transitions for both values. Each entry should have at least one selectable condition and only the audio and optional UCC State that belong to that variation.

## Configure firearm variations

For a firearm, use **Random** when several firing animations or sounds are interchangeable:

1. Expand the firearm's trigger module and its **Use Animator Audio State Set**.
2. Set **Selector** to **Random** and add one entry for each firing variation.
3. Give every entry an **Item Substate Index** that the firearm's Animator supports, then configure its **Audio Clip Set**.
4. Expect Random to choose with replacement, so the same variation can occur twice in a row.
5. Keep **State Name** empty unless you have accounted for the released-Version-3 initialization limitation described below.

Configure reload presentation separately under the shootable action's **Reload Animator Audio State Set**. A full-magazine reload normally needs one entry; a shell-by-shell reload can advance its set as each round is inserted. Do not combine firing and reload substates merely because both belong to the same firearm.

## Key choices

| Selector | Use it when | Important behavior |
| --- | --- | --- |
| **Sequence** | Attacks, equips, or reload stages should advance in order. | This is the default selector. **Reset Delay** defaults to `-1`, which never resets the sequence because of elapsed time. Invalid or disabled entries are skipped and the list wraps. |
| **Random** | Any eligible variation may play next. | A choice may repeat. Movement, grounded, and enabled checks are applied before the entry is accepted. |
| **Matching Recoil** | A melee recoil should correspond to the Use variation that caused the hit. | Released Version 3 uses the final numeric Use substate directly as a zero-based recoil entry index. Keep that value in range and align the recoil list accordingly; a blocked recoil then adds the configured blocked offset. |
| **Sequence Recoil** | Recoil variations should advance in order. | It has the same reset behavior as Sequence and defaults **Blocked Recoil Item Substate Index** to `20`. |
| **Random Recoil** | Recoil variations may be chosen randomly. | It uses the same blocked offset and eligibility checks as the other recoil selectors. |

Each entry starts with **Enabled** and **Allow During Movement** on, **Require Grounded** off, **State Name** empty, and **Item Substate Index** `0`. Disable an entry to keep its configuration without selecting it. Always leave at least one enabled entry whose movement and grounded requirements can be met.

Leave **State Name** empty on Matching Recoil entries in released Version 3. The recoil owner starts selection before copying the current Use substate into that selector, so a named State can be activated or deactivated from the previous row rather than the current hit.

The selected entry controls two independent choices:

- **Item Substate Index** contributes the variation value used by the owning item ability or action. The Animator must already know what that value means.
- **Audio Clip Set** chooses audio from that entry when the owner requests playback. It does not choose a different Animator entry.

## How it runs

The owning Character Item or action initializes the set with its Character Item and Ultimate Character Locomotion. When the operation starts, the owner starts selection and advances the selector. The selector skips entries that are disabled, disallow the character's current movement, or require a grounded character when the character is airborne.

After an entry is selected, its **State Name** is activated through the UCC State System and its **Item Substate Index** is returned to the owner. The owner combines that value with its own item-state data and updates the slot's Animator parameters. It also decides when to call the entry's Audio Clip Set and which visible item or character GameObject emits the clip. When the operation stops or the selector changes entries, the previous named State is deactivated.

Equip and unequip are timed by `OnAnimatorItemEquip`, `OnAnimatorItemEquipComplete`, `OnAnimatorItemUnequip`, and `OnAnimatorItemUnequipComplete`, or their configured delays. Use, reload, and shield impact have their own animation-event or duration controls. The Animator Audio State Set supplies the selected variation; it does not replace those timing controls or call an Animator trigger directly.

### Persistence and multiplayer

The selector type, entries, conditions, State names, substate values, Audio Config, and clips serialize with their owning item or action. The current and next runtime indexes are not save data; after loading or respawning, let the owning item/action initialize and select again.

Animator Audio State Set has no built-in network message for its chosen index or random audio clip. A networking integration can synchronize the owning action and Animator parameters, but separate Random selectors are not guaranteed to make the same choice. If an exact variation affects gameplay or must match across clients, synchronize that decision through the game/network integration instead of relying on local randomness.

## Verify in Play Mode

1. Equip the Iron Sword and watch its live `Slot<ID>ItemStateIndex` and `Slot<ID>ItemSubstateIndex` parameters in the Animator.
2. Perform two valid combo attacks. The first should use substate `2`, the second `3`, with the matching clip and no unrelated UCC State left active afterward.
3. Wait longer than a positive **Reset Delay** and attack again. The sequence should return to its first eligible entry; with `-1`, it should continue wrapping normally.
4. Test while moving and airborne. Entries should be skipped only when their **Allow During Movement** or **Require Grounded** settings require it.
5. Fire the firearm repeatedly. Every selected substate must have a valid transition, audio must occur at the chosen start/use timing, and repeated Random choices should remain valid.
6. Reload the firearm and confirm the reload set, not the firing set, controls its substate and audio.
7. If multiplayer is enabled, compare the authoritative and remote character. Confirm that any gameplay-significant variation is explicitly synchronized.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The action runs but the animation does not change. | Watch the live slot Item State and Item Substate parameters and compare them with the Animator transitions. | Add or correct the transition for the complete value produced by the action and selected entry. |
| Sequence always appears to use one entry. | Confirm that every list row is enabled and that the owning trigger advances the set for each use. | Enable the intended rows and use a combo/repeat workflow when multiple chained uses are expected. |
| No entry can be selected. | All entries may be disabled or rejected by movement and grounded requirements. | Keep at least one enabled entry valid for the current locomotion state. |
| The wrong entry plays while moving or airborne. | Inspect **Allow During Movement** and **Require Grounded** on that entry. | Set the two conditions to match the gameplay rule and retest both locomotion states. |
| The correct animation plays but audio is silent. | Check **Audio Config**, the clip list, the visible item, and **Play Audio On Start Use** versus the owner's event timing. | Assign valid audio, then choose the start/use moment that the owning action actually reaches. |
| A UCC State stays active longer than expected. | **State Name** may be assigned to the wrong entry, or the owning operation may not reach its stop path. | Remove unnecessary State names and verify that the use, equip, reload, recoil, or impact completes normally. |
| A Random entry's State is active before the item is used. | In released Version 3, Random and Random Recoil call `NextState()` during initialization, which can activate the first valid entry's **State Name**. | Leave **State Name** empty on those selectors or manage that State from the owning action. |
| Matching Recoil returns no variation or changes the wrong UCC State. | The Use substate may not be a zero-based, in-range recoil entry index, or the recoil entries may have **State Name** values. | Align the Use values with the recoil list and leave Matching Recoil **State Name** empty in released Version 3. |
| Clients show different Random variations. | The set does not network its random choice. | Synchronize the chosen variation through the networking integration when the exact result must match. |

## Related tasks

- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/)
- [Usable Item Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/)
- [Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/)
- [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/)
- [Use ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Reload ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/reload/)
- [Block ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/block/)
- [Equip Unequip](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

`AnimatorAudioStateSet` exposes `Awake`, `StartStopStateSelection`, `GetStateIndex`, `GetNextStateIndex`, `SetNextStateIndex`, `GetItemSubstateIndex`, `PlayAudioClip`, `NextState`, and `OnDestroy`. Array-index variants are also available for a custom selector that owns more than one pending choice.

To add a selection policy, derive from `AnimatorAudioStateSelector`. The released Version 3 initialization signature is `Initialize(GameObject, UltimateCharacterLocomotion, CharacterItem, AnimatorAudioStateSet.AnimatorAudioState[], int count)`. Override the current/next index accessors and `NextState()` as needed; `NextState()` returns whether selection changed successfully. Override `GetAdditionalItemSubstateIndex()` when a context such as blocked recoil must add an offset.

The set itself raises no public gameplay event. Its optional named State is changed through `StateManager`, while the owning Character Item or action controls animation events, audio timing, and any network or save integration.

---

<a id="page-ultimate-character-controller-items-inventory-item-pickup"></a>

# Item Pickup

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/)

Item Pickup adds one or more Item Definitions to a character's Inventory from a world object. Use it for scene loot, ammunition bundles, and items that a character can drop and collect again.

## Before you begin

- Create the Item Definitions that the pickup will grant. An equippable definition also needs a Character Item prefab, a compatible slot, and a valid Item Set Rule on the character.
- Confirm the character has an enabled [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/). Equipping also requires an Item Set Manager.
- Use a visual model rather than an already built Character Item when creating the pickup.

## Create the pickup object

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name** and assign the visible model to **GameObject**.
3. Set **Object Type** to **Item Pickup** for loot placed in the scene. This route adds an Item Pickup, a trigger collider, a solid collider, and a Respawner.
4. Set **Object Type** to **Dropped Item** when the prefab will be assigned to a Character Item's **Drop Prefab**. This route adds an Item Pickup, colliders, and a Trajectory Object instead of a Respawner.
5. Select **Build Object**, choose where to save the prefab, and then select the created object.
6. On **Item Pickup**, add an entry to **Item Definition Amounts** for every definition and quantity that a scene pickup should grant.
7. Size the trigger collider around the interaction area. The trigger must be on the same GameObject as Item Pickup.

![Item Pickup Inspector used to configure trigger behavior, item amounts, equipping, audio, and pickup messages](https://opsive.com/wp-content/uploads/2022/10/ItemPickup.png)

### Editor checkpoint

A scene pickup should have **Item Pickup**, one collider with **Is Trigger** enabled, a solid collider for its physical shape, and **Respawner** when it should return. A dropped-item prefab should have **Trajectory Object** and normally leaves **Item Definition Amounts** for the Drop workflow to fill at runtime.

## Configure what the pickup grants

Each **Item Definition Amounts** row adds that definition up to its Item Type's configured **Capacity**.

### Iron Sword pickup

1. Add the Iron Sword Item Definition with an amount of `1`.
2. Enable **Equip** when the sword should become active immediately after collection.
3. Leave **Item Set Group** at `-1` to search all groups, or enter the group that owns the sword.
4. Leave **Item Set Name** empty to use the first valid set containing the sword. Enter a name only when the pickup must select a specific Item Set State; the text must match that State name exactly.

Disable **Equip** when the sword should enter the Inventory without changing the current loadout.

### Firearm and ammunition pickup

Add the firearm Item Definition with an amount of `1`, then add its ammunition Item Definition with the desired quantity. Enable **Equip** to select a valid firearm Item Set after both definitions are added. The firearm needs a Character Item prefab in the appropriate slot; count-only ammunition does not need a visible Character Item.

The Inventory limits each amount by the Item Type's **Capacity**. Test a nearly full Inventory so the object and the accepted amounts match the intended game design.

## Choose how collection starts

### Collect on contact

Keep **Pickup On Trigger Enter** enabled for the default no-input workflow. When an eligible character enters the trigger, Item Pickup finds its Inventory, adds the configured definitions, optionally selects an Item Set, and then depletes the world object. The character does not need the Pickup ability for this route.

Use this for ammunition, automatic loot, and other objects where walking through the trigger is the complete interaction.

### Play a pickup animation

Disable **Pickup On Trigger Enter** when the character should press an input and play a reach animation.

1. Add the [Pickup ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/) to the character.
2. Keep **Allowed Pickups** set to **Item**, and ensure the ability's **Detect Layers** includes the pickup layer.
3. Use **Pickup Event** to add the item at the contact frame. The included event name is `OnAnimatorPickup`.
4. Use **Pickup Complete Event** to finish the ability. The included completion event is `OnAnimatorPickupComplete`.

An empty **Pickup Item Definitions** list lets any detected Item Definition use the animation. If only selected definitions should animate, use a single filter entry and verify the result in Play Mode; see the released-version note under [Developer details](#developer-details).

### Reuse a Character Item as a world drop

1. Build the prefab with **Object Type > Dropped Item**.
2. Assign it to the Character Item's **Drop Prefab** field.
3. Add a [Drop ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) to the character.

At runtime, Drop replaces the prefab's **Item Definition Amounts** with the unit removed from the Inventory and any additional identifiers supplied by the Character Item's actions, such as ammunition. If the prefab has a Trajectory Object, Drop also initializes its motion from the character.

## Key choices

| Choice | Starting value | Use it when |
| --- | --- | --- |
| **Trigger Enable Delay** | `4` seconds | A reused or dropped pickup must wait before it can be collected again. On its first scene activation, the trigger is enabled immediately. |
| **Pickup On Trigger Enter** | Enabled | Contact should collect the object. Disable it for the Pickup ability workflow. |
| **Always Pickup** | Disabled | Enable it when the object should be consumed even when the Inventory cannot accept more. The released Version 3.2.0 capacity behavior has a limitation described under [Developer details](#developer-details). |
| **Equip** | Enabled | A valid Item Set containing a collected Character Item should become active. Use and Reload can prevent the equip change while they are active. |
| **Item Set Group** | `-1` | All Item Set groups should be searched. Enter a group index to constrain selection. |
| **Item Set Name** | Empty | The first valid set containing the item is acceptable. Enter an exact State name to request one set. |
| **Destroy Delay** | `0` | The collected object should be removed immediately. Use a positive value for delayed removal; `-1` leaves a depleted object present and does not make it repeatable. |

Use **Rotation Speed** for a simple display rotation. **Pickup Audio Clip Set**, **Pickup Message Text**, and **Pickup Message Icon** provide collection feedback. **On Select** and **On Deselect** are useful when the Pickup ability detects the object before the input is pressed.

For a reused pickup with a Rigidbody, **Trigger Enable Delay** starts after the Rigidbody settles. The Object Manager's **Dropped Item** uses Trajectory Object without adding a Rigidbody, so its delay starts when the drop is initialized rather than when the trajectory visibly stops. Set a delay long enough for the flight, or add a project-specific gate when collection must wait for landing.

## Verify in Play Mode

1. Keep the character's Inventory and the pickup's Item Pickup component visible.
2. Enter an automatic pickup trigger. Confirm the configured Item Definition amounts increase once, the world object is removed or deactivated, and **Equip** selects the intended Item Set when enabled.
3. Repeat with the Inventory close to the Item Type's **Capacity**. Confirm only the allowed amount is added and review the capacity limitation below if the world object is consumed after adding zero.
4. For an animated pickup, enter the detection trigger and press the configured input. Confirm the object remains until the pickup event, the Inventory changes on `OnAnimatorPickup`, and the ability stops on `OnAnimatorPickupComplete` or its configured duration.
5. Drop an equipped Iron Sword or firearm. Confirm the world object receives the dropped definition and quantity, cannot be recollected during **Trigger Enable Delay**, and restores the item when collected.
6. For a scene pickup with Respawner, wait for its configured respawn time and confirm it returns ready to collect again.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Contact does not collect the item. | Check for a trigger collider on the Item Pickup GameObject, an enabled character Inventory, the pickup and character layers, and **Pickup On Trigger Enter**. | Restore the trigger and collision-layer interaction. Enable contact pickup, or complete the Pickup ability setup for an input-driven object. |
| The item is collected before its animation. | **Pickup On Trigger Enter** is still enabled. | Disable it and let the Pickup ability perform the transfer at **Pickup Event**. |
| The Inventory changes but no held item appears. | Check the Character Item prefab, slot, Item Set Rule, **Equip**, **Item Set Group**, and **Item Set Name**. Also check whether Use or Reload is active. | Complete the Character Item and Item Set setup, correct the exact State name, and retry when the conflicting ability is inactive. |
| Pickup starts but the Inventory never changes. | **Pickup Event** may be waiting for a missing `OnAnimatorPickup`. | Add the event to the active clip, or disable event waiting and use a duration. |
| The Inventory changes but Pickup stays active. | **Pickup Complete Event** may be waiting for a missing `OnAnimatorPickupComplete`. | Add the completion event, or use duration mode. |
| A dropped item is collected while still moving. | **Trigger Enable Delay** may expire before a Trajectory Object finishes moving. | Increase the delay or add a landing-aware project-specific gate. |
| The model remains but cannot be collected again. | **Destroy Delay** may be `-1`; the object remains depleted after collection. | Use Respawner or explicitly reinitialize the object instead of treating `-1` as repeatable mode. |
| The object is consumed even though capacity prevented an addition. | This is a released Version 3.2.0 Item Pickup result-check limitation. | Avoid relying on **Always Pickup** for full-capacity persistence; precheck capacity or use a corrected custom Item Pickup when the world object must remain. |

## Persistence, pooling, and multiplayer

The Object Manager's scene **Item Pickup** includes a Respawner, so a non-pooled object can be reactivated after it is disabled. A pooled pickup returns through the Opsive object pool and resets when reused. Verify the selected lifetime path returns the pickup once with the expected delay.

Item Pickup does not by itself save world depletion or respawn timers. A save integration must persist both the authoritative Inventory and any pickup state that should survive loading; otherwise a saved Inventory can coexist with a newly restored copy of the world item.

The multiplayer hooks are compiled only with a supported UCC multiplayer integration. That integration owns Inventory replication and network object spawning or destruction. Item Pickup alone is not a transport or authority system, so verify collection and dropped-prefab ownership with the chosen integration.

## Related tasks

- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) configures capacities, Character Item prefabs, and runtime item ownership.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds the Item Definition and Character Item used by an equippable pickup.
- [Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) determine which collected items form a valid loadout.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) explains the held item and its **Drop Prefab**.
- [Pickup ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/) configures input, detection, and animation timing.
- [Drop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) removes an equipped unit and initializes its pickup prefab.
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) controls motion on a dropped-item prefab.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) controls when a scene pickup returns.

## Developer details

`ItemPickup` derives from `ItemPickupBase`, which derives from `ObjectPickup`. The public pickup flow wraps the inventory transfer with `OnItemPickupStartPickup` and `OnItemPickupStopPickup`; a completed object pickup sends `OnObjectPickedUp`. Inventory additions send `OnInventoryPickupItemIdentifier`, and a spawned Character Item also sends `OnInventoryPickupItem`.

`Destroy Delay` equal to `0` removes the pickup immediately, a positive value schedules removal, and a negative value leaves it active but depleted. Pooled objects use `ObjectPoolBase.Destroy`; a supported multiplayer build uses its network object pool. Non-pooled objects are deactivated so a Respawner can restore them.

The released Version 3.2.0 source has two pickup edge cases to account for:

- Item Pickup treats an Inventory return value of `0` as a successful transfer. Because `0` is also returned when capacity accepts none of a valid definition, the world object can become depleted even while **Always Pickup** is disabled. Precheck capacity or use a corrected `ItemPickupBase` implementation when the object must remain.
- With more than one **Pickup Item Definitions** filter entry on the Pickup ability, a nonmatching first entry can prevent later entries from selecting the animated path. Prefer one entry per Pickup ability and verify multi-definition filters before shipping.

---

<a id="page-ultimate-character-controller-animation"></a>

# Animation

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/)

Ultimate Character Controller uses Unity's Animator for authored character and item clips, Animator Monitor to connect controller values to Animator parameters, Animation Event Triggers to coordinate gameplay timing, and springs for procedural camera and item motion. Start with the supplied Animator Controller as a working reference, then customize one behavior at a time and verify it in Play Mode.

## Understand the animation parts

- **Animator Controller:** Owns animation states, transitions, layers, masks, and clips for locomotion, abilities, and item actions. [Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/) is the entry point for this workflow.
- **Animator parameters and Animator Monitor:** Animator Monitor transfers movement, ability, and item values to the Animator. A custom controller can use a different state-machine layout, but it must include the parameters required by the character and item setup.
- **Animation Event Trigger:** Lets an ability or item action wait for a named animation event or use a duration instead. This keeps gameplay actions synchronized with authored clips without putting gameplay logic in the Animator Controller.
- **Item animation selection:** Animator Item ID, Movement Set ID, Item State Index, and Item Substate Index select the equipped-item stance and action variation. Visible first-person or third-person items can also have their own Animator Controller.
- **Procedural motion:** [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/), bobs, and noise add responsive motion such as first-person item sway, camera movement, and recoil without replacing an animation clip.

## Follow the recommended workflow

1. Build or select a working character through [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/), then enter Play Mode with the supplied Animator Controller unchanged.
2. Test idle, movement, jump and fall, one ability, and one item. This baseline separates setup problems from later animation changes.
3. Read [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) to understand the supplied layers, then use [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) and [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) when building a project-specific controller.
4. Keep a project-owned copy of the controller before replacing clips. Use [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) to preserve all affected layers and event timing.
5. Review every changed clip for its required [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/). When an event is not appropriate, deliberately configure the trigger to use its duration instead.
6. Configure item animation IDs, controllers, states, and variations through [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) and [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/).
7. Add procedural spring, bob, or noise motion only after the authored clips and gameplay timing work correctly.

## Replace supplied clips safely

For a small change, replace the clip in every Animator layer and state that uses it. A locomotion or item clip may appear in multiple masked layers, so changing only the Base Layer can cause the upper and lower body to disagree.

For a larger replacement set:

1. Open **Tools > Opsive > Ultimate Character Controller > Animation Replacer**.
2. Assign the project-owned controller to **Animator Controller**.
3. Optionally assign a **Replacement Template**, or assign replacement clips individually.
4. Leave **Replace Events** enabled when the replacement clips should receive the events from the supplied clips.
5. Review the replacement mapping, select **Replace**, then test the changed controller before replacing another group.

The Animation Replacer updates clips; it does not decide whether a replacement pose, mask, transition, or event time is correct for the project.

## Coordinate gameplay with animation events

Use [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) for ability timing such as the point when Jump applies its force. With **Wait For Animation Event** enabled, the clip must send the event expected by that field. In Unity's Animation window, set the event **Function** to `ExecuteEvent` and its **String** value to the expected event name.

Use [Animation Slot Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/animation-slot-event-trigger/) when item timing must distinguish between item slots. For a character with both perspectives, update the event on every first-person and third-person clip that can perform the action.

If the timing is wrong, enable **Log Events** on Animator Monitor. The Console call stack shows whether the event came from the Animator or from the duration-based Scheduler path.

## Configure item animations

Treat an item animation as three connected choices:

1. **Which item is equipped:** **Animator Item ID** drives the slot's Item ID parameter.
2. **Which action and variation should play:** Item State Index and Item Substate Index select actions such as equip, use, or reload and their variations. [Animator Audio State Set](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/animator-audio-state-set/) controls how a variation is selected.
3. **Which model animates:** A visible first-person or third-person item can use its own Animator Controller in addition to the character's controller.

When both perspectives are supported, verify the character body, first-person arms, and visible item together. Generic first-person arm rigs cannot use Unity's humanoid retargeting; see [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) before replacing that rig or its clips.

## Add procedural motion

Use [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) when the result should react continuously instead of playing a fixed skeletal clip. Stiffness controls how strongly the value returns toward rest, while damping controls how quickly its velocity settles. Bobs provide repeating sinusoidal movement, and noise provides irregular motion.

Tune one source at a time. First verify the authored animation with springs, bobs, and noise minimized; then add procedural motion and confirm that it returns to rest without persistent drift or excessive camera movement.

## Continue by task

- **Understand or replace Animator content:** [Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/) routes to the supplied controller structure, parameters, default values, first-person arms, and clip replacement.
- **Synchronize an ability or item action:** [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) covers named events, duration fallback, logging, and slot-aware item events.
- **Add camera or item motion without another clip:** [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) covers springs, bobs, noise, and their tuning fields.

## Verify in Play Mode

1. Open the Animator window and select the active character. Movement parameters should change as the character starts, stops, turns, and changes speed, and the controller should return cleanly to idle.
2. Run each changed ability. Confirm that its Ability Index and data parameters select the expected state and return when the ability ends.
3. Equip, aim, use, reload, and unequip each changed item. Confirm the correct slot Item ID, Item State Index, and Item Substate Index, plus matching body and visible-item animation.
4. Test animation-driven events at normal speed and during rapid input. The ability or item action should not complete before the intended frame or remain stuck waiting for an event.
5. When both perspectives are present, repeat the action in first person and third person and confirm that both sets of clips and events agree.
6. Re-enable procedural motion and confirm that recoil, sway, bob, and noise react as intended and settle back to rest.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character does not leave idle or uses the wrong state. | Required Animator parameters or transitions may be missing from the custom controller. | Compare the controller with [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) and watch the live values in the Animator window. |
| An ability or item remains active indefinitely. | An Animation Event Trigger may be waiting for an event the replacement clip never sends. | Add the expected `ExecuteEvent` event and String value, or disable **Wait For Animation Event** and configure a deliberate duration. |
| A replacement affects only part of the body. | The old clip may still be used on another masked layer. | Search every layer for the old clip and replace each intended occurrence. |
| The wrong item animation plays. | Animator Item ID, Movement Set ID, slot Item State Index, or Item Substate Index may not match the Animator states. | Compare the live parameters with the item's configured IDs and Animator Audio State Set. |
| First-person arms distort or do not retarget. | The arms may use a generic rig. | Use clips authored for that rig or follow the alternatives in [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/). |
| Camera or item motion oscillates for too long. | Spring stiffness and damping may not be balanced. | Minimize other motion sources, tune stiffness and damping together, then restore bob and noise one at a time. |

---

<a id="page-ultimate-character-controller-animation-springs"></a>

# Springs

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/)

Springs add responsive camera and item motion without requiring an animation clip. Use them for movement sway, landing impact, recoil, and other motion that should return to a rest position or rotation.

![Spring-driven first-person camera and item motion returning toward rest](https://opsive.com/wp-content/uploads/2018/03/AnimationSprings.png?v=364fd33bef12)

## Find the spring controls

The same Spring controls appear inside several Ultimate Character Controller features. Start with the object whose motion you want to change:

1. For camera motion, select the camera with the **Camera Controller** component, expand **View Types**, and select the active first- or third-person View Type.
2. Expand **Primary Spring** to tune regular position and rotation response. Expand **Secondary Spring** for brief reactions such as recoil.
3. For first-person item motion, select the item object with the **First Person Perspective Item** component and expand its **Position Spring**, **Rotation Spring**, or pivot spring.
4. Enter Play Mode with the supplied values first. Change one spring and one axis at a time so that authored animation, head motion, bob, and shake are not mistaken for spring motion.

## Choose the motion source

| Desired result | Controls to use | Why |
| --- | --- | --- |
| Regular camera or item response while moving | **Primary Spring** | Its Position and Rotation Springs handle continuous motion around their rest values. |
| Recoil or another brief impulse | **Secondary Spring** | It is intended to receive a short force and return to equilibrium. |
| A repeatable walking rhythm | **Bob** | Rate sets how quickly the cycle repeats; amplitude sets how far it moves. |
| Irregular breathing, instability, or camera shake | **Shake** | Speed and amplitude generate continuous smooth variation rather than a repeating cycle. |
| A deliberate pose or repeatable action such as reloading | An animation clip, optionally combined with subtle procedural motion | Springs react to forces; they do not replace authored action timing. |

### Bob

Bob adds sinusoidal motion to the first-person camera or item. A small vertical amplitude can suggest footsteps, while carefully balanced horizontal and vertical amplitudes can make a large character feel heavier.

![Sinusoidal position and rotation bob applied to first-person motion](https://opsive.com/wp-content/uploads/2018/03/AnimationBobs.png?v=8349e0826967)

Use **Bob Positional Rate** and **Bob Roll Rate** for frequency, and use their amplitude fields for strength. **Bob Input Velocity Scale** changes how strongly character speed feeds the effect, while **Bob Max Input Velocity** prevents extreme movement speeds from producing extreme bob. Keep **Bob Require Ground Contact** enabled when normal walking bob should stop in the air.

### Shake

Shake adds smooth, irregular rotation to the first-person view. It is useful for restrained breathing motion, status effects, or a brief unstable-camera presentation, but large continuous values can make the view uncomfortable.

![Irregular procedural shake applied to a first-person camera or item](https://opsive.com/wp-content/uploads/2018/03/AnimationNoise.png?v=2f27c094764e)

Use **Shake Speed** to change how quickly the variation develops and **Shake Amplitude** to limit its strength on each axis. Start with a very small amplitude and test while moving and aiming, not only while idle.

## Tune a spring

Expand a Spring property to reveal its shared settings:

![Expanded Spring Inspector with stiffness, damping, velocity, and value limits](https://opsive.com/wp-content/uploads/2018/03/SpringInspector.webp?v=6b0839275a67)

| Setting | What it changes in Version 3 |
| --- | --- |
| **Stiffness** | Controls the pull toward the rest value. The current calculation uses `1 - Stiffness`, so a lower value produces a stronger return and a higher value produces a weaker return. |
| **Damping** | Multiplies the remaining velocity on every update. A lower value removes velocity faster; a higher value preserves it longer and can allow more oscillation. |
| **Velocity Fade In Length** | Scales newly applied forces from zero to their full strength for this duration after the spring initializes, reducing an abrupt start. |
| **Max Soft Force Frames** | Limits how many frames a soft force can be distributed across. More frames spread the same force over a longer interval. |
| **Min Velocity** | Sets the final snap-to-rest tolerance. Increase it slightly when tiny residual movement takes too long to finish. |
| **Max Velocity** | Caps the magnitude of the spring velocity so a large force cannot produce an unlimited response. |
| **Min Value** and **Max Value** | Clamp the resulting position or rotation on each axis. Use them as safety limits, not as the main way to shape the motion. |

Because **Stiffness** and **Damping** follow the shipped Spring calculation, their tuning direction may be different from what their everyday names suggest. Change one of them at a time and judge the complete return-to-rest motion in Play Mode.

## Tune common scenarios

### Recoil

Use the Secondary Position or Rotation Spring for the short impulse. Begin with a small force, lower **Damping** if the camera or item keeps ringing, and use value limits to prevent an extreme kick. The motion should return to its original framing without a lasting offset.

### Landing impact

On a first-person camera, **Position Fall Impact** pushes the position spring when the character lands, and **Rotation Fall Impact** adds roll. Their **Softness** fields distribute that force across a number of frames. Increase softness for a less abrupt reaction; reduce the impact values if normal jumps are distracting.

### Movement sway

Use the primary position and rotation springs for regular camera or first-person item response. On an item, the sway, slide, and input-velocity fields determine which character movement feeds those springs. Establish the spring return first, then introduce look sway, strafe sway, or slide one source at a time.

### Heavy footsteps

Use Bob for the repeating step rhythm. The camera's **Bob Min Trough Vertical Offset** identifies the lower part of the cycle, and **Bob Trough Force** can add a short secondary reaction there. Keep the force small and verify it at every supported movement speed.

## Verify in Play Mode

1. Stand still after the character and camera initialize. The tested object should settle at its rest position or rotation without drifting.
2. Walk, run, strafe, jump, and land. Regular motion should remain controlled and return to rest after input stops.
3. Trigger recoil or the feature that adds a secondary force. The impulse should be readable, then finish without a permanent offset or repeated vibration.
4. Test the lowest and highest supported movement speeds. Bob and sway should not grow beyond the intended range.
5. Switch perspectives, equip and unequip items, and pause or change the character time scale if those actions are supported. Motion should resume from a stable state rather than carrying an unrelated force into the new state.
6. Repeat the test while aiming at a small target. The effect should communicate motion without obscuring gameplay or making the camera uncomfortable.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Motion oscillates for too long. | **Damping** may be preserving too much velocity, or several motion sources may be active together. | Lower **Damping**, then disable bob, shake, and authored motion temporarily to isolate the spring. |
| The object returns too slowly. | A high **Stiffness** weakens the return in the Version 3 calculation. | Lower **Stiffness** in small steps and retest the full motion. |
| Motion snaps when the scene starts. | **Velocity Fade In Length** may be too short for forces applied immediately after initialization. | Increase the fade-in length and replay the scene from its initial state. |
| A landing or other event snaps. | Its soft force may be applied across too few frames. | Increase that feature's **Softness** value without changing the total force, then repeat the event. |
| Tiny movement never appears to finish. | The **Min Velocity** snap-to-rest tolerance may be too small, or another bob or shake source may still be running. | Increase the tolerance slightly and isolate the other procedural motion groups. |
| Fast movement produces a large sway or bob spike. | Input velocity may be scaled too strongly or allowed to grow too high. | Reduce the relevant input velocity scale and set a suitable maximum input velocity. |
| Walking bob continues while airborne. | **Bob Require Ground Contact** is disabled. | Enable it when bob should be driven only by grounded movement. |
| A spring does not move. | The force or amplitude may be zero, the value may already be clamped, or the character or global time scale may be zero. | Confirm the source value, limits, active View Type or item, and time scale before changing the spring response. |

## Related tasks

- [Configure a first-person View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [Configure a third-person View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)
- [Configure a first-person perspective item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/)
- [Add first-person leaning](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/first-person-lean/)
- [Set up the Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/)
- [Configure inverse kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/)

## Developer reference

`Spring` is initialized as positional or rotational and schedules its update in either Update or Fixed Update. Each update pulls the current value toward `RestValue`, multiplies the accumulated velocity by **Damping**, clamps the velocity and value, and resets when the remaining distance is within **Min Velocity**. A soft force divides its total force across the requested number of frames, capped by **Max Soft Force Frames**. Spring updates stop while the spring's local time scale or the global `TimeUtility.TimeScale` is zero.

---

<a id="page-ultimate-character-controller-animation-animator"></a>

# Animator

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/)

Use the Animator workflow to connect Ultimate Character Controller gameplay to a humanoid or generic model, then customize states, clips, and first-person arms without breaking the controller's parameter contract.

## Start with a working character

The Character Manager is the supported starting point because it assigns the Animator Controller, adds Animator Monitor, and ensures the controller contains the required parameters.

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the character and enable **Animator**.
3. For each configured model, choose **Model Type**:
   - Choose **Humanoid** for a valid humanoid Avatar. The supplied Animator Controller can provide a working baseline.
   - Choose **Generic** for a non-humanoid rig. Assign an Animator Controller made for that rig; the supplied humanoid controller cannot be used as its animation source.
4. Assign the controller in **Animator Controller**.
5. Select **Build Character** for a new character or **Update Character** for an existing one.
6. Select the configured model in the Hierarchy. It should have both **Animator** and **Animator Monitor** components when it uses full-body animation.
7. Enter Play Mode before changing the supplied controller. Confirm idle, movement, turning, one ability, and one equipped-item action so the original setup provides a known-good baseline.

A first-person-only character can operate without a full-body Animator. Animator Monitor still holds the controller values and can forward them to supported item animators.

## Follow the recommended customization route

1. Read [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) to understand the supplied layers, masks, and the difference between locomotion, ability, and item states.
2. Keep the names and types documented in [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/). A custom state-machine layout is allowed, but its transitions still depend on the controller values that Animator Monitor updates.
3. Use [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) when matching an Ability Index, Item State Index, Animator Item ID, or Movement Set ID to a transition.
4. Make a project-owned copy of the working controller before editing states or clips.
5. Change one behavior at a time. Watch the live parameters and active state in Unity's Animator window before moving to the next change.
6. Use [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) for clip changes, including every affected layer and required animation event.
7. Treat [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) as a separate rig decision. The supplied first-person arms use a generic rig, so their clips must be authored for that rig rather than humanoid-retargeted automatically.

## Make the important choices

### Supplied or custom controller

Use the supplied controller to establish a working baseline and as a reference for parameters, layers, masks, and transition conditions. Use a project-owned controller when the game's state layout or animation set differs substantially. The layout itself is flexible; the required parameter names, types, IDs, and event timing are the compatibility points.

### Humanoid or generic model

Humanoid models can use Unity retargeting and the supplied humanoid controller. Generic models need clips and an Animator Controller made for their hierarchy. Changing **Model Type** to **Generic** in Character Manager intentionally clears the supplied controller selection so a compatible controller can be assigned.

### Full body or separate first-person arms

A full-body model normally has Animator Monitor beside its Animator. Visible first-person arms or item objects can use their own Animator and Child Animator Monitor. When both perspectives are supported, verify the character body, arms, and visible items because they can use different controllers and clips.

### Animator Monitor tuning

Keep **Animator Speed** at `1` unless all animation playback on that Animator should be scaled. **Update Mode** is passed to Unity's Animator. The **Time** foldout contains damping for Horizontal Movement, Forward Movement, Pitch, and Yaw; change these only when the live parameter response needs to be smoother or more immediate. **Yaw Multiplier** affects turning in place, and **Moving Speed Parameter Value** defines the Speed value Animator Monitor uses while the character is moving.

## Continue by task

- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains the supplied state-machine and layer structure and how to approach a custom controller.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) defines the movement, ability, and per-slot item values that Animator Monitor updates.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the supplied Ability Index, Item State Index, Animator Item ID, and Movement Set ID mappings.
- [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) explains the generic first-person rig and its animation options.
- [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) covers replacing clips without losing layer coverage or animation-event timing.

## Verify in Play Mode

1. Select the active character model and open **Window > Animation > Animator**.
2. Enter Play Mode and move the character. **HorizontalMovement**, **ForwardMovement**, **Speed**, **Moving**, and **Yaw** should respond, and the active state should move between idle and locomotion as expected.
3. Start an ability such as Jump. **AbilityIndex** and **AbilityChange** should drive the intended ability state and return to the normal locomotion flow when the ability ends.
4. Equip and use an item. The relevant `Slot<ID>ItemID`, `Slot<ID>ItemStateIndex`, and `Slot<ID>ItemSubstateIndex` values should match the equipped item and action.
5. Repeat the changed action while stationary and moving so every intended masked layer is exercised.
6. If the character supports both perspectives, switch perspectives and confirm that the body, first-person arms, and visible item all select the intended animation.

For focused diagnostics, expand **Editor** on Animator Monitor. **Log Ability Parameter Changes**, **Log Item Parameter Changes**, and **Log Events** write their corresponding updates to the Console in the Unity Editor. Disable them after testing to avoid unnecessary output.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console says the Animator is not designed for Ultimate Character Controller. | The controller is missing required parameters; Version 3 specifically validates `HorizontalMovement`, `ForwardMovement`, and `AbilityChange` during initialization. | Run **Update Character** with the intended Animator Controller or add the complete parameter set documented on [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/). |
| Parameters change but the model stays in the wrong state. | The transition conditions, parameter types, or expected Ability/Item IDs may not match the controller configuration. | Compare the live Animator values with [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/), then correct the affected transition. |
| A replacement clip affects only part of the body. | Another masked layer may still use the old clip or an incompatible motion. | Review every layer that can override that body region and follow [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/). |
| A custom generic model does not animate correctly. | It may be using the supplied humanoid controller or clips authored for a different hierarchy. | Assign a controller and clips authored for the generic rig. |
| First-person arms do not animate or retarget as expected. | The arms may use a generic rig or their own Animator Controller. | Follow [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) and assign clips made for that rig. |
| An ability or item waits indefinitely at an animation point. | The active clip may be missing the event expected by its Animation Event Trigger. | Add the correct `ExecuteEvent` marker or configure a deliberate Duration on [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/). |

## Related pages

- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/) explains how Animator content, events, item animation selection, and procedural motion fit together.
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) covers building or updating the character through Character Manager.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) coordinates gameplay timing with clip events or a duration.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) explains the Slot IDs used by per-item Animator parameters.

## Developer reference

`AnimatorMonitor` is the Version 3 bridge between Ultimate Character Controller and Unity's Animator. It hashes and updates the standard movement, aiming, ability, and item-slot parameters, applies the configured damping values, and raises the change triggers used by Animator transitions. The Character Manager calls the Animator parameter builder for the assigned controller during character creation or update.

When an Animator is present, Animator Monitor applies **Animator Speed** and **Update Mode** directly to it. When a first-person setup has no full-body Animator, the monitor still stores the parameter state so child item animators can receive the updates. `ChildAnimatorMonitor` also filters animation events by the active perspective before forwarding them to the character.

---

<a id="page-ultimate-character-controller-animation-animator-animator-controller"></a>

# Animator Controller

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/)

Use the supplied Animator Controller as a working reference, or build a project-specific controller that keeps Ultimate Character Controller's parameter, ID, and animation-event contracts.

## Before you edit the controller

- Confirm the character works with the supplied controller in Play Mode.
- Make a project-owned copy of any controller you plan to modify.
- Decide whether the model is **Humanoid** or **Generic**. Generic rigs need a controller and clips authored for their hierarchy.
- Review [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) and [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) before changing transition conditions.

The controller does not require the demo's exact state-machine or layer layout. Animator Monitor updates named parameters; your transitions decide how those values select states. Keeping the demo layout is usually the quickest route when the project uses similar locomotion, abilities, and items.

## Assign a controller to the character

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the character and enable **Animator**.
3. For each model, choose **Model Type** and assign the project-owned controller in **Animator Controller**.
4. Select **Build Character** for a new character or **Update Character** for an existing character. The manager adds the standard Ultimate Character Controller parameters when they are missing.
5. Select the configured model and confirm that its **Animator** uses the intended controller and that **Animator Monitor** is present.
6. Open **Window > Animation > Animator** and verify that the Parameters list contains the movement, ability, and item-slot parameters used by the project.

The Version 3 parameter builder adds 22 standard parameters, including two item slots. A project with more item slots can add the corresponding `Slot<ID>...` parameters; Animator Monitor updates a slot only when that controller contains its Slot Item ID parameter.

## Add or change a state-machine flow

1. Choose the layer by the body region and blend behavior the animation needs. Use the Base Layer for locomotion or a full-body baseline, a masked override layer for a body region, an additive layer for motion added over the current pose, or the Full Body Layer for an action that must replace the whole pose.
2. Add a state or sub-state machine with a name that identifies the ability, item, or locomotion mode.
3. Assign clips compatible with the model's Avatar or generic hierarchy.
4. Create entry conditions from the relevant values:
   - Locomotion commonly uses **HorizontalMovement**, **ForwardMovement**, **Speed**, **Moving**, **Aiming**, and **MovementSetID**.
   - Character abilities use **AbilityIndex**, **AbilityChange**, and, when needed, **AbilityIntData** or **AbilityFloatData**.
   - Item actions use the matching `Slot<ID>ItemID`, `Slot<ID>ItemStateIndex`, `Slot<ID>ItemStateIndexChange`, and `Slot<ID>ItemSubstateIndex` values.
5. Add a deliberate return path to the layer's idle or locomotion state. Test both a normal completion and an interrupted action.
6. Preserve every required Animation Event when replacing or moving a clip. The event must exist on every clip that can drive that action, unless its [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) is deliberately configured to use Duration.
7. Test the change before modifying another layer.

## Understand the supplied 13-layer layout

The Version 3 demo controller currently contains these layers, in this order:

| Layer group | Supplied layer names | Purpose |
| --- | --- | --- |
| Baseline | **Base Layer** | Provides idle, movement, aiming movement, crouch, and core ability flows such as Fall, Interact, Jump, Quick Turn, and Ride. Ability transitions are selected with the ability parameters. |
| Hand overrides | **Left Hand Layer**, **Right Hand Layer** | Holds hand and finger poses without replacing the rest of the body. |
| Two-arm overrides | **Arms Layer**, **Upperbody Layer** | Applies two-arm item actions. The Arms mask avoids replacing torso motion, while Upperbody includes the torso when the action needs it. |
| One-side overrides | **Left Arm Layer**, **Right Arm Layer**, **Left Upperbody Layer**, **Right Upperbody Layer** | Allows one arm, or one arm plus its upper-body contribution, to act independently. This supports dual-wield and secondary-item arrangements. |
| Additive overlays | **Additive Layer**, **Additive Left Arm Layer**, **Additive Right Arm Layer** | Adds motion such as recoil or a reaction over the pose selected by lower layers. These three layers use additive blending. |
| Full replacement | **Full Body Layer** | Overrides the complete pose for actions such as death, revive, or a full-body attack. |

Layer order and Avatar Masks matter. A later override layer can replace motion chosen below it, while an additive layer expects a compatible additive clip. Do not copy a state into another layer without also checking its mask, blend mode, transition conditions, and exit path.

## Choose a customization approach

### Keep the supplied structure

Use this approach when the game needs similar locomotion, abilities, item categories, and body-region layering. Add project-specific states under the existing sub-state machines and keep the supplied parameters and layer masks. This minimizes the number of interacting transitions that must be rebuilt.

### Start from a minimal controller

Use a new controller when the game's animation flow is fundamentally different or it does not need the demo's item and body-region layers. Begin with the required parameters and one working locomotion flow, then add one ability or item action at a time. You do not need to recreate all 13 demo layers.

### Replace clips without redesigning transitions

Use [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) when the state logic is already correct and only the motions need to change. Replace every occurrence across the relevant masked layers and keep **Replace Events** enabled when the new clips should receive the supplied animation events.

## Verify in Play Mode

1. Select the active model and keep the Animator window visible.
2. Move, stop, turn, crouch, and aim. The live parameters should select the intended Base Layer states without rapid unwanted transitions.
3. Start each changed ability. Confirm the expected **AbilityIndex** and any data parameter, watch the intended layer enter its state, and verify that it returns cleanly when the ability ends.
4. Equip and use each changed item while stationary and moving. Confirm that the correct slot parameters select matching states on the hand, arm, and upper-body layers.
5. Trigger an additive reaction and a full-body action. The additive result should retain the underlying pose; the full-body action should replace it.
6. Repeat interrupted actions, perspective changes, and rapid inputs. No layer should remain stuck in an action state, and required events should occur once at the intended frame.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console reports that the Animator is not designed for Ultimate Character Controller. | `HorizontalMovement`, `ForwardMovement`, or `AbilityChange` is missing, and other feature parameters may also be absent. | Run **Update Character** with the intended controller or add the full set from [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/). |
| Parameters change but an ability state never starts. | The transition may use the wrong **AbilityIndex**, parameter type, or trigger condition. | Compare the live values with [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) and correct the transition. |
| An item action works while stationary but not while moving. | The action may exist on **Upperbody Layer** but not the corresponding **Arms Layer**, or vice versa. | Add the intended state and transition to every masked layer the action needs. |
| A one-handed action moves both arms or the torso. | The state may be on a layer with the wrong Avatar Mask. | Move it to the appropriate left/right arm or upper-body layer, or correct that layer's mask. |
| An additive action distorts the pose. | The layer or clip may not be configured for compatible additive blending. | Verify the layer's blending mode and the clip's additive reference pose. |
| An action starts but never returns. | The exit condition, animation event, or return transition may be missing. | Add a return path and verify the event expected by the trigger, or intentionally use Duration timing. |
| A replacement changes only part of the visible result. | Another layer or perspective may still reference the original clip. | Search the full controller and all first-person or item controllers for the old clip, then follow [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/). |

## Related tasks

- [Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/) provides the recommended route through Animator setup and customization.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) defines the exact parameter names, types, and meanings.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the supplied ability and item ID mappings.
- [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) covers the Animation Replacer workflow and event preservation.
- [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) explains the generic first-person rig and its separate controller needs.
- [Animator Controller overview video](https://www.youtube.com/watch?v=J5KClzxpCzE) provides a visual walkthrough of the supplied structure.

## Developer reference

`AnimatorMonitor` does not search for specific layer or state names. It hashes and writes the standard parameter names, including movement, ability, and item-slot values. `AnimatorBuilder.AddParameters` adds the Version 3 baseline of 22 parameters: 13 shared character parameters, four parameters each for slots `0` and `1`, and `LegIndex`.

The shipped `Demo.controller` currently defines 13 layers. Its Base, hand, arm, upper-body, and full-body layers use override blending; the three Additive layers use additive blending. The masked layers use separate Avatar Mask assets, and the Base, Upperbody, and Full Body layers enable IK Pass. These are implementation choices in the supplied demo controller, not mandatory layer names for a custom controller.

---

<a id="page-ultimate-character-controller-animation-animator-animator-parameters"></a>

# Animator Parameters

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/)

Animator parameters connect Ultimate Character Controller's movement, abilities, and equipped items to transitions and blend trees in a Unity Animator Controller.

## Add the Version 3 parameters

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the character, enable **Animator**, and assign the intended **Animator Controller**.
3. Select **Build Character** for a new character or **Update Character** for an existing one. Character Manager adds each missing standard parameter to the assigned controller.
4. Open the controller in **Window > Animation > Animator** and select the **Parameters** tab.
5. Compare every name and type with the tables below. Names are case-sensitive.
6. Build transition conditions around the values the character actually uses, then verify them in Play Mode before editing another flow.

The Version 3 parameter builder adds 22 parameters: 13 shared character parameters, four parameters for each of slots `0` and `1`, plus `LegIndex`. If a parameter already exists with the correct name but the wrong type, the builder does not replace it; correct that parameter manually.

## Movement and look parameters

| Name | Type | Version 3 behavior and common use |
| --- | --- | --- |
| `HorizontalMovement` | Float | Receives the horizontal component of the locomotion input vector. Use it as the horizontal axis of a locomotion blend tree. Animator Monitor applies **Horizontal Movement Damping Time**. |
| `ForwardMovement` | Float | Receives the forward component of the locomotion input vector. Use it as the forward axis of a locomotion blend tree. Animator Monitor applies **Forward Movement Damping Time**. |
| `Pitch` | Float | Receives the active look source's pitch when a look source is present. Use it for vertical aim or look poses. Animator Monitor applies **Pitch Damping Time**. |
| `Yaw` | Float | Receives the character's rotational change multiplied by Animator Monitor's **Yaw Multiplier**. Use it for turn-in-place or turning blends rather than as an absolute world rotation. Animator Monitor applies **Yaw Damping Time**. |
| `Speed` | Float | Normally becomes **Moving Speed Parameter Value** while the character is moving and `0` while stopped. An ability can temporarily override it, such as Speed Change. It is not a direct world-speed measurement. |
| `Height` | Float | Receives a height value set by an ability. Height Change can set its configured height when active and restore `0` when it stops. |
| `Moving` | Bool | Becomes true or false when the character starts or stops moving. Use it for clear idle-versus-movement decisions. |
| `Aiming` | Bool | Follows the character's aiming event and is forwarded to equipped item animators. Do not assume it is always true in first person; verify the live value for the project's Aim setup. |
| `MovementSetID` | Int | Receives **Animator Movement Set ID** from the dominant equipped Character Item. Use it to select stance families such as default, melee, or bow movement. |
| `LegIndex` | Float | Used by the supplied controller's transition conditions to choose a leg-compatible entry back into movement. Keep it when retaining those transitions; a custom controller that does not use leg-aware entry conditions does not have to reference it. |

`HorizontalMovement` and `ForwardMovement` describe controller input, not the character's measured velocity. Use `Speed`, `Moving`, or a project-specific parameter when a transition needs a different meaning.

## Ability parameters

| Name | Type | Version 3 behavior and common use |
| --- | --- | --- |
| `AbilityIndex` | Int | Receives the **Ability Index Parameter** from the highest-priority active ability that supplies one. `0` represents no selected ability in the standard flow. Use it to select an ability state or sub-state machine. |
| `AbilityChange` | Trigger | Is set when `AbilityIndex` changes. Use it with the index condition so the Animator can enter or re-enter the correct ability flow when the selection changes. |
| `AbilityIntData` | Int | Carries ability-specific integer detail in addition to `AbilityIndex`. For example, Interact exposes **Ability Int Data Value** so different interaction animations can share one ability index. |
| `AbilityFloatData` | Float | Carries ability-specific continuous or variant data. Current abilities use it for values such as fall velocity, steering input, or idle variation. An ability can request damping when updating it. |

The first active ability by priority that supplies each value wins. Do not use `AbilityIntData` or `AbilityFloatData` without defining what that value means for the selected `AbilityIndex`.

## Item-slot parameters

Version 3 adds this group for slot `0` and slot `1`. Replace `<ID>` with the numeric Slot ID:

| Name pattern | Type | Version 3 behavior and common use |
| --- | --- | --- |
| `Slot<ID>ItemID` | Int | Receives **Animator Item ID** from the Character Item equipped in that slot. `0` represents no equipped item in the standard flow. Use it to select the item family. |
| `Slot<ID>ItemStateIndex` | Int | Receives the state index from the highest-priority active item ability for that slot. Use it to select actions such as Use, Reload, Equip, or Unequip. |
| `Slot<ID>ItemStateIndexChange` | Trigger | Is set when the slot's item or item state changes to a nonzero value. Use it with the ID and state-index conditions to enter or re-enter the intended item action. |
| `Slot<ID>ItemSubstateIndex` | Int | Carries the action's variation within the selected item state, such as an attack sequence or another Animator Audio State Set choice. |

For example, a pistol with Animator Item ID `2` performing the standard Use item ability in slot `0` can expose `Slot0ItemID = 2` and `Slot0ItemStateIndex = 2`; the substate distinguishes the selected use variation.

If the inventory uses slot `2` or above, add all four matching parameters manually. Animator Monitor treats a slot as available in a controller when it finds that slot's `Slot<ID>ItemID`; keep the full four-parameter group together.

## Choose parameters by use case

- **Directional locomotion:** Drive a two-dimensional blend tree with `HorizontalMovement` and `ForwardMovement`, then use `Moving` for clean entry and exit conditions.
- **Turn-in-place:** Use `Yaw` with suitable positive and negative thresholds. Tune **Yaw Multiplier** and **Yaw Damping Time** on Animator Monitor before changing many transitions.
- **Ability selection:** Pair `AbilityChange` with the intended `AbilityIndex`. Add `AbilityIntData` or `AbilityFloatData` only when one ability needs multiple animation choices.
- **Equipped stance:** Use `MovementSetID` for a broad stance and `Slot<ID>ItemID` when the animation is specific to an item family.
- **Item action:** Pair `Slot<ID>ItemStateIndexChange` with the Slot Item ID and Item State Index. Use the substate only for a variation inside that action.
- **Return to movement:** Use the live movement values and, when keeping the supplied leg-aware transitions, `LegIndex` to choose a compatible re-entry pose.

## Verify in Play Mode

1. Select the active character model and open **Window > Animation > Animator**.
2. On **Animator Monitor**, expand **Editor** and enable **Log Ability Parameter Changes** and **Log Item Parameter Changes**.
3. Enter Play Mode and move in every direction. Watch `HorizontalMovement`, `ForwardMovement`, `Moving`, `Speed`, `Pitch`, and `Yaw` respond.
4. Start an ability. Confirm that `AbilityIndex` and `AbilityChange` select the expected state, and inspect any ability data value used by its transitions.
5. Equip and use an item in each supported slot. Confirm its Slot Item ID, Item State Index, change trigger, and substate match the intended item and action.
6. Stop the action, unequip the item, and return to idle. The active indexes should return to their standard neutral values and the Animator should leave the action state.
7. Disable the logging options after testing.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console says the Animator is not designed for Ultimate Character Controller. | Version 3 validates `HorizontalMovement`, `ForwardMovement`, and `AbilityChange` during Animator Monitor initialization. | Add the missing parameters with the exact names and types, then check the complete table rather than stopping at the three validation names. |
| Character Manager ran, but a transition still reports a type mismatch. | A parameter with that name may already have the wrong type. | Delete or rename the incorrect parameter and recreate it with the type in this page; the parameter builder only adds missing names. |
| The character moves but `Speed` remains `1`. | The default **Moving Speed Parameter Value** is `1`; Speed is not measured velocity. | Use the directional parameters for blend magnitude, tune Moving Speed Parameter Value, or provide a deliberate ability override. |
| An ability index changes but its state does not restart. | The transition may test only `AbilityIndex` and ignore `AbilityChange`. | Add the change trigger to the intended entry transition. |
| An item equips but the item state never changes. | The controller may lack the complete slot group, or its transition may omit `Slot<ID>ItemStateIndexChange`. | Add all four parameters for that slot and use the change trigger with the ID and state index. |
| A slot above `1` never updates. | The standard builder creates only slot `0` and slot `1`. | Add the four correctly named parameters for the additional Slot ID. |
| Aiming transitions are wrong in first person. | The controller may assume `Aiming` is permanently true. | Watch the live value and build transitions around the Aim ability behavior used by the project. |
| The parameters are correct but the wrong state plays. | The configured ability, item, or movement-set ID may not match the transition threshold. | Compare the Inspector values with [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) and correct the ID or transition. |

## Related tasks

- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains how to organize layers, states, and transitions around these parameters.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the supplied Ability Index, Item State Index, Animator Item ID, and Movement Set ID mappings.
- [Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/) provides the full setup and customization route.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains ability priority and **Ability Index Parameter**.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) explains the Slot IDs used in item parameter names.

## Developer reference

`AnimatorBuilder.AddParameters` checks each standard name and adds it only when no parameter with that name exists. It creates the 22-parameter Version 3 baseline but does not verify or replace the type of an existing parameter. `AnimatorMonitor` hashes these exact names and writes values through Unity's Animator API.

Movement and look values update during the character's animation update. Ability and item-ability selections are marked dirty and resolved by active-ability priority at the synchronized update point. `AbilityChange` and each `Slot<ID>ItemStateIndexChange` are Unity Trigger parameters rather than persistent booleans.

For item slots, Animator Monitor first checks for `Slot<ID>ItemID`. If that parameter is absent, the controller does not receive the state-index, change-trigger, or substate writes for that slot. The same values are also forwarded to active supported child and item animators.

---

<a id="page-ultimate-character-controller-animation-animator-default-animator-values"></a>

# Default Animator Values

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/)

Use these Version 3 values when an ability or Character Item should play states from the supplied Animator Controller; use different values only when the matching Animator transitions are changed at the same time.

## Match a value to the Animator

1. Select the character and find its **Ultimate Character Locomotion** component.
2. Under **Abilities**, select an ability and check **Ability Index Parameter**. Under **Item Abilities**, check **Item State Index** or the ability's phase-specific fields, such as **Equip Item State Index** and **Unequip Item State Index**.
3. Select each equipped item prefab and find its **Character Item** component. Check **Animator Item ID**, **Animator Movement Set ID**, and **Dominant Item**.
4. Open **Window > Animation > Animator**, select the relevant transition, and match its `AbilityIndex`, `Slot<ID>ItemID`, `Slot<ID>ItemStateIndex`, or `MovementSetID` condition to the Inspector value.
5. Change both the Inspector value and every affected transition when using a project-specific number. Changing only one side selects the wrong state or no state.

The ability and item-ability values below are assigned when those built-in entries are added. They are editable starting values, not reserved constants. The item and movement-set tables describe the shipped Version 3 Demo content.

## Ability Index defaults

| Ability | Ability Index Parameter |
| --- | ---: |
| Jump | 1 |
| Fall | 2 |
| Height Change | 3 |
| Die | 4 |
| Revive | 5 |
| Quick Start | 6 |
| Quick Stop | 7 |
| Quick Turn | 8 |
| Interact | 9 |
| Damage Visualization | 10 |
| Pickup | 11 |
| Ride and Rideable | 12 |
| Impact Knock Back | 13 |
| Drive | 14 |
| Generic | 10000 |

Ride and Rideable deliberately share `12` so the rider and mount can synchronize through the same Animator flow. A custom ability without a supplied default starts with `-1`, which means it does not select an `AbilityIndex` value until you assign one.

## Item State Index defaults

| Item ability or phase | Item State Index |
| --- | ---: |
| Aim | 1 |
| Use, In Air Melee Use, and Melee Counter Attack | 2 |
| Reload | 3 |
| Equip phase of Equip Unequip | 4 |
| Unequip phase of Equip Unequip | 5 |
| Drop | 6 |
| Block | 8 |
| Parry | 9 |

Sharing `2` is intentional: the Animator Item ID and Item Substate Index provide the additional context needed to choose the correct use animation. An item ability that returns `-1` for a slot does not supply that slot's Item State Index.

## Demo Animator Item IDs

These IDs are configured on the shipped Demo Character Item prefabs. Reuse them when retaining the supplied Demo Animator states, or choose a project-specific mapping and update the transitions that read `Slot<ID>ItemID`.

| Demo item | Animator Item ID |
| --- | ---: |
| Assault Rifle | 1 |
| Pistol | 2 |
| Shotgun | 3 |
| Bow | 4 |
| Sniper Rifle | 5 |
| Rocket Launcher | 6 |
| Body | 21 |
| Sword | 22 |
| Knife | 23 |
| Katana | 24 |
| Shield | 25 |
| Frag Grenade | 41 |
| Flashlight | 42 |
| Fireball | 61 |
| Particle Stream | 62 |
| Ricochet | 63 |
| Heal | 64 |
| Shield Bubble | 65 |
| Teleport | 66 |

Items that use the same animation family may share an Animator Item ID. Items that need different states within the same slot should use different IDs and matching Animator transitions.

## Demo movement-set IDs

The dominant equipped Character Item supplies `MovementSetID`. The Demo uses these broad stance families:

| Demo stance | Animator Movement Set ID |
| --- | ---: |
| Default, ranged, magic, and throwable | 0 |
| Melee | 1 |
| Bow | 2 |

`0` is both the Demo's default stance and the runtime fallback when no dominant equipped item supplies another movement set. Multiple items can share a movement-set value when they use the same locomotion stance.

## Choose values for a custom controller

- Give abilities different nonzero Ability Index values when they need different top-level Animator states. Deliberately synchronized abilities, such as Ride and Rideable, can share a value.
- Use Animator Item ID to identify an item animation family within each slot. The same item family can use the same ID in more than one slot.
- Reuse an Item State Index for the same kind of action, then use Item Substate Index for animation variations inside that action.
- Reuse a Movement Set ID across items that share locomotion. Set **Dominant Item** on the item that should choose the equipped stance.
- Keep `0` for neutral Ability Index, Item ID, and Item State Index behavior. Movement Set ID `0` remains a valid default stance.

## Verify in Play Mode

1. Select the active character and open **Window > Animation > Animator**.
2. On **Animator Monitor**, expand **Editor** and enable **Log Ability Parameter Changes** and **Log Item Parameter Changes** when a written trace is useful.
3. Start each changed ability. Confirm `AbilityIndex` shows its configured value, the expected state becomes active, and the value returns to `0` when no active ability supplies an index.
4. Equip and use each changed item. Confirm the slot's Item ID and Item State Index match the tables or your custom mapping, and that `MovementSetID` matches the dominant item.
5. Stop the item ability and unequip the item. The Item State Index and empty slot Item ID should return to `0`; the movement set should return to `0` when no dominant item supplies another value.
6. Disable parameter logging after testing.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| An ability runs but its animation does not start. | Compare **Ability Index Parameter** with the `AbilityIndex` transition condition. | Give both sides the same nonzero value, or intentionally use `-1` when the ability should not select an Animator state. |
| The wrong item animation plays. | Watch the slot's Item ID, Item State Index, and Item Substate Index together. | Correct the Character Item ID or the item ability's state value, then update the matching Animator conditions. |
| Equipping an item changes the action animation but not the locomotion stance. | Check **Animator Movement Set ID** and which equipped item has **Dominant Item** enabled. | Assign the intended movement set to the dominant item and add a matching `MovementSetID` transition. |
| A value remains active after the action ends. | Check whether another higher-priority ability or item ability is still active. | Stop or reprioritize the remaining ability; the monitor resets the parameter only when no active entry supplies it. |
| A custom number works on one character but not another. | The characters may use different Animator Controllers or item prefabs. | Apply the mapping to each relevant Inspector and controller rather than treating the Demo IDs as global constants. |

## Related tasks

- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) explains what each parameter carries and how to inspect it in Play Mode.
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains how to match these values to states and transitions.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains ability order and animation-related settings.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) explains the item component that supplies Animator Item ID and Movement Set ID.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) explains how slot numbers map to the item Animator parameters.

## Developer reference

`AbilityBuilder` reads the `DefaultAbilityIndex` and `DefaultItemStateIndex` attributes when it creates an ability or item ability. Equip Unequip and Block use their own phase-specific serialized values. Editing an existing entry does not rewrite the Animator Controller.

At runtime, `AnimationMonitorBase` takes the first value supplied by the active abilities in priority order. When no active ability supplies an Ability Index, it writes `0`; when no active item ability supplies a slot's Item State Index or Item Substate Index, it writes `0`. An empty slot receives Item ID `0`. Movement Set ID begins at `0` and is replaced by the configured value from the dominant equipped item.

---

<a id="page-ultimate-character-controller-animation-animator-first-person-arms"></a>

# First Person Arms

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/)

First-person arms give the close camera a dedicated visible rig and Animator Controller; use them when the full character body is hidden in first person or when weapon handling needs camera-specific animation.

## Before you begin

- Use a character whose **Perspective** is **First** or **Both**.
- Import the arm model and its clips with a compatible Unity rig. The supplied Demo arms use a **Generic** rig, so their clips must be authored for that skeleton and cannot be humanoid-retargeted.
- Prepare an Animator Controller for the arms when they should animate. It must contain every Ultimate Character Controller parameter that its transitions read.
- When the character carries items, decide which arm hand transforms should be the first-person **Item Slots**.

Unity's [generic animation import guide](https://docs.unity3d.com/Manual/GenericAnimations.html) explains the model import settings for a non-humanoid rig.

## Add the arms with Character Manager

1. Place the character and arm model in the scene. The character must be a scene object; the **First Person Arms** field can also accept an arm prefab that Character Manager instantiates.
2. Open **Tools > Opsive > Ultimate Character Controller > Character Manager** and assign the character in **Character**.
3. Set **Perspective** to **First** or **Both** and select the intended **First Person Movement**.
4. Assign the arm root in **First Person Arms**. In the controller field on the same row, assign the Animator Controller made for that arm rig. Adding another arm root creates another row and another controller choice.
5. If **Items** is enabled, select **Adjust Slots** beside **Item Slots**. In the **Character Item Slots** window, find the **First Person Arms** section and assign the appropriate hand transforms. Use **Right** for Slot ID `0`, **Left** for Slot ID `1`, or **Other** for a project-specific ID; each parent and ID in that arm model must be unique.
6. Select **Build Character** for a new character or **Update Character** for an existing one.
7. Inspect the result. Character Manager places the arm root below **FirstPersonObjects** and adds **First Person Base Object**. When a controller was assigned, the root also has **Animator** and **Child Animator Monitor**.
8. For every Character Item that should use these arms, configure its [First Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) to reference the correct arm object or **First Person Base Object ID**.

Do not add a second **Animator Monitor** to the arms. The character model keeps **Animator Monitor**; the arms use **Child Animator Monitor** to receive the same movement, ability, and item parameters.

## Choose an arm and controller setup

| Setup | Use it when | Important tradeoff |
| --- | --- | --- |
| Generic arm rig | Final first-person animation needs close-up posing tailored to one skeleton. This is the approach used by the supplied Demo arms. | Clips cannot be humanoid-retargeted, and the humanoid-only Character IK workflow does not drive the generic arms. |
| Humanoid arm rig | A prototype should reuse a humanoid animation library or the full character rig. | Retargeting is convenient, but third-person clips commonly need camera-specific cleanup for hands, weapon framing, and off-screen bones. |
| Multiple arm roots | Different item families or character models need different skeletons or controllers. | Each item must select the correct First Person Base Object, and each arm set needs matching Item Slots and controller parameters. |
| No arm controller | The arm object is intentionally static, absent, or all visible motion is handled elsewhere. | Character Manager does not add Animator or Child Animator Monitor, so ability and item parameters cannot animate that arm root. |

For a quick humanoid prototype, a mesh-isolation tool such as [FPS Mesh Tool](https://assetstore.unity.com/packages/tools/modeling/fps-mesh-tool-28006) can create an arms-only mesh while retaining the humanoid rig. The existing [FPS Mesh Tool integration video](https://www.youtube.com/watch?v=6Ro6mszmeHw) demonstrates that optional third-party workflow. Treat the result as a starting point and review every pose from the gameplay camera.

## How the arms run

**FirstPersonObjects** keeps the first-person hierarchy aligned with the camera and manages which arm base objects are active. By default, a base object is activated when an equipped dominant item references it and is deactivated when no equipped item needs it. Enable **Always Active** on **First Person Base Object** only when that arm set should remain visible without an item.

**Child Animator Monitor** copies the live values from the active character model's **Animator Monitor**, including movement, aiming, ability, Movement Set, and supported item-slot parameters. The arm controller can therefore use the same parameter names and values while playing different first-person clips.

The arm Animator does not apply root motion. Locomotion remains controlled by the character, while the arm clips provide visible first-person motion. Animation events raised by a child Animator Monitor are accepted only when its perspective matches the active perspective.

## Verify in Play Mode

1. Start in first person and equip an item mapped to the arm set. Confirm that the intended arms and visible item appear, with no duplicate third-person arms in front of the camera.
2. Move, look, aim, use, reload, equip, and unequip. Watch the arm Animator and confirm its parameters follow the character and each action enters the expected state.
3. On the character's **Animator Monitor**, expand **Editor** and enable **Log Ability Parameter Changes**, **Log Item Parameter Changes**, or **Log Events** only while diagnosing a mismatch.
4. Unequip the item. Confirm the arm base object hides unless **Always Active** is enabled or another equipped item still references it.
5. For a **Both** character, switch to third person and back. First-person arms should be hidden in third person, return in first person, and resume the correct current Animator state.
6. If multiple character models or arm roots are configured, repeat the equip and perspective checks for every supported combination.
7. Disable the Animator Monitor logging options after testing.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The arms never appear. | Check **Perspective**, the **FirstPersonObjects** hierarchy, the item's arm reference or **First Person Base Object ID**, and whether the item is equipped. | Select **First** or **Both**, run **Update Character**, then map the First Person Perspective Item to the intended base object. Use **Always Active** only for arms that should not depend on an item. |
| The arms are visible for the wrong item or remain visible after unequipping. | Inspect the item's **Object**, **First Person Base Object ID**, additional control objects, and the arm's **Always Active** value. | Point each item at the correct base object and remove unintended additional control objects; disable **Always Active** for item-specific arms. |
| The arm mesh appears but does not animate. | Check the controller field beside **First Person Arms**, then inspect the root for **Animator** and **Child Animator Monitor**. | Assign the intended controller and select **Update Character**. Character Manager adds or removes both components to match that controller field. |
| The arm Animator logs missing parameters or enters the wrong state. | Compare its parameter names, types, Ability Indexes, Item IDs, and Item State Indexes with the character controller. | Add the required parameters and matching transition conditions; use [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) and [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) as the baseline. |
| Generic arm clips deform or do not retarget. | Check the model and clip **Rig** import settings and confirm they use the same generic skeleton. | Use clips authored for that rig, or deliberately switch both model and clips to a valid humanoid workflow instead of mixing rig types. |
| An item appears in the wrong hand. | In **Character Item Slots**, compare the arm hand transform and Slot ID with the Character Item's **Slot ID**. | Assign the correct hand parent and keep the same Slot ID throughout the first- and third-person item setup. |
| An animation event works in one perspective but not the other. | Confirm the active perspective's clip contains the event or uses the intended duration fallback. | Add the event to the first-person clip or configure the matching [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/). |

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) explains the complete Character Manager setup.
- [First Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) controls which arm base object and visible item an equipped item uses.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) lists the parameters copied to an animated arm root.
- [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) covers clips, layers, and required animation events.
- [First Person View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/) explains the camera-side first-person setup.
- [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) explains the humanoid-only Character IK workflow and why it does not drive the supplied generic arms.

## Developer reference

`CharacterManager` calls `ItemBuilder.AddFirstPersonArms` when building or adding an arm root. The builder assigns a unique `FirstPersonBaseObject` ID and moves that hierarchy to the Overlay layer. When the row has a controller, it adds or reuses an `Animator`, disables root motion, sets culling to **Always Animate**, assigns the controller, and adds `ChildAnimatorMonitor`. Updating the row with no controller removes the arm Animator and Child Animator Monitor.

`ChildAnimatorMonitor` reads from the active character model's `AnimatorMonitor`, mirrors the standard character and supported slot parameters, follows the character time scale, and snaps to the current state when enabled or after an immediate transform change. It treats a slot as supported when the arm controller contains that slot's `Slot<ID>ItemID` parameter, so keep the full slot parameter group consistent with the controller's transitions.

---

<a id="page-ultimate-character-controller-animation-animator-replacing-animations"></a>

# Replacing Animations

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/)

Replace clips when the supplied state logic is correct but the character, first-person arms, or visible item needs project-specific motion. The Version 3 Animation Replacer can update every matching clip reference in one Animator Controller while preserving the controller's states, transitions, blend trees, and layers.

## Before you replace clips

- Duplicate the supplied Animator Controller into a project-owned folder under `Assets`. **Replace** edits the selected controller asset directly and does not provide its own rollback workflow.
- Commit or back up both the controller and replacement animation assets. Copying events can modify the replacement model's import settings, which also affects other controllers that use that clip.
- Test the unchanged controller in Play Mode and record the expected idle, locomotion, ability, equip, use, reload, and unequip behavior.
- Confirm that every replacement clip is compatible with the model's rig and Avatar. The Animation Replacer changes clip references; it does not retarget an incompatible rig.
- Identify every controller that needs the motion. Character bodies, first-person arms, and animated visible items can use separate controllers and must be processed separately.

If Unity's Animator workflow is unfamiliar, review the [Unity Animator Controller guide](https://docs.unity3d.com/Manual/class-AnimatorController.html) before changing the supplied controller.

## Replace clips with Animation Replacer

1. Open **Tools > Opsive > Ultimate Character Controller > Animation Replacer**.
2. Assign the project-owned controller to **Animator Controller**. The list shows each original clip found in that controller's layers, nested state machines, and blend trees.
3. For a one-time change, assign a replacement beside each original clip name. Leave entries empty when they should remain unchanged.
4. For a reusable mapping, assign a **Replacement Template**. Create one with **Assets > Create > Opsive > Ultimate Character Controller > Utility > Animation Replacements**, then keep its **Originals** and **Replacements** arrays paired and the same length.
5. Choose **Replace Events** deliberately. Leave it enabled only when the replacement imported clips should receive the original clips' event lists. Disable it when the replacements already contain approved events or the related gameplay triggers use durations.
6. Review every populated mapping. One listed source clip can be referenced by several states or blend trees; selecting **Replace** changes every occurrence of that exact clip in the selected controller.
7. Select **Replace**. Confirm the Console reports the number of clip references replaced, then inspect the controller diff before continuing.
8. Repeat the process for each separate body, arm, or visible-item controller that should use the new motions.

For a state-specific exception, replace that state's **Motion** manually in the Animator window instead. Animation Replacer is intended for replacing every occurrence of a source clip within the selected controller.

## Decide how to handle animation events

Animation events coordinate visible frames with gameplay actions such as applying jump force, firing, reloading, equipping, or completing an interaction.

![Unity Animation window timeline with an animation event marker placed on the clip](https://opsive.com/wp-content/uploads/2018/03/AnimationEventTimeline.webp?v=63929f93f94b)

Use **Replace Events** when the new clip should inherit the original event names and parameters. Version 3 copies each event to the same relative point in the replacement clip. For example, an event halfway through the original clip is placed halfway through the replacement, even when the two clips have different lengths.

Review the result before Play Mode:

- When the original contains events, copying replaces the imported replacement clip's current event list. Disable **Replace Events** when the replacement already has deliberate events that must be retained.
- Automatic event copying works for clips stored in an imported model whose event list can be changed through its Model Importer. Add events manually to standalone `.anim` clips or any replacement that did not receive them.
- Relative timing does not guarantee correct action timing. Move the copied event to the actual contact, release, or completion frame when the new performance is paced differently.
- Do not map original clips with different event requirements to one shared replacement while copying events. A clip asset has one event list wherever it is used.
- For an event-driven [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/), keep **Wait For Animation Event** enabled and verify the replacement sends `ExecuteEvent` with the expected String value.
- For duration timing, disable **Wait For Animation Event** and retune **Duration** for the new clip. Duration mode does not use copied animation events.
- First-person and third-person states may use different clips. Each active perspective needs the event or duration configuration that drives its action.

Unity's [animation events on imported clips guide](https://docs.unity3d.com/Manual/AnimationEventsOnImportedClips.html) shows where imported clip events are edited.

## Check the surrounding Animator setup

The tool replaces motions but does not redesign the states around them. Review these choices after each group:

- **Layers and masks:** confirm the replacement exists in every intended full-body, upper-body, arms, and item layer. A different source clip in another controller is not changed automatically.
- **Transitions:** compare exit time, transition duration, interruption settings, and conditions with the new clip's anticipation and recovery.
- **State settings:** review Speed, Cycle Offset, Mirror, Foot IK, and Write Defaults where they affect the new performance.
- **Blend trees:** preview every direction and speed. Clips with different stride lengths or poses can require new thresholds or motion-speed adjustments.
- **Looping and root motion:** set the replacement clip's import options for the intended loop and root-transform behavior. Animation Replacer does not copy these settings from the original.
- **Rig-specific controllers:** generic first-person arms require clips authored for their exact rig; a humanoid body controller can use compatible retargeted clips.

## Verify in Play Mode

1. Open **Window > Animation > Animator**, select the active character model, and watch the changed state while performing its action.
2. Test idle, start, stop, turns, every locomotion direction, jump, fall, and landing when any locomotion clip changed. The character should enter and leave each state cleanly without a bind pose, foot slide, or layer mismatch.
3. Run each changed ability and item action. Confirm the correct body, arm, and visible-item clips play in every relevant layer.
4. On **Animator Monitor**, expand **Editor** and enable **Log Events**. Confirm each expected event occurs once at the intended visible frame and the action does not remain waiting.
5. Test rapid input, interrupted actions, altered playback speed, and any supported character time scale. Events and transitions should remain synchronized.
6. For a **Both** character, repeat the actions in first person and third person. Verify both controller sets and their events.
7. Unequip items and return to idle. No layer should remain in the replacement action state.
8. Disable **Log Events** after verification.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Replacement Template** leaves expected fields empty. | Compare each **Originals** reference with the exact clips used by the selected controller, and confirm both arrays have the same length. | Correct the source references and pair every valid original with one replacement; null entries are skipped. |
| **Replace** reports `0` or the controller appears unchanged. | Check **Animator Controller** and confirm at least one displayed source clip has a replacement assigned. | Select the project-owned controller actually used by the runtime Animator, populate the intended mappings, and run **Replace** again. |
| A different source clip with the same name is missing from the list. | Animation Replacer sorts and identifies its displayed entries by clip name, so same-named source assets share one mapping. | Do not select **Replace** until the source clips have distinct names, or replace those states manually. |
| Only part of the body changed. | The other layer, perspective, arm, or item controller may use another clip asset. | Inspect every relevant controller and replace its source clip separately. |
| The replacement event never fires. | Check whether the replacement is a standalone `.anim` clip or whether the active trigger is waiting for a named event. | Add the event manually with `ExecuteEvent` and the exact String value, or deliberately switch the trigger to Duration mode. |
| Approved events disappeared from the replacement clip. | **Replace Events** may have overwritten the imported target event list with the source events. | Restore the asset from version control, disable **Replace Events**, and add or retain the approved events manually. |
| The action occurs too early or too late. | A copied event keeps relative clip time, not the new performance's semantic frame. | Move the event to the visible action frame or retune the trigger's **Duration**. |
| Another character changed unexpectedly. | It may share the edited controller or the replacement clip whose imported events changed. | Restore the shared asset, create project-specific controller or clip assets, and repeat the replacement on those copies. |
| The model deforms or enters a bind pose. | Check the replacement clip's rig type and Avatar against the animated model. | Use a compatible clip or correct the import and Avatar setup before editing the controller again. |

## Related tasks

- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains the supplied layers, states, transitions, and customization route.
- [Animator Parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/) lists the values that select the changed states at runtime.
- [Default Animator Values](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/default-animator-values/) lists the supplied ability and item mappings used by transition conditions.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains event-driven and duration-driven gameplay timing.
- [Animation Slot Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/animation-slot-event-trigger/) covers slot-aware item events.
- [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) explains the separate generic arm rig and controller workflow.

## Developer reference

`AnimationReplacer` traverses every layer, nested state machine, state, and nested blend tree in the selected `AnimatorController`. It lists one entry for each source clip name and replaces every traversed reference whose mapping is non-null. Controllers used by first-person arms or visible items are not discovered automatically.

With **Replace Events** enabled, the replacer reads the original clip's events, converts each time to a normalized position based on the original length, and writes that event list through the replacement clip's `ModelImporter`. This path does not update a standalone `.anim` asset. The controller is marked dirty and the Console reports the replacement count, but state settings, transitions, masks, import settings, and gameplay trigger configuration remain unchanged.

---

<a id="page-ultimate-character-controller-animation-animation-event-trigger"></a>

# Animation Event Trigger

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/)

An Animation Event Trigger lets an ability or item action occur at a specific point in an animation, or after a fixed duration when clip-driven timing is not needed.

## Choose the trigger mode

Animation Event Trigger fields appear throughout Ultimate Character Controller, including **Jump Event**, landing, interaction, pickup, and item-action timing fields. Expand the field and choose one of two modes:

- Enable **Wait For Animation Event** when the gameplay action must match a meaningful frame in a clip, such as applying jump force at takeoff or releasing an item during a throw.
- Disable **Wait For Animation Event** when a consistent timed delay is sufficient. The **Duration** field then appears and sets the delay in seconds. A Duration of `0` triggers the action immediately.

These modes do not act as fallbacks for each other. When **Wait For Animation Event** is enabled, a missing event leaves the trigger waiting rather than using Duration.

## Set up an animation event

The Jump ability provides a clear example:

1. Select the character and expand **Ultimate Character Locomotion > Abilities > Jump > Jump Event**.
2. Leave **Wait For Animation Event** enabled.
3. Hover over **Jump Event** and read its tooltip to find the expected event name. Jump expects `OnAnimatorJump`; other fields name their own event.

![Jump Event tooltip identifying OnAnimatorJump as the event that applies jump force](https://opsive.com/wp-content/uploads/2018/03/JumpEventTriggerTooltip-e1527366647399.webp?v=86688b2460b7)

4. Open **Window > Animation > Animation**, select the clip used by the active Animator state, and add an Animation Event at the frame where the gameplay action should occur.
5. Set the event **Function** to `ExecuteEvent` and its **String** value to the exact event name from the trigger tooltip. Event names are case-sensitive.

![Unity Animation event configured with ExecuteEvent and OnAnimatorJump in the String field](https://opsive.com/wp-content/uploads/2018/03/JumpAnimationEvent.webp?v=8ce449e51a08)

6. Confirm that the Animator Controller actually reaches this clip for the relevant ability or item action.
7. If different first-person and third-person clips can perform the action, add the equivalent event to every clip that can be active in its perspective.

For Jump, `OnAnimatorJump` applies the initial jump force. Other triggers can begin an interaction, release a projectile, complete a reload, or end an ability, depending on the field that owns the trigger.

## Set up duration timing

1. Expand the Animation Event Trigger field on the ability or item action.
2. Disable **Wait For Animation Event**. The **Duration** field becomes visible.
3. Enter the number of seconds to wait from the point when that trigger begins waiting.
4. Test the action after any clip, transition, or playback-speed change and retune Duration if its visible timing has shifted.

Duration timing is useful for an action without a meaningful animation frame, a quick prototype, or a fixed delay that should not depend on a particular clip. Prefer an animation event when different clips or playback speeds still need the action to occur at the correct visual moment.

## Verify in Play Mode

1. On the character's **Animator Monitor** component, expand **Editor** and enable **Log Events**.
2. Enter Play Mode and perform the configured action.
3. In animation-event mode, the Console should log the expected event at the intended frame. For Jump, the message includes `Execute OnAnimatorJump`, and the character should receive its jump force at that moment.
4. Repeat the action several times and from every supported perspective. The result should occur once per action and should not remain waiting.
5. In duration mode, confirm that the result occurs after the configured delay. A duration-triggered callback does not produce an `Execute ...` message from Animator Monitor because it is not sent by the Animator.

Disable **Log Events** after testing when the extra Console output is no longer useful.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The ability or item action remains waiting. | **Wait For Animation Event** is enabled, but the active clip may not send the expected event. | Add an event with **Function** set to `ExecuteEvent` and the exact **String** value from the trigger tooltip, or deliberately switch the trigger to Duration mode. |
| The event is visible in the clip but nothing happens. | The event name may have different capitalization, the trigger may be in Duration mode, or the Animator Controller may be playing a different clip. | Match the event string exactly, enable **Wait For Animation Event**, and inspect the active Animator state in Play Mode. |
| The action occurs too early or too late. | Determine whether **Log Events** reports an Animator event. | For event mode, move the event marker in the clip. For duration mode, adjust **Duration**. |
| **Duration** is not visible. | **Wait For Animation Event** is still enabled. | Disable **Wait For Animation Event** to expose the Duration field. |
| The timing works in one perspective only. | The first-person and third-person states may use different clips. | Add the same named event at the appropriate frame in every clip that can drive the action. |
| Timing changed after replacing or speeding up a clip. | A fixed duration does not follow the clip's authored action frame. | Retune Duration or use an animation event so the gameplay action remains attached to the intended frame. |

## Related tasks

- [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) uses `OnAnimatorJump` to apply its initial force.
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains how ability and item states are organized.
- [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) covers preserving event timing when clips change.
- [Animation Slot Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/animation-slot-event-trigger/) adds slot-aware event names for item actions.

## Developer reference

In Ultimate Character Controller Version 3, `AnimationEventTrigger.WaitForEvent` begins one pending wait. With **Wait For Animation Event** enabled, `Animator Monitor.ExecuteEvent` forwards the clip's String value through the Opsive event system and the matching trigger completes. With the option disabled, the Scheduler invokes the trigger after **Duration** instead. `CancelWaitForEvent` ends the pending wait and cancels its scheduled callback.

The trigger owner registers the event name and decides what happens when it completes. For example, Jump registers `OnAnimatorJump` and applies its force in the completion callback. Item actions that must distinguish slots use `AnimationSlotEventTrigger`; see the related page rather than adding a slot number to a standard Animation Event Trigger by assumption.

---

<a id="page-ultimate-character-controller-animation-animation-event-trigger-animation-slot-event-trigger"></a>

# Animation Slot Event Trigger

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/animation-slot-event-trigger/)

An Animation Slot Event Trigger lets an item action respond to a specific equipment slot, which is useful when two equipped items must reach their use, reload, equip, or unequip timing independently.

## Choose shared or slot-specific timing

Animation Slot Event Trigger extends [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) with **Wait For Slot Event**. Choose the mode based on how the equipped items should behave:

| Scenario | Trigger settings | Example event |
| --- | --- | --- |
| One item acts at a time, or every waiting item should advance together. | Enable **Wait For Animation Event** and leave **Wait For Slot Event** disabled. | `OnAnimatorItemUse` |
| Items in different slots must advance independently. | Enable both **Wait For Animation Event** and **Wait For Slot Event**. Use a slot-qualified event in each relevant clip. | `OnAnimatorItemUseSlot0` or `OnAnimatorItemUseSlot1` |
| The action needs only a fixed delay. | Disable **Wait For Animation Event** and set **Duration**. | No Animator event is required. |

In Version 3, enabling **Wait For Slot Event** permits the slot-qualified event in addition to the shared base event. It does not reject the base event. If separate items must complete independently, do not leave an unsuffixed base event in a clip that can run while both triggers are waiting.

## Configure a slot-specific item event

The **Use Event** on a Usable Action is a common example:

1. Select the item's GameObject and find its **Character Item** component. Note its **Slot ID**; the supplied humanoid setup normally uses slot `0` for the right hand and slot `1` for the left hand.
2. Expand the item action's **Use Event**.
3. Enable **Wait For Animation Event**. The **Wait For Slot Event** option becomes visible; enable it for independent per-slot timing.

![Use Event waiting for an animation event with the optional slot setting, while Use Complete Event uses a 0.05-second Duration](https://opsive.com/wp-content/uploads/2022/10/AnimationEventSlotTrigger.webp?v=4d21049593a4)

4. Read the trigger field's tooltip for its base event name. **Use Event** registers `OnAnimatorItemUse`, while **Use Complete Event** registers `OnAnimatorItemUseComplete`.
5. Append `Slot` and the Character Item's numeric Slot ID without spaces. For a Use Event in slot `0`, the result is `OnAnimatorItemUseSlot0`.
6. Open **Window > Animation > Animation** and select the clip that performs this item's action.
7. Add an Animation Event at the intended action frame. Set **Function** to `ExecuteEvent` and **String** to the exact slot-qualified name.
8. Repeat the setup for each slot that acts independently. For slot `1`, use `OnAnimatorItemUseSlot1` rather than copying the slot `0` string.
9. If first-person and third-person states use different clips, add the corresponding event to every clip that can be active in its perspective.

The event name is registered by the item or item-action code; it is not generated from the visible field label at runtime. The tooltip is the reliable source for the base name.

## Common event names

Ultimate Character Controller commonly follows a base-name-plus-slot convention:

| Trigger | Shared base event | Slot `0` event |
| --- | --- | --- |
| **Use Event** | `OnAnimatorItemUse` | `OnAnimatorItemUseSlot0` |
| **Use Complete Event** | `OnAnimatorItemUseComplete` | `OnAnimatorItemUseCompleteSlot0` |
| **Reload Event** | `OnAnimatorItemReload` | `OnAnimatorItemReloadSlot0` |
| **Reload Complete Event** | `OnAnimatorItemReloadComplete` | `OnAnimatorItemReloadCompleteSlot0` |
| **Equip Event** | `OnAnimatorItemEquip` | `OnAnimatorItemEquipSlot0` |
| **Unequip Event** | `OnAnimatorItemUnequip` | `OnAnimatorItemUnequipSlot0` |

Use the field tooltip rather than assuming that every custom trigger follows this naming convention.

## Verify in Play Mode

1. On the character's **Animator Monitor**, expand **Editor** and enable **Log Events**.
2. Enter Play Mode with items assigned to the slots being tested.
3. Perform the slot `0` action. The Console should show the slot-qualified event, such as `Execute OnAnimatorItemUseSlot0`, and only the intended slot should advance.
4. Perform the equivalent slot `1` action. The Console should show the `Slot1` event and the other item should remain unaffected.
5. Repeat the test in every supported perspective and with both items ready at the same time.
6. If the trigger uses Duration instead, verify the delayed result without expecting an Animator Monitor event log.

Disable **Log Events** after the timing has been confirmed.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Both equipped items respond to one animation event. | The active clip may still send the shared base event, such as `OnAnimatorItemUse`. | Use slot-qualified events, enable **Wait For Slot Event** on each trigger, and remove the shared event from clips that must act independently. |
| A slot-specific event is logged but the item does not advance. | **Wait For Slot Event** may be disabled, or the suffix may not match the Character Item's **Slot ID**. | Enable the option and make the event end in the exact `Slot<ID>` value used by that Character Item. |
| **Wait For Slot Event** is not visible. | **Wait For Animation Event** is disabled. | Enable **Wait For Animation Event**; otherwise the trigger uses Duration and does not listen for slot events. |
| Slot `0` works but slot `1` does not. | The second clip may still contain `Slot0`, or both Character Items may use the same Slot ID. | Correct the event String and confirm each **Character Item > Slot ID**. |
| The action remains waiting in one perspective. | That perspective may use a different animation clip without the slot-qualified event. | Add the correct event to every first-person or third-person clip that can drive the action. |
| A duration-based trigger produces no event log. | Animator Monitor logs Animator events, not Scheduler callbacks. | Verify the visible action after **Duration** instead; no `Execute ...` log is expected. |

## Related tasks

- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains the shared event and Duration modes inherited by this trigger.
- [Item Slots](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-slots/) explains Slot IDs and matching first-person and third-person slot layouts.
- [Usable Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) explains the Use and Use Complete stages.
- [Dual Wielding](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/dual-wielding/) covers an item setup where independent slot timing is especially useful.

## Developer reference

`AnimationSlotEventTrigger.RegisterUnregisterEvent` receives the base event name and Slot ID from its owner. Version 3 registers both the base name and a cached slot name formed as `eventName + "Slot" + slotID`. `InvokeSlotEvent` completes the wait only when **Wait For Slot Event** is enabled, while the inherited base-event handler remains available whenever **Wait For Animation Event** is enabled.

The current Usable Action registers its Use Event as follows:

```csharp
m_UseEvent.RegisterUnregisterEvent(
    register,
    m_Character,
    "OnAnimatorItemUse",
    m_CharacterItem.SlotID,
    HandleItemUseAnimationSlotEvent);
```

Start or reset the pending event-or-duration wait with:

```csharp
m_UseEvent.WaitForEvent(true);
```

The callback overload can also receive the registered Slot ID. After one valid event or scheduled callback completes the wait, later events do not invoke the completion callback again until another wait begins.

---

<a id="page-ultimate-character-controller-input"></a>

# Input

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/input/)

Use the input layer to connect a player’s keyboard, mouse, controller, or on-screen controls to one Ultimate Character Controller character. Choose the input implementation before building the character so the Character Manager can create the correct components and references.

## Choose an input route

| Route | Use it when | UCC setup |
| --- | --- | --- |
| **Unity Input System** | A new project needs action assets, control schemes, or device pairing. | Enable **Input System** in the Character Manager. UCC creates an Opsive **Unity Input System** component alongside Unity’s **Player Input** component. |
| **Input Manager** | An existing project already uses Unity’s legacy axis and button mappings, or you want the supplied default mappings for a quick prototype. | Leave **Input System** disabled and add the mappings from **Setup Manager > Project**. UCC creates a **Unity Input** component. |
| **Rewired** | The project already manages actions and player identities with Rewired. | Install the UCC integration, add **Rewired Input**, and assign it through **Player Input Proxy**. |

The rest of UCC reads the common `IPlayerInput` interface, so abilities, camera input, and item input do not need to know which route supplies the values. An AI-controlled character is different: enable **AI Agent** in the Character Manager and do not add a player-input implementation.

## Set up the Unity Input System

1. Install and enable Unity’s Input System package. After Unity recompiles with the Input System active, the **Input System** option becomes available in the Character Manager.
2. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and select **Project**.
3. Use **Update Layers** and the appropriate **Render Pipeline** setup. Do not select **Update Buttons** unless the project also needs the legacy Input Manager mappings.
4. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**, select or create the playable character, leave **AI Agent** disabled, and enable **Input System**.
5. Build or update the character.
6. On the character, verify that **Player Input Proxy > Player Input** references the Opsive **Unity Input System** component on the `<CharacterName>Input` GameObject.
7. On that input GameObject, verify that Unity’s **Player Input** component has the supplied `CharacterInput` actions and uses the `Gameplay` action map. The Character Manager assigns both when it creates the input object.

If you replace `CharacterInput` with a custom action asset, keep the action names used by the character’s abilities and camera settings. The Opsive component looks up each requested input name in Unity Player Input’s current action map.

## Set up the legacy Input Manager

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and select **Project**.
2. Select **Update Buttons** under **Input Manager Button Mappings**. In a new project, the combined **Update Buttons and Layers** or **Update Buttons, Layers, and Render Pipeline** action can perform the same input update with the other required project setup.
3. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**, select or create the playable character, leave **AI Agent** disabled, and disable **Input System** if the option is visible.
4. Build or update the character.
5. On the character, verify that **Player Input Proxy > Player Input** references the **Unity Input** component on the `<CharacterName>Input` GameObject.

The default mappings include names such as `Horizontal`, `Vertical`, `Mouse X`, `Mouse Y`, and `Jump`. Custom mappings can use different names, but the corresponding ability, camera, and input-component fields must request those same names.

## Connect Rewired

1. Install Rewired and the current UCC Rewired integration.
2. Configure the Rewired Input Manager and the actions used by the character.
3. On the character’s input GameObject, replace the existing Opsive input implementation with **Rewired Input**.
4. On the character, assign **Player Input Proxy > Player Input** to that **Rewired Input** component.
5. Enable **Enable Touch Controls** on Rewired Input only when the project uses Rewired’s touch controls.
6. For local multiplayer, give each character its own Rewired Input component and a different Rewired player assignment.

The integration package supplies the Rewired implementation; the UCC character still consumes it through the same Player Input Proxy. See [Rewired](https://opsive.com/support/documentation/ultimate-character-controller/integrations/rewired/) for the integration-specific setup.

## Add on-screen controls

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and select **Scene**.
2. Under **Virtual Controls Setup**, choose **Input Type**:
   - **InputSystem** adds the on-screen controls for Unity’s Input System.
   - **InputManager** adds the legacy Virtual Controls Manager and its controls.
3. Select **Add Virtual Controls**.
4. Assign the intended character where the generated controls do not obtain it from the attached camera.
5. Test the target input mode. The Opsive **Unity Input System > Force Input** choice is **On Screen**; the legacy **Unity Input > Force Input** choice is **Virtual**.

The legacy controls support virtual buttons, joysticks, and touchpads and must remain under their Virtual Controls Manager. See [Virtual Controls](https://opsive.com/support/documentation/ultimate-character-controller/input/virtual-controls/), the direct child of this section, for their names and layout.

## Understand input ownership

Each playable character needs its own **Player Input Proxy** and its own referenced input implementation. A Camera Controller reads the input of its assigned character; adding a second camera does not create a second player or separate devices.

For local multiplayer:

- With Unity’s Input System, give each character a separate Opsive **Unity Input System** component and Unity **Player Input** component. Pair gamepads or control schemes through Unity Player Input. The shipped Opsive component deliberately makes keyboard and mouse available to every enabled player-input instance, so test shared keyboard behavior explicitly.
- With Rewired, give each character a separate Rewired player assignment.
- The legacy Input Manager exposes global axis names, not player identities. Use player-specific mappings and an implementation that distinguishes them, or use the Input System or Rewired when devices must be paired dynamically.

See [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/) for the matching camera, viewport, and HUD setup. For a non-player character, use the [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/) workflow instead of assigning local input.

## Key choices

- **Look input names:** **Horizontal Look Input Name** and **Vertical Look Input Name** must match the selected route’s mappings or actions. The supplied names are `Mouse X` and `Mouse Y`.
- **Look Vector Mode:** Use **Smoothed** for UCC’s buffered look smoothing, **Unity Smoothed** for the input implementation’s smoothed values, **Raw** for direct values, or **Manual** when another system assigns the look vector, such as a tracked headset.
- **Look tuning:** Adjust **Look Sensitivity** first. Change **Smooth Look Steps**, **Smooth Look Weight**, **Smooth Exponent**, or **Look Acceleration Threshold** only when **Smoothed** is selected and the default response does not suit the game.
- **Cursor behavior:** **Disable Cursor** locks and hides the cursor while playing. **Enable Cursor With Escape** releases it, and **Prevent Look Vector Changes** prevents the released cursor from rotating the camera.
- **Input-mode override:** Leave **Force Input** at **None** for normal platform detection. Use **On Screen** for the Unity Input System route or **Virtual** for the legacy route when testing touch controls in the Editor.
- **Repeated presses:** **Double Press Tap Timeout** controls the time window used by tap and double-press checks.
- **Death behavior:** **Disable On Death** stops the input implementation when the character dies and enables it again after respawn.

## Verify in Play Mode

1. Enter Play Mode and use the configured `Horizontal` and `Vertical` inputs. The intended character should move, and no other character should respond.
2. Move the mouse or right stick. The assigned camera should look around using the selected smoothing mode and sensitivity.
3. Press `Jump` or another input assigned to an enabled ability. That ability should start once, using the same action or mapping name shown in its Inspector.
4. If cursor release is enabled, press Escape. The cursor should become visible and camera look should stop until the cursor is captured again.
5. If the scene has on-screen controls, interact with each button and axis. The controls should affect the assigned character and should use the same names as the corresponding actions or mappings.
6. In a local multiplayer scene, test one device at a time. Only its assigned character and camera should respond.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The character does not respond. | **Player Input Proxy > Player Input** may be empty, or it may reference an input component from another character. | Assign the character’s own **Unity Input**, **Unity Input System**, or **Rewired Input** component. |
| Unity Input System actions never fire. | Unity **Player Input > Actions** or its current action map may be missing, or the requested action name may not exist in that map. | Assign the intended action asset, activate `Gameplay` or the custom map, and make its action names match UCC’s input names. |
| Legacy movement works but an ability does not. | The ability’s input name may not match an Input Manager button mapping. | Add or correct the mapping, or change the ability to request the existing name. |
| The camera does not look around. | Check **Horizontal Look Input Name**, **Vertical Look Input Name**, **Look Vector Mode**, and whether the cursor is released. | Match the look names to the route, choose a non-Manual mode unless another system supplies look, and recapture the cursor. |
| Both local characters respond to one device. | The characters may share an input component, Rewired player, Unity device pairing, or global legacy mapping. | Give each character a separate implementation and player/device assignment; do not treat a second camera as input ownership. |
| On-screen controls are hidden or inactive. | **Virtual Controls Setup > Input Type** may not match the character’s input route, or **Force Input** may select the desktop mode while testing in the Editor. | Add the matching controls and temporarily choose **On Screen** or **Virtual** on the input component. |
| Input stays disabled after closing a menu. | The system that sent `OnEnableGameplayInput` with `false` may not have sent the matching `true` event. | Restore gameplay input when the menu closes or the interaction ends. |

## Related pages

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Virtual Controls](https://opsive.com/support/documentation/ultimate-character-controller/input/virtual-controls/)
- [Rewired](https://opsive.com/support/documentation/ultimate-character-controller/integrations/rewired/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)

## Developer reference

### Read input through `IPlayerInput`

`PlayerInputProxy` implements `IPlayerInput`, so gameplay code can read the character-level interface without locating the concrete implementation. The interface supplies `GetButton`, `GetButtonDown`, `GetButtonUp`, `GetAxis`, `GetAxisRaw`, `GetTap`, `GetDoublePress`, `GetLongPress`, and `GetLookVector`.

```csharp
using Opsive.Shared.Input;
using UnityEngine;

public class MyObject : MonoBehaviour
{
    [SerializeField] private GameObject m_Character;

    private IPlayerInput m_PlayerInput;

    private void Awake()
    {
        m_PlayerInput = m_Character.GetComponent<IPlayerInput>();
    }

    private void Update()
    {
        if (m_PlayerInput != null && m_PlayerInput.GetButtonDown("Jump")) {
            // Respond to the Jump press.
        }
    }
}
```

### Enable or disable gameplay input

Send `OnEnableGameplayInput` on the character to disable or enable the input implementation, character locomotion handler, and attached camera input together. This is useful while a full-screen menu or another interaction owns the controls.

```csharp
using Opsive.Shared.Events;
using UnityEngine;

public class GameplayInputToggle : MonoBehaviour
{
    [SerializeField] private GameObject m_Character;

    public void SetGameplayInput(bool enable)
    {
        EventHandler.ExecuteEvent(m_Character, "OnEnableGameplayInput", enable);
    }
}
```

---

<a id="page-ultimate-character-controller-input-virtual-controls"></a>

# Virtual Controls

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/input/virtual-controls/)

Use virtual controls to give a mobile player on-screen movement, camera, and action controls without changing the character's abilities. UCC supplies one layout for Unity's Input System and another for the legacy Input Manager.

## Before you begin

- Set up and test the character with its normal input first. See [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) to choose the Unity Input System or legacy Input Manager route.
- Add the scene managers, camera, and Canvas before arranging a final mobile HUD. [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) covers that scene workflow.
- Use the virtual-control type that matches the character's input component. The two supplied layouts are not interchangeable.

## Choose a control type

| Character input | Setup Manager **Input Type** | Generated root component | How controls send input |
| --- | --- | --- | --- |
| Opsive **Unity Input System** | **InputSystem** | **On Screen Controls** | Unity **On-Screen Button** and **On-Screen Stick** components feed the control paths used by the action asset. |
| Legacy **Unity Input** | **InputManager** | **Virtual Controls Manager** | Opsive **Virtual Button**, **Virtual Joystick**, and **Virtual Touchpad** components feed named Input Manager buttons and axes. |

Use the Unity Input System route for a new project that already uses actions and control schemes. Use the legacy route only when the character uses the Input Manager or when an existing project depends on its named mappings.

## Add the supplied controls

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and select **Scene**.
2. Under **Virtual Controls Setup**, choose **Input Type**:
   - **InputSystem** for a character with Opsive **Unity Input System**.
   - **InputManager** for a character with legacy **Unity Input**.
3. Select **Add Virtual Controls**. The Setup Manager creates a Canvas if the scene does not already have one, then adds a **VirtualControls** UI root.
4. Select the new root and set **Character** when the controls should always operate one specific character. Leave it empty for a single-player scene where the controls should follow the character attached to the Camera Controller.
5. Select the character's input GameObject and set **Force Input** for the current test:
   - On Opsive **Unity Input System**, choose **On Screen**.
   - On legacy **Unity Input**, choose **Virtual**.
6. Enter Play Mode and confirm that the root becomes active. Return **Force Input** to **None** before the mobile build if platform detection should decide between desktop and on-screen input.

On supported mobile builds, both input implementations select their on-screen mode automatically unless **Force Input** is set to **Standalone**. Forcing the mode is mainly useful for testing the layout with a mouse in the Editor.

## Configure Unity Input System controls

The supplied InputSystem layout contains movement and camera sticks plus Attack, Next, Reload, Action, and Jump buttons. Its root **On Screen Controls** component owns the character reference; each child uses Unity's standard on-screen component.

1. For a button, set **Control Path** to a control that is bound to the intended action in the active input action map.
2. For a stick, set **Control Path** to the vector control used by the movement or look bindings.
3. Keep **Use Isolated Input Actions** enabled on a stick when control-scheme switching would otherwise cancel its pointer drag.
4. Adjust **Movement Range** to the visible stick radius. Use **Behaviour** to decide whether the origin stays fixed or follows the first touch.

The supplied prefab uses `<Gamepad>/leftStick` for movement and `<Gamepad>/rightStick` for camera look. Both sticks use **Movement Range** `75`, **Exact Position With Static Origin**, and **Use Isolated Input Actions**. The supplied buttons simulate keyboard controls already represented in `CharacterInput`, including Space for Jump and R for Reload.

Changing a button's label does not change its action. Update **Control Path** and the input action binding together, then verify the result in Play Mode.

## Configure legacy controls

All legacy Virtual Button, Virtual Joystick, and Virtual Touchpad objects must remain below the **Virtual Controls Manager** so they can register their input names with the correct character.

### Movement joystick

The supplied **Virtual Joystick** uses **Horizontal Input Name** `Horizontal`, **Vertical Input Name** `Vertical`, **Radius** `100`, and **Deadzone Radius** `5`. Keep **Joystick** assigned to the movable knob. Increase the deadzone if small unintended motion occurs near the center; increase the radius when the visual control should allow a longer drag.

### Camera touchpad

The supplied **Virtual Touchpad** uses `Mouse X` and `Mouse Y`, so dragging the open look area rotates the camera. **Delta Position Multiplier** controls the drag response. Enable **Require Active Drag** when the value should begin damping as soon as the pointer stops moving, and tune **Active Drag Damping** to control how quickly it falls. Leave **Use Axis Input** disabled for a touch-driven look area.

### Action buttons

Set each **Virtual Button > Button Name** to the exact Input Manager mapping requested by the ability or item action. The supplied layout includes `Fire1`, `Equip Next Item`, `Reload`, `Action`, and `Jump`.

The supplied Virtual Controls Manager leaves **Allow Axis Input** disabled and enables **Allow Button Input**. That keeps physical axes from being mixed into the touch joystick while still allowing a physical button to supplement an unpressed virtual button when the pointer is not over UI. Change those settings only when the game deliberately supports hybrid touch and physical input.

## Design for common mobile scenarios

- **Third-person movement and camera:** Keep the left movement stick, use the touchpad or right stick for look, and place action buttons where they do not cover the look area.
- **Twin-stick controls:** Use a second stick for the look axes. Match its legacy input names or Input System control path to the camera bindings.
- **Large drag-to-look area:** Stretch the touchpad or right-stick hit area behind the action buttons, but keep interactive buttons above it in the Canvas hierarchy so their pointer events are not stolen.
- **Controller plus touch:** Keep the virtual controls active and use the route's physical-input options or bindings. Test simultaneous input because the legacy fallback and Input System control-scheme behavior are different.
- **Multiple local players:** Give each UI root an explicit **Character**. This chooses which UCC input instance is enabled by that root, but it does not by itself pair Unity Input System devices, divide touch regions between players, or configure per-player UI navigation. Complete those responsibilities in the selected input system and follow [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/).

## Verify in Play Mode

1. Force the matching on-screen mode and enter Play Mode. The **VirtualControls** root should become visible only for a character with the matching input implementation.
2. Drag the movement control in all directions. The character should move smoothly, return to idle on release, and remain still inside the intended deadzone.
3. Drag the look control slowly and quickly. The camera should rotate on both axes without continuing after the interaction ends unless that response is intentional.
4. Press each action button once. Only the action whose mapping or binding matches that control should start.
5. Press two controls together, such as movement and Jump. Both should remain responsive under multitouch.
6. Open menus and press near UI boundaries. Gameplay controls should not activate through an interactive menu control.
7. Change or respawn the Camera Controller's character when **Character** is empty. The controls should attach to the new character; an explicitly assigned root should remain with its assigned character.
8. Build to a target device and repeat the test. Confirm safe-area placement, UI scale, orientation changes, and real multitouch instead of relying only on mouse simulation.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The controls never appear. | **Input Type** may not match the character's input component, or **Force Input** may be **Standalone**. | Add the matching layout and use **On Screen**, **Virtual**, or **None** on a mobile build. |
| The Console reports that the character has no Unity input component. | The root's **Character** may use the other input route or reference the wrong character. | Assign a character with Opsive **Unity Input System** to On Screen Controls, or legacy **Unity Input** to Virtual Controls Manager. |
| A legacy control logs that it cannot find Virtual Controls Manager. | The Virtual Button, Joystick, or Touchpad is outside the manager's hierarchy. | Move the control below the correct Virtual Controls Manager root. |
| A button highlights but no action starts. | Its **Button Name** or **Control Path** may not match a configured mapping or binding. | Match the legacy mapping exactly, or bind the simulated Input System control path to the intended action. |
| The movement stick never returns to zero. | Its knob reference, pointer-up event, or UI raycast may be blocked. | Confirm **Joystick** is assigned, the control has a raycast target, and no full-screen UI element intercepts pointer release. |
| Camera look is too slow, too fast, or drifts. | Check the touchpad **Delta Position Multiplier**, **Require Active Drag**, and the character input's look sensitivity. | Tune one layer at a time and verify that release returns both look axes to zero. |
| Desktop input unexpectedly changes touch input. | Legacy **Allow Axis Input** or **Allow Button Input**, or Input System control-scheme switching, may combine sources. | Disable the unwanted legacy fallback or revise the Input System bindings and device pairing. |
| Two players respond to the same touch controls. | Both roots may follow the same camera character, or the virtual device may not be paired per player. | Assign **Character** explicitly on each root and configure ownership in the selected input system. |

## Related pages

- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)
- [Control Freak](https://opsive.com/support/documentation/ultimate-character-controller/integrations/control-freak/)

## Developer reference

Both root components expose a `Character` property for a character spawned or selected at runtime. The legacy manager also exposes `AllowAxisInput` and `AllowButtonInput`. Assigning `Character` performs the same unregister/register work as changing ownership in the Inspector.

```csharp
using Opsive.Shared.Input.InputManager.VirtualControls;
using UnityEngine;

#if ENABLE_INPUT_SYSTEM
using Opsive.Shared.Input.InputSystem;
#endif

public class VirtualControlOwner : MonoBehaviour
{
    [SerializeField] private VirtualControlsManager m_LegacyControls;

#if ENABLE_INPUT_SYSTEM
    [SerializeField] private OnScreenControls m_InputSystemControls;
#endif

    public void SetCharacter(GameObject character)
    {
        if (m_LegacyControls != null) {
            m_LegacyControls.Character = character;
        }

#if ENABLE_INPUT_SYSTEM
        if (m_InputSystemControls != null) {
            m_InputSystemControls.Character = character;
        }
#endif
    }
}
```

Changing `UnityInput.ForceInput` raises `OnUnityInputTypeChanged` with the legacy input instance and a Boolean virtual-input state. Changing `UnityInputSystem.ForceInput` raises `OnUnityInputSystemTypeChanged` with a Boolean on-screen state. The supplied root components listen to those events and activate or hide themselves automatically.

---

<a id="page-ultimate-character-controller-state-system"></a>

# State System

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

Use the State System to change selected public properties when gameplay conditions such as aiming, running, equipping an item, or entering water become active. It keeps these variations in Inspector-configured presets instead of spreading one-off value changes through gameplay scripts.

## When to use a state

A state is a good fit when the desired result is a temporary value change on a state-enabled component or serialized UCC object. Examples include a narrower camera field of view while aiming, different movement values while sprinting, or an item setting that changes while a named character state is active.

Use an ability, action module, or another gameplay system when the feature needs to perform an action rather than apply property values. A state does not replace the logic that decides when aiming, running, or another condition begins; it defines the values that should apply while that condition is active.

The only direct child in this section is [Presets](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/). Read it when you need to choose which public properties a state stores, reuse a preset asset, or remove a property from a preset.

## Create a state

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Scene** tab and choose **Add Managers** under **Manager Setup**. Confirm that the scene's **Game** GameObject has **State Manager**. The runtime can create a fallback manager, but keeping the service visible in the scene makes setup and event configuration easier to verify.
3. Select the state-enabled component, ability, movement type, view type, or item module that owns the value. Configure its normal Inspector values first; these become the runtime **Default** values.
4. Expand **States** and select the plus button.
5. Choose **Create New Preset**, save the asset under a project-owned folder such as `Assets/<ProjectName>/Presets`, and give it a descriptive name. Choose **Add Existing Preset** only when the asset was created for the same owner type.
6. Select the new preset asset. In its Inspector, use **Add Property...** to add only the public properties that this state should change, then enter their state-specific values. A property needs a usable public getter and setter to appear and apply at runtime.
7. Return to the owner and give the new row a unique, case-sensitive **State** name. The same logical condition must use the same spelling everywhere it should apply.
8. Drag the row to its priority position. The top active row wins when multiple presets set the same property. Leave **Default** at the bottom; it cannot be edited, removed, or moved.
9. Use **Blocked By** only when another active state should suppress this row completely. For example, on a camera's `Zoom` row choose `Run` under **Blocked By** when running should prevent the zoom preset from applying.
10. Save the component's scene or prefab and the preset asset, then test the actual gameplay trigger in Play Mode.

The **Persist** button copies the owner's current values into properties already stored by that row's preset. It changes the preset asset, so use it deliberately after confirming the selected owner and preset. The **Activate** button is available in Play Mode for a quick property check; it toggles that one row directly and is not a substitute for testing the real ability, item, or script that owns the state.

## Manage shared State names

A mapped State Name field opens a searchable popup. Select an existing entry, enter a valid name and choose **Add**, or choose **Open Editor** for the complete map. Open that editor directly from **Tools > Opsive > Ultimate Character Controller > Utility > State Names**.

For project-owned names, create **Assets > Create > Opsive > Ultimate Character Controller > Utility > NameMap**, assign it to **Name Map**, and keep the asset in version control. The first Add to a new map asks where to save its editable CSV file; store the map and CSV together. **Order By > Name Ascending** or **Name Descending** changes the editor presentation. Entries supplied through **Read Only Files** can be selected but cannot be edited or removed from this window.

The utility window remembers its selected map in editor preferences for that workstation. Verify the project map on every developer machine; choosing it in the utility window does not rewrite every existing scene or prefab. State names remain case-sensitive at runtime.

## How states combine

At runtime, the bottom **Default** state captures the owner's normal public property values and remains active. When another state activates, its preset changes only the properties stored in that preset. Unlisted properties continue to come from Default or another active state.

If several active states change the same property, the State System reapplies them from lower priority to higher priority, so the row nearest the top supplies the final value. When a state deactivates, the affected properties return to their Default values and the remaining active, unblocked states are applied again.

A row named in **Blocked By** is a blocker of the current row. If that blocker is active, the current state remains recorded as active but its preset is skipped. The Inspector only shows bold text and `(Active)` when the state is active and not blocked.

![States list showing Shield and Default in bold with (Active) during Play Mode while the other item states are inactive.](https://opsive.com/wp-content/uploads/2018/03/ActiveStates.webp?v=23573a3cc873)

When a GameObject-based state change uses a shared name, State Manager updates the registered state owners for that GameObject. UCC also maps relevant character-owned child objects and the attached camera back to the character, allowing their matching states to follow the character condition. An item initialized after a character state is already active receives that active state during initialization.

## Key choices by scenario

| Scenario | Recommended configuration |
| --- | --- |
| Aim uses a different camera zoom for each weapon | Give the relevant camera view type and item owners the same state name, such as `Zoom`, but use a separate type-compatible preset for each owner. Store only the properties each owner needs to change. |
| Running should suppress aim zoom | On the camera's `Zoom` row, add `Run` to **Blocked By**. Do not put `Zoom` in the `Run` row unless zoom should block running instead. |
| A higher-priority condition should override one value but preserve others | Put the higher-priority row nearer the top and include only the property it owns. Values not present in that preset continue to come from lower active states. |
| Several characters share the same tuning | Reuse the same preset only for the same concrete owner type. Duplicate the preset before one character needs independent values. |
| A short damage or interaction effect needs temporary values | Activate a named state, then schedule its deactivation with `StateManager.DeactivateStateTimer`. The timer only schedules deactivation, so the state must already be active. |
| A linked object outside the normal character hierarchy should follow states | Link it deliberately with `StateManager.LinkGameObjects`, and give its state-enabled owners matching state names. Unlink it when the relationship ends. |

## Verify in Play Mode

1. Expand **States** on the owner and record the relevant Default property values.
2. Trigger the real ability, item condition, or script that activates the state. Confirm the expected row becomes bold and displays `(Active)`.
3. Inspect the affected component or StateObject. Only properties included in the preset should change.
4. Activate a second state that overlaps one property. Confirm the row nearer the top supplies the final value while nonoverlapping properties remain combined.
5. Test **Blocked By**. The suppressed row should lose its visible active marker and its values should no longer apply while its blocker is active.
6. End each condition. The remaining active states should recombine, and the last deactivation should restore the recorded Default values.
7. If the state should affect a camera or equipped item, test that object too. Equip or initialize an item while the character state is already active and confirm it starts with the matching values.
8. Stop Play Mode and reopen the scene or prefab. Confirm the state rows and preset references remain assigned and no runtime-only Inspector value was mistaken for an asset change.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| A state never becomes active. | The activating code or built-in feature uses a different spelling or case, or the owner was not initialized with State Manager. | Match the state name exactly, confirm the owner exposes **States**, and verify the scene's **Game** object has State Manager. |
| The row becomes active but no value changes. | The preset contains no property, uses the wrong owner type, or the property lacks a usable public getter and setter. | Open the preset, add the intended property with **Add Property...**, and use a preset created for that owner type. |
| The wrong value wins while several states are active. | Two presets change the same property and their list order is reversed. | Move the state that should win nearer the top, then repeat the overlap test in Play Mode. |
| A state is requested but does not show `(Active)`. | One of the names in that row's **Blocked By** field is active. | Remove the unintended blocker or deactivate it. Keep the blocker on the row that should be suppressed. |
| The camera or item does not follow a character state. | Its owner has no matching state name, has not initialized yet, or is outside the normal character/camera relationship. | Add a type-compatible preset under the exact shared name, verify initialization, or link the GameObjects deliberately. |
| Editing one preset changes several characters or items. | They reference the same preset asset. | Keep sharing when the values should remain common; otherwise duplicate the asset and assign the copy before editing. |
| **Persist** saved unexpected values. | The wrong row, owner, or shared preset was selected. | Undo or restore the preset from version control, select the intended project-owned asset, set the owner values, and persist again. |
| `OnStateChange` is never received. | **Send State Change Event** is disabled, or the state was toggled through the row's **Activate** button or an owner-specific overload instead of the GameObject-based path. | Enable the manager setting and use `StateManager.SetState(GameObject, string, bool)` for changes that need the global event. |

## Related tasks

- [Presets](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Programming Concepts](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Action Modules and Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)

## Developer reference

The released Version 3 State System types are in `Opsive.Shared.StateSystem`. `StateBehavior` is the `MonoBehaviour` owner used by state-enabled components, while `StateObject` is the serializable owner used by abilities, movement types, view types, and other nested objects. Both expose `States`, `SetState(string, bool)`, `StateWillChange()`, and `StateChange()`.

Use the GameObject overload when a named condition should update all registered owners and participate in the optional global event:

```csharp
StateManager.SetState(character, "Zoom", true);

StateManager.SetState(character, "DamageFlash", true);
StateManager.DeactivateStateTimer(character, "DamageFlash", 0.25f);
```

`StateManager.SetState(object, State[], string, bool)` targets one registered owner and state array. `StateManager.ActivateState` toggles a specific `State` directly and is what the Inspector's **Activate** button uses. These narrower paths do not send the manager's global state-change event.

![State Manager Inspector with Send State Change Event enabled.](https://opsive.com/wp-content/uploads/2018/03/StateChangeEvent.webp?v=7faf05657492)

When **Send State Change Event** is enabled, the GameObject-based path sends the global `OnStateChange` event with `GameObject stateGameObject`, `string stateName`, and `bool active`. Register and unregister through the [event system](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/). The manager calls each affected owner's `StateWillChange()` before applying values and `StateChange()` afterward.

`StateManager.AddState(GameObject, IStateOwner, State[], State, int)` can add a non-default, uniquely named state with a preset after that owner has initialized in Play Mode. The index must be inside the existing array; use `0` for the highest-priority position. Prefer editor-authored states unless runtime composition is a real requirement, because the runtime API must also preserve the owner's state array and preset lifetime.

---

<a id="page-ultimate-character-controller-state-system-presets"></a>

# Presets

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/)

A State Preset stores selected public property values for one state-enabled owner type. Use one when a named gameplay condition should temporarily change Inspector values, such as Jump force, movement speed, camera field of view, or an item setting, then restore the normal values when that condition ends.

## When a preset is appropriate

Use a State Preset for value changes that already have a gameplay owner and a clear on/off condition. The system applies the preset while its State is active; it does not detect the condition, start an ability, play an animation, or save gameplay progress.

Keep the normal value directly on the component, ability, movement type, view type, or other state-enabled object. Put only the properties that should differ into the preset. An unlisted property continues to use its normal value or a value supplied by another active State.

Use separate gameplay logic when the change needs a sequence, spawned object, collision query, or another action rather than a property override.

## Create and assign a preset

1. Select the component or nested UCC object that owns the value and configure its normal Inspector values first. These become its runtime **Default** values.
2. Expand **States** at the bottom of the owner Inspector. The table contains **State**, **Preset**, **Blocked By**, **Persist**, and **Activate** columns, with the fixed **Default** row at the bottom.
3. Select the plus button and choose **Create New Preset**.
4. In **Save Preset**, save a unique `.asset` under a project-owned folder such as `Assets/<ProjectName>/Presets`. A new asset is typed for this owner and begins with no stored properties; it is not a snapshot of every current value.
5. Confirm the new row references that asset in **Preset**, then give the row a unique, case-sensitive **State** name that matches the condition that will activate it.
6. Select the preset asset. In its Inspector, choose a property from **Add Property...**, then enter the value that should apply while this State is active.
7. Return to the owner and drag the row to its priority position. Keep **Default** last; it cannot be edited, removed, or moved.
8. Save the owner scene or prefab and the preset asset.

![States add menu with Create New Preset for the selected state-enabled owner](https://opsive.com/wp-content/uploads/2018/04/CreatePreset.webp?v=7ada7f65fd43)

**Add Existing Preset** opens a preset asset picker and adds a State that references the selected asset. Use an asset created for the same concrete owner type. The State Inspector rejects an incompatible recorded type rather than applying similarly named properties to the wrong object.

## Add, update, and remove properties

The preset Inspector lists public properties available on its recorded owner type. A property needs a usable public getter and setter to be a safe runtime override. The released Inspector can list a getter-only property, but the runtime delegate has no setter to apply it; do not add read-only properties.

![Jump preset Inspector with Add Property options for public Jump properties](https://opsive.com/wp-content/uploads/2018/04/AddJumpProperty.webp?v=42fe1fbbf24c)

When a property is first added, the preset uses the type's default value from a temporary default instance. It does not read the selected scene or prefab owner. Choose one of these workflows:

- Enter the state-specific value directly in the preset asset.
- Configure the desired value on the owner, then select the row's **Persist** control to copy the owner's current value into properties already stored by that preset.

**Persist** updates only properties already present in the preset. It changes the shared asset, not just that row or instance. It does not copy a top-level `UnityEngine.Object` property in released Version 3; assign an allowed project asset reference directly in the preset Inspector instead.

Select the **X** beside a property to remove that complete property and its stored value. The State will stop overriding it the next time values are initialized and applied.

![Preset property row with the X removal control outlined in red](https://opsive.com/wp-content/uploads/2018/04/PropertyRemoval.webp?v=d4b5070e5106)

## Choose what owns each value

| Goal | Recommended setup |
| --- | --- |
| One temporary difference | Leave the normal value directly on the owner and store only that property in one preset. |
| Several independent changes | Use separate presets and State names when the conditions start and stop independently. Each preset should contain only the values that condition owns. |
| One condition changes several related values | Put those properties in one preset so they activate and restore together. |
| Several objects use identical tuning | Share one preset asset only among the same owner type. Runtime initialization creates per-owner delegate instances, while the serialized values remain shared. |
| One character or item needs different tuning | Duplicate the preset asset and assign the copy before editing it. Editing a shared asset changes every row that references it. |
| A higher-priority State changes the same property | Move the State nearer the top of **States**. Active States are recombined so the top row supplies the final overlapping value. |
| One State should suppress another completely | On the row that should be suppressed, add the stronger State to **Blocked By**. A blocked State remains recorded as active but its preset is skipped. |
| A quick Play Mode value check | Use the row's **Activate** control in Play Mode. It toggles that row directly; still test the real ability, item, trigger, or code path afterward. |

The generated **Default** preset is different from the `.asset` assigned to a named State. During initialization, it captures the owner's normal public values. When a named State deactivates, Default restores the properties that State changed, then the remaining active, unblocked States are reapplied from lower priority to higher priority.

Directly editing an affected runtime property while its State remains active is temporary. The next State activation, deactivation, block change, or recombination can apply the preset again. Change the preset or the condition's ownership instead of fighting an active override.

## Work with nested values, lists, and references

A top-level public property can contain a serializable class, struct, array, or list. The preset Inspector expands its nested data, and the State treats that top-level property as one override. Removing it removes the complete nested value.

- Use a nested property when the complete setting should change and restore together.
- Expose separate top-level public properties when different States need independent priority over individual parts.
- Keep lists and arrays initialized. The runtime copies their elements into the owner's existing collection and resizes an array through its setter when necessary; a null destination cannot be updated safely.
- Store project asset references only when Unity can serialize them in the preset asset. A project-level preset cannot hold a durable reference to a scene object.
- Do not use a preset as mutable per-instance inventory, target, checkpoint, or save data. Those values belong to their runtime and persistence owners.

## How activation and ordering work

1. A state-enabled owner initializes its State array with State Manager in Play Mode.
2. The last **Default** row receives a generated runtime preset that captures the owner's normal public values and remains active.
3. Each named preset initializes delegates against that specific owner. When the same asset is already initialized for another owner, the State creates a runtime copy so delegates do not point to the earlier object.
4. A built-in feature or project call activates a State by its exact name. The preset changes only its stored properties.
5. When several unblocked States are active, the list is applied from lower priority to higher priority. The row nearest the top is applied last and wins overlapping properties.
6. **Blocked By** prevents a row's values from applying while a named blocker is active. Its active flag remains set so it can resume automatically when the blocker ends.
7. On deactivation, Default restores only the properties affected by that State, then the remaining active States are applied again.

The State Inspector's **Activate** control calls the narrow row activation path. It does not represent the owner callbacks or optional global state-change event used by the normal GameObject-based path, so treat it as a visual preset test rather than full gameplay verification.

## Editor checkpoint

Before Play Mode, confirm that:

- the owner exposes **States**, its normal direct values are correct, and **Default** remains last;
- every named row has a unique, case-sensitive name and a preset for the same concrete owner type;
- each preset contains only public getter-and-setter properties that the State should own;
- newly added values were entered directly or deliberately captured with **Persist**;
- shared assets are meant to remain shared, and instance-specific variants use duplicated assets;
- nested values and lists are initialized and contain no scene-object reference that an asset cannot serialize;
- overlapping presets are ordered with the intended winner nearer the top;
- **Blocked By** is configured on the row that should be suppressed; and
- the ability, item, trigger, or project code that owns activation uses the exact same State name.

## Verify in Play Mode

1. Create a small test preset on a visible property, such as Jump **Jump Force**, camera field of view, or a movement speed value. Record the owner's normal value.
2. Enter Play Mode and trigger the real gameplay condition. Confirm the row becomes bold and displays `(Active)` and the stored property changes to the preset value.
3. End the condition. Confirm the property returns to the normal value captured by Default.
4. Add a second State that changes the same property, place it above the first, and activate both. Confirm the top row supplies the final value.
5. Move that row below the first and repeat. Confirm the winner changes with the list order.
6. Add the stronger State to the weaker row's **Blocked By** field. Activate both and confirm the weaker row is suppressed; deactivate the blocker and confirm the still-active weaker State resumes.
7. Add a nonoverlapping property to one preset. Confirm both States can remain active and combine their independent values.
8. If the preset is shared, test two owners of the same type. Confirm both use the asset values without one owner's runtime delegate targeting the other.
9. Stop Play Mode, reopen the preset asset and owner, and confirm only editor-authored asset and row changes persisted. Runtime active flags and temporary Inspector values should be gone.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| A new preset contains no component snapshot | This is the released workflow: **Create New Preset** creates an empty typed asset. | Add the intended properties, enter their values, or use **Persist** after the properties exist. |
| The row becomes active but no value changes | The preset has no property, the wrong property was added, or the State is blocked. | Open the asset, add the intended property, inspect **Blocked By**, and repeat the Play Mode test. |
| A property appears in **Add Property...** but fails when activated | It has a public getter but no usable public setter. The Inspector's availability check is less strict than runtime application. | Expose a public setter or choose another supported property. Do not add a read-only value. |
| The preset cannot be assigned | Its recorded object type does not match the State owner type. | Create or select a preset from the same concrete component, ability, movement type, view type, or nested owner. |
| **Persist** saved surprising values | The wrong owner or shared asset was selected, or the component was already under another active override. | Restore or undo the asset, configure the intended owner in Edit Mode, verify the row, and persist again. |
| **Persist** does not update an asset reference | Released Version 3 skips a top-level `UnityEngine.Object` property in the Persist path. | Assign a project asset directly in the preset Inspector. Do not use a scene-object reference. |
| Editing one preset changes several characters or items | Their rows reference the same asset. | Keep the shared asset for common tuning or duplicate it and assign the copy before editing. |
| The wrong value wins | Two active presets include the same property and their list order is reversed. | Move the intended winner nearer the top and retest both States together. |
| The value returns to an unexpected default | The normal owner value was changed after State initialization or loaded after Default captured its runtime snapshot. | Establish and load normal values before State initialization, or deliberately reinitialize/restore them through the system that owns load order. |
| A nested list fails or keeps old elements | The owner's collection is null, its getter/setter is unsuitable, or the preset was not refreshed after the desired list changed. | Keep the collection initialized, expose a usable public getter/setter, then edit the preset or use **Persist** for the stored property. |
| The row is active but does not show `(Active)` | Another active row in **Blocked By** suppresses it. | Remove the unintended blocker or end that condition. |
| `OnStateChange` is not received during the Inspector test | **Activate** calls the direct row path, and the manager event is only sent by the GameObject-based path when enabled. | Test through `StateManager.SetState(GameObject, string, bool)` and enable State Manager **Send State Change Event** when an integration needs it. |

## Saving and networking

The preset `.asset`, the owner's State rows, their names, list order, block lists, and preset references are authored configuration. The active flag, generated Default snapshot, runtime delegate copies, linked-object maps, and timed deactivations are transient.

A save system should store the authoritative gameplay condition or active State names that must survive loading. Restore normal owner data first, wait until its States initialize, then reactivate the required names. Saving only the active flag is insufficient when the system that owns the ability, item, camera, or other condition disagrees after load.

State Presets do not replicate themselves or their active status. State Manager **Send State Change Event** starts disabled and only exposes the GameObject-based change to a listening integration; it does not perform networking. Let authority choose the change, keep matching preset assets on every peer, and let the installed integration or project code synchronize the State name and active value.

## Related tasks

- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) explains State creation, priority, blocking, and cross-owner activation.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains registration for the optional global State change event.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) covers common owners and gameplay triggers for named States.
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) covers movement settings that can be varied with a State.
- [Character Time](https://opsive.com/support/documentation/ultimate-character-controller/character/time/) shows a practical `TimeScale` State property.
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) is an example of a component whose behavior can be tuned by State values.

## Developer reference

The released types are in `Opsive.Shared.StateSystem`. `PersistablePreset` stores serialized property data and initializes per-owner delegates. `StateBehavior` is the component owner and `StateObject` is the nested serializable owner; both expose `States`, `SetState(string, bool)`, `StateWillChange()`, and `StateChange()`.

Use the GameObject path when the same State name should update all registered owners on that object and participate in the optional global event:

```csharp
using Opsive.Shared.StateSystem;

StateManager.SetState(character, "Zoom", true);

StateManager.SetState(character, "DamageFlash", true);
StateManager.DeactivateStateTimer(character, "DamageFlash", 0.25f);
```

`DeactivateStateTimer` schedules only deactivation, so activate the State first. `StateManager.SetState(object, State[], string, bool)` targets one registered owner. `StateManager.ActivateState(State, bool, State[])` toggles a specific row and is the path used by the Inspector's **Activate** control. Only the GameObject overload sends the optional global `OnStateChange(GameObject, string, bool)` event when State Manager **Send State Change Event** is enabled.

`Preset.Initialize`, `UpdateValue`, and `ApplyValues` operate on runtime delegates; they do not save an edited asset automatically. `PersistablePreset.CreatePreset(object)` creates an in-memory typed preset with empty property data under the editor workflow's default visibility. Asset creation and durable changes remain editor/project responsibilities.

---

<a id="page-ultimate-character-controller-attributes"></a>

# Attributes

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/attributes/)

Attributes store bounded values such as health, shield, stamina, hunger, battery charge, or durability. Add them to an Attribute Manager when gameplay needs a named value that other UCC components can read, spend, restore, or update over time.

![Attribute Manager Inspector listing Health, Shield, and Stamina with Stamina selected](https://opsive.com/wp-content/uploads/2018/03/AttributeManager.webp?v=618c09a297ea)

## Choose the setup path

| Goal | Start here |
| --- | --- |
| Give a UCC character health, shield, death, and respawn support | In Character Manager, enable **Health**. This adds **Character Attribute Manager**, **Character Health**, and **Character Respawner**. Continue with [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/). |
| Add stamina or another value to a character that already has health | Add the new entry to its existing **Character Attribute Manager**. |
| Add attributes to a character without the health system | Add **Character Attribute Manager** to the character so initialization follows the UCC character lifecycle. |
| Add charge, durability, or another value to an item or ordinary GameObject | Add the standard **Attribute Manager** component to that object. |

The manager stores values; it does not decide what consumes them. Connect each attribute to a Health component, ability Attribute Modifier, item action, UI monitor, or custom system by using the exact same attribute name.

## Add and configure an attribute

1. For a character that needs health, open **Tools > Opsive > Ultimate Character Controller > Character Manager**, assign **Character**, enable **Health**, and select **Build Character** or **Update Character**.
2. Select the GameObject and locate **Character Attribute Manager** or **Attribute Manager** in the Inspector.
3. Select the plus button below the **Attribute** list. Select the new row to show its settings.
4. Set **Name** to a unique, nonempty value such as `Stamina`. Names are case-sensitive at runtime, so copy the same spelling into every component that references it.
5. Set **Min Value**, **Max Value**, and the starting **Value**. The Inspector keeps the range valid and clamps the starting value inside it.
6. Choose **Auto Update Value Type**. Use **None** for a value changed only by gameplay, **Increase** to move toward **Max Value**, or **Decrease** to move toward **Min Value**.
7. When automatic updates are enabled, configure **Update When Inactive**, **Auto Update Start Delay**, **Auto Update Interval**, and **Auto Update Amount**.
8. Configure the component that consumes the value. For example, select `Health` in **Character Health > Health Attribute**, or select `Stamina` in an ability's **Attribute Modifier**.
9. Enter Play Mode and change the value through the real gameplay action before duplicating the setup.

Disabling **Health** in Character Manager removes the character's attribute manager together with Character Health and Character Respawner. Preserve or recreate any custom attributes before deliberately removing that managed component set.

## Choose the value and update settings

| Setting | Decision |
| --- | --- |
| **Name** | Use a stable, unique identifier. `GetAttribute` and UCC consumers match this exact string. |
| **Min Value** and **Max Value** | Define the legal range. Runtime assignments and automatic updates are clamped to these bounds. |
| **Value** | Set the starting value captured when the attribute initializes. `ResetValue()` returns to this starting value. |
| **Auto Update Value Type** | Choose **Increase** for regeneration, **Decrease** for continuous depletion, or **None** when another system owns every change. |
| **Update When Inactive** | Enable it only when automatic updates must continue while the owning GameObject is inactive. |
| **Auto Update Start Delay** | Set how long an automatic update waits after initialization or a direct value change. Every `Value` assignment restarts this delay. |
| **Auto Update Interval** | Set the time between automatic update steps. Short intervals look smoother but execute more often. |
| **Auto Update Amount** | Enter the positive amount applied on each step. **Increase** adds it; **Decrease** subtracts it. |

Use the **States** foldout only when a named UCC state should override attribute settings. Keep the default values correct first, then test every state transition that changes the range or automatic update behavior. See the [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/).

## Configure common scenarios

### Health and a regenerating shield

Keep the `Health` attribute at its full starting value with **Auto Update Value Type** set to **None** unless the game deliberately regenerates health. Add a separate `Shield` attribute, choose **Increase**, and use **Auto Update Start Delay** to create the pause after taking damage. In Character Health, set **Health Attribute** and **Shield Attribute** to those exact names.

The Health component applies shield damage before health and provides damage, healing, death, hitbox, and fall-damage behavior. Follow the direct child guide: [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/).

### Stamina used by an ability

Add `Stamina` to **Character Attribute Manager** and let it regenerate with **Increase**. On the ability, select `Stamina` in **Attribute Modifier**, set a negative **Amount**, and enable the modifier's **Auto Update** when the cost should repeat while the ability remains active. The ability checks the modifier before starting and can stop when the repeated cost reaches the minimum.

The ability modifier temporarily owns the attribute's auto-update settings while active, then restores the previous settings and schedules the normal attribute update again. Test the transition from drain to regeneration rather than configuring both in isolation.

### Hunger or another continuous countdown

Choose **Decrease**, set the starting **Value** near **Max Value**, and use a longer **Auto Update Interval** with a suitable **Auto Update Amount**. Another gameplay system must decide what happens at the minimum; the Attribute Manager only changes and reports the value.

### Item charge or durability

Put an **Attribute Manager** on the item when the value belongs to that item rather than the character. UCC item actions can reference values such as a usable action's use attribute or a shield's durability attribute. Ensure the action's attribute name matches the manager entry exactly.

## How attributes run

When an Attribute Manager initializes, it builds a name lookup and records each attribute's starting value. Assigning `Value` clamps it between **Min Value** and **Max Value**, sends `OnAttributeUpdateValue`, cancels the previous automatic-update schedule, and starts a new delay when the attribute is not already at its destination.

After the delay, **Increase** adds **Auto Update Amount** until **Max Value**, while **Decrease** subtracts it until **Min Value**. Each step sends another update event. Reaching the destination sends `OnAttributeReachedDestinationValue` on that Attribute instance. If **Update When Inactive** is disabled, the automatic update does not run while the owning GameObject is inactive.

Attribute names must remain unique. The manager builds its runtime lookup by name, and `GetAttribute` returns `null` when no exact match exists.

## Verify in Play Mode

1. Inspect the manager immediately after the scene starts. Every attribute should begin inside its configured range with the intended starting value.
2. Trigger the real action that spends or restores the value. Confirm it changes once by the expected amount and never passes its minimum or maximum.
3. For an auto-updating attribute, change the value and time the **Auto Update Start Delay**. Confirm each later step follows **Auto Update Interval** and reaches the correct bound.
4. Change the value again during the delay. Confirm the delay restarts rather than allowing an older scheduled update to run.
5. Start and stop any ability that uses **Attribute Modifier**. Confirm the ability cost, minimum-value stop, and return to the attribute's normal regeneration behavior.
6. If **Update When Inactive** matters, disable and re-enable the GameObject during the delay and during repeated updates. Confirm the result matches the chosen setting.
7. Verify every UI element and consuming component follows the correct attribute, especially when Health, Shield, and Stamina exist together.
8. Test any required reset path. Character Health resets its configured Health and Shield attributes on respawn; custom attributes need their own deliberate reset behavior.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| A component cannot find the attribute. | Its name may be blank, duplicated, misspelled, or use different capitalization. | Give every entry a unique name and copy that exact value into the consuming component. |
| The value immediately snaps to an unexpected number. | **Value** may be outside **Min Value** and **Max Value**, or a state may override the range. | Correct the default range, inspect active States, and retest from a fresh initialization. |
| Regeneration never starts. | **Auto Update Value Type** may be **None**, the value may already be at its destination, or the GameObject may be inactive without **Update When Inactive**. | Choose **Increase** or **Decrease**, move the value away from its destination, and select the inactive behavior deliberately. |
| Regeneration begins too soon after repeated damage or use. | **Auto Update Start Delay** may be too short, or an active State or Attribute Modifier may temporarily replace the update settings. | Inspect the active overrides, then increase the normal start delay and retest the complete transition. |
| A drain increases the value instead. | **Auto Update Amount** on the Attribute should be positive, or an Attribute Modifier may have the wrong sign. | Use a positive Attribute amount with **Decrease**, and a negative modifier **Amount** for a cost. |
| An ability starts without enough stamina or stops immediately. | Its **Attribute Modifier** may reference the wrong name, use an unsuitable amount, or begin at the minimum. | Select the correct attribute, verify the cost against the starting value, and retest the ability from full stamina. |
| Health changes but the shield does not absorb damage. | **Character Health > Shield Attribute** may be empty or may not match the Shield entry. | Assign the exact shield name and verify the shield starts above its minimum. |
| Custom attributes disappeared after a Character Manager update. | The **Health** option may have been disabled, which removes Character Attribute Manager with the managed health set. | Restore the managed components and attributes from version control or a backup, then keep **Health** enabled when using that set. |
| The UI does not update. | It may observe a different GameObject or attribute name, or it may not listen for `OnAttributeUpdateValue`. | Point the monitor at the manager's GameObject and exact name, then verify the update event is registered and unregistered correctly. |

## Related pages

- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) covers health, shield, damage, healing, death, and fall damage.
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) explains the Character Manager workflow that adds the managed health component set.
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) explains ability configuration and the Attribute Modifier shared by abilities.
- [Usable Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/) describes item and character use attributes.
- [Shield](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/shield/) uses an item Attribute Manager for durability.
- [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/) connects depleted health to character death and respawn.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains registering and unregistering UCC events.
- [Event Names](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/event-names/) lists the attribute update, destination, and modifier events.

## Developer reference

Retrieve an attribute by its exact name, guard against a missing entry, and change it through `Value` so clamping, events, and the automatic-update delay all run.

```csharp
using UnityEngine;
using Opsive.Shared.Events;
using Opsive.UltimateCharacterController.Traits;
using Attribute = Opsive.UltimateCharacterController.Traits.Attribute;

[RequireComponent(typeof(AttributeManager))]
public class StaminaConsumer : MonoBehaviour
{
    private AttributeManager m_AttributeManager;
    private Attribute m_Stamina;

    private void Awake()
    {
        m_AttributeManager = GetComponent<AttributeManager>();
        m_Stamina = m_AttributeManager.GetAttribute("Stamina");
        EventHandler.RegisterEvent<Attribute>(gameObject, "OnAttributeUpdateValue", OnAttributeUpdateValue);
    }

    public bool TrySpend(float amount)
    {
        if (m_Stamina == null || amount < 0 || !m_Stamina.IsValid(-amount)) {
            return false;
        }

        m_Stamina.Value -= amount;
        return true;
    }

    private void OnAttributeUpdateValue(Attribute attribute)
    {
        if (attribute == m_Stamina) {
            Debug.Log($"Stamina: {attribute.Value}");
        }
    }

    private void OnDestroy()
    {
        EventHandler.UnregisterEvent<Attribute>(gameObject, "OnAttributeUpdateValue", OnAttributeUpdateValue);
    }
}
```

The current Version 3 runtime surface includes:

- `AttributeManager.Attributes` to replace or inspect the managed array and `GetAttribute(string)` to retrieve an entry.
- `Attribute.Value`, `MinValue`, and `MaxValue`, with clamping performed through the `Value` setter.
- `ScheduleAutoUpdate(float)`, `CancelAutoUpdate()`, `IsAtDestinationValue()`, `IsValid(float)`, and `ResetValue()` for lifecycle control.
- `AttributeModifier.Initialize`, `IsValid`, and `EnableModifier` for one-time or repeated changes owned by abilities and other systems.
- `OnAttributeUpdateValue` on the manager's GameObject, `OnAttributeReachedDestinationValue` on the Attribute instance, and `OnAttributeModifierAutoUpdateEnabled` on the AttributeModifier instance.

---

<a id="page-ultimate-character-controller-attributes-health"></a>

# Health

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)

Health turns Attribute Manager values into damage, healing, shield, death, and respawn behavior. Use **Character Health** for a UCC character, or the generic **Health** component for a crate, target, or other GameObject.

## Choose the setup

| Goal | Components to use |
| --- | --- |
| A UCC character can take damage and respawn | **Character Attribute Manager**, **Character Health**, and **Character Respawner**. Character Manager adds this set when **Health** is enabled. |
| A character should also play a death ability | Add **Die** to **Ultimate Character Locomotion > Abilities** after creating the health set. Character Manager does not add Die with the **Health** option. |
| A character should ragdoll or revive | Add and configure the **Ragdoll** or **Revive** ability in addition to the health set. |
| An ordinary object can take damage | Add **Attribute Manager** and **Health** to the same GameObject. Add **Respawner** only when that object should return. |

Health requires an Attribute Manager on the same GameObject. Its **Health Attribute** and optional **Shield Attribute** select entries from that manager by name.

## Set up character health

1. Place the character in the scene and open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Assign **Character**, enable **Health**, and select **Build Character** or **Update Character**.
3. Select the character and confirm it now has **Character Attribute Manager**, **Character Health**, and **Character Respawner**.
4. In **Character Attribute Manager**, select the default `Health` entry and set its **Min Value**, **Max Value**, and starting **Value**. The default entry starts at `100` with a minimum of `0` and maximum of `100`.
5. In **Character Health**, select `Health` for **Health Attribute**.
6. Add and configure a `Shield` attribute only when damage should consume a separate shield first. Select it in **Shield Attribute**.
7. If the character needs a visible death animation, add [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/) to the ability list and verify its Animator transitions.
8. Configure **Character Respawner** for the intended return location and delay, then test the complete damage-to-respawn sequence in Play Mode.

For a non-character object, add **Attribute Manager** and **Health** manually, create the same named attributes, and choose them from the Health Inspector. The generic Health component supports damage, healing, hitboxes, death objects, audio, Unity events, and optional deactivation, but it does not add character fall damage.

## Configure health and shield

Damage is applied to Shield first and Health second. Death occurs when neither configured attribute remains above its **Min Value**.

Healing uses the opposite priority: `Heal` fills Health first, then puts any remaining amount into Shield. Use the Attribute Manager's automatic update when Shield should regenerate independently after a delay.

| Field | Version 3 default | Use it for |
| --- | --- | --- |
| **Invincible** | Disabled | Ignore normal damage while a state, cutscene, or gameplay rule protects the object. |
| **Time Invincible After Spawn** | `0` seconds | Ignore normal damage for this duration after `OnRespawn`. Before the first respawn, Version 3 compares the value with time since application start. |
| **Health Attribute** | `Health` | Select the primary Attribute Manager value. |
| **Shield Attribute** | **(None)** | Select an optional value that absorbs damage before Health. |

Keep normal Health automatic updating set to **None** unless the game deliberately regenerates it. For a regenerating Shield, choose **Increase** on the Shield attribute and configure its delay, interval, and amount. Every shield value change restarts that delay.

See [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/) for the complete automatic-update workflow.

## Configure hit locations

Use **Hitboxes** when specific colliders should change non-radius damage, such as reduced limb damage or increased head damage:

1. Expand **Hitboxes** in Health.
2. Add an entry and assign its **Collider**.
3. Set **Damage Multiplier** to `1` for unchanged damage, below `1` for reduced damage, or above `1` for increased damage.
4. Keep **Max Hitbox Collision Count** at its default `10` unless the fallback raycast can encounter more overlapping colliders.
5. Test each collider with the actual weapon or impact that supplies the hit collider and damage direction.

![Head collider configured as a Health hitbox with an increased damage multiplier](https://opsive.com/wp-content/uploads/2018/03/HeadshotCollider.png?v=7da73131b110)

Hitbox multipliers apply only to non-radius damage that includes a nonzero direction and a hit collider. Radius damage does not use the multiplier because one explosion can overlap multiple colliders.

## Configure feedback and death

Use the foldouts in the Health Inspector for focused feedback:

- **Audio > Take Damage**, **Heal**, and **Death** select the Audio Clip Sets played for those outcomes. Lethal damage plays Death audio instead of Take Damage audio.
- **UI > Damage Popup Manager ID** connects the Health component to a registered Damage Popup Monitor. Leave the default `-1` when no popup manager is used.
- **Events** exposes Unity events for damage, healing, and death. Use these for local Inspector wiring; use UCC events when several systems or code listeners need the notification.
- On Character Health, **Damaged Effect** and **Damaged Effect Index** select an existing character Effect to start after accepted damage.

Expand **Death** to configure the result:

| Field | Version 3 default | Behavior |
| --- | --- | --- |
| **Spawned Objects On Death** | Empty | Instantiates each prefab through the object pool at the object's position and rotation. |
| **Destroyed Objects On Death** | Empty | Returns pooled objects to their pool or destroys ordinary objects. |
| **Deactivate On Death** | Disabled | Deactivates the object after **Deactivate On Death Delay**. |
| **Deactivate On Death Delay** | `0` seconds | Delays deactivation when that option is enabled. Keep it shorter than the minimum respawn time. |
| **Death Layer** | None | Moves the object to a single layer while dead; Character Health also updates the locomotion collision layer. |

Health cancels Health and Shield regeneration on death. On `OnRespawn`, it restores those two attributes to their recorded starting values and restores the alive layer. Spawned or destroyed death objects are not automatically reversed; another system must restore any persistent scene state.

The Character Respawner added by Character Manager defaults to **Start Location**, a random delay between **Min Respawn Time** `2` and **Max Respawn Time** `3`, and scheduling on death. Follow [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) when the character should use a Spawn Point, stay dead, or be revived by another system.

## Configure fall damage

Character Health adds a **Fall Damage** foldout. The generic Health component does not receive character landing events.

| Field | Version 3 default | Behavior |
| --- | --- | --- |
| **Apply Fall Damage** | Disabled | Enables damage when the reported fall height reaches the minimum. |
| **Min Fall Damage Height** | `3` | Falls below this height do no damage. |
| **Min Fall Damage** | `1` | Damage at the minimum height. |
| **Max Fall Damage** | `50` | Damage just below **Death Height**. |
| **Death Height** | `20` | A fall at or above this height sends infinite damage through the normal damage path. |
| **Damage Curve** | Linear | Maps the normalized distance between minimum height and death height to the range between minimum and maximum damage. |

Test the curve with several known ledge heights. **Invincible** and **Time Invincible After Spawn** also guard fall damage because Character Health sends the calculated amount through the normal `Damage` method.

## How health runs

An accepted damage request follows this order:

1. Reject zero damage, an already-dead object, **Invincible**, or the active spawn grace period.
2. Apply a qualifying hitbox multiplier.
3. Subtract from Shield down to its minimum, then apply any remainder to Health down to its minimum.
4. Apply force through the character force interface or a non-kinematic Rigidbody.
5. Send damage events and update the optional damage popup.
6. If both configured attributes are at their minimum, run death behavior and send `OnDeath`; otherwise play Take Damage audio.

Death spawns and destroys configured objects, changes the death layer, plays Death audio, optionally schedules deactivation, cancels attribute regeneration, and notifies UCC systems. Ultimate Character Locomotion, Die, Ragdoll, inventory, camera, UI, and Respawner can respond to the same `OnDeath` event.

`Heal` clamps the applied amount to the available Health and Shield capacity and returns `false` when nothing changed. Healing attribute values after death does not run the respawn lifecycle by itself; use Respawner or a configured Revive workflow to restore the full character state.

## Verify in Play Mode

1. Confirm the Inspector shows the intended starting Health and Shield values after initialization.
2. Apply damage smaller than the current Shield. Shield should decrease, Health should remain unchanged, and shield regeneration should restart only after its delay.
3. Apply enough damage to exhaust Shield. Confirm only the remainder reduces Health.
4. Heal a partially damaged object. Health should fill before any remaining amount restores Shield.
5. Strike every configured hitbox with the real damage source. Confirm its multiplier changes non-radius damage and radius damage remains unmultiplied.
6. Toggle **Invincible**, then respawn and test during **Time Invincible After Spawn**. No damage, force, damage event, or popup should occur while the request is rejected.
7. Apply lethal damage. Confirm death audio, Unity/UCC events, layer changes, death objects, ability behavior, and deactivation occur once.
8. Let Respawner complete. Health and Shield should return to their starting values, the alive layer should be restored, and the character should move and receive damage again after the grace period.
9. For Character Health, test falls below the minimum, near the minimum, between the limits, and at **Death Height**.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Health shows an Attribute Manager warning or fails during initialization. | The same GameObject may not have **Attribute Manager** or **Character Attribute Manager**. | Add the correct manager before Health and create the referenced attributes. |
| Damage has no effect. | The object may already be considered dead, be **Invincible**, still be inside the spawn grace period, or receive zero damage. | Confirm at least one configured attribute is above its minimum, then disable immunity or wait for the grace period. |
| Damage skips Shield. | **Shield Attribute** may be **(None)**, miss the exact attribute, or already be at its minimum. | Select the Shield entry in Character Health and verify its starting value and range. |
| Healing restores Shield before Health. | Another system may be changing the attributes directly rather than calling `Health.Heal`. | Use `Heal` when the intended rule is Health first, then Shield. |
| A headshot multiplier does not apply. | The damage may be radius-based, omit its direction or hit collider, or reference a different collider. | Send non-radius damage with the actual collider and direction, then verify the **Hitboxes** entry. |
| The character reaches zero Health but never plays a death animation. | Character Manager adds the health component set, not the **Die** ability or its Animator transitions. | Add and configure [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/). |
| The object deactivates after it already respawned. | **Deactivate On Death Delay** may be longer than the Respawner's minimum delay. | Shorten the deactivation delay, lengthen the respawn delay, or disable death deactivation. |
| Shield or Health regenerates after death. | A separate system may be changing the attributes or scheduling its own updates. | Confirm Health owns the same attributes, remove the competing update, and verify death reaches `OnDeath`. |
| `Heal` raises the values but the dead character remains unusable. | Healing does not send `OnRespawn` or restore locomotion and ability state. | Use Character Respawner or the [Revive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/) workflow. |
| Fall damage never occurs. | The component may be generic Health, **Apply Fall Damage** may be disabled, or the landing height may be below the minimum. | Use Character Health, enable the option, and test from a measured height above the threshold. |
| Damage feedback appears twice. | The same response may be wired to both the Inspector Unity event and a UCC event listener. | Keep one owner for each audio, UI, or gameplay response. |

## Related pages

- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/) configures bounds, regeneration, names, and attribute events.
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) adds the character health component set through Character Manager.
- [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/), [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/), and [Revive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/) define visible character death and recovery behavior.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) configures timing and return location.
- [Damage Processor](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/) describes reusable damage-data processing.
- [Health Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/health-pickup/) restores health through a pickup.
- [Damage Visualization](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/damage-visualization/) reacts to health damage with character feedback.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains UCC event registration and cleanup.
- [Event Names](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/event-names/) lists the standard health, death, and respawn signatures.

## Developer reference

### Damage, heal, and death APIs

Use positive amounts and the simplest overload that preserves the information the gameplay needs. `Damage(float)` applies value damage without a direction, force, attacker, or hit collider; richer overloads and `Damage(DamageData)` support those details.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Traits;

public class HealthCommands : MonoBehaviour
{
    [SerializeField] private Health m_Health;

    public void ApplyDamage(float amount)
    {
        if (amount > 0) {
            m_Health.Damage(amount);
        }
    }

    public bool ApplyHealing(float amount)
    {
        return amount > 0 && m_Health.Heal(amount);
    }

    public void KillImmediately()
    {
        m_Health.ImmediateDeath();
    }
}
```

`ImmediateDeath` temporarily bypasses **Invincible** and sends enough damage through the normal damage path. In the current Version 3 implementation, **Time Invincible After Spawn** still rejects that request while its grace period is active.

Useful runtime properties include `HealthValue`, `ShieldValue`, combined `Value`, `HealthAttribute`, `ShieldAttribute`, `Invincible`, and the configured attribute-name, hitbox, death, audio, popup, and Unity-event properties. `IsAlive()` returns true while either configured Health or Shield is above its minimum.

### Health events

Register UCC events on the GameObject that owns Health, and unregister the same callback when the listener is destroyed:

```csharp
using UnityEngine;
using Opsive.Shared.Events;

public class HealthListener : MonoBehaviour
{
    private void Awake()
    {
        EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, Collider>(
            gameObject, "OnHealthDamage", OnDamage);
        EventHandler.RegisterEvent<float>(gameObject, "OnHealthHeal", OnHeal);
        EventHandler.RegisterEvent<Vector3, Vector3, GameObject>(gameObject, "OnDeath", OnDeath);
    }

    private void OnDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider)
    {
        Debug.Log($"Damage remaining after Shield: {amount}");
    }

    private void OnHeal(float amount)
    {
        Debug.Log($"Health and Shield restored: {amount}");
    }

    private void OnDeath(Vector3 position, Vector3 force, GameObject attacker)
    {
        Debug.Log($"Killed by: {attacker}");
    }

    private void OnDestroy()
    {
        EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, Collider>(
            gameObject, "OnHealthDamage", OnDamage);
        EventHandler.UnregisterEvent<float>(gameObject, "OnHealthHeal", OnHeal);
        EventHandler.UnregisterEvent<Vector3, Vector3, GameObject>(gameObject, "OnDeath", OnDeath);
    }
}
```

The current Version 3 event surface is:

- `OnHealthDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider)`. The float is the damage remaining after Shield absorption in the current processing order.
- `OnHealthDamageWithData(DamageData damageData)` for the structured damage context available during the callback. Scalar `Damage` overloads use pooled data, so listeners should not retain that instance after the callback.
- `OnHealthHeal(float amount)` with the amount actually applied, not the amount requested.
- `OnDeath(Vector3 position, Vector3 force, GameObject attacker)` after death processing runs.
- `OnRespawn()` from Respawner; Health uses it to reset Health, Shield, layer, and spawn-grace timing.

The **Events** foldout also exposes Unity callbacks for damage (`float`, position, force, attacker), healing (`float`), and death (position, force, attacker). The Unity damage callback does not include the hit collider or full `DamageData`.

---

<a id="page-ultimate-character-controller-inverse-kinematics"></a>

# Inverse Kinematics (IK)

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/)

Character IK adjusts a humanoid after its animation has evaluated so its feet can meet uneven ground, its upper body can follow the look direction, and its hands can remain aligned with equipped items. Use UCC's built-in **Character IK** for a Unity Humanoid rig; use animation or a separately supported IK integration for other rig types.

## Before you begin

- Import the character as **Humanoid** and confirm that Unity reports a valid Avatar with head, hips, hands, upper arms, feet, and lower-leg bones. UCC's built-in Character IK uses Unity's humanoid IK and does not solve a Generic rig.
- Start with a working **Animator**, **Animator Monitor**, **Ultimate Character Locomotion**, and camera or AI look source. Character IK remains disabled until an `ILookSource` attaches.
- Use an Animator Controller whose intended IK layers have **IK Pass** enabled. UCC's released Version 3 defaults expect **Base Layer Index** `0` and **Upper Body Layer Index** `4`.
- Decide which provider owns the animated model. Do not run **Character IK** and [Final IK Bridge](https://opsive.com/support/documentation/ultimate-character-controller/integrations/final-ik/) on the same model.

Separate first-person arms are normally Generic rigs. Character IK belongs on the humanoid character model, not on those arms; first-person arms and items use their authored animations and [first-person item springs](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/).

## Add Character IK

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the character. For a new model, enable **Animator**, set **Model Type** to **Humanoid**, and assign the intended Animator Controller.
3. Enable **Unity IK**. This option defaults to enabled for a valid Humanoid and is disabled for a Generic model.
4. Select **Build Character** for a new character or **Update Character** for an existing one.
5. Select the animated model GameObject that contains **Animator** and **Animator Monitor**. Confirm that **Character IK** was added there. A character with switchable models needs one compatible IK provider on every humanoid model that can become active.
6. On a custom Animator Controller, enable **IK Pass** on the layers that should solve the lower and upper body, then set **Base Layer Index** and **Upper Body Layer Index** to those layer indices.
7. Enter Play Mode once and confirm the component enables after the camera or AI look source attaches. Resolve bone, Avatar, layer, and look-source problems before tuning weights.

### Editor checkpoint

Before tuning the pose, confirm that **Character IK** is on the Animator model rather than only the locomotion root, the model is Humanoid, the required bones resolve, the layer indices match IK-enabled Animator layers, and exactly one `CharacterIKBase` provider is active on the model.

## Configure feet and hips

Character IK casts from each foot and optional toe toward the character's gravity direction. When the character is grounded and using vertical collision detection, it raises and rotates a foot that would pass below the detected surface and lowers the hips when the two feet need different heights.

![Atlas standing on individual stair steps with both feet planted at different heights by Character IK](https://opsive.com/wp-content/uploads/2018/03/IKStairs.png?v=55cf98c8b255)

Use these controls for the ground solve:

| Setting | Released Version 3 default | Choose it by result |
| --- | --- | --- |
| **Layer Mask** | All layers except common ignored, character, overlay, water, UI, and visual-effect layers | Include the real ground colliders. Exclude invisible navigation ramps or helper colliders when the feet should meet visible stair treads instead. |
| **Hips Position Adjustment Speed** | `4` | Increase it when the pelvis lags behind changing ground height; reduce it when the pelvis correction looks abrupt. |
| **Hips Position Offset** | `0` | Apply a small model-specific vertical correction after the automatic hips adjustment. |
| **Foot Offset Adjustment** | `0.005` | Increase it slightly when the sole intersects the surface; avoid using a large value to hide an incorrect Avatar or collider setup. |
| **Foot Weight Active Adjustment Speed** | `10` | Controls the blend into ground or explicit foot IK. A value of `0` disables the resulting foot weight in the released implementation. |
| **Foot Weight Inactive Adjustment Speed** | `2` | Controls the blend back to the animated pose when a foot no longer needs correction. |
| **Override Foot IK Weight** | `-1` | Keep `-1` for automatic grounded behavior, use `0` to turn foot weighting off, or use a positive weight for an intentional override. |

An invisible slope collider can support the character capsule while visible step colliders support the feet. Exclude the slope helper from **Layer Mask** so the IK rays reach the steps.

## Configure look direction

The attached camera or AI `ILookSource` supplies the normal look direction. **Look At Offset** moves the body-and-arm target relative to that direction without rotating the camera, while the body, head, eyes, and clamp weights decide how much of the pose follows it.

![Rear comparison of zero Look At Offset and a positive horizontal offset shifting Atlas's upper-body aim](https://opsive.com/wp-content/uploads/2018/03/IKLookAtOffset.png?v=e3948a8a760e)

![Three increasing body and head look-at weights bending Atlas progressively farther toward an upward target](https://opsive.com/wp-content/uploads/2018/03/IKLookAtWeight.png?v=bc78710d1a8e)

Start from the released defaults and tune one decision at a time:

- **Look At Body Weight** defaults to `0.025`; keep it low for subtle torso participation.
- **Look At Head Weight** defaults to `0.2`; increase it when the head should lead the look pose.
- **Look At Clamp Weight** defaults to `0.35`; higher values restrict how far Unity's look-at solve can turn.
- **Look At Adjustment Speed** defaults to `0.5`, and **Look At Weight Adjustment Speed** defaults to `0.2`; use them to avoid a snap when the target changes.
- **Active Look At State Name** defaults to `LookAt`. An explicit target supplied by the [Look At ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/look-at/) activates that State while the target is active.

The released Version 3 **Look At Eyes Weight** field is not applied correctly: both the immediate and blended eye weight use **Look At Head Weight** in the current source. Treat the eyes as following the head weight, or use a corrected/custom IK implementation when independent eye weighting is required.

Enable **Debug Draw Look Ray** to draw the current target direction in green in the Scene view while testing. It is an editor-only diagnostic.

![Atlas aiming upward with a green debug ray marking the Character IK look direction](https://opsive.com/wp-content/uploads/2018/03/IKDebugLine.png?v=887bf0622954)

## Configure arms, hands, and items

**Upper Arm Weight** controls how strongly the dominant upper arm follows vertical aim. **Left Hand Weight**, **Right Hand Weight**, **Left Elbow Weight**, and **Right Elbow Weight** control each humanoid goal independently; all default to `1`. The corresponding adjustment speeds blend between the animated and IK poses.

![Upward-aim comparison with upper-arm weight disabled and enabled, showing the dominant arm align to the rifle](https://opsive.com/wp-content/uploads/2018/03/IKUpperArmWeight.png?v=0b6fabdb785b)

![Rifle-pose comparison with hand IK weight disabled and enabled, showing both hands reposition toward the aim direction](https://opsive.com/wp-content/uploads/2018/03/IKHandIKWeight.png?v=b885c592c4f2)

For a two-handed item:

1. Open the item's [Third Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/) and expand **IK**.
2. Create a child Transform on the visible item at the non-dominant hand's intended grip.
3. Assign it to **Non Dominant Hand IK Target**.
4. Optionally create an elbow guide and assign **Non Dominant Hand IK Target Hint**.
5. Equip, aim, use, reload, and unequip the item. The active model's Character IK receives and clears these targets with the item.
6. If a reload animation must release the grip, use a [State preset](https://opsive.com/support/documentation/ultimate-character-controller/state-system/presets/) to reduce the relevant hand and elbow weights during that state, then restore them afterward.

Aim and Use also tell Character IK when the hands should rotate and position toward the look direction. An [Interact](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/) target can supply a temporary hand, elbow, foot, or knee goal through **Ability IK Target**; ability targets take priority over item targets while active.

## How it runs

After the Animator evaluates a layer with **IK Pass**, Unity calls `OnAnimatorIK`. Character IK uses the base-layer callback for foot placement, hips preparation, and body look-at, then uses the upper-body callback for hand rotation, upper-arm rotation, hand position, and elbow hints. If an item or ability requires a second pass, the hands are positioned again on another IK-enabled layer. The hips correction is finalized in Late Update.

The component listens for the attached look source, item equip and unequip, Aim and Use, secondary item forces, Animator snaps, death, and respawn. It disables itself on death and restores its previous enabled state on respawn. Explicit look targets activate **Active Look At State Name**, and State presets can override the component's public properties.

Character IK runs locally on each animated model. In a multiplayer build, remote models are treated as third person for the first-person-specific hand condition; the component does not itself transmit custom look positions or ability IK targets. Synchronize the gameplay target or action that produces the pose. Inspector settings persist with the scene or prefab, but a temporary runtime target or interpolation is not a save record; restore the owning ability, item, or interaction after loading when that pose must continue.

## Verify in Play Mode

1. Confirm **Character IK** enables after the player camera or AI look source attaches and the Console reports no Humanoid, head, hand, or foot errors.
2. Stand on flat ground, a slope, and stairs. Both soles should meet the visible surface without a sudden pelvis drop, leg stretch, or foot intersection.
3. Toggle **Debug Draw Look Ray**, move the look source above, below, and across the character, and confirm the green ray agrees with the intended target.
4. Compare **Look At Offset**, body weight, head weight, and clamp weight one at a time. The body should follow without changing the camera direction or twisting past the desired limit.
5. Equip a two-handed item. The non-dominant hand should settle on its target and the elbow should bend toward its hint without a visible pop.
6. Start and stop Aim and Use at several pitch angles. The upper arm and hands should blend toward the look direction, then return to the authored pose.
7. Reload and unequip. Any State-based hand release should activate for the intended interval, and the target must clear when the item is no longer active.
8. Trigger a Look At or Interact target. Confirm the explicit target activates, the correct limb reaches it over the configured duration, and the pose returns cleanly afterward.
9. Switch every supported perspective and character model, then test death and respawn. Each active humanoid model should have one working IK provider; separate first-person arms should remain animation-driven.
10. In multiplayer, compare the local, spectator, and remote view. Replicated gameplay intent should produce an equivalent third-person pose without attempting to network final bone transforms.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Character IK stays disabled. | The model may be Generic, missing required humanoid bones, or have no attached `ILookSource`. | Repair the Humanoid Avatar and bone mapping, then attach the player camera or an AI look source. Do not add built-in Character IK to Generic first-person arms. |
| No IK changes are visible. | The Animator layer may not have **IK Pass** enabled, or the layer indices may not match. | Enable IK Pass and set **Base Layer Index** and **Upper Body Layer Index** to the actual Animator layer indices. |
| Feet intersect or float above the ground. | Check grounded state, vertical collision detection, **Layer Mask**, **Foot Offset Adjustment**, and **Override Foot IK Weight**. | Restore automatic weight `-1`, include the visible ground, exclude helper colliders, and tune only a small foot offset. |
| Feet follow an invisible stair ramp. | The helper ramp is included in **Layer Mask**. | Move it to an excluded layer or remove that layer from the Character IK mask while retaining the visible step colliders. |
| The non-dominant hand misses the item. | The active Third Person Perspective Item may have no target, the target may not be a child of the visible item, or the active model may lack Character IK. | Assign **Non Dominant Hand IK Target** and its optional hint on the active item, then verify the active model's IK provider. |
| The hand remains locked during reload. | The item target is still active and the relevant hand weight remains `1`. | Use the Reload State to reduce the specific hand and elbow weights, then restore them after the animation. |
| First-person arms do not respond to Character IK. | Separate arms are normally Generic and are outside Unity humanoid IK. | Position them through their animation, First Person Perspective Item, and springs; keep Character IK on the humanoid full-body model. |
| The body or hands jitter or solve twice. | Character IK, Final IK Bridge, or another custom IK owner may be active together. | Keep one `CharacterIKBase` provider on each active model and remove the competing solver route. |
| **Look At Eyes Weight** has no independent effect. | Released Version 3 reads **Look At Head Weight** for the eye weight. | Tune the head value as the shared result or use a corrected/custom IK implementation. |
| A remote character looks or reaches toward the wrong target. | The explicit target or owning gameplay action may not be synchronized. | Replicate the target/action and let each client solve the pose locally; do not rely on Character IK to send it. |
| A loaded game loses a temporary reach or look pose. | Runtime IK targets and interpolation are not standalone save data. | Restore the item, ability, interaction, and target state after loading. |

## Built-in IK or Final IK

Use **Character IK** when the model is a valid Unity Humanoid and its feet, look direction, item grip, and ability targets fit the built-in workflow. It ships with UCC and is added by the Character Manager's **Unity IK** option.

Use the [Final IK integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/final-ik/) when a supported RootMotion solver must own the final pose. Replace Character IK with **Final IK Bridge** on the animated model and configure the required RootMotion components; the bridge does not automatically make every Generic rig compatible and should not run beside Character IK.

## Related tasks

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Generic Character](https://opsive.com/support/documentation/ultimate-character-controller/character/generic-character/)
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/)
- [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/)
- [Third Person Perspective Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/)
- [Aim](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/aim/)
- [Look At](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/look-at/)
- [Interact](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/)
- [Model Switch](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Final IK](https://opsive.com/support/documentation/ultimate-character-controller/integrations/final-ik/)

## Developer reference

`CharacterIK` derives from `CharacterIKBase`, reports `UseOnAnimatorIK` as `true`, and exposes `SetLookAtPosition`, `GetDefaultLookAtPosition`, `SetItemIKTargets`, `SetAbilityIKTarget`, and `UpdateSolvers`. `OnUpdateIKPosition` and `OnUpdateIKRotation` delegates can adjust a final limb result before it is sent to Unity's Animator IK API.

`CharacterIKBase.IKGoal` includes both hands, elbows, feet, and knees. Ability targets override item hand targets while their interpolation is active. The built-in Interact ability uses **Ability IK Target** values for the goal, delay, interpolation duration, and active duration; the component defaults are `0`, `0.2`, and `1` seconds respectively.

Two released Version 3 API limitations are important:

- **Look At Eyes Weight** is serialized and exposed, but `LookAtTarget` uses **Look At Head Weight** when setting the eye weight.
- The public `RightHandRotationSpring` getter and setter route to the right-hand position spring. The serialized **Right Hand Rotation Spring** Inspector field is correct; configure it in the Inspector and avoid that public property in released Version 3 code or State presets.

---

<a id="page-ultimate-character-controller-objects"></a>

# Objects

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/)

The object systems provide reusable prefabs and components for pickups, projectiles, explosions, magic effects, damage rules, and detected scene targets. Start here when gameplay needs an object outside the character, then follow the route for the behavior that object must perform.

## Choose the object behavior

| Goal | Start with | What it covers |
| --- | --- | --- |
| Build a supported gameplay prefab | [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/) | Creates a configured starting prefab for pickups, projectiles, shells, grenades, explosions, magic projectiles, particles, and several weapon effects. |
| Give the character health or inventory objects | [Object Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/) | Explains the shared pickup behavior and routes to Health Pickup and Item Pickup. |
| Launch, throw, bounce, or preview an object's path | [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) | Provides the shared trajectory simulation and routes to Projectile, Grenade, Magic Projectile, and Shell. |
| Apply area damage and force | [Explosions](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) | Configures a radius-based effect that can damage targets and push supported physics objects. |
| Turn particle collisions into magic impacts | [Magic Particle](https://opsive.com/support/documentation/ultimate-character-controller/objects/magic-particle/) | Connects Particle System collision messages to the Magic Action that cast the effect. |
| Let an ability recognize a particular scene target | [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) | Assigns a numeric ID that Detect Object Ability Base abilities can use as a filter. |
| Change how damage is calculated | [Damage Processor](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/) | Defines the rule between a damage source and target, including integration with an external stats or modifier system. |

These pages describe different responsibilities. For example, a grenade can use a Trajectory Object for flight, spawn an Explosion at the end, and let a Damage Processor modify the resulting damage.

## Build a supported prefab

Use the Object Manager when its **Object Type** list contains the result you need:

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. Enter a **Name** and choose an **Object Type**.
3. Assign a **GameObject** when the selected type requests one. Use the model or visual object that should become the prefab, not an already configured Character Item for an Item Pickup.
4. For **Magic Projectile** or **Particle**, enable **Magic Particle Collisions** only when particle collisions should perform Magic Action impacts.
5. Select **Build Object** and save the prefab under the project's `Assets` folder.
6. Open the new prefab and complete the feature-specific configuration using the route in the table above.
7. Assign the prefab to the item action, spawner, scene object, or other system that will create or enable it.

The Object Manager adds the common components, colliders, layers, and starting values for the selected type. It does not choose project-specific item definitions, effects, damage rules, layer masks, or references for you.

## Common scenarios

### A health or item pickup

Choose **Health Pickup** or **Item Pickup** in Object Manager, then follow [Object Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/). Decide whether pickup happens on trigger entry, what the character receives, whether the object respawns, and which message or audio confirms collection.

### A projectile or throwable object

Choose **Projectile**, **Grenade**, or **Shell**, then follow [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) and its concrete child page. Match the collider and impact layers to the physical object, and connect the resulting prefab to the appropriate item action. A visible trajectory preview is optional and uses the same motion settings as the launched object.

### A projectile that explodes

Treat flight and detonation as separate responsibilities. Configure the projectile or grenade through [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/), create the area effect through [Explosions](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/), and assign the Explosion prefab where the launched object handles destruction or impact.

### A magic particle that reacts on contact

Use [Magic Particle](https://opsive.com/support/documentation/ultimate-character-controller/objects/magic-particle/) when individual Particle System collisions should invoke the casting Magic Action's impact. The Particle System must have its Collision module and **Send Collision Messages** enabled, and the particle must be initialized by the Magic Action that spawned it.

### A target that only certain abilities detect

Add [Object Identifier](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/) to the scene target and give it an **ID**. Configure the Detect Object Ability Base ability with the same **Object ID** when it should ignore otherwise detectable objects with different IDs.

### Project-specific damage rules

Use [Damage Processor](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/) when the normal damage amount must pass through armor, attributes, difficulty, teams, or another modifier system. Keep movement, collision, and visual effects on their normal components; the processor owns only the damage calculation and delivery rule.

## Verify in Play Mode

1. Trigger the system that creates or enables the prefab rather than dragging an unconnected prefab into an unrelated scene test.
2. Confirm that the expected trigger or collision occurs on the intended layers.
3. Watch for one concrete result: the pickup changes the character, the trajectory follows its configured path, the explosion affects an in-range target, the magic particle performs its impact, or the ability accepts only the matching object ID.
4. Reuse or respawn the object when that is part of the scenario and confirm that it initializes correctly again.
5. Check the Console. Missing component references, invalid particle collision setup, or an unassigned feature prefab should be corrected before tuning values.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Build Object** is disabled. | **Name** is blank, or the selected type requires a **GameObject** that has not been assigned. For **Item Pickup**, the source object may already contain a Character Item. | Enter a name, assign the required visual GameObject, and use an item model rather than an already built Character Item. |
| The prefab was created but never appears in gameplay. | The Object Manager builds the asset but does not assign it to an item action, spawner, or scene reference. | Assign the generated prefab to the system that should create it, then test that complete workflow. |
| A collision produces no pickup, impact, or explosion. | The required trigger, Rigidbody, layer mask, or Particle System collision message is missing or excludes the target. | Follow the concrete feature page and verify its collider and layer requirements before changing effect values. |
| The object moves correctly but applies the wrong result. | Flight, impact, and damage are configured by separate systems. | Keep Trajectory Object responsible for motion, the impact or Explosion responsible for the hit effect, and Damage Processor responsible for modifying damage. |
| An ability detects the wrong scene object. | Its layer mask is broad and its **Object ID** remains `-1`, which disables ID filtering, or the value does not match the target's Object Identifier. | Set a deliberate Object Identifier **ID** and use the same **Object ID** on the detecting ability. |

## Related pages

- [Items & Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/)

## Developer orientation

The Object Manager is editor-only prefab scaffolding. Runtime behavior comes from the generated components and the system that initializes, spawns, or enables the prefab.

The main runtime types are divided by responsibility:

- `TrajectoryObject` implements `IForceObject`, `IDamageSource`, and `ISmoothedObject` for simulated flight, forces, impacts, and trajectory previews.
- `Explosion` implements `IDamageSource` and sends its configured impact data and actions to objects inside its radius.
- `ObjectPickup` is the abstract `IObjectPickup` base used by concrete health and item pickups.
- `MagicParticle` receives Particle System collision callbacks after a `MagicAction` initializes it.
- `ObjectIdentifier` exposes a `uint ID` for ability and object-reference matching.
- `DamageProcessor` is a ScriptableObject that processes `DamageData` for an `IDamageTarget`; `DamageProcessorModule` provides a character-level assignment point.

---

<a id="page-ultimate-character-controller-objects-explosions"></a>

# Explosions

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/)

Use the **Explosion** component to damage and push nearby objects from one point, such as when a grenade detonates or a destructible barrel reaches zero Health.

## Create an explosion prefab

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. Enter a **Name**, select **Explosion** for **Object Type**, and select **Build Object**. An Explosion does not require a source GameObject in the manager.
3. Save the generated prefab. The Object Manager adds **Particle System** and **Explosion** components.
4. Configure the Particle System's material, duration, and playback so the visual starts when the prefab is activated. The Explosion component does not control particles directly.
5. In **Explosion**, set **Radius** to the gameplay reach and configure **Impact Damage Data** for the targets, damage, and force.
6. Review **Impact Actions**. The generated component starts with **Simple Damage**, **Spawn Surface Effect**, and **Impact Event**.
7. Enable **Line Of Sight** when solid cover should protect targets, then make sure the cover layers are also included in **Impact Damage Data > Layer Mask**.
8. Add clips to **Explosion Audio Clip Set** when the detonation needs sound. UCC's shared audio system obtains the audio source at runtime.
9. Choose one owner for detonation: **Explode On Enable**, a grenade or projectile, a Health death object, or your own call to `Explode`. Do not enable two of these paths for the same spawn.

![Explosion component configured with radius, impact damage data, impact actions, line of sight, lifespan, collision capacity, and an audio clip set](https://opsive.com/wp-content/uploads/2026/08/ucc-explosion-inspector.webp?v=56f5cf6718a6)

Before testing, the saved prefab should contain one Explosion component, its visual effect, an intentional detonation path, and a **Lifespan** long enough for the particles and audio to finish.

## Choose how the explosion starts

### Grenade or projectile

Assign the explosion prefab to the grenade or projectile's **Spawned Objects On Destruction** list. Keep **Explode On Enable** disabled: the Version 3 projectile code spawns the prefab and then calls `Explode` with the projectile's impact data and damage-source ownership. Enabling the option would detonate the same spawned object twice.

Use this path when the collision, timer, or trajectory object should decide when and where the explosion occurs. Follow [Grenade](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/grenade/) for the trajectory setup.

### Destructible barrel

Add **Attribute Manager** and **Health** to the barrel, then place the explosion prefab in **Health > Death > Spawned Objects On Death**. Keep **Explode On Enable** disabled here as well. Health explicitly calls `Explode` after it spawns a death object.

This path attributes the explosion to the barrel GameObject. If a chain reaction or score system must retain the original attacker as an `IDamageSource`, invoke the owner/source overload from the system that owns that attribution.

### Direct or pooled effect

Enable **Explode On Enable** only when activating the explosion prefab is the complete trigger. Each enable performs the overlap query, runs the actions, plays audio, and schedules the object for pooled destruction after **Lifespan**. A script can instead leave the option disabled and call one of the public `Explode` overloads.

## Tune reach, damage, and force

The outer **Radius** controls target detection and distance strength. **Impact Damage Data > Impact Radius** is separate data passed to damage and force processing; it does not expand the detection sphere.

| Setting | Version 3 default | Use it for |
| --- | --- | --- |
| **Explode On Enable** | Disabled | Detonate whenever this pooled object becomes active. Leave it disabled for projectile and Health death-object workflows. |
| **Radius** | `5` | Detect colliders and calculate a strength from the explosion center to each collider's closest point. |
| **Impact Damage Data > Damage Amount** | `10` | Supply the base damage used by the default **Simple Damage** action. |
| **Impact Damage Data > Impact Force** | `2` | Supply the base force. Force is multiplied by distance strength. |
| **Impact Damage Data > Impact Force Frames** | `1` | Spread force handled by an `IForceObject`, such as a character, over this many frames. |
| **Impact Damage Data > Impact Radius** | `0` | Mark radius damage and select downstream radial-force behavior. This is not the Explosion detection radius. |
| **Impact Damage Data > Layer Mask** | All except Ignore Raycast, Water, SubCharacter, Overlay, and Visual Effect | Choose affected colliders and, when **Line Of Sight** is enabled, which colliders can block the test. Trigger colliders are always ignored. |
| **Impact Damage Data > Damage Processor** | None | Supply custom damage filtering or modification before a damage target receives it. |
| **Line Of Sight** | Disabled | Skip a target when an included-layer collider blocks the route from the explosion. |
| **Lifespan** | `3` seconds | Return or destroy the explosion object after detonation. |
| **Max Collision Count** | `100` | Size the non-allocating collider buffer created in `Awake`. Multiple colliders can fill this buffer even though duplicate objects are filtered later. |
| **Explosion Audio Clip Set** | Empty | Play one configured explosion clip once per detonation. |

Explosion always calculates a distance strength, which approaches one percent at the radius edge, and **Simple Damage** multiplies **Impact Force** by that strength before applying its direction. Damage does **not** fall off by default. To scale damage too, expand **Impact Actions > Simple Damage** and enable **Scale Damage By Impact Strength**.

Explosion Version 3.2.0 has no **Upward Modifier** field. The direction runs outward from the explosion center. Add a custom impact action or apply a separate force when an upward lift is part of the design.

The **Impact State Name**, **Impact State Disable Timer**, and **Surface Impact** values in Impact Damage Data are only consumed by actions that use them. The default group does not contain **State Impact**, so add that action if an explosion should activate a state. Configure and test **Spawn Surface Effect** when a per-target surface response is required; use the prefab's Particle System for the main blast visual.

## How it runs

When `Explode` runs, the component:

1. Searches **Radius** with a non-allocating overlap sphere using the Impact Damage Data layer mask and ignoring triggers.
2. Filters duplicate GameObjects and duplicate parent force objects so a multi-collider target is not processed repeatedly.
3. Applies the optional line-of-sight test.
4. Finds the collider's closest point and calculates outward direction and distance strength.
5. Runs every enabled **Impact Action** for that target. By default, **Simple Damage** damages an `IDamageTarget` or pushes an `IForceObject` or non-kinematic Rigidbody, **Spawn Surface Effect** requests a Surface System response, and **Impact Event** notifies the source and target.
6. Plays **Explosion Audio Clip Set** once, then returns or destroys the explosion object through the object pool after **Lifespan**.

For objects with [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/), damage consumes the configured Shield attribute before Health. That attribute shield is separate from an equipped item's **Shield Action**: **Absorb Explosions** is disabled by default on Shield Action, so enable it when that item should intercept explosion damage.

## Verify in Play Mode

1. Place one target close to the explosion, one near the radius edge, one outside it, and one behind included-layer cover.
2. Give damage targets Attribute Manager and Health, and give physics-only targets a non-kinematic Rigidbody.
3. Detonate once. Confirm the visual and audio play once and the explosion object leaves the scene after **Lifespan**.
4. Confirm the two in-range targets receive outward force and the outside target is unchanged.
5. With **Scale Damage By Impact Strength** disabled, confirm both damage targets receive the base damage. Enable it and confirm the edge target then receives less damage.
6. Enable **Line Of Sight** and confirm the covered target is protected. Check that both the target and cover layers are in **Layer Mask**.
7. Test a target with several colliders and a crowded scene. Each logical object should react once, and the Console should not report that **Max Collision Count** was reached.
8. Test the actual trigger path: grenade collision or timer, barrel death, direct activation, or script call. Confirm only one detonation occurs.
9. If the project uses multiplayer or saving, test through that integration's authority and restoration flow rather than assuming the Explosion component synchronizes itself.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Nothing is damaged or pushed. | The target may be outside **Radius**, excluded by **Layer Mask**, represented only by a trigger, blocked by **Line Of Sight**, or missing Health/Rigidbody/`IForceObject`. | Include a non-trigger collider on an affected layer and add the receiver required for damage or force. |
| Edge targets take the same damage as close targets. | **Simple Damage > Scale Damage By Impact Strength** is disabled by default. | Enable it when damage, rather than only force, should fall off with distance. |
| A barrel or grenade detonates twice. | **Explode On Enable** may be enabled while Health or ProjectileBase also calls `Explode`. | Disable **Explode On Enable** and let the owning gameplay system make the call. |
| Cover does not block the explosion. | **Line Of Sight** may be disabled, or the cover layer may be absent from the same Impact Damage Data layer mask used by the test. | Enable the option and include both blockers and targets in **Layer Mask**. |
| Only some crowded targets react. | The overlap query may have filled **Max Collision Count**; the value counts colliders before duplicate targets are removed. | Increase it on the prefab before runtime and test again. Changing it after `Awake` does not resize the current buffer. |
| A Rigidbody receives no useful force. | It may be kinematic, use an excluded layer, or have zero **Impact Force**. **Impact Radius** may also be confused with the outer Radius. | Use a non-kinematic Rigidbody or `IForceObject`, set Impact Force, and use the outer **Radius** for detection. |
| An equipped shield does not block the blast. | **Shield Action > Absorb Explosions** defaults to disabled. | Enable it and verify the shield collider is the collider found by the explosion. |
| Particles or audio are cut off. | **Lifespan** may be shorter than the configured effect. | Increase Lifespan or shorten the Particle System and Audio Clip Set playback. |
| A surface effect appears at the wrong place or cannot identify the surface. | Version 3.2.0 builds explosion targets from an overlap collider, not a full raycast hit. | Keep the main blast on the prefab and use a tested custom impact action when exact per-surface placement is required. |
| Multiplayer clients produce duplicate or different explosions. | Explosion has no built-in network spawn, authority, or replication logic. | Let the multiplayer integration's authority spawn and detonate the effect, then replicate the resulting gameplay state as required. |

## Related pages

- [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/) creates the starting explosion prefab.
- [Grenade](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/grenade/) configures a throwable object that spawns an explosion on destruction.
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) explains collision, timing, and spawned destruction objects shared by projectiles.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) configures damage, Shield attributes, death objects, and barrel-style destruction.
- [Damage Processor](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/) customizes how structured damage reaches a target.
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) maps impacts to effects.
- [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/) explains Audio Clip Sets and shared audio playback.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains how to register and unregister UCC event listeners.

## Developer reference

### Detonation API and ownership

`Explosion` implements `IDamageSource`. Use an owner when damage attribution matters, and forward an existing `IDamageSource` when the explosion belongs to another attack:

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Objects;
using Opsive.UltimateCharacterController.Traits.Damage;

public class ExplosionTrigger : MonoBehaviour
{
    [SerializeField] private Explosion m_Explosion;

    public void Detonate(GameObject owner, IDamageSource ownerSource)
    {
        m_Explosion.Explode(m_Explosion.ImpactDamageData, owner, ownerSource);
    }
}
```

The public overloads are `Explode()`, `Explode(GameObject owner)`, `Explode(float damageAmount, float impactForce, int impactForceFrames, GameObject owner, IDamageSource ownerSource = null)`, and the virtual `Explode(IImpactDamageData impactDamageData, GameObject owner, IDamageSource ownerSource = null)`. Useful public properties include `ExplodeOnEnable`, `Radius`, `ImpactDamageData`, `ImpactActionGroup`, `LineOfSight`, `Lifespan`, and `ExplosionAudioClipSet`. **Max Collision Count** is serialized but has no public property in the inspected Version 3.2.0 source.

The default **Impact Event** action sends `OnObjectImpact` with an `ImpactCallbackContext` to the explosion source and the impacted target. Damage applied through Health then produces the normal Health damage and death events.

### Version 3.2.0 source boundaries

The inspected Version 3.2.0 implementation uses the `LayerMask` from an `impactDamageData` argument for target detection, but assigns the component's serialized **Impact Damage Data** to the default action context. A projectile-supplied or temporary data object therefore does not necessarily replace the damage and force read by context-driven default actions. Keep the explosion prefab's data aligned with the caller and recheck this behavior after upgrading.

The default **Spawn Surface Effect** receives overlap-derived collision data without a populated `RaycastHit`. Surface selection and placement that require raycast details need a custom action or an explicitly tested fallback.

Explosion contains no save serialization or multiplayer replication. Its scheduled pooled destruction is local runtime state. Persist the source object's durable state, such as barrel Health, and let the chosen multiplayer integration own network spawning, authority, damage, and despawning.

---

<a id="page-ultimate-character-controller-objects-damage-processor"></a>

# Damage Processor

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/)

A Damage Processor changes or rejects damage between a source and an `IDamageTarget`. Use one when a firearm, melee weapon, projectile, or explosion must account for armor, resistance, difficulty, teams, or an external stat system before the target's Health applies the result.

The built-in `DamageProcessor.Default` does not change the data: it calls `target.Damage(damageData)`. Ultimate Character Controller Version 3 does not include separate armor, resistance, or team processor types. Those rules belong in a project-specific `DamageProcessor` subclass.

## Choose where the processor applies

| Scope | Configure | Best for |
| --- | --- | --- |
| Every compatible hit from one character | Add **Damage Processor Module** to the attacking character and assign **Default Damage Processor**. | One team, difficulty, or stat rule shared by that character's weapons and nested damage sources. |
| One Impact Action | Assign **Damage Processor** on **Simple Damage**. | A weapon or attack that needs a different rule from the character default. |
| Projectile or Explosion context | Assign **Damage Processor** in the source's **Impact Damage Data**, then enable **Use Context Data** on **Simple Damage**. | A processor that should travel with the damage amount and force supplied by the source. |
| Normal UCC damage | Leave every processor field empty. | The runtime-created default processor passes the data directly to the target. |

The module belongs on the source character, not on the object receiving damage.

![Damage Processor Module on an attacking character with Default Damage Processor assigned](https://opsive.com/wp-content/uploads/2021/10/Damage-Processor-Module.png?v=58bae200c9a8)

Assign an attack-specific asset directly on its **Simple Damage** Impact Action when that attack must override the character rule.

![Simple Damage Impact Action with a weapon-specific Damage Processor assigned](https://opsive.com/wp-content/uploads/2021/10/SimpleDamageProcessor.png?v=0b818e23b3e8)

There is no registration list or processor stack. Exactly one processor is selected for a **Simple Damage** invocation, in this order:

1. Start with the **Damage Processor** on **Simple Damage**.
2. If **Use Context Data** is enabled and `ImpactDamageData` exists, use its processor instead. A blank context value also replaces the local value, so selection continues to the fallbacks.
3. If the selected value is empty and the source character has **Damage Processor Module**, use **Default Damage Processor** from that component.
4. If it is still empty, use `DamageProcessor.Default`.

An explicitly selected processor still passes through `DamageProcessorModule.ProcessDamage`, but it is not replaced by the module default.

## Configure the damage source

After the project contains a custom processor class:

1. Create its ScriptableObject asset from the **Assets > Create** menu path declared by that class.
2. Decide whether the rule belongs to an attacking character, one **Simple Damage** action, or the source's **Impact Damage Data**.
3. Assign the asset in only the intended location. When using context data, verify **Use Context Data** on **Simple Damage**.
4. Confirm the target has **Health**, **Character Health**, or another component that implements `IDamageTarget`.
5. Test the same known damage amount with the processor assigned and unassigned before adding more rules.

These released-Version-3 defaults are useful when checking the Inspector:

| Location | Field | Default |
| --- | --- | --- |
| Damage Processor Module | **Default Damage Processor** | None |
| Simple Damage | **Use Context Data** | Off |
| Simple Damage | **Damage Processor** | None |
| Simple Damage | **Damage Amount** | `10` |
| Simple Damage | **Impact Force** | `2` |
| Simple Damage | **Impact Force Frames** | `15` |
| Simple Damage | **Impact Radius** | `0` |
| Simple Damage | **Scale Damage By Impact Strength** | Off |
| Impact Damage Data | **Damage Processor** | None |

## How damage runs

A standard weapon or object impact follows this path:

1. The source creates an `ImpactCallbackContext`. Its `ImpactCollisionData` identifies the hit, source, target, direction, strength, and colliders; optional `ImpactDamageData` carries configured damage, force, radius, and processor values.
2. The ordered Impact Action Group reaches **Simple Damage**. That action reads either its local values or the context values and optionally scales damage by **Impact Strength**.
3. A struck item shield can absorb damage through `ShieldCollider` before a processor runs.
4. **Simple Damage** resolves an `IDamageTarget`, builds a temporary `DamageData`, and selects one processor using the fallback order above.
5. The processor changes the request, rejects it, or calls `target.Damage(damageData)`. The default processor calls the target once without changing the data.
6. The built-in Health target rejects invalid requests, applies a qualifying hitbox multiplier, consumes its Shield attribute, consumes Health, applies force, sends damage events, and invokes death behavior when neither value remains above its minimum.

This order matters. A held shield acts before the processor; Health hitbox multipliers and the Health **Shield Attribute** act after it. A custom processor that returns without calling `target.Damage` suppresses Health changes, force, Health events, and death. A processor should normally call the target no more than once.

## Choose the rule by outcome

### Armor or resistance

Read the target's external armor or resistance value, modify `DamageData.Amount`, clamp the result to the range your game supports, then pass it to the target. Do not duplicate Health's hitbox or Shield Attribute logic unless the custom design deliberately replaces those systems.

For a firearm, compare one unarmored and one armored target with the same shot. For an Iron Sword, also strike every configured Health hitbox so the processor rule and hitbox multiplier can be verified separately.

### Teams and friendly fire

Use `DamageData.DamageSource` to identify the source and the processor's `target` argument to identify the receiver. `IDamageSource` can form an owner chain such as character -> item action -> projectile -> explosion; `DamageSourceUtility.GetRootOwner()` returns the outer owner for a normal, non-null chain.

Ask the project's team or faction system whether the root source owner may damage `target.Owner`. Return without calling the target when friendly fire is disabled. UCC's core Version 3 package does not provide a team database or a built-in team comparison.

### Projectiles and explosions

A projectile can carry its **Impact Damage Data** into the hit context. Keep **Use Context Data** enabled on the receiving **Simple Damage** action when its amount, force, radius, and processor should come from the projectile.

For an Explosion, assign the processor on the Explosion component's serialized **Impact Damage Data**. Enable **Scale Damage By Impact Strength** on **Simple Damage** when damage, rather than only force, should use the Explosion's distance-based impact strength.

In released Version 3, `Explosion.Explode(IImpactDamageData, ...)` uses the supplied data for its overlap layer mask but sends the component's serialized Impact Damage Data to the Impact Action callback. A processor or amount supplied only through that runtime argument therefore does not reach **Simple Damage**. Configure the component data, or use project code that constructs and invokes the intended impact context.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the custom ScriptableObject asset is assigned at the intended scope;
- **Use Context Data** agrees with the location that owns the processor and damage values;
- the attacking character, rather than the receiver, owns **Damage Processor Module** when a character-wide fallback is required;
- the receiver resolves to one `IDamageTarget` and has valid Health/Shield attributes when using Health;
- the processor is stateless or stores per-character state in another component or system, because one ScriptableObject asset can serve many attackers at once;
- a custom impact source component implements `IDamageSource` and supplies the intended owner chain; and
- an Explosion that needs a custom processor has it in the component's serialized **Impact Damage Data**.

## Verify in Play Mode

Use one target with known Health, one with a Shield attribute, one armored target, and two characters on the same team.

| Test | Expected result |
| --- | --- |
| Fire the weapon with no processor assigned | The default processor passes the configured amount to Health. |
| Assign a character-level multiplier processor | Compatible firearm and melee hits from that character use the changed amount. |
| Assign a different processor on one Simple Damage action | That action uses its explicit processor; the character default still applies to other unassigned actions. |
| Enable context data and assign a projectile processor | The projectile's context processor wins over the local Simple Damage field. |
| Hit an armored and unarmored target | Only the armored target applies the external resistance rule, followed by its normal Health hitbox and Shield processing. |
| Hit an ally with friendly fire disabled | Health, force, Health damage events, and death do not run for the rejected request. |
| Hit a target with a held shield and a Health Shield attribute | The held shield adjusts the amount before the processor; the Health Shield attribute consumes the processed remainder. |
| Detonate an Explosion at two distances | Force follows impact strength; damage follows it only when **Scale Damage By Impact Strength** is enabled. Both hits use the serialized Explosion processor. |
| Apply lethal processed damage | Health sends its damage events, then death behavior and `OnDeath` run once. |

Temporarily log the source root, target owner, incoming amount, outgoing amount, and chosen processor while validating an external stat or team integration. Remove per-hit logging after the rule is proven.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| A processor assigned on Simple Damage never runs | **Use Context Data** may be enabled while a context exists with a different or blank processor. | Assign the processor in **Impact Damage Data**, or disable context use so the local field is read. |
| The character default is ignored for one weapon | That Simple Damage action or its context may select an explicit processor. | Clear the explicit value when the character module should be the fallback. |
| The processor changes `Amount`, but Health does not change | The processor may not call the target, or Health may reject zero damage, invincibility, an already-dead target, or spawn grace. | Call `target.Damage(damageData)` exactly once for an accepted request and verify the Health state. |
| A custom team rule cannot find its target through `DamageData.DamageTarget` | Built-in `DamageData.SetDamage` overloads do not assign that property, and `DamageData.Copy` does not copy it. | Use the `IDamageTarget target` argument supplied to `DamageProcessor.Process`. Explicitly populate the property only in a fully owned custom pipeline. |
| `DamageData.UserData` contains an unexpected object | Built-in `SetDamage` overloads do not initialize or clear **User Data**, and standard Simple Damage uses pooled `DamageData`. | Set or clear `UserData` for every custom request that uses it. Never treat an unset pooled value as meaningful. |
| A custom impact has a null `DamageSource` | Simple Damage replaces the initially resolved source with `ImpactCollisionData.SourceComponent as IDamageSource`. | Make the custom source component implement `IDamageSource` and configure its owner/source chain. Standard Usable Action, Trajectory Object, Projectile, and Explosion sources already do this. |
| A runtime Explosion argument uses the wrong processor or amount | The released overload forwards serialized component data to the Impact Action callback. | Configure the Explosion component's **Impact Damage Data**, or invoke a project-owned context with the intended data. |
| The processor applies its rule twice | More than one target call or more than one Impact Action may own damage. | Keep one damage owner and call `target.Damage` once. A Damage Processor is not a processor chain. |
| Remote players calculate a different result | The custom rule may be running on more than one peer or depend on data not carried by the network health interface. | Run the result on the authoritative combat path and synchronize the resulting Health state through the installed multiplayer integration. |

Do not retain `DamageData`, `ImpactCallbackContext`, or their pooled nested data after the synchronous call. Copy only the primitive or project-owned values that must outlive the hit.

## Save and multiplayer boundaries

A Damage Processor asset is configuration, not saved combat state. Persist armor, resistance, faction membership, difficulty, and other mutable values through the system that owns them. Health and inventory save support is separate from the processor and must be configured in the chosen save integration.

The UCC core package defines `INetworkHealthMonitor`, but a networking integration supplies the transport. On a networked Health component, only the authority forwards the accepted request through that monitor. Its damage method carries amount, position, direction, force magnitude, frames, radius, `IDamageSource`, and hit collider; it does not carry `DamageData.UserData`, `DamageTarget`, or `ImpactContext`. Make the processor's authoritative result reproducible from synchronized data, or explicitly replicate any additional project-owned result.

## Related tasks

- [Configure Health, Shield, hitboxes, and death](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Configure ordered Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Configure a Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/)
- [Configure a Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/)
- [Configure a Throwable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/)
- [Configure Explosions](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/)
- [Use programming extension points](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/)
- [Listen for Health and death events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)

## Developer reference

### Create a custom processor

Derive a ScriptableObject from `DamageProcessor` and override `Process`. This example applies a nonnegative multiplier and then delegates to the target:

```csharp
using Opsive.UltimateCharacterController.Traits.Damage;
using UnityEngine;

[CreateAssetMenu(
    fileName = "MultiplierDamageProcessor",
    menuName = "Ultimate Character Controller/Damage Processors/Multiplier Damage Processor")]
public sealed class MultiplierDamageProcessor : DamageProcessor
{
    [SerializeField, Min(0)] private float m_Multiplier = 1;

    public override void Process(IDamageTarget target, DamageData damageData)
    {
        if (target == null || damageData == null) {
            return;
        }

        damageData.Amount = Mathf.Max(0, damageData.Amount * m_Multiplier);
        if (damageData.Amount > 0) {
            target.Damage(damageData);
        }
    }
}
```

Returning before the target call is the normal way to reject a hit. Calling the target with an amount of `0` does not preserve force or events because the built-in Health target rejects zero-damage requests.

### Runtime data contracts

`DamageData` contains:

- `DamageSource`, an `IDamageSource` with **Owner Damage Source**, **Source Owner**, **Source GameObject**, and **Source Component** semantics;
- `DamageTarget`, which custom callers may set but the standard built-in population path does not;
- `Amount`, `Position`, `Direction`, `ForceMagnitude`, `Frames`, and `Radius`;
- `HitCollider`;
- `ImpactContext`, which exposes the originating `ImpactCallbackContext`; and
- `UserData`, an untyped project extension slot.

The current `IDamageTarget` contract exposes `Owner`, `HitGameObject`, `Invincible`, `Damage`, `IsAlive`, and `Heal`. Use the `target` argument as the authoritative target for the current call.

An `ImpactCallbackContext` contains the owning `CharacterItemAction` when one exists, required `ImpactCollisionData`, and optional `IImpactDamageData`. Collision data includes source ID, detection layers, raycast hit, impact position/object/Rigidbody/collider/direction/strength, damage source and target, source component/GameObject/character/item action, hit count/colliders, and surface impact. Use that detail only when the processor is intentionally coupled to an item impact; ordinary `Health.Damage` calls may have no impact context.

There is no processor-specific event. The processor decides whether to enter the target pipeline; the built-in Health component then sends `OnHealthDamage`, `OnHealthDamageWithData`, and, for a lethal result, `OnDeath`. See [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) for the exact event timing and signatures.

---

<a id="page-ultimate-character-controller-objects-magic-particle"></a>

# Magic Particle

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/magic-particle/)

Use **Magic Particle** when particles emitted by a Magic Action should turn Unity Particle System collisions into UCC impacts, such as a Fire Wand spray that damages what its embers touch.

## Choose a particle or a projectile

Magic Particle reports collisions; it does not move, aim, home, deal damage, or end the visual by itself.

| Intended result | Recommended setup |
| --- | --- |
| Several emitted particles can each touch a target | **Particle System**, **Magic Particle**, and **Particle Pooler**, spawned by the Magic Action's Cast Effects **Spawn Particle** module. The Particle System owns movement and collision. |
| One fireball follows a physical trajectory and produces one precise impact | **Projectile** with its required trajectory setup, spawned by Cast Effects **Spawn Projectile**. Let Projectile own collision and leave **Magic Particle Collisions** disabled unless a second particle-driven impact is deliberate. |
| A burst, glow, beam, or trail is visual only | Cast Effects **Spawn Particle** without **Magic Particle**, and keep the Collision module or **Send Collision Messages** disabled. |

For targeting, select **Forward**, **Target**, or **Indicate** on the Magic Action's Caster. That controls the cast data and the spawned root's orientation while the Cast Effect is active; Magic Particle does not steer individual particles toward a target. Use [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/) or project-specific movement when the object itself needs trajectory or homing behavior.

## Create a collision particle prefab

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. Enter a **Name**, select **Particle** for **Object Type**, enable **Magic Particle Collisions**, and select **Build Object**. The released Version 3 manager does not list a separate **Magic Particle** object type.
3. Save the prefab, then confirm its root has **Particle System**, **Particle Pooler**, and **Magic Particle**. In the inspected Version 3.2.0 builder, the **Particle** path adds Particle Pooler and optional Magic Particle but does not add Particle System; add that required component manually when it is absent.
4. Configure the Particle System's Main, Emission, Shape, movement, Renderer, and lifetime for the intended Fire Wand effect.
5. Enable the Particle System **Collision** module. Choose the appropriate world collision mode and **Collides With** layers, then enable **Send Collision Messages**. Magic Particle cannot receive `OnParticleCollision` without both the module and that option.
6. Configure the particle collision response. For a one-hit ember, make the particle stop or lose its remaining lifetime on contact. For an area stream, decide intentionally how often a continuing particle may report a collision.
7. Leave **Can Collide With Originator** disabled for a normal weapon. Also exclude the character's layers in **Collides With** when self-collision must be impossible.
8. Keep **Particle Pooler** on the prefab. Use a non-looping Particle System or make sure the Magic Action stops a looping one so it can return to the object pool.

![Particle System Collision module configured to send collision messages for a Magic Particle](https://opsive.com/wp-content/uploads/2020/02/ParticleSystemCollisionMessages.webp?v=d1a7725ca625)

The [Unity Particle System Collision module](https://docs.unity3d.com/Manual/PartSysCollisionModule.html) determines which scene colliders produce these messages. Magic Particle adds UCC impact handling after Unity reports a collision.

## Connect a Fire Wand

1. Create or select the Character Item's **Magic Action**. Add an enabled Trigger, a **Simple Caster**, and valid first- and third-person **Cast Origin** transforms as described in [Magic](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/).
2. For a look-directed spray, set Simple Caster **Direction** to **Forward** and keep **Use Look Source** enabled.
3. In **Cast Effects Module Group**, add **Spawn Particle**. Assign the collision-particle prefab to **Particle Prefab**.
4. Tune **Position Offset** and **Rotation Offset** at the wand tip. Leave **Parent To Origin** disabled when emitted particles should remain in world space after the character moves. Choose Particle System **Simulation Space** to match that result.
5. Leave **Particle Layer** at its default Ignore Raycast unless the spawned visual itself must occupy another layer. This setting changes the spawned hierarchy's GameObject layer; the Particle System's **Collides With** mask still decides which targets particles can hit.
6. In **Impact Module Group**, add **Generic Magic Impact Module**. Configure its **Conditions** and successful **Impact Actions**. The default action group contains **Simple Damage**, **Spawn Surface Effect**, and **Impact Event**.
7. Set **Simple Damage > Damage Amount**, and select a **Surface Impact** on **Spawn Surface Effect** when the Surface System should create target-specific feedback. These values belong to the Magic Impact module, not Magic Particle. For a physics push, prefer Projectile or a custom Impact Action because the Magic Particle path leaves impact strength at zero in Version 3.2.0.
8. Save the Character Item and prefab, then verify that the Magic Action's **ID** matches the character's Use ability **Action ID**.

![Magic Action Spawn Particle cast effect with the collision-particle prefab assigned to Particle Prefab](https://opsive.com/wp-content/uploads/2020/03/SpawnParticleCastActionParticlePrefab.webp?v=59e1e6b0dca5)

## Editor checkpoint

Before entering Play Mode, confirm that:

- the prefab has Particle System, Particle Pooler, and Magic Particle on the same root;
- **Collision** and **Send Collision Messages** are enabled, with deliberate **Collides With** layers;
- the Particle System's speed, lifetime, simulation space, looping, and collision lifetime behavior match the spell;
- the Cast Effects **Spawn Particle** row references this prefab and the cast origin is the wand tip;
- one or more enabled Magic Impact modules contain the intended damage, force, surface, event, or custom actions;
- self-collision is excluded unless it is a tested feature; and
- either Magic Particle or Projectile owns a collision result, rather than both responding to the same visible fireball.

## Choose the important settings

Magic Particle has one serialized option:

| Setting | Version 3 default | Behavior |
| --- | --- | --- |
| **Can Collide With Originator** | Disabled | Ignore a collision when Unity reports the casting character's Ultimate Character Locomotion GameObject as the target. Layer filtering is the safer additional guard for child-collider character setups. |

The Cast Effects **Spawn Particle** module controls how the prefab enters the scene:

| Setting | Version 3 default | Choose it based on |
| --- | --- | --- |
| **Particle Prefab** | None | The pooled prefab containing the particle setup. |
| **Position Offset** / **Rotation Offset** | Zero | Alignment relative to the current perspective's cast origin. |
| **Parent To Origin** | Disabled | Whether the particle root follows the cast origin. Emitted particle behavior also depends on Simulation Space. |
| **Project Direction On Plane** | Disabled | Whether to remove the character-up component from the cast direction. |
| **Clear Parent On Stop** | Disabled | Whether a parented particle root becomes independent before the cast stops emitting. |
| **Set Renderer Length Scale** | Disabled | Stretch a compatible Particle System renderer to the cast target distance; useful for a beam, not a normal ember spray. |
| **Particle Layer** | Ignore Raycast | The layer applied recursively to the spawned hierarchy. |
| **Fade In Duration** / **Fade Out Duration** | `0` | Optional material-alpha transitions. The material color property defaults to `_TintColor`. |
| **Delay** / **Initial Delay** | `0` / `-1` | Cast Effect timing. `-1` makes the first cast use Delay. Repeats require a Caster that keeps updating the cast. |

Particle velocity, gravity, lifetime, size, simulation space, and collision response remain Particle System settings. Magic Particle has no movement speed, targeting, collision mask, damage, impact limit, or lifespan fields.

A newly added **Generic Magic Impact Module** starts with one target-condition check, an empty failure group, and this successful action group:

| Impact Action | Important Version 3 defaults | Magic Particle result |
| --- | --- | --- |
| **Simple Damage** | **Damage Amount** `10`, **Impact Force** `2`, **Impact Force Frames** `15`, **Impact Radius** `0`, **Scale Damage By Impact Strength** disabled | Applies the base damage to a damage target. Magic Particle leaves **Impact Strength** at `0`, so its standard force is zero; enabling damage scaling would also reduce damage to zero. |
| **Spawn Surface Effect** | **Use Context Data** enabled; local **Surface Impact** None | Assign the local Surface Impact because this collision path does not supply Impact Damage Data. Placement uses Magic Particle's reconstructed raycast. |
| **Impact Event** | Source and target callbacks enabled | Sends `OnObjectImpact` to the particle source and impacted target. |

Keep **Scale Damage By Impact Strength** disabled for this component unless an earlier custom action explicitly assigns a nonzero strength.

## How it runs

1. Cast Effects **Spawn Particle** obtains the prefab from `ObjectPoolBase`, positions and rotates it from the Caster data, applies **Particle Layer**, clears the Particle System, and initializes Magic Particle with the active Magic Action and cast ID.
2. Unity simulates the particles. The Particle System Collision module decides which collisions generate `OnParticleCollision` messages.
3. Magic Particle rejects the reported originator when **Can Collide With Originator** is disabled, finds a non-trigger Collider on the reported GameObject, and reconstructs a `RaycastHit` from the particle-system root toward that object.
4. `MagicAction.PerformImpact` records the particle root as the source GameObject, the casting character in the impact context's fallback owner data, and the cast ID as the impact source ID. Every enabled Magic Impact module receives the context.
5. Generic Magic Impact evaluates its conditions, then invokes the successful or failed Impact Action group. Simple Damage can affect Health, Spawn Surface Effect uses the reconstructed hit, and Impact Event can notify listeners. The Magic Particle path does not assign Impact Strength, so the default Simple Damage force is zero.
6. When the particle GameObject is disabled, Magic Particle resets each enabled Magic Impact module for that cast ID.
7. Particle Pooler waits for the Particle System to stop being alive, then returns the GameObject through the local or active network object pool. A looping system remains alive until another owner stops it.

Magic Particle does not stop a particle after collision and does not suppress repeated callbacks. A particle that continues colliding can perform the Magic Impact group again. Use the Particle System collision response, an Impact Condition, or a Projectile workflow to enforce the intended hit count.

## Verify in Play Mode

1. Equip the Fire Wand, expand the Magic Action's **Debug** view, and cast at a Health target on an included collision layer.
2. Confirm particles begin at the correct first-person or third-person wand tip, travel in the expected simulation space, and do not collide with the caster.
3. Confirm one particle collision enters the enabled Magic Impact modules and produces the configured damage, surface response, and impact event. If the design requires push force, verify the custom action or Projectile path that supplies it.
4. Cast at scenery without Health. Confirm the surface response occurs and no damage error is produced.
5. Cast several particles into one target. Confirm the observed number of impacts matches the spell design; change collision lifetime or conditions if a continuing particle applies damage repeatedly.
6. Test a miss. Non-looping particles should finish and the prefab should become inactive through Particle Pooler.
7. Stop or interrupt the cast and switch perspectives. Confirm no looping particle remains attached to the old origin and the next cast initializes cleanly.
8. If using a physical fireball instead, repeat with **Spawn Projectile** and verify that Projectile alone owns the collision and lifespan.
9. In multiplayer, repeat as owner, server, and remote observer. Confirm only the authoritative path applies gameplay impacts and every role cleans up the visual.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console says the Magic Projectile has no Particle System. | The Version 3.2.0 Object Manager **Particle** path may have created Particle Pooler without Particle System. | Add Particle System to the prefab root before Play Mode. |
| The Console says Collision or Send Collision Messages is disabled. | Particle System **Collision** and **Send Collision Messages** are required by Magic Particle. | Enable both and configure **Collides With**. |
| Particles are visible but impacts never run. | The prefab may be spawned as ordinary scenery, the Cast Effect may not have initialized Magic Particle, or no Magic Impact module is enabled. | Spawn it through Magic Cast Effects **Spawn Particle**, or call `Initialize` from custom code, then enable the intended Impact module. |
| Particles do not move or move with the wand unexpectedly. | Magic Particle has no movement. Check Particle System velocity, lifetime, **Simulation Space**, and **Parent To Origin**. | Configure motion in the Particle System or use a Projectile for trajectory-driven movement. |
| The spell hits its caster. | **Can Collide With Originator** only filters the GameObject Unity reports when it resolves directly to the caster's locomotion object. | Also exclude the character layers from Particle System **Collides With**, especially for child colliders. |
| One particle damages the same target repeatedly. | The particle remains alive and Unity continues sending collision messages; Magic Particle does not end it or deduplicate callbacks. Generic Magic Impact forces its Impact Actions, so **Allow Multi Hits** does not suppress these callbacks. | Stop or kill the particle on collision, add an Impact Condition/custom hit guard, or use one Projectile impact. |
| **Impact Force** is nonzero but the target is not pushed. | `MagicAction.PerformImpact` initializes this collision context with **Impact Strength** `0`, and Simple Damage multiplies force by that value. | Use Projectile or a custom Impact Action that assigns a deliberate strength before applying force. |
| Damage becomes zero after enabling strength scaling. | **Scale Damage By Impact Strength** also multiplies damage by the zero strength on this path. | Keep the option disabled or assign strength in project code before Simple Damage runs. |
| A physical fireball damages twice. | Both Projectile collision and Magic Particle collision may be reporting the same encounter. | Choose one collision owner. For a normal Spawn Projectile fireball, disable **Magic Particle Collisions**. |
| Surface feedback appears at an unexpected point. | Version 3.2.0 reconstructs a raycast from the Particle System root rather than reading the individual particle's collision event position. | Keep particles tightly aligned with the root or use Projectile/custom collision-event processing when exact hit position and normal matter. |
| The prefab never returns to the pool. | The Particle System may be looping or remain alive in a child. | Stop every looping system and allow all child particles to die; Particle Pooler waits while `IsAlive(true)` remains true. |
| A collision with a child or unusual collider does nothing. | Magic Particle searches the reported GameObject's Colliders and skips triggers before reconstructing a raycast on that GameObject's layer. | Put a non-trigger Collider on the reported target object or use Projectile/custom collision handling for complex hierarchies. |
| Remote players produce duplicate damage or stale particles. | Magic Particle itself does not decide authority. | Let the multiplayer integration own Magic Cast Effect and Impact replication, and do not independently execute gameplay impacts on observers. |
| Damage, scoring, or kill credit has no attacker. | In Version 3.2.0, Magic Particle is not an `IDamageSource`, and default **Simple Damage** replaces its prepared fallback source with `SourceComponent as IDamageSource`, which is null for this component. | Use Projectile for source-preserving impacts, add a project `IDamageSource` component to the particle root, or use a custom Impact Action that keeps the context's `DamageSource`. |
| A combined spell uses damage or surface data from a different effect. | The Magic Particle `PerformImpact` overload does not assign or clear the reused context's `ImpactDamageData`; a previous projectile-style effect can leave data there. | Use separate Magic Actions for unlike impact data or clear and populate the context in a custom collision path before running Impact modules. |

## Related pages

- [Magic](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/) configures the Caster, Cast Effects, Impact modules, timing, and networking flow.
- [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/) creates the starting particle or projectile prefab.
- [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/) is the better collision owner for a single moving fireball.
- [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) configure damage, force, surface effects, and callbacks.
- [Impact Action Conditions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-action-conditions/) filter which targets receive an impact.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) configures damage and Shield reception.
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) map an impact to surface-specific effects.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains UCC event registration and cleanup.

## Developer reference

`MagicParticle.Initialize(MagicAction magicAction, uint castID)` is the required runtime handoff. Cast Effects **Spawn Particle** and **Spawn Projectile** call it automatically when the spawned root contains Magic Particle. A custom spawner must call it before collision messages arrive. `OnParticleCollision(GameObject other)` is the Unity callback that reconstructs a hit and calls `MagicAction.PerformImpact`.

Magic Particle exposes no public property for **Can Collide With Originator** in the inspected Version 3.2.0 source. Subclass the component or configure the serialized field on the prefab rather than expecting a runtime property.

The source does not call `ParticleSystem.GetCollisionEvents`; it reconstructs one raycast using the Particle System root and the reported target. That is adequate for a simple, aligned effect but is not an exact per-particle collision position or normal. It also does not destroy the particle, impose a hit limit, or provide targeting.

`MagicAction.PerformImpact(uint, GameObject, GameObject, RaycastHit)` resets the reused `ImpactCollisionData` but does not assign `ImpactStrength`, leaving it at `0`. The standard Simple Damage action multiplies force by that value. It also multiplies damage by the same value when **Scale Damage By Impact Strength** is enabled. A project action must assign strength before those calculations when either scaled result is required.

That overload also neither assigns nor clears `MagicImpactCallbackContext.ImpactDamageData`. It is normally null for a particle-only spell, so Simple Damage and Spawn Surface Effect use their local values. If another Cast Effect previously supplied Impact Damage Data through the same Magic Action, the reused context can retain it; custom code should explicitly clear or replace that data.

Version 3.2.0 prepares fallback owner data for a Magic Particle impact, but the default **Simple Damage** action subsequently assigns `DamageData.DamageSource` from `ImpactCollisionData.SourceComponent`. Magic Particle does not implement `IDamageSource`, so that assignment is null unless another source component is supplied. Projects that require reliable attacker or kill attribution should use the Projectile path, add a source component, or customize damage processing.

Prefab and Magic Action settings serialize normally, but an active cast ID, initialized Magic Action reference, live particles, scheduled pool check, and Impact module runtime state are transient. Finish or cancel the spell around a save/load boundary rather than expecting an in-flight particle stream to resume.

With the multiplayer integration enabled, Magic Action exposes Cast Effect and Impact replication calls, and Particle Pooler uses `NetworkObjectPool.Destroy` while network pooling is active. Authority, spawning, impact replication, and object registration remain integration responsibilities; custom spawning is not synchronized automatically.

---

<a id="page-ultimate-character-controller-objects-object-identifier"></a>

# Object Identifier

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-identifier/)

Use **Object Identifier** to give a GameObject a stable numeric role when UCC must find it within a runtime hierarchy, or when a Detect Object ability should accept only a particular kind of target.

An Object Identifier is a passive marker. It does not register the GameObject globally, make an ID unique, or save and synchronize the object. A consumer such as an ID/Object field or Detect Object ability decides where and when to look for the marker.

## Choose when to use an identifier

| Goal | Recommended reference |
| --- | --- |
| A component always uses one object in the same scene or prefab | Assign the object reference directly when that field supports it. |
| A reusable item prefab must find a spawn point, holster, muzzle, or another role on the character's active model | Give the role an Object Identifier and select the same ID in the item's ID/Object field. |
| Several interchangeable character models expose the same role | Put the same semantic ID on the equivalent GameObject in each model. Keep only one match within each searched model hierarchy. |
| Interact, Look At, Pickup, Drive, Ride, or another Detect Object ability should accept a narrower set of targets | Put the identifier on the detected GameObject or one of its parents and set the ability's **Object ID** to match. |
| A system needs a scene-wide lookup, persistent save identity, or network identity | Use a project-level registry or persistence/network identifier. Object Identifier does not provide those behaviors. |

Some UCC fields intentionally force an ID search so they can follow the active model. For example, a Third Person Perspective Item resolves **Spawn Parent** and **Holster Target** by ID. Follow the owning feature's page instead of assuming that its adjacent object-reference field overrides the ID.

## Create a project ID

1. Create a project-owned map with **Assets > Create > Opsive > Ultimate Character Controller > Utility > NameIDMap**. Keep this asset in version control so every team member uses the same names and numbers.
2. Open **Tools > Opsive > Ultimate Character Controller > Utility > Object Identifiers**.
3. Assign the project asset to **Name Map**. The packaged map remains available for the demo, but project roles should live in the project's map.
4. Select the target GameObject and add the **Object Identifier** component.
5. Select the dropdown beside **ID**, enter a descriptive role such as `Rifle Spawn Parent`, and select **Add**. The editor assigns the next unused ID beginning at `10000`; values below `10000` are reserved for Opsive demo content.
   The first Add to a new NameIDMap asks where to save its editable CSV file. Save that CSV beside the map and version both files; the map reads its editable entries from the CSV.
6. Select the new name in the dropdown. The name is an editor aid; the component serializes and compares the numeric **ID** at runtime.
7. In the consuming ability or ID/Object field, select or enter the same ID. For an ID/Object lookup, clear an old direct object reference unless the owning feature explicitly documents that it uses both.
8. Save the scene or prefab. If this is a model-specific role, repeat the same name and ID on the equivalent GameObject in every model prefab.

An ID/Object field uses the same searchable popup. Select an existing entry, enter a valid name and choose **Add**, or choose **Open Editor** for the complete NameIDMap. In the utility window, **Order By** offers **ID Ascending**, **ID Descending**, **Name Ascending**, and **Name Descending**. Names and IDs must each be unique; sorting changes only their editor presentation.

![Object Identifier Inspector with ID 106 assigned to the selected GameObject](https://opsive.com/wp-content/uploads/2018/04/ObjectIdentifier.webp?v=fffd11d84400)

The registered legacy image uses ID `106`. For new project roles, use the project map's generated IDs rather than copying an ID from this image or the demo.

## Choose IDs and marker locations

### Use positive project IDs

The Object Identifier component starts at ID `0`. An `IDObject<T>` field, such as **Spawn Parent** or **Holster Target**, starts at `-1`, which means no ID lookup. Detect Object abilities also use `-1` to disable their ID filter.

For new shared roles, use the map-generated range from `10000` through `2147483647`. Object Identifier stores an unsigned value, but UCC's ID/Object fields and Detect Object abilities store signed integers, so larger values cannot be represented consistently by every consumer. Avoid negative manual entries: the Object Identifier Inspector converts its integer input to an unsigned value.

The NameIDMap editor rejects a duplicate name or ID when adding or editing a project entry, but the runtime component does not enforce uniqueness. If two markers with the same ID exist in one searched parent or child hierarchy, an `IDObject<T>` resolves the first one returned by Unity. Reusing one ID on equivalent, mutually exclusive model prefabs is intentional; duplicating it within one active model is ambiguous.

### Put the marker on the resolved component

An `IDObject<T>` finds a matching Object Identifier and then requests component `T` from that same GameObject. Put both components together. For example, a `Transform` target needs only the marker because every GameObject has a Transform; a custom component target needs that custom component beside the marker.

The search is limited to the parent or child hierarchy supplied by the consuming feature, including inactive GameObjects. It is not a scene-wide search. Place model-specific markers below the model or Item Slot that the field searches.

### Reuse a role across character models

A runtime Character Item prefab can use one **Spawn Parent** ID to find the corresponding attachment below each model's matching Item Slot. A Third Person Perspective Item can likewise use one **Holster Target** ID for an equivalent hip or back target on every model. When the active model changes, these item paths perform a fresh lookup in the new model.

Use the same positive role ID on each alternative model, but verify that each individual model contains exactly one matching marker. This lets the item prefab remain model-independent without storing a reference to one scene instance.

### Filter a detected target

On an ability derived from Detect Object Ability Base, leave **Object ID** at `-1` when the ID should not filter candidates. Set it to a project ID when the detected GameObject or one of its parents must contain a matching Object Identifier.

**Detect Layers** remains the first physics filter. A matching ID does not make a collider detectable when its layer, distance, trigger, angle, or ability-specific requirements reject it. See [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) for the complete detection workflow.

## How resolution runs

Object Identifier itself only exposes its numeric `ID`. For an ID/Object field, `IDObject<T>` performs the lookup:

1. Unless the caller forces a search, it first returns a previously assigned or cached object.
2. ID `-1` returns no object.
3. The caller chooses a parent or child search and provides the root GameObject.
4. UCC includes inactive GameObjects, compares marker IDs, and uses the first matching marker.
5. It reads component `T` from the marker's GameObject and caches the result. A failed search is cached too.

The cache avoids repeating hierarchy scans, but it also means a non-forced lookup does not notice a later-spawned marker, a changed ID, a replaced model, or a destroyed cached component. Built-in features that expect model changes can force a new search or call `ResetValue()`. Custom code must do the same when its hierarchy changes.

Detect Object abilities use a separate path: after physics finds a candidate, they check Object Identifier components on that GameObject and its parents. They do not use the generic `IDObject<T>` cache.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the project **Name Map** contains a descriptive, non-demo ID;
- the target has Object Identifier with the intended numeric **ID**;
- an ID/Object lookup has the required component on the same GameObject as the marker;
- the marker is inside the parent or child hierarchy searched by the owning feature;
- each active searched hierarchy has only one marker for that role;
- alternate models repeat the same semantic role and ID; and
- a Detect Object target also has a collider on a layer included by **Detect Layers**.

## Verify in Play Mode

1. Select the consuming component and enter Play Mode.
2. Trigger the workflow that uses the reference. For an item prefab, equip and unequip it and confirm that its visible object uses the intended spawn or holster Transform.
3. If the character supports model switching, change to every model and repeat the workflow. The item should resolve the equivalent target rather than remain on the previous model.
4. For a Detect Object ability, approach one target with the matching ID and one without it. Confirm that **Detected Object** selects only the valid target while all other detection requirements are met.
5. Disable or temporarily change the intended marker and repeat the test. The workflow should fail or use its documented fallback rather than silently resolve an unrelated duplicate.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The wrong object is resolved. | Search the relevant parent or child hierarchy for duplicate IDs. UCC uses the first matching marker returned by Unity. | Give each role one match per active hierarchy. Reuse the ID only on alternative model prefabs. |
| The marker is found but the result is null. | The requested component may not be on the same GameObject as Object Identifier. | Move the marker to the component's GameObject or add the required component there. |
| A runtime-spawned target is never found after an earlier miss. | `IDObject<T>` caches a failed lookup. | Call `ResetValue()` or force the next search after changing the hierarchy. |
| Changing the ID during Play Mode has no effect. | Changing `IDObject<T>.ID` does not clear its cached value. | Set the new ID, then call `ResetValue()` or perform a forced search. |
| An item remains attached to the previous model. | The next model may be missing the matching positive ID, or custom code may be reusing a cached result. | Add the equivalent marker to every model and reset or force the lookup on the model-change event. |
| A Detect Object ability rejects a correctly identified target. | Check **Detect Layers**, collider/trigger setup, distance, angle, and the concrete ability's required target component. | Correct the detection setup; Object ID is an additional filter, not a replacement for it. |
| The Inspector shows a large unexpected number. | A negative value may have been entered into the Object Identifier's integer control and converted to an unsigned ID. | Select a valid entry from the NameIDMap and use a positive value no larger than `2147483647`. |
| The ID dropdown is empty or shows the wrong project names. | The **Object Identifiers** window may still reference the packaged or a deleted **Name Map**. | Open the utility window and assign the project's NameIDMap. A deleted selection falls back to the packaged map. |

## Related tasks

- [Detect Object Ability Base](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/) configures layer, cast, trigger, angle, and Object ID filtering.
- [Third Person Perspective](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/third-person-perspective/) uses identified spawn and holster targets for runtime Character Item prefabs.
- [First Person Perspective](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/) explains first-person item objects and their model-specific references.
- [Model Switch](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/) prepares equivalent slots and attachment roles across interchangeable models.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) builds scene items and reusable Character Item prefabs.

## Developer reference

`ObjectIdentifier.ID` is a `uint` and defaults to `0`. `IDObjectBase.ID` is an `int` and defaults to `-1`. `IDObject<T>` exposes `Obj`, `BaseObject`, `GetObjectInChildren`, `TryGetObjectInChildren`, `GetObjectInParent`, `TryGetObjectInParent`, `GetObject`, `TryGetObject`, and `ResetValue`.

```csharp
using Opsive.UltimateCharacterController.Objects;
using UnityEngine;

public class ModelAttachmentResolver : MonoBehaviour
{
    [SerializeField] private IDObject<Transform> m_Attachment = new IDObject<Transform>();

    public Transform Resolve(GameObject modelRoot, bool hierarchyChanged)
    {
        return m_Attachment.GetObjectInChildren(modelRoot, hierarchyChanged);
    }

    public void Invalidate()
    {
        m_Attachment.ResetValue();
    }
}
```

With `forceSearch` set to `false`, an assigned object or any previous lookup result is returned from the cache. `ResetValue()` clears both the cached flag and cached object. Setting `BaseObject` during Play Mode changes the ID to `-1` and marks the direct reference as cached; setting `Obj` directly does not perform that reset.

In released Version 3.2.0, `TryGetObject` returns `true` as soon as an ID matches, even when component `T` is missing from that marker's GameObject and the output is null. Check both the Boolean result and the returned object, or use the `GetObject...` result and test it for null.

Object Identifier has no registration, lifecycle, event, save, or network code. Its serialized ID survives with its scene or prefab, and an ID/Object field can serialize an object assigned in Edit Mode. A reference found by a runtime hierarchy search and its cache are not persistent. Do not use the component as a persistent object key or assume that adding it synchronizes a spawned object.

---

<a id="page-ultimate-character-controller-objects-object-pickup"></a>

# Object Pickup

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/)

Object Pickup is the shared world-object lifecycle for collectable health and inventory items. Use an Object Manager prefab when a trigger should grant a result, show collection feedback, then deactivate, return to a pool, or respawn.

## Choose a pickup type

Released Ultimate Character Controller Version 3 includes two concrete Object Pickup types:

| Goal | Pickup type | Character requirement | Detailed page |
| --- | --- | --- | --- |
| Restore a living target | **Health Pickup** | A parent component that implements `IDamageTarget`; the built-in choice is Health or Character Health. | [Health Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/health-pickup/) |
| Add Item Definitions to Inventory | **Item Pickup** | An enabled Inventory and the character's main collision layer. | [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/item-pickup/) |

`ObjectPickup` and `ItemPickupBase` are abstract. Create a custom implementation only when the result is neither built-in healing nor inventory collection. A custom object used by the character's Pickup ability implements `IObjectPickup` and owns its `DoPickup` result.

## Build the starting prefab

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name**.
3. Set **Object Type** to **Health Pickup** or **Item Pickup**.
4. Assign the visible model to **GameObject**. For an Item Pickup, use the model rather than an already built Character Item.
5. Select **Build Object**, choose a location under the project's `Assets` folder, and open the generated prefab.
6. Confirm the root has the expected pickup component and a Collider with **Is Trigger** enabled. Size the trigger around the intended collection area.
7. Configure the result, feedback, and lifetime before placing the prefab in a scene.

The **Item Pickup** builder adds a solid Box Collider, a trigger Sphere Collider, Item Pickup, and Respawner, and puts the object on the Visual Effect layer. **Dropped Item** creates the same pickup and colliders with Trajectory Object instead of Respawner. Follow the full [Item Pickup workflow](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) when building scene loot or a Character Item's **Drop Prefab**.

In released Version 3, the **Health Pickup** builder adds a Sphere Collider but does not enable **Is Trigger**. Enable it manually on the generated prefab. Without a trigger on the same GameObject, Object Pickup logs an error and its initialization can fail.

## Configure the shared pickup behavior

Every concrete Object Pickup exposes these shared fields:

| Field | Version 3 default | Behavior |
| --- | --- | --- |
| **Trigger Enable Delay** | `4` seconds | Delays collection when a depleted pickup is reused. A Rigidbody pickup waits until its velocity settles, then starts this delay. |
| **Pickup On Trigger Enter** | Enabled | Selects immediate contact collection for Item Pickup. The built-in Health Pickup does not read this field. |
| **Rotation Speed** | `(0, 0, 0)` | Rotates the display by the configured Euler amount during each physics update. |
| **On Select** | No listeners | Invoked when a Detect Object ability selects the pickup. |
| **On Deselect** | No listeners | Invoked when that ability releases the pickup. |
| **Destroy Delay** | `0` seconds | Removes the depleted pickup immediately. A positive value delays removal; `-1` leaves it visible but depleted. |
| **Pickup Audio Clip Set** | Empty | Plays collection audio when UCC finds a camera associated with the collecting object. |
| **Pickup Message Text** | Empty | Supplies the Message Monitor's post-collection text and can populate a Pickup ability message placeholder. |
| **Pickup Message Icon** | None | Supplies the Message Monitor's post-collection icon. |

The first scene activation enables the trigger immediately even when **Trigger Enable Delay** is positive. The delay applies after the pickup has been depleted and initialized again. For a reused pickup without a Rigidbody, the countdown starts at initialization; with a Rigidbody, it starts after the body settles.

Keep the trigger on the same GameObject as the pickup component. Item Pickup also requires the entering collider to belong to the character's main layer according to Character Layer Manager, preventing item and ragdoll colliders from collecting it.

## Configure a Health Pickup

Use this for a health pack that is collected on contact:

1. Set **Health Amount**. The Version 3 default is `40`.
2. Leave **Always Pickup** disabled when a full target should leave the pack available.
3. Enable **Always Pickup** when a living target should consume the pack even if `Heal` applies no value.
4. Confirm the pickup's trigger can collide with the character's main colliders.
5. Confirm the character's Health component references valid Health and optional Shield attributes.

Health Pickup searches the entering object and its parents for `IDamageTarget`, requires that target to be alive, and calls `Heal(Health Amount)`. Built-in Health restores Health first, then puts any remaining amount into Shield. A dead target cannot consume the pickup even when **Always Pickup** is enabled.

The inherited **Pickup On Trigger Enter** field does not gate Health Pickup: its `TriggerEnter` always calls `DoPickup`. For an animation- or input-gated health object, use a custom externally controlled `IObjectPickup` rather than relying on that checkbox.

## Configure an Item Pickup

Use this for an Iron Sword, firearm, ammunition bundle, or another inventory result:

1. Add each Item Definition and quantity to **Item Definition Amounts**.
2. Leave **Always Pickup** disabled when a full Inventory should keep the world object available. Test the released-version capacity limitation below before relying on that behavior.
3. Leave **Equip** enabled when a valid collected Character Item should become active. Disable it for ammunition or inventory-only loot.
4. Leave **Item Set Group** at `-1` to search all groups, or enter the intended group index.
5. Leave **Item Set Name** empty to use a valid set containing the item, or enter the exact Item Set State name that should be selected.
6. Keep **Pickup On Trigger Enter** enabled for automatic contact collection.
7. Disable it only when the character's [Pickup ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/) should detect the object, wait for input or animation, and perform the transfer.

The character does not need the Pickup ability for automatic Item Pickup. The animated route needs an enabled Inventory, Item Set Manager for equipping, compatible Equip Unequip abilities, correct detection layers, and its pickup animation events or durations.

Use [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) for capacities, equipping, dropped-item population, and the complete animated workflow.

## How collection runs

When an eligible object enters the trigger:

1. Object Pickup rejects the request if it is already depleted.
2. Health Pickup tries to heal a living `IDamageTarget`; Item Pickup validates the enabled Inventory and main character layer.
3. The concrete pickup decides whether any value was accepted, unless **Always Pickup** forces depletion.
4. A completed pickup marks itself depleted and sends `OnObjectPickedUp` on the collecting object.
5. Collection audio plays when UCC finds the collector's camera. A Message Monitor can display the configured text and icon.
6. **Destroy Delay** removes the object immediately, schedules removal, or leaves it visible but depleted.
7. A pooled pickup returns through the Opsive object pool. A non-pooled pickup deactivates so Respawner can reactivate it when configured.

For Item Pickup with **Pickup On Trigger Enter** disabled, the Pickup ability reserves the object, coordinates Equip Unequip, and adds the definitions at its pickup event. The world object can become depleted before the delayed Inventory transfer, so test capacity-limited inventories explicitly.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the pickup component and one trigger Collider are on the same GameObject;
- the trigger's layer collides with the character and is included by Pickup's **Detect Layers** when using the ability;
- a Health Pickup generated by Object Manager has **Is Trigger** enabled manually;
- a Health Pickup target has a live `IDamageTarget` with valid attributes;
- an Item Pickup has non-null Item Definitions, positive useful amounts, and an enabled Inventory on the character;
- equippable loot has its Character Item, slots, Item Set rules, and Item Set Manager configured;
- **Pickup On Trigger Enter** matches the intended automatic or animated Item Pickup route;
- **Destroy Delay** and Respawner create one deliberate lifetime; and
- message, audio, and selection feedback have the UI, camera, or detection listener they require.

## Verify in Play Mode

1. Enter a Health Pickup trigger with partially depleted Health and Shield. Confirm Health fills first, then Shield receives any remainder, and the pickup depletes once.
2. Repeat at full values with **Always Pickup** off and on. The pickup should remain for the first test and be consumed for the second.
3. Enter an automatic Iron Sword or firearm pickup. Confirm the configured amount enters Inventory once and the intended Item Set equips when allowed.
4. Repeat with an ammunition pickup near capacity. Confirm the accepted amount and whether the world object remains match the project's capacity policy.
5. Disable **Pickup On Trigger Enter** on an Item Pickup. Confirm contact only selects it, then input and the configured animation event add the item.
6. Observe **On Select**, **On Deselect**, pickup audio, message text/icon, and `OnObjectPickedUp` in their intended order.
7. For a scene pickup with Respawner, wait through depletion and the respawn interval. Confirm it returns at the intended position and can be collected again.
8. For a pooled or dropped pickup, confirm **Trigger Enable Delay** prevents immediate recollection after reuse.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| Object Pickup logs that a trigger must exist, or initialization throws | The Health Pickup builder may have left its Sphere Collider non-trigger. | Enable **Is Trigger** on a Collider on the same GameObject as the pickup and size it appropriately. |
| **Trigger Enable Delay** does not delay a pickup placed in the scene | First initialization intentionally enables the trigger immediately. | Treat the field as a reuse delay; use a separate startup gate when the initial scene object must wait. |
| A Health Pickup is collected before an animation | Its implementation ignores **Pickup On Trigger Enter** and handles contact directly. | Use a custom externally controlled `IObjectPickup` for animation-gated health collection. |
| A full target consumes the Health Pickup | **Always Pickup** is enabled. | Disable it when `Heal` must change a value before depletion. |
| Item Pickup does nothing on contact | Check the trigger, collision matrix, enabled Inventory, Character Layer Manager, and **Pickup On Trigger Enter**. | Restore the main-character collider path, or finish the Pickup ability setup for an input-driven object. |
| The item disappears even though Inventory capacity accepted zero | Released Version 3 treats an Inventory return value of `0` as a successful Item Pickup because it checks for `>= 0`. | Precheck capacity or use a corrected custom Item Pickup when the world object must remain. **Always Pickup** does not fix this boundary. |
| The item enters Inventory but does not equip | Check **Equip**, Item Set Manager, group/name, Character Item, slots, and whether Use or Reload is active. | Complete the item-set setup and retry when the conflicting ability is inactive. |
| A dropped pickup can be collected while still moving | Object Manager's **Dropped Item** has Trajectory Object but no Rigidbody, so the delay starts at initialization rather than waiting for rigidbody velocity. | Increase **Trigger Enable Delay** to cover the flight or add a landing-aware project gate. |
| The model remains but cannot be collected again | **Destroy Delay** is `-1`, which leaves an already depleted object active. | Use a positive delay, Respawner, pooling, or explicitly call `Initialize` as part of a controlled reuse path. |
| Pickup sound does not play | UCC may not find a camera associated with the collecting object. | Assign the character to the active camera workflow or play project-owned feedback from `OnObjectPickedUp`. |
| **On Select** and **On Deselect** never run | Trigger contact alone does not send detection selection events. | Use a Detect Object ability that selects the pickup, or connect feedback to the collection event instead. |

## Persistence, pooling, and multiplayer

Object Pickup does not save depletion, a pending destroy delay, or a Respawner timer. A save integration must persist the authoritative Inventory or Health state and any world pickup state that should survive loading. Otherwise a loaded character can keep the collected value while the scene restores another copy of the pickup.

Pooled pickups use `ObjectPoolBase.Destroy` and initialize again when enabled. Non-pooled objects are deactivated; a Respawner with **Schedule Respawn On Disable** can restore them. The Object Manager adds Respawner to Item Pickup and Health Pickup, but not to Dropped Item.

Multiplayer hooks compile with a supported integration. A pickup created through the Opsive pool uses `NetworkObjectPool.Destroy` when a network pool is active, while Inventory and Respawner each have separate network bridges. Core Object Pickup does not decide combat authority or persist ownership. Let the server or owning peer accept collection once, then replicate the Inventory/Health change and world-object removal through the installed integration.

## Related tasks

- [Health Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/health-pickup/) covers the built-in healing result.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/item-pickup/) is the direct inventory-pickup reference.
- [Item Pickup workflow](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) covers creation, capacity, equipping, animation, and drops in depth.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) configures Health, Shield, healing order, and death state.
- [Pickup ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/) configures detection, input, and animation timing.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) owns Item Definition amounts and runtime Character Items.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) controls return time and position.
- [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/) creates the starting pickup prefabs.
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) controls a dropped pickup's motion.

## Developer reference

`IObjectPickup` defines `DoPickup(GameObject target)`. `ObjectPickup` implements that interface and requires derived classes to implement both `TriggerEnter(GameObject other)` and `DoPickup(GameObject target)`. Its public runtime surface includes the shared trigger, rotation, audio, message, selection-event properties, `IsDepleted`, `Initialize(bool forceInitialization)`, and `DestroyPickup()`.

The base sends `OnObjectPickedUp(ObjectPickup pickup)` on the collecting GameObject after marking the object depleted. It listens for `OnObjectDetected(GameObject interactor, bool selected)` on the pickup and maps that state to the **On Select** and **On Deselect** UnityEvents.

`ItemPickupBase` wraps an inventory transfer with `OnItemPickupStartPickup` and `OnItemPickupStopPickup`. `ItemPickup` exposes its definition amounts through `GetItemDefinitionAmounts()` and `SetItemDefinitionAmounts(...)`; Drop uses that surface to populate a dropped prefab at runtime.

Health Pickup resolves `IDamageTarget` and calls its `IsAlive()` and `Heal(float)` methods. A custom target owns its healing semantics; the built-in Health implementation fills Health before Shield.

---

<a id="page-ultimate-character-controller-objects-object-pickup-health-pickup"></a>

# Health Pickup

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/health-pickup/)

Health Pickup restores a living `IDamageTarget` when it enters the pickup's trigger. Use it for health packs that collect on contact, optionally disappear at full health, and can return through Respawner.

## Before you begin

- The receiving character or object needs **Health**, **Character Health**, or another component that implements `IDamageTarget`.
- Built-in Health needs an Attribute Manager on the same GameObject and a valid **Health Attribute**. Assign a **Shield Attribute** only when the target uses one.
- The pickup needs a Collider with **Is Trigger** enabled on the same GameObject as Health Pickup.
- The pickup layer and character collision layers must interact in Unity's Physics settings.
- Decide whether the object should be a one-time pickup, return through Respawner, or be spawned and returned through an object pool.

## Create the Health Pickup

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name**.
3. Set **Object Type** to **Health Pickup**.
4. Assign the visible health-pack model to **GameObject**.
5. Select **Build Object**, save the prefab under the project's `Assets` folder, and open the generated prefab.
6. On the root Sphere Collider, enable **Is Trigger**. Released Version 3 adds the Collider but does not enable this option for Health Pickup.
7. Size the trigger around the intended collection area and confirm it remains on the same GameObject as **Health Pickup**.
8. Configure **Health Amount**, **Always Pickup**, feedback, and lifetime.
9. Place the prefab in the scene and test it against the real character.

Object Manager also adds **Respawner**. Keep it when the scene health pack should return after collection, or remove/disable its respawn-on-disable behavior for a one-time object.

## Configure healing and collection

| Field | Version 3 default | Behavior |
| --- | --- | --- |
| **Health Amount** | `40` | Passed to the target's `Heal` method. Use a positive value. |
| **Always Pickup** | Disabled | When disabled, the pickup depletes only if `Heal` changes a value. When enabled, a living target consumes it even when nothing changes. |
| **Trigger Enable Delay** | `4` seconds | Delays collection after a depleted pickup is reused. The first scene activation enables the trigger immediately. |
| **Pickup On Trigger Enter** | Enabled | Displayed by the shared base Inspector, but ignored by the built-in Health Pickup implementation. |
| **Rotation Speed** | `(0, 0, 0)` | Applies the configured display rotation during each physics update. |
| **Destroy Delay** | `0` seconds | Removes or deactivates the depleted pickup immediately. A positive value delays removal; `-1` leaves it visible but depleted. |

The Inspector also exposes an empty **Pickup Audio Clip Set**, empty **Pickup Message Text**, no **Pickup Message Icon**, and **On Select**/**On Deselect** UnityEvents with no listeners by default.

**Health Amount** has no minimum clamp in released Version 3. Keep it positive. A negative value can reduce partially depleted built-in Health while still using the heal feedback and event path.

## Choose the healing result

### Restore Health, then Shield

The built-in Health implementation fills Health first and puts only the remaining amount into Shield. For example, a `40`-point pack used when Health is missing `25` and Shield is missing `30` restores `25` Health and `15` Shield.

This is the opposite of incoming damage, which consumes Shield before Health. Configure attribute regeneration separately on the Attribute Manager; Health Pickup performs one immediate `Heal` request.

### Leave a pack for a full target

Keep **Always Pickup** disabled when the pack should remain available until it changes Health or Shield. Enable it for an arcade-style pickup that should disappear whenever a living target touches it, even at full values.

`Always Pickup` does not let a dead target collect the object. Health Pickup checks `IsAlive()` before calling `Heal` or consuming the pack.

### Add feedback and respawn

- Set **Pickup Message Text** and **Pickup Message Icon** for a Message Monitor response after collection.
- Assign **Pickup Audio Clip Set** when a collection sound should play. The collector must be associated with a camera that UCC can find.
- Use **On Select** and **On Deselect** only when a Detect Object ability selects this pickup. Trigger contact by itself does not invoke those selection events.
- Configure Respawner's time and position mode when a non-pooled scene pickup should return after it deactivates.

## Pickup ability boundary

Health Pickup always calls `DoPickup` when its trigger receives a valid entry. Disabling the inherited **Pickup On Trigger Enter** checkbox does not stop this behavior.

The character's Pickup ability can classify Health objects, but the standard Health Pickup still handles contact immediately. When healing must wait for input or an animation event, use a custom externally controlled `IObjectPickup` that does not collect from `TriggerEnter`, then let the Pickup ability call its `DoPickup` method.

## How it runs

1. On enable, Object Pickup clears its depleted state and prepares the trigger. First activation is immediate; reuse honors **Trigger Enable Delay**.
2. When a Collider enters, Health Pickup searches that object and its parents for `IDamageTarget`.
3. It rejects a missing or dead target.
4. It calls `Heal(Health Amount)` on a living target.
5. If `Heal` returns `true`, or **Always Pickup** is enabled, the object marks itself depleted and sends `OnObjectPickedUp` on the target owner's GameObject.
6. The pickup optionally plays audio and supplies its message text/icon to Message Monitor.
7. **Destroy Delay** removes the pickup now, later, or not at all. Pooled objects return to the pool; ordinary objects deactivate so Respawner can restore them.

For built-in Health, `Heal` clamps the positive amount to available capacity, fills Health before Shield, sends `OnHealthHeal` with the amount actually applied, and returns `false` when neither attribute changes.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the generated Sphere Collider has **Is Trigger** enabled and sits on the Health Pickup GameObject;
- the pickup's layer collides with the character's main colliders;
- **Health Amount** is positive;
- the target's Health component resolves valid Health and optional Shield attributes;
- **Always Pickup** matches the intended full-health behavior;
- **Destroy Delay** and Respawner describe one deliberate lifetime; and
- audio, message, and selection feedback have the camera, Message Monitor, or Detect Object listener they require.

## Verify in Play Mode

1. Reduce Health by less than **Health Amount**, leave Shield full, and enter the trigger. Confirm Health increases by the available capacity and the pickup depletes once.
2. Reduce both Health and Shield. Confirm Health fills first and only the remainder restores Shield.
3. Start with both attributes full and **Always Pickup** disabled. Confirm the pickup remains available.
4. Repeat at full values with **Always Pickup** enabled. Confirm the living target consumes the pickup even though no value changes.
5. Test a dead target. Confirm it does not consume the pickup in either Always Pickup mode.
6. Confirm `OnHealthHeal` reports the amount actually restored and `OnObjectPickedUp` runs only after the object is consumed.
7. Verify audio and Message Monitor feedback, then wait for Respawner and confirm the trigger can collect again.
8. After reuse, confirm **Trigger Enable Delay** prevents immediate recollection. Do not expect that delay on the first scene activation.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console says a trigger must exist, or the pickup fails during initialization | Object Manager's Health Pickup Sphere Collider is not marked as a trigger. | Enable **Is Trigger** on a Collider on the same GameObject as Health Pickup. |
| Contact does not restore a value | Check the collision matrix, target hierarchy, `IDamageTarget`, alive state, Health/Shield attributes, and **Health Amount**. | Restore a valid trigger collision, select valid attributes, and use a positive amount. |
| Shield remains low while Health increases | Built-in `Health.Heal` deliberately fills Health first. | Increase **Health Amount** enough to leave a remainder for Shield, or implement a custom target when the game needs different healing priority. |
| The pack disappears at full values | **Always Pickup** is enabled. | Disable it when `Heal` must change a value before collection succeeds. |
| A dead target does not consume the pack with **Always Pickup** enabled | Health Pickup checks `IsAlive()` before the Always Pickup decision. | Revive or respawn the target first, or use a project-specific dead-target interaction. |
| Disabling **Pickup On Trigger Enter** has no effect | Health Pickup does not read the inherited field. | Use a custom externally controlled `IObjectPickup` for input- or animation-gated healing. |
| A placed pickup ignores **Trigger Enable Delay** | The first initialization enables its trigger immediately. | Use a separate startup gate when the initial scene object must wait; reserve this field for reuse. |
| The model stays visible but cannot heal again | **Destroy Delay** is `-1`, leaving an already depleted object active. | Use a positive delay, Respawner, pooling, or a controlled call to `Initialize`. |
| The pickup deactivates but never returns | Respawner may be absent, disabled, or have **Schedule Respawn On Disable** off. | Add/configure Respawner or spawn the pickup through the intended pool. |
| No collection sound or message appears | UCC may not find the collector's camera, or Message Monitor may not be assigned to the character. | Complete the character camera/UI setup or respond to `OnObjectPickedUp` with project-owned feedback. |

## Persistence and multiplayer

Health Pickup does not save its depleted state, destroy delay, or respawn timer. Persist the authoritative Health values and any world-pickup state that must survive loading; otherwise a restored scene can recreate a pack that the saved character already consumed.

In a supported multiplayer build, Health uses its network health monitor and pooled pickups can use the network object pool for removal. Core Health Pickup does not decide which peer owns the trigger result. Let the server or owning peer accept the heal once, then replicate both the Health change and world-object lifetime through the installed integration.

## Related tasks

- [Object Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/) explains shared trigger, feedback, pooling, and lifetime behavior.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) configures Health, Shield, healing order, events, death, and respawn behavior.
- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/) configures starting values, limits, and regeneration.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) controls when and where a scene pickup returns.
- [Pickup ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/) explains detection, input, and the custom `IObjectPickup` route.
- [Item Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/item-pickup/) covers inventory collection instead of healing.
- [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/) creates the starting prefab.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains UCC event registration and cleanup.

## Developer reference

`HealthPickup` derives from `ObjectPickup` and exposes `HealthAmount` and `AlwaysPickup`. `TriggerEnter(GameObject other)` directly calls `DoPickup(other)`; the inherited `PickupOnTriggerEnter` property is not consulted.

`DoPickup` resolves a parent `IDamageTarget`, checks `IsAlive()`, calls `Heal(float)`, and completes the pickup when healing succeeds or **Always Pickup** is enabled. The object then sends `OnObjectPickedUp(ObjectPickup pickup)` on `damageTarget.Owner`.

The built-in Health target sends `OnHealthHeal(float amount)` with the value actually applied. Object Pickup also listens for `OnObjectDetected(GameObject interactor, bool selected)` on its own GameObject and maps that event to the Inspector's **On Select** and **On Deselect** UnityEvents.

---

<a id="page-ultimate-character-controller-objects-object-pickup-item-pickup"></a>

# Item Pickup

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/item-pickup/)

Item Pickup transfers one or more Item Definitions from a world object into a character's Inventory and can optionally equip a matching Item Set. Use it for placed loot, ammunition bundles, and Character Items that can be dropped and collected again.

## Before you begin

- Create every Item Definition that the pickup will grant. An equippable definition also needs a Character Item prefab, a compatible slot, and a valid Item Set Rule.
- Confirm the character has an enabled [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/). Equipping also requires an Item Set Manager.
- Prepare a visible world model. In Object Manager, assign the model rather than an already built Character Item.
- Confirm the pickup layer can collide with the character's main collision layer. Item and ragdoll colliders do not collect an Item Pickup.

## Create the pickup object

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name**.
3. Set **Object Type** to **Item Pickup** for loot placed in a scene, or **Dropped Item** for a prefab that will be assigned to a Character Item's **Drop Prefab**.
4. Assign the visible model to **GameObject**.
5. Select **Build Object**, choose a path under the project's `Assets` folder, and open the generated prefab.
6. Confirm the root has Item Pickup, a solid Box Collider, and a Sphere Collider with **Is Trigger** enabled. Object Manager also adds Respawner to **Item Pickup**, or Trajectory Object to **Dropped Item**.
7. Size the trigger around the collection area. Keep it on the same GameObject as Item Pickup.
8. For a scene pickup, add each definition and quantity under **Item Definition Amounts**. A Character Item drop replaces this list with the removed item and any additional definitions at runtime.

### Editor checkpoint

A scene pickup should have Item Pickup, a trigger collider, a solid collider, and Respawner. A dropped-item prefab should have Item Pickup, both colliders, and Trajectory Object. Its Character Item should reference that prefab in **Drop Prefab**.

## Configure what the pickup grants

Each **Item Definition Amounts** row has an **Item Definition** and an integer **Amount**. The Inventory accepts up to that Item Type's configured capacity.

### Iron Sword pickup

1. Add the Iron Sword Item Definition with an amount of `1`.
2. Leave **Equip** enabled when the sword should become active after collection.
3. Leave **Item Set Group** at `-1` to search all groups, or enter the group that owns the sword.
4. Leave **Item Set Name** empty to select the first valid set containing the sword. Enter a name only when a specific Item Set State should be selected; the text must match its State name exactly.

Disable **Equip** when the sword should enter the Inventory without changing the active loadout.

### Firearm and ammunition pickup

Add the firearm Item Definition with an amount of `1`, then add its ammunition Item Definition with the desired quantity. The firearm needs a Character Item prefab in a valid slot; count-only ammunition does not need a visible Character Item.

Enable **Equip** when a valid firearm Item Set should become active after both definitions are added. Use separate ammunition-only pickups when collecting ammunition should not change equipment.

## Choose how collection starts

### Collect on contact

Keep **Pickup On Trigger Enter** enabled for automatic collection. When an eligible main character collider enters the trigger, Item Pickup finds the enabled Inventory, adds the configured amounts, optionally requests an Item Set, and depletes the world object.

This route does not require the Pickup ability. Use it for ammunition and other loot where walking through the trigger is the complete interaction.

### Use input and an animation

Disable **Pickup On Trigger Enter** when the character should select the object, press an input, and play a pickup animation.

1. Add the [Pickup ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/) to the character.
2. Keep **Allowed Pickups** set to **Item**, and include the pickup layer in **Detect Layers**.
3. Leave **Pickup Item Definitions** empty to animate every Item Definition, or add the definition that should use this animation.
4. Configure **Pickup Event** to use `OnAnimatorPickup`, or use its duration mode when the animation has no matching event.
5. Configure **Pickup Complete Event** to use `OnAnimatorPickupComplete`, or use its duration mode.

When an Item Definition matches the animated route, the ability reserves and depletes the world object as it prepares the pickup. The Inventory transfer waits for **Pickup Event**. This prevents a second character from collecting the same object during the animation, but it also means a zero-delay object can disappear before the hand reaches it. Use a positive **Destroy Delay** when the model should remain visible through the reach.

### Reuse an item as a world drop

1. Build the prefab with **Object Type** set to **Dropped Item**.
2. Assign it to the Character Item's **Drop Prefab** field.
3. Add and configure the [Drop ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/).

When the Character Item is dropped, Inventory spawns the prefab, replaces **Item Definition Amounts** with the removed unit and any additional definitions supplied by the item, initializes the pickup, and starts Trajectory Object. Do not hard-code the carried item amount on a reusable dropped-item prefab.

## Key settings

| Field | Version 3 default | Use it when |
| --- | --- | --- |
| **Always Pickup** | Disabled | The object should be consumed even when no amount can be added. See the capacity limitation below before relying on the disabled state to preserve a full pickup. |
| **Equip** | Enabled | A valid collected Character Item should become active. Use and Reload can prevent the equipment change while either ability is active. |
| **Item Set Group** | `-1` | All Item Set groups should be searched. Enter a group index to constrain the request. |
| **Item Set Name** | Empty | The first valid set containing the item is acceptable. Enter an exact Item Set State name to request a specific set. |
| **Item Definition Amounts** | Empty | A scene object should grant fixed definitions and quantities. A dropped-item workflow supplies them at runtime. |
| **Trigger Enable Delay** | `4` seconds | A reused or dropped pickup should wait before becoming collectible again. The first scene activation is immediate. |
| **Pickup On Trigger Enter** | Enabled | Contact should collect the object. Disable it for the input-and-animation route. |
| **Destroy Delay** | `0` seconds | The depleted object should be removed immediately. A positive value delays removal; `-1` leaves it visible but already depleted. |

**Rotation Speed** starts at `(0, 0, 0)`. **Pickup Audio Clip Set**, **Pickup Message Text**, and **Pickup Message Icon** start empty, while **On Select** and **On Deselect** have no listeners.

For a reused pickup with a Rigidbody, **Trigger Enable Delay** begins after the body settles. Object Manager's **Dropped Item** adds Trajectory Object without adding a Rigidbody, so its delay begins when the pickup is initialized rather than when the visible flight ends. Use a delay that covers the flight when immediate recollection would be a problem.

## How it runs

1. Item Pickup ignores colliders that do not resolve to an enabled Inventory on the character's main layer.
2. With **Pickup On Trigger Enter** enabled, it requests each configured amount immediately. With the animated route, the Pickup ability first reserves the object and later performs the transfer at **Pickup Event**.
3. Inventory limits the accepted amount according to the Item Type and raises its pickup events for amounts that were added.
4. If **Equip** is enabled, Item Pickup updates Item Sets and tries the exact **Item Set Name** first. Otherwise it searches for a valid set containing a collected Character Item. It skips this equipment request while Use or Reload is active.
5. A successful result marks the object depleted and sends `OnObjectPickedUp` on the collecting character.
6. **Destroy Delay** removes the object immediately, schedules removal, or leaves the depleted model present. A pooled object returns to its pool; an ordinary object deactivates so Respawner can restore it.

## Verify in Play Mode

1. Keep the character's Inventory and the pickup's Item Pickup component visible.
2. Enter an automatic Iron Sword pickup. Confirm the amount increases once, the object depletes, and **Equip** selects the intended Item Set when enabled.
3. Test a firearm-and-ammunition pickup. Confirm both amounts change and the ammunition entry does not create an unwanted held object.
4. Fill an Item Type close to capacity, collect a larger amount, and confirm the Inventory accepts only the remaining space. Test the full-capacity case described below.
5. For an animated pickup, confirm the object is reserved when the ability starts, the Inventory changes at `OnAnimatorPickup`, and the ability ends at `OnAnimatorPickupComplete` or its configured duration.
6. Drop an equipped item. Confirm the spawned prefab receives the removed definition and amount, follows its trajectory, cannot be recollected before **Trigger Enable Delay**, and returns the item when collected.
7. For a scene pickup, wait for Respawner and confirm the object returns and can be collected exactly once again.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| Contact does not collect the object | Check for a trigger collider on the Item Pickup GameObject, an enabled Inventory, the collision matrix, the character's main layer, and **Pickup On Trigger Enter**. | Restore the trigger and layer interaction. Enable contact collection, or finish the Pickup ability setup for an input-driven object. |
| The item is collected without the intended animation | Check **Pickup On Trigger Enter**, the Pickup ability's **Start Type**, **Enabled** state, **Allowed Pickups**, and **Pickup Item Definitions**. | Disable contact collection and use an enabled, input-driven Pickup ability whose filter contains the definition. |
| The animation starts but Inventory does not change | **Pickup Event** may be waiting for a missing `OnAnimatorPickup`. | Add the event to the active clip or switch the trigger to duration mode. |
| Inventory changes but Pickup remains active | **Pickup Complete Event** may be waiting for a missing `OnAnimatorPickupComplete`. | Add the completion event or use duration mode. |
| Inventory changes but no held item appears | Check the Character Item prefab, slot, Item Set Rule, **Equip**, group/name, and whether Use or Reload is active. | Complete the Character Item and Item Set setup, correct the exact State name, and retry without the conflicting ability. |
| A full Inventory consumes the world object | Released Version 3.2.0 treats Inventory's `0` return as a successful Item Pickup result, even with **Always Pickup** disabled. | Precheck capacity or use a corrected custom Item Pickup when a full Inventory must leave the object available. |
| One of several Pickup ability filter entries does not animate | In released Version 3.2.0, a nonmatching first **Pickup Item Definitions** entry can stop the later entries from being considered. | Prefer one definition per Pickup ability, or put the matching definition first and verify every pickup. |
| A dropped item can be collected while it is still moving | The generated Dropped Item has Trajectory Object but no Rigidbody, so the reuse delay does not wait for Rigidbody settling. | Increase **Trigger Enable Delay** to cover the flight or add a project-owned landing gate. |
| The model remains but cannot be collected again | **Destroy Delay** is `-1`, so the object is visible but depleted. | Use Respawner, pooling, a positive delay, or an explicit controlled reinitialization. |

## Persistence, pooling, and multiplayer

Item Pickup does not save its depleted state, pending destroy delay, or Respawner timer. Persist the authoritative Inventory and any world-pickup state that must survive loading; otherwise a loaded Inventory can coexist with a restored copy of the collected object.

Pooled pickups return through the Opsive object pool and initialize when reused. Non-pooled scene pickups deactivate, allowing Respawner to return them. Keep one deliberate lifetime path and verify that it restores the pickup only once.

In a supported multiplayer build, the authoritative peer owns the Inventory change and network spawn or removal. Core Item Pickup does not provide transport or resolve simultaneous collection by itself. Verify that the installed integration accepts one collection, replicates the Inventory result, and removes the world object for every peer.

## Related tasks

- [Object Pickup](https://opsive.com/support/documentation/ultimate-character-controller/objects/object-pickup/) explains the shared trigger, feedback, depletion, pooling, and lifetime behavior.
- [Complete Item Pickup workflow](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-pickup/) covers the Inventory and Character Item side in more depth.
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/) configures capacities and runtime item ownership.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) creates the Item Definition and Character Item used by an equippable pickup.
- [Character Item](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/) configures the held object and its **Drop Prefab**.
- [Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) determine which collected items form valid loadouts.
- [Pickup ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/pickup/) configures detection, input, filters, and animation timing.
- [Drop](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/drop/) removes an item and initializes its dropped prefab.
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) controls dropped-object motion.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) controls when a scene pickup returns.
- [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/) creates the starting prefab.

## Developer reference

`ItemPickup` derives from `ItemPickupBase`, which derives from `ObjectPickup`. `GetItemDefinitionAmounts()` and `SetItemDefinitionAmounts(...)` expose the pickup contents; Inventory uses this surface to populate a dropped prefab.

`DoItemPickup(...)` owns reservation and depletion, while `DoItemIdentifierPickup(...)` wraps the Inventory transfer with `OnItemPickupStartPickup` and `OnItemPickupStopPickup`. A completed object sends `OnObjectPickedUp(ObjectPickup pickup)`. Successful Inventory additions send `OnInventoryPickupItemIdentifier`; a spawned Character Item also sends `OnInventoryPickupItem`.

See [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) for registration and cleanup patterns.

---

<a id="page-ultimate-character-controller-objects-trajectory-object"></a>

# Trajectory Object

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/)

Trajectory Object moves a launched object along a kinematic arc and can simulate the same path for a preview line. It owns movement, collision casts, reflection, settling, and basic surface feedback; the firing or throwing module and a derived Projectile, Grenade, or Shell own gameplay impact, lifetime, and removal.

## Before you begin

- Decide whether the object is fired by a Shootable Action, thrown by a Throwable Action, spawned by a Magic Action, or initialized from project code.
- Prepare a visible model for Projectile, Grenade, or Shell. Object Manager creates the particle-based Magic Projectile without a supplied model.
- Choose the layers that can be hit and whether the moving object should stop, bounce, pass through, or report a gameplay impact.
- Use a solid Sphere Collider, Capsule Collider, or Box Collider on the Trajectory Object GameObject when the collision cast should match its volume. Without a supported solid collider, Trajectory Object uses a raycast from its transform.

## Choose a trajectory object

| Goal | Built-in type | Runtime owner | Starting behavior |
| --- | --- | --- | --- |
| Fire an arrow, rocket, or moving bullet | [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/) | Shootable Action's Projectile Shooter, Magic Spawn Projectile, or project code | Projectile adds impact data, destruction, pooling, and a `10`-second **Lifespan**. |
| Throw and cook an explosive | [Grenade](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/grenade/) | Throwable Action plus the optional Throwable Grenade module | Grenade adds a `5`-second **Lifespan** and optional **Pin**. The fuse starts only when `StartCooking` is called. |
| Eject a cosmetic casing | [Shell](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/shell/) | A Shootable Action's Shell Effect or project code | Shell uses a `10`-second **Lifespan**, **Persistence** `1`, shrinking removal, and extra random spin on hard impacts. |
| Send a Magic Action impact through a moving effect | [Magic Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/magic-projectile/) | Magic Action's Spawn Projectile Cast Effect | Object Manager creates a Particle System and Projectile. The Cast Effect's **Speed** starts at `1`. |

Use plain Trajectory Object for a custom kinematic prop or a preview simulator only when another system deliberately owns its impact result and lifetime.

## Build the prefab

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name**.
3. Select **Projectile**, **Grenade**, **Shell**, or **Magic Projectile** under **Object Type**.
4. For Projectile, Grenade, or Shell, assign the visible model to **GameObject**. Magic Projectile does not show this field.
5. For Magic Projectile, enable **Magic Particle Collisions** only when individual Particle System particles should invoke Magic impacts.
6. Select **Build Object**, choose a path under the project's `Assets` folder, and open the generated prefab.
7. Adjust the generated collider to match the visible object, then configure the shared Trajectory Object and type-specific fields.
8. Assign the prefab to the matching Shootable, Throwable, or Magic module and configure that module's origin, velocity, layer change, and impact result.

Object Manager creates these starting components:

| Object Type | Generated result |
| --- | --- |
| **Projectile** | Rigidbody, Capsule Collider, and Projectile. |
| **Grenade** | Rigidbody, Capsule Collider, and Grenade, with **Destroy On Collision** disabled. |
| **Shell** | Rigidbody, Capsule Collider, Shell, and a 3D Audio Source with **Spatial Blend** `1` and **Max Distance** `10`. |
| **Magic Projectile** | Rigidbody, Particle System, and Projectile, with **Collision Mode** serialized as **Ignore**. **Magic Particle Collisions** additionally adds Magic Particle. |

The Rigidbody does not drive the arc. Trajectory Object disables Rigidbody gravity and makes it kinematic; Projectile-derived types and Shell also freeze its constraints.

## Configure the shared trajectory

These are the released Version 3 starting values that most often change a result:

| Field | Default | What to decide |
| --- | --- | --- |
| **Initialize On Enable** | Disabled | Leave this off when a Shootable, Throwable, or Magic module supplies launch data. Enable it only for a self-starting object that should initialize with zero velocity. |
| **Mass** / **Start Velocity Multiplier** | `1` / `1` | Runtime divides the supplied launch velocity by both values. Keep both positive; values above `1` reduce initial speed. |
| **Gravity Magnitude** / **Speed** | `9.8` / `1` | Gravity follows the owning character's gravity direction when one exists. Speed scales each movement step. |
| **Rotation Speed** / **Damping** / **Rotation Damping** | `5` / `0.1` / `0.1` | Tune settling and visual rotation. **Rotate In Move Direction** starts disabled. |
| **Settle Position Threshold** / **Settle Rotation Threshold** | `0.01` / `0.01` | Movement and rotation stop when their values fall below these thresholds. Nonpositive values are not a never-settle mode in released Version 3. |
| **Sideways Settle Threshold** / **Start Sideways Velocity Magnitude** | `0.75` / `3` | Choose when a Capsule or Box settles on its side and when it begins rotating toward that resting pose. |
| **Impact Layers** | All except Ignore Raycast, Water, SubCharacter, Overlay, and Visual Effect | Restrict the physics queries to intended surfaces and targets. Trigger colliders are ignored. |
| **Collision Mode** / **Reflect Multiplier** | **Reflect** / `1` | Choose stop, bounce, random bounce, or pass-through behavior. |
| **Surface Impact** / **Force Multiplier** | None / `40` | Add surface feedback and scale forces later applied through `AddForce`. Gameplay damage still belongs to Projectile impact data/actions or the calling item action. |
| **Max Collision Count** / **Max Position Count** | `5` / `150` | Size the collision buffers and cap a displayed curve. Increase only when the scene or preview needs it. |

**Active Audio Clip Set** starts empty, and the **On Collision Event** UnityEvent has no listeners.

## Choose collision and impact behavior

| Collision Mode | Motion after a hit | Use it for |
| --- | --- | --- |
| **Collide** | Stops movement and disables Trajectory Object. A Projectile can parent to an allowed **Sticky Layers** target with uniform scale. | Arrows, rockets, sticky objects, and one-hit projectiles. |
| **Reflect** | Reflects velocity from the hit normal and applies collider material friction plus **Reflect Multiplier**. | Predictable bounces and most thrown objects. |
| **Random Reflect** | Adds a random direction change before reflection. | Local visual effects such as casings; do not use it for authoritative network motion. |
| **Ignore** | Reports the collision but leaves velocity unchanged. | Pass-through queries where another system owns filtering and cleanup. Projectile destruction settings can still remove the object. |

Trajectory Object invokes **On Collision Event**, stops its active audio, applies force to a hit Rigidbody, and spawns **Surface Impact** feedback. Projectile and Grenade then build an `ImpactCallbackContext`, notify their owner, and optionally run **Internal Impact** through their Impact Action Group. A base Trajectory Object does not deal damage by itself.

ProjectileBase also owns **Disable Collider On Impact**, **Destroy On Collision**, **Wait For Particle Stop**, **Destruction Delay**, **Spawned Objects On Destruction**, and the impact-data choice. A spawned Explosion receives the projectile's impact data and damage-source chain.

## Show a trajectory preview

The same simulator can populate an attached Line Renderer. For a Version 3 Throwable Action, keep the preview Trajectory Object on the Character Item and use the **Throwable Visualize Trajectory** Extra module.

![Curved trajectory preview extending from a held grenade toward its predicted landing point](https://opsive.com/wp-content/uploads/2018/03/GrenadeTrajectory.png?v=02c7c9a95305)

1. Add Trajectory Object and Line Renderer to the Character Item or another dedicated preview GameObject.
2. Match **Mass**, **Start Velocity Multiplier**, gravity, speed, damping, collision mode, layers, and collider shape to the live thrown prefab.
3. If the live object uses a Sphere, Capsule, or Box, add the same collider type and dimensions to the simulator. Leave it solid; simulation disables it while drawing the curve.
4. On Line Renderer, disable shadow casting and receiving, assign the line material, leave **Positions** at `0`, and choose a readable width. The legacy example uses `0.15`.
5. In the Throwable Action's Extra Module Group, enable **Throwable Visualize Trajectory** and **Show Trajectory On Aim**. The preview appears only for input-driven Aim and clears when use starts.

![Line Renderer Inspector configured with shadows disabled, zero positions, a material, and width 0.15 for the trajectory preview](https://opsive.com/wp-content/uploads/2018/03/TrajectoryObjectLineRenderer.webp?v=dad8fe1ec2b0)

![Capsule Collider Inspector sized to match the grenade used by the trajectory simulator](https://opsive.com/wp-content/uploads/2018/03/TrajectoryObjectCapsuleCollider.webp?v=91260ac2e1d6)

The preview is deterministic for a stable start, static colliders, and nonrandom collision behavior. Released Version 3's Throwable preview does not apply Trigger force or add the character's forward velocity even though the live throw does. Tune an exact preview while stationary with a Simple Trigger, or use a custom preview module for charged or moving throws.

## How it runs

1. The caller spawns the object, usually through the Opsive pool, and calls an `Initialize` overload with velocity, torque, owner, and impact context.
2. Trajectory Object resolves the owner's gravity direction and local time scale, enables its supported collider, ignores the owner's colliders initially, starts active audio, and registers with Simulation Manager.
3. Each physics step applies gravity and damping, casts the configured shape along the next movement segment, then moves and rotates the transform.
4. A hit runs the shared collision feedback and the selected collision response. ProjectileBase can additionally run impact actions, stick, delay destruction, spawn effects, and return to a pool.
5. The built-in Projectile launch paths start its lifespan during initialization. Grenade starts its fuse only through `StartCooking`. Shell removes itself after its lifespan or an earlier soft-bounce decision. Plain Trajectory Object has no automatic removal policy.
6. A preview uses the same simulation without moving the live object, writes the resulting positions to Line Renderer, disables its collider, and stops updating until the next simulation.

## Editor checkpoint

Before Play Mode, confirm that:

- the intended derived component and supported solid collider are on the prefab root;
- Rigidbody is present for Projectile, Grenade, and Shell but is not being treated as the movement driver;
- Mass and Start Velocity Multiplier are positive;
- **Impact Layers**, **Collision Mode**, and destruction settings describe one coherent result;
- Projectile or Grenade has valid impact data/actions when it should damage or apply force;
- the caller references the prefab and supplies its origin, launch velocity, layer, and lifetime trigger;
- a Grenade has a caller that starts cooking when its fuse should begin;
- a Magic Particle path has Particle System Collision enabled with **Send Collision Messages** enabled; and
- a visible preview has a Line Renderer, a matching collider/physics setup, and the Version 3 visualization module.

## Verify in Play Mode

1. Fire a Projectile at an included layer and an excluded layer. Confirm only the included hit invokes collision feedback and gameplay impact, then confirm the object returns to its pool on collision or lifespan.
2. Throw a Grenade against the same surface. Confirm it reflects or settles according to its mode, keeps its fuse after the bounce, and spawns the configured destruction result when the cook time expires.
3. Eject several Shells. Confirm each uses local cosmetic motion, shrinks after its lifespan, and that **Persistence** changes whether a soft impact shortens its life.
4. Cast a Magic Projectile. Confirm exactly one intended collision path invokes the Magic Impact group and that the particle, root Projectile, and spawned effects all clean up.
5. Aim a stationary Throwable using a Simple Trigger and compare the displayed line with the landing point. Repeat while moving or charging to evaluate the released-Version-3 preview difference.
6. Reuse every prefab from its pool. Confirm its collider, trail, particle, audio, parent, velocity, impact state, lifespan, and visible scale reset before the next launch.
7. In multiplayer, compare server, owner, and observer. Confirm authoritative Projectile/Grenade results match, and keep Random Reflect/Shell presentation local.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The object enables but does not move | **Initialize On Enable** is disabled and no firing, throwing, Magic, or project caller initialized it. | Let the owning module initialize it, or enable self-initialization only for a deliberate zero-velocity setup. |
| Launch speed is infinite, invalid, or unexpectedly low | **Mass** or **Start Velocity Multiplier** is zero or large. Released Version 3 divides velocity by their product. | Keep both values positive, normally `1`, and match the preview and live prefab. |
| Setting a settle threshold to `0` does not prevent settling | `Awake` and the public setters coerce nonpositive **Settle Position Threshold** and **Settle Rotation Threshold** values to `0.001`. | Use positive thresholds and a project-specific mover when the object must never settle. |
| A generated Projectile logs a collision-mode warning and stops instead of reflecting | Object Manager leaves Projectile's inherited **Collision Mode** at **Reflect** while **Destroy On Collision** starts enabled. ProjectileBase forces **Collide** during `Awake`. | Set **Collision Mode** to **Collide** explicitly for a one-hit projectile, or disable **Destroy On Collision** and provide a tested alternative lifetime. |
| A generated Magic Projectile does not remain in **Ignore** mode | Object Manager serializes **Ignore**, but the same enabled **Destroy On Collision** guard forces **Collide** at runtime. | Use **Collide** for a one-hit spell. For true pass-through behavior, disable collision destruction and add explicit project-owned cleanup; do not rely on the default combination. |
| Magic Particle collisions log an error or never invoke the Magic impact | **Magic Particle Collisions** adds Magic Particle but does not configure the generated Particle System's Collision module. | Enable Particle System **Collision** and **Send Collision Messages**, then test whether root Projectile and per-particle impacts should both be active. |
| The line and live throw diverge while moving or charging | The Version 3 preview omits Trigger force and character forward velocity. | Tune while stationary with Simple, or implement a custom preview that uses the live launch calculation. |
| The line is missing | Check Line Renderer, its material, the simulator, the matching collider, input-driven Aim, and **Show Trajectory On Aim**. | Restore the components and module, then verify that Aim starts from input before throwing. |
| A mesh-shaped object clips a surface or detects only along its center | Mesh Collider and trigger-only setups are not supported shape casts. | Add a solid Sphere, Capsule, or Box approximation on the Trajectory Object root. |
| Collision feedback runs but no damage occurs | Only shared Trajectory Object feedback is configured. | Use Projectile/Grenade impact data and **Internal Impact**, or let the Shootable, Throwable, or Magic action own the gameplay result. |
| A plain Trajectory Object remains forever | Base Trajectory Object has no lifespan or pool-return behavior. | Use Projectile, Grenade, or Shell, or have the caller return the object explicitly. |

## Saving, pooling, and multiplayer

The prefab stores its physics, impact, audio, curve, and derived-type settings. Current velocity, torque, collision state, platform attachment, pending lifespan/fuse/destruction events, and preview positions are runtime state. Save the durable gameplay result and deliberately respawn or discard active moving objects around a load boundary rather than expecting a flight to resume automatically.

ProjectileBase and Shell return through `ObjectPoolBase`; a supported network build can use `NetworkObjectPool` for authoritative Projectile/Grenade destruction and spawning. Plain Trajectory Object has no pool-return behavior, so its caller owns cleanup.

**Random Reflect** and Shell's random torque are not deterministic across peers. Treat Shell as local visual feedback and keep authoritative hits, damage, explosions, and object removal on the server or owning peer through the installed integration.

## Related tasks

- [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/) creates the starting prefabs.
- [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) configures hitscan and moving Projectile weapons.
- [Throwable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/) configures live throw velocity, preview, Grenade cooking, and inventory use.
- [Magic Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/) configures Spawn Projectile and Magic impact modules.
- [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) configures a spawned area result.
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) configures **Surface Impact** feedback.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reusable object ownership.

## Developer reference

`TrajectoryObject` implements `IForceObject`, `IDamageSource`, and `ISmoothedObject`. Its public runtime surface includes `Initialize(...)`, `SimulateTrajectory(...)`, `ClearTrajectory()`, `AddForce(...)`, `Velocity`, `Torque`, `Owner`, and `LineRenderer`.

The base **On Collision Event** UnityEvent receives a `RaycastHit` only for a physical hit. `ProjectileBase` separately exposes the C# `OnImpact` and `OnDestruct` events and notifies an `IProjectileOwner` through `OnProjectileImpact` and `OnProjectileDestruct`. Whether a target receives `OnObjectImpact` depends on the configured Impact Actions; it is not emitted by base Trajectory Object.

Use [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) for project listeners, and unregister C# or Event System callbacks when a pooled owner is disabled or destroyed.

---

<a id="page-ultimate-character-controller-objects-trajectory-object-grenade"></a>

# Grenade

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/grenade/)

A Grenade gives a Throwable Action a timed, physical explosive that can begin cooking while it is still in the character's hand. Use it when the object should follow a trajectory, bounce or settle, and spawn a separate Explosion when its fuse expires.

## Before you begin

- Prepare a visible grenade model and a separate [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) prefab for the final area effect.
- Configure a [Throwable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/) with an enabled Thrower, Ammo, Projectile, and Re-Equipper module.
- Decide whether touching a target should also cause an immediate impact result, or whether all damage should come from the final Explosion.
- Use a solid Sphere, Capsule, or Box Collider on the grenade root. The trajectory casts ignore trigger colliders.

## Build the grenade prefab

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name**, set **Object Type** to **Grenade**, and assign the visible model to **GameObject**.
3. Select **Build Object**, save the prefab under the project's `Assets` folder, and open the generated prefab.
4. Confirm the root has **Rigidbody**, **Capsule Collider**, and **Grenade** components. Object Manager disables **Destroy On Collision** for this object type so the generated grenade can keep moving after a hit.
5. Resize the Capsule Collider to the model, or replace it with a solid Sphere Collider when that better matches a round grenade. The Grenade component makes the Rigidbody kinematic and disables Rigidbody gravity at runtime; Trajectory Object owns the arc.
6. In the Grenade component's trajectory settings, keep **Initialize On Enable** disabled when the Throwable Action will launch the object. **Collision Mode** starts as **Reflect**, so the generated object bounces.
7. Under **Destruction**, keep **Destroy On Collision** disabled and **Destruction Delay** at `0` for a fuse-only result. Add the Explosion prefab to **Spawned Objects On Destruction** and leave its **Probability** at `1` when every cooked grenade should explode.
8. Under the impact settings, configure **Default Impact Damage Data** even when the Explosion owns the visible damage result. Disable **Internal Impact** if a bounce should not run the Grenade's own Impact Action Group.

## Connect the Throwable Action

1. On the Character Item's Throwable Action, assign the prefab to **Spawn Projectile > Thrown Object**.
2. Add **Throwable Grenade** to the action's **Extra** module group. The released Version 3 Item Manager recipe does not add this module automatically.
3. On the Grenade prefab, set **Lifespan**. Its released Version 3 default is `5` seconds.
4. For a removable pin, make the pin a child Transform of the grenade and assign it to **Pin**. A root pin with no parent cannot be detached and restored by the built-in component.
5. In **Throwable Grenade**, leave **Animate Pin Removal** enabled when the animation shows the pin being pulled. Assign **Pin Attachment Location** for each enabled perspective, then synchronize **Remove Pin Event** with `OnAnimatorItemRemovePin`. The trigger waits for that animation event by default; its stored **Duration** is `0.4` seconds when event waiting is disabled.
6. Match the Throwable Action's **Use Event** to the release frame. The fuse starts when item use starts, before this release event, so time spent holding the cooked grenade counts toward **Lifespan**.

The held object and the launched object are the same pooled Grenade instance. Do not add a separate timer to the Throwable Action unless it deliberately replaces the built-in cooking flow.

## Key choices

| Goal | Configure | Result |
| --- | --- | --- |
| Bounce until the fuse expires | **Collision Mode Reflect**, **Destroy On Collision** disabled, **Destruction Delay** `0` | Contact changes the trajectory but does not schedule destruction. |
| Stop on the first surface, then wait for the fuse | **Collision Mode Collide**, **Destroy On Collision** disabled, and include every intended stop surface in **Sticky Layers** | The object stops and attaches at the hit while the cook event remains active. A uniform-scale target outside Sticky Layers forces destruction. |
| Explode immediately on contact | **Collision Mode Collide** and **Destroy On Collision** enabled | The first valid collision destroys the Grenade without waiting for the remaining fuse. |
| Damage only through the final blast | Disable **Internal Impact** and configure the spawned Explosion | Bounces provide trajectory and surface feedback without applying the Grenade's collision Impact Action Group. |
| Damage on contact and at the final blast | Keep **Internal Impact** enabled, configure its Impact Action Group, and configure the Explosion separately | Each path owns an explicit result; test for unintended double damage near the final contact. |
| Keep collider-based interactions after a bounce | Disable **Disable Collider On Impact** | The physical Collider remains enabled after the first impact. The released Version 3 default disables it on impact even when the Grenade continues moving. |

**Impact Layers** decides which colliders the trajectory can hit. **Sticky Layers** matters only in **Collide** mode. A positive **Destruction Delay** schedules destruction after the first collision even if **Destroy On Collision** is disabled, so it is not an extra fuse duration.

## How it runs

1. **Spawn Projectile** takes a Grenade from the pool, initializes its projectile data, attaches it to the held item, and keeps trajectory movement disabled.
2. When the Use ability starts successfully, **Throwable Grenade** calls `StartCooking`. This records the character and Throwable Action as the damage-owner chain and schedules destruction after **Lifespan**.
3. If pin removal is animated, the selected animation-event or duration mode moves the pin to **Pin Attachment Location**. Enabling a reused Grenade restores the pin to its original parent and local pose.
4. At **Use Event**, the Projectile Thrower releases and initializes the trajectory. Hits run shared collision feedback and can run the Grenade's own impact path, while the selected collision mode decides whether motion stops, reflects, or continues.
5. When the cook event expires, the Grenade temporarily moves to Ignore Raycast so its own spawned Explosion does not detect it, then destructs at its current position.
6. Destruction invokes the configured result, passes the Grenade's impact and ownership data to a spawned Explosion, and returns the Grenade through the object or network pool.

## Editor checkpoint

Before Play Mode, confirm that:

- the prefab root has Grenade, Rigidbody, and one supported solid Collider;
- **Initialize On Enable** is disabled and **Mass** plus **Start Velocity Multiplier** are positive;
- **Impact Layers**, **Collision Mode**, **Destroy On Collision**, and **Destruction Delay** describe one coherent contact result;
- **Default Impact Damage Data** is populated and **Internal Impact** matches the intended collision damage;
- **Spawned Objects On Destruction** contains the Explosion with **Probability** `1` for a guaranteed blast;
- the Throwable Action's **Spawn Projectile > Thrown Object** references this prefab;
- **Throwable Grenade** is enabled in the Extra group; and
- an assigned **Pin** has an original parent, a perspective-specific attachment location, and either a matching animation event or duration mode.

## Verify in Play Mode

1. Start using the grenade and keep holding it. Confirm the pin moves at the intended frame and the grenade destructs in the hand after **Lifespan**.
2. Start again and release quickly. Confirm the object leaves the hand at **Use Event**, follows the expected arc, and keeps the remaining fuse time rather than restarting it.
3. Throw against an included surface. Confirm **Reflect** bounces or **Collide** stops as configured, and confirm a fuse-only grenade does not destruct on first contact.
4. Throw against an excluded layer. Confirm the trajectory does not report the contact or run the collision impact path.
5. Let the fuse expire after a bounce. Confirm one Explosion appears at the Grenade's current position, attributes damage to the character/item owner chain, and the Grenade returns to its pool.
6. Reuse the prefab several times. Confirm the pin, collider, visible model, fuse, ownership, and destruction result reset on every throw.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The Grenade flies forever | **Throwable Grenade** is missing or no project code calls `StartCooking`. Enabling or launching a Grenade does not start its fuse. | Add **Throwable Grenade** to the Extra group, or call `StartCooking` from the system that deliberately owns activation. |
| The use starts with a null-reference error | **Throwable Grenade** is enabled but **Thrown Object** is not a Grenade prefab. | Assign a prefab with the Grenade component, or remove the grenade-specific Extra module. |
| The Grenade explodes on its first bounce | **Destroy On Collision** is enabled or **Destruction Delay** is greater than `0`. | Disable collision destruction and set the delay to `0` for a fuse-only grenade. |
| Reflect changes to Collide and a warning appears | **Destroy On Collision** is enabled with a non-Collide mode. | Disable collision destruction for a bouncing grenade. ProjectileBase forces **Collide** for that conflicting combination during `Awake`. |
| The pin never moves | The Grenade's **Pin** has no original parent, the attachment location is empty, or event waiting is enabled but `OnAnimatorItemRemovePin` never occurs. | Keep the pin as a child, assign **Pin Attachment Location**, then supply the animation event or disable event waiting and use the configured **Duration**. |
| The first bounce stops later collider-based interactions | **Disable Collider On Impact** remains at its enabled default. | Disable that field when the Collider must remain active after contact, then retest the intended collision and pooling behavior. |
| Bounces deal damage when only the blast should | **Internal Impact** and its Impact Action Group are enabled. | Disable **Internal Impact** and keep damage on the spawned Explosion. |
| The Console reports missing impact damage data | **Default Impact Damage Data** is not populated before the Throwable modules initialize the Grenade. | Configure the Grenade's default impact data, including its layers and damage ownership choices. |
| Canceling a cooked use leaves a live fuse | Released Version 3 starts cooking at the beginning of use, but the built-in cancellation path does not cancel that scheduled Grenade event. | Prevent interruption after cooking starts, or add project-owned cancellation that returns or safely destructs the pre-spawned object. |
| No Explosion appears at the end of the fuse | **Spawned Objects On Destruction** has no valid object, its probability is below `1`, or the Explosion prefab is misconfigured. | Assign the tested Explosion prefab, use probability `1` for a guaranteed result, and verify that prefab separately. |

## Saving, pooling, and multiplayer

The prefab stores its trajectory, fuse, pin, impact, and destruction configuration. The remaining cook time, current flight, detached pin, contact state, and active owner are runtime state. Around a save/load boundary, preserve the gameplay consequence you need and deliberately respawn or discard an active Grenade rather than expecting its scheduled fuse and trajectory to resume.

Grenade destruction returns through `ObjectPoolBase`. With the supported multiplayer integration active, destruction and spawned results use the network path and only the server is allowed to explode the ProjectileBase. Configure and test the prefab through that integration; the base component does not by itself synchronize a custom save or networking policy.

## Related tasks

- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) explains shared movement, collision, settling, and preview settings.
- [Throwable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/) configures spawning, cooking, release timing, inventory use, and re-equipping.
- [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) configures the area damage and effects spawned at destruction.
- [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/) is the corresponding one-hit or lifespan-based moving object.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reusable object ownership.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains project-level event listeners.

## Developer reference

`Grenade` derives from `ProjectileBase`. Its public members are `Lifespan`, `Pin`, `StartCooking(GameObject originator, IDamageSource ownerSource = null)`, and `DetachAttachPin(Transform attachTransform)`. `ProjectileBase` exposes the C# `OnImpact` and `OnDestruct` events and notifies an `IProjectileOwner` through `OnProjectileImpact` and `OnProjectileDestruct`.

`StartCooking` schedules its fuse through the Opsive `Scheduler`; `OnDisable` cancels that event. `DetachAttachPin(null)` restores the cached original parent, position, and rotation. Subscribe and unsubscribe listeners with the pooled object's enable/disable lifecycle, and use [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) for project-level Event System callbacks.

---

<a id="page-ultimate-character-controller-objects-trajectory-object-magic-projectile"></a>

# Magic Projectile

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/magic-projectile/)

A Magic Projectile gives a Magic Action a pooled, trajectory-driven fireball or similar moving effect whose collision can enter the spell's Impact Module Group. In released Version 3, Magic Projectile is an Object Manager recipe that creates a Particle System and the standard `Projectile` component; there is no separate Magic Projectile runtime component.

## Before you begin

- Create a [Magic Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/) with an enabled Trigger, Simple Caster, **Spawn Projectile** Cast Effect, and the intended Magic Impact modules.
- Decide whether one root Projectile collision or individual Particle System collisions should report the hit. Do not enable both paths for the same visible fireball unless two impacts are intentional.
- Prepare any Particle System material, shape, emission, and renderer settings required for the effect. Object Manager creates a new Particle System instead of accepting a visible model in this recipe.
- Decide which layers the root trajectory can hit and whether trigger-only targets need a different collision system. Trajectory Object casts ignore trigger colliders.

## Build the projectile prefab

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name** and set **Object Type** to **Magic Projectile**. This object type does not show a **GameObject** field.
3. Leave **Magic Particle Collisions** disabled for a normal one-hit fireball. Enable it only when individual Particle System collisions should invoke the Magic Action's impact path.
4. Select **Build Object**, save the prefab under the project's `Assets` folder, and open the generated prefab.
5. Confirm that the root contains **Rigidbody**, **Particle System**, and **Projectile**. When requested, Object Manager also adds **Magic Particle**. It does not add a Collider.
6. For a thin effect, the no-collider setup uses a raycast from the root along each movement step. Add and size a solid Sphere, Capsule, or Box Collider when the cast should match the fireball's visible volume.
7. Configure the Particle System's material, lifetime, emission, and rendering. ProjectileBase stops the Particle System while idle and plays it when the projectile is initialized.
8. Configure the Projectile as a one-hit Magic collision owner: use **Collision Mode Collide**, keep **Destroy On Collision** enabled, set **Lifespan** for missed shots, and disable **Internal Impact** so only the Magic Action's Impact Module Group applies the gameplay result.
9. Configure **Default Impact Damage Data**. Its layer mask and Surface Impact are supplied to the Magic impact callback; unless **Use Object Impact Layer And Surface** is enabled, they also overwrite the Projectile's **Impact Layers** and **Surface Impact** when the shot initializes.
10. Leave **Wait For Particle Stop** disabled for immediate pool return, or enable it to stop emission and delay destruction by the Particle System's main **Duration** after a hit or lifespan expiry.

Object Manager serializes **Collision Mode** as **Ignore**, but the same generated Projectile keeps **Destroy On Collision** enabled. ProjectileBase treats that combination as invalid during `Awake`, logs a warning, and changes the mode to **Collide**. Set **Collide** explicitly for the normal one-hit setup instead of relying on the contradictory generated values.

## Connect the Magic Action

1. On the Character Item's Magic Action, add **Spawn Projectile** to **Cast Effects Module Group**.
2. Assign the generated prefab to **Projectile Prefab**. The `Projectile` component must be on the prefab root.
3. Leave **Position Offset** and **Rotation Offset** at `(0, 0, 0)` until the effect is aligned with the Caster's first- and third-person **Cast Origin**.
4. Set **Speed** for the scene scale. Its released Version 3 default is `1`; the module launches the Projectile in the current cast direction at that speed.
5. Keep **Parent To Origin** disabled for an independent fireball. Enabling it leaves the moving Projectile under the wand-tip or hand Transform.
6. For one projectile per use, use **Delay** `0`, **Initial Delay** `-1`, and a non-continuous Caster. **Allow Multi Target** starts enabled; disable it unless the Caster should create one projectile for every selected target.
7. In **Impact Module Group**, add **Generic Magic Impact Module** and configure its Conditions plus successful and failed Impact Action Groups. A Projectile hit forwards its complete impact context to every enabled Magic Impact module.

## Choose collision and result ownership

| Goal | Root Projectile | Magic Particle | Cleanup |
| --- | --- | --- | --- |
| One physical fireball hit | **Collide**, **Destroy On Collision** enabled, **Internal Impact** disabled | Do not add it | Collision or the default `10`-second **Lifespan** returns the object. |
| Let the visual finish after the hit | Same as one-hit, with **Wait For Particle Stop** enabled | Do not add it | Movement and emission stop; pool return waits for the Particle System's main **Duration**. |
| Report individual particle collisions | Prevent root hits with deliberate **Impact Layers** and keep a tested lifetime | Add and configure it | Particle System collisions invoke Magic impacts; the root Projectile still owns lifetime and pool return. |
| Run only Projectile-local Impact Actions | Keep **Internal Impact** enabled and leave the Magic Action's Impact group empty | Do not add it | The prefab owns the result, but the Spawn Projectile owner callback still reaches the empty Magic group. |
| Pass through and report root contacts | **Ignore**, **Destroy On Collision** disabled, **Internal Impact** as intended | Do not add it | Add project-owned cleanup. The built-in lifespan does not destroy this `Ignore`/no-destruction/zero-delay combination. |

For a particle-collision spell, enable Particle System **Collision** and **Send Collision Messages**, configure **Collides With**, and follow [Magic Particle](https://opsive.com/support/documentation/ultimate-character-controller/objects/magic-particle/). Object Manager's **Magic Particle Collisions** toggle only adds the component; it does not configure the Particle System Collision module. Keep the root Projectile and particle collision masks separate so exactly one path owns each target encounter.

The Projectile callback reaches the Magic Action first, then **Internal Impact** runs the Projectile's local Impact Action Group. Leaving both configured can apply damage, force, surface effects, or events twice.

## How it runs

1. At the Magic Action's start-cast event, **Spawn Projectile** gets the prefab from `ObjectPoolBase` and positions it from the Caster's origin, cast position, and offsets.
2. The module finds `Projectile` on the root and initializes it with the cast ID, cast direction multiplied by **Speed**, the Magic Action as the damage source, and the prefab's **Default Impact Damage Data**.
3. The Projectile starts its Particle System, schedules its **Lifespan**, enables trajectory simulation, and ignores collisions between any projectile Colliders and the casting character's locomotion Colliders.
4. A root trajectory hit creates an `ImpactCallbackContext`. **Spawn Projectile** forwards that context to `MagicAction.PerformImpact`, which invokes every enabled Magic Impact module. The Projectile then invokes its own group when **Internal Impact** remains enabled.
5. An optional Magic Particle follows a separate route: Unity sends `OnParticleCollision`, and Magic Particle reconstructs a hit before invoking the same Magic Action Impact modules.
6. **Destroy On Collision**, **Destruction Delay**, **Wait For Particle Stop**, or **Lifespan** decides when the root destructs. Destruction restores ignored character collisions and returns the object through the local or network pool.

The Spawn Projectile Cast Effect completes after creating the object; it does not wait for the projectile to hit or expire. Ending or interrupting the Magic Action therefore does not recall an in-flight Projectile. Its prefab owns the remaining lifetime and cleanup.

## Editor checkpoint

Before Play Mode, confirm that:

- the root has Projectile, Rigidbody, Particle System, and an optional supported solid Collider;
- **Initialize On Enable** is disabled, **Mass** and **Start Velocity Multiplier** are positive, and **Lifespan** is greater than `0` for missed shots;
- **Collision Mode**, **Destroy On Collision**, **Destruction Delay**, and **Wait For Particle Stop** describe one coherent cleanup result;
- **Default Impact Damage Data**, its layer mask, and the **Use Object Impact Layer And Surface** choice match the intended targets and surface feedback;
- **Internal Impact** is disabled when the Magic Action's Impact Module Group owns damage and effects;
- **Projectile Prefab** references this prefab and **Speed**, offsets, origin, parenting, delay, and multi-target choices are deliberate;
- the Magic Action has at least one enabled Impact module when a hit should produce a result; and
- when Magic Particle is present, Particle System **Collision** and **Send Collision Messages** are enabled and the root and particle paths cannot double-report the same hit.

## Verify in Play Mode

1. Equip the spell item, expand the Magic Action's **Debug** view, and cast once. Confirm one projectile starts at the current perspective's Cast Origin and travels at the configured **Speed**.
2. Hit a target on an included layer. Confirm the Projectile invokes the Magic Impact modules exactly once, produces the intended damage and surface result, then becomes inactive or finishes its configured particle delay.
3. Cast at an excluded layer and at a trigger-only collider. Confirm neither enters the root trajectory impact path.
4. Miss every target. Confirm the Projectile returns to its pool after **Lifespan** and does not leave a live Particle System in the scene.
5. Switch perspectives and cast while the character moves. Confirm offsets remain aligned and **Parent To Origin** has the intended independent or parented result.
6. Reuse the same pooled prefab repeatedly. Confirm the Particle System, Collider, ignored character collisions, impact state, lifespan, position, and ownership reset for every shot.
7. If using Magic Particle, repeat with the root impact path excluded. Confirm particle collisions invoke the Magic Impact modules once per intended contact and the root still cleans up.
8. With multiplayer enabled, repeat as owner, server, and observer. Confirm the authoritative role owns impact and destruction, remote roles show one visual, and the object returns through the registered network pool.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console says the prefab has no Magic Projectile component | **Projectile Prefab** does not contain `Projectile` on its root. The warning uses the legacy Magic Projectile name, but released Version 3 looks for `Projectile`. | Add Projectile to the root or rebuild with Object Manager's **Magic Projectile** type. |
| The generated prefab logs a collision-mode warning and changes to Collide | Object Manager serialized **Ignore** while inherited **Destroy On Collision** remained enabled. | Set **Collide** explicitly for a one-hit spell. For true pass-through, disable collision destruction and add explicit cleanup. |
| A pass-through projectile never returns after Lifespan | **Ignore**, **Destroy On Collision** disabled, and **Destruction Delay** `0` leave no destruction condition when the lifespan callback runs. | Use a one-hit configuration or return the object from project code. A positive Destruction Delay also starts after the first contact, so it is not a pure miss-only lifetime. |
| Impact modules never run | The prefab lacks root Projectile, the target is outside the active impact layer mask, or the Magic Action has no enabled Impact module. | Restore Projectile, configure **Default Impact Damage Data** and the layer/surface ownership choice, then add the intended Magic Impact module. |
| Damage or effects occur twice | **Internal Impact** and the Magic Impact group are both configured, or Magic Particle and root Projectile both report the same encounter. | Choose one gameplay collision owner and disable or exclude the other path. |
| The fireball only detects a line through its center | Object Manager does not add a Collider to Magic Projectile. | Add a solid Sphere, Capsule, or Box Collider sized to the visible volume. |
| The Projectile hits layers that differ from its Inspector's Impact Layers | **Use Object Impact Layer And Surface** is disabled, so initialization copies the layer mask and Surface Impact from **Default Impact Damage Data**. | Configure the default data to match, or enable the object-level override deliberately. |
| Magic Particle logs that Collision or Send Collision Messages is disabled | Object Manager added Magic Particle but left the Particle System Collision module at its Unity defaults. | Enable both Particle System options and configure **Collides With**, or remove Magic Particle for a root-projectile spell. |
| The projectile follows or rotates with the wand | **Parent To Origin** is enabled. | Disable it for an independent world-space projectile. |
| The particle disappears abruptly on impact | **Wait For Particle Stop** is disabled. | Enable it when the root should stop emission and delay pool return by the Particle System's main Duration, then test the effect's remaining lifetime. |
| Stopping the cast leaves a projectile in flight | Spawn Projectile completes immediately and does not keep ownership for cast-stop cleanup. | Let collision or Lifespan own cleanup, or add a project module that tracks and recalls its spawned objects. |
| A network cast duplicates or loses the projectile | The prefab is not registered with the installed integration's network pool, or custom spawning also runs on observers. | Register and spawn through the supported integration, keep gameplay impact authoritative, and do not independently spawn the same projectile on remote roles. |

## Saving, pooling, and multiplayer

The prefab stores its trajectory, particle, impact, collision, and destruction configuration. The current cast ID, flight, remaining lifespan or destruction delay, ignored collision pairs, active particle state, impact state, and owner are runtime data. Finish or discard an in-flight projectile around a save/load boundary rather than expecting that transient state to resume.

Projectile destruction uses `ObjectPoolBase`. With the supported multiplayer integration enabled, the authoritative Spawn Projectile path uses `NetworkObjectPool`, the server manages the Projectile, and ProjectileBase restricts network destruction to the server. Prefab registration, custom-module synchronization, save behavior, and authoritative damage remain integration or project responsibilities.

## Related tasks

- [Magic Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/magic/) configures the Caster, Cast Effect, Impact modules, timing, and animation flow.
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) explains the shared movement, collision, and preview settings.
- [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/) documents the underlying one-hit and lifespan behavior.
- [Magic Particle](https://opsive.com/support/documentation/ultimate-character-controller/objects/magic-particle/) configures individual Particle System collisions instead of one root trajectory hit.
- [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) configure damage, force, surface effects, and callbacks.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reusable object ownership.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains project-level event registration and cleanup.

## Developer reference

The Cast Effect type is `Opsive.UltimateCharacterController.Items.Actions.Modules.Magic.CastEffects.SpawnProjectile`. It implements `IProjectileOwner` and exposes `ProjectilePrefab`, `PositionOffset`, `RotationOffset`, `Speed`, and `ParentToOrigin`. `Owner` is the character, `SourceComponent` is the Character Item Action, and `DamageSource` is the Magic Action.

`OnProjectileImpact` forwards the Projectile's `ImpactCallbackContext` to `MagicAction.PerformImpact`, preserving its Impact Damage Data while replacing the source ID with the cast ID and associating the Magic Action as the source item action. `OnProjectileDestruct` restores the ignored character/projectile Collider pairs.

`Projectile` exposes `Lifespan` and inherits `Initialize`, `Destruct`, `OnImpact`, and `OnDestruct` behavior from ProjectileBase and Trajectory Object. `MagicParticle.Initialize(MagicAction, uint castID)` is a separate optional collision route. The Magic Action publishes `OnMagicItemCast(CharacterItem)` through the Event System when its Cast Effects have cast; impact callbacks such as `OnObjectImpact` depend on the configured Impact Actions. Subscribe and unsubscribe C# or [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) listeners with the pooled object's enable/disable lifecycle.

---

<a id="page-ultimate-character-controller-objects-trajectory-object-projectile"></a>

# Projectile

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/)

A Projectile gives a Shootable Action a physical shot with visible travel time, gravity, collision volume, and its own lifetime. Use it for a rocket, arrow, grenade-launcher round, or slow energy bolt; use Hitscan instead when the hit should resolve immediately without a moving object.

## Before you begin

- Create a [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) with **Projectile Shooter**, **Spawn Projectile**, and the intended Shootable Impact modules.
- Prepare a visible projectile model. For a rocket that explodes, also prepare a separate [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) prefab.
- Decide whether the Shootable Action's Impact Module Group or the Projectile prefab's **Internal Impact** group owns damage and effects. Configure one primary path to avoid duplicate results.
- Decide whether the shot should destruct, stick, bounce, or pass through on contact before configuring its collision and cleanup.

## Build the projectile prefab

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name**, set **Object Type** to **Projectile**, and assign the visible model to **GameObject**.
3. Select **Build Object**, save the prefab under the project's `Assets` folder, and open the generated prefab.
4. Confirm that the root contains **Rigidbody**, **Capsule Collider**, and **Projectile**. Resize the Capsule Collider to the model, or replace it with a solid Sphere or Box Collider when that better represents the shot. Trigger colliders are ignored by Trajectory Object casts.
5. Set **Collision Mode** to **Collide** for a normal one-hit projectile. Object Manager leaves the inherited **Reflect** value while **Destroy On Collision** starts enabled; ProjectileBase logs a warning and forces that conflicting combination to **Collide** during `Awake`.
6. Keep **Initialize On Enable** disabled when Shootable or Magic modules launch the object. The released Version 3 movement defaults are **Mass** `1`, **Start Velocity Multiplier** `1`, **Gravity Magnitude** `9.8`, **Speed** `1`, and movement plus rotation **Damping** `0.1`.
7. Configure **Impact Layers** and **Surface Impact**, then configure **Default Impact Damage Data**. Unless **Use Object Impact Layer And Surface** is enabled, initialization copies the layer mask and Surface Impact from that default data over the object-level values.
8. For a Shootable Action that owns the gameplay hit, disable **Internal Impact** and configure **Generic Shootable Impact** on the item. Keep **Internal Impact** enabled only when the prefab's own Impact Action Group is an intentional second or alternative result.
9. For a one-hit shot, keep **Destroy On Collision** enabled and set **Destruction Delay** to `0`. **Lifespan** defaults to `10` seconds and removes a missed projectile in this configuration.
10. Add optional prefabs under **Spawned Objects On Destruction**. Use **Probability** `1` for a guaranteed Explosion or effect, and enable **Random Spin** only for a presentation object whose orientation may vary.

ProjectileBase makes the Rigidbody kinematic, disables Rigidbody gravity, and freezes its constraints. Trajectory Object owns the movement; do not tune the Rigidbody as though Unity physics launches the shot.

## Connect the Shootable Action

1. In **Shooter Action Module Group**, add **Projectile Shooter** and make it the first enabled Shooter.
2. In **Projectile Action Module Group**, add **Spawn Projectile** and make it the first enabled Projectile module. Assign the prefab to its **Projectile** field; the `Projectile` component must be on the prefab root.
3. Assign **Fire Point Location** for every enabled perspective. Keep **Use Look Source Position** disabled to spawn there, or enable it for the Look Source position when the current Movement Type does not use independent look.
4. Enable **Fire In Look Source Direction** for crosshair-directed fire. Leave it disabled when the Fire Point's forward direction should aim the shot.
5. Set **Projectile Fire Velocity Magnitude**. Its released Version 3 default is `10`. **Spread** defaults to `0.01`, **Fire Count** to `1`, and **Inherit Character Velocity** is disabled.
6. Keep **Projectile Fired Layer** at **VisualEffect** only when that layer is correct for the project, and choose **Layer Change Delay**. Its default is `0`. The Shooter's **Impact Layers** aim and obstruction-check the shot; the Projectile prefab's impact data and layers control the moving object's actual hits.
7. **Spawn Projectile > Projectile Visibility** defaults to **On Fire**, so the object is created when fired. Choose **On Aim**, **On Reload**, or **Always** only when a loaded arrow or round should be visible before release. **Projectile Start Layer** defaults to Ignore Raycast for that attached state.
8. Add **Generic Shootable Impact** and configure its Conditions plus pass and fail Impact Action Groups. The Projectile Shooter forwards the Projectile's collision context to every enabled Shootable Impact module.

The launch velocity is **Projectile Fire Velocity Magnitude** multiplied by Trigger force, plus the character's forward local velocity when **Inherit Character Velocity** is enabled. Trajectory Object then divides that velocity by the product of **Mass** and **Start Velocity Multiplier** before applying its gravity, speed, and damping.

## Choose the contact result

| Goal | Configure | Cleanup behavior |
| --- | --- | --- |
| Rocket or ordinary one-hit round | **Collide**, **Destroy On Collision** enabled, **Destruction Delay** `0` | The hit invokes impacts, spawns destruction objects, and returns the Projectile immediately. |
| Delay an explosion after impact | **Collide**, **Destroy On Collision** enabled, positive **Destruction Delay** | The Projectile stays until the delay expires; its Collider is disabled on impact by default. |
| Arrow that follows a target | **Collide**, **Destroy On Collision** disabled, include the target in **Sticky Layers**, and use a positive **Destruction Delay** or project cleanup | A uniform-scale target becomes the parent. The first hit cancels the normal Lifespan, so cleanup must be explicit. |
| Bouncing shot | **Reflect** or **Random Reflect**, **Destroy On Collision** disabled | Add project-owned cleanup. The first hit cancels Projectile's Lifespan; a positive Destruction Delay instead counts from that first bounce. |
| Pass-through detector | **Ignore**, **Destroy On Collision** disabled | Add project-owned cleanup and hit filtering. Contacts are reported without changing velocity, but the built-in Lifespan does not destroy this zero-delay configuration. |
| Let a root Particle System finish after stopping emission | **Wait For Particle Stop** enabled | On impact or Lifespan, emission and movement stop and destruction waits for the root Particle System's main **Duration**. This value replaces, rather than adds to, Destruction Delay. |

**Sticky Layers** is used only in **Collide** mode. A uniform-scale hit outside that mask forces destruction even when **Destroy On Collision** is disabled. A nonuniform target cannot become the parent, so a stopped arrow will not follow it.

**Disable Collider On Impact** starts enabled. That suits a one-hit or stuck shot. Disable it for a bouncing or pass-through design only when later Collider-based interactions must remain active; the trajectory simulator continues using its cached shape for casts.

## How it runs

1. **Spawn Projectile** obtains the prefab from `ObjectPoolBase` at fire time, or prepares it earlier when **Projectile Visibility** shows a loaded object.
2. Projectile Shooter reads the current clip round, calculates the Fire Point and direction, and obtains the object from Spawn Projectile. A pre-spawned object is linecast from the Look Source to prevent separate first-person arms from placing it through an obstruction.
3. The Shooter changes the hierarchy to **Projectile Fired Layer** after **Layer Change Delay**, then initializes the root Projectile with velocity, Trigger force, Shootable Action ownership, and the prefab's Default Impact Damage Data.
4. Projectile schedules **Lifespan**, enables its Collider and trajectory simulation, starts active audio or particles, and ignores its owner's hierarchy during trajectory casts.
5. A hit runs shared collision and surface feedback. Projectile Shooter forwards the context to the Shootable Action's Impact Module Group; ProjectileBase then runs its local group when **Internal Impact** is enabled.
6. The first hit cancels the scheduled Lifespan. Collision mode changes movement, while destruction settings decide whether and when the object spawns its configured results and returns through the local or network pool.
7. A shot that never hits reaches **Lifespan**. With **Destroy On Collision** enabled, this uses the same destruction path without a RaycastHit and returns the object.

## Editor checkpoint

Before Play Mode, confirm that:

- Rigidbody, Projectile, and one supported solid Collider are on the prefab root;
- **Initialize On Enable** is disabled and **Mass**, **Start Velocity Multiplier**, and **Lifespan** are positive;
- **Collision Mode**, **Sticky Layers**, **Destroy On Collision**, **Destruction Delay**, and **Wait For Particle Stop** form one coherent contact and cleanup policy;
- **Default Impact Damage Data**, its layer mask, and **Use Object Impact Layer And Surface** match the intended targets and feedback;
- **Internal Impact** is disabled when Generic Shootable Impact owns damage and effects;
- Projectile Shooter and Spawn Projectile are the first enabled modules in their groups, and the **Projectile** field references this prefab;
- every perspective has a valid **Fire Point Location**, and look direction, velocity, fired layer, spread, Fire Count, and inherited velocity are intentional; and
- a pre-spawned projectile has the correct visibility, start layer, reload attachment, and animation-event or duration timing.

## Verify with a firearm in Play Mode

1. Equip the firearm or launcher, expand the Shootable Action's **Debug** section, and fire one round. Confirm one Projectile appears at the active perspective's Fire Point and the clip decreases by one.
2. Compare Fire Point direction with **Fire In Look Source Direction** enabled and disabled. Confirm velocity, Trigger force, character movement inheritance, spread, and gravity produce the intended path.
3. Hit a target on an included layer. Confirm Generic Shootable Impact runs exactly once, applies the intended damage and surface result, and the Projectile follows its one-hit, delayed, or sticky policy.
4. Fire at an excluded layer and a trigger-only collider. Confirm the moving Projectile does not report those contacts even when the Shooter's aiming mask includes nearby scenery.
5. Miss every target. Confirm the Projectile returns to its pool after **Lifespan**.
6. Test an arrow against a uniform moving target and a nonuniform target. Confirm only the supported target becomes its parent, and verify the explicit delayed or project-owned cleanup.
7. Reuse the same prefab repeatedly. Confirm its Collider, parent, layer, particles, trail, impact state, ownership, position, and lifespan reset before every shot.
8. With multiplayer enabled, repeat as owner, server, and observer. Confirm one authoritative impact and destruction result, one remote visual, and correct network-pool return.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The projectile is null, does not move, or throws when fired | Projectile Shooter is paired with Basic Projectile, **Spawn Projectile > Projectile** is empty, or the prefab lacks `Projectile` on its root. | Pair Projectile Shooter with Spawn Projectile, assign the prefab, and keep Projectile on the root. |
| A generated Projectile logs a collision warning and changes to Collide | Object Manager left **Collision Mode Reflect** while **Destroy On Collision** starts enabled. | Set **Collide** explicitly for a one-hit shot. Disable collision destruction only with a tested alternative cleanup policy. |
| The shot hits the wrong layers | Shooter **Impact Layers** are being treated as the flight collision mask, or prefab **Impact Layers** are overwritten at initialization. | Use the Shooter mask for aiming and pre-spawn obstruction; configure **Default Impact Damage Data** and **Use Object Impact Layer And Surface** for the moving Projectile. |
| Damage or effects occur twice | Generic Shootable Impact and Projectile **Internal Impact** both contain gameplay actions. | Choose one result owner, normally Generic Shootable Impact, and disable the other path. |
| `OnObjectImpact` never arrives | The legacy workflow assumed every collision emitted the event. Released Version 3 sends it only when a configured Impact Action, such as Impact Event, invokes it. | Add the appropriate Impact Action and enable its source or target callback. Use Projectile's C# `OnImpact` or **On Collision Event** for direct collision observation. |
| An arrow disappears instead of sticking | **Destroy On Collision** is enabled, the target layer is outside **Sticky Layers**, or Collision Mode is not Collide. | Disable collision destruction, use Collide, include the target layer, and test its scale and parenting. |
| A stuck arrow or bouncing shot never disappears | Its first hit canceled Projectile's Lifespan and no destruction event was scheduled. | Give a stuck arrow a positive Destruction Delay, or add project-owned cleanup. For a timed bounce independent of first contact, use project-owned cleanup rather than Destruction Delay. |
| A stopped arrow does not follow the moving target | The target Transform has nonuniform scale, so ProjectileBase does not parent to it. | Use a uniform-scale attachment transform or handle attachment in project code. |
| The first bounce disables later collider interactions | **Disable Collider On Impact** remains enabled. | Disable it for a tested multi-contact setup when the Collider itself must remain active. |
| A pass-through Projectile never returns after Lifespan | **Ignore**, **Destroy On Collision** disabled, and zero Destruction Delay leave no destruction condition; any earlier contact also canceled Lifespan. | Return it from project code or use a one-hit configuration. A positive delay starts from the first contact, not from launch. |
| A spawned Explosion or effect is missing | **Spawned Objects On Destruction** is empty, its probability is below `1`, or destruction never occurs. | Assign the tested prefab, use probability `1` for a guaranteed result, and verify the Projectile's cleanup path. |
| A delayed Explosion appears at the old impact point | Destruction was scheduled from a collision before the target moved. Released Version 3 retains that original `RaycastHit` point and normal. | Use immediate destruction for that result, or implement project cleanup that spawns from the Projectile's current Transform. |
| **Wait For Particle Stop** does not preserve a child effect | ProjectileBase searches only the Projectile root for Particle System and waits its main Duration; child systems and Trail Renderer lifetime are not included. | Put the coordinating Particle System on the root or use project-owned effect cleanup. |
| **Projectile Enable Delay After Other Use** has no effect | Projectile Shooter serializes the default `0.4` field but does not read it in released Version 3. | Coordinate dual-item timing with Use Rate, animation events, or project code. |
| Weapon-source conditions fail only for moving projectiles | Projectile Shooter clears the direct Shootable Action reference before **Check Weapon Source Category** and **Check Weapon Source Definition** evaluate. | Avoid those filters unless **Allow Non Weapon Impact** matches the design; use projectile/target conditions or a project-fixed Shooter module. |
| A network shot duplicates or disappears | The prefab is not registered with the network pool or custom spawning also runs on observers. | Register the prefab with the installed integration, keep impacts authoritative, and do not independently spawn the same shot on remote roles. |

## Saving, pooling, and multiplayer

The prefab stores trajectory, collision, impact, destruction, lifetime, particle, and audio configuration. Current position, velocity, parent, ignored owner, remaining lifetime or destruction delay, impact state, and active visual state are runtime data. Save the durable gameplay result and deliberately respawn or discard in-flight projectiles around a load boundary rather than expecting a flight to resume.

Projectile destruction uses `ObjectPoolBase`. With the supported multiplayer integration enabled, Projectile Shooter spawns through `NetworkObjectPool`, non-server local instances defer to the server, and ProjectileBase restricts network destruction to the server. Prefab registration, custom-module replication, save behavior, and authoritative damage remain integration or project responsibilities.

## Related tasks

- [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) configures Shooter, Projectile, ammo, clip, impact, feedback, and reload modules.
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) explains shared movement, collision, settling, and preview settings.
- [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) configure damage, force, surface effects, and callbacks.
- [Damage Processor](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/) configures project-specific damage rules.
- [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) configures an area result spawned on destruction.
- [Magic Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/magic-projectile/) connects the same runtime Projectile to a Magic Action.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reusable object ownership.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains Event System registration and cleanup.

## Developer reference

`Projectile` derives from `ProjectileBase` and adds `Lifespan`. ProjectileBase exposes `Initialize(...)`, `InitializeProjectileProperties(...)`, `Destruct(...)`, `OnImpact`, and `OnDestruct`. Trajectory Object exposes movement, collision, force, and simulation members.

`ProjectileShooter` implements `IProjectileOwner`. Its `Owner` is the character, `SourceComponent` is the Character Item Action, and `DamageSource` is the Shootable Action. `OnProjectileImpact` associates the collision with the Shootable Action and invokes `ShootableAction.OnFireImpact`; its `OnProjectileDestruct` callback is intentionally empty.

Base **On Collision Event** is a UnityEvent receiving the physical `RaycastHit`. `OnObjectImpact` is an Opsive Event System callback produced only by configured Impact Actions. Spawn Projectile also publishes `OnShootableWeaponShowProjectile(GameObject, bool)` when a loaded projectile is shown or hidden. Subscribe and unsubscribe C# or [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) listeners with the pooled object's lifecycle.

---

<a id="page-ultimate-character-controller-objects-trajectory-object-shell"></a>

# Shell

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/shell/)

Shell creates a cosmetic casing that ejects from a Shootable Action, follows a small kinematic arc, bounces, settles, and returns to the object pool. Use it for firearm feedback, not for the fired round, ammo state, damage, or another authoritative gameplay result.

## Before you begin

- Create or select a [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/). The standard Shootable recipe already includes **Shell Effect** in its **Fire Effects Module Group**.
- Prepare a small casing model with its pivot and scale suitable for a solid Capsule, Sphere, or Box Collider.
- Make sure every enabled item perspective has a visible object and a transform where the casing should appear.
- Decide whether impacts need [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) feedback. The generated Audio Source does not assign a clip by itself.

Shell is presentation-only. Keep the projectile, impact modules, inventory, and server-authoritative damage responsible for gameplay.

## Build the Shell prefab

1. Open **Tools > Opsive > Ultimate Character Controller > Object Manager**.
2. In **Object Builder**, enter a **Name**, set **Object Type** to **Shell**, and assign the casing model to **GameObject**.
3. Select **Build Object**, save the prefab under the project's `Assets` folder, and open the generated prefab.
4. Confirm that the root contains **Rigidbody**, **Capsule Collider**, **Shell**, and **Audio Source**. Object Manager sets the Audio Source to **Spatial Blend** `1` and **Max Distance** `10`.
5. Resize the Capsule Collider to the casing, or replace it with a solid Sphere or Box Collider when that is a closer fit. Trajectory Object ignores trigger colliders and uses a raycast when it cannot find one of those supported solid shapes.
6. Leave **Initialize On Enable** disabled when **Shell Effect** launches the prefab. Keep **Mass** and **Start Velocity Multiplier** at their released Version 3 defaults of `1` unless the effect needs deliberate speed scaling.
7. Keep **Collision Mode** at its default **Reflect** for ordinary casing bounces. Configure **Impact Layers**, optional **Surface Impact**, and the collider's Physics Material for the intended floors and walls.
8. In the **Shell** foldout, start with **Lifespan** `10` and **Persistence** `1`. Lifespan controls normal cleanup. Persistence controls whether a low-speed impact can shorten that remaining life.
9. Leave **Active Audio Clip Set** empty unless the casing needs a sound while it is moving. It is stopped by the first physical hit. Use **Surface Impact** or **On Collision Event** for collision-specific feedback.

The Rigidbody only notifies Unity that the casing is not static; it does not move the casing. Shell makes it kinematic, freezes its constraints, and lets [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) update the transform.

## Connect the Shootable Action

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager** and select the Character Item with the Shootable Action.
2. Expand the Shootable Action's **Fire Effects Module Group**. Enable **Shell Effect**, or add it if this item was built without the standard Shootable recipe.
3. Assign the generated prefab to **Shell**.
4. Assign **Shell Location** for every enabled perspective. Place each transform at the ejection port and rotate it to give the spawned casing the intended initial orientation.
5. Set **Shell Velocity**. Its default randomized range is `(3, 0, 0)` to `(4, 2, 0)`. These values use the active visible object's local axes, so the default moves mainly along local positive X with some positive Y variation.
6. Set **Shell Torque**. Its default range is `(-50, -50, -50)` to `(50, 50, 50)`.
7. Keep **Shell Eject Delay** at its default `0` for immediate ejection, or use a short tested delay when the casing should appear at a particular frame of the firing animation.

Shell Effect does not have **Inherit Character Velocity**. It transforms only the randomized **Shell Velocity** by the active visible object, so the character's current movement velocity is not added to the casing.

## Choose the presentation

| Goal | Configure | Result |
| --- | --- | --- |
| Consistent firearm ejection | Use a narrow **Shell Velocity** and **Shell Torque** range | Casings leave in a predictable direction with modest variation. |
| More varied brass motion | Widen the velocity and torque ranges, then test the active visible object's axes | Each casing starts differently; hard hits also add random torque. |
| Long-lived floor dressing | Keep **Persistence** at `1` and choose an appropriate **Lifespan** | Soft impacts do not shorten the normal lifetime. |
| Clear busy scenes sooner | Lower **Persistence** | A low-speed impact has a greater chance to move cleanup earlier. |
| Audible contact | Assign **Surface Impact** for the intended surface types | Each valid physical hit can use Surface System feedback. |
| Looping flight sound | Assign **Active Audio Clip Set** | Audio starts on initialization and stops on the first valid physical hit, even when the casing reflects and keeps moving. |

**Shell Location** controls spawn position and orientation, but released Version 3 calculates ejection direction from the active visible object's transform rather than from Shell Location. Rotating only Shell Location therefore does not rotate **Shell Velocity**.

## How it runs

1. When the Shootable Action fires, it invokes every enabled Fire Effects module. Shell Effect schedules ejection using **Shell Eject Delay**.
2. At ejection time, the module resolves the current perspective's **Shell Location** and obtains the prefab from `ObjectPoolBase` at that position and rotation.
3. If the root has a Shell component, the module chooses random velocity and torque values. It converts velocity from the active visible object's local axes to world space and initializes the casing with the character as owner.
4. Trajectory Object resolves the character's gravity direction and local time scale, ignores the owner's hierarchy during its initial collision check, starts active audio, and simulates the supported Collider. It divides the supplied velocity by **Mass** multiplied by **Start Velocity Multiplier**.
5. A physical hit stops active audio, applies optional surface feedback, invokes **On Collision Event**, and reflects according to the Collider materials and **Reflect Multiplier**. A hit above a velocity magnitude of `2` adds random torque.
6. On a lower-speed hit, a random test against **Persistence** can shorten cleanup. A value of `1` never takes this early-removal branch; lower values make it progressively more likely.
7. At **Lifespan**, the casing begins shrinking and returns through `ObjectPoolBase.Destroy` half a second later. A lower-speed early-removal decision first sets the removal time to half a second after that hit, so pool return occurs about one second after the hit. Reuse restores the original scale and enables the Collider.

## Editor checkpoint

Before Play Mode, confirm that:

- Rigidbody, Shell, and one supported solid Collider are on the prefab root;
- **Initialize On Enable** is disabled, **Mass** and **Start Velocity Multiplier** are positive, and **Collision Mode** is **Reflect**;
- **Impact Layers** include the intended floors and walls, while **Surface Impact** and audio are configured only when needed;
- **Lifespan** and **Persistence** match the desired casing count and cleanup rate;
- **Shell Effect** is enabled in Fire Effects and its **Shell** field references this prefab;
- every enabled perspective resolves a valid **Shell Location**;
- the active visible object's local X and Y axes make the configured **Shell Velocity** leave the weapon in the intended direction; and
- **Shell Eject Delay** remains short enough that the same item and perspective are still active when the callback runs.

## Verify with a firearm in Play Mode

1. Equip the firearm while stationary and fire once. Confirm exactly one casing appears at the active perspective's Shell Location and leaves mainly along the visible object's local positive X direction.
2. Fire several times. Confirm **Shell Velocity**, **Shell Torque**, gravity, and hard-impact random torque create controlled variation without spawning inside the weapon or character.
3. Switch between first and third person and fire again. Confirm each perspective uses its own Shell Location and the same Shell prefab.
4. Walk or run while firing. Confirm the casing starts at the moving ejection point but does not add the character's movement velocity. Adjust the local velocity range or use a custom module if movement inheritance is required.
5. Hit an included surface, an excluded layer, and a trigger-only Collider. Confirm only supported included contacts reflect and produce the configured surface or collision-event feedback.
6. Compare **Persistence** `1` with `0` across several low-speed impacts. Confirm `1` keeps the normal Lifespan, while `0` normally schedules the shorter cleanup path.
7. Wait beyond **Lifespan**. Confirm the casing shrinks, returns to the pool, and reappears at full scale with an enabled Collider on the next shot.
8. In a multiplayer test, compare owner and observer. Confirm shell feedback appears where the integration invokes the fire effect, but do not require identical bounce paths or use the casing as an authoritative result.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| No casing appears | **Shell Effect** is disabled, **Shell** is empty, or **Shell Location** does not resolve for the active perspective. | Enable the module, assign the prefab, and assign a location for every enabled perspective. |
| The object appears but does not move | The prefab root does not have Shell. Shell Effect still instantiates the assigned GameObject, but it initializes motion only when it finds that component. | Build or repair the prefab so Shell and a supported solid Collider are on its root. |
| The casing ejects in the wrong direction | **Shell Velocity** is interpreted in the active visible object's local axes, not Shell Location's axes. | Inspect the visible object's local axes and change the velocity range. Use a corrected parent or custom module when the model axes cannot be changed safely. |
| Rotating Shell Location changes orientation but not the path | Released Version 3 uses Shell Location for spawn pose, then uses the active visible object for `TransformDirection`. | Treat Shell Location as the spawn pose and tune velocity against the visible object's axes. |
| Casings trail behind a moving character | Shell Effect does not add character velocity and has no inheritance setting. | Increase the local ejection velocity for presentation, or implement a custom fire-effect module that deliberately adds character velocity. |
| Ejection fails after a delay or perspective change | The scheduled callback is not retained or canceled by Shell Effect, and it resolves Shell Location plus the active visible object when the delay expires. | Keep the delay within the active firing sequence and maintain valid perspective references. Use an animation-timed custom module for a long or cancelable delay. |
| The casing passes through or misses a surface | The Collider is a trigger, the shape is unsupported, **Impact Layers** excludes the surface, or the casing is too small or fast for the configured cast. | Use a solid Sphere, Capsule, or Box Collider sized to the model, include the layer, and test the velocity range. |
| Initial speed becomes invalid or unexpectedly low | **Mass** or **Start Velocity Multiplier** is zero or large. Released Version 3 divides velocity by their product despite the multiplier wording. | Keep both values positive, normally `1`, and tune **Shell Velocity** first. |
| The casing makes no sound | Object Manager added an Audio Source but **Active Audio Clip Set** and **Surface Impact** start empty. | Assign the intended clip set or surface feedback. Use Surface Impact or On Collision Event for bounce sounds. |
| A looping sound stops while the casing is still bouncing | Trajectory Object stops **Active Audio Clip Set** on the first valid physical hit. | Reserve Active Audio for flight, and use collision feedback for later bounce sounds. |
| Casings disappear too early or remain too long | **Persistence** was treated as a settle duration or removal percentage. It is a probability check on lower-speed impacts; Lifespan is still the normal timer. | Use **Lifespan** for the overall maximum and test Persistence statistically with repeated low-speed contacts. |
| Peers show different resting positions | Shell adds random torque and its kinematic trajectory is not synchronized. | Treat casings as local presentation and keep gameplay impacts, ammo, and damage authoritative elsewhere. |

## Saving, pooling, and multiplayer

The prefab stores its trajectory, collision, audio, **Lifespan**, and **Persistence** settings. Shell Effect stores the prefab, velocity and torque ranges, delay, and perspective locations. Current position, velocity, torque, owner, random choices, remaining lifetime, and scale are transient runtime state. Do not save individual active casings; discard them across a load boundary and let later shots create new presentation objects.

Shell uses `ObjectPoolBase` for spawn and return. A supported multiplayer integration can relay the Shootable Fire Effects module invocation so each peer creates presentation locally, but the Shell path does not network-synchronize its position, random torque, collision, or removal. Do not register gameplay listeners that make a Shell collision authoritative.

## Related tasks

- [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) configures firing, ammo, projectiles, fire effects, impacts, and reload.
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/) explains shared kinematic movement, collision, settling, and preview behavior.
- [Object Manager](https://opsive.com/support/documentation/ultimate-character-controller/objects/objects/) creates the starting casing prefab.
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) configures material-specific collision feedback.
- [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/) explains shared audio configuration.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reusable object ownership.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains Event System registration and cleanup.

## Developer reference

`Shell` derives from `TrajectoryObject`. It overrides `Awake`, `OnEnable`, `Move`, and `OnCollision`; movement initialization remains the inherited `Initialize(Vector3 velocity, Vector3 torque, GameObject owner)` path. Shell has no damage or ammo interface and exposes no shell-specific runtime event.

`ShellEffect` derives from `ShootableFireEffectModule` and exposes `Shell`, `ShellVelocity`, `ShellTorque`, `ShellEjectDelay`, and `ShellLocation`. `InvokeEffects` schedules `EjectShell`; that callback uses `ObjectPoolBase.Instantiate`, resolves the current perspective, and initializes the root Shell. The scheduled handle is not stored, so the built-in module has no cancellation path for delayed ejection.

Trajectory Object's **On Collision Event** is a UnityEvent receiving the physical `RaycastHit`. Its active-audio, Surface Impact, and owner time-scale behavior are inherited by Shell. Register and unregister project listeners with the pooled object's lifecycle.

---

<a id="page-ultimate-character-controller-moving-platforms"></a>

# Moving Platforms

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/)

Moving Platform keeps elevators, trains, doors, and other moving surfaces synchronized with the Ultimate Character Controller character. Use it for a waypoint-driven object; use Animator Update when an Animator drives the motion.

## Before you begin

- Prepare the scene and its managers with [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/).
- Confirm that the project has the required `MovingPlatform` layer in the [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/).
- Decide which transform will actually move. Put its visible geometry and solid colliders on that transform.

Set the component GameObject, and any separate child surface collider that the character can stand on, to the `MovingPlatform` layer. The component warns and corrects its own GameObject at runtime, but it does not change child layers.

![The moving platform GameObject uses the MovingPlatform layer.](https://opsive.com/wp-content/uploads/2018/03/MovingPlatformLayer.webp?v=00e9020987bb)

## Build a waypoint platform

1. Create an empty GameObject to hold the route. Leave this container stationary.
2. Add the platform object and its colliders as a child of the route container.
3. Add the **Moving Platform** component to the platform object. Unity also adds the required Rigidbody; the component configures that Rigidbody for its synchronized movement.
4. Create one GameObject for each destination. Keep these waypoints beside the platform object under the stationary route container, not below the moving object.
5. Position and rotate each waypoint. Place the first waypoint at the platform's starting pose unless the platform should travel there when Play Mode begins.
6. Open **Path** on the Moving Platform component. Add rows and assign each **Transform** in travel order.
7. For each waypoint, optionally set **Delay** and **State**. The state becomes active when that waypoint is the destination and remains active through its delay, until another destination is selected.
8. Choose **Direction** and **Movement Type**, then open **Movement** to set the speed and interpolation.

![A stationary Moving Platform route container with the moving Object and three sibling waypoint GameObjects.](https://opsive.com/wp-content/uploads/2018/03/MovingPlatformSetup.webp?v=5a41a0f4514c)

The Scene view draws the waypoint poses and connecting route. Under **Editor**, enable **Draw Debug Labels** to include the delay and distance labels while tuning the path.

## Choose the route behavior

| Scenario | Movement Type | What it does |
| --- | --- | --- |
| Elevator, shuttle, or sliding door | **Ping Pong** | Travels to the last waypoint, reverses, and follows the same route back. |
| Train or continuously circulating platform | **Loop** | Travels through the list and then takes a direct segment from the last waypoint to the first. |
| Called elevator or scripted destination | **Target** | Follows the waypoint sequence until it reaches **Target Waypoint**, then stops there. |
| Unpredictable destination | **Random** | Selects a waypoint at random after each delay. Use **Random Seed** for a repeatable sequence, or `-1` to leave the random sequence unseeded by this component. |

**Direction** controls whether the route begins by increasing or decreasing the waypoint index. In **Target** mode, choose the direction that leads through the intended intermediate stops.

## Tune movement and rotation

- Start with **Movement Speed** `0.1`, **Movement Interpolation** **Ease In Out**, and **Rotation Interpolation** **Sync To Movement** for a smooth passenger platform.
- Choose **Ease In** or **Ease Out** when only the departure or arrival should be softened. **Ease Out 2**, **Slerp**, and **Lerp** provide alternative path interpolation when the standard easing does not fit the motion.
- **Sync To Movement** blends between waypoint rotations as the platform travels. **Ease Out** and **Custom Ease Out** let the rotation settle independently; the latter reveals **Rotation Ease Amount**.
- Choose **Custom Rotate** for a continuously revolving object and set **Custom Rotation Speed**. This rotation mode also works without waypoints.
- **Max Rotation Delta Angle** limits the rotation applied in one simulation step. Keep `-1` when no limit is required.

Do not animate or otherwise move the same transform independently while the Moving Platform component controls it.

## Start or change the platform through gameplay

Open **Interaction** on the Moving Platform component for these options:

- Enable **Enable On Interact** when the platform should remain stopped until the character activates it. Add an **Interactable** component to the scene object, include Moving Platform in its **Targets**, and configure the character's [Interact ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/).
- Enable **Change Directions On Interact** when an already-moving platform should reverse. Use this instead of **Enable On Interact**; when both are enabled, starting the platform takes precedence and the interaction does not reverse it.
- Add a trigger Collider and set **Character Trigger State** when standing on the platform should activate a [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) state on the platform. **Character Trigger Layer** determines which colliders count. The first matching collider enables the state and the last one to leave disables it.

The **State** beside each waypoint is a separate route state: it is active while that waypoint is the current destination. Use route states for direction-specific effects and the trigger state for effects that depend on a character being aboard.

## Use Animator-driven motion

When an Animator controls the platform, add **Animator Update** to the animated root instead of Moving Platform. Animator Update advances the Animator through the Ultimate Character Controller simulation so the character and camera receive synchronized motion.

Set the GameObject of each moving surface collider to the `MovingPlatform` layer. Assign **Moving Children** only when the Animator moves child transforms while its root stays in place; list each child whose position and rotation must be smoothed.

## How the character follows the platform

While grounded, Character Locomotion recognizes a surface collider whose hit transform is on the `MovingPlatform` layer and tracks that transform's position and rotation. The character is not reparented, so its own locomotion and jump behavior continue to run normally. The collider the character stands on must move with the same transform hierarchy that Moving Platform or Animator Update synchronizes.

## Verify in Play Mode

1. Enter Play Mode without the character on the platform. Confirm that the platform visits the waypoint positions and rotations in the selected order, pauses for each **Delay**, and follows the expected loop, reversal, target, or random behavior.
2. Watch the component in the Inspector. In the Scene view, the green route line identifies the current destination while the component is enabled.
3. Step onto the platform. The character should remain stable relative to its surface while still accepting movement and jump input.
4. If interaction is enabled, activate the configured Interactable and confirm that the platform starts or reverses according to the selected option.
5. If a waypoint or trigger state is configured, confirm that the state becomes active only during its intended route or occupancy condition.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The platform does not move. | The **Waypoints** list is empty, contains a missing transform, **Movement Speed** is zero, **Target Waypoint** is already reached, or **Enable On Interact** started the component disabled. | Assign every waypoint, use a positive speed, select a different valid target, or trigger the configured Interactable. A missing waypoint disables the component when Play Mode starts in the Unity Editor. |
| The character jitters, slides, or does not follow. | The moving surface is not on the `MovingPlatform` layer, its collider is outside the synchronized hierarchy, or two systems drive the same transform. | Set up the required layer, move the collider with the synchronized object, and use either Moving Platform or Animator Update as the movement driver. |
| Loop mode takes an unwanted shortcut. | **Loop** connects the last waypoint directly to the first. | Add waypoints along the return route or use **Ping Pong**. |
| Interact starts the platform but never reverses it. | Both **Enable On Interact** and **Change Directions On Interact** are enabled. | Keep only the behavior required for this platform, or switch the option from another script after it starts. |
| A character trigger state never activates. | The platform has no trigger Collider, **Character Trigger Layer** excludes the character collider, or the state name is not configured on the platform. | Add a trigger to the platform's Rigidbody hierarchy, include the character layer, and add a matching state to the Moving Platform component. |

## Related pages

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/)
- [Interact](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

`MovingPlatform` implements `IInteractableTarget` and `ISmoothedObject`. Its commonly useful public members include `Waypoints`, `Direction`, `MovementType`, `TargetWaypoint`, `MovementSpeed`, `MovementInterpolation`, `RotationInterpolation`, `CharacterTriggerLayer`, `CharacterTriggerState`, `EnableOnInteract`, `ChangeDirectionsOnInteract`, `NextWaypoint`, and `ActiveCharacterCount`.

### Released defaults

| Inspector area | Default configuration |
| --- | --- |
| **Path** | **Direction** is **Forward**, **Movement Type** is **Ping Pong**, **Target Waypoint** is `0`, and **Random Seed** is `0`. A new waypoint has **Delay** `0` and a blank **State**. |
| **Movement** | **Movement Speed** is `0.1`, **Movement Interpolation** is **Ease In Out**, **Rotation Interpolation** is **Sync To Movement**, **Rotation Ease Amount** is `0.1`, **Custom Rotation Speed** is `(0, 0, 0)`, and **Max Rotation Delta Angle** is `-1`. |
| **Interaction** | **Character Trigger Layer** contains the Character layer, **Character Trigger State** is blank, and both interaction toggles are off. |
| **Editor** | **Gizmo Color** is translucent blue and **Draw Debug Labels** is off. |

At startup, Moving Platform configures its required Rigidbody as kinematic with **Discrete** collision detection and frozen constraints. The Rigidbody reports movement and collisions to Unity; it is not the movement driver.

The component has no dedicated arrival or departure event. For data-driven responses, use the waypoint **State** or **Character Trigger State** fields. Code can inspect `NextWaypoint` and `ActiveCharacterCount`, or set a target at runtime:

```csharp
using Opsive.UltimateCharacterController.Objects;

public void SendPlatformTo(MovingPlatform platform, int waypointIndex,
                           MovingPlatform.PathDirection direction)
{
    if (platform == null || platform.Waypoints == null ||
        waypointIndex < 0 || waypointIndex >= platform.Waypoints.Length) {
        return;
    }

    platform.Direction = direction;
    platform.MovementType = MovingPlatform.PathMovementType.Target;
    platform.TargetWaypoint = waypointIndex;
    platform.enabled = true;
}
```

Character Locomotion normally attaches automatically from the grounded `MovingPlatform` layer check. For a special attachment that does not use that grounded check, call `CharacterLocomotion.SetMovingPlatform(transform, true)` and later pass `null` with the override argument to release it.

---

<a id="page-ultimate-character-controller-layer-manager"></a>

# Layer Manager

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/)

Set up the UCC layers before building characters so movement, targeting, first-person rendering, child colliders, effects, and moving platforms use the intended collision rules.

## Before you begin

The released Version 3 package reserves Unity user-layer indices 26 through 31. Check **Edit > Project Settings > Tags and Layers** before applying the defaults, especially in a project that already has gameplay layers.

Commit or back up `ProjectSettings/TagManager.asset` and the affected prefabs or scenes first. A Unity layer is stored as an index, so renaming or moving a layer can change the meaning of every GameObject and LayerMask that uses it.

## Required layers

| Index | Exact layer name | Main UCC use |
| ---: | --- | --- |
| 26 | `Enemy` | Default target layer for **Enemy Layers**, Crosshairs Monitor, and Assist Aim. |
| 27 | `MovingPlatform` | Marks moving platforms so locomotion and trajectory objects can preserve platform-relative movement. |
| 28 | `VisualEffect` | Keeps projectiles, dropped reload clips, explosions, decals, and other temporary effects out of character and item collision queries. |
| 29 | `Overlay` | Holds first-person arms, items, muzzle flashes, and other objects rendered by the first-person overlay path. |
| 30 | `SubCharacter` | Holds most character children and secondary colliders so they do not interfere with the main locomotion collider. |
| 31 | `Character` | Holds the character root and primary character colliders used by triggers, moving platforms, and character queries. |

These names have no spaces. UCC runtime code uses the fixed indices, while the names make the assignments readable in the Unity Editor.

## Apply the defaults in a new project

1. Open **Edit > Project Settings > Tags and Layers** and confirm that user layers 26 through 31 are empty or already contain the exact UCC names above.
2. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and select **Project**.
3. Under **Layers**, select **Update Layers**. A new project can instead use **Update Buttons and Layers** for the Built-in Render Pipeline or **Update Buttons, Layers, and Render Pipeline** for URP or HDRP.
4. Return to **Tags and Layers** and verify all six indices. The update action fills only empty entries; it does not replace a different name already stored in a slot.
5. In **Setup Manager > Scene**, select **Add Managers** under **Manager Setup**. The **Game** GameObject should now contain **Layer Manager**.
6. Create or update the character with the [Character Manager](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/). It assigns the character root and primary colliders to `Character`, and most other children to `SubCharacter` while preserving first-person and item-placement objects that need special handling.

Run this project setup before creating characters, items, moving platforms, or trajectory objects. Their builders serialize layer indices and masks when they create those objects.

## Recover occupied layer slots

Do not select **Update Layers** expecting it to replace an existing layer. If any slot from 26 through 31 belongs to another system, choose one of these recovery paths before building UCC content:

### Migrate the existing project layers

This is usually the safer long-term option because UCC can keep its released defaults.

1. Identify every GameObject, prefab, scene, LayerMask, physics query, camera culling mask, and project collision setting that uses the occupied index.
2. Create a replacement user layer in a free index.
3. Reassign the affected objects and masks to that replacement.
4. Rename indices 26 through 31 to the exact UCC names.
5. Reopen representative prefabs and scenes to confirm that no serialized mask still points at the old index.

Version-control the migration as one reviewable change. Renaming a layer does not move the objects that used its index.

### Maintain custom UCC indices

If the existing indices cannot move, embed or otherwise maintain a controlled copy of the Version 3 package and change the custom constants in `Game/LayerManager.cs`. Create matching layer names at the new indices, then rebuild or audit every existing character, item, effect, moving platform, prefab, and serialized LayerMask.

This is an advanced maintenance choice: package updates can restore the released constants, and existing serialized values do not automatically follow a source-code change. Changing only **Character Layer Manager > Character Layer** at runtime is not a complete layer-index migration because other UCC systems also read the static `LayerManager` indices.

## Configure each character's masks

The Character Manager adds **Character Layer Manager** to each character. Its three editable masks answer different questions:

- **Enemy Layers** identifies valid enemies for systems such as Crosshairs Monitor and Assist Aim. Its default is `Enemy` only. Add another project layer here when that layer should also count as a target.
- **Invisible Layers** identifies layers that character, camera, aiming, and crosshairs raycasts should look through. The default contains `TransparentFX`, `Ignore Raycast`, `UI`, `VisualEffect`, `Overlay`, and `SubCharacter`.
- **Solid Object Layers** identifies surfaces that block or support locomotion and related abilities. The default includes every layer except `Ignore Raycast`, `Water`, `UI`, `VisualEffect`, `Overlay`, and `SubCharacter`.

"Invisible" here means ignored by the relevant physics queries; it does not change Renderer visibility. The invisible and solid masks are independent. For example, a transparent object can be ignored by a camera query while still remaining solid for locomotion if the masks deliberately say so.

At runtime, **Character Layer Manager > Character Layer** is derived from the actual layer of the character GameObject during `Awake`. Keep the character root and its primary collider hierarchy consistent instead of using that runtime value to compensate for incorrect project-layer setup.

## Runtime collision rules

The scene **Layer Manager** applies these global `Physics.IgnoreLayerCollision` pairs in `Awake`:

| Layer | Does not collide with |
| --- | --- |
| `VisualEffect` | `Ignore Raycast`, `VisualEffect` |
| `SubCharacter` | `Default`, `VisualEffect` |
| `Overlay` | `Default`, `VisualEffect`, `Enemy`, `SubCharacter`, `Character` |

These are runtime rules; **Update Layers** does not rewrite the collision matrix displayed in Project Settings. **Setup Manager > Scene > Add Managers** places Layer Manager on the **Game** GameObject. If it is missing, Character Layer Manager calls `LayerManager.Initialize()` and creates a fallback **LayerManager** GameObject, but keeping the manager on **Game** makes scene setup explicit and easier to verify.

## Practical scenarios

- **Enemies use an existing project layer:** Keep that layer and add it to each relevant character's **Enemy Layers** mask. Use the reserved `Enemy` layer only where the fixed UCC default is useful.
- **An invisible stair ramp should guide locomotion:** Put it on a layer included in **Invisible Layers** but also included in **Solid Object Layers**. Camera and aim queries can look through it while the character still walks on it.
- **Water should be visible but not ground:** The default solid mask excludes Unity's `Water` layer. Add or remove it only when the game's water geometry should physically support the character.
- **A platform should carry the character:** Add **Moving Platform** to the platform object. The Moving Platform component warns and corrects the layer at runtime, but the prefab should be correct before Play Mode.
- **Ragdoll or model colliders push the main capsule:** Keep secondary character objects on `SubCharacter`; keep the root and primary locomotion colliders on `Character`.
- **First-person arms or weapons interact with world physics:** Verify they use `Overlay` and that the first-person View Type and camera culling masks still use the released overlay index.

## Verify in Play Mode

1. Confirm that **Game** has an enabled **Layer Manager** component and that no unexpected fallback LayerManager GameObject appears.
2. Select the character. Its root and primary collider objects should use `Character`; ordinary model children and secondary colliders should use `SubCharacter` unless a first-person or item component requires another layer.
3. Walk over Default-layer ground, slopes, steps, and any custom ground layer. The character should stay grounded and should not pass through a layer included in **Solid Object Layers**.
4. Step onto a `MovingPlatform` object. The character and a resting trajectory object should preserve platform-relative motion without a layer warning in the Console.
5. Aim at an object included in **Enemy Layers**. Crosshairs or Assist Aim should recognize it; an object outside that mask should not be treated as an enemy.
6. Spawn a projectile, reload clip, muzzle flash, or other effect. `VisualEffect` and `Overlay` objects should not block or push the character.
7. Switch between first- and third-person views when both are available. First-person overlay objects should render through the intended camera path without appearing as world collision.
8. Test respawn and ragdoll. The primary and secondary collider layers should return to their intended states.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **Update Layers** finishes but a required name is missing. | The target index already contains another layer name. | Resolve the occupied index, then rename it or rerun **Update Layers** after it is empty. Verify all six indices manually. |
| The character falls through ground or cannot move through open space. | **Solid Object Layers** may omit the ground layer or include a non-solid helper/effect layer. | Add real ground layers and remove layers that should not block locomotion. |
| Crosshairs or Assist Aim does not recognize a target. | The target's layer may be absent from **Enemy Layers**. | Add the target layer to the character's Enemy Layers mask or move the target to an included layer. |
| A moving platform does not carry the character. | The platform may not use layer 27 `MovingPlatform`, or that layer may have another name. | Restore the required layer and assign it to the platform prefab. |
| Child or inactive ragdoll colliders interfere with locomotion. | Those objects may use `Default` or `Character` instead of `SubCharacter`, or a custom character query mask may include `SubCharacter`. | Correct the child layers and exclude `SubCharacter` from the relevant collider and solid-object masks. |
| First-person arms or items disappear, render in the world camera, or collide with the character. | Their layer or the View Type culling masks may not use `Overlay`. | Restore layer 29 `Overlay`, update the affected objects, and verify the first-person camera setup. |
| Effects stop projectiles or block movement. | The effect object may not use `VisualEffect`, or a custom mask may include it. | Assign `VisualEffect` and exclude it from the relevant impact or solid masks. |
| A custom layer-index fork breaks after updating UCC. | `LayerManager.cs` constants or serialized masks may have returned to released values. | Reapply the maintained package change and audit existing serialized layers before opening or saving production scenes. |

## Related pages

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Moving Platforms](https://opsive.com/support/documentation/ultimate-character-controller/moving-platforms/)
- [First Person View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)

## Developer reference

`Opsive.UltimateCharacterController.Game.LayerManager` exposes the built-in and custom indices through static properties such as `Default`, `IgnoreRaycast`, `Water`, `UI`, `Enemy`, `MovingPlatform`, `VisualEffect`, `Overlay`, `SubCharacter`, and `Character`.

Use `LayerManager.IgnoreCollision(mainCollider, otherCollider)` when a temporary collision exclusion should be tracked by UCC. Later, `LayerManager.RevertCollision(mainCollider)` restores every active collider pair recorded for that main collider. This bookkeeping is separate from the global layer-pair rules installed in `Awake`.

`CharacterLayerManager` exposes `EnemyLayers`, `InvisibleLayers`, `SolidObjectLayers`, and `CharacterLayer`. Its derived `IgnoreInvisibleLayers`, `IgnoreInvisibleCharacterLayers`, and `IgnoreInvisibleCharacterWaterLayers` masks are used throughout movement, camera, aiming, footstep, item, and ability queries.

```csharp
using Opsive.UltimateCharacterController.Character;
using UnityEngine;

public class AddEnemyLayer : MonoBehaviour
{
    [SerializeField] private CharacterLayerManager m_CharacterLayerManager;
    [SerializeField] private string m_AdditionalEnemyLayer = "Boss";

    private void Awake()
    {
        var layer = LayerMask.NameToLayer(m_AdditionalEnemyLayer);
        if (layer >= 0) {
            m_CharacterLayerManager.EnemyLayers =
                m_CharacterLayerManager.EnemyLayers.value | (1 << layer);
        }
    }
}
```

---

<a id="page-ultimate-character-controller-surface-system"></a>

# Surface System

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)

Use the Surface System to make the same impact produce material-appropriate feedback: a footstep can sound different on wood and metal, while a projectile can create a different sound, spawned object, or decal on those same surfaces.

## How the system matches an effect

Each result is selected from three project assets:

1. A **Surface Impact** identifies what happened, such as a footstep, projectile hit, melee hit, jump, or landing.
2. A **Surface Type** identifies what was hit, such as wood, metal, dirt, or water. Its **Impact Effects** list pairs each supported Surface Impact with a Surface Effect.
3. A **Surface Effect** is the response recipe. It can spawn objects, choose a decal, play an **Audio Config** or AudioClip, and temporarily activate a named state on the hit object.

When an impact supplies a `RaycastHit`, Surface Manager looks for a **Surface Identifier** associated with the hit collider first. If that does not provide a type, the manager tries a mapped simple texture, a mapped texture from a multi-material mesh or UV region, and then the dominant terrain texture. Its **Fallbacks** can supply a missing Surface Impact or Surface Type.

Configure surface assets and identifiers before entering Play Mode. Surface Manager caches collider, renderer, texture, and impact-to-effect lookups, so changing those relationships after they have been detected is not a reliable runtime workflow.

## Choose your route

- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/) explains scene-wide texture mappings, terrain detection, the main texture property, and fallbacks.
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) explains the identity asset assigned by a footstep, item, ability, or other impact source.
- [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/) explains the material asset and its **Impact Effects** mappings.
- [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) explains the spawned objects, decals, audio, randomness, and optional state response.
- [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/) is the recommended route for assigning a Surface Type directly to a collider or scene prefab.
- [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/) covers the scene decal limit, weathering, fadeout, and placement rejection at exposed edges.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) covers footstep detection and footprint placement on a UCC character.
- [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/) covers cached data, atlases, multiple materials, static renderers, terrain, and other detection limitations.

## Set up a surface response

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Scene** tab and choose **Add Managers** under **Manager Setup**. Confirm that the scene's **Game** GameObject has **Surface Manager** and **Decal Manager**. The setup also adds the shared Object Pool used by spawned effects.
3. Create an impact identity with **Assets > Create > Opsive > Ultimate Character Controller > Surface Impact**. Name it for the cause, such as `Footstep` or `Bullet Hit`; the asset has no settings of its own.
4. Create the feedback recipe with **Assets > Create > Opsive > Ultimate Character Controller > Surface Effect**. Add the audio, spawned objects, or decal needed for this one impact-and-material combination.
5. Create the material identity with **Assets > Create > Opsive > Ultimate Character Controller > Surface Type**. In **Impact Effects**, add the Surface Impact and the Surface Effect that should respond to it.
6. Select the scene object or reusable prefab that owns the hit collider, add **Surface Identifier**, and assign the **Surface Type**. **Allow Decals** is enabled by default; disable it when decals should not attach to this object.
7. Assign the same Surface Impact asset to the feature that causes the hit. For example, assign a footstep impact to **Character Foot Effects**, or assign the appropriate impact to the item action, projectile, jump, or fall setting that produces the hit.
8. Save the assets, prefab, and scene, then verify the complete pairing in Play Mode.

Repeat the **Impact Effects** mapping on every Surface Type that should respond to that cause. A `Bullet Hit` impact can therefore select a wood effect on a wood type and a metal effect on a metal type without changing the projectile.

## Key choices by scenario

| Scenario | Recommended configuration |
| --- | --- |
| Most props and level pieces | Add **Surface Identifier** and assign one **Surface Type**. This direct lookup is predictable and avoids texture analysis. |
| Several objects share a texture | Add the texture under Surface Manager's object-surface list and pair it with a Surface Type. Keep the direct identifier route for exceptions. |
| One atlas contains several materials | Map the same texture more than once and restrict each mapping with its **UV** rectangle. Review the static-object and collider limitations before committing to this layout. |
| Terrain uses several layers | Add each terrain layer's diffuse texture to the corresponding object-surface mapping. Surface Manager chooses the dominant texture at the hit position. Enable **Detect Terrain Tree Textures** only when tree detection is required because it performs extra work. |
| Character footsteps and footprints | Assign a footstep Surface Impact to **Character Foot Effects** and choose **Body Step**, **Trigger**, **Fixed Interval**, or **Camera Bob** for the character and perspective. The component raycasts below the detected footstep and asks Surface Manager to spawn the matched effect. |
| Projectiles, melee, jumps, and landings need different feedback | Give each cause its own Surface Impact, then map those impacts independently on every relevant Surface Type. Do not encode the hit material into the impact name. |
| Unknown impacts or surfaces still need feedback | Configure **Fallback Surface Impact** and **Fallback Surface Type** on Surface Manager. **Fallback Allow Decals** is enabled by default; disable it when an approximate match could place an unsuitable decal. |
| A busy scene accumulates decals | Decal Manager starts with **Decal Limit** `100`, **Weathered Decal Limit** `20`, and **Remove Fadeout Speed** `10`. Tune those limits for the scene. Lower **Allowed Decal Edge Overlap** on the Surface Effect when decals must sit farther inside a surface edge. |

## Verify in Play Mode

1. Place two colliders with different Surface Types, such as wood and metal, and map the same Surface Impact to a visibly or audibly distinct Surface Effect on each type.
2. Trigger the impact on the first collider. Confirm that only the effect mapped by that collider's Surface Type plays at the hit point.
3. Trigger the same impact on the second collider. The impact source should remain unchanged while the sound, spawned object, or decal changes with the Surface Type.
4. If the Surface Effect includes decals, confirm **Allow Decals** controls the identified object and that decals near an exposed edge are rejected according to **Allowed Decal Edge Overlap**.
5. If the Surface Effect includes several clips, objects, or decals, repeat the impact and confirm the configured spawn probabilities and audio or decal selection behave without creating more feedback than intended.
6. Test one missing assignment deliberately. Confirm the configured **Fallbacks** provide the expected approximate response, or that no effect is spawned when no valid pair exists.
7. For footsteps, walk across the boundary between the two surfaces. Each detected step should follow the surface beneath the foot, and footprints should appear only where the identified surface and Surface Type permit them.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| No effect plays. | The impact source has no Surface Impact, the detected Surface Type has no matching entry in **Impact Effects**, or the entry has no Surface Effect. | Assign the same Surface Impact asset at the source and in the Surface Type mapping, then assign a Surface Effect to that pair. |
| Every object produces the same effect. | Surface Manager is using **Fallback Surface Type**, or the objects share a texture mapping and have no direct identifiers. | Add **Surface Identifier** to each exception and assign the intended Surface Type. Temporarily clear the fallback while testing detection. |
| A Surface Identifier appears to be ignored. | It is not associated with the hit collider, has no **Surface Type**, or the collider relationship changed after the manager cached it. | Put the identifier on the collider object or a stable related parent/child, assign its type before Play Mode, and restart Play Mode after hierarchy changes. |
| Texture-based detection fails. | The texture is absent from Surface Manager, **Main Texture Property Name** does not match the shader, or the mesh/material arrangement cannot provide the hit material. | Add the exact texture, use the shader's main texture property, or use a Surface Identifier. See the advanced limitations for atlases, static renderers, and multiple materials. |
| A decal does not appear. | **Allow Decals**, **Fallback Allow Decals**, or the matched surface/effect prevents it; the edge test may also reject the placement. | Enable decals only on the intended route, verify the effect has a decal prefab, and test farther from an edge before adjusting overlap. |
| A decal is stretched or does not follow a moving object. | The target has non-uniform scale. Decal Manager parents decals to uniformly scaled targets and keeps other decals under the manager. | Use uniform scale on moving decal receivers, or disable decals for that object. |
| Footsteps are missing or mistimed. | **Footstep Mode**, feet, movement requirements, intervals, or the footstep Surface Impact do not match the character. | Choose the mode for the rig and perspective, assign the footstep impact, and tune the mode-specific fields while observing movement in Play Mode. |
| Edits made during Play Mode do not change later hits. | Surface Manager already cached the collider, texture, or impact mapping. | Stop Play Mode, make the asset or hierarchy change, and start a fresh test. |

## Related tasks

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)
- [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

The released Version 3 surface types are in `Opsive.UltimateCharacterController.SurfaceSystem`. Gameplay code normally calls a static `SurfaceManager.SpawnEffect` overload with a `RaycastHit`, Surface Impact, gravity direction, time scale, and originator. Overloads can provide a collider explicitly or add footprint direction and flip state. The method returns `true` only when it resolves and spawns a Surface Effect.

With a Surface Manager component reference, `GetSurfaceType(RaycastHit, Collider)` returns the detected Surface Type, and `GetSurfaceEffect(RaycastHit, Collider, SurfaceImpact, ref SurfaceType, ref bool)` exposes both the resolved type and whether the decal route remains allowed. `SurfaceIdentifier` exposes writable `SurfaceType` and `AllowDecals` properties, but set them before detection because the manager caches results.

`CharacterFootEffects.TriggerFootStep(Transform, bool)` supports explicit trigger-driven placement, while its virtual `FootStep(Transform, bool)` performs the ground raycast and forwards the result to Surface Manager. `SurfaceEffect.Spawn` and `SpawnFootprint` are virtual extension points for a custom response. `DecalManager.Spawn` and `SpawnFootprint` are the lower-level static decal entry points.

The built-in Surface System does not publish a dedicated surface-impact event. Built-in consumers such as trajectory objects, item impact actions, Jump, Fall, and Character Foot Effects call Surface Manager directly. A Surface Effect can instead configure **State Name** and **State Disable Timer** to activate a [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) state on the hit object; a timer value of `-1` leaves deactivation to another system.

---

<a id="page-ultimate-character-controller-surface-system-surface-manager"></a>

# Surface Manager

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/)

Use Surface Manager to turn a hit collider, material texture, or terrain layer into a Surface Type, then resolve the Surface Effect that matches the incoming Surface Impact. This lets one bullet, footstep, or landing source produce different feedback on wood, metal, dirt, and other materials without placing a Surface Identifier on every simple renderer.

## Before you begin

- Use the released Ultimate Character Controller Version 3 package. The source verified for this page is UCC `3.2.0`; Version 4 development behavior is outside this workflow.
- Create or choose a [Surface Impact](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/), at least two [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/), and a [Surface Effect](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) for each response you want to compare.
- Give each Surface Type an **Impact Effects** pair that maps the test Surface Impact to its Surface Effect.
- Assign that same Surface Impact to the source that produces the contact, such as Character Foot Effects, Jump, Fall, a Trajectory Object, or an item impact action.
- Make sure each test target has a Collider. Texture-based multi-material and UV-region detection also requires a MeshCollider and readable mesh data.

Use a [Surface Identifier](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/) for a critical object, a skinned renderer, a procedural material, or any target whose texture cannot be resolved reliably. Surface Manager's texture lookup is best for many static objects that share ordinary materials.

## Add Surface Manager to the scene

1. Choose **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Scene** tab.
3. Under **Manager Setup**, select **Add Managers**.
4. In the Hierarchy, select the `Game` object that was created or reused. The setup command adds Surface Manager, Decal Manager, Object Pool, Scheduler, Audio Manager, and the other scene managers to this object.
5. Select **Surface Manager** in the Inspector and confirm that the scene does not contain another active Surface Manager.
6. Set **Main Texture Property Name** to the property that holds the material texture you will register. The component's released code default is `_BaseMap`; many Built-in Render Pipeline shaders instead use `_MainTex`.
7. Leave **Detect Terrain Tree Textures** disabled unless terrain trees must have a different response from the terrain beneath them.
8. Save the scene before adding mappings.

Surface Manager can create an unconfigured `SurfaceManager` GameObject on first static use when none exists. Use the Setup Manager path for a real scene so the configured component and companion managers are present before gameplay starts.

**Editor checkpoint:** one active Surface Manager is on the scene manager object, **Main Texture Property Name** matches the test shader exactly, and the Console is clear after saving the scene.

## Register surfaces and responses

The manager maps a texture to a Surface Type. The Surface Type separately maps a Surface Impact to a Surface Effect.

1. Select the Surface Manager and add an element to **Object Surfaces**.
2. Select the new row and assign its **Surface Type**, such as `Wood`.
3. Select **Add Texture**, then assign the exact texture used by the wood material.
4. Keep **UV** at `X 0`, `Y 0`, `W 1`, `H 1` for the whole texture. Use a smaller rectangle only for a tested MeshCollider atlas workflow.
5. Add another Object Surface for `Metal` and register the metal texture.
6. On both Surface Type assets, add the same Surface Impact under **Impact Effects**, but assign different Surface Effects.
7. Assign the same Surface Impact at the source of the hit.
8. Expand **Fallbacks** and decide whether unknown inputs should resolve or remain silent.
9. Save the Surface Types, Surface Effects, source prefab, and scene, then enter a fresh Play Mode session.

Do not register the same Texture more than once in released 3.2.0. The initializer adds every registered Texture to a unique dictionary before building its UV-region maps; repeating a Texture with another UV rectangle can throw a duplicate-key exception. The legacy recommendation to repeat one atlas texture across multiple Object Surfaces is not a safe no-code workflow in this release. Use separate textures/materials, a Surface Identifier, or a tested project-side extension instead.

## Surface Manager Inspector fields

These are the fields drawn by the released 3.2.0 custom Inspector and their new-component defaults:

| Field | Default | Decision |
| --- | --- | --- |
| **Object Surfaces** | No entries | Maps each Surface Type to one or more unique textures. Selecting an entry exposes **Surface Type**, its texture tiles, **UV**, **Remove**, and **Add Texture**. |
| **Main Texture Property Name** | `_BaseMap` | Name passed to `Shader.PropertyToID` and read from the renderer's shared material. It must match the active shader. |
| **Detect Terrain Tree Textures** | Disabled | When enabled, tests terrain tree instances to find the hit tree's main texture. This is explicitly CPU-intensive. |
| **Fallback Surface Impact** | None | Substituted when the incoming Surface Impact is null and also used as the final impact lookup after a primary pair fails. |
| **Fallback Surface Type** | None | Substituted when no Surface Type is detected and used when a detected Surface Type lacks the requested pair. |
| **Fallback Allow Decals** | Enabled | Controls decals when the incoming impact or detected surface was null and its fallback was substituted. Disable it when an approximate fallback decal would be misleading. |

Adding a texture initializes its UV rectangle to the full `0,0,1,1` range. The component has no separate terrain list: terrain-layer diffuse textures and optional terrain-tree material textures use the same Object Surfaces registrations.

## Choose how the Surface Type is detected

Surface Manager evaluates these routes in order:

| Target | Recommended setup | Released behavior |
| --- | --- | --- |
| Explicit object | Add Surface Identifier and assign its Surface Type | The identifier wins over texture and terrain detection. The manager checks the collider object, then its children, then its parents. |
| One ordinary material | Register the material's main texture in Object Surfaces | The renderer's shared material is read with **Main Texture Property Name** and cached for that collider. |
| Multiple materials | Use a MeshCollider with readable mesh data and register each material texture | The raycast triangle is matched to a submesh and then to the corresponding shared material. |
| One atlas region | Register the texture once with a tested UV rectangle | Runtime applies material tiling and offset, wraps the coordinate, flips Y for the Inspector convention, and tests whether the rectangle contains the hit UV. Multiple regions for one repeated Texture are unsafe in released 3.2.0. |
| Legacy secondary texture | Prefer Surface Identifier; test this compatibility path only if the project already depends on it | Released source contains a `_Mask` and `_MainTex2` branch that selects the secondary texture when readable mask alpha exceeds `0.5`, but its static shader IDs are assigned only through lazy-instance initialization. Do not assume a scene manager or another shader convention resolves it. |
| Terrain ground | Register each Terrain Layer's diffuse texture | The dominant alphamap layer at the hit point supplies the texture. A Surface Identifier is not used for a TerrainCollider. |
| Terrain tree | Register the tree texture and enable **Detect Terrain Tree Textures** | The manager probes terrain tree instances before falling back to the ground texture. Keep it disabled unless the extra per-hit work is necessary. |
| Skinned, generated, or unresolved target | Use Surface Identifier | Released texture resolution deliberately rejects SkinnedMeshRenderer triangle lookup and cannot infer a type without a recognized texture route. |

A Surface Identifier can leave **Surface Type** unassigned and still turn off **Allow Decals** while texture detection supplies the type. Keep the identifier on the collider GameObject when possible so hierarchy lookup is unambiguous.

## Understand response and fallback resolution

After detecting a Surface Type, Surface Manager resolves an effect in this order:

1. Use the incoming Surface Impact. If it is null, substitute **Fallback Surface Impact**.
2. Use the detected Surface Type. If none was detected, substitute **Fallback Surface Type**.
3. Look for the Surface Impact in that Surface Type's **Impact Effects**.
4. If a detected Surface Type lacks the pair, switch to **Fallback Surface Type** and try the original or substituted impact there.
5. If no effect was found, try **Fallback Surface Impact** on the Surface Type currently being used.
6. Spawn nothing and return `false` when no Surface Effect resolves.

If a Surface Type contains the same Surface Impact more than once, the manager logs a warning and caches only the first pair. Keep one unambiguous pair.

**Fallback Allow Decals** is narrower than its label may suggest. Released 3.2.0 applies it only when the incoming Surface Impact or initially detected Surface Type was null. A fallback reached solely because a known Surface Type lacked a pair is not flagged for this decal check. For sensitive surfaces, also disable **Allow Decals** on a Surface Identifier or use a fallback Surface Effect with no decals.

## Control decals and runtime lifetime

Surface Manager decides only whether the resolved effect may request a decal:

- A null collider blocks decals.
- A discovered Surface Identifier with **Allow Decals** disabled blocks them.
- An applicable fallback uses **Fallback Allow Decals**.
- A Surface Effect with no decal prefabs cannot spawn one.

[Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/) performs placement, limits, weathering, fadeout, and object-pool return. In released 3.2.0, a decal on a uniformly scaled receiver is parented to the hit transform; a decal on a non-uniformly scaled receiver is parented under Decal Manager to avoid inherited distortion. There is no current **Allow Non Uniform Decals** field or **Placement Tests** toggle. Use Surface Identifier's **Allow Decals** for per-object policy.

Surface Effect spawned objects and decals use the shared [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/). Audio and temporary state responses follow the selected Surface Effect; Surface Manager does not own their cleanup.

## Check the editor setup

Before Play Mode, confirm:

- The scene contains one intended Surface Manager and its companion managers.
- **Main Texture Property Name** exists on every material that relies on texture detection.
- Every registered Texture appears only once in Object Surfaces.
- Each Object Surface has a Surface Type and at least one non-null Texture.
- Multi-material or UV tests use a MeshCollider and readable mesh; mask sampling uses a readable Texture2D.
- Terrain Layer diffuse textures are registered and tree detection is enabled only when required.
- Each Surface Type has one pair for the Surface Impact used by the source.
- Fallback Surface Type contains the pairs that the fallback path is expected to find.
- Fallback decal policy and every relevant Surface Identifier's **Allow Decals** value are intentional.

Stop and restart Play Mode after changing a mapping, hierarchy, material, identifier, or Surface Type pair. The released manager caches these lookups and exposes no Inspector command to rebuild them in place.

## Verify on multiple surfaces in Play Mode

1. Create adjacent Wood and Metal test objects with colliders, one ordinary material each, and visibly different registered textures. Do not add Surface Identifiers yet.
2. Map the two textures to distinct Wood and Metal Surface Types in Object Surfaces.
3. Pair one Bullet Hit Surface Impact with a wood response on Wood and a clearly different metal response on Metal.
4. Trigger the same source on Wood. Confirm only the wood audio, spawned objects, decal, and optional state run.
5. Trigger that source on Metal without changing the source. Confirm the metal pair runs instead.
6. Add a Surface Identifier to the metal collider and temporarily assign the Wood Surface Type. Restart Play Mode and confirm the identifier overrides the registered metal texture; then restore the intended type.
7. If the scene uses terrain, map two Terrain Layer diffuse textures, hit a point where each layer is dominant, and confirm the response changes across the blend.
8. Hit an unmapped object and trigger a null Surface Impact. Confirm the configured fallback pair, including its decal policy, or confirm silence if the fallbacks are intentionally unassigned.
9. Disable **Allow Decals** on one receiver's Surface Identifier, restart Play Mode, and confirm its audio and spawned objects remain while its decal is absent.
10. Repeat the test after changing a mapping outside Play Mode. Confirm a fresh session uses the new mapping and produces no duplicate-key exception or duplicate-impact warning.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| No response plays | The source impact, detected type, or Impact Effects pair is missing | Assign the same Surface Impact at the source and in the Surface Type, then assign a Surface Effect to that pair. |
| Every object uses the fallback | **Main Texture Property Name** does not exist on the shader, or the material texture is not registered | Enter the exact shader property, register the actual shared-material texture, and restart Play Mode. |
| Unity reports that the same key was added during `Awake` | One Texture appears with more than one distinct UV entry | Register that Texture once. Use separate materials, Surface Identifiers, or project code instead of repeated atlas entries in released 3.2.0. |
| A multi-material or UV hit resolves incorrectly | The target is not a MeshCollider, the raycast has no triangle index, or the mesh is not readable | Use a readable MeshCollider workflow or assign a Surface Identifier. |
| A secondary texture is ignored | The material differs from the legacy `_Mask` and `_MainTex2` convention, the mask is unreadable, or the scene-manager path did not initialize those static property IDs | Bypass this fragile released path with Surface Identifier, or apply and verify a project-side initialization fix before relying on it. |
| Terrain always reports one material | The diffuse textures are not registered, or that layer is dominant at the sampled alphamap cell | Register each Terrain Layer diffuse texture and test well inside each painted region. |
| A terrain tree uses the ground response | Tree detection is disabled, the tree prefab has no usable collider, or its texture is unmapped | Enable detection only for this test, provide the collider and mapping, then measure the cost before shipping. |
| Inspector edits do not change later hits | The collider, texture, identifier, or pair was already cached | Stop Play Mode, make the change, and start a fresh session. |
| The wrong hierarchy type is selected | Multiple Surface Identifiers are found across the collider's children or parents | Put one intended identifier on the collider GameObject and restart Play Mode. |
| A fallback decal appears unexpectedly | **Fallback Allow Decals** defaults to enabled, or the fallback was reached through a missing pair rather than a null input | Disable fallback decals, disable them on the receiver, or remove decals from the approximate fallback effect. |
| The old non-uniform or placement setting is missing | The page or project was based on an older Inspector | Use the current automatic parenting and Surface Effect edge-overlap behavior; those manager toggles are not present in 3.2.0. |
| Duplicate managers produce inconsistent results | More than one active Surface Manager exists and the static lookup selects one | Keep one configured scene manager and remove the unintended duplicate through a recoverable editor change. |

## Related pages

- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)
- [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/)
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/)
- [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/)
- [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/)
- [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/)
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/)
- [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/)
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/)

## Developer reference

`SurfaceManager`, `SurfaceType`, `SurfaceImpact`, `SurfaceEffect`, and `SurfaceIdentifier` are in `Opsive.UltimateCharacterController.SurfaceSystem`.

### Runtime APIs and lifecycle

`SurfaceManager.SpawnEffect` has four static overloads: regular and footprint-aware calls, each with either the `RaycastHit.collider` or an explicit Collider. A successful resolution invokes the Surface Effect and returns `true`; failure returns `false`. Footprint-aware calls use `SurfaceType.AllowFootprints` to choose `SpawnFootprint` or the regular spawn path.

The public instance methods `GetSurfaceType`, `GetSurfaceIdentifier`, and `GetSurfaceEffect` support custom callers that need to inspect resolution before spawning. `GetSurfaceEffect` returns the chosen Surface Effect and writes the resolved Surface Type and decal permission through `ref` parameters.

Static use locates the first Surface Manager or creates an unconfigured `SurfaceManager` GameObject. Scene unload and subsystem registration reset the static instance. Keep one configured manager per gameplay scene; there is no dedicated surface-resolution event.

### Caches and runtime changes

Object Surface texture dictionaries are built in `Awake`. Collider lookups then cache identifiers, decal permission, resolved simple types, renderer, mesh, main texture, terrain, and material complexity. Surface Type impact maps are built lazily on first use. The released API exposes no cache invalidation or Object Surface rebuild method.

Configure mappings before `Awake`, and treat collider/material/hierarchy edits as next-session changes unless project code deliberately recreates the manager. A runtime Surface Type edit may also leave its already-built impact map unchanged.

### Pooling, saving, and networking

Surface Manager does not pool the manager or a resolved effect. Its optional terrain-tree probe temporarily instantiates tree prefabs through `ObjectPoolBase` and returns them after each test; this per-tree work is why the Inspector labels the option CPU-intensive. Surface Effects and Decal Manager own the pooled cosmetic objects they spawn.

Scene serialization preserves the manager's configured fields, while Surface Type, Impact, and Effect assets preserve their mappings. Runtime caches, random selection state, spawned decals, particles, audio, and temporary states are not save-game state. Persist any underlying gameplay consequence separately.

Surface Manager does not replicate resolution or effects. In a networked project, choose which peer or server resolves the hit, replicate the authoritative impact or cosmetic result, and prevent prediction plus replication from spawning the same response twice.

### Released 3.2.0 source notes

- Repeating a Texture with a different UV rectangle can throw during `InitObjectSurfaces`; do not rely on legacy first-overlap/list-order guidance for atlas regions without a project-side fix.
- **Fallback Allow Decals** is applied only to fallbacks caused by an initially null Surface Impact or Surface Type. A pair-missing fallback is not marked by those flags.
- The released Decal Manager has no **Allow Non Uniform Decals** field. It parents decals from uniform receivers to the hit transform and decals from non-uniform receivers to the manager transform.
- The `_Mask` and `_MainTex2` shader-property IDs are assigned inside the lazy static `Instance` lookup, while a scene component's `OnEnable` can mark the singleton initialized without that assignment. Treat secondary-texture detection as a source-level compatibility path that requires a project fix and focused verification.

---

<a id="page-ultimate-character-controller-surface-system-surface-impacts"></a>

# Surface Impacts

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/)

Use a Surface Impact asset to identify what caused contact, such as a bullet hit, melee strike, footstep, jump, or landing, so each target Surface Type can select the appropriate Surface Effect.

## Before you begin

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select **Scene > Manager Setup > Add Managers**. Confirm that the scene's **Game** object contains **Surface Manager**, **Decal Manager**, and the shared **Object Pool**.
3. Decide which causes need different response matrices. Create one reusable impact for each cause, such as `BulletHit`, `MeleeHit`, and `Footstep`; do not create `BulletHitOnWood` as the impact.
4. Create or choose at least two [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/), such as Wood and Metal, and make their test Colliders resolve those types through [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/).

A Surface Impact contains no sound, particle, decal, damage, or force values. It is a blank `ScriptableObject` used as an object-reference key. Renaming the asset does not change a serialized reference; duplicating it creates a different key that must be mapped separately.

## Create and map a Surface Impact

1. In the Project window, choose **Assets > Create > Opsive > Ultimate Character Controller > Surface Impact**.
2. Save the asset under `Assets` and name it for the cause, such as `BulletHit`.
3. Create a [Surface Effect](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) for each target-specific response, such as `BulletHitOnWood` and `BulletHitOnMetal`, with **Assets > Create > Opsive > Ultimate Character Controller > Surface Effect**.
4. Select the Wood Surface Type. In **Impact Effects**, add an element, assign `BulletHit` to **Surface Impact**, and assign `BulletHitOnWood` to **Surface Effect**.
5. Repeat on Metal, using the same `BulletHit` asset and the metal-specific effect.
6. Assign `BulletHit` to exactly one contact consumer. The correct field depends on whether the source is a hitscan item, moving projectile, melee attack, footstep, or ability.
7. On Surface Manager, configure **Fallback Surface Impact**, **Fallback Surface Type**, and **Fallback Allow Decals** only when unknown or incomplete input should produce an approximate response.

The Surface Impact Inspector has no configurable fields or defaults. All behavior comes from where that asset is referenced.

## Build the source and target matrix

The source supplies the Surface Impact; the target supplies the Surface Type. Their intersection supplies the Surface Effect:

| Target Surface Type | Bullet Hit impact | Melee Hit impact | Footstep impact |
| --- | --- | --- | --- |
| Wood | `BulletHitOnWood` effect | `MeleeHitOnWood` effect | `FootstepOnWood` effect |
| Metal | `BulletHitOnMetal` effect | `MeleeHitOnMetal` effect | `FootstepOnMetal` effect |

Use the same impact asset down a column. A Surface Type's **Impact Effects** starts empty; each element starts with **Surface Impact** `None` and **Surface Effect** `None`. Add only one element for each Surface Impact. On first use, Surface Manager builds a dictionary for that Surface Type; if the same impact appears more than once, it warns and keeps only the first entry.

### Resolution and fallback order

Surface Manager first detects the target type and decal permission from the hit. It then resolves the response in this order:

1. uses the incoming Surface Impact, or substitutes **Fallback Surface Impact** when the incoming value is null;
2. stops if both are null;
3. uses the detected target Surface Type, or substitutes **Fallback Surface Type** when detection returned null;
4. stops if the resulting type is null or its **Impact Effects** array is null or empty;
5. tries the current impact on the current type;
6. if that pair is missing and the fallback type was not already selected, tries the current impact on **Fallback Surface Type**;
7. if still missing, tries **Fallback Surface Impact** on the type from the previous step; and
8. spawns nothing when no valid pair exists.

**Fallback Surface Impact** and **Fallback Surface Type** default to `None`; **Fallback Allow Decals** defaults to enabled. A known Surface Type with an empty **Impact Effects** list returns before the pair-fallback steps, so give every production type at least one deliberate mapping.

Released Version 3.2.0 applies **Fallback Allow Decals** when the incoming impact or detected type was initially null. It does not mark the later "known pair missing, switch to fallback type" path as a fallback for that decal check. Use an explicit pair or a fallback effect with no decal when approximate feedback must never leave a decal.

On that known-pair-missing path, the released code replaces the current type with **Fallback Surface Type** even when the field is `None`; it does not then try **Fallback Surface Impact** against the original detected type. Configure a populated fallback type or, preferably, complete the explicit matrix.

A fallback can act only after a consumer calls Surface Manager. Character Foot Effects and the item **Spawn Surface Effect** action can pass a null impact into that call. Jump, Fall, and Trajectory Object guard their direct calls with a non-null check, so leaving those source fields `None` skips the request instead of invoking **Fallback Surface Impact**.

## Configure the Surface Effect response

The selected Surface Effect owns target-dependent presentation. These are the released new-asset defaults most relevant to an impact setup:

| Response | Fields | Defaults |
| --- | --- | --- |
| Pooled particle, dust, spark, or debris prefab | **Spawned Objects** entries: **Object**, **Probability**, **Random Spin** | No entries; `None`, `1`, disabled per new entry |
| Decal or footprint | **Decals > Prefabs**, **Min Scale**, **Max Scale**, **Allowed Decal Edge Overlap** | No entries; `1`, `1`, `0.25` |
| Shared audio recipe | **Audio > Audio Config** | `None` |
| Raw audio clips | **Audio Clips**, **Min/Max Volume**, **Min/Max Pitch**, **Random Clip Selection**, **Min Audio Clip Frame Interval** | No entries; `1`/`1`, `1`/`1`, enabled, `-1` |
| Temporary target State | **State Name**, **State Disable Timer** | Empty, `10` seconds |

When **Audio Config** is assigned, the raw clip, volume, pitch, and selection controls are hidden and ignored; **Min Audio Clip Frame Interval** still applies. `-1` disables that frame throttle, while `0` permits at most one play from the shared effect asset per frame.

There is no dedicated particle field. Put a particle prefab in **Spawned Objects**, or use the item **Spawn Particle** Impact Action when the same particle should appear regardless of target Surface Type.

## Choose one contact consumer

One physical contact can pass through several systems. Choose one place to request the Surface Effect or the same feedback can spawn more than once.

Like every Impact Action, a newly added **Spawn Surface Effect** starts **Enabled**, with **Delay** `0` and **Allow Multi Hits** disabled. Its own **Use Context Data** starts disabled and **Surface Impact** starts `None`. The default damage group is a special constructor path that creates this action with context use enabled.

### Projectile and hitscan sources

For a hitscan Shootable Action:

1. Open **Impact Action Module Group > Generic Shootable Impact > Impact Actions**.
2. Add or keep **Spawn Surface Effect**.
3. Assign the local **Surface Impact** to `BulletHit`. A newly added action has **Use Context Data** disabled and **Surface Impact** `None`; the built-in default damage group constructs its copy with context use enabled.
4. Keep one surface-effect action in the successful impact path.

The action uses `ImpactDamageData.SurfaceImpact` when **Use Context Data** is enabled and that value is non-null; otherwise it uses its local **Surface Impact**. It does not read `ImpactCollisionData.SurfaceImpact` for this choice. A valid `RaycastHit` is required for detection and placement.

A moving Projectile can request the same response through as many as three routes:

- the inherited Trajectory Object **Surface Impact**, called directly during base collision handling;
- the owning Shootable Action's **Spawn Surface Effect** action; and
- the Projectile's own **Impact Action Group** when **Internal Impact** is enabled.

Use exactly one. For an action-based route, leave the Trajectory Object **Surface Impact** null, keep **Surface Impact** null in projectile damage data when initialization would copy it to the Trajectory Object, assign the action's local impact, and remove or disable the duplicate **Spawn Surface Effect** action. For a direct Trajectory Object route, keep its impact and remove the action-based duplicates while retaining any required damage, force, and event actions.

ProjectileBase initialization normally copies `ImpactDamageData.SurfaceImpact` to the Trajectory Object unless **Use Object Impact Layer And Surface** is enabled. This makes duplicate-consumer auditing essential on projectile prefabs.

### Melee sources

For a Melee Action, add **Spawn Surface Effect** to **Generic Melee Impact Module > Impact Actions** and assign the local **Surface Impact**. The built-in action falls back to that local value because ordinary melee context has no `ImpactDamageData`.

Released Version 3.2.0 stores a Melee Hitbox's optional **Surface Impact** in `ImpactCollisionData.SurfaceImpact`, but **Spawn Surface Effect** reads only `ImpactDamageData.SurfaceImpact` or its local field. The hitbox value alone therefore does not select the built-in surface response. Use the local action field for one melee cause, separate action configurations for different attacks, or a project-owned Impact Action that deliberately reads the collision value.

### Footstep, jump, and landing sources

- Assign **Surface Impact** on [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) for footsteps. It raycasts below the selected foot and calls the footprint-aware Surface Manager overload with forward direction and left/right flip.
- Assign **Jump Surface Impact** on Jump for takeoff feedback. It calls the ordinary overload with the grounded hit.
- Assign **Land Surface Impact** on Fall and tune **Min Surface Impact Velocity** for landing feedback. Fall calls the footprint-aware overload with character-forward direction and no flip.

These character sources call Surface Manager directly; they do not need an item Impact Action.

## Separate presentation from force and damage

| Desired result | Correct owner |
| --- | --- |
| Material-dependent audio, decal, particle/debris prefab, or State | Surface Effect selected by the impact-and-type pair |
| Material-independent hit particle or sound | **Spawn Particle** or **Play Audio Clip** Impact Action |
| Damage and push configured together | **Simple Damage** Impact Action |
| Additional linear or angular push | **Add Force** or **Add Torque** Impact Action |
| Projectile's physical Rigidbody push | Trajectory Object collision handling, which applies its current velocity independently of Surface Effect |
| Gravity-relative movement on spawned visual debris | **Directional Constant Force** on a Surface Effect spawned-object prefab; Surface Effect sets its direction but does not push the hit target |

Do not encode force strength in separate Surface Impact assets. The impact selects a response recipe; damage, force, impact strength, and radius remain part of the item or projectile context. Avoid combining Trajectory Object Rigidbody force, **Simple Damage**, and **Add Force** unless cumulative force is intentional.

The item **Spawn Surface Effect** action suppresses a non-shield response when an available damage context reports exactly zero damage. A **Shield Collider** is the explicit exception. Use another feedback path or project code when a harmless zero-damage hit must still show a response.

## Follow the runtime lifecycle and pooling

1. A source detects contact and supplies a `RaycastHit`, hit Collider, Surface Impact, gravity direction, time scale, and originator.
2. Surface Manager resolves the target Surface Type and decal permission, then applies the impact/type fallback chain.
3. On a Surface Type's first resolved use, the manager caches its Surface Impact-to-Surface Effect dictionary. Later edits do not rebuild that dictionary during the same manager lifetime.
4. The ordinary Surface Effect path spawns configured objects, plays audio at the hit point, activates the optional State on `hit.transform.gameObject`, then requests a decal when permitted.
5. The footprint path performs the same response order but plays audio on its supplied originator and sends direction/flip to Decal Manager. If the resolved type does not allow footprints, Surface Manager calls the ordinary path instead.
6. Source-owned gameplay actions such as damage and force run independently in their own configured order.

**Spawned Objects** uses `ObjectPoolBase.Instantiate`; Surface Effect does not return those objects itself. Give particle prefabs **Particle Pooler**, **Remover**, or another explicit return lifecycle. Decal Manager obtains and returns decals through the shared Object Pool according to its limits and weathering lifecycle.

The Surface Impact is a shared asset reference and is not instantiated or pooled. A Surface Effect also holds shared nonserialized selection state: last decal, last raw AudioClip, last audio frame, and sequential clip index. Every source using the same Surface Effect asset shares its audio throttle and selection history.

Delayed item Impact Actions duplicate their impact context from generic pools, then return the duplicate after execution. That context pooling is separate from Surface Effect object and decal pooling.

## Editor checkpoint

Before Play Mode, confirm that:

- each cause uses one intentional Surface Impact asset, and source fields reference the same asset object used in Surface Type mappings;
- every target Collider resolves the intended Surface Type;
- each Surface Type has one **Impact Effects** entry per tested impact, with a non-null Surface Effect;
- no duplicate entry precedes the intended pair;
- every projectile contact has exactly one surface-effect consumer;
- melee uses the local **Spawn Surface Effect > Surface Impact** unless project code deliberately consumes the hitbox collision value;
- each Surface Effect contains only material-dependent feedback, while force and damage remain in their intended impact actions;
- spawned particles and decals have valid pool-return lifecycles and receiver decal permission is deliberate;
- fallbacks are explicitly configured or intentionally remain `None`; and
- authored mapping changes are saved before a fresh Play Mode start.

## Verify in Play Mode

1. Place adjacent Wood and Metal Colliders with distinct Surface Types. Map the same `BulletHit` impact to dust and a dull clip on Wood, then sparks and a ricochet clip on Metal.
2. Fire the same hitscan source at both. Confirm the source impact remains `BulletHit` while the target type changes the selected Surface Effect.
3. Map `MeleeHit` and `Footstep` on both target types. Strike and walk across Wood, then Metal. Confirm each matrix cell produces its own effect without changing the target identifiers.
4. For melee, temporarily clear the action's local impact and **Fallback Surface Impact**, then assign only the hitbox Surface Impact. Confirm that it is not a working built-in selector in 3.2.0. Restore the local **Spawn Surface Effect** impact and confirm the expected effect resolves.
5. Fire one moving projectile once. Confirm the surface response occurs exactly once. If it repeats, audit the direct Trajectory Object, owner Impact Action, and Internal Impact routes.
6. On a footstep effect containing audio and a footprint decal, confirm audio follows the foot originator and the decal uses the correct direction/left-right flip. Disable receiver **Allow Decals**, restart Play Mode, and confirm audio remains while the decal is absent.
7. Through Character Foot Effects or an item action that still calls Surface Manager, test a null incoming impact, an unknown target type, and a known but unmapped pair separately. Confirm each follows the documented fallback branch and decal policy, or intentionally spawns nothing.
8. Give the hit target a non-kinematic Rigidbody and compare the surface response with gameplay force actions disabled and enabled. Confirm changing Surface Effect content does not change the force.
9. Repeat impacts rapidly. Confirm the shared audio interval behaves as configured and spawned particles and decals return to their pools rather than accumulating indefinitely.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Surface Impact Inspector appears empty | The released asset intentionally declares no fields. | Configure the source reference and each Surface Type's **Impact Effects** pair; do not look for response settings on the impact asset. |
| No effect plays | Source impact, detected Surface Type, exact pair, and Surface Effect reference | Assign the same asset object at the source and in one mapping, then test with fallbacks temporarily cleared. |
| Renaming an impact changes nothing | Resolution uses the ScriptableObject reference, not the filename. | Rename freely for organization. Update mappings only when replacing or duplicating the asset. |
| Unity warns about a duplicate impact | The same Surface Impact appears more than once in one Surface Type. | Keep one entry. Released Version 3.2.0 caches and uses only the first. |
| A newly added hitscan action uses the fallback impact | **Spawn Surface Effect > Surface Impact** is `None`, and context damage has no impact. | Assign the local bullet impact; do not rely on the scene fallback for a known source. |
| A Melee Hitbox impact is ignored | It was written to collision context, while the built-in action reads damage context or its local field. | Assign the action's local Surface Impact or implement an action that reads `ImpactCollisionData.SurfaceImpact`. |
| One projectile spawns two or three identical effects | Direct Trajectory Object, owner, and Internal Impact consumers are all enabled. | Keep one surface-effect route and remove only the duplicate **Spawn Surface Effect** actions. |
| A zero-damage item hit has no surface feedback | The built-in action suppresses non-shield effects when context damage equals zero. | Use a non-suppressed feedback action or a custom surface action for harmless contacts. |
| A known Surface Type with no mappings does not reach fallback | Resolution stops when its **Impact Effects** is null or empty. | Add at least one explicit mapping to that type; an empty known type cannot fall through to pair fallback. |
| A missing pair creates an unexpected fallback decal | The later fallback-type branch is not flagged for **Fallback Allow Decals** in 3.2.0. | Add the explicit pair or use a fallback Surface Effect with no decal. |
| A particle never returns to the pool | Surface Effect spawns it but does not own its cleanup. | Add Particle Pooler, Remover, or another explicit return path and avoid an endless looping particle. |
| The target receives no force | Surface Effect has no target-force field. | Configure **Simple Damage**, **Add Force**, projectile collision force, or another gameplay action and verify its Rigidbody/force target. |
| Audio is unexpectedly throttled across several characters | They share one Surface Effect and its **Min Audio Clip Frame Interval** state. | Use `-1`, reduce the interval, or use separate effect assets when independent histories are required. |
| A footstep reports success but nothing is heard | Character Foot Effects returns success when its ground raycast hits, even if no effect pair resolves. | Diagnose the Surface Impact, detected type, and mapping separately from foot timing. |
| Inspector mapping edits do not affect later hits | Surface Manager cached the type's impact dictionary. | Stop and restart Play Mode after changing **Impact Effects**. |

## Related tasks

- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) explains the full source, target, and response relationship.
- [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/) owns the impact-to-effect mapping for each target material.
- [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) configures pooled objects, decals, audio, and State responses.
- [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/) assigns deterministic target identity to a Collider.
- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/) configures alternate identity detection and fallbacks.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) configures footstep timing and footprint placement.
- [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/) controls decal placement, limits, weathering, and pooling.
- [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/) covers lookup caches and complex targets.
- [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/) configures item feedback, damage, force, and callbacks.
- [Melee Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/) and [Shootable Action](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/) configure the item contact sources.
- [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/) configures moving projectile collision and Internal Impact behavior.
- [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) and [Fall](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/fall/) configure takeoff and landing impacts.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reusable response-object ownership.

## Developer reference

`SurfaceImpact` is an intentionally empty `ScriptableObject` in `Opsive.UltimateCharacterController.SurfaceSystem`. The mapping key is the asset reference. `ImpactCollisionData.SurfaceImpact` and `IImpactDamageData.SurfaceImpact` are separate context locations; released `SpawnSurfaceEffect` selects only the damage-data value when **Use Context Data** is enabled, then falls back to its local property.

Call Surface Manager directly when project code already owns a valid hit:

```csharp
using Opsive.UltimateCharacterController.SurfaceSystem;
using UnityEngine;

public sealed class SurfaceImpactEmitter : MonoBehaviour
{
    [SerializeField] private SurfaceImpact m_SurfaceImpact;

    public bool Emit(RaycastHit hit)
    {
        return SurfaceManager.SpawnEffect(
            hit, m_SurfaceImpact, Vector3.down, 1f, gameObject);
    }
}
```

`SurfaceManager.SpawnEffect` provides ordinary and footprint-aware static overloads, each also available with an explicit Collider. The ordinary overload returns `true` when a Surface Effect resolves and `Spawn` is invoked; an effect with empty response lists can therefore still report success. `SurfaceManager.GetSurfaceEffect(RaycastHit, Collider, SurfaceImpact, ref SurfaceType, ref bool)` exposes the final type, effect, and decal decision for diagnostics. `SurfaceEffect.Spawn` and `SpawnFootprint` are virtual extension points.

### Events

Surface Impact and Surface Manager emit no dedicated event when a pair resolves. `ProjectileBase.OnImpact` is a C# event, Trajectory Object exposes its collision UnityEvent, and an item **Impact Event** action can invoke source and target callbacks. These report contact independently of whether Surface Manager found an effect. See the [Event System](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) and [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/).

### Save and network ownership

Authored references are serialized in assets, prefabs, scenes, abilities, and action modules. Runtime changes to a consumer's Surface Impact, Surface Manager mappings, shared effect selection state, active decals, particles, audio, and temporary States are not a durable save record. Save a stable project-owned impact key when the selected cause must persist, then map that key back to the local asset after load.

A Surface Impact reference and a manual `SurfaceManager.SpawnEffect` call do not replicate themselves. The optional multiplayer integrations route selected built-in item impact modules and projectile ownership, but custom calls, random Surface Effect choices, and cosmetic pool activity still need an explicit authority and duplication policy. Resolve gameplay damage and force on the authoritative peer, decide where presentation runs, and transmit a stable impact identifier rather than assuming a Unity asset reference is a network message.

---

<a id="page-ultimate-character-controller-surface-system-surface-types"></a>

# Surface Types

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/)

A Surface Type is the material identity used by the Surface System. Each asset maps a cause, represented by a [Surface Impact](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/), to the [Surface Effect](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) that should run on that material. After completing this workflow, the same footstep or projectile can produce different feedback on Ground, Metal, and Wood.

## Before you begin

- Add the scene managers with **Tools > Opsive > Ultimate Character Controller > Setup Manager**, select **Scene**, and choose **Manager Setup > Add Managers**. Confirm that the created manager object has a **Surface Manager** component.
- Create the Surface Impact assets that describe causes such as `Footstep` or `BulletHit`.
- Create the Surface Effect assets that contain the audio, spawned objects, decals, and state changes for each response.
- Ensure every tested surface has a Collider. Texture and material detection also requires a compatible Renderer; multi-material detection requires a readable mesh and a MeshCollider hit.

## Create and configure a Surface Type

1. In the Project window, select the folder that should contain the asset.
2. Choose **Assets > Create > Opsive > Ultimate Character Controller > Surface Type**. The same command is available from the Project window's context menu.
3. In **Save Surface Type**, enter a descriptive filename such as `Ground`, `Metal`, or `Wood` and save the asset under the project's `Assets` folder. The suggested filename for a new asset is `SurfaceType.asset`.
4. Select the new asset and expand **Impact Effects**.
5. Set the array **Size** to the number of responses this material needs.
6. For each element, assign one **Surface Impact** and the **Surface Effect** that it should trigger. Add separate rows for `Footstep`, `BulletHit`, and every other cause the type supports.
7. Make the asset reachable with a [Surface Identifier](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/), an **Object Surfaces** texture entry on the Surface Manager, or **Fallback Surface Type**. Creating the asset alone does not register it with a scene.

The released 3.2.0 asset has these serialized values:

| Field | New-asset value | Purpose |
| --- | --- | --- |
| **Impact Effects** | No elements | Maps each **Surface Impact** reference to one **Surface Effect** reference. |
| Element > **Surface Impact** | **None** | The cause used as the lookup key. A row with no impact is skipped. |
| Element > **Surface Effect** | **None** | The response returned for that impact. Assign a real effect for a usable pair. |
| **Allow Footprints** | Enabled | Chooses footprint-oriented spawning for footprint requests. In 3.2.0 this serialized field is not drawn by the released custom Inspector, so there is no standard Inspector control for it. |

Do not add the same Surface Impact twice to one Surface Type. The first lookup builds a dictionary, logs a warning for a duplicate key, and keeps the first row.

### Understand the footprint setting

**Allow Footprints** does not enable or disable the whole footstep response. When it is enabled, a footprint request uses the Surface Effect's footprint-oriented spawn path. When it is disabled, the same request uses the ordinary effect spawn path, so audio and other configured response objects can still run. The public 3.2.0 API exposes this value as read-only; changing the hidden serialized value requires project-owned editor or asset-migration tooling.

## Use names without assuming inheritance

Use names to communicate intent, but do not rely on names for lookup:

| Asset kind | Example | Meaning |
| --- | --- | --- |
| Surface Type | `Ground`, `Metal`, `Wood` | The material identity. |
| Surface Impact | `Footstep`, `BulletHit` | The cause of the contact. |
| Surface Effect | `FootstepOnMetal`, `BulletHitOnWood` | The response for one cause/material pair. |

Surface Types are flat, independent ScriptableObjects. There is no parent, base type, or inherited Impact Effects list. Duplicating `Ground` to start `Wood` copies the rows once; later changes to either asset do not propagate. Likewise, naming an asset `Ground` has no runtime meaning: the system compares asset references.

To reuse behavior, assign the same Surface Effect asset to explicit rows on several Surface Types. Manager fallbacks provide missing-response behavior, not type inheritance.

## Register each material identity

Choose the most stable identity source for the object:

| Surface | Setup | Use when |
| --- | --- | --- |
| Collider or prefab | Add **Surface Identifier** and assign **Surface Type**. | One collider hierarchy has one explicit identity. This is checked before texture detection. |
| Simple rendered object | On **Surface Manager > Object Surfaces**, add an element, assign **Surface Type**, choose **Add Texture**, assign the material's main texture, and leave **UV** at `(0, 0, 1, 1)`. | A single-material object should be identified from its texture. |
| Multi-material mesh | Register each material's main texture in **Object Surfaces**. Use a readable mesh and a MeshCollider so the hit triangle can select the material. | Different submeshes represent different surfaces. Object Surfaces map textures, not Material assets. |
| Texture atlas or secondary map | Add the texture and the intended **UV** region to **Object Surfaces**. | One texture contains more than one material region. See [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/) for the released limitations. |
| Terrain | Register each Terrain Layer's diffuse texture in **Object Surfaces**. | The dominant painted terrain layer at the hit point should choose the type. A Surface Identifier is ignored for a TerrainCollider. |
| Unknown surface | Open **Surface Manager > Fallbacks** and assign **Fallback Surface Type**. | An impact can reach an object whose type cannot be detected. |
| Runtime-spawned collider | Include a stable Surface Identifier and its Surface Type before the collider's first query. | A spawned or pooled object needs explicit identity. |

A new Surface Manager starts with no **Object Surfaces** entries. **Main Texture Property Name** defaults to `_BaseMap`; change it to the shader's actual main-texture property before the manager initializes if the shader uses another property. **Detect Terrain Tree Textures** defaults to disabled. Enable it only when tree-texture detection is required because that path is CPU intensive.

For ordinary terrain painting, the manager chooses the Terrain Layer with the greatest weight at the hit point and looks up that layer's diffuse texture. **Detect Terrain Tree Textures** is a separate choice for terrain trees.

### Set fallbacks deliberately

Under **Surface Manager > Fallbacks**, a new manager has **Fallback Surface Impact** set to **None**, **Fallback Surface Type** set to **None**, and **Fallback Allow Decals** enabled.

In 3.2.0, **Fallback Allow Decals** is consulted when a missing incoming impact or missing detected type is initially replaced by its fallback. A later pair-missing hop from a known type to **Fallback Surface Type** does not set that fallback flag.

Resolution follows these boundaries:

1. A missing incoming Surface Impact is replaced with **Fallback Surface Impact**. If both are null, resolution stops.
2. A missing detected Surface Type is replaced with **Fallback Surface Type**. If there is still no type, resolution stops.
3. The manager checks the chosen impact/type pair.
4. If that pair is missing on a non-fallback type, it tries the same impact on **Fallback Surface Type**.
5. If the pair is still missing, it tries **Fallback Surface Impact** on the type currently being checked, which is normally the fallback type.

A detected Surface Type whose **Impact Effects** array is null or empty returns no effect before the pair-fallback checks. Add at least one valid row rather than expecting an empty type to inherit the manager fallback. Also note that the pair-missing path replaces the detected type with **Fallback Surface Type**; it does not try **Fallback Surface Impact** against the original type.

## Understand the runtime lifecycle

The Surface Manager prepares its Object Surfaces texture maps and shader property ID during `Awake`. For each contact it then:

1. Resolves an explicit Surface Identifier, then simple texture, complex material or UV region, and finally terrain texture.
2. Applies the configured fallback type when identity is still unknown.
3. Builds and caches the Surface Type's impact-to-effect dictionary on that type's first effect lookup.
4. Returns the mapped Surface Effect and lets the caller spawn the response.

The manager caches collider identity components, renderers, meshes, main textures, material complexity, and several resolved texture/type results. It also caches each Surface Type's Impact Effects map. As a result:

- Author Impact Effects and Object Surfaces before entering Play Mode. Object Surfaces changes after `Awake` are not reindexed, and Impact Effects changes after that type's first lookup do not rebuild its dictionary in 3.2.0.
- Keep a Surface Identifier on a collider before its first lookup. Adding or replacing the component later can leave the cached component result unchanged.
- Changing the `SurfaceType` value on an already-discovered Surface Identifier is supported because the manager reads that value for each query.
- Changing a renderer's material or main texture after its first lookup can leave the collider associated with the old cached identity.
- Reused pooled colliders keep the same manager cache entries. Give a pooled object a stable Surface Identifier, then change that identifier's Surface Type if the reused instance needs a new material identity.

## Editor checkpoint

Before entering Play Mode, verify all of the following:

- The scene contains one active Surface Manager.
- `Ground`, `Metal`, and `Wood` are three separate Surface Type assets.
- Every type has one row per required Surface Impact, with both references assigned and no duplicate impact keys.
- Each collider has an explicit Surface Identifier, or its texture is registered exactly once in **Object Surfaces**.
- Terrain Layer diffuse textures, not Terrain Layer assets, are registered for terrain detection.
- **Main Texture Property Name** matches the shader used by texture-detected objects.
- **Fallback Surface Type**, **Fallback Surface Impact**, and **Fallback Allow Decals** reflect an intentional fallback policy.

## Verify Ground, Metal, and Wood in Play Mode

Use visibly or audibly distinct Surface Effects so the result is unambiguous.

1. Create `Footstep` and `BulletHit` Surface Impacts.
2. Give each of `Ground`, `Metal`, and `Wood` a `Footstep` row and a `BulletHit` row. Map them to six distinguishable effects, such as ground thuds and dust, metal rings and sparks, and wood knocks and splinters.
3. Make a Ground pad with a Surface Identifier assigned to `Ground`.
4. Make a single-material Metal pad with no Surface Identifier. Register its main texture to `Metal` in **Object Surfaces**.
5. Paint a Wood Terrain Layer as the dominant layer in a small terrain area and register that layer's diffuse texture to `Wood`.
6. Enter Play Mode and walk the same character across all three surfaces. Each contact should retain the `Footstep` cause but select the Ground, Metal, or Wood effect from the detected type.
7. Fire the same projectile at all three surfaces. Each hit should retain the `BulletHit` cause and select the corresponding material response.
8. Add an otherwise unidentifiable test collider. With **Fallback Surface Type** set to `Ground`, verify that it uses the Ground mapping; with the fallback cleared, verify that no surface response is selected.
9. While still in Play Mode, change the Ground pad's existing Surface Identifier from `Ground` to `Metal` and repeat the same contact. The next lookup should use Metal. Restore the value before leaving Play Mode if the scene should remain Ground.

For a cache-boundary test, use a disposable duplicate asset: trigger it once, change one Impact Effects row during Play Mode, and trigger it again. The first cached mapping remains in use until the manager is recreated. Exit Play Mode and restore or discard the test asset rather than saving that temporary edit.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The asset shows no configurable response rows | **Impact Effects** is collapsed or has **Size** `0`. | Expand the array and create one element per supported Surface Impact. |
| **Allow Footprints** is missing from the Inspector | The released 3.2.0 custom Inspector only draws **Impact Effects**. | Treat the serialized default as enabled, or use project-owned editor tooling if the asset truly requires a different value. |
| A known type produces no response and never reaches the fallback | Its **Impact Effects** array is empty. | Add a valid mapping. An empty detected type stops before pair fallback. |
| One cause always uses the wrong response | The Surface Impact appears more than once in the type. | Remove duplicate keys. The first row wins and the manager logs a warning. |
| An Inspector mapping change has no effect in Play Mode | That Surface Type was already queried, so its dictionary is cached. | Exit and re-enter Play Mode after authoring the asset. There is no released public cache-rebuild API. |
| A texture mapping is ignored | A Surface Identifier on the collider, a child, or a parent resolves first. | Correct or remove that identifier, or keep the explicit assignment and stop relying on texture detection. |
| A Terrain Surface Identifier is ignored | The hit collider is a TerrainCollider. | Register each Terrain Layer's diffuse texture in **Object Surfaces**. |
| A multi-material mesh always resolves one type or none | The hit is not returning a mesh triangle, the mesh is not readable, or a material texture is unregistered. | Use a MeshCollider with a readable mesh and register every relevant main texture. |
| A runtime material swap keeps the old type | Renderer, texture, and collider results may already be cached. | Use an existing Surface Identifier and change its Surface Type instead of changing the material identity source. |
| A duplicated type does not receive changes from the original | Surface Types do not inherit. | Add the mapping to both assets or reference the same Surface Effect explicitly. |
| An unregistered object produces no response | **Fallback Surface Type** or its required impact mapping is missing. | Assign a populated fallback type and, when the incoming impact can be null, a populated **Fallback Surface Impact**. |

## Related tasks

- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)
- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/)
- [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/)
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/)
- [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/)
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/)
- [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/)
- [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/)

## Developer reference

`SurfaceType`, `ImpactEffect`, `SurfaceIdentifier`, and `SurfaceManager` are in `Opsive.UltimateCharacterController.SurfaceSystem`.

- `SurfaceType.ImpactEffects` returns the serialized `ImpactEffect[]`; each element exposes read-only `SurfaceImpact` and `SurfaceEffect` references.
- `SurfaceType.AllowFootprints` is a read-only property whose serialized default is `true`.
- `SurfaceIdentifier.SurfaceType` is writable and is the supported direct identity to change on an already-discovered identifier.
- `SurfaceManager.GetSurfaceType(RaycastHit, Collider)` returns the detected type or `null`; it does not apply **Fallback Surface Type** by itself.
- `SurfaceManager.GetSurfaceEffect(RaycastHit, Collider, SurfaceImpact, ref SurfaceType, ref bool)` detects identity, applies pair fallbacks, returns the resolved effect or `null`, and updates the referenced type and decal decision.

Surface Type assets are not instantiated or pooled per contact. The effect's spawned objects can use the [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/); the type asset and the manager's lookup dictionary remain shared configuration. Version 3.2.0 exposes no Surface Type change event and no public method to clear or rebuild the impact map, so systems that cache derived data should be initialized after asset configuration is final.

### Save and network boundaries

Surface Type mappings are project-authored ScriptableObject data referenced by scenes and prefabs. They are not per-player state and do not need a runtime save record in the normal case. A runtime assignment to `SurfaceIdentifier.SurfaceType` is not written back as saved gameplay state unless the project records and restores that choice explicitly.

The Surface Type API has no network serialization or replication. All peers should ship matching assets and scene references. If gameplay changes a Surface Identifier's type at runtime, replicate the material-state decision or the stable identifier needed to reconstruct it; do not assume the Surface System transmits the asset reference or spawned presentation effect automatically.

---

<a id="page-ultimate-character-controller-surface-system-surface-effects"></a>

# Surface Effects

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/)

Use a Surface Effect asset to define the material-specific feedback for one kind of contact: the same Bullet Hit Surface Impact can produce sparks and a ricochet on metal, dust on dirt, and a different result on wood. The asset is a shared response recipe; it is never instantiated as a scene object.

## Before you begin

- Use the released Ultimate Character Controller Version 3 package. The source verified for this page is UCC `3.2.0`; Version 4 development APIs are outside this workflow.
- Add **Surface Manager**, **Decal Manager**, and the shared Object Pool through **Tools > Opsive > Ultimate Character Controller > Setup Manager > Scene > Add Managers**. Surface and decal managers can create themselves on first use, but scene components expose the fallbacks and lifetime limits that should be reviewed before testing.
- Create or choose a [Surface Impact](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) for what happened and a [Surface Type](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/) for what was hit.
- Give the hit collider a [Surface Identifier](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/), or register its texture with [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/), so the manager can resolve a Surface Type.
- Prepare any Audio Config, AudioClip, particle, debris, or flat decal prefabs the effect will use.

A Surface Effect provides spawned objects, a decal, audio, and an optional state. It does not directly apply damage, force, torque, or knockback; use the item impact actions for gameplay consequences.

## Create and register a Surface Effect

1. In the Project window, choose **Assets > Create > Opsive > Ultimate Character Controller > Surface Effect**.
2. Save the asset under `Assets` and name it for the pair it represents, such as `BulletHitOnMetal` or `FootstepOnWood`.
3. Configure only the response groups needed for this pair: **Spawned Objects**, **Decals**, **Audio**, and **State**.
4. Select the matching Surface Type. In **Impact Effects**, add an element and assign the Surface Impact plus this Surface Effect.
5. Assign the Surface Type to the target through a Surface Identifier or a Surface Manager **Object Surfaces** texture mapping.
6. Assign the same Surface Impact asset to the source that causes the contact, such as Character Foot Effects, Jump, Fall, a Trajectory Object, or an item's **Spawn Surface Effect** impact action.
7. Configure Surface Manager's **Fallback Surface Impact**, **Fallback Surface Type**, and **Fallback Allow Decals** only when unknown or incomplete pairs should still produce feedback.
8. Save the asset, prefab, and scene before entering Play Mode.

The Surface Effect is not added directly to Surface Manager. Registration is the **Surface Impact > Surface Effect** pair stored in a Surface Type. If one Surface Type contains the same Surface Impact more than once, the released manager warns and uses only the first pair.

**Editor checkpoint:** the source and Surface Type reference the same Surface Impact asset, the Surface Type has one unambiguous pair for it, the hit collider resolves that Surface Type, and every referenced prefab is a project asset rather than a scene instance.

## Built-in response types and defaults

Released UCC 3.2.0 has exactly four built-in Surface Effect response groups. The current fields and new-asset defaults are:

| Group | Field | Default | Runtime behavior |
| --- | --- | --- | --- |
| Spawned Objects | Entries | No entries | Every entry is evaluated independently, so one hit can spawn several objects. |
| Spawned Objects | **Object** | None | Prefab instantiated at the hit point with its forward axis aligned to the hit normal. |
| Spawned Objects | **Probability** | `1` | Chance for this entry to spawn; `0` disables it and `1` is the intended always-spawn setting. |
| Spawned Objects | **Random Spin** | Disabled | Adds a random 0-360 degree rotation around the hit normal. |
| Decals | **Prefabs** | No entries | Selects one prefab at random and avoids an immediate repeat when more than one valid choice exists. |
| Decals | **Min Scale** / **Max Scale** | `1` / `1` | Inspector range is `0.01`-`2`; a random value is selected for each decal. |
| Decals | **Allowed Decal Edge Overlap** | `0.25` | Range is `0`-`0.5`; lower values require more of the decal mesh to remain over the hit surface. |
| Audio | **Audio Config** | None | When assigned, it is used instead of the raw AudioClip, volume, pitch, and selection fields. |
| Audio | **Audio Clips** | No entries | Used only when Audio Config is unassigned. |
| Audio | **Min Volume** / **Max Volume** | `1` / `1` | Raw-clip random volume range; Inspector range is `0`-`1`. |
| Audio | **Min Pitch** / **Max Pitch** | `1` / `1` | Raw-clip random pitch range; Inspector range is `-2`-`2`, then runtime time-scale values are applied. |
| Audio | **Random Clip Selection** | Enabled | Random selection avoids an immediate repeat when the list contains more than one usable clip; disabled selection advances through the list. |
| Audio | **Min Audio Clip Frame Interval** | `-1` | `-1` disables throttling, `0` allows at most one play per frame, and positive values require additional frames between plays. |
| State | **State Name** | Empty | Activates this State System state on the hit transform's GameObject. |
| State | **State Disable Timer** | `10` seconds | Schedules deactivation; `-1` leaves the state active until another system disables it. |

The former **One Clip Per Frame** checkbox is not a current field. Use **Min Audio Clip Frame Interval**. The current Inspector also includes **Audio Config**, which takes precedence over the raw clip controls.

## Configure spawned particles, debris, and force-driven visuals

Use **Spawned Objects** for particle bursts, dust, sparks, rubble, shell effects, or another one-shot prefab.

- Each entry has its own probability. Entries are not alternatives unless their probabilities and prefab design make them so.
- The object is spawned through `ObjectPoolBase` at the hit point. Add **Particle Pooler** to a root Particle System so it returns after all child particles finish, or add **Remover** for a fixed lifetime; Surface Effect does not remove spawned objects itself.
- A looping Particle System never becomes dead, so Particle Pooler keeps rescheduling its check. Stop the loop or use a deliberate removal policy.
- If the spawned root has **Directional Constant Force**, Surface Effect replaces that component's direction with the supplied gravity direction. Use it for gravity-relative visual debris. It does not push the hit target.
- Put force, torque, damage, ricochet, or character knockback that affects gameplay in the corresponding [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/).

## Configure decals and footprints

Add one or more decal prefabs under **Decals > Prefabs**. A usable decal root needs a Mesh Filter with a mesh and a Renderer with a material. A flat quad whose forward axis faces away from the receiver gives the predictable result, but the released cache code does not explicitly require a two-triangle mesh as the old field description claimed.

Decal placement follows these rules:

- Ordinary impacts rotate the decal to the hit normal and add a random spin.
- Footprint-aware consumers provide a forward direction and left/right flip value, so Decal Manager aligns and optionally mirrors the footprint instead.
- A sampled scale of exactly `1` preserves the prefab's original local scale. Any other sampled value sets local X and Y to that value and Z to `1`; it does not multiply arbitrary prefab X/Y values.
- **Allowed Decal Edge Overlap** below `0.5` runs the edge test automatically by raycasting the decal mesh vertices toward the receiver. At `0.5`, that test is skipped. Released 3.2.0 has no **Placement Tests** toggle on Decal Manager.
- A Surface Identifier with **Allow Decals** disabled blocks decals for its collider. A missing collider also blocks them. Surface Manager's fallback setting can further restrict a fallback selected for an unknown incoming impact or surface.
- Decal Manager owns the active list, weathering, fadeout, and pooling. Its defaults are **Decal Limit** `100`, **Weathered Decal Limit** `20`, and **Remove Fadeout Speed** `10`.

If a footprint-aware call resolves a Surface Type whose serialized **Allow Footprints** is false, Surface Manager invokes the ordinary Surface Effect spawn instead. In the released 3.2.0 custom Surface Type Inspector, only **Impact Effects** is drawn and the serialized footprint setting defaults to enabled.

## Configure audio

Prefer **Audio Config** when the response needs the shared audio selection, mixer, source prefab, or modifier workflow. When Audio Config is assigned, raw **Audio Clips**, volume, pitch, and random-selection settings are hidden and ignored; **Min Audio Clip Frame Interval** still applies.

Use the raw clip route for a small one-shot list:

1. Leave **Audio Config** unassigned.
2. Add the clips under **Audio Clips**.
3. Keep volume and pitch at `1` for unchanged playback, or set min/max ranges for variation.
4. Leave **Random Clip Selection** enabled for randomized variation, or disable it for list order.
5. Set **Min Audio Clip Frame Interval** to `0` when several same-frame contacts, such as shotgun pellets, must collapse to one sound from this Surface Effect asset.

Ordinary `Spawn` playback is positioned at the hit point. `SpawnFootprint` plays on the supplied originator when one exists; Character Foot Effects supplies the foot GameObject. The interval and last-clip selection state belong to the shared Surface Effect asset, so every character and collider using that same asset participates in the same throttle and selection history.

See [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/) for Audio Config and shared Audio Manager choices.

## Choose the impact consumer

| Source | Configuration choice |
| --- | --- |
| Character footsteps | Assign a Footstep Surface Impact on [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/). It uses the footprint direction and alternating flip path. |
| Jump | Assign **Jump Surface Impact** on the Jump ability. It uses the ordinary effect path at the grounded raycast hit. |
| Landing | Assign **Land Surface Impact** and tune **Min Surface Impact Velocity** on Fall. The released Fall ability uses the footprint-aware overload with the character forward direction. |
| Trajectory objects and shells | Assign **Surface Impact** on the Trajectory Object so its collision can call Surface Manager directly. |
| Modular item hits | Add **Spawn Surface Effect** to an Impact Action Group. Enable **Use Context Data** when the impact's damage data should provide the Surface Impact; otherwise assign the action's local **Surface Impact**. The default damage group includes this action. |
| Melee hitbox override | Assign the Surface Impact directly on **Spawn Surface Effect**. In released 3.2.0, the hitbox override is stored in `ImpactCollisionData.SurfaceImpact`, while this action's **Use Context Data** path reads `ImpactDamageData.SurfaceImpact`; the hitbox value alone does not select the effect. |
| Material-independent force, damage, audio, or particles | Use **Add Force**, **Simple Damage**, **Play Audio Clip**, **Spawn Particle**, or another Impact Action instead of duplicating the same Surface Effect on every Surface Type. |
| Material-dependent audio, decals, particles, or state | Put the response in Surface Effect and pair the same Surface Impact with a different Surface Effect on each Surface Type. |

When an impact damage context is present and reports zero damage, the item **Spawn Surface Effect** action does not run on a non-shield collider. A Shield Collider is the explicit exception. If a harmless hit still needs feedback, use an impact configuration whose action actually runs for that case and verify it in Play Mode.

## Understand pairing and fallbacks

Think of Surface Types as a matrix. For example:

| Surface Type | Bullet Hit | Footstep |
| --- | --- | --- |
| Wood | `BulletHitOnWood` | `FootstepOnWood` |
| Metal | `BulletHitOnMetal` | `FootstepOnMetal` |

At runtime Surface Manager resolves the pair in this order:

1. Use the incoming Surface Impact, or **Fallback Surface Impact** when the incoming value is null.
2. Detect the Surface Type, or use **Fallback Surface Type** when no type is detected.
3. Look for that Surface Impact in the resolved Surface Type's **Impact Effects**.
4. If the pair is missing and the detected type was not already the fallback, try the same impact on **Fallback Surface Type**.
5. If it is still missing, try **Fallback Surface Impact** on the current resolved type.
6. Spawn nothing when no Surface Effect is found.

Surface Manager caches Surface Identifier, renderer, texture, decal permission, and Surface Type impact maps. Treat the pair matrix as edit-time configuration: stop Play Mode after changing a mapping or collider hierarchy, then start a fresh test.

## Check the editor setup

Before Play Mode, confirm:

- The scene has the intended Surface Manager, Decal Manager, and Object Pool configuration.
- Every test collider resolves a distinct Surface Type through a Surface Identifier or texture mapping.
- Each Surface Type contains one pair for every Surface Impact being tested.
- The pair points to this Surface Effect and no duplicate Surface Impact precedes it.
- Audio uses either Audio Config or the raw clip route intentionally.
- Every spawned particle or debris prefab has an appropriate pool-return or removal component.
- Every decal prefab has a root Mesh Filter, mesh, Renderer, and material; the receiver allows decals.
- Force and damage are configured through impact actions rather than assumed to come from Surface Effect.
- Fallback assets and fallback decal permission match the desired unknown-surface behavior.

Save everything and start a new Play Mode session so the manager builds its caches from the final setup.

## Verify on multiple surfaces in Play Mode

1. Place adjacent Wood and Metal colliders, each with a Surface Identifier and its matching Surface Type.
2. On both Surface Types, pair one Bullet Hit Surface Impact with deliberately different effects. Give the metal effect a spark particle and ricochet audio; give the wood effect dust and a different clip.
3. Trigger the same Bullet Hit source on Wood. Confirm only the wood objects, audio, decal, and optional state run at the hit.
4. Trigger it on Metal without changing the source. Confirm the manager chooses the metal pair instead.
5. Walk a character across both colliders with one Footstep Surface Impact mapped on both types. Confirm the sound changes at the boundary and footprint orientation alternates correctly where decals are allowed.
6. Disable **Allow Decals** on one receiver, restart Play Mode, and repeat the hit. Audio and spawned objects should remain while the decal is absent.
7. Test an unmapped Surface Impact and an object with no detectable Surface Type. Confirm the configured fallback response, including its decal policy, or confirm that no effect is the intended result.
8. Fire a same-frame burst. Confirm **Min Audio Clip Frame Interval** limits the shared asset as configured, spawned particles return to the pool, and Decal Manager keeps its active/weathered counts bounded.
9. Repeat enough times to observe random entries. Every spawned-object entry should follow its own probability, while a decal trigger should select no more than one decal.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| No response plays | The source Surface Impact, detected Surface Type, or pair is missing | Assign the same Surface Impact at the source and in the Surface Type, then assign a Surface Effect to the pair. |
| The wrong material response plays | A fallback is resolving, the collider has the wrong Surface Identifier, or the manager cached an earlier setup | Verify the collider's type, temporarily clear fallbacks, and restart Play Mode after the correction. |
| Unity warns about a duplicate Surface Impact | The Surface Type contains the same Surface Impact more than once | Keep one pair; only the first duplicate is used. |
| Audio Clips and volume controls disappear | Audio Config is assigned | Configure the Audio Config, or clear it to use the raw AudioClip fields. |
| Audio is missing during a burst | **Min Audio Clip Frame Interval** is throttling a Surface Effect shared by several contacts or characters | Use `-1` for no throttle or reduce the interval, then retest the complete burst. |
| A particle or debris object never leaves the scene | Surface Effect spawns it but does not own its cleanup | Add Particle Pooler, Remover, or another explicit pool-return lifecycle; stop looping particles when appropriate. |
| The target receives no force or damage | Surface Effect has no built-in gameplay force or damage response | Add the matching Impact Action. Use Directional Constant Force only for a spawned prefab's gravity-relative motion. |
| A decal never appears | The effect has no valid prefab, the receiver blocks decals, fallback decals are disabled, or the edge test rejects the hit | Verify the prefab components and permission, test near the center, then adjust overlap only as needed. |
| A decal scale is unexpected | A non-`1` sampled value replaces decal X/Y and sets Z to `1` | Author the prefab for that behavior or keep Min/Max Scale at `1` to preserve its local scale. |
| Footprints spin like impact decals | The source used the ordinary overload, or the resolved Surface Type does not allow footprints | Use Character Foot Effects or another footprint-aware call and verify the Surface Type's serialized footprint setting. |
| The optional state affects the wrong object or never resets | **State Name** is absent on the hit transform's GameObject, or **State Disable Timer** is `-1` | Put the state on the hit object and use a finite timer, or disable the state explicitly from project code. |
| Inspector edits do not affect later hits | Surface Manager already cached the collider or pair | Stop Play Mode, make the edit, and begin a fresh session. |
| Multiplayer shows duplicate or different random feedback | Surface Effect resolution and random selection were invoked independently on several peers | Choose one networking authority and replicate the impact or cosmetic result deliberately; do not assume Surface Manager synchronizes it. |

## Related pages

- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)
- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/)
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/)
- [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/)
- [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/)
- [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/)
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/)
- [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/)
- [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

`SurfaceEffect`, `SurfaceImpact`, `SurfaceType`, `SurfaceIdentifier`, `SurfaceManager`, and `DecalManager` are in `Opsive.UltimateCharacterController.SurfaceSystem`. `SurfaceManager.SpawnEffect` has regular and footprint-aware static overloads, with optional explicit Collider parameters. They accept a `RaycastHit`, Surface Impact, gravity direction, time scale, and originator; footprint overloads also accept direction and flip. The call returns `true` when an effect was resolved and invoked.

`SurfaceEffect.Spawn` and `SpawnFootprint` are virtual extension points. The asset's last decal, last raw AudioClip, audio frame, and sequential index are nonserialized runtime state shared by every caller of that asset. The built-in Surface System raises no dedicated surface-effect event; Character Foot Effects, Jump, Fall, Trajectory Object, and the **Spawn Surface Effect** Impact Action call Surface Manager directly. Add an item **Impact Event** action or a custom wrapper when project code needs a notification.

Surface Effects have no built-in saver. Their selection/throttle state is not persisted, and spawned objects, decals, audio, and temporary states are not automatically restored from a save. Persist the underlying gameplay change separately when it matters.

Surface Manager and Surface Effect do not replicate a result over the network. `ObjectSpawnInfo` uses the shared object pool. Particle Pooler can return through Network Object Pool when the multiplayer define is active, but that cleanup path does not make the original effect invocation authoritative or synchronized. Networked projects must decide where the impact is resolved and prevent local prediction plus replicated execution from spawning the cosmetic response twice.

### Released 3.2.0 source notes

- **Fallback Allow Decals** is applied when the incoming Surface Impact or detected Surface Type is null and the corresponding fallback is substituted. In released 3.2.0, a fallback reached only because a known Surface Type lacks the requested pair is not marked as a fallback for this decal check. Disable decals on sensitive receivers or omit decals from approximate fallback effects when that distinction matters.
- `SurfaceType.AllowFootprints` is serialized with a default of `true`, but the released custom Surface Type Inspector draws only **Impact Effects** and exposes no normal control for it.
- `SurfaceEffect.OnEnable` subscribes `Reset` to the static domain-reset delegate, while released `OnDisable` attempts to unsubscribe `OnEnable` instead. Ordinary project assets generally remain loaded, but custom systems that repeatedly create, enable, and disable Surface Effect instances should not assume the reset subscription is removed.
- Arrays created through custom runtime code must be initialized. Built-in spawn and lookup paths access the spawned-object and decal arrays without consistently guarding against null, whereas editor-created assets serialize them as empty lists.

---

<a id="page-ultimate-character-controller-surface-system-surface-identifiers"></a>

# Surface Identifiers

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/)

Use a Surface Identifier when one Collider should always report one deliberate Surface Type, independent of its Renderer, material, or texture.

## Before you begin

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select **Scene > Manager Setup > Add Managers**. Confirm that the scene's **Game** object contains **Surface Manager**, **Decal Manager**, and the shared **Object Pool**.
3. Create a [Surface Impact](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/), [Surface Type](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/), and [Surface Effect](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/).
4. On the Surface Type, add the Surface Impact to **Impact Effects** and assign the Surface Effect. A Surface Identifier chooses the type; it does not create this impact-to-effect mapping.

## Add a Surface Identifier

1. Select the GameObject that owns the Collider receiving the hit. Prefer the exact Collider GameObject when a hierarchy contains more than one surface.
2. Select **Add Component** and add **Surface Identifier**.
3. Assign **Surface Type**.
4. Leave **Allow Decals** enabled if effects may place decals or footprints on this Collider. Disable it when decals would float, clip, stretch, or be inappropriate for that object.
5. Apply the component to the prefab when every instance should use the same identity.

The released Version 3.2.0 component has two fields:

| Field | Released default | Decision |
| --- | --- | --- |
| **Surface Type** | `None` | Assign the type that describes the Collider. When left `None`, the identifier does not force a fallback; Surface Manager continues to texture, material, and terrain detection. |
| **Allow Decals** | Enabled | Disable to veto decals on this Collider. Enabling it permits decals but does not override a Surface Effect with no decal or a fallback route whose decal policy disables them. The value is cached on first lookup. |

## Choose the identifier location

| Object setup | Recommended choice |
| --- | --- |
| One Collider, one logical surface | Put Surface Identifier on the same GameObject as the Collider. This is the fastest and most deterministic lookup. |
| Several child Colliders share one surface | A parent identifier can serve them, but only when no closer child identifier can be discovered first. Exact per-Collider identifiers are clearer in mixed hierarchies. |
| Child Colliders need different surfaces | Put an identifier with the correct type on each Collider GameObject. Do not rely on sibling or child search order. |
| Collider has no Renderer or material | Use Surface Identifier. It works without a Renderer, readable mesh, material, or UV data. |
| One Collider covers several renderer materials | One non-null identifier always returns one type. Split the geometry into separate Colliders and identifiers, or omit the identifier and configure [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/) material detection. |
| Material or texture changes only the appearance | Keep Surface Identifier authoritative when the logical surface is unchanged. Renderer and material edits do not affect its result. |
| Terrain uses several painted layers | Do not use Surface Identifier on the TerrainCollider; Version 3.2.0 explicitly ignores it. Map every Terrain Layer diffuse texture in Surface Manager **Object Surfaces** so the dominant layer at the hit position selects the type. |
| Object is instantiated at runtime | Include the identifier on the spawned prefab before its Collider is queried. A new Collider is cached correctly on its first hit. |

## Understand resolution and fallback order

For a non-terrain Collider, Surface Manager resolves identity in this order:

1. Search the hit Collider's GameObject for **Surface Identifier**.
2. If none exists there, search its children, then its parents.
3. Cache that component reference, including a `null` result, for the specific Collider. Cache **Allow Decals** separately when an identifier is found.
4. If the identifier has a non-null **Surface Type**, return it immediately.
5. Otherwise try the simple main-texture mapping, then multi-material, UV-region, or supported secondary-texture mapping.
6. If those routes fail, try terrain-layer detection. `TerrainCollider` skips the identifier search and reaches this route directly.

After identity detection, Surface Manager resolves the Surface Effect in this order:

1. Replace a missing incoming Surface Impact with **Fallback Surface Impact**. If neither exists, no effect spawns.
2. Replace a missing detected type with **Fallback Surface Type**. If the resulting type is null or has no **Impact Effects**, no effect spawns.
3. Try the current Surface Impact on the current Surface Type.
4. If that pair is missing and the fallback type was not already selected, try the current impact on **Fallback Surface Type**.
5. If no effect was found, try **Fallback Surface Impact** on the type from the previous step.
6. If no valid pair exists, nothing spawns.

**Fallback Surface Impact** and **Fallback Surface Type** default to `None`; **Fallback Allow Decals** defaults to enabled. The fallback decal setting is applied when the incoming impact or detected type was initially missing. Released Version 3.2.0 does not mark the later "pair missing, switch to fallback type" branch as a fallback for that decal check. If a fallback effect must never place a decal, give every expected type an explicit pair or use a fallback effect with no decal.

An identifier with **Allow Decals** disabled remains a hard veto. With it enabled, the final result can still suppress decals because the selected Surface Effect has none or because **Fallback Allow Decals** is disabled on an initially missing impact or type.

## Follow the runtime lifecycle

1. Surface Manager initializes **Object Surfaces**, the main-texture property ID, and its scene-level lookup state in `Awake`.
2. A projectile, melee hit, footstep, or project call supplies a `RaycastHit`, the hit Collider, and a Surface Impact.
3. The manager detects the Surface Type. On the Collider's first identifier query, it caches the found component or `null` and copies the current **Allow Decals** value when a component exists.
4. The manager resolves the impact-and-type pair, caching that Surface Type's impact-to-effect dictionary on first use.
5. The selected Surface Effect runs its ordinary or footprint response. Audio, spawned objects, decals, and State activation are independent options on that effect.
6. Later hits reuse the manager's caches. A scene reload or a new Surface Manager starts with fresh caches.

### Runtime change boundaries

Author identifiers before the first hit and keep the Collider hierarchy stable.

| Runtime change | Version 3.2.0 behavior |
| --- | --- |
| Change `SurfaceIdentifier.SurfaceType` on the same component | Supported. The cached component reference is read again on each type query. This is the supported route for dry/wet or intact/damaged identity changes. |
| Set that existing `SurfaceType` to `null` | The identifier stops winning and resolution continues through the remaining cached texture, material, or terrain routes. |
| Change `SurfaceIdentifier.AllowDecals` after first lookup | Not reflected. Surface Manager cached the first Boolean for that Collider. |
| Add or move an identifier after first lookup | Not rediscovered. The earlier component or `null` result remains cached. |
| Remove or replace a cached identifier | The manager does not search again for a replacement. Lower resolver caches and the original decal Boolean can remain in effect. |
| Swap a Renderer, mesh, material, main texture, or hierarchy | Existing renderer, mesh, texture, complexity, and detected-type caches are not rebuilt. Keep a pre-existing identifier and change only its `SurfaceType` when identity must change. |
| Edit Surface Manager **Object Surfaces** or **Main Texture Property Name** | Lookup dictionaries and the shader property ID are initialized in `Awake`; restart Play Mode after authored changes. |
| Edit a Surface Type's **Impact Effects** after it has resolved | Its first impact-to-effect dictionary remains cached. Restart Play Mode to rebuild it. |
| Spawn a new Collider with its configured identifier | Supported. Its first query creates new cache entries. |
| Reuse the same Collider instance from a pool for another surface | The old identifier reference and decal permission remain cached. Reassign the existing identifier's `SurfaceType`; do not change its decal policy between uses. |

There is no public cache-clear or rebuild method. Reload the scene or restart Play Mode when authoring changes must rebuild these maps.

## Editor checkpoint

Before entering Play Mode, confirm that:

- every test object has a Collider included by the test impact's physics query and, except for terrain, an identifier on the exact Collider GameObject;
- **Surface Type** is assigned on each direct identifier, and each type maps the test Surface Impact to an intentional Surface Effect;
- **Allow Decals** is final for the lifetime of each Collider instance;
- a collider-only test object has no Renderer, proving that identity does not depend on visuals;
- a multi-material test either uses separate Colliders and identifiers or has no identifier and is deliberately configured through Surface Manager;
- terrain has no identifier dependency and every relevant Terrain Layer diffuse texture appears once in **Object Surfaces**; and
- fallback impact, type, and decal values are either deliberately configured or deliberately left at their defaults.

## Verify multiple surfaces in Play Mode

1. Create a **Wood** Collider and a **Metal** Collider. Give each an exact Surface Identifier, assign different Surface Types, and map the same test Surface Impact to visibly or audibly distinct effects.
2. Trigger the same impact on both objects. Wood must select the Wood mapping and Metal must select the Metal mapping without consulting their Renderer materials.
3. Disable **Allow Decals** on Metal before entering Play Mode. Trigger an effect that contains a decal on both surfaces; Wood may place it, while Metal must still run its non-decal audio, object, or State response without placing the decal.
4. Hit a collider-only object whose identifier uses Wood. Confirm that it resolves the Wood effect even though no Renderer or material exists.
5. On a multi-material object, assign one non-null identifier and hit different rendered materials. Confirm that every hit uses the identifier's one Surface Type. Remove the identifier in Edit Mode, configure the material mappings, restart Play Mode, and verify material-dependent results separately.
6. Paint two large terrain regions with different mapped Terrain Layers. Hit each region and confirm the dominant diffuse texture selects its Surface Type. Adding Surface Identifier to the TerrainCollider must not change that result.
7. On an existing non-terrain identifier, change `SurfaceType` through project code or the Play Mode Inspector. The next hit must use the new type. After the first hit, changing **Allow Decals** is not a valid runtime switch and should demonstrate the cached original policy.
8. Hit an unconfigured Collider and confirm the deliberate fallback effect, or no response when fallback assets remain `None`. This distinguishes missing identity from a missing impact-to-effect pair.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The wrong Surface Type wins | A Surface Identifier exists on the hit Collider, one of its children, or a parent. The child search runs before the parent search. | Put the intended identifier on the exact Collider GameObject and remove ambiguous nearby identifiers. Restart Play Mode to clear the cached result. |
| A configured material mapping is ignored | The Collider resolves a non-null identifier first. | Keep the identifier as the single authority, or remove it before first lookup and use the Surface Manager material route. |
| An identifier with **Surface Type** `None` uses a texture-mapped type | A null identifier type intentionally allows later resolvers to run. | Assign the intended Surface Type when the component must be authoritative. |
| Surface Identifier on terrain has no effect | `GetSurfaceIdentifier` returns null for `TerrainCollider`. | Map each Terrain Layer diffuse texture in Surface Manager **Object Surfaces**. |
| Adding an identifier at runtime changes nothing | The Collider already cached an identifier or `null`. | Include the identifier on the prefab before its first query, or use a project-owned dynamic resolver. |
| Changing **Allow Decals** at runtime changes nothing | The first identifier lookup cached the Boolean separately from the component reference. | Treat the field as fixed authoring data. Implement a custom response if decal permission must change dynamically. |
| A pooled object keeps its earlier decal policy | The same Collider instance and its cached Boolean were reused. | Keep one decal policy for the pool or use separate prefab pools. Only `SurfaceType` is safe to change on the existing identifier. |
| A Renderer or material swap still reports the old type | Surface Manager cached its renderer, mesh, texture, complexity, or detected type. | Put an identifier on the object before its first hit and change `SurfaceType`, or reload the scene to rebuild manager caches. |
| The correct type is detected but nothing spawns | Its **Impact Effects** has no entry for the incoming Surface Impact, or the chosen fallback type is null/empty. | Add one explicit impact-to-effect pair to the Surface Type and test again after restarting Play Mode. |
| A fallback effect creates an unexpected decal | The primary pair was missing and Version 3.2.0's later fallback-type branch does not apply **Fallback Allow Decals**. | Add the explicit pair or remove the decal from the fallback effect. |
| No decal appears even though **Allow Decals** is enabled | The Surface Effect has no decal, an initially used fallback disables decals, or Decal Manager rejects the placement. | Inspect the resolved effect and fallback policy, then verify the decal prefab and placement with [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/). |

## Related tasks

- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) explains the complete impact, type, and effect relationship.
- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/) configures texture and terrain identity plus the fallback policy.
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) defines what caused the contact.
- [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/) maps that cause to a response for a material identity.
- [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) configures objects, decals, audio, and State activation.
- [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/) covers multi-material, UV, terrain, and cache limitations.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) uses the detected ground type for footsteps and footprints.
- [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/) controls pooled decal placement and lifetime.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reuse of spawned feedback objects.

## Developer reference

`SurfaceIdentifier` is `Opsive.UltimateCharacterController.SurfaceSystem.SurfaceIdentifier`. It exposes writable `SurfaceType` and `AllowDecals` properties. Change only `SurfaceType` after the Collider has been queried:

```csharp
using Opsive.UltimateCharacterController.SurfaceSystem;
using UnityEngine;

public sealed class RuntimeSurfaceIdentity : MonoBehaviour
{
    [SerializeField] private SurfaceIdentifier m_SurfaceIdentifier;
    [SerializeField] private SurfaceType m_WetSurfaceType;

    public void BecomeWet()
    {
        m_SurfaceIdentifier.SurfaceType = m_WetSurfaceType;
    }
}
```

`SurfaceManager.GetSurfaceIdentifier(Collider)` returns the cached hierarchy result for a non-terrain Collider. `GetSurfaceType(RaycastHit, Collider)` returns the detected type. `GetSurfaceEffect(RaycastHit, Collider, SurfaceImpact, ref SurfaceType, ref bool)` also exposes the final fallback-resolved type, effect, and decal decision. The static `SurfaceManager.SpawnEffect` overloads perform the normal response.

Surface Identifier has no `Awake`, enable/disable, update, or destruction lifecycle logic and emits no dedicated events. Built-in projectile, melee, and footstep consumers query Surface Manager; listen to the originating gameplay system or add a project event around the call when other systems need notification.

The component itself does not obtain or return anything from the Object Pool. Surface Effects can spawn pooled objects, and Decal Manager uses the shared pool for decals. Because Surface Manager caches by Collider, disabling and re-enabling the same pooled instance does not create a new identity lookup.

The two fields are ordinary serialized prefab or scene configuration. Runtime property changes are not automatically recorded by a save system or synchronized across a network. To persist or replicate a dynamic surface, save or send a stable project-owned surface key, map it to the local Surface Type asset, and assign the existing identifier's `SurfaceType` before the next impact. Keep `AllowDecals` invariant for that Collider instance.

---

<a id="page-ultimate-character-controller-surface-system-decal-manager"></a>

# Decal Manager

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/)

Use Decal Manager to place pooled impact marks and footprints, reject marks that extend beyond an exposed edge, and gradually retire older marks as new ones arrive.

## Before you begin

Create one direct Surface System response before tuning decal capacity:

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. On **Scene**, under **Manager Setup**, select **Add Managers**.
3. Select the scene's **Game** object and confirm it has exactly one **Surface Manager**, **Decal Manager**, and shared **Object Pool**.
4. Create a [Surface Impact](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/), [Surface Effect](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/), and [Surface Type](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/). Map the impact to the effect in the type's **Impact Effects** list.
5. Add [Surface Identifier](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/) to a test collider, assign the Surface Type, and leave **Allow Decals** enabled.

The runtime can create fallback Decal Manager and Object Pool GameObjects when either singleton is missing, but an explicitly configured **Game** object gives the scene deterministic ownership and settings.

## Configure Decal Manager

Select **Game > Decal Manager** and begin with the released defaults:

| Field | Default | Released Version 3.2.0 behavior |
| --- | --- | --- |
| **Decal Limit** | `100` | When the active decal queue reaches this value, its oldest entry moves to the weathered queue. It is not a hard limit on every visible decal. |
| **Weathered Decal Limit** | `20` | Each transfer into the weathered queue reduces every weathered material's alpha by `1 / Weathered Decal Limit`. When that queue reaches the value, its oldest entry moves to the final fade list. |
| **Remove Fadeout Speed** | `10` | Controls the per-frame interpolation of final-fade alpha toward zero. It is a speed, not a lifetime in seconds. |

Keep **Decal Limit** and **Weathered Decal Limit** at least `1`, and keep **Remove Fadeout Speed** positive. The Inspector does not constrain these integer fields; zero or negative values do not provide a useful bounded lifecycle, and a zero Weathered Decal Limit also makes the weathering division invalid.

Because each queue uses a `>=` comparison, the active and weathered queues normally retain at most one fewer entry than their configured values after a transfer. Decals already in the final fade list are additional. Tune the fields against the project's peak impact rate rather than treating **Decal Limit** as a total object budget.

## Build a compatible decal prefab

Decal Manager expects the decal data on the prefab's root GameObject:

1. Use a simple quad-style mesh whose local forward normal is positive Z. Its first four mesh vertices should represent the four placement-test corners.
2. Add **Mesh Filter** on the root and assign a nonempty mesh with at least four vertices.
3. Add a **Renderer** on the same root and assign a non-null material.
4. Use a transparent material whose color alpha changes the visible result. Decal Manager edits `Renderer.material.color.a` while weathering and resets it to `1` when a pooled instance is reused.
5. Keep the prefab at unit scale when Surface Effect will randomize its size. Avoid adding a Collider that could interfere with the placement raycasts.
6. Save the prefab, create or select a Surface Effect, expand **Decals**, and add the prefab under **Prefabs**. Remove every null list entry.

The built-in placement test reads `MeshFilter.mesh`, the root Renderer, its material, and `mesh.vertices[0]` through `[3]`. A child-only mesh or renderer is not found. An invalid prefab is returned to the pool immediately and no decal remains.

## Choose scale and edge behavior

Configure these fields on **Surface Effect > Decals**:

| Field | Default | Decision |
| --- | --- | --- |
| **Prefabs** | Empty | One prefab is selected randomly. With multiple entries, the immediately previous selection is avoided when possible. |
| **Min Scale** | `1` | Lower bound for the selected decal scale; the Inspector slider range is `0.01` to `2`. |
| **Max Scale** | `1` | Upper bound for the selected decal scale; it cannot be lower than Min Scale in the custom Inspector. |
| **Allowed Decal Edge Overlap** | `0.25` | Shrinks the four tested corner positions toward the mesh origin. Its range is `0` to `0.5`. |

Released Version 3.2.0 treats scale `1` specially. When the random result is exactly `1`, the instance uses the prefab's local scale. For every other result, Decal Manager replaces local scale with `(scale, scale, 1)` rather than multiplying the prefab scale. Authoring the prefab at `(1, 1, 1)` keeps that discontinuity from changing the intended proportions. A footprint may then negate local X to mirror the chosen side.

Edge overlap works as follows:

- `0` raycasts from the first four mesh vertices, requiring support beneath the full tested quad;
- `0.25` tests points halfway from those vertices toward the decal origin; and
- `0.5` skips the four placement raycasts entirely.

There is no **Placement Tests** toggle in released Version 3.2.0. Values below `0.5` always run the test. Each corner ray only needs to hit an eligible collider; it does not require all four rays to hit the original impact collider.

## Decide whether a decal follows its receiver

After placing a decal `0.001` units above the hit point, Decal Manager checks the hit Transform's local scale:

- A uniformly scaled receiver becomes the decal's parent, so the mark follows its movement and rotation.
- A non-uniformly scaled receiver is not used as the parent. The mark is parented under Decal Manager to avoid inherited distortion, so it stays at its world placement and does not follow that receiver.

There is no **Allow Non Uniform Decals** control in this release. Use `(1, 1, 1)` receiver scale for the most predictable world size, use uniform scale when a mark must follow a moving receiver, or implement a project-owned moving-decal solution for non-uniform objects. Uniform parent scale still contributes to the decal's final world scale.

## Connect impacts and footsteps

A decal request normally travels through the Surface System:

1. A projectile, item action, ability, or another caller supplies a **RaycastHit** and [Surface Impact](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) to Surface Manager.
2. Surface Manager resolves a Surface Type from the hit collider and finds the Surface Effect mapped to that impact.
3. **Surface Identifier > Allow Decals** and the fallback policy determine whether the effect may request a decal. This Boolean is cached per collider on its first lookup, so author it before Play Mode.
4. Surface Effect selects one **Decals > Prefabs** entry and a scale between **Min Scale** and **Max Scale**.
5. A normal impact requests a randomly rotated decal around the hit normal. [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) uses the footprint overload, supplying the character's forward direction and the left/right flip decision.

New Surface Type assets use the footprint path by default. A legacy or custom-authored type whose hidden `Allow Footprints` value is false sends Character Foot Effects through the regular, randomly rotated decal path instead.

**Fallback Allow Decals** gates cases where the Surface Impact or Surface Type was initially missing. Released Version 3.2.0 does not apply that gate reliably when both exist but their pair is missing and Surface Manager later switches to the fallback type. If a fallback must never leave a mark, map it to a Surface Effect with an empty **Decals > Prefabs** list. See [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/) for the full fallback and cache boundaries.

## Tune pooling and lifecycle

Every accepted decal is obtained with the shared Object Pool. A rejected prefab or edge placement is returned immediately. A weathered decal returns to the pool only after its final fade alpha reaches zero; it is disabled and stored beneath Object Pool until the same prefab is requested again.

The limits do not preallocate instances. For a frequently used decal, select **Game > Object Pool**, add a **Preloaded Prefab** row, assign the decal prefab, and set **Count** to a measured warm capacity. Preload only hot prefabs; the pool can still instantiate additional copies when all preloaded instances are active.

Decal lifetime is spawn-driven:

1. New decals remain fully opaque in the active queue.
2. Once **Decal Limit** is reached, each new accepted decal moves the oldest active decal to the weathered queue.
3. Every such transfer reduces the alpha of all weathered decals. If no more decals arrive, their partial weathering stops indefinitely.
4. Once **Weathered Decal Limit** is reached, the oldest weathered decal enters the final fade list.
5. Only final-fade entries update by time. When one reaches zero alpha, Decal Manager returns it to the pool.

Use a separate project component when a mark requires a fixed time-to-live. Decal Manager exposes no per-decal duration and does not retire active or weathered entries merely because time passes.

## Runtime lifecycle

1. The explicit Decal Manager claims the static singleton when enabled. If none exists when a static spawn method is called, the package creates a `DecalManager` GameObject.
2. Surface Effect asks Decal Manager for a regular mark or direction-aware footprint.
3. The manager takes an instance from Object Pool, positions and rotates it at the hit, chooses its parent, applies scale, validates its mesh and material, and restores alpha to `1`.
4. For overlap values below `0.5`, four short raycasts validate the shrunken mesh corners. A failed placement returns to the pool without entering a capacity queue.
5. An accepted decal enters the active queue. New accepted decals drive active-to-weathered and weathered-to-final-fade transitions.
6. Decal Manager enables its per-frame `Update` only while the final fade list has entries, then disables itself again when that list is empty. Static spawn calls still work while the component is disabled.
7. Scene unload resets the static singleton reference. The queues are scene-local and are not carried into another scene.

## Editor checkpoint

Before Play Mode, confirm that:

- the scene has one explicit Decal Manager and Object Pool on **Game**;
- **Decal Limit** and **Weathered Decal Limit** are at least `1`, and **Remove Fadeout Speed** is positive;
- every Surface Effect decal entry references a prefab rather than `None`;
- each prefab root has Mesh Filter, a mesh with at least four meaningful corner vertices, a Renderer, and a transparent alpha-responsive material;
- prefab scale is `(1, 1, 1)` unless the special scale-`1` behavior is intentional;
- every known Surface Type maps the intended Surface Impact to the Surface Effect;
- each receiver has the intended authored **Allow Decals** value before its first lookup;
- moving receivers that must carry marks have uniform scale;
- no-decal fallback effects have an empty **Prefabs** list; and
- optional Object Pool preload counts reflect measured bursts rather than the Decal Manager limits.

## Verify on several surfaces in Play Mode

1. For an observable test, temporarily set **Decal Limit** to `4`, **Weathered Decal Limit** to `2`, and leave **Remove Fadeout Speed** at `10`.
2. Prepare adjacent wood and metal colliders with different Surface Types. Map the same impact to visibly distinct decal prefabs, and add a third collider whose Surface Identifier has **Allow Decals** disabled.
3. Trigger one impact near the center of each collider. Wood and metal should select their mapped marks; the no-decal collider should still run any configured audio or spawned object but leave no mark.
4. Trigger regular impacts several times on one surface. Confirm their rotation varies and the Surface Effect does not immediately repeat the same prefab when alternatives exist.
5. Trigger footsteps with distinct left/right flip settings. Confirm footprints face with the character and only the configured side mirrors.
6. Hit the center and exposed edge of a large plane with overlap below `0.5`. Confirm the center passes and an unsupported corner is rejected. Repeat at `0.5` and confirm the edge test is skipped.
7. Place marks on a uniformly scaled moving receiver and a non-uniformly scaled moving receiver. Confirm only the uniformly scaled target carries its mark.
8. Spawn enough accepted decals to exceed both small queue thresholds. Confirm older marks weather in arrival order, final-fade entries disappear smoothly, and disabled pooled instances accumulate beneath Object Pool for reuse.
9. Stop spawning while a mark is only partly weathered. Confirm it remains at that alpha, demonstrating that weathering is driven by later accepted decals rather than elapsed time.
10. Restore the production limits, repeat the expected peak burst, and inspect the Hierarchy, rendered result, and Profiler for acceptable active, weathered, fading, and pooled counts.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| No decal appears, but audio or particles do. | Check **Allow Decals**, the resolved impact/type/effect pair, **Decals > Prefabs**, fallback policy, prefab validity, and edge rejection. | Correct the authored route, remove null prefab entries, and test a valid quad prefab at the center of a large receiver. |
| A spawn logs a null-reference exception. | A selected **Prefabs** element is `None`; Decal Manager's low-level spawn path assumes a non-null original. | Remove every null entry and keep the list empty when the effect should not request a decal. |
| The decal appears to spawn and immediately disappears. | The prefab lacks a root Mesh Filter, mesh, Renderer, or material, or a corner placement ray missed. | Put all required components on the prefab root and test with a simple four-corner quad away from edges. |
| Edge rejection is inconsistent. | The first four mesh vertices are not the intended corners, another eligible collider satisfies a corner ray, or overlap is `0.5` and skips testing. | Use a predictable quad mesh, isolate the test geometry, and select a value below `0.5`. |
| Old decals never begin weathering. | The active queue has not reached **Decal Limit**, or no accepted decals arrived afterward. | Lower the threshold for the test or generate more accepted marks. Use a custom time-to-live for age-based removal. |
| A partly faded decal remains forever after impacts stop. | It is still in the weathered queue; only new accepted decals change weathered alpha. | Continue spawning until it enters the final fade list, or implement a time-based lifecycle. |
| More decals are visible than **Decal Limit**. | Active, weathered, and final-fade queues coexist; the field is not a total cap. | Budget all three queues, increase fade speed, reduce both queue thresholds, or own a hard-cap policy in project code. |
| Final-fade decals do not disappear. | **Remove Fadeout Speed** is zero/negative, or **Weathered Decal Limit** is invalid. | Restore positive values; the released defaults are `10` and `20`. |
| A decal pops out instead of fading visibly. | The material is opaque or its shader does not use color alpha for transparency. | Use a transparent shader/material whose visible alpha follows `Renderer.material.color.a`. |
| A mark is too large, stretched, or changes size unexpectedly. | The prefab is not unit scale, the chosen scale is exactly `1` versus another value, or a uniformly scaled parent contributes to world scale. | Author the prefab at unit scale, use a controlled Min/Max range, and keep receiver scale at `(1, 1, 1)` where practical. |
| A mark does not follow a moving non-uniform object. | Version 3.2.0 parents it under Decal Manager to avoid inherited distortion. | Use a uniformly scaled receiver or a project-owned moving-decal implementation. |
| Changing **Allow Decals** during Play Mode has no effect. | Surface Manager cached the Boolean for that collider during its first identifier lookup. | Author it before the first hit, reload the scene, or implement the dynamic gate outside the built-in cache. |
| A fallback creates a decal with **Fallback Allow Decals** disabled. | The original impact and type existed but their pair was missing; the later fallback-type route bypasses that gate. | Add the explicit pair or use a fallback Surface Effect whose **Prefabs** list is empty. |
| Footprints rotate randomly instead of facing the character. | A legacy/custom Surface Type has hidden `Allow Footprints` disabled, or the call used the regular decal path. | Use the footprint path and verify Character Foot Effects direction/flip inputs. New Surface Types default to footprints enabled. |
| Pool errors or stale marks appear after project code removes a decal. | The instance was destroyed or disabled outside Decal Manager/Object Pool ownership. | Let Decal Manager retire its marks, or use `ObjectPoolBase.Destroy` only for project-owned instances created by that same pool. |

## Related tasks

- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) explains the complete impact, type, and effect relationship.
- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/) resolves Surface Types and fallback policies.
- [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) configures decal prefabs, scale, and edge overlap.
- [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/) assigns the receiver's Surface Type and decal permission.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) supplies footprint direction and mirroring.
- [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/) covers caching, fallback, terrain, and multi-material boundaries.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains shared pooled-object ownership and preloading.

## Developer reference

`DecalManager` is in `Opsive.UltimateCharacterController.SurfaceSystem`. Its public configuration properties are `DecalLimit`, `WeatheredDecalLimit`, and `RemoveFadeoutSpeed`.

`DecalManager.Spawn(GameObject, RaycastHit, float, float)` places a regular, randomly rotated decal. `DecalManager.SpawnFootprint(GameObject, RaycastHit, float, float, Vector3, bool)` uses a direction and optional X-axis flip. Both methods are static, return `void`, and bypass Surface Manager's impact mapping, identifier permission, and fallback policy when called directly. They do not report whether prefab validation or the edge test rejected the placement.

The active, weathered, final-fade, renderer, and mesh collections are private. There is no public per-decal remove method, count query, placement-result event, fixed-lifetime setting, or queue-reset API. Derive a separate project system when those controls are required rather than editing the manager's internal lists.

Decals are transient visual feedback. Decal Manager does not save them, restore them after a scene load, or send a network message. A multiplayer game must reproduce an impact request on the clients that should see it and provide matching Surface System assets; Decal Manager itself performs no replication. Pool returns and scene-unload cleanup also publish no gameplay event.

---

<a id="page-ultimate-character-controller-surface-system-character-foot-effects"></a>

# Character Foot Effects

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/)

Use Character Foot Effects to detect each step, raycast to the ground below it, and let the Surface System choose the audio, decal, particle, or other response for the material under the character.

## Before you begin

Set up one complete footstep response before tuning detection:

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. On **Scene**, under **Manager Setup**, select **Add Managers**. Confirm the scene's **Game** object has **Surface Manager**, **Decal Manager**, and the shared **Object Pool**.
3. In the Project window, choose **Assets > Create > Opsive > Ultimate Character Controller > Surface Impact**, save the asset as `Footstep`, and review [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/).
4. Choose **Assets > Create > Opsive > Ultimate Character Controller > Surface Effect** for each response, such as wood audio, metal audio, a dust particle, or a footprint decal. See [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/).
5. Select each [Surface Type](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/). Add an **Impact Effects** element, assign `Footstep` to **Surface Impact**, and assign that material's response to **Surface Effect**.
6. Give each test floor collider a [Surface Identifier](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/), assign its **Surface Type**, and leave **Allow Decals** enabled only where a footprint decal is appropriate.
7. Confirm the character has Ultimate Character Locomotion, Character Layer Manager, an Animator Monitor, and an Animator before adding foot effects through Character Manager.

The detector and Surface System are separate. A correctly timed step can still be silent when its Surface Impact, detected Surface Type, or mapped Surface Effect is missing.

## Add Character Foot Effects

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Assign the scene model for a new character, or assign the Ultimate Character Locomotion root to **Character** for an existing character. Verify every **Character Model** row and its Animator Controller.
3. Enable **Foot Effects**. It starts enabled for a new character.
4. Select **Build Character** for a new character or **Update Character** for an existing character.
5. Select each animated model below the character root. Character Manager adds **Character Foot Effects** to the same GameObject as its Animator Monitor.
6. For a Humanoid Animator, verify that **Feet** references the left and right toe bones when available, otherwise the foot bones. The builder flips the generated right-foot entry and, when a foot has no Audio Source, adds one with **Volume** `0.4`, **Spatial Blend** `1`, and **Max Distance** `20`.
7. For a Generic Animator or custom rig, assign the contact transforms manually. Character Manager cannot infer non-humanoid feet.
8. Expand **Character Foot Effects > Footprint**, assign the `Footstep` **Surface Impact**, select **Footstep Mode**, and tune the fields for that mode.

Character Foot Effects starts with **Body Step** as the serialized mode. Its released field defaults are:

| Field | Default | Purpose |
| --- | --- | --- |
| **Surface Impact** | None | Identifies the footstep when Surface Manager chooses a response. |
| **Footstep Mode** | **Body Step** | Chooses how an automatic step is detected. |
| **Feet** | None | Holds the contact Transforms. Character Manager initializes two entries only when it can resolve a Humanoid head and foot or toe bones. |
| **Foot Offset** | `0.11` | Extends the downward ground raycast. It is not the Body Step height threshold. |
| **Move Direction Frame Count** | `7` | Filters brief foot-direction changes in Body Step mode. |
| **Min Trigger Interval** | `0.1` | Prevents Trigger mode from accepting another step too soon. |
| **Require Movement** | Enabled | Makes Trigger mode ignore contact while horizontal local velocity is nearly zero. |
| **Require Alternating Feet** | Enabled | Makes Trigger mode reject the same foot twice in succession. |
| **Fixed Interval** | `0.3` | Sets the time between Fixed Interval step groups while grounded and moving. |
| **Min Bob Interval** | `0.2` | Sets the minimum time between Camera Bob steps. |

## Choose how a step is detected

| Mode | Use it when | How released Version 3.2.0 detects a step |
| --- | --- | --- |
| **Body Step** | Animated feet make dependable contact and exact left/right timing matters. | While the character is grounded and moving, it watches each configured foot's vertical motion. A descending foot can step after its direction has remained stable for **Move Direction Frame Count** and it is not the last accepted foot. |
| **Trigger** | Physical foot contact is more reliable than animation motion. | A **Footstep Trigger** on the contacting foot calls Character Foot Effects from `OnTriggerEnter`. **Min Trigger Interval**, **Require Movement**, and **Require Alternating Feet** filter the call. The **Feet** array is not used. |
| **Fixed Interval** | A steady cadence is more important than exact contact. | While grounded and moving, it cycles the configured foot groups every **Fixed Interval**. The group origin is raycast even when that particular foot is not touching the ground. |
| **Camera Bob** | A first-person view has a reliable vertical bob. | After a look source is attached, it detects the low point where the view changes from descending to ascending, then cycles a foot group. **Min Bob Interval** suppresses close repeats. |
| **None** | Project code or animation events own the timing. | No built-in automatic detector runs. Use a small relay to call `TriggerFootStep` or `FootStep`; an animation-event mode is not exposed in this Inspector. |

All four automatic routes still end with the same ground raycast and Surface System lookup. Body Step does not compare the foot's height with **Foot Offset**. The offset only increases how far the final ray can reach below the selected origin.

### Configure Trigger mode

For each contacting foot:

1. Add a Collider sized around the contact area and enable **Is Trigger**.
2. Add **Footstep Trigger** to the same GameObject.
3. Set **Flip Footprint** on the side that needs a mirrored decal.
4. Ensure Unity can produce `OnTriggerEnter` for the foot and floor collider. A Character Manager build supplies the character root's kinematic Rigidbody; a manually assembled character still needs a valid Unity trigger/Rigidbody arrangement.
5. Put the floor on a layer that is not the character's layer, **Water**, or one of Character Layer Manager's **Invisible Layers**. Both Footstep Trigger and the final ground ray use the derived `IgnoreInvisibleCharacterWaterLayers` mask.
6. Enter Play Mode and confirm each contact passes **Require Movement**, **Require Alternating Feet**, and **Min Trigger Interval**.

Footstep Trigger ignores contacts outside the character's `IgnoreInvisibleCharacterWaterLayers` mask. It also suppresses steps for three fixed-update intervals after an immediate transform change, which prevents a teleport from creating a false contact.

## Map feet, sides, and groups

Each **Feet** entry contains:

- **Object**: the Transform whose position becomes the step raycast origin;
- **Group**: the group used by Fixed Interval and Camera Bob; every Transform in the active group steps together, then the component advances to the next group; and
- **Flipped Footprint**: mirrors the footprint decal on its local X axis, normally for the right side.

Body Step evaluates feet individually and ignores **Group**. Trigger mode receives its Transform and flip setting from Footstep Trigger, so it ignores the **Feet** list entirely.

For a biped with group-driven placement, place the left foot in group `0` and the right foot in group `1`. For a quadruped, group the contacts that should land together. Keep group numbers contiguous from `0`; an unused group produces an interval with no step.

At `Awake`, a null or zero-length **Feet** list creates one fallback group at the Character Foot Effects GameObject. That fallback is useful for a centered Fixed Interval or Camera Bob sound, but not for separate left/right footprints. It does not make Body Step valid: an empty list detects no feet, and a null list on a non-humanoid can fail when Body Step evaluates it.

Released Version 3.2.0 displays **Feet** only while **Body Step** is selected even though Fixed Interval and Camera Bob reuse serialized groups. To configure those origins in the Inspector, select Body Step, edit **Feet**, then switch to the intended group-driven mode before saving.

The released footprint direction is the forward direction of the GameObject that owns Character Foot Effects. A Feet **Object** supplies position, not facing. Align the model/component transform with the character's forward direction, then use **Flipped Footprint** for side mirroring.

## Choose the surface response

Keep one Footstep Surface Impact and vary the Surface Effect by Surface Type:

| Desired result | Configure it on the mapped Surface Effect |
| --- | --- |
| Positional footstep sound | Under **Audio**, assign **Audio Config** or leave it empty and configure **Audio Clips**, **Min/Max Volume**, **Min/Max Pitch**, **Random Clip Selection**, and **Min Audio Clip Frame Interval**. The footprint path plays audio on the foot originator. |
| Dust, splash, or debris | Under **Spawned Objects**, assign a pool-safe **Object** and set **Probability**. The effect spawns at the ground hit. |
| Left/right footprint | Under **Decals**, assign **Prefabs**, set **Min Scale**, **Max Scale**, and **Allowed Decal Edge Overlap**, enable **Allow Decals** on the Surface Identifier, and configure the foot's flip setting. |
| Surface-specific combinations | Map the same Footstep Surface Impact to a different Surface Effect in every Surface Type. |
| A safe response for an unidentified floor | Surface Manager starts with **Fallback Surface Impact** and **Fallback Surface Type** unassigned, while **Fallback Allow Decals** starts enabled. Assign both fallback assets deliberately. If a fallback must never leave a decal, map it to a Surface Effect whose **Prefabs** list is empty; the released later missing-pair fallback path does not always apply **Fallback Allow Decals**. |

New Surface Type assets serialize `Allow Footprints` as enabled, which selects the direction-aware footprint path. Released Version 3.2.0's custom Surface Type inspector does not draw that field. Use the visible **Surface Identifier > Allow Decals** setting and the Surface Effect's **Decals > Prefabs** list for normal editor authoring. A legacy or custom-authored Surface Type with the hidden field disabled uses the regular response path instead; it still plays audio, spawns objects, applies a State, and can request an ordinary decal.

## How it runs

1. At initialization, the component builds its foot groups. Body Step and Fixed Interval run from `FixedUpdate`; Trigger waits for Footstep Trigger; None waits for project code; and Camera Bob begins after an `ILookSource` attaches.
2. For a locally controlled character, Body Step, Fixed Interval, and Camera Bob return unless Ultimate Character Locomotion reports both **Grounded** and **Moving**. Trigger mode is contact-driven and applies its own optional movement filter instead.
3. The selected placement mode accepts a foot or foot group only while its direction, interval, bob, or contact rules pass.
4. `FootStep` casts from `0.2` units above the selected Transform, down along the character model's local down direction. The base distance is `0.21 + Foot Offset`, with additional reach for vertical movement. Trigger colliders are ignored.
5. Surface Manager resolves the hit collider's Surface Type and pairs it with the configured Surface Impact.
6. With the normal new-Surface-Type default, Surface Effect spawns objects, plays audio on the foot originator, applies its optional State, and asks Decal Manager for a direction-aware footprint. A custom type whose hidden `Allow Footprints` value is false uses the regular response path.
7. Spawned feedback objects and decals use the shared object pool. The surface and decal policies decide whether a footprint decal is permitted.

`FootStep` returns `true` when its ground raycast hits. It ignores the Boolean returned by Surface Manager, so an accepted step can update the last-foot and interval state even when no Surface Effect resolves. Diagnose detection and surface mapping as separate checkpoints.

## Editor checkpoint

Before Play Mode, confirm that:

- Character Manager's **Foot Effects** option produced one Character Foot Effects component for each intended animated model;
- Generic and custom rigs have explicit contact Transforms;
- the Footstep **Surface Impact** is assigned and appears once in every relevant Surface Type's **Impact Effects** list;
- every test floor resolves its intended Surface Type directly or through an intentional fallback;
- Body Step feet move vertically and have sensible left/right flip settings;
- Trigger feet have working trigger Colliders and Footstep Trigger components;
- Fixed Interval or Camera Bob groups are contiguous, alternate as intended, and do not fall back accidentally to the model origin;
- **Foot Offset** is only large enough to reach the expected floor below each origin;
- footprint receivers use the intended **Allow Decals** value, their Surface Effects contain the intended decal prefabs, and any no-decal fallback effect has an empty decal list;
- every decal or spawned-effect prefab is configured for pooling and has a bounded lifetime.

## Verify on several surfaces in Play Mode

1. Place adjacent wood and metal floor colliders. Give each a distinct Surface Type and map the same Footstep impact to clearly different audio. Add a third test floor whose Surface Type has no matching Footstep pair so the configured fallback can be tested without editing an asset during Play Mode.
2. Walk entirely on wood. Confirm the chosen mode produces one sensible step per intended contact and only the wood response plays.
3. Cross slowly onto metal. Confirm the response changes according to the surface directly below each accepted foot, not the character root.
4. Add distinct left and right footprint decals. Confirm their positions alternate, face with the character model, and the configured side is mirrored.
5. Test a small step, slope, and descending motion. Increase **Foot Offset** only if the ground ray misses; do not use it to retime Body Step.
6. For Trigger mode, stop moving with one trigger touching the floor, then start again. Confirm **Require Movement**, alternating-foot filtering, and the minimum interval prevent duplicate contacts.
7. For Fixed Interval or Camera Bob, compare walking and running States with different interval presets. Confirm the cadence changes without double-playing a foot group.
8. Walk onto the intentionally unmapped floor. Confirm Surface Manager uses the intended fallback and that a no-decal fallback remains decal-free.
9. Repeat steps rapidly and watch the Hierarchy and audio output. Pooled objects should return correctly, decal limits should hold, and **Min Audio Clip Frame Interval** should suppress any unacceptable same-frame duplicates.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| Character Foot Effects was not added. | The selected model has no Animator Monitor/Animator, or the Character Manager update did not include **Foot Effects**. | Add the required animated-character components, enable **Foot Effects**, and use **Update Character**. For a Generic rig, verify and configure the component manually. |
| Body Step never fires or logs a null-reference exception. | The character is not grounded and moving, **Feet** is empty or null on a non-humanoid, a Feet **Object** is null, or the animation does not produce stable vertical motion. | Assign every real contact Transform, remove null elements, and tune **Move Direction Frame Count** while observing the animated bones. Do not rely on the group fallback for Body Step. |
| Changing **Foot Offset** does not retime Body Step. | The offset controls the final raycast distance, not the Body Step motion threshold. | Tune the animation/mode and **Move Direction Frame Count** for timing; use **Foot Offset** only for ray reach. |
| Trigger mode never fires. | The foot lacks an **Is Trigger** Collider or Footstep Trigger, the Rigidbody arrangement cannot produce `OnTriggerEnter`, the floor is on Water, the character layer, or an **Invisible Layers** entry, or a movement/alternation/interval rule rejects it. | Correct the Collider, Rigidbody, and layer setup, then temporarily relax one Trigger filter at a time. |
| A step is detected but no sound or particle plays. | `FootStep` can succeed from a ray hit even when Surface Manager cannot resolve a valid impact/type/effect pair. | Verify the assigned Surface Impact, detected Surface Type, explicit **Impact Effects** mapping, and fallback separately. |
| Sound plays but no footprint appears. | The receiver disallows decals, **Decals > Prefabs** is empty, the decal prefab lacks the mesh/renderer data Decal Manager needs, the edge test rejects it, or a legacy/custom Surface Type has hidden `Allow Footprints` disabled. | Enable **Allow Decals**, assign a valid decal prefab, and test away from edges. New Surface Types default to the footprint path; use a project editor tool when an older asset's hidden value must be changed. |
| Both footprints appear together or at the model center. | Group assignments are the same, or **Feet** is empty and the component created one fallback group. | Configure separate left/right groups under Body Step, then restore Fixed Interval or Camera Bob. |
| Fixed Interval or Camera Bob skips a cadence with no response. | The serialized group numbers contain a gap, so the active group can be empty. | Edit **Feet** while Body Step is selected and renumber the groups contiguously from `0`, then restore the intended mode. |
| Footprints face sideways. | Released Version 3.2.0 uses the Character Foot Effects GameObject's forward direction, not the foot Transform's forward direction. | Align the model/component transform with character forward and use the flip setting only for mirroring. |
| Camera Bob produces no steps. | No look source is attached, the view has no vertical bob, the character is not grounded/moving, or **Min Bob Interval** is too large. | Attach the camera/look source, enable a visible bob, and verify the locomotion conditions before reducing the interval. |
| Trigger steps repeat or disappear after teleporting. | The minimum interval, alternating-foot filter, or built-in post-teleport suppression rejected the contact. | Test after three fixed updates, verify each Footstep Trigger passes the correct foot Transform, and tune the trigger filters. |
| Footsteps are too loud or effects accumulate. | Several feet share a group, two detectors are active, audio has no frame interval, or spawned feedback does not return to the pool. | Keep one timing route per model, correct the groups, configure **Min Audio Clip Frame Interval**, and use pool-safe finite effects. |
| An animation event cannot select Footstep mode. | Released Version 3.2.0 has no Animator Event entry in **Footstep Mode**. | Select **None** and use a project relay that calls `TriggerFootStep` or `FootStep`. |
| A fallback footprint appears even with **Fallback Allow Decals** disabled. | The detected impact and type existed, but their pair was missing; Version 3.2.0's later fallback-type path does not mark that lookup as a fallback for the decal check. | Add the explicit pair, or use a fallback Surface Effect with an empty **Decals > Prefabs** list. |

## Related tasks

- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) explains the Surface Impact + Surface Type + Surface Effect relationship.
- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/) configures texture detection and fallbacks.
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) creates the shared Footstep identity.
- [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/) maps each floor material to its response.
- [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) configures audio, particles, decals, and State changes.
- [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/) assigns a deterministic Surface Type to a floor collider.
- [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/) controls footprint placement tests and decal limits.
- [Advanced Surface System Topics](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/) explains caches, terrain, multi-materials, and runtime boundaries.
- [Generic Character](https://opsive.com/support/documentation/ultimate-character-controller/character/generic-character/) covers manual non-humanoid setup.
- [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/) explains Audio Config assets and runtime playback.

## Developer reference

`CharacterFootEffects` is in `Opsive.UltimateCharacterController.Character`. Its public configuration includes `FootstepMode`, `SurfaceImpact`, `Feet`, `MoveDirectionFrameCount`, `FootOffset`, `MinTriggerInterval`, `RequireMovement`, `RequireAlternatingFeet`, `FixedInterval`, and `MinBobInterval`.

`TriggerFootStep(Transform, bool)` applies movement, interval, alternating-foot, and teleport filters before calling the virtual `FootStep(Transform, bool)`. `FootStep` bypasses those Trigger filters, performs the ground raycast, and forwards it to the footprint overload of `SurfaceManager.SpawnEffect`. Override `FootStep` only when the project needs a different contact query or additional bookkeeping.

There is no built-in Animator Event mode. For deliberately authored animation timing, select **None** and put a small relay on the Animator GameObject:

```csharp
using Opsive.UltimateCharacterController.Character;
using UnityEngine;

public sealed class FootstepAnimationRelay : MonoBehaviour
{
    [SerializeField] private CharacterFootEffects m_FootEffects;
    [SerializeField] private Transform m_LeftFoot;
    [SerializeField] private Transform m_RightFoot;

    public void LeftFootstep()
    {
        m_FootEffects.FootStep(m_LeftFoot, false);
    }

    public void RightFootstep()
    {
        m_FootEffects.FootStep(m_RightFoot, true);
    }
}
```

Add `LeftFootstep` and `RightFootstep` Animation Events to the clips at contact. This relay calls `FootStep`, so each event still performs the ground raycast but bypasses the Trigger-only filters. Call `TriggerFootStep` instead when the animation events should obey **Require Movement**, **Require Alternating Feet**, **Min Trigger Interval**, and teleport filtering. Those fields are hidden while **None** is selected; configure them while **Trigger** is selected, then switch back to **None**.

`SurfaceType.AllowFootprints` is public read-only at runtime and its backing `m_AllowFootprints` field defaults to `true`, but the released custom inspector draws only **Impact Effects**. A project that must change an existing asset's hidden value should do so through a controlled editor tool using `SerializedObject`, then verify whether the direction-aware or regular decal path is intended.

The component listens for `OnCharacterAttachLookSource`, `OnCharacterChangePerspectives`, `OnCharacterMoving`, and `OnCharacterImmediateTransformChange` to prepare Camera Bob data, delay the first moving step, and suppress teleport contacts. It does not publish a separate footstep event.

Footstep feedback is transient and is not saved. The component does not send a footstep network message. With the UCC multiplayer define enabled, non-authoritative, non-local remote characters gate the `FixedUpdate`-driven modes on interpolated movement plus a ground raycast; each client still needs matching Surface System assets and pooled feedback. Trigger or project-invoked calls are not sent by Character Foot Effects itself.

---

<a id="page-ultimate-character-controller-surface-system-advanced-surface-system-topics"></a>

# Advanced Surface System Topics

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/advanced-surface-system-topics/)

Use these workflows when a basic Surface Identifier is not enough: one renderer contains several materials, a terrain blends textures, a runtime object changes material identity, or frequent impacts need stricter control over decals, pooling, and detection cost.

## Before you begin

Build and verify one simple response first:

1. Add the scene managers with **Tools > Opsive > Ultimate Character Controller > Setup Manager**, **Scene > Manager Setup > Add Managers**.
2. Confirm the scene's **Game** object has **Surface Manager**, **Decal Manager**, and the shared **Object Pool**.
3. Create one Surface Impact, Surface Type, and Surface Effect, then map the impact to the effect in the type's **Impact Effects** list.
4. Add **Surface Identifier** to a test collider, assign the type, and trigger the impact in Play Mode.
5. Continue only after that direct route resolves the expected sound, object, decal, or State.

The advanced resolvers still end at the same Surface Impact + Surface Type mapping. They change how the Surface Type is detected, not what the Surface Effect means.

## Choose the simplest reliable resolver

| Situation | Recommended route |
| --- | --- |
| One collider has one logical material | Add [Surface Identifier](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/). It is the first lookup and avoids texture, UV, terrain, and submesh analysis. |
| Many simple objects share one texture | Add one **Object Surfaces** entry on Surface Manager, assign the Surface Type, select **Add Texture**, and keep **UV** at `(0, 0, 1, 1)`. |
| One mesh uses several renderer materials | Use a readable mesh, a MeshCollider that produces a triangle index, and matching renderer/collider triangle and submesh data. Map every material texture once. |
| One texture atlas represents several surfaces | Prefer separate colliders with Surface Identifiers in released Version 3.2.0. Repeating one texture for several UV regions has an initialization defect described below. |
| Terrain blends several layers | Map each Terrain Layer diffuse texture to its Surface Type. The manager chooses the dominant layer at the hit position. |
| A runtime object changes from dry to wet, clean to dirty, or another identity | Put Surface Identifier on the collider before its first hit and change its `SurfaceType` property. Do not rebuild texture or hierarchy mappings at runtime. |
| The project needs a different query or response | Perform the project-owned detection, use the public diagnostic APIs where helpful, or derive a Surface Effect/Character Foot Effects response. There is no pluggable resolver interface in this release. |

## Follow the detection and fallback order

For each `RaycastHit`, Surface Manager checks:

1. a cached **Surface Identifier** on the hit Collider GameObject, then one found in its children, then one found in its parents;
2. a cached simple main texture mapping;
3. multi-material, UV-region, or supported secondary-texture resolution;
4. the dominant mapped Terrain Layer texture, optionally including terrain trees; and
5. Surface Manager **Fallbacks** when the impact, detected type, or resulting pair cannot produce an effect.

Keep one obvious Surface Identifier near each collider when a hierarchy contains several renderers or identifiers. The first child or parent discovered by the component searches is cached; rearranging that hierarchy later does not force a new search.

The fallback chain is pair-based:

- a missing Surface Impact is replaced by **Fallback Surface Impact**;
- a missing Surface Type is replaced by **Fallback Surface Type**;
- when the resolved type has no mapping for the current impact, Version 3 next tries the current impact on **Fallback Surface Type**;
- if that still has no effect, it tries **Fallback Surface Impact** on that fallback type; and
- if no valid pair exists, nothing spawns.

Do not use fallbacks to hide incomplete core mappings. Add an explicit Impact Effect entry to every known Surface Type, then reserve fallbacks for genuinely unknown inputs.

Released Version 3.2.0 applies **Fallback Allow Decals** when the impact or type was initially missing. It does not mark the later “pair missing, switch to fallback type” path as a fallback for that decal check. When a fallback effect must never create decals, omit decals from that effect or provide every expected explicit pair.

## Map textures and multiple materials

### One texture per surface

1. Select **Surface Manager** on the scene's **Game** object.
2. Add an **Object Surfaces** row and select it.
3. Assign its **Surface Type**, select **Add Texture**, and assign the exact texture used by the material.
4. Leave **UV** at `(0, 0, 1, 1)` for the complete texture.
5. Set **Main Texture Property Name** to the shader property that holds the texture. The released default is `_BaseMap`; a shader using `_MainTex` or a custom name must be configured explicitly before Play Mode.
6. Restart Play Mode after changing the list or shader-property name so the manager rebuilds its lookup dictionaries and property ID in `Awake`.

A material with no usable texture cannot participate in texture mapping. Add Surface Identifier to its collider instead.

### Multiple renderer materials

The released resolver can identify the hit submesh, but only when all of these conditions are true:

- the physics hit supplies `triangleIndex`, which requires a MeshCollider;
- Surface Manager can find an enabled, non-skinned Renderer on the collider, a child, or a parent;
- it can find a readable MeshFilter mesh or readable MeshCollider shared mesh with triangle data;
- the hit triangle indexes correspond to the Renderer mesh submeshes; and
- the Renderer has a non-null shared material at the resolved submesh index.

This corrects the legacy claim that a MeshCollider itself prevents multi-material detection. In Version 3.2.0 the MeshCollider hit is required for the triangle/submesh path. Detection still fails when collider and renderer meshes do not share the same logical triangle layout, when Read/Write is disabled, or when static batching changes the mesh relationship. Use separate single-material colliders with Surface Identifiers when that relationship cannot be guaranteed.

### UV regions and secondary textures

The Inspector exposes repeated **UV** rectangles, and the runtime can compare an adjusted `RaycastHit.textureCoord` against a region. However, released Version 3.2.0 also inserts every configured texture into a single texture-to-surface dictionary with `Add`. Registering the same atlas texture more than once can throw a duplicate-key exception during Surface Manager `Awake` before those UV mappings are usable.

For this release, do not build production detection around repeated atlas entries. Split the geometry or colliders and assign Surface Identifiers, use distinct textures, or maintain a bounded project resolver. A UV region also requires a MeshCollider; a Unity primitive Collider does not provide the needed triangle/texture-coordinate route.

The built-in secondary-map path recognizes material properties named `_Mask` and `_MainTex2`. It reads the mask texture pixel at the hit UV and selects the secondary texture when alpha exceeds `0.5`. The mask must be a readable `Texture2D`; otherwise use a Surface Identifier or project-specific material resolver.

## Detect terrain and trees

1. Add each Terrain Layer's **Diffuse Texture** to the appropriate Surface Manager **Object Surfaces** mapping.
2. Trigger impacts on clearly dominant areas first. The manager samples the terrain alphamap cell at the hit position and chooses the layer with the highest weight; it does not blend two Surface Effects.
3. Test painted boundaries repeatedly and decide whether a dominant-layer switch is acceptable for footsteps and impacts.
4. Leave **Detect Terrain Tree Textures** disabled unless trees genuinely need texture resolution. It starts disabled and its tooltip correctly warns that the operation is CPU intensive.

Tree detection iterates terrain tree instances, obtains a prototype object through the pool, positions it, synchronizes physics, and raycasts its Collider until a texture is found. Use direct identifiers on independently instantiated tree prefabs or another project-owned lookup for frequent impacts in a large forest.

Terrain lookup also uses the same texture-to-surface dictionary initialized from **Object Surfaces**. One exact texture should map to one Surface Type.

## Plan runtime surface changes around the caches

Surface Manager caches identifiers, decal permission, renderers, meshes, main textures, simple detected types, terrain components, and impact-to-effect dictionaries. Its Object Surfaces maps and main texture property ID are initialized in `Awake`.

| Runtime change | Released-Version-3 behavior |
| --- | --- |
| Change `SurfaceIdentifier.SurfaceType` on an identifier that existed before detection | Supported for later type queries because the cached identifier reference is read again. |
| Change `SurfaceIdentifier.AllowDecals` after the first lookup | Not reflected; decal permission is cached as a Boolean per Collider. |
| Add or move a Surface Identifier after the Collider was queried | Not rediscovered; the earlier component or null result remains cached. |
| Swap a Renderer, Mesh, material, main texture, or collider hierarchy after detection | Existing cache entries remain; later hits can use the original relationship. |
| Edit Surface Type **Impact Effects** after that type resolved once | The first mapping dictionary remains cached. Duplicate Surface Impact entries also use only the first and log a warning. |
| Edit **Object Surfaces** or **Main Texture Property Name** after `Awake` | The lookup dictionaries or shader property ID are not rebuilt. The public name setter alone does not refresh the ID. |
| Spawn a new, fully configured Collider and identifier | Its first lookup can be cached normally. Keep its hierarchy and identifier stable afterward. |

For a supported wet/dry switch, author both Surface Types, put one Surface Identifier on the collider from the start, and swap only its `SurfaceType`. Keep **Allow Decals** constant. When the renderer itself must change, let Surface Identifier remain the authoritative material identity instead of asking the texture resolver to notice the swap.

There is no public cache-clear or rebuild API. Stop and restart Play Mode for authored changes, reload the scene for a deliberate runtime rebuild, or own the dynamic detection in project code.

## Coordinate impacts, effects, footsteps, and decals

- Give each cause its own [Surface Impact](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/), such as Footstep, Bullet Hit, or Melee Hit. Do not create a different impact for wood and metal; Surface Type owns that distinction.
- In every [Surface Type](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/), keep one **Impact Effects** entry per Surface Impact. The first duplicate wins and later duplicates are ignored with a warning.
- A [Surface Effect](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) can spawn pooled objects, play an Audio Config or clips, activate a State on the hit GameObject, and request one decal. Keep high-frequency footstep effects lighter than rare explosions or heavy impacts.
- **Allow Decals** on Surface Identifier is cached per collider. **Allow Footprints** on Surface Type selects `SpawnFootprint` when true; when false, the manager calls the regular `Spawn` response instead, so audio, objects, State, and an ordinary decal can still run.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) raycasts below the chosen foot and calls the footprint overload. Its `FootStep` method returns success when the raycast hits even if no Surface Effect pair resolves, so diagnose the type/effect mapping separately from footstep timing.

Decal Manager obtains decals through the shared object pool, needs a MeshFilter, mesh, Renderer, and material on the prefab, and can reject a decal by raycasting its first four mesh vertices near an exposed edge. Use a simple quad-style decal mesh.

Current code avoids non-uniform-parent warping by parenting a decal to the hit transform only when that transform has uniform local scale. On a non-uniform target, it parents the decal under Decal Manager instead. The decal therefore remains unwarped but does not follow a moving or rotating receiver; use uniform receiver scale or a project-owned moving-decal solution.

## Control pooling and cost

1. Keep one explicit Surface Manager, Decal Manager, and Object Pool in the scene rather than relying on runtime fallback objects.
2. Use Surface Identifier for frequently hit geometry. It avoids renderer, readable-mesh, submesh, UV, and terrain work after the identifier lookup.
3. Keep **Detect Terrain Tree Textures** disabled for ordinary terrain footsteps and projectiles.
4. Limit complex multi-material hits on high-triangle meshes. Renderer and mesh references are cached, but the resolver still scans submesh triangle arrays to identify the hit material.
5. Tune Decal Manager **Decal Limit**, **Weathered Decal Limit**, and **Remove Fadeout Speed**; released defaults are `100`, `20`, and `10`.
6. Use Surface Effect **Min Audio Clip Frame Interval** to suppress duplicate high-frequency audio, and use Spawned Object **Probability** deliberately.
7. Ensure spawned-effect and decal prefabs are pool-safe and reset their visible state when reactivated. Durable gameplay objects should have their own lifecycle rather than being treated as disposable feedback.

## Editor checkpoint

Before Play Mode, confirm that:

- one direct Surface Identifier test already resolves the intended Surface Impact + Surface Type pair;
- each known Surface Type has one explicit entry for every impact it should handle;
- **Main Texture Property Name** matches the shader before Surface Manager `Awake`;
- each texture is registered once, and no production atlas depends on duplicate UV entries in released Version 3.2.0;
- multi-material objects use a readable, triangle-compatible MeshCollider and Renderer mesh, or direct identifiers instead;
- every Terrain Layer diffuse texture that matters has one mapping, while tree detection is enabled only with a measured need;
- runtime-changing objects start with a stable Surface Identifier and constant decal policy;
- decal prefabs contain the required quad-style mesh and renderer, and moving decal receivers use uniform scale;
- Decal Manager limits, audio frame interval, and spawned-object probabilities match the expected impact rate; and
- fallback assets are deliberate safety nets rather than substitutes for missing primary mappings.

## Verify advanced cases in Play Mode

1. Hit two Surface Identifier colliders with the same Surface Impact and confirm their distinct Surface Types choose different effects.
2. Hit a simple texture-mapped collider without an identifier. Confirm the exact configured texture resolves, then change **Main Texture Property Name** to an incorrect value in Edit Mode and confirm the test fails after a fresh Play Mode start.
3. Test a two-material readable mesh with a MeshCollider. Hit triangles in each submesh and confirm the resolved effect follows the Renderer material. Repeat with mismatched collider geometry and confirm the diagnostic fails rather than assuming a material.
4. On terrain, paint two large dominant regions and cross the boundary with footsteps. Confirm one dominant type is chosen per hit and tree detection remains off.
5. Change a pre-existing Surface Identifier's `SurfaceType` through project code and confirm the next hit uses the new type. Change **Allow Decals** only after the first hit and confirm why that cached permission is not a supported switch.
6. Remove one primary Impact Effect mapping and test the fallback chain. Confirm the resolved type/effect and decal policy, then restore the explicit mapping.
7. Spawn a decal on a uniform stationary receiver, a uniform moving receiver, and a non-uniform moving receiver. Confirm parenting/following behavior and edge rejection are acceptable.
8. Generate enough repeated effects to reach the configured decal and audio limits. Confirm old decals weather/fade and pooled feedback does not accumulate unbounded active objects.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| Surface Manager throws a duplicate-key error during `Awake` | The same texture appears more than once in **Object Surfaces**, commonly for atlas UV regions. | Register each texture once. Use Surface Identifiers, separate textures, or a bounded custom resolver for multiple regions. |
| A multi-material hit always uses fallback | The hit is not from a MeshCollider, `triangleIndex` is unavailable, the mesh is not readable, or collider triangles do not match Renderer submeshes. | Use a readable matching MeshCollider/Renderer mesh or split the colliders and assign Surface Identifiers. |
| A Unity primitive or non-mesh Collider cannot resolve an atlas region | UV-region resolution requires a MeshCollider hit and texture coordinates. | Use Surface Identifier or author a suitable MeshCollider workflow. |
| A material swap still uses the old type | Renderer, main texture, or simple type was cached for that Collider. | Keep a pre-existing Surface Identifier authoritative and change only its `SurfaceType`, or rebuild through a scene reload. |
| Adding Surface Identifier at runtime has no effect | The Collider's earlier identifier lookup cached `null` or another component. | Add the identifier before the first hit or use project-owned resolution for that dynamic object. |
| Changing **Allow Decals** at runtime has no effect | Decal permission was cached during the first identifier lookup. | Treat it as authored configuration or implement the dynamic decision in a custom response. |
| A detected Surface Type ignores a changed Impact Effect | Its impact/effect dictionary was cached on first use. | Author asset mappings before Play Mode and restart the test after edits. |
| Fallback response creates an unexpected decal | The primary pair was missing and the later fallback-type path does not apply **Fallback Allow Decals** in released Version 3.2.0. | Add the explicit pair or use a fallback effect with no decal. |
| Terrain always chooses one material near a blend | Resolution selects the single highest alphamap weight at the hit cell. | Paint a clearer boundary or accept/project a custom blend policy. |
| Tree impacts cause spikes | **Detect Terrain Tree Textures** performs per-tree pooled instantiation, physics synchronization, and raycasts. | Disable it and use direct identifiers or a project-owned tree lookup. |
| A footstep ray hits but no feedback plays | Character Foot Effects found ground, but the Surface Impact + resolved Surface Type pair has no Surface Effect. | Inspect detection and the type's explicit **Impact Effects** mapping separately from foot timing. |
| A decal does not appear | The identifier/fallback disallows it, the Surface Effect has no valid decal, its prefab lacks required components, or the edge test rejects it. | Verify the resolved route, use a quad-style prefab, and test away from an exposed edge. |
| A decal does not follow a non-uniform moving object | Decal Manager parents it under itself to prevent inherited scale distortion. | Use uniform receiver scale or a moving-decal implementation designed for that object. |

## Related tasks

- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) covers the core impact, type, and effect workflow.
- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/) configures Object Surfaces, terrain detection, and fallbacks.
- [Surface Identifiers](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-identifiers/) provides deterministic collider-based type selection.
- [Surface Impacts](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-impacts/) defines the cause of an effect.
- [Surface Types](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-types/) maps causes to effects and controls footprint handling.
- [Surface Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-effects/) configures spawned objects, decals, audio, and State responses.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) configures step detection and footprint placement.
- [Decal Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/decal-manager/) configures limits, weathering, and edge placement.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reusable feedback object ownership.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) configures the optional State activated by a Surface Effect.

## Developer reference

The released surface types are in `Opsive.UltimateCharacterController.SurfaceSystem`. `SurfaceManager.SpawnEffect` has regular and footprint overloads, each with an optional explicit Collider. It returns `true` when it resolves and invokes a Surface Effect. With a component reference, `GetSurfaceType(RaycastHit, Collider)` returns the detected type, while `GetSurfaceEffect(RaycastHit, Collider, SurfaceImpact, ref SurfaceType, ref bool)` exposes the final resolved type, effect, and decal decision.

Use those query methods for a diagnostic before replacing the resolver:

```csharp
using Opsive.UltimateCharacterController.SurfaceSystem;
using UnityEngine;

public sealed class SurfaceDiagnostic : MonoBehaviour
{
    [SerializeField] private SurfaceManager m_SurfaceManager;
    [SerializeField] private SurfaceImpact m_SurfaceImpact;

    public void LogHit(RaycastHit hit)
    {
        var detectedType = m_SurfaceManager.GetSurfaceType(hit, hit.collider);
        SurfaceType resolvedType = null;
        var allowDecals = false;
        var effect = m_SurfaceManager.GetSurfaceEffect(
            hit, hit.collider, m_SurfaceImpact, ref resolvedType, ref allowDecals);

        Debug.Log($"Detected: {detectedType}; Resolved: {resolvedType}; " +
                  $"Effect: {effect}; Decals: {allowDecals}");
    }
}
```

`SurfaceIdentifier.SurfaceType` and `AllowDecals` are writable, with the cache boundaries described above. `SurfaceEffect.Spawn` and `SpawnFootprint` are virtual extension points for a custom response. `CharacterFootEffects.FootStep` is virtual for custom foot detection. `DecalManager.Spawn` and `SpawnFootprint` are lower-level static decal entry points.

Surface Manager's type-resolution methods are public but not virtual, and the package has no resolver interface or cache invalidation API. A project that needs dynamic renderer/material resolution should keep that decision outside the built-in cache, then call a chosen Surface Effect or another project response deliberately.

---

<a id="page-ultimate-character-controller-spawn-system"></a>

# Spawn System

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/)

Use the Spawn System to return characters and world objects at a controlled location after death, disablement, or a manual reset. A Respawner controls when the object returns; Spawn Points control where it can return.

## Choose your route

- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) covers return timing, positioning modes, audio, and the respawn events. Start there when an object already has a destination or should return where it began.
- [Spawn Points](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/spawn-points/) covers candidate locations, groups, shapes, ground snapping, and obstruction checks. Add these when a Respawner should choose among scene locations.

Use both pages for a deathmatch spawn, checkpoint group, or random arena placement. A single object that only needs to return to its original transform can use a Respawner with **Positioning Mode** set to **Start Location** and does not need a Spawn Point.

## Set up the scene

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Scene** tab and, under **Manager Setup**, select **Add Managers**.
3. Select the scene's **Game** GameObject and confirm it has **Spawn Point Manager**. Leave **First Spawn Preferred** disabled for random selection among eligible points. The runtime can create a fallback manager, but an explicit scene manager is easier to inspect and test.
4. Create an empty GameObject at each allowed return location and add the **Spawn Point** component.
5. Set **Grouping** to the pool that should use the point. Use one agreed index per team or checkpoint. Keep both the Respawner and its ungrouped Spawn Points at the default `-1` when no separation is needed.
6. Choose **Shape**:
   - **Point** uses the GameObject's transform.
   - **Sphere** or **Box** defines an area with **Size**. The first candidate is the point's center; when **Check For Obstruction** and **Random Shape Spawn** are enabled, later **Placement Attempts** sample other positions in the area.
7. Set the GameObject's rotation to the required facing direction, or enable **Random Direction**. Use **Ground Snap Height** when placements within an area must be projected onto the ground.
8. For a busy location, enable **Check For Obstruction**, choose **Obstruction Layers**, and leave enough **Placement Attempts** to find a clear candidate. The Version 3 defaults are 20 for **Max Collision Count** and 10 for **Placement Attempts**.

Each enabled Spawn Point registers itself with Spawn Point Manager. Disabled points are removed from selection, so a scene can enable or disable a checkpoint group as the game progresses.

## Configure the respawning object

1. For a UCC character, open **Tools > Opsive > Ultimate Character Controller > Character Manager**, select the character, enable **Health**, and select **Update Character**. This adds **Character Attribute Manager**, **Character Health**, and **Character Respawner**. For an ordinary world object, add **Respawner** to the same GameObject that sends the standard death event or will be disabled and returned.
2. In **Respawner** or **Character Respawner**, choose **Positioning Mode**:
   - **None** keeps the current transform. Use this for an in-place revive or a custom system that has already moved the object.
   - **Start Location** returns to the position and rotation recorded when the Respawner awakens.
   - **Spawn Point** asks Spawn Point Manager for a valid placement.
3. For **Spawn Point**, set **Grouping** to exactly the same value as the eligible points.
4. Set **Min Respawn Time** and **Max Respawn Time**. Version 3 defaults to a random delay from `2` to `3` seconds; use the same value in both fields for a fixed delay.
5. Enable **Schedule Respawn On Death** for the standard UCC death flow. Enable **Schedule Respawn On Disable** for an ordinary object that should return after it is disabled. A Character Respawner cannot restore a character whose root GameObject is inactive, so keep a death-respawn character active and let its health, abilities, and states represent death.
6. On **Character Respawner**, enable **Check For Obstruction** when the complete character collider shape must fit at the selected destination. If blocked, the character waits for another respawn interval and tries again.
7. Optionally configure **Respawn Audio** and **Events > On Respawn Event** for feedback or scene-specific responses.

## Key choices by scenario

| Scenario | Recommended configuration |
| --- | --- |
| Return to the scene start | Use **Start Location**. No Spawn Point is required. |
| Revive where the character fell | Use **None**, disable competing automatic schedules, and let the revive workflow call Respawner when its animation completes. |
| Random arena placement | Give several enabled Spawn Points the same **Grouping**, leave **First Spawn Preferred** disabled, and use obstruction checks for occupied areas. |
| Two teams | Use a separate **Grouping** index for each team's Respawner and Spawn Points, such as `0` and `1`. |
| Checkpoint progression | Give each checkpoint its own group and update the Respawner's **Grouping** when the checkpoint is earned. A group with one enabled point gives a deterministic destination. |
| Preferred fallback location | Enable **First Spawn Preferred** on Spawn Point Manager. It tries the first enabled point registered for that group before shuffling the group; if that point is invalid, other points are still attempted. |
| Respawning pickup or target | Use the ordinary **Respawner** with **Schedule Respawn On Disable** when disabling the object is the intended return trigger. Do not use this pattern for an inactive UCC character root. |

For **Sphere** and **Box**, Spawn Point **Check For Obstruction** evaluates the candidate area and can try another location within the point or another point in the group. A **Point** always supplies its transform, so use Character Respawner **Check For Obstruction** when a character must not return to an occupied point. That character-level check tests whether the character's supported solid colliders fit at the final placement. Use both layers for crowded area-based locations; use only the layer that answers the actual risk in a simpler scene.

## Verify in Play Mode

1. Keep **Spawn Point Manager**, the eligible Spawn Points, and the object's Respawner visible in the Inspector.
2. Trigger the intended death or disable and time the scheduled return. It should occur between **Min Respawn Time** and **Max Respawn Time**. A direct call to `Respawn()` runs immediately unless placement is blocked.
3. Confirm the object returns using the selected **Positioning Mode**. For **Spawn Point**, verify its position belongs to the matching **Grouping** and its rotation follows the point or **Random Direction** setting.
4. With the relevant Spawn Point or Character Respawner obstruction check enabled, occupy one candidate with an object on **Obstruction Layers**. The system should use another valid candidate or wait and retry; it should not place the object in the obstruction.
5. Repeat the cycle several times. Random groups should use more than one valid point, while a single-point checkpoint should remain deterministic.
6. For a character, confirm Health, locomotion, abilities, camera state, and colliders recover after respawn. Check the Console for a missing-group error or repeated placement failure.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console reports that no Spawn Point exists for a grouping index. | The Respawner's **Grouping** does not have an enabled Spawn Point with the same value. | Match the values exactly and enable at least one point in that group. Keep both sides at `-1` for the default ungrouped pool. |
| The character never returns after death. | **Schedule Respawn On Death** is disabled, the character root was deactivated, or every placement is blocked. | Enable death scheduling, keep the UCC character root active, and provide a clear eligible placement. |
| An ordinary object never returns after being disabled. | **Schedule Respawn On Disable** is disabled, or another script destroys the object instead of disabling it. | Enable disable scheduling and use a lifecycle that leaves the Respawner available to the Scheduler. |
| The object returns to the wrong place. | **Positioning Mode**, **Grouping**, or **First Spawn Preferred** does not match the intended scenario. | Select the correct mode, match the group, and disable first-point preference unless that registration-order preference is deliberate. |
| A spawn appears inside geometry. | **Check For Obstruction** is disabled, **Obstruction Layers** omits the blocker, or the point's shape and size do not represent the available space. | Enable the appropriate point or character obstruction check, include the blocking layer, and resize or move the Spawn Point. |
| A Spawn Point area places the object in the air. | **Ground Snap Height** is zero or shorter than the distance to the ground, or the ground layer is excluded. | Increase **Ground Snap Height** and include the ground in **Obstruction Layers**. |
| Respawn happens twice. | More than one system schedules the return, such as death scheduling, disable scheduling, Revive, or custom code. | Choose one owner for the respawn and disable or cancel the competing schedules. |
| A changed Spawn Point is not selected. | The point is disabled, assigned to another group, or a preferred first point always succeeds. | Enable the point, correct **Grouping**, and disable **First Spawn Preferred** when all points should participate randomly. |

## Related tasks

- [Spawn Points](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/spawn-points/)
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/)
- [Revive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)

## Developer reference

`Opsive.UltimateCharacterController.Game.SpawnPoint` registers with `SpawnPointManager` in `OnEnable` and unregisters in `OnDisable`. Its virtual `GetPlacement(GameObject, ref Vector3, ref Quaternion)` method returns `false` when it cannot find a valid placement. `SpawnPointManager.GetPlacement` selects within the requested group, tries **First Spawn Preferred** when enabled, and otherwise shuffles and tests the available points. The manager also exposes `GetSpawnPoints`, `AddSpawnPoint`, `RemoveSpawnPoint`, and `UpdateSpawnPointGrouping`.

`Opsive.UltimateCharacterController.Traits.Respawner` listens for the object-scoped `OnDeath` event and exposes `Respawn()`, `Respawn(Vector3, Quaternion, bool)`, and `CancelRespawn()`. If a Spawn Point or Character Respawner obstruction check fails, Respawner schedules another attempt using the configured time range.

Immediately before a successful return, Respawner sends the object-scoped `OnWillRespawn` event. It then applies the placement when required, activates the object, plays the configured audio, sends `OnRespawn`, and invokes **On Respawn Event** when the object is active in the hierarchy. `CharacterRespawner` sends `OnCharacterImmediateTransformChange` after `OnRespawn` when it moved the character. Subscribe and unsubscribe through the [UCC event system](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) using the same target, name, parameter types, and delegate.

---

<a id="page-ultimate-character-controller-spawn-system-respawner"></a>

# Respawner

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/)

Respawner returns a character or scene object after the standard UCC death event, after disablement, or from a direct call. Use it when the same object should become active again at its current transform, its original transform, or a valid scene Spawn Point.

## Before you begin

- For a UCC character, use **Character Respawner**. Character Manager adds it with Character Health and Character Attribute Manager when **Health** is enabled.
- For an ordinary object, add **Respawner** to the same GameObject that sends `OnDeath` or will be disabled and returned.
- Decide whether Respawner, [Revive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/), a checkpoint system, an object pool, or multiplayer authority owns the return. Configure one owner for each lifecycle.
- Add [Spawn Points](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/spawn-points/) only when the destination should come from a scene group. **Start Location** and **None** do not need them.

Respawner reactivates the same GameObject. It does not instantiate a replacement, restore a destroyed object, or remove an object from an Opsive pool before activation.

## Add Respawner to a character or object

### Character death and respawn

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Select the character, enable **Health**, and select **Update Character**. Confirm the character root has **Character Attribute Manager**, **Character Health**, and **Character Respawner**.
3. Keep the character root active when it dies. Character Respawner does not reactivate an inactive character root; the Die ability, Health, collision layers, renderers, and states represent the dead state while the GameObject remains active.
4. On Character Respawner, leave **Schedule Respawn On Death** enabled and disable any competing automatic Revive or custom return.
5. Choose a **Positioning Mode**, set the respawn delay, then configure optional **Respawn Audio** and **Events > On Respawn Event**.
6. Enable **Check For Obstruction** when the character's supported solid Colliders must fit at the chosen destination. A blocked character waits for another configured respawn interval and tries placement again.

Character Health resets Health and Shield when it receives `OnRespawn`. Ultimate Character Locomotion becomes alive again, the Die ability stops, collision state is restored, and other character systems listening to the same event reset themselves.

### Ordinary world object

1. Add **Respawner** to the same root as the object's Health component or other standard `OnDeath` sender.
2. Enable **Schedule Respawn On Death** when the object sends the UCC death event. Enable **Schedule Respawn On Disable** when `SetActive(false)` or disabling Respawner should start the timer.
3. Keep the object in the scene and disable it for the return interval. Do not destroy it; a destroyed Respawner cancels its scheduled event in `OnDestroy`.
4. If the object was instantiated through `ObjectPoolBase`, let the pool owner respawn it instead of allowing Respawner to activate an object that is still registered as available in the pool.
5. Choose the destination and verify that the object's Health, Collider, renderer, state, and other listeners reset on `OnRespawn`.

## Configure the destination and timing

| Field | Version 3.2.0 default | What it controls |
| --- | --- | --- |
| **Positioning Mode** | **Start Location** | **None** keeps the current transform. **Start Location** uses the position and rotation recorded once during `Awake`. **Spawn Point** asks Spawn Point Manager for a placement. |
| **Grouping** | `-1` | Visible in Spawn Point mode. It selects Spawn Points with exactly the same group value. In released Version 3, `-1` is the default group; it does not mean every group. |
| **Min Respawn Time** | `2` seconds | Lower end of the random automatic delay. |
| **Max Respawn Time** | `3` seconds | Upper end of the random automatic delay. Use the same nonnegative value for Min and Max when the delay should be fixed. |
| **Schedule Respawn On Death** | Enabled | Listens for the object-scoped `OnDeath(Vector3, Vector3, GameObject)` event and schedules one return. |
| **Schedule Respawn On Disable** | Enabled | Schedules a return when Respawner is disabled, unless a return is already pending. Re-enabling while this option is enabled cancels the pending return. |
| **Check For Obstruction** | Disabled | Character Respawner only. Tests the character's enabled, non-trigger Sphere, Capsule, and Box Colliders on solid-object layers at the final placement. |
| **Respawn Audio** | Empty | Plays on the returned GameObject after activation when it is active in the hierarchy. |
| **Events > On Respawn Event** | No listeners | Invokes after activation, alongside the object-scoped `OnRespawn` event, when the object is active in the hierarchy. |

Use **None** for an in-place revive or when another system has already moved the object. Use **Start Location** for a fixed scene prop or character that always returns to its initial transform. Use **Spawn Point** for teams, checkpoints, or random arena locations.

**Start Location** is not updated after a checkpoint move or a pooled reuse. If the destination can change, use a Spawn Point group, call `Respawn(position, rotation, true)`, or maintain a project-specific checkpoint value.

## Set up Spawn Point placement

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Scene** tab and, under **Manager Setup**, select **Add Managers**.
3. Select the scene's **Game** GameObject and confirm it has **Spawn Point Manager**. **First Spawn Preferred** starts disabled, so valid points in the selected group are shuffled.
4. Create an empty GameObject at each allowed destination and add **Spawn Point**.
5. Give every eligible point the exact **Grouping** used by Respawner. Keep both the Respawner and its default points at `-1` for one ungrouped pool, or use deliberate indices such as `0` and `1` for two teams.
6. Configure the point's shape, size, ground snapping, facing, obstruction layers, and placement attempts as described on [Spawn Points](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/spawn-points/).
7. Keep each point enabled when it should be eligible. Enabled points register with Spawn Point Manager; disabled points are removed.

If no explicit Spawn Point Manager exists, Version 3 creates one at runtime when a Spawn Point first registers or a placement is requested. Add it to the scene deliberately when **First Spawn Preferred** or an inspectable manager is required.

When a group has no valid placement, Respawner does not fall back to its current or start location. It schedules another attempt using the same Min/Max time range.

## Choose the scheduling owner

| Scenario | Recommended configuration |
| --- | --- |
| Standard character deathmatch | Character Respawner, **Schedule Respawn On Death** enabled, active character root, Spawn Point mode, and one exact team group. |
| Fixed-delay test | Set Min and Max to the same value, such as `2`. |
| Scene pickup or destructible target | Ordinary Respawner with death or disable scheduling and a non-pooled scene-object lifecycle. |
| Manual checkpoint return | Disable both automatic triggers, move or choose the destination in project code, then call `Respawn()` or `Respawn(position, rotation, true)`. |
| Animated revive at the death position | Use **None**, disable the automatic Respawner schedule, and let Revive call the return at the intended animation point. |
| Pooled object | Disable Respawner's automatic scheduling and let the pool's spawn owner obtain and initialize the object. |
| Cancel a pending return | Call `CancelRespawn()` before an alternate revive, scene transition, permanent removal, or early manual activation. |

Automatic death and disable triggers do not normally create two Respawner timers: `OnDeath` schedules first, and `OnDisable` schedules only when no event is pending. A Revive ability, custom Scheduler event, save restore, or network callback can still compete, so keep one deliberate owner.

## How it runs

1. During `Awake`, Respawner records the starting position and rotation, detects Ultimate Character Locomotion, and registers for the object-scoped `OnDeath` event.
2. An allowed death cancels an older Respawner event and schedules `Respawn()` at a random time from Min to Max. An allowed disable schedules only when no Respawner event is pending. In a network build, only the authoritative instance schedules.
3. When the timer expires, **None** keeps the current transform, **Start Location** uses the `Awake` snapshot, and **Spawn Point** asks for a valid placement in the exact group.
4. A missing, blocked, or otherwise invalid Spawn Point placement schedules another attempt. Character Respawner performs its own full-character obstruction test after a point is chosen and also retries when blocked.
5. A successful return sends `OnWillRespawn`, changes position and rotation when required, and activates the GameObject. Characters use Ultimate Character Locomotion's position-and-rotation setter.
6. When the object is active in the hierarchy, Respawner plays its audio, sends `OnRespawn`, and invokes **On Respawn Event**. Character Respawner then sends `OnCharacterImmediateTransformChange(true)` when it moved the character.
7. Health, locomotion, Die, Colliders, camera, items, states, and project listeners respond to those events. Multiplayer authority tells the required Network Respawner Monitor to apply the same return remotely.

## Editor checkpoint

Before Play Mode, confirm that:

- the character uses Character Respawner and remains active through death, or the ordinary object uses Respawner and is disabled rather than destroyed;
- exactly one automatic or manual system owns the return;
- **Positioning Mode**, the `Awake` start transform, and any custom checkpoint behavior agree;
- Min and Max are nonnegative, Min is not greater than Max, and the intended fixed or random delay is clear;
- Spawn Point mode has at least one enabled point with an exactly matching **Grouping**, including matching `-1` values for the default group;
- Spawn Point and Character Respawner obstruction checks use the intended shapes and layers;
- audio and event listeners are on the same object and its parent hierarchy will be active at return time;
- a pooled object does not also have automatic Respawner reactivation; and
- a networked object has the installed integration's Network Info and required Network Respawner Monitor.

## Verify a character death and respawn

1. For a repeatable test, set **Min Respawn Time** and **Max Respawn Time** to `2`, choose **Start Location**, and note the character's initial position and rotation.
2. Apply lethal damage. Confirm the Die ability starts, the root remains active, and the character returns after about two seconds at the recorded transform.
3. Confirm Health and Shield reset, the alive collision layer and Colliders return, Die stops, locomotion and camera recover, respawn audio plays, and the Unity event runs once.
4. Change to **None**, move the character before killing it, and confirm the return keeps the death-location transform.
5. Change to **Spawn Point**, create two enabled points in the same group, and repeat several deaths. Confirm every return uses that group and the point's rotation or random direction.
6. Enable Character Respawner **Check For Obstruction** and block one destination with a solid object. Confirm the character uses another valid placement or waits one more interval instead of overlapping the blocker.
7. Disable an ordinary non-pooled test object with **Schedule Respawn On Disable** enabled. Confirm the same instance activates after the delay and restores its configured transform and listener state.
8. Call `CancelRespawn()` during a pending test and confirm no later return occurs.
9. In multiplayer, repeat on the authority and an observer. Confirm the authority schedules one return, the monitor applies one remote transform and activation, and Health/death state agrees on every role.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The character never returns after death | **Schedule Respawn On Death** is disabled, no standard `OnDeath` event was sent, the character root is inactive, or every placement is blocked. | Enable the standard death path, keep the character root active, and provide a clear destination. |
| An inactive character root stays inactive | Character Respawner returns immediately when `gameObject.activeSelf` is false and does not schedule another attempt. | Represent death with Health, Die, layers, renderers, and states while keeping the root active. Use a project or network spawner when the root must be inactive. |
| An ordinary object never returns | It was destroyed, **Schedule Respawn On Disable** is disabled, or its Respawner was destroyed before the Scheduler callback. | Disable a persistent scene object instead of destroying it, or let a spawner or pool create the replacement. |
| A pooled object reappears without being requested | **Schedule Respawn On Disable** remained enabled when the object was returned to `ObjectPoolBase`. Respawner activates the same GameObject directly and does not remove it from the pool's available set. | Disable automatic Respawner scheduling on pooled prefabs and let the pool owner spawn and initialize them. |
| `-1` selects no points or the Console reports a missing group | The legacy tooltip was read as “ignore grouping.” Released Version 3 performs an exact dictionary lookup, so `-1` selects only points whose Grouping is `-1`. | Match Respawner and Spawn Point group values exactly, or maintain the intended cross-group choice in project code. |
| A missing-group error repeats | Spawn Point placement failure schedules another full Respawner attempt, which logs the same missing grouping again. | Enable at least one point in that exact group or change Positioning Mode before the next attempt. |
| Start Location returns to an old checkpoint | The value was captured once during `Awake`; moving or reusing the object does not update it. | Use a Spawn Point group, call the positioned overload, or store and apply the current checkpoint in project code. |
| A Point Spawn Point ignores its own obstruction setting | Spawn Point's Point shape always accepts its transform in released Version 3. | Enable **Check For Obstruction** on Character Respawner for a character, or use a Sphere/Box point with configured obstruction layers for a general object. |
| The character retries forever in an apparently clear place | Character Respawner cached supported active solid Colliders and its solid-object layers at initialization, or Spawn Point obstruction layers include an unexpected object. | Inspect the character Colliders, Character Layer Manager, point layers, and final placement. Test with one clear Point and add obstruction rules back deliberately. |
| Respawn audio or events do not run | A parent is inactive, so the returned object is not active in the hierarchy, or the listener is registered on another GameObject. | Activate the required parent hierarchy and register against the Respawner's GameObject. Respawner does not retry solely because the parent is inactive. |
| A manually re-enabled object later teleports or resets again | A pending death schedule remained active. `OnEnable` automatically cancels only while **Schedule Respawn On Disable** is enabled. | Call `CancelRespawn()` before an early manual activation or alternate revive. |
| Respawn occurs twice | Revive, custom scheduling, save restore, or network code also returns the object. | Choose one owner and cancel the pending Respawner event before the alternate path. |
| A networked object logs a monitor error or fails during return | Network Info exists without the required Network Respawner Monitor. | Add and configure the integration's monitor on the same object, then test authority and observer roles. |

## Saving, pooling, and multiplayer

Respawner serializes its mode, group, timing, trigger flags, audio, Unity event, and States. The start transform is captured at runtime, while a pending Scheduler event, its remaining delay, chosen placement, obstruction retry, and death/active state are not durable Respawner data. A save system should store the authoritative alive/dead state and intended destination, cancel stale timers, then deliberately call or reschedule the return after loading.

Respawner does not call `ObjectPoolBase.Instantiate` or remove an object from a pool. It calls `SetActive(true)` on the same GameObject. Use Respawner for a scene instance or another lifecycle that owns that instance; use the [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) owner for pooled spawn and return.

With the multiplayer define enabled, an object with Network Info must also provide `INetworkRespawnerMonitor`. Non-authoritative instances do not schedule on death or disable. The authoritative instance performs the local return, then calls the monitor with position, rotation, and whether the transform changed. Prefab registration, ownership transfer, save-state reconciliation, and custom respawn rules remain integration or project responsibilities.

## Related tasks

- [Spawn System](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/) gives the short route through timing and placement.
- [Spawn Points](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/spawn-points/) configures groups, shapes, ground snapping, facing, and obstruction checks.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) configures death, attribute reset, deactivation, and feedback.
- [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/) configures the character's dead-state ability.
- [Revive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/revive/) configures an animated or manually timed return.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains object-scoped event registration and cleanup.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) explains reusable object ownership.

## Developer reference

`Opsive.UltimateCharacterController.Traits.Respawner` exposes `PositioningMode`, `Grouping`, `MinRespawnTime`, `MaxRespawnTime`, `ScheduleRespawnOnDeath`, `ScheduleRespawnOnDisable`, `RespawnAudioClipSet`, `OnRespawnEvent`, `Respawn()`, `Respawn(Vector3, Quaternion, bool)`, and `CancelRespawn()`. It has no public “schedule after this delay” method; automatic scheduling comes from `OnDeath` or `OnDisable`, while a custom delay belongs to project Scheduler code.

The event order for a successful active-hierarchy return is `OnWillRespawn`, optional transform change, activation, audio, object-scoped `OnRespawn`, and **On Respawn Event**. Character Respawner follows with `OnCharacterImmediateTransformChange(true)` when `transformChange` is true.

Subscribe to the parameterless `OnRespawn` event and unregister with the same object and delegate:

```csharp
using UnityEngine;
using Opsive.Shared.Events;

public class MyObject : MonoBehaviour
{
    private void Awake()
    {
        EventHandler.RegisterEvent(gameObject, "OnRespawn", OnRespawn);
    }

    private void OnRespawn()
    {
        Debug.Log(name + " Respawned.");
    }

    private void OnDestroy()
    {
        EventHandler.UnregisterEvent(gameObject, "OnRespawn", OnRespawn);
    }
}
```

---

<a id="page-ultimate-character-controller-spawn-system-spawn-points"></a>

# Spawn Points

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/spawn-points/)

Spawn Points give a Respawner one or more scene locations to try. Use them for team starts, checkpoints, arena returns, and other cases where the destination should come from the scene instead of the object's current or original transform.

## Before you begin

- A Spawn Point chooses a position and rotation. It does not create an object, schedule a return, reset Health, or synchronize a player.
- Add a [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) to the character or object that should return, then select **Spawn Point** as its **Positioning Mode**.
- Decide which points belong to each team, checkpoint, or other pool. Respawner and Spawn Point must use exactly the same **Grouping** value.
- Use one active **Spawn Point Manager** in the scene. The runtime can create a fallback manager, but an explicit manager exposes the selection setting and gives the scene a clear owner.

## Add the manager and scene points

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Select the **Scene** tab and, under **Manager Setup**, select **Add Managers**.
3. Select the scene's **Game** GameObject and confirm it has **Spawn Point Manager**. **First Spawn Preferred** starts disabled.
4. Create an empty GameObject at an allowed destination and add **Spawn Point**.
5. Place the GameObject at the center of the location. Its rotation supplies the normal spawn facing direction. Keep its Transform scale at `(1, 1, 1)` and use **Size** to change the area.
6. Set **Grouping** to the exact pool that should use this point. Keep the default `-1` on both the point and Respawner for one ungrouped pool, or use deliberate values such as `0` and `1` for two teams.
7. Duplicate and place as many points as the group needs. Enabled points register with Spawn Point Manager; disabling a point removes it from selection until it is enabled again.

![Spawn Point Inspector showing placement area, facing, and obstruction settings](https://opsive.com/wp-content/uploads/2018/03/SpawnPoint.png)

## Configure the placement area

| Field | Version 3.2.0 default | What it controls |
| --- | --- | --- |
| **Grouping** | `-1` | Selects one exact manager group. In released Version 3, `-1` is a real group value; it does not mean every group. |
| **Shape** | **Point** | **Point** uses the GameObject's position. **Sphere** and **Box** can define a horizontal area for retry candidates. |
| **Size** | `0` | For **Sphere**, this is the maximum horizontal sample radius and the gizmo radius. For **Box**, it is the full local X/Z width and depth; samples range from `-Size / 2` to `Size / 2`. |
| **Random Shape Spawn** | Enabled | Allows later obstruction retries to sample another position. The first candidate is still the center, and this setting has no effect unless the center fails an obstruction test. |
| **Ground Snap Height** | `0` | When positive, casts downward from above the accepted candidate and moves it to a hit on **Obstruction Layers**. No hit leaves the candidate unchanged. For **Box**, this value is also the obstruction volume's height. |
| **Random Direction** | Disabled | Disabled uses the Spawn Point Transform rotation. Enabled gives an upright point a random yaw. |
| **Check For Obstruction** | Disabled | Tests the candidate with the point's configured volume before accepting it. **Point** bypasses this test and succeeds when at least one placement attempt is allowed. |
| **Max Collision Count** | `20` | Sets the fixed Collider result-buffer capacity used by the Spawn Point obstruction query. |
| **Obstruction Layers** | Most project layers | Supplies both the obstruction query and ground-snap ray. The default excludes Default, Ignore Raycast, Transparent FX, Water, UI, SubCharacter, Overlay, and Visual Effect. Review the mask for the scene. |
| **Placement Attempts** | `10` | Sets the maximum candidates tested within this point. Keep it at least `1`; the center is the first attempt. |
| **Gizmo Color** | Red at 30% opacity | Controls the Scene view area visualization only. |

The Spawn Point obstruction volume is not derived from the spawning object's Colliders. A Sphere point checks a sphere of `Size / 2` around the candidate; a Box point checks `Size / 2` in local X/Z and `Ground Snap Height / 2` vertically. For a UCC character, enable **Check For Obstruction** on Character Respawner as well when the complete character collider shape must fit at the final position.

Ground snapping happens after the Spawn Point obstruction test. Place the Spawn Point near the intended surface, give **Ground Snap Height** enough reach, and include the ground layer in **Obstruction Layers**. A failed ray does not make the placement fail.

## Choose grouping and selection behavior

| Goal | Configuration |
| --- | --- |
| One shared pool | Leave Respawner and all eligible points at **Grouping** `-1`. This is an exact default group, not a wildcard. |
| Team starts | Give each team a distinct value, such as `0` and `1`, and apply the matching group to its Respawner. |
| Fixed checkpoint | Keep one enabled point in the current checkpoint group, or change the Respawner group when the next checkpoint is earned. |
| Several eligible locations | Keep **First Spawn Preferred** disabled. Spawn Point Manager shuffles the group's registered list, then uses the first point that returns a valid placement. |
| Preferred location with fallbacks | Enable **First Spawn Preferred**. The first registered point in the group is tried before the group is shuffled; if it fails, it may be tried again as part of the shuffled fallback list. |
| Sequential or round-robin locations | Version 3 has no sequential selection mode. Enable one checkpoint point at a time or implement a project-owned selection policy. |

“First” means the first point currently registered for that group, not the first alphabetically named point. Disabling that point promotes the first remaining list entry; re-enabling it appends it again. When preference order matters, establish the registration order deliberately and verify it in Play Mode.

The released-Version-3 shuffle is not a statistically uniform picker. With two always-valid points, its in-place shuffle swaps their order on every request, so the selected location alternates. Use the built-in behavior for variety, not for weighted probability or a guaranteed random distribution.

## Connect a character or object

1. On **Respawner** or **Character Respawner**, set **Positioning Mode** to **Spawn Point**.
2. Set **Grouping** to the exact value used by the eligible points.
3. Configure **Min Respawn Time**, **Max Respawn Time**, and the intended death, disable, or manual scheduling owner on [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/).
4. For a character, keep the character root active through death and enable Character Respawner **Check For Obstruction** when the final character shape must fit.
5. For an ordinary object, decide whether the Spawn Point's Size-based test is enough. Supply a project-specific final-volume test when the object shape is materially different.
6. Keep scene points enabled only while they should participate. Enabling or disabling a checkpoint point updates the manager automatically.

## How placement runs

1. Each enabled Spawn Point registers itself in the manager dictionary under its exact **Grouping** value.
2. A Respawner requests a placement for its group. A missing group logs an error and fails the request.
3. With **First Spawn Preferred** enabled, the group's first registered point is tried first. The manager then shuffles the group and tries points until one succeeds.
4. A Spawn Point starts at its Transform center. With obstruction checking enabled, **Point** accepts that center; **Sphere** and **Box** test their configured volume.
5. After a blocked Sphere or Box candidate, **Random Shape Spawn** can choose another horizontal position. The point repeats until it succeeds or reaches **Placement Attempts**.
6. A positive **Ground Snap Height** then tries to move the accepted candidate onto a surface, and **Random Direction** or the Transform supplies its rotation.
7. If every point fails, Spawn Point Manager returns `false`. Respawner waits for another configured respawn interval and requests placement again.
8. On success, Respawner moves and activates the object and sends its normal respawn events. Character Respawner can perform its separate full-character obstruction check before completing the return.

## Editor checkpoint

Before Play Mode, confirm that:

- the scene has one active Spawn Point Manager and **First Spawn Preferred** matches the intended policy;
- every Respawner group has at least one enabled point with the exact same value, including matching `-1` values for the default pool;
- each point's center, Transform rotation, unit scale, **Shape**, and **Size** represent the visible safe area;
- **Placement Attempts** is at least `1` and **Max Collision Count** can hold the expected nearby results;
- **Obstruction Layers** includes blockers and, when used, the ground surface;
- **Ground Snap Height** reaches from the candidate to the intended surface;
- Point locations that must fit a character also use Character Respawner **Check For Obstruction**; and
- the project has one clear owner for respawn scheduling, checkpoint state, pooling, and network authority.

## Verify several points in Play Mode

1. Create three visibly separated Point Spawn Points with distinct rotations and set all three to **Grouping** `7`.
2. Configure a test character's Character Respawner for **Spawn Point**, group `7`, and a fixed two-second delay.
3. Leave **First Spawn Preferred** disabled. Trigger several deaths and confirm every successful return uses a point in group `7`, applies that point's rotation, and eventually uses more than one eligible point.
4. Disable one point and repeat. Confirm it is no longer selected; re-enable it and confirm it becomes eligible again.
5. Add one point in group `8` and confirm the group-`7` character never uses it. Change the Respawner to group `8` and confirm only that point is used.
6. Change one group-`7` point to **Box**, set a visible **Size**, enable **Check For Obstruction** and **Random Shape Spawn**, then block its center with an object on **Obstruction Layers**. Confirm a clear retry position is used or the manager moves to another point.
7. Give the Box a positive **Ground Snap Height** and verify the accepted candidate reaches the intended ground. Remove the ground layer from **Obstruction Layers** and confirm the missing ray leaves the candidate unsnapped.
8. Block every eligible area and enable Character Respawner **Check For Obstruction**. Confirm the character waits and retries instead of overlapping a blocker.
9. Enable **First Spawn Preferred** and establish a known registration-first point. Confirm it wins while valid and a fallback is used when it cannot place the character.

## Troubleshooting and released-Version-3 limitations

| Symptom | Check | Fix |
| --- | --- | --- |
| The Console reports no Spawn Point for the group | Respawner and enabled points do not share an exact group key. `-1` was treated as a wildcard. | Match the values exactly. Keep both sides at `-1` for the default pool. |
| Respawner waits and retries without a missing-group error | The group was registered previously but now contains no enabled points, or every point returns `false`. | Enable a valid point in the group and clear its placement area. |
| Sphere or Box always returns the center | The center is clear, **Check For Obstruction** is disabled, or **Random Shape Spawn** is disabled. Version 3 randomizes only retries after the center fails. | Use several Point locations for ordinary variety, or implement a custom Spawn Point when every request must sample the full area. |
| A Point accepts an occupied location | Point shape bypasses the Spawn Point obstruction query in released Version 3. | Enable Character Respawner **Check For Obstruction** for a character, use an area shape, or add a project-specific final-volume test. |
| The object appears in the air | **Ground Snap Height** is zero or too short, the ground is absent from **Obstruction Layers**, or the ray misses. A miss still returns success. | Increase the height, include the ground layer, and place the point close enough to the surface. |
| The final snapped object overlaps geometry | Spawn Point obstruction runs before ground snapping and uses the point volume rather than the object's Collider shape. | Use Character Respawner's final character check or validate the final object volume in project code. |
| A scaled area does not match its obstruction test | The Transform has non-unit scale. Sampling and gizmo transforms use it, while the overlap extents use unscaled field values. | Keep Spawn Point scale at `(1, 1, 1)` and adjust **Size** and **Ground Snap Height**. |
| A point always fails when obstruction checking is enabled | **Placement Attempts** is `0`, every candidate is blocked, or the layer mask includes an unintended Collider. | Set attempts to at least `1`, inspect the mask, and test from a clear center. |
| Preferred-first chooses an unexpected point | Registration order changed after a point was disabled, re-enabled, or moved between groups. | Establish enable order deliberately or use one enabled point when the destination must be deterministic. |
| Two points alternate instead of looking random | The Version 3 shuffle swaps a two-entry list on every request. | Treat this as built-in variety or implement the required random, weighted, or sequential policy. |
| A Grouping edit during Play Mode is ignored | Directly editing the serialized Inspector field does not call the runtime `Grouping` property that updates the manager map. | Change `SpawnPoint.Grouping` through project code, or disable and re-enable the point after an Inspector-only test change. |
| There are inconsistent results with multiple managers | More than one Spawn Point Manager exists and only the initialized singleton owns registration and selection. | Keep one active manager in the scene and remove duplicates. |

## Saving, networking, and scene ownership

Spawn Point Manager and Spawn Point are scene configuration. They do not save the current checkpoint, persist which points are enabled, schedule an object, or send spawn events. A save system should store the authoritative checkpoint or group and restore the relevant Respawner value and enabled-point state after loading.

Spawn Point selection itself has no network synchronization. In the UCC multiplayer path, the authoritative Respawner chooses a placement and its required Network Respawner Monitor applies the chosen position and rotation remotely. Do not let each client choose independently. Dynamic point registration, checkpoint ownership, team assignment, late joining, and scene transitions remain integration or project responsibilities.

## Related tasks

- [Spawn System](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/) explains how placement and return timing work together.
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) configures timing, positioning mode, scheduling, audio, and return events.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) configures character death and attribute reset.
- [Die](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/die/) controls the character's dead-state ability.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains the events sent by Respawner after placement succeeds.
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) creates a working character and scene foundation.

## Developer reference

`Opsive.UltimateCharacterController.Game.SpawnPoint` registers in `OnEnable` and unregisters in `OnDisable`. Its virtual `GetPlacement(GameObject, ref Vector3, ref Quaternion)` method supplies one position and rotation or returns `false`. Public properties expose `Grouping`, `Shape`, `Size`, `GroundSnapHeight`, `RandomDirection`, `CheckForObstruction`, `ObstructionLayers`, and `PlacementAttempts`. **Random Shape Spawn** and **Max Collision Count** are serialized fields without public properties in released Version 3.

Change a live point's group through its `Grouping` property so `SpawnPointManager.UpdateSpawnPointGrouping` removes it from the old list and adds it to the new one. `SpawnPointManager` also exposes static `GetPlacement`, `GetSpawnPoints`, `AddSpawnPoint`, and `RemoveSpawnPoint` methods. **First Spawn Preferred** is serialized on the manager and has no public property in this release.

Spawn Point has no gameplay event of its own. Respawner sends `OnWillRespawn`, moves and activates the object after placement succeeds, then sends `OnRespawn` and invokes its Unity event when the object is active in the hierarchy. Follow [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/) for exact event order and cancellation behavior.

---

<a id="page-ultimate-character-controller-audio"></a>

# Audio

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/audio/)

Use the Opsive audio system to add varied, spatial sounds to character abilities, health, items, footsteps, impacts, and other gameplay without managing a separate Audio Source for every playback.

The **Audio Manager** finds or creates an available Audio Source on the object that plays the sound. This lets multiple clips overlap when needed and gives built-in UCC features a common way to play audio.

## Add audio to a UCC feature

Most audio-enabled UCC features expose an **Audio Clip Set**. Examples include **Start** and **Stop** on an ability, **Take Damage**, **Heal**, and **Death** on the Health component, and **Audio Clip Set** on character or item effects.

1. Select the character, item, or scene object that owns the behavior.
2. In the relevant component, ability, effect, or action module, expand its audio field.
3. For a quick, local setup, leave **Audio Config** empty and add one or more clips under **Audio Clips**. Each playback chooses a clip at random.
4. Enter Play Mode and trigger the behavior. UCC plays the sound from the object associated with that behavior.

Use inline **Audio Clips** when the clips belong to one feature only. Use an Audio Config when several features should share the same clips and playback rules.

## Create a reusable Audio Config

1. In the Project window, choose **Assets > Create > Opsive > Audio > Audio Config**.
2. Add the available sounds to **Audio Clips**.
3. Set **Clip Selection** to match the intended behavior.
4. If the default source is not suitable, assign an **Audio Source Prefab** that contains a configured Unity Audio Source.
5. Set only the required values in **Audio Modifier**. Leave a value at **No Override** to inherit it from the selected Audio Source.
6. Assign the asset to **Audio Config** in the feature's Audio Clip Set. When a config is assigned, its clips replace the inline **Audio Clips** list.

You can also select AudioClip assets in the Project window and use **Assets > Create > Opsive > Audio > One Audio Config From Selected Clips**. Use **Multi Audio Configs From Clips** when each selected clip should receive its own config.

## Key choices

### Choose a clip

- **Random** chooses a random entry for each playback and is the default.
- **Sequence** advances from the first clip to the last, then repeats.
- **Index** uses `AudioClipIndex`, which starts at 0 and can be changed from code. Use it when gameplay chooses a specific variation.

An inline Audio Clip Set chooses randomly when a built-in feature plays it without an explicit index. Create an Audio Config when you need Sequence behavior or an Inspector-configured Index mode.

### Control overlap and Audio Sources

- **Share Audio Source** is enabled by default. The manager reuses any available shared source on the same GameObject and creates another when all shared sources are busy.
- **Replace Previous Audio Source** is disabled by default. Enable it when a new clip should replace an active clip instead of overlapping it.
- **Copy Existing Audio Source Properties** is enabled by default. When the manager creates another source, it copies the Unity Audio Source settings already on the originating GameObject.
- **Audio Source Prefab** provides the source settings when no suitable source exists. The prefab must contain an Audio Source component.

For a local 3D sound, play it on the character, visible item, or impact position. For non-spatial UI or narration, use a 2D Audio Source prefab or set **Spatial Blend Override** to a constant value of 0.

### Vary or override playback

The Audio Config's **Audio Modifier** can override **Output**, **Loop**, **Volume**, **Pitch**, **Stereo Pan**, **Spatial Blend**, **Reverb Zone**, and **Delay**. Float overrides can use a constant or a random range; **Loop Override** can use a constant or random Boolean. Small random pitch or volume ranges can make repeated footsteps or impacts sound less repetitive.

## Configure the scene Audio Manager

The normal UCC setup adds an **Audio Manager** to the scene's **Game** object and assigns the included 3D Audio Manager Module. If no Audio Manager exists, the runtime creates one with a 3D Audio Source, so a basic Audio Clip Set still works.

To add the normal scene managers explicitly:

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. In **Manager Setup**, select **Add Managers**.
3. Select the **Game** object and confirm that its **Audio Manager** component has **Audio Manager Module** assigned.

For project-wide custom defaults, create an **Audio Manager Module** from **Assets > Create > Opsive > Audio > Audio Manager Module**, assign its **Default Audio Config**, and then assign the module to the scene's **Audio Manager**. Use **Output Override** on an Audio Config when a sound needs a particular Audio Mixer Group.

## Verify in Play Mode

Trigger each configured behavior several times and confirm that:

- the sound begins at the expected ability, health, item, surface, or impact event;
- Random or Sequence selection changes clips as configured;
- simultaneous sounds overlap unless **Replace Previous Audio Source** is enabled;
- 3D sounds follow or originate from the intended object or world position; and
- volume, pitch, delay, looping, and mixer routing match the Audio Source plus any Audio Modifier overrides.

During playback, expand the source GameObject in the Hierarchy. The manager names generated children `SharedAudioSource` or `ReservedAudioSource: <config name>`, which helps confirm which source is being used.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| No sound plays | The Audio Clip Set may have neither an assigned Audio Config nor an inline clip. | Assign a config containing clips or add clips under **Audio Clips**. Also confirm that the source and mixer are not muted. |
| Inline clips never play | An **Audio Config** is assigned. | Remove the config to use the inline list, or move the intended clips into the config. |
| The same clip always plays | **Clip Selection** is set to **Index**; its runtime index starts at 0. | Use **Random** or **Sequence**, or set `AudioClipIndex` from code. |
| A new sound cuts off the previous one | **Replace Previous Audio Source** is enabled. | Disable it when the sounds should overlap. |
| A sound is unexpectedly 2D or 3D | The Audio Source prefab, an existing Audio Source, or **Spatial Blend Override** is supplying the spatial setting. | Set the intended spatial blend on the source or use an explicit constant override. |
| New sources use unexpected volume, pitch, or routing | **Copy Existing Audio Source Properties** is copying a source on the playback GameObject, or an Audio Modifier is overriding it. | Correct the existing source, disable the copy option, or reset the modifier to **No Override**. |
| A warning reports a missing default Audio Source prefab | The module's **Default Audio Config** has no **Audio Source Prefab**. | Assign the included 3D or 2D default module/config, or provide a prefab containing an Audio Source. |

## Related pages

- [Quick setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) adds the standard scene managers.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) uses Audio Clip Sets for damage, healing, and death feedback.
- [Jump](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/) shows ability-specific audio alongside the common ability Start and Stop sets.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) connects footsteps to Surface Effects and Audio Config assets.
- [Item actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) explains the action and module system that item audio effects participate in.
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) explains how to react to UCC gameplay events before playing custom audio.
- [FMOD](https://opsive.com/support/documentation/ultimate-character-controller/integrations/fmod/) and [Master Audio](https://opsive.com/support/documentation/ultimate-character-controller/integrations/master-audio/) replace the default playback module while retaining the Opsive audio data workflow.

## Developer reference

The released audio types are in the `Opsive.Shared.Audio` namespace. Built-in UCC integrations call Audio Clip Sets from their own lifecycle: abilities play their Start and Stop sets, Health plays its Take Damage, Heal, and Death sets, item effects and modules play from the item or visible object, and surface or impact effects can play at a world position. These integrations do not require a separate audio-specific event subscription. For custom behavior, respond to the relevant UCC event and call the audio API from that handler.

Keep the returned `PlayResult` when you need to stop the exact source started by a call:

```csharp
using Opsive.Shared.Audio;
using UnityEngine;

public class AlertAudio : MonoBehaviour
{
    [SerializeField] private AudioConfig m_AlertAudioConfig;
    private PlayResult m_PlayResult;

    public void PlayAlert()
    {
        m_PlayResult = AudioManager.Play(gameObject, m_AlertAudioConfig);
    }

    public void StopAlert()
    {
        AudioManager.Stop(gameObject, m_PlayResult);
    }

    public void PlayAlertAt(Vector3 position)
    {
        AudioManager.PlayAtPosition(m_AlertAudioConfig, position);
    }
}
```

`AudioManager` also provides overloads for an AudioClip, volume, pitch, delay, looping, AudioConfig, and AudioClipInfo. `AudioClipSet` provides `PlayAudioClip`, `PlayAtPosition`, and `Stop` when a component should expose the same Inspector workflow used by UCC.

---

<a id="page-ultimate-character-controller-programming-concepts"></a>

# Programming Concepts

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/)

Extend the Ultimate Character Controller without editing package source: start with the gameplay or Inspector result you need, then use the smallest supported extension point that owns that result.

## Start with the visible result

Describe the change in terms that can be checked in the editor or in Play Mode before choosing an API. For example, decide whether the character should gain a new action, movement input should be interpreted differently, the camera should frame the character differently, an item should gain another behavior, or an existing event should update a separate system.

Prefer configuration before code. An existing component, ability, action module, or [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) preset is easier to inspect and maintain than a new subclass. Create a custom type only when the existing choices cannot produce the required result.

## Choose the smallest extension point

| Goal | Recommended extension point | Editor-visible result |
| --- | --- | --- |
| Add a character action with its own start, update, and stop rules | Derive from `Ability`, or from the nearest included ability base. | The compiled type appears in the **Abilities** add menu on **Ultimate Character Locomotion**. See [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/). |
| Change how input and look direction become character movement | Derive from `MovementType`. | The compiled type appears in the **Movement Types** add menu on **Ultimate Character Locomotion**. See [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/). |
| Change camera position, rotation, or perspective behavior | Derive from `ViewType`. | The compiled type appears in the **View Types** add menu on **Camera Controller**. See [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/). |
| Add one responsibility to a usable item | Derive from the module base accepted by the relevant action-module group. | The compiled type appears in that group's **Modules** add menu. See [Action Modules and Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/). |
| Add or gate a response when an item impacts something | Create an `ImpactAction` or `ImpactActionCondition` for the appropriate impact group. | The response or condition can be selected in the item's impact configuration. See [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/). |
| Change how damage data is applied to a target | Derive from `DamageProcessor` and use a project-owned processor asset. | Assign it to **Default Damage Processor** on a Damage Processor Module or to **Damage Processor** in item impact data. See [Damage Processor](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/). |
| React to an existing character, item, camera, or state change | Subscribe through `EventHandler` instead of modifying the sender. | The receiving component updates when the documented event occurs. See [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/). |

Keep the extension focused on one responsibility. If a feature needs several independent outcomes, combine a small ability, module, component, state, or event listener instead of creating one class that replaces multiple controller systems.

## Use the programming utilities

These are the direct programming topics in this section:

- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/) connects systems without requiring the sender to know about every receiver. Events can be scoped to an object or sent globally; use the [Event Names](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/event-names/) catalog to match an existing Version 3 event before defining another one.
- [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/) runs a callback later in `Update` or `FixedUpdate` and returns a handle that can be cancelled. Use it for controller work that should follow UCC's timing rather than starting a coroutine solely for a delay.
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/) reuses spawned Unity objects and regular C# objects. Use it for frequently created projectiles, effects, temporary data, and similar short-lived objects.

## Build an upgrade-safe extension

1. Create the script under `Assets/<ProjectName>/Scripts/Runtime`, not inside `Packages/com.opsive.*` or an imported demo folder.
2. If the project uses an Assembly Definition, add **Opsive.UltimateCharacterController** under **Assembly Definition References**. Also reference **Opsive.Shared.Runtime** when the script directly uses `Opsive.Shared` APIs such as events, scheduling, or pooling.
3. Derive from the extension point that owns the result. Start with the nearest existing base type so built-in lifecycle and validation behavior remains available.
4. Expose only the settings a designer needs to change. Give serialized fields clear names and useful tooltips.
5. Let Unity compile and clear every Console error. The Version 3 add menus only offer compatible, concrete types from successfully loaded assemblies.
6. Select the owning character, camera, item action, or processor field. Use the appropriate **Abilities**, **Movement Types**, **View Types**, or **Modules** plus menu, or assign the project-owned asset described by that feature's page.
7. Configure the new entry, save the owning scene or prefab deliberately, and record the expected Play Mode result before adding more behavior.

Keep custom runtime and editor code in separate assemblies or folders. If a custom Inspector is useful, place its code in an Editor assembly; the runtime type should not depend on UnityEditor APIs.

## Verify in Play Mode

1. Enter Play Mode with one controlled scenario that triggers the extension.
2. Confirm the expected visible result occurs once: the ability starts, movement or framing changes, the item response runs, or the listening component updates.
3. End the scenario and confirm the result stops or resets. Trigger it a second time to catch stale state or duplicate subscriptions.
4. Disable and re-enable the owning object. If the object can be pooled, respawn it through the same pool path used by the game.
5. Stop Play Mode, reopen the scene or prefab, and confirm the custom type and its configured values remain assigned.
6. Check the Console. A successful extension produces the intended result without missing-reference, serialization, duplicate-registration, or uncancelled-callback errors.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| A custom type does not appear in an add menu. | The Console has compile errors, the class is abstract or generic, it derives from the wrong base, or its Assembly Definition lacks the required reference. | Clear compile errors, use a concrete compatible subclass, and add the required UCC or Shared assembly reference. Then let Unity reload the scripts and reopen the Inspector. |
| A callback runs more than once after an object is re-enabled. | The component registers repeatedly without unregistering the same target, event name, parameter types, and delegate. | Pair registration and unregistration in matching lifecycle methods. Test two enable/disable cycles. |
| Delayed work runs after the owner is disabled, destroyed, or reused. | The returned `ScheduledEventBase` is still active. | Store the handle and call `Scheduler.Cancel` when the owner no longer needs the callback. Reset the handle before reuse. |
| A pooled object retains data from its previous use. | Initialization and cleanup do not reset every mutable value, or spawn and return use different systems. | Reinitialize the object when it is obtained and return it through the matching pool. For regular pooled classes, implement `IPoolable.Reset` when references or state must be cleared on return. |
| Inspector values disappear after a compile or reload. | A field is not serialized, or the type, namespace, assembly, or field name changed after data was saved. | Serialize designer-facing fields and plan migrations before renaming serialized types or fields. Reassign the asset only after checking the version-control diff. |
| A package update removes the customization. | The custom file was saved under an Opsive package, demo, or integration-owned folder. | Restore it from version control, move it under the project's `Assets` folder, and reconnect the project-owned type or asset. |

## Related tasks

- [Organization](https://opsive.com/support/documentation/ultimate-character-controller/organization/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [Action Modules and Groups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/)
- [Damage Processor](https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/)

## Developer reference

The released Version 3 runtime exposes these primary extension families:

| Responsibility | Base type and namespace |
| --- | --- |
| Character action | `Opsive.UltimateCharacterController.Character.Abilities.Ability` |
| Movement interpretation | `Opsive.UltimateCharacterController.Character.MovementTypes.MovementType` |
| Camera behavior | `Opsive.UltimateCharacterController.Camera.ViewTypes.ViewType` |
| Item action module | `Opsive.UltimateCharacterController.Items.Actions.Modules.ActionModule` and the compatible group-specific base |
| Item impact response | `Opsive.UltimateCharacterController.Items.Actions.Impact.ImpactAction` or `ImpactActionCondition` |
| Damage application | `Opsive.UltimateCharacterController.Traits.Damage.DamageProcessor` |

Abilities, Movement Types, View Types, and Action Modules are serialized objects owned by their controller or item component rather than standalone `MonoBehaviour` components. The Version 3 editor scans loaded assemblies for nonabstract assignable types when it builds their add menus. Put component references and other initialization in the lifecycle methods provided by the selected base class instead of assuming a `MonoBehaviour` lifecycle.

`EventHandler` is in `Opsive.Shared.Events`. `Scheduler`, `ScheduledEventBase`, and the Unity-object `ObjectPool` are in `Opsive.Shared.Game`; `GenericObjectPool` and `IPoolable` are in `Opsive.Shared.Utility`. Keep the handle returned by `Scheduler.Schedule` or `Scheduler.ScheduleFixed` when the operation may need to be cancelled, and pair `ObjectPool.Instantiate` with `ObjectPool.Destroy` for objects managed by that pool.

---

<a id="page-ultimate-character-controller-programming-concepts-events"></a>

# Events

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)

Use Opsive's `EventHandler` when one gameplay system must react to a UCC character, item, or object change without holding a direct reference to the component that caused it. It is best for notifications with a stable name, target, and typed parameter contract; use a normal method call when the sender already owns the receiver and needs an immediate result.

## Choose an event scope

`EventHandler` stores subscriptions in static tables and exposes static methods. You do not need to add an EventHandler component to every publisher.

| Scope | Call shape | Use it when |
| --- | --- | --- |
| Object-scoped | Pass a target object first | The event belongs to one character, item, camera, or impacted object. This is the normal UCC pattern. |
| Global | Omit the target object | Every listener should receive one project-wide signal regardless of scene object. |

For an object-scoped event, the target is the publisher's key, not necessarily the listener's GameObject. UCC commonly uses the character GameObject for ability and inventory events, the Health GameObject for death events, and the impacted GameObject for impact events. Register, execute, and unregister with the same target instance.

Global events are easier to reach but harder to own. They remain registered across scene changes until explicitly unregistered or until the event tables are reset at Play Mode subsystem registration. Prefer an object-scoped event unless the signal is genuinely global.

## Use one typed contract

The event name, target, parameter count, parameter types, and parameter order form one contract. Registration, execution, and unregistration must use that same contract.

These UCC 3.2.0 events illustrate the pattern:

| Scenario | Target | Typed signature |
| --- | --- | --- |
| A Health component dies | The Health GameObject | `OnDeath(Vector3 position, Vector3 force, GameObject attacker)` |
| A character Ability starts or stops | The character GameObject | `OnCharacterAbilityActive(Ability ability, bool active)` |
| A Character Item is equipped | The character GameObject | `OnInventoryEquipItem(CharacterItem item, int slotID)` |
| An item impact reaches an object | The impacted GameObject | `OnObjectImpact(ImpactCallbackContext context)` |

Use the [event names reference](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/event-names/) to find the target concept and expected parameters for built-in events. When an integration defines an additional event, verify its exact signature against the installed integration source.

Do not reuse one event name with unrelated signatures. Opsive Shared can optionally allow multiple signature types for some one-, two-, and three-parameter registrations, but the normal and clearer design is one name per typed contract.

## Follow the listener lifecycle

Every subscription has three parts:

1. Register when the listener becomes interested.
2. Let the publisher execute the event on the agreed target.
3. Unregister with the same target, name, generic types, and delegate before the listener stops being interested.

Use `Awake` and `OnDestroy` for a listener that should remain subscribed for its complete component lifetime. Use `OnEnable` and `OnDisable` when disabling or pooling the listener should pause the subscription. Do not combine both patterns for the same callback.

This pooled-friendly component listens for the Health event on its own GameObject:

```csharp
using UnityEngine;
using EventHandler = Opsive.Shared.Events.EventHandler;

public sealed class DeathReporter : MonoBehaviour
{
    private void OnEnable()
    {
        EventHandler.RegisterEvent<Vector3, Vector3, GameObject>(
            gameObject, "OnDeath", OnDeath);
    }

    private void OnDisable()
    {
        EventHandler.UnregisterEvent<Vector3, Vector3, GameObject>(
            gameObject, "OnDeath", OnDeath);
    }

    private void OnDeath(
        Vector3 position,
        Vector3 force,
        GameObject attacker)
    {
        Debug.Log($"{name} died at {position}.", this);
    }
}
```

A listener does not need to be attached to the target. For example, a HUD can register against its assigned character GameObject and unregister from that same character before switching players.

Use a named method or cache the delegate. Creating a new lambda during unregistration does not reproduce the delegate that was registered, so the old callback remains.

## Practical UCC subscriptions

The following registrations use source-verified Version 3 signatures:

```csharp
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Items;
using Opsive.UltimateCharacterController.Items.Actions.Impact;
using EventHandler = Opsive.Shared.Events.EventHandler;

// Character lifecycle: target is the character GameObject.
EventHandler.RegisterEvent<Ability, bool>(
    character, "OnCharacterAbilityActive", OnAbilityActive);

// Inventory lifecycle: target is also the character GameObject.
EventHandler.RegisterEvent<CharacterItem, int>(
    character, "OnInventoryEquipItem", OnItemEquipped);

// Impact lifecycle: target is the GameObject that received the impact.
EventHandler.RegisterEvent<ImpactCallbackContext>(
    impactTarget, "OnObjectImpact", OnObjectImpact);
```

The matching callbacks are:

```csharp
private void OnAbilityActive(Ability ability, bool active)
{
    // React only to the Ability types relevant to this listener.
}

private void OnItemEquipped(CharacterItem item, int slotID)
{
    // Refresh the UI or another dependent system for this slot.
}

private void OnObjectImpact(ImpactCallbackContext context)
{
    // Read the source-verified impact context needed by this object.
}
```

Mirror all three calls with `UnregisterEvent` when their owner is disabled, destroyed, or assigned a different character or target.

## Runtime and ownership cautions

- **Main thread:** the Shared 2.0.0 implementation mutates ordinary static `Dictionary` and `List` instances without synchronization and invokes Unity-facing callbacks. Register, execute, and unregister on Unity's main thread.
- **Duplicate registration:** in the Editor, registering the same delegate twice logs a warning but still adds the second subscription. One unregistration removes one matching entry, so an unmatched duplicate can continue firing.
- **Pooling:** a pooled listener should normally pair `OnEnable` with `OnDisable`. A pooled publisher does not automatically remove callbacks registered against its GameObject.
- **Destroyed targets:** the table does not infer subscription ownership from Unity object destruction. Explicitly unregister listeners rather than relying on a scene unload or destroyed target.
- **Global listeners:** a global registration has no object key to constrain it. Always give it an explicit owner and matching cleanup path.
- **Play Mode/domain reload:** `EventHandler.DomainReset()` is marked for `SubsystemRegistration` and clears both object and global event tables. This also protects a new Play Mode session when domain reload is disabled, but it is not a replacement for normal scene and pooling cleanup.
- **Execution changes:** the implementation accounts for listeners being removed while an event is executing. Avoid adding broader lifecycle work inside a callback unless the order is intentional.

The internal invokable wrappers are pooled, so EventHandler avoids creating a new wrapper for every execution. Treat this as a notification mechanism, not as permission to broadcast high-frequency data when a direct update path would be simpler.

## Verify the event flow

1. Add a temporary, uniquely worded `Debug.Log` to the callback.
2. Trigger the gameplay action once, such as starting one Ability, equipping one Character Item, or applying one impact.
3. Confirm the callback runs exactly once and that its parameters describe the expected object and state.
4. Disable or unassign the listener and repeat the action. The callback should not run.
5. Re-enable or reassign the listener and repeat once more. The callback should again run exactly once, not once per previous enable cycle.

For a custom event, first test the object-scoped form on one known GameObject before considering a global version.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The callback never runs | Compare the target object, event name, generic types, type order, and registration timing with the publisher | Use the publisher's exact target and typed contract, and register before the gameplay action occurs |
| The Console reports an unexpected event type | Check whether another listener registered the same target and name with a different generic signature | Correct the signature or give the different contract a distinct event name |
| The callback runs twice | Check repeated `OnEnable`, initialization, or character-assignment paths | Pair every registration with one matching unregistration and remove the duplicate path |
| Unregistration has no effect | Compare the target, name, generic arguments, and delegate instance | Use the same named method or cached delegate and the same target that was registered |
| A callback fires after a scene change or reassignment | Check global registrations and listeners that retained the old character or target | Unregister before unloading, disabling, returning to a pool, or replacing the target |
| A pooled object stops receiving events | Check whether it unregisters on disable but never re-registers on enable | Pair `OnEnable` with `OnDisable` and verify both are reached once per pool cycle |
| A background task causes inconsistent behavior | Check whether it calls EventHandler or Unity APIs off the main thread | Marshal the result back to Unity's main thread before registering, executing, or unregistering |

## Related workflows

- [Event names](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/event-names/)
- [Programming concepts](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Create a custom Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/)
- [Object pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/)

## API reference

### Register, execute, and unregister

String literals are accepted because they convert to the Shared `StringHash` value used by the API. Object-scoped and global forms support zero through six typed parameters:

```csharp
using EventHandler = Opsive.Shared.Events.EventHandler;

// Object-scoped, no parameters.
EventHandler.RegisterEvent(target, "OnProjectReady", OnProjectReady);
EventHandler.ExecuteEvent(target, "OnProjectReady");
EventHandler.UnregisterEvent(target, "OnProjectReady", OnProjectReady);

// Object-scoped, two parameters.
EventHandler.RegisterEvent<int, bool>(
    target, "OnProjectValueChanged", OnProjectValueChanged);
EventHandler.ExecuteEvent<int, bool>(
    target, "OnProjectValueChanged", 12, true);
EventHandler.UnregisterEvent<int, bool>(
    target, "OnProjectValueChanged", OnProjectValueChanged);

// Global, one parameter: omit the target from all three calls.
EventHandler.RegisterEvent<string>(
    "OnProjectAnnouncement", OnProjectAnnouncement);
EventHandler.ExecuteEvent<string>(
    "OnProjectAnnouncement", "Round started");
EventHandler.UnregisterEvent<string>(
    "OnProjectAnnouncement", OnProjectAnnouncement);
```

`RegisterUnregisterEvent` is a convenience method when one lifecycle method already receives a boolean registration state:

```csharp
private void SetEventRegistration(bool register)
{
    EventHandler.RegisterUnregisterEvent<Ability, bool>(
        register,
        character,
        "OnCharacterAbilityActive",
        OnAbilityActive);
}
```

### Cache a custom event name

For a project event used frequently, cache its `StringHash` and keep the parameter contract beside it:

```csharp
using Opsive.Shared.Runtime.Utility;
using EventHandler = Opsive.Shared.Events.EventHandler;

private static readonly StringHash s_OnAlertLevelChanged =
    new StringHash("OnAlertLevelChanged");

private void PublishAlertLevel(int level)
{
    EventHandler.ExecuteEvent<int>(
        gameObject, s_OnAlertLevelChanged, level);
}
```

The listener must register and unregister with `RegisterEvent<int>` and `UnregisterEvent<int>` using that same target and event name.

---

<a id="page-ultimate-character-controller-programming-concepts-events-event-names"></a>

# Event Names

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/event-names/)

Use this reference to match an Ultimate Character Controller event name with the exact callback signature used by the released 3.2.0 runtime. The target object, event name, parameter types, and parameter order must all match the publisher.

## Find the correct event and signature

Before registering a callback:

1. Find the relevant `EventHandler.ExecuteEvent` call in the Ultimate Character Controller or Opsive Shared source. Animator and input callbacks may instead be created by an animation event or an `ActiveInputEvent`.
2. Note whether the call is object-scoped, such as `ExecuteEvent(character, ...)`, or global, such as `ExecuteEvent("OnStateChange", ...)`.
3. Copy the event name exactly, including capitalization and any dynamic suffix such as the item slot ID.
4. Match the generic parameter types and their order. A fully qualified type and its imported short name are the same type.
5. Register and unregister the same delegate on the same target object.

The tables below inventory the string event contracts found in the UCC 3.2.0 and Opsive Shared runtime source. Optional integrations can add their own events.

## Register and unregister safely

Register while the listener is active and always unregister before the listener is destroyed or pooled. This component listens on the character that owns the `UltimateCharacterLocomotion` component:

```csharp
using Opsive.Shared.Events;
using Opsive.UltimateCharacterController.Character.Abilities;
using UnityEngine;

public class AbilityStateListener : MonoBehaviour
{
    [SerializeField] private GameObject m_Character;

    private void OnEnable()
    {
        EventHandler.RegisterEvent<Ability, bool>(
            m_Character, "OnCharacterAbilityActive", OnAbilityActive);
    }

    private void OnDisable()
    {
        EventHandler.UnregisterEvent<Ability, bool>(
            m_Character, "OnCharacterAbilityActive", OnAbilityActive);
    }

    private void OnAbilityActive(Ability ability, bool active)
    {
        Debug.Log($"{ability.GetType().Name}: {active}");
    }
}
```

Do not replace `OnAbilityActive` with a new lambda in `UnregisterEvent`; it would be a different delegate and would leave the original callback registered.

## Character and locomotion events

### Character lifecycle and movement

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnCharacterAbilityActive` | `Ability, bool` | A non-item ability started or stopped. |
| `OnCharacterActivate` | `bool` | The character became active or inactive. |
| `OnCharacterAttachCamera` | `CameraController` | A camera controller was attached to the character. |
| `OnCharacterAttachLookSource` | `ILookSource` | The character's look source changed. |
| `OnCharacterChangeMovementType` | `MovementType, bool` | A movement type was deactivated or activated. The Boolean is the active state. |
| `OnCharacterChangeMovingPlatforms` | `Transform` | The active moving platform changed; the transform can be `null`. |
| `OnCharacterChangePerspectives` | `bool` | The character changed to first person (`true`) or third person (`false`). |
| `OnCharacterChangeTimeScale` | `float` | The character time scale changed. |
| `OnCharacterDestroyed` | `()` | Consumer contract used when character-owned helper objects should be destroyed. |
| `OnCharacterForceIndependentLook` | `bool` | An ability requested or released independent look control. |
| `OnCharacterGrounded` | `bool` | The grounded state changed. |
| `OnCharacterImmediateTransformChange` | `bool` | Position or rotation changed immediately; the Boolean requests an Animator snap. |
| `OnCharacterIndependentFade` | `bool, bool` | Another system took or released control of character fading, with the requested revert behavior. |
| `OnCharacterItemAbilityActive` | `ItemAbility, bool` | An item ability started or stopped. |
| `OnCharacterLand` | `float` | The character landed after falling the supplied height. |
| `OnCharacterLean` | `float, float, float` | Lean distance, tilt, and item-tilt multiplier changed. |
| `OnCharacterMoving` | `bool` | The character started or stopped moving. |
| `OnCharacterSnapAnimator` | `bool` | Consumers should snap Animator state; the Boolean controls whether `OnAnimatorSnapped` is then executed. |
| `OnCharacterSwitchModels` | `GameObject` | `ModelManager` changed the active character model. |
| `OnCharacterUpdateAbilityParameters` | `bool` | Ability Animator parameters should update; the Boolean requests an immediate update. |
| `OnCharacterUpdateItemAbilityParameters` | `bool` | Item-ability Animator parameters should update; the Boolean forces changed values to be applied. |
| `OnEnableGameplayInput` | `bool` | Character gameplay input was enabled or disabled. |
| `OnHeightChangeAdjustHeight` | `float` | The Height Change ability applied a collider-height adjustment. |
| `OnStoredInputAbilityResetStoredInputs` | `()` | Stored movement input should be cleared. |

### Input and movement-type callbacks

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnAssistAimSwitchInput` | `float` | Axis input used to switch Assist Aim targets. |
| `OnAssistAimUpdateBreakForce` | `float` | Axis input used to update Assist Aim break force. |
| `OnInputControllerConnected` | `bool` | A controller connected or disconnected. |
| `OnJumpAbilityAirborneJump` | `()` | Button-down input requests an airborne jump. |
| `OnJumpAbilityReleaseHold` | `()` | Button-up input releases a held jump. |
| `OnLeanInputUpdate` | `float` | Axis input updates the active Lean ability. |
| `OnRPGMovementTypeAutoMove` | `()` | Input toggles RPG automatic movement. |
| `OnRPGMovementTypeStartRotate` | `()` | Input begins RPG rotation. |
| `OnRPGMovementTypeStopRotate` | `()` | Input ends RPG rotation. |
| `OnRPGMovementTypeTurn` | `float` | Axis input supplies the RPG turn amount. |
| `OnUnityInputSystemTypeChanged` | `bool` | Unity Input System on-screen-control mode changed. |
| `OnUnityInputTypeChanged` | `UnityInput, bool` | Legacy `UnityInput` virtual-input mode changed. |

### Ability animation callbacks

These zero-parameter names are received through the character Animator Monitor. The animation clip must contain the corresponding animation event when an ability is configured to wait for it.

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnAnimatorDamageVisualizationComplete` | `()` | Damage Visualization animation completed. |
| `OnAnimatorDropItem` | `()` | The Drop ability reached its drop point. |
| `OnAnimatorEnteredVehicle` | `()` | The vehicle-entry animation reached its completion point. |
| `OnAnimatorExitedVehicle` | `()` | The vehicle-exit animation reached its completion point. |
| `OnAnimatorFallComplete` | `()` | The Fall ability's landing animation completed. |
| `OnAnimatorGenericAbilityComplete` | `()` | A Generic ability animation completed. |
| `OnAnimatorImpactKnockBackComplete` | `()` | Impact Knock Back animation completed. |
| `OnAnimatorInteract` | `()` | The Interact ability reached its interaction point. |
| `OnAnimatorInteractComplete` | `()` | The Interact ability animation completed. |
| `OnAnimatorJump` | `()` | The Jump ability reached its force-application point. |
| `OnAnimatorPickup` | `()` | The Pickup ability reached its pickup point. |
| `OnAnimatorPickupComplete` | `()` | The Pickup ability animation completed. |
| `OnAnimatorQuickTurnComplete` | `()` | Quick Turn animation completed. |
| `OnAnimatorReviveComplete` | `()` | Revive animation completed. |
| `OnAnimatorRideDismount` | `()` | The Ride ability reached its dismount point. |
| `OnAnimatorRideMount` | `()` | The Ride ability reached its mount point. |
| `OnAnimatorRideMountComplete` | `()` | The Ride mount animation completed. |
| `OnAnimatorSnapped` | `()` | The Animator Monitor finished snapping. |
| `OnAnimatorStartMovementComplete` | `()` | Quick Start animation completed. |
| `OnAnimatorStopMovementComplete` | `()` | Quick Stop animation completed. |
| `OnAnimatorWillSnap` | `()` | The Animator Monitor is about to snap. |

### Item animation callbacks

An `AnimationSlotEventTrigger` registers both the base name and a zero-parameter name ending in `Slot{slotID}`. For example, slot 1 can invoke either `OnAnimatorItemUse` or `OnAnimatorItemUseSlot1`. Rows shown as "base or slot" use that behavior; the remaining rows use only the displayed name.

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnAnimatorActivateThrowableObject` | `()` | A throwable module activates its throwable object. |
| `OnAnimatorActiveAttackStart` or `OnAnimatorActiveAttackStartSlot{slotID}` | `()` | A melee attack enters its active hit period. |
| `OnAnimatorAllowChainAttack` or `OnAnimatorAllowChainAttackSlot{slotID}` | `()` | A melee attack allows the next chained attack. |
| `OnAnimatorEndCast` or `OnAnimatorEndCastSlot{slotID}` | `()` | A magic caster reaches its end-cast point. |
| `OnAnimatorItemDepleteChargeComplete` or `OnAnimatorItemDepleteChargeCompleteSlot{slotID}` | `()` | An item trigger finishes depleting its charge. |
| `OnAnimatorItemEquip` or `OnAnimatorItemEquipSlot{slotID}` | `()` | A Character Item reaches its equip point. |
| `OnAnimatorItemEquipComplete` or `OnAnimatorItemEquipCompleteSlot{slotID}` | `()` | A Character Item's equip animation completes. |
| `OnAnimatorItemImpactComplete` | `()` | An item-impact animation completes. |
| `OnAnimatorItemImpactCompleteSlot{slotID}` | `()` | A Block item-impact animation completes for the appended slot ID. |
| `OnAnimatorItemMaxChargeComplete` or `OnAnimatorItemMaxChargeCompleteSlot{slotID}` | `()` | An item trigger reaches maximum charge. |
| `OnAnimatorItemMinChargeComplete` or `OnAnimatorItemMinChargeCompleteSlot{slotID}` | `()` | An item trigger reaches minimum charge. |
| `OnAnimatorItemReactivateClip` | `()` | A shootable reloader reactivates its clip. |
| `OnAnimatorItemReload` or `OnAnimatorItemReloadSlot{slotID}` | `()` | A shootable reloader reaches its reload point. |
| `OnAnimatorItemReloadAttachClip` | `()` | A shootable reloader attaches its clip. |
| `OnAnimatorItemReloadAttachProjectile` | `()` | A projectile module attaches the reload projectile. |
| `OnAnimatorItemReloadComplete` or `OnAnimatorItemReloadCompleteSlot{slotID}` | `()` | A shootable reload animation completes. |
| `OnAnimatorItemReloadDetachClip` | `()` | A shootable reloader detaches its clip. |
| `OnAnimatorItemReloadDropClip` | `()` | A shootable reloader drops its detached clip. |
| `OnAnimatorItemReloadShowProjectile` | `()` | A projectile module shows its reload projectile. |
| `OnAnimatorItemRemovePin` | `()` | A throwable module removes its pin. |
| `OnAnimatorItemUnequip` or `OnAnimatorItemUnequipSlot{slotID}` | `()` | A Character Item reaches its unequip point. |
| `OnAnimatorItemUnequipComplete` or `OnAnimatorItemUnequipCompleteSlot{slotID}` | `()` | A Character Item's unequip animation completes. |
| `OnAnimatorItemUse` or `OnAnimatorItemUseSlot{slotID}` | `()` | A usable item reaches its use point. |
| `OnAnimatorItemUseComplete` or `OnAnimatorItemUseCompleteSlot{slotID}` | `()` | A usable item's animation completes. |
| `OnAnimatorMeleeAttackComplete` or `OnAnimatorMeleeAttackCompleteSlot{slotID}` | `()` | A melee attack animation completes. |
| `OnAnimatorReequipThrowableItem` or `OnAnimatorReequipThrowableItemSlot{slotID}` | `()` | A throwable item reaches its re-equip point. |
| `OnAnimatorRepeatCast` or `OnAnimatorRepeatCastSlot{slotID}` | `()` | A magic caster reaches its repeat-cast point. |
| `OnAnimatorStartCast` or `OnAnimatorStartCastSlot{slotID}` | `()` | A magic caster reaches its start-cast point. |
| `OnAnimatorStartVisibleProjectile` | `()` | A projectile module begins showing its visible projectile. |
| `OnAnimatorStopTrail` | `()` | A melee extra module stops its trail. |

### State System

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnStateChange` | `GameObject, string, bool` | Global event sent when a state changes, but only when the scene `StateManager` has **Send State Change Event** enabled. |

`OnStateChange` is global. Register it without a target object; do not register it on the changed GameObject.

## Abilities, items, and inventory events

### Ability and aiming events

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnAbilityMessageCanStart` | `Ability, bool` | An ability's message-based start permission changed. |
| `OnAbilityUnequipItemComplete` | `CharacterItem, int` | Unequipping a Character Item from a slot completed. |
| `OnAbilityWillEquipItem` | `CharacterItem, int` | An ability is about to equip a Character Item in a slot. |
| `OnAimAbilityAim` | `bool` | The Aim ability's aiming state changed. |
| `OnAimAbilityStart` | `bool, bool` | Aim started or stopped; the second value identifies an input-driven change. |
| `OnAimTargetChange` | `int, Transform, bool` | An Assist Aim target ID, target transform, or lock state changed. |
| `OnEquipUnequipItemSetIndexChange` | `int` | Equip Unequip changed its item-set index. |
| `OnEquipUnequipVerifyUnequipItem` | `int, int` | Equip Unequip requests verification for an item-set group and slot before completing unequip. |
| `OnUseAbilityStart` | `bool, Use` | A Use ability started or stopped. |
| `OnUseAbilityUsedItem` | `IUsableItem` | The Use ability used an item. |

### Inventory and item-set events

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnActiveItemSetChange` | `int, ItemSet, ItemSet` | An item-set group changed from its previous set to a new set. |
| `OnInventoryAddItem` | `CharacterItem` | A Character Item was added to the inventory. |
| `OnInventoryAdjustItemIdentifierAmount` | `IItemIdentifier, int, int` | An Item Identifier amount changed from the previous amount to the new amount. |
| `OnInventoryDestroyItem` | `CharacterItem` | A Character Item is being destroyed by the inventory. |
| `OnInventoryDropItem` | `GameObject` | Removing an Item Identifier with dropping enabled produced a drop instance. |
| `OnInventoryDropItem` | `CharacterItem, int, GameObject` | A Character Item drop reports the item, amount, and spawned object. |
| `OnInventoryEquipItem` | `CharacterItem, int` | A Character Item was equipped in a slot. |
| `OnInventoryLoadDefaultLoadoutComplete` | `()` | The inventory finished loading its default loadout. |
| `OnInventoryPickupItem` | `CharacterItem, int, bool, bool` | A Character Item pickup reports amount, immediate-pickup, and force-equip choices. |
| `OnInventoryPickupItemIdentifier` | `IItemIdentifier, int, bool, bool` | An Item Identifier pickup reports amount, immediate-pickup, and force-equip choices. |
| `OnInventoryRemoveItem` | `CharacterItem, int` | A Character Item was removed from a slot. |
| `OnInventoryRespawned` | `()` | Inventory respawn processing completed. |
| `OnInventoryUnequipItem` | `CharacterItem, int` | A Character Item was unequipped from a slot. |
| `OnInventoryWillAddItem` | `CharacterItem` | A Character Item is about to be added. |
| `OnItemSetGroupUpdated` | `ItemSetGroup` | An item-set group finished updating. |
| `OnItemSetGroupWillUpdate` | `ItemSetGroup, List<ItemSetStateInfo>` | An item-set group is about to update and exposes its state list. |
| `OnItemSetIndexChange` | `int, int` | An item-set group index and active item-set index changed. |
| `OnItemSetManagerUpdateItemSet` | `int, int` | The Item Set Manager should update a group's active item set. |
| `OnItemSetManagerUpdateNextItemSet` | `int, int, int` | The Item Set Manager reports the group, previous set, and next set indices. |
| `OnNextItemSet` | `CharacterItem, bool` | A Character Item requests the next item set and states whether failure should unequip it. |

`OnInventoryDropItem` deliberately has two parameter shapes in 3.2.0. If one listener registers both shapes on the same character, use the `allowMultipleTypes` overload for both registrations.

### Item actions, perspective items, and UI

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnAddCrosshairsSpread` | `bool, bool` | Starts or stops crosshair spread and identifies recoil-driven spread. |
| `OnAddSecondaryCameraForce` | `Vector3, Vector3, float` | Adds positional and rotational camera force with a rest-accumulation value. |
| `OnAddSecondaryForce` | `int, Vector3, Vector3, bool` | Adds positional and rotational item force for a slot, optionally in global space. |
| `OnFirstPersonPerspectiveActivate` | `FirstPersonPerspectiveItem, bool` | A first-person perspective item activated or deactivated. |
| `OnFirstPersonPerspectiveItemStartEquip` | `CharacterItem` | A first-person Character Item began equipping. |
| `OnFirstPersonPerspectiveItemUnequip` | `CharacterItem` | A first-person Character Item was unequipped. |
| `OnItemActionTriggerStoppedEarly` | `TriggerModule` | A trigger module stopped before it triggered, such as when its character died. |
| `OnItemPickupStartPickup` | `()` | An Item Pickup began its pickup sequence. |
| `OnItemPickupStopPickup` | `()` | An Item Pickup ended its pickup sequence. |
| `OnItemReload` | `IReloadableItem` | Reloading began for a reloadable item. |
| `OnItemReloadComplete` | `IReloadableItem` | Reloading completed for a reloadable item. |
| `OnItemShowFullScreenUI` | `int, bool` | A Character Item requests that its full-screen UI ID be shown or hidden. |
| `OnItemStartUse` | `IUsableItem, bool` | A usable item began or ended use. |
| `OnItemTryReload` | `int, IItemIdentifier, IItemIdentifier, bool, bool` | A slot requests reload with the item and consumable identifiers plus immediate-reload and equip-check choices. |
| `OnItemUpdateDominantItem` | `CharacterItem, bool` | A Character Item's dominant-item state changed. |
| `OnItemUse` | `IUsableItem` | A usable item performed its use action. |
| `OnItemUseComplete` | `IUsableItem` | A usable item's use action completed. |
| `OnMagicItemCast` | `CharacterItem` | A magic Character Item cast. |
| `OnMagicItemStartStopBeginEndActions` | `CharacterItem, bool, bool` | A magic item started or stopped its begin/end actions. |
| `OnMeleeRecoil` | `MeleeRecoilModule` | A melee recoil module applied recoil. |
| `OnMonitoredCharacterItemChanged` | `CharacterItem, CharacterItem` | An item monitor changed from its previous Character Item to a new one. |
| `OnRefreshSlotItemMonitor` | `CharacterItem` | A Character Item requests a slot monitor refresh. |
| `OnShieldImpact` | `ShieldAction, ImpactCallbackContext` | A Shield Action received an impact context. |
| `OnShootableItemAmmoChange` | `CharacterItem, ShootableAmmoModule` | A shootable item's active ammo module or amount changed. |
| `OnShootableItemClipChange` | `CharacterItem, ShootableClipModule` | A shootable item's active clip module or amount changed. |
| `OnShootableWeaponShowProjectile` | `GameObject, bool` | A shootable item requests that a projectile object be shown or hidden. |
| `OnStartReload` | `ShootableReloaderModule` | A shootable reloader module began reloading. |
| `OnThrowableItemAmmoChange` | `CharacterItem, ThrowableAmmoModule` | A throwable item's active ammo module or amount changed. |

## Health and attribute events

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnAttributeModifierAutoUpdateEnabled` | `AttributeModifier, bool` | An Attribute Modifier's automatic update was enabled or disabled. See the 3.2.0 source note below before relying on the built-in impact listener. |
| `OnAttributeReachedDestinationValue` | `()` | An Attribute reached its configured destination value. This event is scoped to the `Attribute` object. |
| `OnAttributeUpdateValue` | `Attribute` | An Attribute value changed. This event is scoped to the Attribute Manager's GameObject. |
| `OnDeath` | `Vector3, Vector3, GameObject` | Health reached zero and reports impact position, force, and attacker. |
| `OnHealthDamage` | `float, Vector3, Vector3, GameObject, Collider` | Health received damage with amount, position, force, attacker, and hit collider. |
| `OnHealthDamageWithData` | `DamageData` | Health received the complete damage payload. |
| `OnHealthHeal` | `float` | Health was healed by the supplied amount. |
| `OnRespawn` | `()` | An object completed its respawn or pooled reset. |
| `OnWillRespawn` | `()` | A Respawner is about to respawn the object. |

## Camera, objects, and impact events

### Camera and view types

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnAnchorOffsetUpdated` | `()` | The Camera Controller anchor offset changed during Play Mode. |
| `OnCameraAttachCharacter` | `GameObject` | The Camera Controller attached a character. |
| `OnCameraChangePerspectives` | `bool` | The camera changed to first person (`true`) or third person (`false`). |
| `OnCameraChangeViewTypes` | `ViewType, bool` | A View Type was deactivated or activated. |
| `OnCameraImmediatePosition` | `()` | The camera should move to its target position immediately. |
| `OnCameraPositionalForce` | `Vector3` | Adds positional force to the attached Camera Controller. |
| `OnCameraRotationalForce` | `Vector3` | Adds rotational force to the attached Camera Controller. |
| `OnCameraWillChangePerspectives` | `bool` | The camera is about to change perspective. |
| `OnCameraZoom` | `bool` | Camera zoom activated or deactivated. |
| `OnRPGViewTypeStartForcedRotation` | `()` | RPG view forced rotation began. |
| `OnRPGViewTypeStartFreeMovement` | `()` | RPG view free movement began. |
| `OnRPGViewTypeStopForcedRotation` | `()` | RPG view forced rotation ended. |
| `OnRPGViewTypeStopFreeMovement` | `()` | RPG view free movement ended. |
| `OnThirdPersonViewTypeStepZoom` | `float` | A third-person view requests a zoom step. |
| `OnTryRecenterTracking` | `()` | A global event requests tracking recentering after a view rotation change. |

### Objects, impacts, and monitors

| Event | Parameters | Runtime use |
| --- | --- | --- |
| `OnObjectDetected` | `GameObject, bool` | A detected object receives the interacting character and selected state. |
| `OnObjectImpact` | `ImpactCallbackContext` | The impacted object receives the impact context. |
| `OnObjectImpactSourceCallback` | `ImpactCallbackContext` | The impact originator receives its source callback context. |
| `OnObjectPickedUp` | `ObjectPickup` | A character picked up an Object Pickup. |
| `OnShowUI` | `bool` | Character monitors should show or hide their UI. |

## Verify a callback

1. Add a temporary log or breakpoint inside the callback.
2. Enter Play Mode and trigger the smallest action that publishes the event.
3. Confirm the callback fires once and that its values match the observed action.
4. Disable or despawn the listener, repeat the action, and confirm it no longer fires.
5. Re-enable or respawn the listener and confirm it still fires only once.

For an Animator callback, inspect the animation clip and confirm the animation event name matches exactly. For an input callback, confirm the owning ability or movement type registered its `ActiveInputEvent` before testing.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Callback never runs | Compare the object passed to `RegisterEvent` with the publisher's first `ExecuteEvent` argument. | Register on the same character, camera, Attribute, impacted object, or other owner. Use the targetless overload only for a global event. |
| Callback reports a type mismatch | Compare every generic type and its order with the publisher. | Update both `RegisterEvent` and `UnregisterEvent` to the exact signature. |
| Callback runs more than once | Look for repeated registration during enable, pooling, or initialization. | Pair one registration with one unregistration and reuse the same delegate instance. |
| Callback remains after despawn | Check whether the pooled object unregisters before returning to the pool. | Unregister in the listener's disable or teardown path. |
| Animator callback never runs | Inspect the active animation clip and whether the ability is waiting for an event rather than a duration. | Add or correct the clip event, or configure the supported duration path. |
| `OnStateChange` never runs | Inspect the scene `StateManager`. | Enable **Send State Change Event** and use a global registration. |
| One `OnInventoryDropItem` signature conflicts with the other | Check whether both signatures were registered under the same target and name. | Register both with the `allowMultipleTypes` overload, or listen only to the path you need. |

## UCC 3.2.0 source notes

The released 3.2.0 source contains a few cleanup or spelling mismatches. They are not additional event contracts:

- `AttributeModifier` publishes `OnAttributeModifierAutoUpdateEnabled`, but the built-in impact action registers `OnAttributeModifierAutoUpdateEnable`. That listener does not match the publisher.
- Equip Unequip registers `OnEquipUnequipVerifyUnequipItem` but unregisters `OnEquipUnequipVerifyUnequip`. The valid runtime event includes `Item`.
- Lean registers `OnCharacterChangePerspectives` with a `bool` callback but its final cleanup uses `OnLeanInputUpdate`. The valid `OnLeanInputUpdate` runtime signature is `float`.
- Shield Action contains cleanup for `OnBlockAbilityStart`, but the released runtime has no matching registration or execution for that literal.

Do not build new listeners around the mismatched spellings. If these defects affect a project, keep any local source correction isolated so it can be reviewed when updating UCC.

## EventHandler API reference

`Opsive.Shared.Events.EventHandler` provides object-scoped and global overloads for zero through six parameters:

```csharp
// Object-scoped.
EventHandler.RegisterEvent<T1>(target, eventName, callback);
EventHandler.ExecuteEvent<T1>(target, eventName, value);
EventHandler.UnregisterEvent<T1>(target, eventName, callback);

// Global.
EventHandler.RegisterEvent<T1>(eventName, callback);
EventHandler.ExecuteEvent<T1>(eventName, value);
EventHandler.UnregisterEvent<T1>(eventName, callback);
```

The event name parameter is a `StringHash`; string literals convert to it implicitly. The handler stores registrations in static tables and clears them during Unity's subsystem registration. Use events on Unity's main thread and unregister normal object and pooled-object listeners explicitly rather than relying on a later domain or subsystem reset.

The one-, two-, and three-parameter registration overloads also accept `allowMultipleTypes`. Use that option only when the same target and event name intentionally carry more than one signature, such as `OnInventoryDropItem`.

## Related pages

- [Events overview](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Programming concepts](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/)
- [Create a custom ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)
- [Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/inventory/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Object pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/)
- [Objects](https://opsive.com/support/documentation/ultimate-character-controller/objects/)

---

<a id="page-ultimate-character-controller-programming-concepts-scheduler"></a>

# Scheduler

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/)

Run a callback later in UCC's shared Update or FixedUpdate loop, and keep a cancellable handle when the work must stop with its owner. Use the Scheduler for small game-time delays and repeating controller work, not as an ownerless replacement for every coroutine or update method.

## When to use the Scheduler

The Scheduler is a good fit when code needs to:

- finish a projectile, effect, state, or animation fallback after a short game-time delay;
- defer physics or locomotion work to a later FixedUpdate;
- repeat a small callback every Update or FixedUpdate without adding another `MonoBehaviour` update method; or
- cancel pending work when an ability, item, pooled object, or scene owner stops.

Keep an ordinary `Update`, `FixedUpdate`, coroutine, or purpose-built UCC lifecycle when the operation needs complex sequencing, yields, unscaled time, per-character time, or several independently visible states.

## Set up the Scheduler

No scene component is required for a basic call. The first `Scheduler.Schedule` or `Scheduler.ScheduleFixed` finds an existing `SchedulerBase`; if none exists, it creates a GameObject named `Scheduler` with a `SchedulerBase` component.

Add one **Scheduler** component deliberately when capacity and scene ownership matter. Its **Max Event Count** defaults to `200` and allocates separate arrays of that size for Update and FixedUpdate callbacks during `Awake`. Change the value before Play Mode. In Play Mode, its Inspector shows the scheduled callback target and method for diagnosis.

Keep that Scheduler in a scene that remains loaded for as long as its callbacks are expected to run. It is a global queue, not a queue owned by the component that scheduled each callback.

## Choose when the callback runs

Both scheduling methods calculate their end time from `TimeUtility.Time`. Without a project `TimeManagerBase`, that is Unity's scaled `Time.time`.

| Requirement | Choice | Observable behavior |
| --- | --- | --- |
| General gameplay, presentation, respawn, or UI-adjacent work | `Scheduler.Schedule` | The callback runs from the Scheduler's next eligible `Update` after the global end time. |
| Physics, locomotion, or item work that must align with a physics step | `Scheduler.ScheduleFixed` | The callback runs from the next eligible `FixedUpdate` after the same global end time. |
| Run synchronously | A delay of `0` | On an enabled Scheduler, the action runs inside the `Schedule` call and the method returns `null`; nothing enters the queue. |
| Repeat every rendered frame | `Scheduler.Schedule(-1, action)` | The action runs every `Update` until explicitly cancelled. |
| Repeat every physics step | `Scheduler.ScheduleFixed(-1, action)` | The action runs every `FixedUpdate` until explicitly cancelled. |

A positive delay is a minimum, not an exact timestamp: the callback waits until its selected loop next checks the queue. Do not use negative delays other than the documented `-1` repeating value.

The released Shared Scheduler has no unscaled-time overload. At the default clock, a positive delay pauses when `Time.timeScale` is `0`; `FixedUpdate` also stops running. Use an owner-managed timer based on `Time.unscaledTime` or `Time.unscaledDeltaTime` when a pause menu, connection timeout, or other real-time operation must continue.

The `-1` sentinel is loop-driven rather than elapsed-time-driven. An Update repeater continues while global time is paused because Unity still calls `Update`; a FixedUpdate repeater waits because Unity stops physics steps at a zero time scale.

The Scheduler also does not read an individual `UltimateCharacterLocomotion.TimeScale`. A slowed or paused character's scheduled callback still follows the global `TimeUtility.Time`. Keep character-time work in the owning UCC lifecycle, or accumulate time explicitly from that character's scale when it must adapt to changes during the delay. A project `TimeManagerBase` changes the Scheduler's clock globally, not per character.

## Own the handle lifecycle

Every nonzero call returns a `ScheduledEventBase` handle. Store it when the callback might need to be cancelled.

1. Cancel the previous handle before replacing it.
2. Assign the new handle returned by `Schedule` or `ScheduleFixed`.
3. At the start of a one-shot callback, set the owning field to `null`.
4. On early completion, disable, destruction, or pool return, call `Scheduler.Cancel(handle)` and immediately set the field to `null`.
5. Explicitly cancel every `-1` repeating event; it never removes itself.

Scheduled event objects are internally obtained from `GenericObjectPool`. A one-shot handle is removed from the active queue before its callback and returned to that pool after the callback finishes. Cancellation also returns it. The same object can then become another system's event, so a completed or cancelled handle is no longer yours: do not retain it, poll its `Active` property later, or cancel it again.

`Active` is useful only while the owner still controls a pending handle. A stale reference may become active again when the internal object is reused for an unrelated callback.

## Clean up with the owner

The Scheduler does not inspect the callback target's lifetime and does not automatically cancel by GameObject, component, ability, item, or scene. A disabled component's callback still runs unless it is cancelled, and a delegate can retain captured objects until the event is reused.

- Cancel owner-bound work in `OnDisable` when disabling means the operation has ended.
- Use `OnDestroy` as a final cleanup path for work that intentionally survives a temporary disable.
- For a pooled GameObject, cancel in `OnDisable`, clear the handle, and schedule a fresh event after each checkout.
- For an ability or item module, cancel when the action stops or the module is no longer active, not only when the character is destroyed.
- Avoid lambdas that capture a large object graph when a method plus one of the Scheduler's typed parameter overloads can pass the required values directly.

Some lifecycles intentionally outlive a disabled target. The built-in **Respawner**, for example, can schedule a respawn while its GameObject is inactive because the independent Scheduler remains active. Decide that ownership explicitly rather than applying `OnDisable` cancellation to every use case.

The Scheduler singleton reference resets at subsystem registration and after its scene unloads. Active callbacks do not migrate to a replacement Scheduler. Stop or transfer the owning operation before unloading the Scheduler's scene.

## Verify in Play Mode

1. Schedule one visible one-shot result with a positive delay. Confirm it does not run immediately and runs once from the intended Update or FixedUpdate phase.
2. Schedule it again, cancel the handle before the end time, set the field to `null`, and confirm the result never occurs.
3. Disable or return the owner to its pool before the delay completes. Confirm no callback changes the inactive or reused object.
4. Re-enable or reuse the owner and trigger it twice. Confirm one current handle exists and the callback occurs only once for the latest use.
5. Pause global time. Confirm ordinary Scheduler delays wait until global time resumes; separately test an owner-managed unscaled timer if the feature requires one.
6. If the feature uses a character-specific time scale, slow only that character and confirm whether the intended behavior should follow the character or the global Scheduler clock.
7. Select the scene Scheduler in Play Mode. Confirm its active count returns to the baseline after completion or cancellation and the Console has no capacity or missing-reference error.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The callback runs immediately and the saved handle is `null`. | The supplied delay is `0`. | Call the method directly when synchronous execution is intended, or use a positive delay when a queued, cancellable callback is required. |
| A callback runs after an ability, component, or pooled object has stopped. | Its handle was not cancelled in the owner's stop, disable, destroy, or return path. | Cancel the current handle and set the field to `null` before the owner can be reused. |
| Cancelling one operation stops an unrelated callback. | Code retained a handle after its callback or cancellation, and that pooled handle was reused. | Clear the field during both completion and cancellation. Never reuse or inspect an expired handle. |
| A delay does not progress while the game is paused. | Scheduler uses scaled `TimeUtility.Time`, and `ScheduleFixed` also needs FixedUpdate to run. | Use an explicit unscaled timer for real-time work; do not expect a Scheduler overload to change clocks. |
| A slowed character's callback fires at normal game speed. | Scheduler has no per-character time-scale parameter. | Keep the timer in the character-owned lifecycle and advance it using the intended character-scale rule. |
| The Console reports that the `ActiveEvents` array is full. | Concurrent Update or FixedUpdate events reached **Max Event Count**, commonly because `-1` events or ownerless callbacks were not cancelled. | Cancel leaked work, reduce repeating callbacks, then raise **Max Event Count** before Play Mode only if the measured workload requires it. |
| No callback runs after a scene transition. | The scene that owned the Scheduler unloaded, or the explicit Scheduler component was disabled. | Keep the Scheduler in the required long-lived scene and reschedule work under the new scene owner. Do not schedule against a disabled Scheduler. |

## Related pages

- [Programming Concepts](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/)
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/)
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/)
- [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/)

## API examples

### Cancel a one-shot event safely

This component assumes its root was checked out through the [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/). It schedules a fresh return on every activation, clears the field before the callback returns the GameObject, and cancels an early disable.

```csharp
using Opsive.Shared.Game;
using UnityEngine;

public sealed class TimedPooledEffect : MonoBehaviour
{
    [Min(0.001f)]
    [SerializeField] private float m_Lifetime = 1.5f;

    private ScheduledEventBase m_ReturnEvent;

    private void OnEnable()
    {
        CancelReturn();
        m_ReturnEvent = Scheduler.Schedule(m_Lifetime, ReturnToPool);
    }

    private void ReturnToPool()
    {
        m_ReturnEvent = null;
        ObjectPool.Destroy(gameObject);
    }

    private void OnDisable()
    {
        CancelReturn();
    }

    private void CancelReturn()
    {
        if (m_ReturnEvent == null) {
            return;
        }

        Scheduler.Cancel(m_ReturnEvent);
        m_ReturnEvent = null;
    }
}
```

For an object that is not pool-owned, replace `ObjectPool.Destroy` with the completion behavior owned by that object.

### Pass values without a capturing lambda

The released API provides zero-, one-, two-, and three-parameter overloads for both loops. Each public overload returns `ScheduledEventBase`.

```csharp
using Opsive.Shared.Game;
using UnityEngine;

public sealed class DelayedMarker : MonoBehaviour
{
    private ScheduledEventBase m_MarkerEvent;

    public void ShowLater(GameObject marker, Vector3 position, float delay)
    {
        CancelMarker();
        m_MarkerEvent = Scheduler.Schedule(
            delay, ShowMarker, marker, position);
    }

    private void ShowMarker(GameObject marker, Vector3 position)
    {
        m_MarkerEvent = null;
        marker.transform.position = position;
        marker.SetActive(true);
    }

    private void OnDisable()
    {
        CancelMarker();
    }

    private void CancelMarker()
    {
        if (m_MarkerEvent == null) {
            return;
        }

        Scheduler.Cancel(m_MarkerEvent);
        m_MarkerEvent = null;
    }
}
```

The principal signatures are `Schedule(float, Action)`, `Schedule<T>(float, Action<T>, T)`, and the matching two- and three-parameter forms. `ScheduleFixed` provides the same shapes for FixedUpdate. `Cancel(ScheduledEventBase)` removes a still-active handle. `ScheduledEventBase.EndTime`, `Location`, and `Active` are readable, but only while the caller still owns that pending handle.

---

<a id="page-ultimate-character-controller-programming-concepts-object-pool"></a>

# Object Pool

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/)

Reuse frequently spawned projectiles, impact effects, and temporary data instead of repeatedly allocating and destroying them. Pool an object only when its complete checkout, initialization, and return lifecycle has one clear owner.

## Choose the correct pool

The released Version 3 packages provide two separate pools:

| Object being reused | Pool | Lifecycle |
| --- | --- | --- |
| A `GameObject` or a `Component` on its root | `Opsive.Shared.Game.ObjectPool` | `Instantiate` -> initialize -> `Destroy` |
| An ordinary managed C# object | `Opsive.Shared.Utility.GenericObjectPool` | `Get` -> initialize -> `Return` |

`ObjectPool` is the public wrapper around `ObjectPoolBase`. UCC runtime code often calls `ObjectPoolBase` directly, but both names use the same Unity-object pool. Contrary to older versions of this page, `ObjectPool` does not pool an arbitrary `System.Object`; use `GenericObjectPool` for that case.

Do not add pooling only because an object exists briefly. Pooling is most useful for objects created often enough that instantiation, destruction, or garbage collection is measurable. Long-lived scene objects and objects with expensive, error-prone reset logic are usually clearer without a pool.

## Set up the GameObject pool

No registration call is required. The first `ObjectPool.Instantiate` for an original prefab creates its pool key and either reuses an available instance or lets Unity create the first clone.

For a predictable warm-up instead of a first-use allocation:

1. Create one scene GameObject for the pool and add the **Object Pool** component.
2. Add an entry to its preload list.
3. Assign the project prefab under **Preloaded Prefab** and set **Count** to the largest number that the controlled scenario normally needs at once.
4. Keep the source prefab active, save the scene, and enter Play Mode. At `Start`, the component creates that many instances and immediately returns them to the pool.

If the scene has no pool component, the first pool call finds an existing `ObjectPoolBase` or creates a GameObject named `ObjectPool`. Add the component deliberately when preload count, scene ownership, or teardown order matters.

Prefer a prefab asset as the original. A temporary scene object can technically be cloned, but its instance ID and lifetime become part of the pool key; unloading that scene can invalidate both the original and entries derived from it.

## Understand checkout and return

When a previously returned GameObject is checked out, the pool sets its world position and rotation, assigns the requested parent, activates it, and records the original that owns it. When it is returned, the pool deactivates it, reparents it under the pool component, and queues it for reuse.

Treat the root GameObject handed out by the pool as the unit of ownership:

- Return that same root, not one of its children.
- Do not call `UnityEngine.Object.Destroy` on a checked-out or inactive pooled instance.
- Do not return the object twice. Once returned, it is no longer recorded as checked out.
- Do not use `ObjectPool.Destroy` for an object created with Unity's `Instantiate`; Version 3 logs an error and leaves that object active.
- Let the system that checked out the object decide when it is finished. A projectile, an impact effect, and the effect's caller should not all try to return the same root.

The pool changes position, rotation, parent, and active state. It does not restore local scale, Rigidbody values, particles, trails, collider state, ignored collisions, event subscriptions, scheduled callbacks, or custom fields.

## Reset every reused instance

Design a pooled component as if its second use were the main test:

1. Put one-time reference lookup in `Awake`.
2. Put per-use values in an explicit method such as `Initialize`, `Launch`, or `Play` and call it after every checkout.
3. Clear transient visual and physics state before starting the new use. Reset local scale explicitly when gameplay can change it.
4. Cancel scheduled work and unregister external listeners before return. `OnDisable` is a useful final safeguard because `ObjectPool.Destroy` deactivates the root.
5. Make the return path idempotent in project code so two completion signals cannot return the same instance twice.

For managed objects, implement `IPoolable.Reset` when the object holds lists, delegates, Unity object references, or other mutable data. `GenericObjectPool.Return` calls `Reset` before storing an `IPoolable`; `Get` does not initialize the next use for you.

## Follow the built-in projectile lifecycle

The included UCC Projectile is already designed for pooling. A Shootable or Magic **Spawn Projectile** module checks the prefab out through `ObjectPoolBase`, positions it, and calls its initialization path. Initialization assigns a new ID, velocity, owner, and impact data; cancels an old destruction callback; restores the collider; clears the Trail Renderer; restarts the Particle System; and removes ignored-collider state left by the prior use.

On impact or at the configured **Lifespan**, `ProjectileBase` stops the current use and returns its root through `ObjectPoolBase.Destroy`. Configure the projectile and its owning module through the [Projectile workflow](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/). Do not add a second `Destroy` call to that built-in path.

Use the same ownership model for a custom impact effect: check out its root, clear and play the effect, then let its completion callback return that root. The API example below shows this pattern. An [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/) or [Magic Particle](https://opsive.com/support/documentation/ultimate-character-controller/objects/magic-particle/) may have additional damage, timing, or networking ownership; follow that component's documented lifecycle rather than returning it independently from the caller.

## Plan scene and teardown ownership

Inactive GameObject instances become children of the pool component, so they belong to the pool's scene. Keep the pool in the same long-lived scene as the systems that use it, or use a deliberately persistent owner for cross-scene effects. Before unloading an additive scene, stop its spawners, return its checked-out objects, and make sure the unload will not destroy originals or inactive entries owned by another scene's pool.

`ObjectPoolBase` resets its singleton reference during subsystem registration and after its scene unloads. `GenericObjectPool` has no public clear operation or subsystem-registration reset in the released Shared package. When **Enter Play Mode Options** disables domain reload, managed entries can therefore survive a Play Mode boundary. `IPoolable.Reset` must remove Unity references and prior-use state instead of assuming a fresh static pool.

The Shared runtime shipped with UCC 3.2.0 also expects every queued GameObject entry to remain valid: its queue reader retries a null first entry without removing that entry. Avoid allowing an additive-scene unload to destroy an inactive entry that belongs to a surviving pool.

For a supported multiplayer integration, use its `NetworkObjectPool` path for network-owned projectiles and destruction. Local `ObjectPool.Destroy` does not establish spawn authority, replication, save persistence, or ownership.

## Verify in Play Mode

1. Preload one instance and trigger the feature once. Confirm the object appears at the intended position and under the intended runtime parent.
2. Let it finish. Confirm it becomes inactive beneath the Object Pool and produces no pool, missing-reference, or uncancelled-callback error.
3. Trigger it again. In the Hierarchy, confirm the same instance is reactivated rather than another clone being created.
4. Change state during the first use, such as scale, particle playback, velocity, or a target reference. Confirm the second use begins from the expected clean state.
5. Trigger the maximum expected burst. Confirm the pool grows only to the number of simultaneously active instances and then reuses them.
6. If additive scenes or disabled domain reload are supported, repeat the test across that exact unload or Play Mode boundary.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| `Unable to pool ... the GameObject was not instantiated with ObjectPoolBase.Instantiate` appears. | The object came from Unity's `Instantiate`, the returned object is a child, or it was already returned. | Pair one Opsive checkout with one return and retain the checked-out root reference. Let the original owner use Unity's `Destroy` for a nonpooled object. |
| The second use retains velocity, particles, a trail, scale, a target, or a callback. | The component relies only on activation to reset state. | Reset every per-use value in an initialization method and clear scheduled work, listeners, and mutable state before return. |
| The first spawn causes a frame spike. | The scene has no explicit Object Pool preload, or **Count** is below the normal simultaneous demand. | Add the prefab under **Preloaded Prefab**, raise **Count** to the measured burst size, and profile again. |
| More clones appear on every use. | The completion path never calls `ObjectPool.Destroy`, uses Unity `Destroy`, or creates from a different original/secondary key. | Keep one original prefab reference and one Opsive return path. Verify the object becomes inactive below the pool after each use. |
| A managed object refers to data from its previous owner. | Its fields are not initialized after `Get`, or it does not clear references on `Return`. | Initialize after every `Get` and implement `IPoolable.Reset` to clear references and collections. Never return `null`. |
| Pooling stalls during or after additive-scene unload. | A surviving pool contains an inactive entry that Unity destroyed with another scene. | Keep pool and entries under one scene owner, return active instances before unload, and do not unload the scene that owns the source or inactive entry first. |

## Related pages

- [Programming Concepts](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/)
- [Projectile](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/)
- [Trajectory Object](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/)
- [Explosion](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/)
- [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/)

## API examples

### Reuse an impact effect

Set the Particle System's **Play On Awake** off and **Stop Action** to **Callback**. Keep this component on the prefab root so the object returned is the same root that was checked out.

```csharp
using Opsive.Shared.Game;
using UnityEngine;

public sealed class PooledImpactEffect : MonoBehaviour
{
    [SerializeField] private ParticleSystem m_Particles;

    public void Play()
    {
        m_Particles.Clear(true);
        m_Particles.Play(true);
    }

    private void OnParticleSystemStopped()
    {
        ObjectPool.Destroy(gameObject);
    }
}
```

Check out and initialize the effect at the impact point:

```csharp
using Opsive.Shared.Game;
using UnityEngine;

public sealed class ImpactEffectSpawner : MonoBehaviour
{
    [SerializeField] private PooledImpactEffect m_EffectPrefab;

    public void Spawn(RaycastHit hit)
    {
        var rotation = Quaternion.LookRotation(hit.normal);
        var effect = ObjectPool.Instantiate(
            m_EffectPrefab, hit.point, rotation);
        effect.Play();
    }
}
```

The generic `Component` overload returns the matching component from the checked-out root. The explicit position and rotation overload avoids the parent-only overloads' different transform rules.

### Reuse managed scratch data

`GenericObjectPool.Get<T>()` creates a value with `Activator.CreateInstance<T>()` when its stack is empty, so the type needs a usable parameterless constructor. Return the exact concrete type that was obtained.

```csharp
using System.Collections.Generic;
using Opsive.Shared.Utility;
using UnityEngine;

public sealed class HitScratchData : IPoolable
{
    public Collider Target;
    public readonly List<Vector3> Points = new List<Vector3>();

    public void Reset()
    {
        Target = null;
        Points.Clear();
    }
}

public static class HitCollector
{
    public static void Collect(Collider target, Vector3 point)
    {
        var data = GenericObjectPool.Get<HitScratchData>();
        try {
            data.Target = target;
            data.Points.Add(point);
            // Consume the data during this checkout.
        } finally {
            GenericObjectPool.Return(data);
        }
    }
}
```

The primary Version 3 GameObject overloads are `ObjectPool.Instantiate(GameObject, Vector3, Quaternion, Transform)`, `ObjectPool.Instantiate<T>(T, Vector3, Quaternion, Transform)` for a `Component`, and `ObjectPool.Destroy(GameObject)`. `Destroy(UnityEngine.Object)` accepts a `Component` and returns its GameObject; it is not a managed-object return API. Its delayed overload schedules that same component-only path, so do not pass a `GameObject` to `Destroy(UnityEngine.Object, float)`. Use a stored [Scheduler](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/scheduler/) handle that eventually calls the `GameObject` overload when delayed return must be cancellable. `InstantiatedWithPool` and `GetOriginalObject` inspect only an instance that is currently checked out, not one that has already been returned.

---

<a id="page-ultimate-character-controller-artificial-intelligence"></a>

# Artificial Intelligence (AI)

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)

Ultimate Character Controller supplies the character movement, animation, items, health, and abilities that an AI can control. It does not choose when to patrol, chase, attack, or retreat; connect a behavior tree, state machine, or your own decision system for those choices.

## Choose an AI workflow

| Scenario | Character setup | Decision and movement source |
| --- | --- | --- |
| A guard patrols, detects a target, and chases it | **AI Agent**, **NavMeshAgent**, Animator, and the abilities used by the guard | A behavior system chooses destinations and actions; NavMeshAgent Movement follows the baked NavMesh. |
| A stationary turret aims and fires | **AI Agent**, Items, and a Local Look Source; no navigation is required | The behavior system assigns a target and starts the Aim and Use abilities. |
| A companion repeatedly follows a moving target | **AI Agent** and the selected pathfinding integration | The behavior system refreshes the destination until it is within the chosen follow distance. |
| An agent uses the A* Pathfinding Project | **AI Agent**, but not the Unity **NavMeshAgent** option | Install the integration and use its Astar AI Agent Movement ability. |
| A custom navigation solution drives the character | **AI Agent** and a custom Pathfinding Movement ability | The custom ability converts the navigation result into UCC input and rotation. |

Use one system for decisions and one integration for movement. Avoid letting a pathfinding component and Ultimate Character Locomotion both move the Transform.

## Build an AI-ready character

1. Place the character model in the scene. Character Manager updates scene objects rather than editing a prefab asset directly.
2. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
3. Assign the model to **Character**, choose **Perspective**, and select **First Person Movement** and/or **Third Person Movement** for that perspective. Enable **Animator** and assign a compatible **Animator Controller** when the model should animate.
4. Enable **AI Agent**. This adds **Local Look Source** and removes **Ultimate Character Locomotion Handler**, **Item Handler**, and the Unity input component.
5. Enable **NavMeshAgent** only when this character will use Unity navigation. Character Manager adds **NavMeshAgent Movement** and its required Unity **NavMeshAgent** component.
6. Enable **Standard Abilities**, **Items**, and **Health** only when the AI scenario needs them. Assign the required item collection and item-set rule when Items is enabled.
7. Select **Build Character** for a new character or **Update Character** for an existing UCC character.
8. Inspect the result. An AI character should have **Local Look Source** and should not retain player-input handlers. A Unity-navigation character should also have **NavMeshAgent Movement** in its ability list.

The **AI Agent** option prepares the character for external control; it does not add sensing, decisions, targets, patrol points, or attack logic.

## Connect the behavior system

Choose a controlling system that can issue small, explicit commands to the character:

- For Behavior Designer, install the character-controller integration and follow the [Opsive Character Controllers integration](https://opsive.com/support/documentation/behavior-designer/integrations/opsive-character-controllers/). Its tasks can coordinate navigation and UCC abilities from a behavior tree.
- For a stationary or aiming agent, set **Look Transform** on **Local Look Source** to the head or desired origin, then assign **Target** when the AI acquires something to look at. The target changes the look direction; the behavior system must still decide when to Aim or Use an item.
- For a custom decision system, use the public movement and ability APIs in the developer section instead of simulating keyboard input or moving the character Transform.

Keep decisions separate from character mechanics. For example, a chase state should select the target and destination, while NavMeshAgent Movement, Ultimate Character Locomotion, and the Animator handle the path, collision, and visible movement.

## Configure Unity navigation

1. Build a NavMesh that contains the agent's starting position and every intended destination.
2. Select the character and expand **Abilities** in **Ultimate Character Locomotion**.
3. Select **NavMeshAgent Movement** and configure **Auto Enable**, **Rotation Override**, **Arrived Distance**, **Allow Movement In Air**, and any off-mesh link choices.
4. Have the behavior system assign a reachable destination.
5. Use **HasArrived** or the behavior system's equivalent condition before advancing to the next patrol point or action.

The Unity NavMeshAgent calculates the path, but Ultimate Character Locomotion performs the character movement. NavMeshAgent Movement disables direct NavMesh position updates, converts desired velocity into UCC input, and keeps the agent synchronized with the resulting character position. See [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/) for rotation, arrival, speed, and off-mesh link choices.

## Design common scenarios

### Patrol and chase

Store patrol destinations in the behavior system. Send the current point to NavMeshAgent Movement, wait for arrival, and then choose the next point. When the character detects a target, replace the patrol destination with the target's current or predicted position. Decide how often to refresh a moving destination so the agent responds without recalculating unnecessarily every frame.

### Aim and attack

Assign the detected target to **Local Look Source > Target**, then start Aim and Use only while the behavior permits an attack. Configure Items in Character Manager and verify that the required item is equipped before starting Use. Stop the abilities or clear the target when the behavior exits the attack state.

### Investigate and return

Keep the last known position separate from the current target. Navigate to that position, perform the investigation behavior for a limited time, then return to patrol when the target is not reacquired. UCC performs the movement and abilities; the decision system owns the timer and state transition.

### Use another pathfinder

Do not enable Character Manager's **NavMeshAgent** option when the character will use a different navigation system. For the A* Pathfinding Project, follow the [A* Pathfinding Project integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/astar-pathfinding-project/). For another system, implement a Pathfinding Movement ability that exposes its desired input, rotation, destination, arrival, and teleport behavior.

## Verify in Play Mode

1. Start the scene without providing player input. Keyboard or controller input should not move the AI character.
2. Assign a reachable destination. Confirm the pathfinding movement ability becomes active, a valid path is created, and the character follows it using its UCC movement and animation.
3. Confirm the character stops within **Arrived Distance** and the controlling behavior advances only after arrival.
4. Change the target while the character moves. Navigation and facing should update from the intended systems without the character snapping or rotating between two competing owners.
5. For an armed agent, assign the Local Look Source target, equip the intended item, and start Aim and Use. The item should act in the same direction the AI presents visually.
6. Apply damage and trigger death or respawn if the character supports them. The behavior should react, and navigation should resume from the new character position rather than the previous agent position.
7. Test every required off-mesh link, movement speed, and target-loss transition before duplicating the agent.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Keyboard or controller input still moves the AI. | The character may still have **Ultimate Character Locomotion Handler**, **Item Handler**, or a Unity input component. | Enable **AI Agent** in Character Manager and select **Update Character**. Confirm the player-input components were removed. |
| The AI has no look direction or attacks forward instead of at its target. | **Local Look Source** may be missing, its **Look Transform** may be unsuitable, or **Target** may be empty. | Update the AI Agent setup, assign the look origin, and set the target before starting Aim or Use. |
| Setting a Unity NavMesh destination fails. | The ability may be disabled without **Auto Enable**, or the agent may not be on a baked NavMesh. | Enable the ability or **Auto Enable**, then place the character on a valid NavMesh and retry a reachable destination. |
| A path exists but the character does not move. | The path may still be pending, the NavMeshAgent may be stopped, the destination may already be inside **Arrived Distance**, or movement animation may not provide the expected root motion. | Inspect the path and active ability, test a farther destination, and verify the Movement Type and Animator setup. |
| The character slides, jitters, or separates from its NavMeshAgent. | Another component may be updating the Transform or NavMeshAgent position directly. | Let NavMeshAgent Movement synchronize the agent and let Ultimate Character Locomotion move the character. Remove the competing Transform update. |
| The item is equipped but does not attack. | The Items setup, Local Look Source, Use ability, or the behavior's manual start and stop commands may be incomplete. | Verify item support and the active item set, assign the look target, then start and stop the correct Use ability deliberately. |
| The agent will not cross a jump link. | Jump or Fall may be absent, or the link area may not match **Manual Off Mesh Link Name**. | Add the required abilities and match the NavMesh link and NavMeshAgent Movement settings. |
| Many AI characters are expensive. | Animator, inverse kinematics, collision detection, items, and decision updates may all contribute. | Profile before changing behavior, then disable unneeded features on the AI setup and reduce update frequency or visual detail for distant agents. |

## Related tasks

- [Create or update a character](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Configure NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)
- [Understand abilities and update order](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Configure the Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Equip an item set](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/item-set/equip-unequip/)
- [Configure Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Listen for UCC events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Configure the Animator](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/)

## Developer integration

### Send a Unity NavMesh destination

Retrieve the built-in NavMeshAgent Movement ability and call `SetDestination`. The call returns `false` when the disabled ability cannot auto-enable, the agent is not on a NavMesh, or Unity rejects the destination.

```csharp
using UnityEngine;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities.AI;

public class AIDestination : MonoBehaviour
{
    [SerializeField] private GameObject m_Character;
    [SerializeField] private Transform m_Destination;

    public bool MoveToDestination()
    {
        var locomotion = m_Character.GetComponent<UltimateCharacterLocomotion>();
        var movement = locomotion.GetAbility<NavMeshAgentMovement>();
        return movement != null && movement.SetDestination(m_Destination.position);
    }
}
```

The current movement surface also provides `GetDestination()`, `HasArrived`, `SetDestinationRotation(Quaternion)`, and `Teleport(Vector3)`.

### Integrate another pathfinder

Derive the movement ability from `PathfindingMovement`. Supply `InputVector`, `DeltaRotation`, `HasArrived`, `SetDestination`, `GetDestination`, and `Teleport`; override `SetDestinationRotation` when the pathfinder supports a final facing direction. The base ability is concurrent, can suppress input in the air, writes the result to Ultimate Character Locomotion, and applies an active Speed Change multiplier.

### Control abilities, items, damage, and impacts

- Retrieve an ability with `UltimateCharacterLocomotion.GetAbility<T>()`, then use `TryStartAbility` and `TryStopAbility`. AI characters do not have an input handler to start these actions for them.
- Start a specific item-set change with `EquipUnequip.StartEquipUnequip(itemSetIndex)`. The index belongs to that Item Set Group, so do not assume the same index across different groups.
- Apply simple damage with `Health.Damage(float)`, or use a richer overload when the behavior needs an impact point, direction, force, attacker, or collider.
- Listen for `OnObjectImpact` with `EventHandler.RegisterEvent<ImpactCallbackContext>` when the configured impact action invokes that event. Unregister the same callback when the receiving component is destroyed.

---

<a id="page-ultimate-character-controller-integrations"></a>

# Integrations

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)


Integrations connect Ultimate Character Controller to input, camera, pathfinding, audio, vehicle, quest, inventory, and other Unity systems.

## Install an integration

Download the matching Version 3 bridge from [Opsive Downloads](https://opsive.com/downloads/), then import it after the third-party asset. Bridges are separate downloads and appear in the project only after import. Partner-maintained and legacy exceptions are identified on their integration pages.

Open **Tools > Opsive > Ultimate Character Controller > Integrations Manager** to review an installed entry and any version notice.

## Available integrations

| Integration | What it adds or changes |
| --- | --- |
| [A* Pathfinding Project](https://opsive.com/support/documentation/ultimate-character-controller/integrations/astar-pathfinding-project/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/behavior-ai/a-pathfinding-project-pro-87744?aid=1100lGdc) | AI movement that follows paths produced by an A* agent. |
| [Adventure Creator](https://opsive.com/support/documentation/ultimate-character-controller/integrations/adventure-creator/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/game-toolkits/adventure-creator-11896?aid=1100lGdc) | Adventure Creator character, motion, item, and interaction handoffs through its provider-maintained bridge. |
| [Atlas](https://opsive.com/support/documentation/ultimate-character-controller/integrations/atlas/)<br>[Atlas page](https://opsive.com/atlas/) | Ask, plan, generate, correct, review, and apply validated ability source inside Unity. |
| [Behavior Designer Pro](https://opsive.com/support/documentation/ultimate-character-controller/integrations/behavior-designer/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/visual-scripting/behavior-designer-pro-dots-powered-behavior-trees-298743?aid=1100lGdc) | Behavior-tree tasks for abilities, effects, items, health, attributes, aim, State System state, and events. |
| [Cinemachine](https://opsive.com/support/documentation/ultimate-character-controller/integrations/cinemachine/)<br>[Package documentation](https://docs.unity3d.com/Packages/com.unity.cinemachine@latest) | Cinemachine-backed first-person and third-person View Types. |
| [Control Freak](https://opsive.com/support/documentation/ultimate-character-controller/integrations/control-freak/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/input-management/control-freak-2-touch-input-made-easy-11562?aid=1100lGdc) | A Control Freak player-input provider and touch-control rig workflow. |
| [DestroyIt](https://opsive.com/support/documentation/ultimate-character-controller/integrations/destroyit/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/physics/destroyit-destruction-system-18811?aid=1100lGdc) | A legacy compatibility note for existing owners; no current bridge is supplied. |
| [Dialogue System](https://opsive.com/support/documentation/ultimate-character-controller/integrations/dialogue-system/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/behavior-ai/dialogue-system-for-unity-11672?aid=1100lGdc) | Pixel Crushers dialogue, quest, saver, and interaction handoffs. |
| [Easy Build System](https://opsive.com/support/documentation/ultimate-character-controller/integrations/easy-build-system/)<br>[Asset Store](https://assetstore.unity.com/packages/slug/45394?aid=1100lGdc) | A Building Ability that participates in the normal ability lifecycle. |
| [Easy Touch](https://opsive.com/support/documentation/ultimate-character-controller/integrations/easy-touch/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/input-management/easy-touch-5-touchscreen-virtual-controls-3322?aid=1100lGdc) | A legacy input-replacement workflow for a deprecated asset. |
| [Edy's Vehicle Physics](https://opsive.com/support/documentation/ultimate-character-controller/integrations/edys-vehicle-physics/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/physics/edy-s-vehicle-physics-403?aid=1100lGdc) | An EVP Drive Source for the Drive ability. |
| [Feel](https://opsive.com/support/documentation/ultimate-character-controller/integrations/feel/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/particles-effects/feel-183370?aid=1100lGdc) | Feedback modules for character Effects and modular item actions. |
| [Final IK](https://opsive.com/support/documentation/ultimate-character-controller/integrations/final-ik/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/animation/final-ik-14290?aid=1100lGdc) | A Final IK Bridge and selected RootMotion IK components. |
| [FMOD](https://opsive.com/support/documentation/ultimate-character-controller/integrations/fmod/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/audio/fmod-for-unity-2-03-311497?aid=1100lGdc) | An FMOD Audio Manager module that preserves Audio Config workflows. |
| [FPS Mesh Tool](https://opsive.com/support/documentation/ultimate-character-controller/integrations/fps-mesh-tool/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/modeling/fps-mesh-tool-28006?aid=1100lGdc) | A first-person-compatible mesh preparation workflow. |
| [High Definition Render Pipeline](https://opsive.com/support/documentation/ultimate-character-controller/integrations/high-definition-render-pipeline/)<br>[Package documentation](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest) | Overlay Pass, material, shadow, and Object Fader support. |
| [Horse Animset Pro](https://opsive.com/support/documentation/ultimate-character-controller/integrations/horse-animset-pro/)<br>[Asset Store](https://assetstore.unity.com/packages/3d/characters/animals/horse-animset-pro-riding-system-79902?aid=1100lGdc) | A Malbers-maintained riding and camera handoff. |
| [InControl](https://opsive.com/support/documentation/ultimate-character-controller/integrations/incontrol/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/input-management/incontrol-14695?aid=1100lGdc) | An InControl player-input provider. |
| [Input System](https://opsive.com/support/documentation/ultimate-character-controller/integrations/input-system/)<br>[Package documentation](https://docs.unity3d.com/Packages/com.unity.inputsystem@latest) | A legacy child page; use the current [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) workflow. |
| [Juicy Actions](https://opsive.com/support/documentation/ultimate-character-controller/integrations/juicy-actions/)<br>[Asset Store](https://assetstore.unity.com/packages/slug/269711?aid=1100lGdc) | Character Actions, event triggers, Blackboard helpers, Conditions, and extension points. |
| [Love/Hate](https://opsive.com/support/documentation/ultimate-character-controller/integrations/love-hate/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/ai/love-hate-33063?aid=1100lGdc) | A Pixel Crushers combat-deed compatibility route. |
| [Master Audio](https://opsive.com/support/documentation/ultimate-character-controller/integrations/master-audio/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/audio/master-audio-2022-aaa-sound-212962?aid=1100lGdc) | Master Audio Sound Groups and Variations for character audio. |
| [NWH Vehicle Physics](https://opsive.com/support/documentation/ultimate-character-controller/integrations/nwh-vehicle-physics/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/physics/nwh-vehicle-physics-2-166252?aid=1100lGdc) | An NWH Drive Source and camera handoff. |
| [Omni Animation Packs](https://opsive.com/support/documentation/ultimate-character-controller/integrations/omni-animation-packs/) | [Core Locomotion](https://assetstore.unity.com/packages/3d/animations/omni-animation-core-locomotion-pack-286945?aid=1100lGdc), [Knife](https://assetstore.unity.com/packages/3d/animations/omni-animation-knife-pack-277864?aid=1100lGdc), or [Pistol](https://assetstore.unity.com/packages/3d/animations/omni-animation-pistol-pack-276060?aid=1100lGdc). Animation Replacer templates rather than a runtime bridge. |
| [PlayMaker](https://opsive.com/support/documentation/ultimate-character-controller/integrations/playmaker/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/visual-scripting/playmaker-368?aid=1100lGdc) | PlayMaker 1 actions for supported character operations. |
| [PuppetMaster](https://opsive.com/support/documentation/ultimate-character-controller/integrations/puppetmaster/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/physics/puppetmaster-48977?aid=1100lGdc) | A historical physical-animation bridge with a pinned compatibility boundary. |
| [Quest Machine](https://opsive.com/support/documentation/ultimate-character-controller/integrations/quest-machine/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/game-toolkits/quest-machine-39834?aid=1100lGdc) | Pixel Crushers quest, interaction, inventory, and attribute handoffs. |
| [RayFire](https://opsive.com/support/documentation/ultimate-character-controller/integrations/rayfire/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/game-toolkits/rayfire-2-342492?aid=1100lGdc) | A legacy-bridge evaluation route for destructible objects. |
| [Realistic Car Controller](https://opsive.com/support/documentation/ultimate-character-controller/integrations/realistic-car-controller/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/physics/realistic-car-controller-16296?aid=1100lGdc) | An RCC Drive Source with a version-specific compile boundary. |
| [Realistic Car Controller Pro](https://opsive.com/support/documentation/ultimate-character-controller/integrations/realistic-car-controller-pro/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/physics/realistic-car-controller-pro-178967?aid=1100lGdc) | An RCC Pro Drive Source with a version-specific compile boundary. |
| [Rewired](https://opsive.com/support/documentation/ultimate-character-controller/integrations/rewired/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/utilities/rewired-21676?aid=1100lGdc) | A Rewired player-input provider and player assignment. |
| [State Designer](https://opsive.com/support/documentation/ultimate-character-controller/integrations/state-designer/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/visual-scripting/state-designer-dots-powered-finite-state-machines-369152?aid=1100lGdc) | State Actions and Conditions for supported character operations. |
| [Ultimate Inventory System](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/game-toolkits/ultimate-inventory-system-166053?aid=1100lGdc) | Inventory, item-definition, item-collection, item-set, interface, and save integration. |
| [UMA](https://opsive.com/support/documentation/ultimate-character-controller/integrations/uma/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/uma-2-unity-multipurpose-avatar-35611?aid=1100lGdc) | Editor-built or runtime-generated avatar construction. |
| [Universal Render Pipeline](https://opsive.com/support/documentation/ultimate-character-controller/integrations/universal-render-pipeline/)<br>[Package documentation](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@latest) | Overlay rendering, camera, material, post-processing, and build support. |

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The integration is not listed under **Integration Inspectors**. | The integration may not implement a custom inspector, or compilation may have failed. | Check **Available Integrations**, the expected bridge component, and the Console. Do not use the inspector tab alone as the installation test. |
| One input controls two characters or an action fires twice. | More than one input implementation is active, or two Player Input Proxies reference the same provider. | Give each player one provider and point each **Player Input Proxy** to its own component. Remove the competing input route from the test. |
| A vehicle can be entered but does not move. | The vehicle's own setup, matching Drive Source, or Drive ability references are incomplete. | Verify the vehicle without Ultimate Character Controller, add the exact Drive Source named by its page, then repeat the Drive ability setup. |
| First-person objects clip or render pink in URP or HDRP. | The active render pipeline and imported Ultimate Character Controller support package do not match, or **Overlay Render Type** is not configured. | Import the matching support package from **Setup Manager > Project**, complete its overlay setup, and select **Render Pipeline** on the first-person View Type. |

## Related pages

- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/)
- [Drive](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/)
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)

## Developer reference

The Version 3 Integrations Manager discovers loaded `IntegrationInspector` implementations separately from its online **Available Integrations** list. A downloaded bridge is not required to provide a custom inspector.

Prefer the extension point owned by the subsystem instead of calling a third-party singleton throughout gameplay code. Current integrations demonstrate the intended boundaries: input providers implement `Opsive.Shared.Input.IPlayerInput` and are assigned through `PlayerInputProxy`; vehicle adapters implement `IDriveSource`; external cameras use Ultimate Character Controller View Types; audio backends use an Audio Manager module; and item, effect, ability, or behavior integrations add modules and abilities at the existing Ultimate Character Controller extension points.

---

<a id="page-ultimate-character-controller-integrations-astar-pathfinding-project"></a>

# A* Pathfinding Project

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/astar-pathfinding-project/)


Use the [A* Pathfinding Project](https://assetstore.unity.com/packages/tools/behavior-ai/a-pathfinding-project-pro-87744?aid=1100lGdc) integration when an AI character should follow an A* graph while Ultimate Character Controller remains responsible for collision, animation, abilities, and final character movement.

## Before you begin

- Install Ultimate Character Controller Version 3 and the A* Pathfinding Project version supported by the integration package.
- Download the Ultimate Character Controller A* integration from the [Opsive downloads page](https://opsive.com/downloads/). The bridge is distributed separately so it can compile against A* without adding that dependency to Ultimate Character Controller.
- Start with an A* graph that scans successfully and includes both the character's starting point and its intended destinations. The official [A* get started guide](https://arongranberg.com/astar/documentation/stable/getstarted.html) covers **AstarPath**, graphs, movement scripts, and scanning.
- Read the integration package's included documentation before choosing an A* movement component. A* adds and changes movement implementations independently of Ultimate Character Controller, so a newer component name does not by itself establish bridge support.

Import A* before the integration. If either product is upgraded later, confirm that the bridge release supports the new version before replacing it in a working project.

## Connect an A* agent to Ultimate Character Controller

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**.
2. Assign the character model and enable **AI Agent**. Leave **NavMeshAgent** disabled because that option installs Unity's navigation components and **NavMeshAgent Movement** instead.
3. Choose the required perspective, Animator, standard abilities, items, and health for the agent, then select **Build Character** or **Update Character**.
4. Add the A* movement component required by the downloaded integration release. Current A* versions include components such as **AIPath**, **RichAI**, **AILerp**, and **FollowerEntity**, but do not substitute one unless the bridge documentation explicitly lists it.
5. Add any A* companion component required by that movement implementation. For example, **AIPath**, **RichAI**, and **AILerp** use a **Seeker**; **FollowerEntity** has different requirements.
6. Add one **AstarPath** component to the scene through **Component > Pathfinding > AstarPath**, configure its graph, and select **Scan**.
7. On the character's **Ultimate Character Locomotion** component, expand **Abilities**, select the plus button, and add **Astar AI Agent Movement**.
8. Keep only one pathfinding movement ability on the character. **Astar AI Agent Movement** is concurrent, so it does not need a priority position merely to remain active with other abilities. If the character uses **Speed Change**, keep Speed Change above the pathfinding ability so the generated input is not scaled twice by update order.
9. Supply a reachable destination through the supported A* movement component or through the behavior system that controls the agent.

The **AI Agent** option removes player-input ownership and adds a **Local Look Source**. It prepares the character for external decisions but does not add patrol points, sensing, target selection, or attack logic.

## How movement is shared

A behavior tree, state machine, or gameplay script chooses the destination. A* calculates the path and steering needed to follow it. **Astar AI Agent Movement** converts that result into the input vector and rotation expected by **Ultimate Character Locomotion**. Ultimate Character Controller then moves the character, resolves collisions, and drives its movement animation.

Do not let an A* movement script and Ultimate Character Controller both apply final position or rotation to the Transform. Use the movement settings supplied with the integration release; fields such as A*'s **Update Position** and **Update Rotation** have changed across A* versions. A competing Transform writer usually produces sliding, jitter, or separation between the graph agent and visible character.

## Set a destination

Choose one owner for destination updates:

- For a fixed patrol point, set the A* movement agent's `destination` and request a path. Calling `SearchPath()` requests the new path immediately; otherwise the agent may wait for its next automatic repath.
- For a moving target, A*'s **AIDestinationSetter** can copy its **Target** Transform into `IAstarAI.destination` before path searches. Use it only with an A* movement component supported by the bridge release.
- For a behavior system, update the destination when the target changes enough to justify a new path. Recalculating an unchanged path every frame adds work without improving the character movement.

A* path requests are asynchronous. `pathPending` remains true until the result is available, and `remainingDistance` may be infinite when no path exists. Do not treat either state as arrival.

## Decide what arrival means

Current A* movement agents expose two related results:

- `reachedDestination` is the recommended best-effort check for the requested destination. For **AIPath** and **RichAI**, it uses **End Reached Distance** and also considers whether the destination lies above or below the character.
- `reachedEndOfPath` means the agent reached the end of the calculated path. That endpoint can differ from the requested destination when an obstacle makes the destination unreachable.

Ultimate Character Controller's `PathfindingMovement` contract exposes **HasArrived**, and the integration maps the A* result into that property. The exact A* property and tolerance used by that mapping are bridge-version details; check the downloaded source or README before gameplay logic depends on one interpretation. For a patrol, verify both that path calculation has finished and that the arrival result matches whether an unreachable endpoint should count.

## Choose A* or Unity NavMesh

| Use case | Recommended route |
| --- | --- |
| The project already uses A* graphs, tags, penalties, graph updates, or A*-specific movement | Build an Ultimate Character Controller **AI Agent** without **NavMeshAgent**, then use the downloaded **Astar AI Agent Movement** integration. |
| The project only needs Unity navigation | Enable **AI Agent** and **NavMeshAgent** in Character Manager and use Ultimate Character Controller's built-in **NavMeshAgent Movement**. No A* integration is required. |
| The project needs a custom pathfinder | Derive a movement ability from Ultimate Character Controller's `PathfindingMovement` contract and keep the pathfinder from moving the Transform directly. |

Do not install both **Astar AI Agent Movement** and **NavMeshAgent Movement** for the same navigation job. They can issue different movement and rotation values during the same frame.

## Key choices and limitations

- **Graph and movement implementation:** choose these in A* first, then confirm that the integration release supports the selected movement component. The current A* manual listing a component is not a compatibility promise from the Ultimate Character Controller bridge.
- **Root motion:** A* supplies the route, not the final animated displacement. Match Ultimate Character Controller movement animations and Speed Change settings to the speed the character should display.
- **Airborne movement:** **Allow Movement In Air** comes from Ultimate Character Controller's pathfinding base ability. Disable it when a jump, fall, or another airborne ability must own planar input and rotation.
- **Links and special traversal:** Unity **NavMeshAgent Movement** has Ultimate Character Controller-specific off-mesh-link handling, but those settings do not automatically apply to an A* graph link. Confirm both the A* movement component's link support and the bridge release's handoff before relying on jumps or custom traversal.
- **Teleports and respawns:** Ultimate Character Controller pathfinding abilities must keep their navigation agent synchronized after an immediate Transform change. Test these flows because the implementation is bridge-version specific.

## Verify in Play Mode

1. Show the A* graph in the Scene view and confirm the character starts on a walkable node or surface.
2. Assign a destination on the same connected graph. Confirm a path is calculated after any brief `pathPending` period.
3. In **Ultimate Character Locomotion**, confirm **Astar AI Agent Movement** becomes active and the character follows the path around an obstacle.
4. Confirm the visible character, collider, and A* agent remain together. Position and rotation should not be applied twice.
5. Move the destination while running. The path should update at the intended rate without pausing or recalculating continuously when the target is stationary.
6. Test a reachable and an unreachable destination, then confirm the result used by the behavior system matches the intended arrival rule.
7. Trigger Speed Change, an airborne ability, teleport, death, and respawn when the game uses those features. Confirm the A* agent and Ultimate Character Controller character remain synchronized.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The integration produces missing A* types or namespaces | A* may be absent, imported after the bridge, or outside the bridge's supported version range | Import the supported A* release first, then reimport the matching Ultimate Character Controller integration. |
| No path is calculated | **AstarPath** may be missing, the graph may not be scanned, or the endpoints may be outside connected walkable nodes | Add one **AstarPath**, configure and **Scan** the graph, then move both endpoints onto the same connected graph. |
| A path appears but the Ultimate Character Controller character does not move | **Astar AI Agent Movement** may be absent or disabled, or the chosen A* movement component may not be supported by this bridge release | Add and enable the integration ability, then restore the A* component named by the package README or demo. |
| The character jitters, slides, or separates from the A* agent | Both systems may be writing the Transform | Restore the integration's recommended A* movement settings and let Ultimate Character Controller apply final position and rotation. Remove any additional movement script that also moves the character. |
| The behavior reports arrival too early | The path may still be pending, or it may be checking the end of the current path instead of the requested destination | Wait for path calculation, then use the arrival result whose semantics match the scenario. Check **End Reached Distance** when supported by the selected A* agent. |
| The character reaches the closest walkable point but never reaches the requested destination | The destination may be outside the graph or behind an unreachable area | Move or project the destination onto a reachable graph location, or deliberately treat `reachedEndOfPath` as a separate failure result. |
| Keyboard or controller input still moves the AI | The character may still have player-input handlers | Enable **AI Agent** in Character Manager, select **Update Character**, and confirm player-input components are removed. |
| A root-motion character moves at the wrong visible speed | The pathfinder's speed and the selected movement animation do not match | Use Ultimate Character Controller **Speed Change** and suitable movement animations; do not expect the A* speed field alone to retime root motion. |
| A graph link does not trigger a jump or special animation | The A* movement component or bridge may not support that traversal handoff | Use a supported A* link workflow and explicitly connect it to the required Ultimate Character Controller ability or animation. Do not copy Unity NavMesh link settings. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [Create or update a character](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)

## Developer reference

The released Ultimate Character Controller Version 3 `PathfindingMovement` base class defines the handoff expected from any navigation integration:

- `InputVector` and `DeltaRotation` provide the values consumed by **Ultimate Character Locomotion**.
- `SetDestination(Vector3)` and `GetDestination()` manage the navigation target.
- `HasArrived` reports the integration's arrival result.
- `Teleport(Vector3)` synchronizes the navigation agent after an immediate character Transform change.
- `SetDestinationRotation(Quaternion)` optionally supplies final facing.
- `AllowMovementInAir` determines whether path input continues while airborne.

On the A* side, current `IAstarAI` implementations expose `destination`, `SearchPath()`, `pathPending`, `reachedDestination`, `reachedEndOfPath`, `remainingDistance`, and `Teleport()`. The Ultimate Character Controller bridge connects these two contracts, but its concrete class names and mappings can change independently of both products. Compile and test custom code against the integration package installed in the project rather than copying a namespace or field from a different bridge release.

---

<a id="page-ultimate-character-controller-integrations-adventure-creator"></a>

# Adventure Creator

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/adventure-creator/)


Use the [Adventure Creator](https://assetstore.unity.com/packages/tools/game-toolkits/adventure-creator-11896?aid=1100lGdc) integration when Ultimate Character Controller should handle character movement and items while Adventure Creator coordinates cutscenes, cameras, interactions, and its inventory interface.

## Before you begin

- Install Adventure Creator and Ultimate Character Controller Version 3.
- Confirm that the Ultimate Character Controller character and camera work in Play Mode before adding the bridge.
- Download **Integration: UCC** from the official Adventure Creator [downloads page](https://adventurecreator.org/downloads), then import the package. Adventure Creator maintains and distributes this bridge separately from Ultimate Character Controller.
- Keep the Ultimate Character Controller player in the scene. The supplied setup does not support spawning that player through Adventure Creator's Settings Manager.

When upgrading Adventure Creator or Ultimate Character Controller, test the integration in a copy of the project before updating production scenes.

## Try the supplied demo

The package includes a small scene that confirms the two products can communicate before you change your own character.

1. In the Project window, double-click the `AC_UCC_ManagerPackage` asset to assign the demo's Adventure Creator Managers.
2. Open the `AC_UCC_Demo` scene.
3. Enter Play Mode and try its triggers, cutscenes, cameras, and inventory interactions.

Use your own Managers again before returning to a production scene.

## Connect the player

1. Set up the scene with a working Ultimate Character Controller player and Ultimate Character Controller main camera.
2. Select the player and add Adventure Creator's **Player** component.
3. On **Player**, set **Animation engine** to **Mecanim**, then clear every Mecanim parameter text field. Ultimate Character Controller continues to drive the Animator.
4. Add **AC_UCC_Character** to the same GameObject.
5. Drag the character's Ultimate Character Controller **Player Input** component into **Player Input** on **AC_UCC_Character**.
6. On **Ultimate Character Locomotion**, add **AC Motion** to the **Abilities** list and set its **Start Type** to **Manual**.
7. In Adventure Creator's Settings Manager, set **Movement method** to **First Person** or **Direct**.
8. On the Ultimate Character Controller **Camera Controller**, assign the scene player to **Character**.

In normal gameplay, Ultimate Character Controller accepts player input. During an Adventure Creator cutscene or another non-gameplay state, the bridge starts **AC Motion** so the character follows Adventure Creator's target position and rotation.

## Choose how the camera is controlled

### Use the Ultimate Character Controller camera for the whole scene

Add Adventure Creator's **MainCamera** component to the Ultimate Character Controller main camera. This is the simplest setup when no Adventure Creator camera should replace it.

### Switch between Ultimate Character Controller and Adventure Creator cameras

1. Rename the Ultimate Character Controller camera GameObject to `UCC MainCamera`.
2. Remove its **MainCamera** tag and add Adventure Creator's **Basic Camera** component.
3. Create a separate GameObject with a Unity **Camera** and Adventure Creator **MainCamera** component.
4. Remove the **Overlay** layer from that Camera's **Culling Mask**, then tag the GameObject **MainCamera**.
5. In Adventure Creator's Scene Manager, assign `UCC MainCamera` to **Default camera**.
6. If **Movement method** is **First Person**, use a **Camera: Switch** Action in the scene's **OnStart** cutscene to select the starting camera.

On **AC_UCC_Character**, leave **Sync Camera And Cursor Lock** enabled when Adventure Creator should suspend Ultimate Character Controller look input while a cursor, free-aim lock, or camera drag is active. Enable **Control Camera During Cutscenes** only when the player should still be able to look around during a cutscene.

## Synchronize inventory items

Use this setup when an item picked up or equipped through Ultimate Character Controller should also appear or become selected in Adventure Creator's inventory.

1. In Adventure Creator's Inventory Manager, create the corresponding inventory item and note the ID shown to the left of its name.
2. Select the Ultimate Character Controller item prefab and add **AC_UCC_Item**.
3. Enter the Adventure Creator item ID in **Linked AC Item ID**.
4. Repeat the mapping for each item that the two systems should share.

The supplied component synchronizes in one direction: Ultimate Character Controller pickup, equip, unequip, and drop events add, select, clear, or remove the linked Adventure Creator item. Changing the Adventure Creator inventory directly does not create, equip, or drop the Ultimate Character Controller item.

## Run an ActionList from an Ultimate Character Controller interaction

1. Create the Adventure Creator Cutscene or ActionList asset that should run.
2. Add an Ultimate Character Controller **Interactable** to the scene object, then create an empty child GameObject.
3. Add **AC_UCC_Button** to the child.
4. Assign either **Action List On Interact** for a scene ActionList or **Action List Asset On Interact** for an ActionList asset. Assign both only when both lists should run.
5. On the parent **Interactable**, add the **AC_UCC_Button** component to **Targets**.
6. Leave **Is Interactive** enabled while the interaction should be available.

The button accepts interaction only during Adventure Creator gameplay and while its assigned ActionList is not already running.

To use Adventure Creator's **Inventory: Check selected** Action with an equipped Ultimate Character Controller item, first map that item with **AC_UCC_Item**. On the player's **Ultimate Character Locomotion** component, expand **General** and **Allow Equipped Items**, then enable every **Slot** that the Interact ability may keep equipped.

## Verify in Play Mode

1. During normal gameplay, move and look with the usual Ultimate Character Controller input. The character should respond normally.
2. Start an Adventure Creator cutscene that moves the player. Direct Ultimate Character Controller movement should pause and **AC Motion** should follow the Adventure Creator target.
3. End the cutscene. Ultimate Character Controller movement and camera input should return.
4. If the scene switches cameras, confirm that Adventure Creator shows its camera and returns cleanly to `UCC MainCamera`.
5. Pick up, equip, unequip, and drop a mapped Ultimate Character Controller item. Adventure Creator's runtime inventory should add, select, clear, and remove the matching item.
6. Use the Ultimate Character Controller Interact ability on the configured object. The assigned Adventure Creator ActionList should run once.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The player does not move during a cutscene | **AC Motion** is missing or its **Start Type** is not **Manual** | Add **AC Motion** to **Ultimate Character Locomotion** and select **Manual**. |
| Input remains disabled after a cutscene | **Player Input** is unassigned, or the Adventure Creator player is not the active player | Assign the Ultimate Character Controller **Player Input** component on **AC_UCC_Character** and confirm the correct Adventure Creator **Player** is active. |
| The wrong camera renders, or camera switching fails | More than one camera has the **MainCamera** tag, or **Default camera** points to the wrong object | Keep the tag on the separate Adventure Creator MainCamera only and assign `UCC MainCamera` as the Scene Manager's **Default camera**. |
| An Ultimate Character Controller item does not appear in Adventure Creator | **Linked AC Item ID** does not match the ID in the Inventory Manager | Correct the ID on the item's **AC_UCC_Item** component and test a new pickup. |
| The interaction never starts | **AC_UCC_Button** is absent from **Targets**, **Is Interactive** is disabled, or the ActionList is already running | Add the button to **Targets**, enable it, and wait for the existing ActionList to finish. |
| Scene changes produce `MultiSceneChecker` warnings | Adventure Creator and Ultimate Character Controller scene checks run in the wrong order | In Unity's **Script Execution Order**, give `AC.MultiSceneChecker` a higher value than Ultimate Character Controller's checker. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Interact ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/)
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)

## Developer reference

The partner package adds four bridge types:

- `AC_UCC_Character` coordinates Adventure Creator game-state changes with Ultimate Character Controller locomotion, camera input, cursor locking, and the `AC_Motion` ability.
- `AC_Motion` derives from Ultimate Character Controller's `PathfindingMovement` and reads Adventure Creator's target position, target rotation, and running state.
- `AC_UCC_Item` listens to the Ultimate Character Controller `CharacterItem` pickup, equip, unequip, and drop events and updates Adventure Creator's runtime inventory.
- `AC_UCC_Button` implements Ultimate Character Controller's `IInteractableTarget`. It can run a scene ActionList, an ActionList asset, or both, and exposes `IsInteractive` for runtime control.

Because these scripts depend on both products' runtime APIs, keep local changes to the bridge isolated and recheck them whenever either product is upgraded.

---

<a id="page-ultimate-character-controller-integrations-atlas"></a>

# Atlas

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/atlas/)

Atlas is the Opsive assistant for asking Ultimate Character Controller questions, planning an ability, and generating validated Version 3 Ability, Item Ability, Ability Starter, or Ability Stopper source inside Unity. Generated files remain previews until you explicitly apply them.

## Install and connect Atlas

Atlas requires **Ultimate Character Controller 3.3.7 or newer**.

1. Confirm the installed Ultimate Character Controller version is 3.3.7 or newer.
2. Download Atlas from the [Atlas page](https://opsive.com/atlas/) and import it into the released Ultimate Character Controller Version 3 project. Atlas is not available from the Opsive Downloads page.
3. Install the Codex desktop app or standalone Codex CLI on Windows or macOS and sign in with the subscription Atlas should use.
4. Open **Tools > Opsive > Ultimate Character Controller > Atlas**.
5. Select **Sign in**. The one-time browser page checks the current Opsive account for Ultimate Character Controller. Enter the Unity invoice only if the purchase is not already linked.
6. Return to Unity and select **Ultimate Character Controller** as the active Opsive asset.

No Atlas token or Codex credential is copied into Unity. Codex authentication remains on the local machine.

![Atlas docked in Unity while preparing an Ultimate Character Controller ability result.](https://opsive.com/wp-content/uploads/2026/08/ucc-integrations-atlas-ability-editor.webp?v=95c3144efab4)

## Choose the generated type

- **Ability** is a character-wide behavior managed by Ultimate Character Locomotion.
- **Item Ability** coordinates equipped Character Items and their actions through the item-ability lifecycle.
- **Ability Starter** encapsulates a custom rule that requests an ability start.
- **Ability Stopper** encapsulates a custom rule that requests an ability stop.
- **Ask** and **Plan** can explain or design a solution without generating a file. Prefer a built-in ability or existing component when it already provides the complete behavior.

Atlas validates Ultimate Character Controller base classes, field structure, and lifecycle shape, but the project still owns gameplay correctness, animation, networking authority, save behavior, and compatibility with other active abilities.

## Generate a first ability

1. Create a source-control checkpoint and a duplicate test character.
2. Describe one observable responsibility and its start/stop rules. Include whether it is concurrent, whether it needs input, and which active abilities should block or stop it.
3. Ask Atlas to plan first when the behavior requires movement, Animator parameters, items, States, or several files.
4. Review the generated base type, serialized fields, `CanStartAbility`, `AbilityStarted`, update method, `AbilityStopped`, and destruction cleanup.
5. Select **Apply _FileName_.cs**, **Save as...**, **Copy**, or **Discard**. Use **Apply all** only after reviewing every file in a completed package build.
6. Let Unity compile. Send the exact compiler diagnostic through Atlas correction when required.
7. Add the ability to the duplicate character and configure its Start Type, Stop Type, State, Animator index, and other inherited settings through the normal Ultimate Character Controller Inspector.

Atlas does not add the new ability to every prefab automatically. Apply reviewed source first, then use the normal Character Manager or Ultimate Character Locomotion workflow to configure each intended character.

## Understand the visible controls

- **Active Opsive asset** selects Ultimate Character Controller when several supported Opsive products are installed.
- **Model** and **Effort** show the current provider choices.
- **New chat**, tabs, and **All chats** keep unrelated abilities separate.
- **Show work** expands request progress without changing project files.
- **Apply**, **Save as...**, **Copy**, **Discard**, and **Apply all** control generated files.
- **Retry request** and **Resume package build** recover supported interrupted work.
- The **Atlas** menu under **Tools > Opsive > Ultimate Character Controller** contains **Verbose Diagnostics**, which is intended for support investigation.

Atlas sends a bounded relevant API summary and explicitly included project files, not the entire project. Review the current provider and privacy explanation on the [Atlas page](https://opsive.com/atlas/).

## Verify the generated ability

1. Enter Play Mode with the duplicate character and confirm the ability starts only under its documented conditions.
2. Verify position, rotation, Animator parameters, States, camera, items, and input have one intended owner.
3. Start a higher-priority or blocking ability and confirm the new ability obeys the intended concurrency rules.
4. Stop, interrupt, disable, die, respawn, and switch perspective where those flows apply. Confirm callbacks, events, scheduled actions, and temporary States are cleaned up.
5. Test a network-authoritative build separately when the ability changes shared gameplay state; generated local behavior does not create replication automatically.
6. Commit the reviewed source and character configuration normally.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Ultimate Character Controller is unavailable in the asset selector. | Confirm the released Ultimate Character Controller Version 3 package and ability base types compiled. | Resolve the first Console error and reopen Atlas. Do not use a Version 4 development checkout for this documentation. |
| The browser cannot verify Ultimate Character Controller ownership. | Check the signed-in Opsive account and linked Unity invoice. | Use the owning account or enter the matching invoice on the connection page. |
| The ability compiles but never starts. | Check Start Type, input, `CanStartAbility`, ability order, blocking abilities, and required components. | Configure the inherited ability settings and inspect active abilities before changing generated code. |
| The character keeps a State or motion after stopping. | Check every resource acquired in start/update and the matching cleanup in stop/destruction. | Return the reproducible case for correction or repair the reviewed source before using it in a project. |
| The ability fights movement, camera, or an item action. | Check ownership and concurrency. | Let one system own each output and use Ultimate Character Controller's ability coordination methods rather than writing competing Transform or Animator values. |
| The ability works locally but not over the network. | Check authority and integration-specific replication. | Add explicit authoritative execution and synchronization through the chosen networking integration. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Item Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/)
- [Ability Starter](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/ability-starter/)
- [Creating a New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)
- [States](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)

---

<a id="page-ultimate-character-controller-integrations-behavior-designer"></a>

# Behavior Designer Pro

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/behavior-designer/)


Use the [Behavior Designer Pro](https://assetstore.unity.com/packages/tools/visual-scripting/behavior-designer-pro-dots-powered-behavior-trees-298743?aid=1100lGdc) integration when a behavior tree should decide what an AI character does while Ultimate Character Controller handles locomotion, collision, animation, items, health, abilities, and effects.

## Before you begin

- Install Ultimate Character Controller Version 3 and a compatible Behavior Designer Pro release. Ultimate Character Controller 3.2.1 was the first Version 3 release with Behavior Designer Pro support; when either product changes, install the integration version intended for that combination.
- Build or update the character as an **AI Agent** in Character Manager. This prepares the character for external decisions and removes player-input ownership, but does not add sensing or a behavior tree.
- Enable **NavMeshAgent** when the character will use Unity navigation. Enable **Items** and **Health** only when the tree needs the related Ultimate Character Controller tasks.
- Bake a valid NavMesh before testing a moving agent. Behavior Designer chooses the destination, but Ultimate Character Controller's **NavMeshAgent Movement** ability performs the character movement.

## Install and connect the integration

1. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the Behavior Designer Pro integration for Ultimate Character Controller. The bridge is not included in either base product's Integrations folder before this download.
2. Import the downloaded package after both products compile. Importing it creates the integration files in the project; resolve any package or assembly errors before continuing.
3. Open **Tools > Opsive > Ultimate Character Controller > Character Manager**. Assign the character and enable **AI Agent**. Enable **NavMeshAgent** if the tree will use Unity navigation, then select **Build Character** or **Update Character**.
4. Open **Tools > Opsive > Ultimate Character Controller > Integrations Manager** and select **Behavior Designer Pro**.
5. Expand **Agent Setup**, assign the Ultimate Character Controller character to **Character**, and select **Setup Agent**.
6. Inspect the character. Setup adds **Behavior Tree** and **Behavior Tree Agent** and ensures that the character uses the Ultimate Character Controller AI-agent configuration.
7. Open the **Behavior Tree** and create or assign the tree that will control the character.

The **Behavior Tree Agent** component coordinates the tree with Ultimate Character Controller death and respawn. Its **Pause On Death** choice determines whether an active tree is paused or stopped when the character dies. A tree that was active before death starts again after respawn.

## Build a patrol-and-attack scenario

Start with one small behavior whose result is easy to observe:

1. Add a high-priority branch that checks whether the agent has a valid, visible target. Sensing tasks come from Behavior Designer, an add-on, or your own project; they are not supplied by this bridge.
2. In the attack branch, use **Set Aim Target** to assign the target to Ultimate Character Controller's **Local Look Source**.
3. Use **Start Stop Ability** to start the Aim ability, then **Start Stop Use** to use the equipped item. Enable **Wait For Use Complete** when the branch should remain active until the Use ability finishes.
4. Add a chase branch that sends the target position to the selected Behavior Designer movement task. That task supplies the destination; **NavMeshAgent Movement** converts the path into Ultimate Character Controller input and rotation.
5. Add a lower-priority patrol branch for the no-target state.
6. When an attack or chase branch is aborted, deliberately stop any ability that should not remain active and clear the aim target.

This creates a clean ownership chain: the behavior tree chooses patrol, chase, or attack; navigation calculates the route; the integration requests Ultimate Character Controller actions; and Ultimate Character Controller produces the final movement, collision, items, and animation. See [Patrol and chase an enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/) for a nontechnical tree structure.

## Choose the correct integration task

All integration tasks can act on the tree owner or another target GameObject. The selected object must contain the Ultimate Character Controller component required by that task.

### Abilities and effects

| Task | Important fields | Result |
| --- | --- | --- |
| **Start Stop Ability** | **Ability Type**, **Priority Index**, **Start**, **Always Return Success** | Starts or stops the matching Ultimate Character Controller ability. **Priority Index** selects the ability's Index when more than one ability has the same type; `-1` uses the first match. |
| **Is Ability Active** | **Ability Type**, **Priority Index** | Succeeds only while the matching ability is active. |
| **Start Stop Effect** | **Effect Type**, **Start**, **Always Return Success** | Starts or stops the matching Ultimate Character Controller effect. |
| **Is Effect Active** | **Effect Type** | Succeeds only while the matching effect is active. |
| **Start Stop Interact** | **Ability Type**, **Priority Index**, **Start**, **Interactable GameObject** | Assigns the target object's **Interactable** component to an Ultimate Character Controller Interact ability, then starts or stops that ability. |

The **Ability Type** and **Effect Type** controls list types present on the selected Ultimate Character Controller character. Starting can fail when the ability is missing, blocked, or rejected by Ultimate Character Controller's ability rules. Leave **Always Return Success** disabled when the tree should react to that failure.

### Items and aiming

| Task | Important fields | Result |
| --- | --- | --- |
| **Set Aim Target** | **Aim Target** | Assigns or clears **Local Look Source > Target**. It fails if the target character has no Local Look Source. |
| **Start Stop Use** | **Slot ID**, **Action ID**, **Start**, **Wait For Use Complete**, **Always Return Success**, **Aim Target** | Selects the matching Use ability, optionally aims at a target, and starts or stops item use. When waiting, the task returns Running until use completes. |
| **Reload** | **Slot ID**, **Action ID** | Starts the matching Reload ability for an item slot and action. |
| **Start Equip Unequip** | **Category ID**, **Item Set Index** | Starts the Equip Unequip ability for the selected item-set group and index. |
| **Start Item Set Ability** | **Ability Type**, **Category ID** | Starts the matching item-set ability in the chosen item-set category. |
| **Get Item Identifier Amount** | **Item Type**, **Store Result** | Stores the inventory amount for the selected item identifier. It fails if the inventory, item, or output variable is unavailable. |

Use **Slot ID** and **Action ID** when a character has multiple item actions. Do not assume that the first Use or Reload ability controls the intended weapon. Also confirm that the correct item set is equipped before asking the tree to use or reload it.

### Health, attributes, state, and events

| Task | Important fields | Result |
| --- | --- | --- |
| **Damage** | **Amount** | Applies positive damage through the target's Health component. |
| **Heal** | **Amount** | Heals the target through its Health component. |
| **Is Alive** | None | Succeeds while the target's Health component reports that it is alive. |
| **Has Taken Damage** | **Attacker** | Succeeds as a short damage notification and can store the attacking GameObject. It is not a persistent damaged state. |
| **Get Attribute Value** | **Attribute Name**, **Store Result** | Stores the current value of a named Ultimate Character Controller attribute, such as Health. |
| **Set State** | **State Name**, **Activate State** | Activates or deactivates an Ultimate Character Controller state on the target. |
| **Execute Event** | **Event Name** | Sends a named, parameterless Ultimate Character Controller event to the target GameObject. |

Use shared variables for stored results so later tasks can compare the inventory, attribute, or attacker value. **Has Taken Damage** is intended to trigger an immediate reaction; store any information needed after that brief notification.

## Key choices and limitations

- **Decision tasks and UCC tasks are different layers.** The integration supplies Ultimate Character Controller actions and conditions, not sight, hearing, patrol routes, target selection, or general pathfinding tasks.
- **Only one system should move the character.** Let a supported navigation task choose or update the destination, then let an Ultimate Character Controller pathfinding movement ability and Ultimate Character Locomotion apply final motion. Do not also move the Transform.
- **Ultimate Character Controller owns normal character animation.** Start abilities and item actions instead of forcing Animator states for standard locomotion, aiming, reloading, or item use.
- **Task failure is useful.** A start task normally fails when Ultimate Character Controller rejects the request. Use that result to select a fallback branch. Reserve **Always Return Success** for cleanup where rejection is intentionally harmless.
- **Waiting changes branch lifetime.** **Start Stop Use** returns Running while **Wait For Use Complete** is enabled and the Use ability is active. If the task ends during that wait, it stops the active Use ability.
- **Events have no payload in this task.** **Execute Event** sends only **Event Name**. Use another task or custom integration code when the receiver requires arguments.
- **Death handling is component-based.** Keep **Behavior Tree Agent** on the character if the tree should stop or pause on death and resume after respawn.

## Verify in Play Mode

1. Enter Play Mode without pressing movement controls. The AI character should not respond to player input.
2. Watch the Behavior Designer runtime view. The tree should become active and select the expected patrol branch when no target is present.
3. Present a reachable target. Confirm the movement task updates the destination, **NavMeshAgent Movement** becomes active, and the character follows the path using Ultimate Character Controller movement and animation.
4. Enter attack range. Confirm **Local Look Source > Target** points at the intended object, Aim starts, and **Start Stop Use** controls the correct item slot and action.
5. Force an ability to be blocked. The corresponding start task should return Failure unless **Always Return Success** is enabled, and the tree should take its intended fallback.
6. Apply damage. Confirm **Has Taken Damage** triggers the immediate reaction and stores the attacker when configured.
7. Kill and respawn the character. The tree should pause or stop according to **Pause On Death**, then restart only if it was active before death.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The integration tasks are missing or Unity reports missing types | One product may be absent, or the bridge may not match the installed Behavior Designer Pro and Ultimate Character Controller releases | Install both supported product versions first, then reimport the matching integration and allow Unity to recompile. |
| **Setup Agent** is disabled or does nothing | **Character** may be empty or may not contain **Ultimate Character Locomotion** | Build or update the object as an Ultimate Character Controller character, assign that root GameObject in **Agent Setup**, and run **Setup Agent** again. |
| The tree runs but the character never moves | The bridge does not provide a destination task, the NavMesh may be missing, or **NavMeshAgent Movement** may not be installed | Add a supported Behavior Designer movement task, bake the NavMesh, and update the Ultimate Character Controller character with **AI Agent** and **NavMeshAgent** enabled. |
| The character jitters or separates from its navigation agent | A navigation component and Ultimate Character Controller may both be applying Transform movement | Let the behavior system set the destination and let Ultimate Character Controller apply final position and rotation. Remove the competing Transform update. |
| **Start Stop Ability** always fails | The selected **Ability Type** may be absent, **Priority Index** may select no matching Index, or another ability may block it | Add the ability, correct the Index selection, and inspect the active abilities that can block the request. Do not hide the failure until the cause is understood. |
| The agent aims correctly but uses or reloads the wrong item | **Slot ID**, **Action ID**, or the active item set may not match the intended item action | Equip the expected item set and select the exact slot and action used by that item. |
| The agent attacks forward instead of toward its target | **Local Look Source** may be missing, or **Set Aim Target** may not have run before Aim and Use | Update the character as an **AI Agent**, then set the aim target before starting the abilities. |
| A damage reaction is inconsistent when checked later | **Has Taken Damage** is a brief event-driven condition rather than a lasting state | React immediately, or store the attacker and any follow-up state in shared variables. |
| The tree continues through death or does not restart after respawn | **Behavior Tree Agent** may be missing, the tree may not have been active before death, or **Pause On Death** may not match the desired lifecycle | Run **Setup Agent**, choose the intended death behavior, and verify the tree is active before testing death and respawn. |
| Movement works but animation does not match | The Animator, Animator Controller, Movement Type, or root-motion configuration may be incomplete | Repair the Ultimate Character Controller Animator setup and let Ultimate Character Controller drive its parameters instead of forcing Animator states from the tree. |

## Related pages

- [Behavior Designer Pro](https://opsive.com/support/documentation/behavior-designer-pro/)
- [Choose and configure Behavior Designer tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Patrol and chase an enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [Create or update a character](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Configure the Use item ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)

## Developer reference

The integration's Agent Setup calls the Ultimate Character Controller AI-agent builder, then adds the Behavior Designer **Behavior Tree** and the bridge's **Behavior Tree Agent** components. The bridge tasks use Ultimate Character Controller's normal public systems rather than bypassing them:

- Ability and effect tasks call the same start and stop validation used by Ultimate Character Controller gameplay code.
- Use waits by observing the selected Use ability and its usable item actions; ending a waiting task stops that active Use ability.
- Health and attribute tasks resolve the target's **Health**, **Attribute Manager**, and named attribute at runtime.
- **Has Taken Damage** listens for Ultimate Character Controller damage and death events and exposes the attacker only during its short success window.
- **Execute Event** invokes Ultimate Character Controller's named event dispatcher without arguments.
- **Behavior Tree Agent** listens for Ultimate Character Controller death and respawn events to preserve the tree's intended lifecycle.

Create a custom Behavior Designer task when a tree must pass event parameters, select a project-specific item module, expose a longer-lived condition, or coordinate several Ultimate Character Controller calls as one reusable action. Keep the same ownership boundary: the tree decides what should happen, and Ultimate Character Controller performs character mechanics through its supported APIs.

---

<a id="page-ultimate-character-controller-integrations-cinemachine"></a>

# Cinemachine

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/cinemachine/)


Use the Cinemachine integration when Cinemachine should frame and compose the shot while Ultimate Character Controller continues to assign the character, select the gameplay View Type, provide the look direction, and coordinate character and item states.

## Before you begin

- Start with a working Ultimate Character Controller Version 3 character and **Camera Controller**. Verify the ordinary Ultimate Character Controller camera before replacing its active View Type.
- Install Cinemachine 3.1 or later from Unity's Package Manager, not the legacy Asset Store package. The released bridge uses the Cinemachine 3 `Unity.Cinemachine` API and names such as **Cinemachine Camera**, **Orbital Follow**, **Pan Tilt**, and **Rotation Composer**. See Unity's [Cinemachine 3.1 installation guide](https://docs.unity.cn/Packages/com.unity.cinemachine@3.1/manual/InstallationAndUpgrade.html).
- Decide whether the game needs first person, third person, or both. A dual-perspective camera needs a separate Cinemachine Camera and Ultimate Character Controller Cinemachine View Type for each perspective.
- Keep one owner for each job: Cinemachine composes the shot, the Ultimate Character Controller Camera Controller owns the active gameplay View Type, and Ultimate Character Locomotion owns the character.

## Install the integration

1. Open **Window > Package Manager**, install **Cinemachine**, and confirm that its installed version is 3.1 or later.
2. Open **Tools > Opsive > Ultimate Character Controller > Integrations Manager**, select **Available Integrations**, and use the **Integration** action for Cinemachine to obtain the current Ultimate Character Controller Version 3 package.
3. Import the Cinemachine integration package and allow Unity to compile. Keep its scripts in the supplied location unless the project deliberately organizes integrations under a custom assembly definition.
4. Select the camera with **Camera Controller**, expand **View Types**, and confirm that **First Person Cinemachine** and/or **Third Person Cinemachine** is available from the add menu.

Resolve compilation errors before configuring the scene. A missing `Unity.Cinemachine` namespace normally means Cinemachine is absent, is an incompatible major version, or is not referenced by a custom assembly definition that contains the integration scripts.

## Connect a Cinemachine Camera

1. Select the Unity Camera GameObject that contains **Camera Controller**. Add **Cinemachine Brain** to this same GameObject. Creating the first Cinemachine Camera may add the Brain automatically, but the bridge specifically looks for it beside Camera Controller.
2. Select **GameObject > Cinemachine > Cinemachine Camera** to create a separate Cinemachine Camera GameObject.
3. On its **Cinemachine Camera** component, assign the **Tracking Target** and choose the perspective-specific **Position Control** and **Rotation Control** described below.
4. From **Add Extension**, add **Cinemachine Camera Offset**. On the resulting component, set **Apply After** to **Noise**. The bridge uses this extension for its configured camera offset, positional springs, and first-person height adjustment.
5. Return to **Camera Controller > View Types**, use the add control, and select **First Person Cinemachine** or **Third Person Cinemachine**.
6. Select the new View Type and assign the Cinemachine Camera GameObject's **Cinemachine Camera** component to **Cinemachine Camera**.
7. In the **Active** column, select the Cinemachine View Type that should start active.
8. For a camera that can change perspective, repeat the process with a second Cinemachine Camera and the other Cinemachine View Type. Set **First Person View Type**, **Third Person View Type**, and **Can Change Perspectives** on Camera Controller.

Do not assign one Cinemachine Camera to both View Types. The integration changes its priority and activates or deactivates its GameObject when the Ultimate Character Controller View Type changes.

## Configure first person

Use a stable head or eye-level Transform as the tracking target:

1. On **Cinemachine Camera**, set **Tracking Target** to the character's head.
2. Set **Position Control** to **Orbital Follow** and **Rotation Control** to **Pan Tilt**.
3. On **Cinemachine Orbital Follow**, begin with **Target Offset** `(0, 0, 0)`, **Binding Mode** set to **World Space**, **Position Damping** `(0, 0, 0)`, **Orbit Style** set to **Sphere**, and **Radius** `0`.
4. On **Cinemachine Camera Offset**, begin with **Offset** `(0, 0, 0)` and **Apply After** set to **Noise**.
5. On **First Person Cinemachine**, preserve the Ultimate Character Controller first-person **Culling Mask**, **Overlay Render Type**, **First Person Camera**, and **First Person Culling Mask** required by the active render pipeline. Tune **Min Pitch Limit**, **Max Pitch Limit**, and the bob settings for the intended feel.

![First-person Cinemachine Camera tracking the character's head with Orbital Follow radius zero, Pan Tilt rotation, and Camera Offset applied after Noise](https://opsive.com/wp-content/uploads/2018/11/CinemachineFirstPersonCamera-900x1024.png)

The head target establishes the camera position, but the Ultimate Character Controller View Type still supplies gameplay pitch, yaw, look direction, field of view, recoil, and first-person overlay behavior. Test animated head movement carefully; an unstable target can make the view shake even when all damping values are zero.

## Configure third person

Use the character root or another stable character-relative target:

1. On **Cinemachine Camera**, set **Tracking Target** to the character.
2. Set **Position Control** to **Orbital Follow** and **Rotation Control** to **Rotation Composer**.
3. On **Cinemachine Orbital Follow**, begin with **Target Offset** `(0, 0, 0)`, **Binding Mode** set to **World Space**, **Position Damping** `(1, 1, 1)`, **Orbit Style** set to **Sphere**, and **Radius** `4`.
4. On **Cinemachine Rotation Composer**, begin with **Target Offset** `(0, 1.81, 0)` and tune it for the character's actual height and desired framing.
5. On **Cinemachine Camera Offset**, begin with **Offset** `(0, 0, 0)` and **Apply After** set to **Noise**.

![Third-person Cinemachine Camera tracking the character with Orbital Follow radius four, Rotation Composer target offset 1.81, and Camera Offset applied after Noise](https://opsive.com/wp-content/uploads/2018/11/CinemachineThirdPersonCamera-791x1024.png)

These values are a starting composition, not a character-size requirement. Tune the orbit radius, damping, and target offset with the actual model, movement speed, field of view, and gameplay spaces. The integration does not add obstruction avoidance; add and configure Cinemachine's **Deoccluder** or another supported collision extension when walls can enter the shot.

## How camera ownership works

| System | Responsibility |
| --- | --- |
| **Camera Controller** | Attaches the character, receives Ultimate Character Controller look input, selects the active View Type, exposes the gameplay look source, and coordinates zoom, states, and perspective changes. |
| **First Person Cinemachine** or **Third Person Cinemachine** | Connects the active Ultimate Character Controller View Type to one Cinemachine Camera and translates field of view, look direction, offsets, springs, character up, and runtime activation. |
| **Cinemachine Camera** | Tracks the selected target and applies its Position Control, Rotation Control, Noise, and extensions. |
| **Cinemachine Brain** | Chooses the live Cinemachine Camera and applies its result to the Unity Camera. The integration changes the assigned camera's priority when the Ultimate Character Controller View Type activates. |
| **Ultimate Character Locomotion and Perspective Monitor** | Move the character and update first-person or third-person model presentation after the perspective changes. |

At runtime the integration puts Cinemachine Brain into a manual update route coordinated with Ultimate Character Controller's Simulation Manager. It also updates the Brain's world-up override from the character's current up direction, which allows the shot to follow Ultimate Character Controller dynamic gravity instead of assuming global Y is always up.

When Camera Controller changes perspective, it deactivates the outgoing Cinemachine View Type and activates the selected default for the new perspective. **First Person Cinemachine** also updates the first-person overlay camera and culling mask in response to the perspective event. Configure the Ultimate Character Controller [Transition View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/transition/) or the Cinemachine Brain blend deliberately; avoid applying a long blend in both systems until each handoff works on its own.

## Key choices

- **Cinemachine Camera:** this is the required camera assigned to the Ultimate Character Controller View Type. “Virtual Camera” is the Cinemachine 2 name and is not the current field label.
- **Field Of View** and **Field Of View Damping:** Ultimate Character Controller writes the active View Type's field of view into the Cinemachine Camera lens. Camera states such as Aim can therefore change the lens without bypassing Cinemachine.
- **Look Direction Distance:** controls how far forward the gameplay look direction extends.
- **Use Character Look Direction:** enable this when abilities and items should use the character's forward direction. Leave it disabled when the Cinemachine Camera and crosshairs should define the look direction.
- **Camera Offset:** requires **Cinemachine Camera Offset**. The bridge warns when a nonzero offset is requested without that extension.
- **Position Spring**, **Rotation Spring**, and their secondary springs: preserve Ultimate Character Controller camera forces such as recoil and impacts. Add the integration's **Cinemachine Spring Extension** when Cinemachine orientation should receive rotational spring corrections.
- **First-person overlay:** choose the same **Overlay Render Type** and camera-layer setup used by the rest of the Ultimate Character Controller first-person camera workflow. Cinemachine does not replace the render-pipeline overlay configuration.
- **Obstruction and bounds:** use Cinemachine extensions such as **Deoccluder** or **Confiner**. The Cinemachine View Types do not inherit the included Ultimate Character Controller third-person collision fields.
- **Split screen:** each Camera Controller needs its own Cinemachine Brain and Cinemachine Cameras. Assign distinct Cinemachine output channels so one player's Brain does not select another player's shot.
- **Timeline:** Timeline can override Cinemachine's normal priority and activation rules. Do not let Timeline and Ultimate Character Controller compete for the same gameplay Cinemachine Camera; make the ownership handoff explicit and verify the return to gameplay.

## Verify in Play Mode

1. Enter Play Mode and confirm the Console has no missing **Cinemachine Brain** or **Cinemachine Camera** error.
2. Inspect the assigned Cinemachine Camera. It should report **Live**, and the Ultimate Character Controller Cinemachine View Type should be selected as active on Camera Controller.
3. Move horizontal and vertical look input. Confirm the shot responds as intended and the character or item uses the same gameplay look direction.
4. Walk, turn, jump, aim, use an item, and apply a camera force. Framing, field of view, first-person overlays, and spring motion should remain synchronized.
5. For third person, walk behind walls and through narrow spaces. Confirm the configured Cinemachine collision or occlusion extension keeps the target visible without clipping.
6. For both perspectives, switch in both directions while standing, moving, aiming, and holding an item. The correct Cinemachine Camera should become Live, the outgoing one should deactivate, and model visibility should match the perspective.
7. Test a slope or dynamic-gravity surface when the game uses nonstandard up directions. The Brain's world up should follow the Ultimate Character Controller character.
8. Test respawn, teleport, pause, and scene loading. If Timeline or another cinematic camera takes control, confirm the Ultimate Character Controller gameplay View Type becomes Live again afterward.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports that `Unity.Cinemachine` or a Cinemachine type is missing | Cinemachine may be absent, older than 3.1, or excluded from a custom assembly definition that contains the integration scripts | Install Cinemachine 3.1 or later from Package Manager. If the scripts were moved under an assembly definition, add **Unity.Cinemachine** and the required Opsive assemblies to that assembly's references. |
| The Cinemachine View Types are absent from the add menu | The integration may not have imported or may have stopped compiling | Resolve the first Console error, then reimport the Ultimate Character Controller Version 3 Cinemachine integration. |
| Play Mode logs that a Cinemachine Brain must be set up | **Cinemachine Brain** is not on the same GameObject as **Camera Controller** | Move or add Cinemachine Brain to the Unity Camera that owns Camera Controller. |
| Play Mode logs that the Cinemachine Camera must be set | The View Type's **Cinemachine Camera** field is empty | Assign the intended Cinemachine Camera component to that View Type. Use a different camera for each perspective. |
| The camera is present but never becomes Live | Another Cinemachine Camera, output channel, Timeline track, or inactive GameObject may own the Brain | Check the Brain's channel and active camera, stop the competing owner, and let the Ultimate Character Controller View Type activate its assigned camera. |
| Look input moves the shot but items aim in another direction | **Use Character Look Direction**, the crosshairs, View Type, and Movement Type may describe different facing rules | Choose whether character forward or camera/crosshairs should own the look direction, then test the matching Movement Type and item setup. |
| A nonzero Ultimate Character Controller camera offset has no effect | **Cinemachine Camera Offset** may be missing from the assigned camera | Add the extension, set **Apply After** to **Noise**, and retest the View Type's **Camera Offset**. |
| Recoil or camera impacts do not rotate the Cinemachine shot | **Cinemachine Spring Extension** may be absent | Add the integration's spring extension to the assigned Cinemachine Camera and verify the View Type spring values. |
| The third-person camera passes through walls | No Cinemachine obstruction extension is configured | Add **Cinemachine Deoccluder** or another suitable Cinemachine 3 collision workflow and configure its layers and obstacle behavior. |
| Perspective switching flashes, cuts twice, or blends unpredictably | Ultimate Character Controller Transition and the Cinemachine Brain may both be blending, or both View Types may share one Cinemachine Camera | Give each perspective its own camera and establish one blend owner before adding a second layer of transition. |
| First-person arms disappear or render incorrectly | The first-person **Overlay Render Type**, **First Person Camera**, or culling masks may not match the active render pipeline | Restore the Ultimate Character Controller first-person overlay setup and verify it before tuning the Cinemachine composition. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/)
- [First Person View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [Third Person View Type](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/third-person/)
- [Transition](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/transition/)
- [Post Processing](https://opsive.com/support/documentation/ultimate-character-controller/camera/post-processing/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

## Developer reference

The integration supplies `CinemachineViewType`, `FirstPersonCinemachine`, `ThirdPersonCinemachine`, `CinemachineUpdater`, and `CinemachineSpringExtension`.

During initialization, `CinemachineViewType` requires a `CinemachineBrain` on the Camera Controller GameObject and an assigned `CinemachineCamera`. It adds `CinemachineBrainEvents` and `CinemachineUpdater` when needed. The updater sets the Brain to manual updates and invokes it once during the render frame so Cinemachine runs in the intended order with Ultimate Character Controller simulation.

When the View Type activates, the bridge enables Cinemachine Brain, raises its assigned camera above the current live camera's priority, synchronizes field of view, and activates that camera GameObject. When it deactivates, it lowers the priority and deactivates the assigned camera. This lifecycle is why a Cinemachine Camera should belong to one gameplay View Type and why Timeline or another priority controller must hand ownership back explicitly.

The View Type returns either character forward or the Cinemachine Camera's rotation as the gameplay look direction, then incorporates crosshairs and Ultimate Character Controller spring corrections where configured. `FirstPersonCinemachine` additionally listens for Ultimate Character Controller perspective and height-change events to update overlays and vertical offset. Custom extensions should preserve these responsibilities rather than moving the Unity Camera independently of Camera Controller.

---

<a id="page-ultimate-character-controller-integrations-control-freak"></a>

# Control Freak

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/control-freak/)


Use the [Control Freak](https://assetstore.unity.com/packages/tools/input-management/control-freak-2-touch-input-made-easy-11562?aid=1100lGdc) integration when a Control Freak 2 touch rig should provide movement, look, and action input while Ultimate Character Controller continues to run the character, camera, abilities, and items. The integration replaces the character's Unity input provider with **Control Freak Input**; it does not replace **Player Input Proxy** or create separate touch ownership for multiple players.

## Before you begin

- Install and test an Ultimate Character Controller Version 3 character with its existing input before changing providers.
- Install [Control Freak 2](https://assetstore.unity.com/packages/tools/input-management/control-freak-2-touch-input-made-easy-11562?aid=1100lGdc) before importing the Ultimate Character Controller integration. The bridge compiles against the `ControlFreak2` API.
- Use the Ultimate Character Controller Control Freak integration package offered for the installed Ultimate Character Controller Version 3 release. The supplied bridge does not declare a minimum or maximum Control Freak version, so retest the isolated scene after upgrading either product.
- Commit or back up the project. The setup removes the character's current input provider and any Ultimate Character Controller virtual-control UI that would compete with the Control Freak rig.
- Plan one input owner. The supplied bridge reads Control Freak's shared input source and active rig; it does not expose a player or rig assignment for split-screen touch input.

## Install and connect the integration

1. Import Control Freak 2 and allow Unity to compile.
2. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the Control Freak integration. The bridge is not included in the base product's Integrations folder before this download.
3. Import the downloaded package and resolve every Console error. Importing it creates the integration files in the project; confirm that **Control Freak Input** is available from **Add Component** and that `CF2-Opsive-Rig` is present.
4. In the Hierarchy, expand the character and select its `<CharacterName>Input` GameObject, such as `AtlasInput`.

![AtlasInput selected beneath the character with its legacy Unity Input component ready to be replaced](https://opsive.com/wp-content/uploads/2020/08/UnityInputGameObject.webp?v=3efba5fe6ff5)

The image shows the legacy **Unity Input** provider. A character created with Unity's Input System instead has an Opsive **Unity Input System** provider on this object.

5. Remove the current Opsive input provider, either **Unity Input** or **Unity Input System**, and add **Control Freak Input** to the same GameObject. Keep only one enabled Opsive `PlayerInput` implementation. If no other project code uses Unity's separate **Player Input** component, remove that component when replacing the Input System route as well.
6. Select the character root and assign the new component to **Player Input Proxy > Player Input**.
7. Add `CF2-Opsive-Rig` to the scene, or use a project-owned Control Freak rig with equivalent bindings.
8. In the rig, make the axis and button names match the names requested by the Ultimate Character Controller character. The supplied rig includes common mappings such as `Horizontal`, `Vertical`, `Mouse X`, `Mouse Y`, `Jump`, `Fire1`, and `Reload`; add or rename bindings for any custom ability or item input.
9. Remove the Ultimate Character Controller **VirtualControls** UI created by Setup Manager. Those controls target Ultimate Character Controller's Unity Input or Unity Input System providers, not **Control Freak Input**.
10. Save the scene and prefab changes, then test this one character before adding the integration to a larger scene.

## Configure touch-control behavior

| Choice | Use it when |
| --- | --- |
| **Hide All Touch Controls When Not In Gameplay** | Leave this enabled, its default, when menus or interactions should hide the active Control Freak rig after Ultimate Character Controller disables gameplay input. Disable it only when the rig must remain visible and its own switches decide which controls can be used. |
| **Non Gameplay Switch Name** | Keep the default `Non-Gameplay` when the active rig contains a switch with that exact name. The integration turns the switch on while gameplay input is disabled and off when gameplay resumes. Clear the field if the rig does not use this switch. |
| **Horizontal Look Input Name** and **Vertical Look Input Name** | Keep `Mouse X` and `Mouse Y` when the rig uses the supplied look bindings. Otherwise, change both the rig and these fields to the same names. |
| **Look Vector Mode** and **Look Sensitivity** | Start with Ultimate Character Controller's normal smoothed look and tune sensitivity after movement and action buttons work. The bridge reads Control Freak's raw axis values; Ultimate Character Controller then applies the selected look-vector behavior. |

For a custom rig, bind every visible control to the same name used by the corresponding Ultimate Character Controller ability, item action, movement axis, or camera field. Changing a button's label does not change the input name it sends.

## Understand input ownership

Each playable Ultimate Character Controller character still needs its own **Player Input Proxy**, and that proxy must reference the **Control Freak Input** component intended for the character. At runtime the proxy exposes the provider to the character, camera, abilities, and items.

The supplied provider itself reads the static `CF2Input` source and operates `CF2Input.activeRig`. It has no serialized player ID or rig reference. This is a clear single-active-rig handoff, but duplicating the provider and prefab does not create isolated touch players. For local multiplayer, use a project-specific adapter that separates Control Freak input and rig ownership, or choose an input route with explicit player/device assignment before following the [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/) workflow.

When Ultimate Character Controller disables gameplay input for a menu or interaction, **Control Freak Input** first disables the normal Ultimate Character Controller input path and then updates the active rig. Depending on the two fields above, it hides the touch controls and turns on the `Non-Gameplay` switch. Closing the menu must re-enable gameplay input so the rig and character recover together.

## How input reaches the character

1. A Control Freak touch control writes a named button or axis to `CF2Input`.
2. **Control Freak Input** reads that value through Ultimate Character Controller's standard player-input contract.
3. **Player Input Proxy** exposes the provider on the character root.
4. Ultimate Character Controller's character, camera, ability, and item handlers request their configured input names and produce the visible gameplay result.

This boundary lets the rest of the Ultimate Character Controller setup remain unchanged. If movement works but one action does not, inspect the requested input name before changing the character or ability logic.

## Verify in Play Mode

1. Enter Play Mode and confirm the Console has no missing `ControlFreak2` type or unassigned **Player Input** error.
2. Drag the movement controls through their full range. The intended character should move in every direction and return to idle when the touch ends.
3. Drag the look control slowly and quickly. Both look axes should respond with the intended sensitivity and stop when released.
4. Press `Jump`, `Fire1`, `Reload`, and any project-specific action once. Each control should start only the matching ability or item action.
5. Open a menu or interaction that disables Ultimate Character Controller gameplay input. With **Hide All Touch Controls When Not In Gameplay** enabled, gameplay controls should hide; with a configured `Non-Gameplay` switch, the rig's menu controls should enter that switch state.
6. Close the menu. The gameplay controls should return and the character should respond without reloading the scene.
7. Make a development build for the target mobile device and repeat the test with real multitouch, orientation changes, safe-area placement, pausing, death, and respawn.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports that `ControlFreak2` or `CF2Input` is missing. | Control Freak 2 may be absent, may have been imported after the bridge, or may not compile in the current project. | Install and compile Control Freak 2 first, then reimport the matching Ultimate Character Controller Version 3 integration. |
| The character does not respond. | **Player Input Proxy > Player Input** may be empty or may still reference the removed Unity provider. | Assign the character's enabled **Control Freak Input** component and keep only one Opsive input provider active. |
| Movement works but look or an action does not. | The Control Freak binding and the Ultimate Character Controller field or ability may use different names. | Match the names exactly on both sides, including spaces and capitalization. |
| One press triggers twice or two control layouts appear. | A Unity input provider or Ultimate Character Controller **VirtualControls** UI may still be active beside the Control Freak setup. | Remove the competing provider and generated Ultimate Character Controller virtual controls; keep the intended Control Freak rig. |
| Touch controls remain visible over a gameplay-blocking menu. | **Hide All Touch Controls When Not In Gameplay** may be disabled, no active rig may exist, or the menu may not disable Ultimate Character Controller gameplay input. | Enable the field, confirm the rig is active, and make the menu send the normal Ultimate Character Controller gameplay-input disable and enable flow. |
| The wrong controls are available while a menu is open. | **Non Gameplay Switch Name** may not match a switch in the active rig. | Create the matching `Non-Gameplay` switch, correct the field, or clear it when the rig does not use switch-based menu controls. |
| A second local character responds to the same touch controls. | Both providers read the shared `CF2Input` source; the supplied bridge has no per-player assignment. | Do not duplicate the stock bridge as a split-screen ownership solution. Add a project-specific isolated provider or use an input system with player/device assignment. |
| Cursor-position aiming or UI-hover blocking does not work. | The stock bridge returns a zero mouse position and reports that the pointer is not over UI. | Use touch bindings that do not depend on screen-pointer queries, or extend the provider to return the Control Freak pointer and UI state required by the project. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Virtual Controls](https://opsive.com/support/documentation/ultimate-character-controller/input/virtual-controls/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)

## Developer reference

The integration supplies `Opsive.Shared.Input.ControlFreak.ControlFreakInput`, which derives from Ultimate Character Controller's `PlayerInput`. Button requests delegate to `CF2Input.GetButton`, `GetButtonDown`, and `GetButtonUp`. Both ordinary and raw axis requests begin with `CF2Input.GetAxisRaw`; the inherited Ultimate Character Controller look settings then determine whether and how the look vector is smoothed.

`GetMousePosition` returns zero and `IsPointerOverUI` returns `false` in the stock bridge. Movement, named buttons, and named look axes do not depend on those methods, but screen-position View Types, cursor-following crosshairs, point-and-click movement, or abilities that block while the pointer is over UI need a project-specific override.

When Ultimate Character Controller changes gameplay-input state, the provider calls the base implementation and then checks `CF2Input.activeRig`. It can call `ShowOrHideTouchControls` and set the configured non-gameplay switch, but it does not search for or assign a rig. Keep the intended rig active before this lifecycle runs.

---

<a id="page-ultimate-character-controller-integrations-dialogue-system"></a>

# Dialogue System

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/dialogue-system/)


Use the [Dialogue System](https://assetstore.unity.com/packages/tools/behavior-ai/dialogue-system-for-unity-11672?aid=1100lGdc) integration when an Ultimate Character Controller character should start conversations through the normal Interact ability, hand camera and input control to the conversation when needed, and include Ultimate Character Controller character data in Dialogue System saves.

For example, the player can approach an NPC, see an interaction prompt, press the Action input, talk with movement and weapons disabled, and return to gameplay when the conversation ends.

## Before you begin

- Start with a working Ultimate Character Controller Version 3 character. Verify movement, camera, input, and the Interact ability before adding dialogue.
- Install Dialogue System for Unity and create a small conversation that works with its Dialogue Manager.
- Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the current Pixel Crushers bridge. It is not included in the base product's Integrations folder before download. The downloaded package does not declare a semantic minimum or maximum Dialogue System version, so reinstall the matching current bridge after updating either product.
- Back up the project before importing or replacing an integration package.

This workflow describes the supported Ultimate Character Controller Version 3 bridge. It does not apply to the legacy UFPS, UTPS, First Person Controller, or Third Person Controller integrations that appeared on the older version of this page.

## Install the integration

1. Open **Tools > Opsive > Ultimate Character Controller > Integrations Manager**.
2. Find **Dialogue System for Unity**, select **Integration**, and import the package provided for the installed products.
3. Allow Unity to compile. Resolve the first Console error before configuring the scene; the bridge requires both Ultimate Character Controller and Dialogue System assemblies.
4. Add Dialogue System's **Dialogue Manager** prefab from **Plugins > Pixel Crushers > Dialogue System > Prefabs** to the scene, then assign the project's dialogue database and UI using the normal Dialogue System workflow.
5. Confirm that the imported support contains **Converse**, **Dialogue System Trigger Interactable Target**, **UCC Saver**, and the supplied **UCC DS Example** scene.

If the project also uses Ultimate Inventory System, add `UIS` to **Edit > Project Settings > Player > Other Settings > Scripting Define Symbols** after importing the bridge. This enables the integration's Ultimate Inventory System-aware menu and input handling.

## Configure the player

1. Select the player root and open the **Abilities** list on **Ultimate Character Locomotion**.
2. Add the **Converse** ability. Leave **Start Type** and **Stop Type** set to **Manual**; the integration starts and stops this passive ability from Dialogue System conversation events.
3. Leave **Allow Positional Input** and **Allow Rotational Input** disabled so the character cannot move or turn during the conversation.
4. Configure the conversation behavior:
   - **Hide UI** hides Ultimate Character Controller gameplay UI while dialogue is active.
   - **Disable Gameplay Input** sends Ultimate Character Controller's gameplay-input event off at the start and restores it after the conversation.
   - **Detach Camera** temporarily removes the character from the active Ultimate Character Controller Camera Controller so Dialogue System can own the shot.
   The current bridge enables all three choices by default; disable one only when another system deliberately owns that responsibility.
5. Under **Allow Equipped Slots**, disable any slots that must be holstered while talking. For a two-slot character, this normally means disabling **Slot 0** and **Slot 1**.
6. Add or keep the standard Ultimate Character Controller **Interact** ability. Converse does not detect an NPC or start a conversation by itself.
7. In the Interact ability, set **Ability Message Text** to a prompt such as `Talk to {0}`. The integration replaces `{0}` with the target Dialogue Actor's name.

### Choose camera ownership

- Keep **Detach Camera** disabled when the normal Ultimate Character Controller gameplay camera should remain attached throughout the conversation.
- Enable **Detach Camera** when Dialogue System's sequencer should control the shot. Assign a dedicated camera under **Dialogue Manager > Display Settings > Camera & Cutscene Settings > Sequencer Camera** and verify that only one camera owns the conversation view.

The stock **Converse** ability locates the first active Ultimate Character Controller Camera Controller. A split-screen or multi-camera game should use a project-specific bridge that resolves the correct camera for each player rather than relying on this single-camera behavior.

### Configure the conversing input state

1. On the input component used by the player, add a state named `Conversing` that exposes the cursor and blocks the gameplay controls that should not run during dialogue.
2. If the character uses Ultimate Character Controller's **Unity Input** component, apply the imported `ConversingUnityInputPreset` as the starting configuration.
3. If the character uses Unity Input System, Rewired, or another input integration, create the equivalent `Conversing` state on that provider. The supplied preset targets **Unity Input** and should not be assumed to configure every provider.
4. If gamepad dialogue should use a separate state without exposing the cursor, create a second state such as `ConversingDisableCursor` and assign it to **Converse > Conversing State Names > Conversing State Hide Cursor**.

Converse selects the normal or hide-cursor state from Dialogue System's current input-device information. Test both mouse and gamepad instead of assuming that one cursor rule fits every device.

### Coordinate Ultimate Inventory System menus

When Ultimate Inventory System owns menus and cursor state:

1. Add **UCC Menu Utility** and **Dialogue System Events** to the player.
2. Connect **Dialogue System Events > On Conversation Start ()** to **UCC Menu Utility > On Open Menu**.
3. Connect **On Conversation End ()** to **UCC Menu Utility > On Close Menu**.
4. Test the end of a conversation while another Ultimate Inventory System menu is open. The `UIS` scripting symbol allows Converse to avoid restoring gameplay input while Ultimate Inventory System still owns the menu.

## Configure an NPC or conversation object

1. Select the NPC or object that the player should use.
2. Add **Dialogue System Trigger Interactable Target**. Set **Trigger** to **On Use**, then configure its conversation action and actor assignments as you would on a normal Dialogue System trigger.
3. Add Ultimate Character Controller's **Interactable** component to the same detected object and assign **Dialogue System Trigger Interactable Target** in **Targets**.
4. On the player's Interact ability, choose an **Object Detection** mode, **Detect Layers**, and **Cast Distance** that can find the Interactable.
5. Enter Play Mode and use Ultimate Character Controller's ability message to confirm that the intended object is detected before testing the conversation.

Do not add a second ordinary **Dialogue System Trigger** for the same Ultimate Character Controller interaction. **Dialogue System Trigger Interactable Target** already receives Ultimate Character Controller's interaction and invokes its configured **On Use** action.

If the NPC is also an Ultimate Character Controller character, place the **Interactable** on the detected collider object, normally the **Colliders > CapsuleCollider** child. Ultimate Character Controller character roots are commonly tagged `Player` while their collider children are untagged, so a tag-based Dialogue System trigger may miss the collider. The Ultimate Character Controller Interactable route avoids that mismatch.

## Add Ultimate Character Controller data to saved games

Dialogue System saves its own dialogue, quest, and variable data. Add **UCC Saver** to an Ultimate Character Controller character when the same save should also include selected Ultimate Character Controller state:

1. Add **UCC Saver** to the character root.
2. Enable only the categories the game needs: **Save Perspective**, **Save Mouse Settings**, **Save Position**, **Save Attributes**, and **Save Inventory**. The current bridge enables all five by default.
3. Tag the player root `Player` when a Dialogue System scene portal or save-system load should place the player at a spawn point. The integration also uses this tag as its default player lookup.
4. Test a complete save and load after changing every enabled category. **Save Mouse Settings** depends on the active Ultimate Character Controller input route and should be verified rather than assumed.

For runtime pickups that were not present in the starting inventory:

1. Select **Create > Pixel Crushers > Dialogue System > UCC Saver Runtime Pickups**.
2. Add the runtime item identifiers to the asset's **Runtime Items** list.
3. Assign the asset to **UCC Saver > Runtime Pickups**.

To respawn at the most recent save instead of the normal Ultimate Character Controller respawn point, replace **Character Respawner** with **Checkpoint Character Respawner** and set **Checkpoint Save Slot** to the slot used by the game. Its default is slot `1`; when that slot has no saved game, normal Ultimate Character Controller respawning is used.

## How it runs

1. Ultimate Character Controller's Interact ability detects the **Interactable** and calls the assigned **Dialogue System Trigger Interactable Target**.
2. The target invokes its **On Use** conversation action with the interacting character as the user.
3. Dialogue System's conversation events start **Converse** on the actors involved in the conversation. Converse applies its input, UI, equipped-slot, state, and camera choices.
4. Dialogue System runs the conversation and any sequencer commands. Ultimate Character Controller continues to own the character's locomotion and abilities unless the integration deliberately disables or detaches them.
5. When the conversation ends, Converse restores the camera, UI, input, equipped slots, and conversing state. Input restoration is delayed briefly so a newly starting conversation does not cause a one-frame gameplay-input handoff.

## Key choices and limitations

| Choice | Use it when | Important consequence |
| --- | --- | --- |
| Keep the Ultimate Character Controller camera attached | Dialogue uses the normal gameplay view | Leave **Detach Camera** disabled; do not ask a sequencer camera to control the same shot. |
| Let Dialogue System control the shot | A conversation needs cuts or staged framing | Enable **Detach Camera** and configure a dedicated **Sequencer Camera**. |
| Use Ultimate Character Controller interaction | The player should use the normal Action input, detection, prompt, and ability rules | Use **Interactable** plus **Dialogue System Trigger Interactable Target**, not a duplicate ordinary trigger. |
| Save Ultimate Character Controller character state | Dialogue System saves must include position, attributes, inventory, perspective, or mouse settings | Add **UCC Saver** and explicitly test each enabled category. Custom ability state is not included automatically. |
| Use multiple local players or cameras | Each player has separate camera, input, or menu ownership | The stock camera and menu utilities use a global or first-camera lookup; extend them so the correct player owns each conversation. |

The interactable target rejects a non-local network character when Ultimate Character Controller multiplayer support is enabled, but that does not make the rest of the stock bridge split-screen aware. Camera, cursor, menu, and save ownership still need a deliberate per-player design.

## Verify in Play Mode

1. Approach the NPC. The Interact ability message should show the Dialogue Actor name in place of `{0}`.
2. Press the Action input. The configured conversation should start exactly once.
3. Confirm that movement, look, items, gameplay UI, cursor, and camera follow the selected Converse settings.
4. End the conversation. The same player should regain input, UI, equipped items, camera ownership, and the previous cursor behavior.
5. Start another conversation immediately. Input should not flash on between the two conversations.
6. Test with mouse and gamepad. The correct conversing state should activate for each device.
7. If Ultimate Inventory System is installed, end dialogue while an Ultimate Inventory System menu is still open. Gameplay input should remain disabled until the menu closes.
8. Save after changing an enabled attribute, inventory item, perspective, and position; change them again, then load. Only the categories enabled on **UCC Saver** should be restored.
9. Load a scene through the selected Dialogue System save flow and test the configured spawn point or checkpoint slot.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The bridge scripts are missing or Unity reports unresolved Pixel Crushers or Opsive types | One product may be absent, or the imported bridge may not match the installed releases | Install both products first, then obtain and reimport the current bridge through **Integrations Manager**. Resolve the first Console error. |
| The prompt appears but no conversation starts | **Interactable > Targets** may be empty, **Trigger** may not be **On Use**, or the target may have no configured conversation action | Assign **Dialogue System Trigger Interactable Target** in **Targets**, select **On Use**, and configure its action and actors. |
| The prompt never appears | The Interact ability may not detect the correct collider or layer | Inspect **Object Detection**, **Detect Layers**, **Cast Distance**, and the collider that owns **Interactable**. Put it on the detected CapsuleCollider child for an Ultimate Character Controller NPC. |
| The conversation starts twice | An ordinary **Dialogue System Trigger** may be running beside the integration target | Keep one interaction route. Remove or disable the duplicate trigger for the same use action. |
| The player can move, look, or use items during dialogue | Converse may be absent from the participating Ultimate Character Controller character, its restrictions may be disabled, or the allowed equipped-slot mask may still permit the item | Add Converse to the actor, keep its start and stop types Manual, enable the needed UI/input restrictions, and update **Allow Equipped Slots**. |
| Input or the cursor is wrong during dialogue | The active input provider may not have the named conversing state | Apply `ConversingUnityInputPreset` only to **Unity Input**, or create matching `Conversing` and optional hide-cursor states on the actual provider. |
| Gameplay input stays disabled after dialogue | Conversation end may not have fired, Ultimate Inventory System may still own a menu, or two input owners may be restoring state in the wrong order | Confirm **On Conversation End ()**, the `UIS` symbol and menu events, then reduce the setup to one clear menu/input owner and retest. |
| The camera snaps, goes blank, or never returns | **Detach Camera** may be enabled without a working sequencer camera, or two camera systems may be competing | Configure one dedicated **Sequencer Camera**, or disable **Detach Camera** to keep the Ultimate Character Controller camera attached. Test the end event and camera return. |
| A save restores dialogue but not health, inventory, or position | Dialogue System's save exists, but **UCC Saver** or its category is missing | Add **UCC Saver** to the character and enable the exact Ultimate Character Controller categories that should be included. |
| A runtime pickup disappears after loading | Its item identifier may not be in the assigned runtime-pickups asset | Add it to **UCC Saver Runtime Pickups > Runtime Items** and assign that asset to **UCC Saver > Runtime Pickups**. |
| Respawn loads the wrong checkpoint or uses the normal respawn point | **Checkpoint Save Slot** may not match the slot that contains the save | Select the correct slot. Normal respawn is expected when no saved game exists in that slot. |
| The wrong local player or camera is affected | The stock bridge may have resolved the first Camera Controller or the `Player`-tagged object | Give each player an explicit camera, input, menu, and save owner in a project-specific extension. Do not rely on the stock global lookup for split screen. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Interact ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Ultimate Inventory System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/)
- [Respawner](https://opsive.com/support/documentation/ultimate-character-controller/spawn-system/respawner/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Pixel Crushers' Ultimate Character Controller integration manual](https://www.pixelcrushers.com/dialogue_system/manual2x/html/ucc.html)

## Developer reference

The bridge supplies these primary integration points:

- `Converse` listens to Dialogue System conversation events for the Ultimate Character Controller character and applies the configured UI, gameplay-input, camera, item-slot, and state behavior. It is passive and does not initiate a conversation.
- `DialogueSystemTriggerInteractableTarget` implements Ultimate Character Controller's interactable target and message interfaces. It passes the interacting character to its **On Use** action and uses the target's Dialogue Actor name for `{0}` prompts.
- `UCCMenuUtility` sends Ultimate Character Controller's gameplay-input event and changes cursor visibility for Dialogue System or Ultimate Inventory System menu events. The stock component resolves the character from the active Camera Controller.
- `UCCSaver` contributes the selected position, attribute, inventory, perspective, and mouse-setting data to Pixel Crushers' Save System. Dialogue System remains responsible for its own dialogue and quest data.
- `CheckpointCharacterRespawner` loads **Checkpoint Save Slot** on respawn when that slot has a saved game, otherwise it falls back to the ordinary Ultimate Character Controller respawn behavior.

Add **Ultimate Character Controller Lua** to the Dialogue Manager only when dialogue Lua needs Ultimate Character Controller data. It registers `uccGetAttribute`, `uccSetAttribute`, `uccGetItemCount`, `uccAddItem`, `uccRemoveItem`, `uccEquipItem`, `uccUnequipItem`, and `uccNotifyOnEquip`. A blank character name resolves the `Player`-tagged Ultimate Character Controller character; append `.CollectionName` to select a nondefault item collection, such as `Vendor.SpecialStock` or `.Backpack` for the tagged player. The remove function removes items, not ammunition, and equip or unequip calls require **Equip Unequip Item Ability > Auto Equip** to be **NotPreset**.

The bridge also adds the Dialogue System sequencer command `uccLookAt(target, subject, duration, allAxes)`. The target defaults to the listener, the subject defaults to the speaker, duration is optional, and omitting `allAxes` keeps the subject upright. The command temporarily disables the subject's **Ultimate Character Locomotion** while it rotates, so do not overlap it with another system that must move that character during the same sequence.

---

<a id="page-ultimate-character-controller-integrations-easy-build-system"></a>

# Easy Build System

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/easy-build-system/)

Use the [Easy Build System](https://assetstore.unity.com/packages/slug/45394?aid=1100lGdc) integration when an Ultimate Character Controller character should enter and control a building workflow through a character Ability instead of bypassing Ultimate Character Controller input, camera, locomotion, and State coordination.

## Install and add the ability

1. Install and verify Easy Build System without Ultimate Character Controller.
2. Sign in to [Opsive Downloads](https://opsive.com/downloads/), download the Easy Build System integration, and import `UltimateCharacterControllerEasyBuildSystem.unitypackage`. The bridge does not exist in the base product's Integrations folder before this download; importing it creates the integration files in the project.
3. Let Unity compile and confirm the **Building Ability** type is available in the Ultimate Character Locomotion ability list.
4. Add **Building Ability** to the character and configure its inherited Start Type, Stop Type, input, State, and concurrency settings for the intended build mode.
5. Connect the Easy Build System controller expected by the installed integration version.

The released bridge contains one `BuildingAbility` source file. Easy Build System still owns its preview, placement, adjustment, destruction, and save configuration.

## Verify in Play Mode

1. Start the Building Ability and confirm the expected build controller enters its mode.
2. Place and cancel one preview while checking cursor, camera, movement, and item input ownership.
3. Stop or interrupt the Ability and confirm the preview and build mode are cleaned up.
4. Test perspective changes, pause, death, respawn, and scene reload.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Building Ability is missing. | Check Easy Build System, the bridge package, and the first Console error. | Install the dependency first and reimport the released Ultimate Character Controller bridge. |
| Build input and item input both fire. | Check the Ability State and input ownership. | Disable or block the competing item/gameplay input while Building Ability is active. |
| A preview remains after interruption. | Check the bridge and build controller cleanup path. | Stop building through the Ability lifecycle and add project cleanup for the installed version if needed. |

## Related pages

- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Creating a New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/)
- [States](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)

---

<a id="page-ultimate-character-controller-integrations-edys-vehicle-physics"></a>

# Edy's Vehicle Physics

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/edys-vehicle-physics/)


Use the [Edy's Vehicle Physics](https://assetstore.unity.com/packages/tools/physics/edy-s-vehicle-physics-403?aid=1100lGdc) integration when an Ultimate Character Controller character should approach a vehicle, enter its driver position, hand driving and optional camera control to Edy's Vehicle Physics, then return to ordinary character control on exit.

## Before you begin

- Build and test the Ultimate Character Controller Version 3 character, camera, and **Drive** ability without relying on the vehicle to diagnose character setup.
- Build and test the Edy's Vehicle Physics vehicle with **Vehicle Controller** and **Vehicle Standard Input** before connecting Ultimate Character Controller. Follow the [Edy's Vehicle Physics 5 user guide](https://www.edy.es/dev/vehicle-physics/user-guide/) for its wheels, Rigidbody, handling, and control setup.
- The audited integration project contains Edy's Vehicle Physics 5.3. The bridge has no embedded minimum or maximum version check, so confirm the required `EVP.VehicleStandardInput` and `EVP.VehicleCameraController` APIs still exist when using a later 5.x release.
- Decide whether Ultimate Character Controller's Camera Controller or Edy's **Vehicle Camera Controller** should own the Unity Camera while driving.
- Check the input boundary before importing. Edy's supplied **Vehicle Standard Input** reads Unity's legacy `Input.GetAxis` API directly; it does not read the character's Ultimate Character Controller **Player Input Proxy**.

## Install the integration

1. Install [Edy's Vehicle Physics](https://assetstore.unity.com/packages/tools/physics/edy-s-vehicle-physics-403?aid=1100lGdc) and verify one of its vehicles in Play Mode.
2. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the Edy's Vehicle Physics integration. The bridge is not included in the base product's Integrations folder before this download.
3. Import the downloaded Version 3 bridge after the vehicle asset. Importing it creates the integration files in the project.
4. Allow Unity to compile. Resolve the first Console error before adding components; the bridge requires both Ultimate Character Controller and the `EVP` types.
5. Open the imported integration sample and confirm that **EVP Drive Source** is available from Add Component.

Reimport the current bridge after updating Ultimate Character Controller or Edy's Vehicle Physics. A working 5.3 integration scene is useful evidence, but it is not a compatibility guarantee for every later package combination.

## Connect the vehicle

1. Select the vehicle root that contains **Vehicle Controller**.
2. Add or keep **Vehicle Standard Input** on this same GameObject. Assign its **Target** to the Vehicle Controller, or leave it empty so Edy's component finds the Vehicle Controller beside it when enabled.
3. Add **EVP Drive Source** to the same GameObject. The bridge specifically looks for **Vehicle Standard Input** beside itself and cannot enable a component on another object.
4. Create a child Transform named `Driver Location`. Position and rotate it at the character's seated pose, then assign it to **EVP Drive Source > Driver Location**.
5. Set **Animator ID**. Use `0` for a simple vehicle with the default Drive animation set, or use a unique base ID when the Animator contains vehicle-specific Enter, Drive, and Exit states.
6. Add one or more **Move Towards Location** children beside the doors or other safe entry and exit points. Drive requires at least one clear location even when **Teleport Enter Exit** is enabled.
7. Add the collider or trigger that Drive should detect. Put it on a layer included by the ability's **Detect Layers** and keep **EVP Drive Source** on that object or one of its parents.
8. Confirm that every active vehicle collider which should ignore the seated character is below the EVP Drive Source GameObject when the scene starts. The bridge caches those child colliders once during `Start`.

### Configure Edy's driving input

On **Vehicle Standard Input**, choose the control behavior before testing the Ultimate Character Controller handoff:

- **Steer Axis** defaults to `Horizontal`.
- **Throttle And Brake Input** can use **Single Axis** with **Throttle And Brake Axis** `Vertical`, or **Separate Axes** with **Throttle Axis** `Fire2` and **Brake Axis** `Fire3`.
- **Continuous Forward And Reverse** allows the vertical input to brake and then reverse without a separate modifier.
- **Handbrake Axis** defaults to `Jump`. **Handbrake Overrides Throttle** reduces throttle while the handbrake is applied.
- **Reset Vehicle Key** defaults to Return.

These are Unity Input Manager names, not Ultimate Character Controller action names. If the project uses Unity Input System only, either enable the legacy Input Manager compatibility required by Vehicle Standard Input and create these mappings, or adapt the Drive Source to enable a project-owned EVP input component. Do not expect assigning an Ultimate Character Controller **Unity Input System** component to the character to feed Edy's `Input.GetAxis` calls.

## Configure the character

1. Add **Drive** to **Ultimate Character Locomotion > Abilities**. Keep its normal `Action` input unless the project uses another enter and exit control.
2. For an animated approach, add **Move Towards** above Drive in the ability list. Add the exact `OnAnimatorEnteredVehicle` and `OnAnimatorExitedVehicle` events to every reachable entry and exit animation.
3. Enable **Teleport Enter Exit** when the character should move immediately between the selected Move Towards Location and **Driver Location** without entry or exit animation events.
4. Configure the inherited **Object Detection**, **Detect Layers**, and optional **Object ID** so Drive detects the vehicle collider.
5. Choose whether the character may keep items or Aim active with **Allow Equipped Slots** and **Can Aim**. Use **Disable Mesh Renderers** when the seated character body should be hidden.
6. Follow the complete [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/) workflow for exit clearance, collision handling, item restoration, interpolation, and vehicle-specific Animator IDs.

The Ultimate Character Controller `Action` input starts and stops Drive. Edy's Vehicle Standard Input remains disabled until the character has fully entered, then reads its own steering, throttle, brake, handbrake, and reset controls.

## Choose the camera owner

### Keep the Ultimate Character Controller camera

Disable **EVP Drive Source > Use Vehicle Camera Controller** and disable or remove Edy's **Vehicle Camera Controller**. Ultimate Character Controller's Camera Controller then remains active while the character is seated at **Driver Location**.

Use this route when the existing Ultimate Character Controller View Type already gives the desired vehicle framing. The bridge does not automatically switch to a vehicle-specific Ultimate Character Controller View Type, so configure any perspective or state change separately.

### Use Edy's vehicle camera

1. Add **Vehicle Camera Controller** to the same active GameObject as Ultimate Character Controller's **Camera Controller** and **Camera Controller Handler**.
2. Assign **Target** to the vehicle and choose the starting **Mode**: Attach To, Smooth Follow, Mouse Orbit, Look At, or Free.
3. Configure **Follow Center Of Mass**, **Camera Collisions**, **Collision Mask**, and the selected mode's framing. **Change Camera Key** defaults to `C`.
4. Enable **EVP Drive Source > Use Vehicle Camera Controller**. This choice is enabled by default in the audited bridge.
5. Leave the camera GameObject active when the scene starts. EVP Drive Source finds the first Vehicle Camera Controller once during `Start`, disables it while the vehicle is unoccupied, and enables it after entry.

When Edy's camera becomes active, the bridge disables Ultimate Character Controller's Camera Controller and Camera Controller Handler on that Unity Camera. It reverses the handoff as soon as exit begins. The Unity Camera and Audio Listener themselves remain on the same GameObject.

The stock bridge does not change **Vehicle Camera Controller > Target** when a different vehicle is entered. A scene with several drivable vehicles must update the target deliberately or use a project-specific Drive Source. The first scene-wide Vehicle Camera Controller found at startup is the only one the stock source toggles.

## How it runs

1. At scene start, **EVP Drive Source** caches its GameObject, Transform, and active child colliders. It finds **Vehicle Standard Input**, finds the first Vehicle Camera Controller, and disables the vehicle input and opted-in Edy camera.
2. Ultimate Character Controller Drive detects the source and begins the approach or teleport. `EVPDriveSource.EnterVehicle` does not enable the vehicle yet, so the character and Ultimate Character Controller camera retain control during entry.
3. When entry completes, Ultimate Character Controller calls `EnteredVehicle`. The bridge remembers the character, enables Vehicle Standard Input, and optionally enables Edy's camera while disabling the Ultimate Character Controller camera components.
4. Vehicle Standard Input writes steering, throttle, brake, and handbrake values to Edy's Vehicle Controller. Ultimate Character Controller Drive keeps the character aligned with **Driver Location** and ignores collisions with the cached vehicle colliders.
5. A valid exit request calls `ExitVehicle` before the exit animation completes. The bridge disables Vehicle Standard Input, which zeros the vehicle controls, disables Edy's camera, and re-enables the Ultimate Character Controller camera components.
6. Ultimate Character Controller completes the exit, restores character collision and parenting, and places the character at the selected clear Move Towards Location.

## Key choices and limitations

| Choice | Use it when | Important consequence |
| --- | --- | --- |
| **Teleport Enter Exit** | No enter or exit animations are available | Entry and exit are immediate, but a clear Move Towards Location is still required. |
| Animated entry and exit | The character should approach a door and play seated transitions | Animator events must call `OnAnimatorEnteredVehicle` and `OnAnimatorExitedVehicle` at the handoff points. |
| Ultimate Character Controller camera | One Ultimate Character Controller View Type should remain active | Disable **Use Vehicle Camera Controller** and the Edy camera component so they do not compete. |
| Edy's vehicle camera | EVP modes should control the shot | Put both camera controllers on one GameObject and assign the correct vehicle target before entry. |
| Legacy Input Manager | Vehicle Standard Input should be used unchanged | Configure its named axes; its input is global and separate from Ultimate Character Controller Player Input Proxy. |
| Unity Input System, mobile, or local multiplayer | Input needs action maps, touch ownership, or per-player devices | Use a project-owned EVP input handoff instead of assuming Vehicle Standard Input understands the Ultimate Character Controller provider. |

The stock integration assumes one local driver and one scene-wide vehicle camera. It contains no multiplayer synchronization, per-player input selection, or dynamic camera-target assignment. When Ultimate Character Controller multiplayer support is enabled, an `IDriveSource` is responsible for notifying remote players; EVP Drive Source does not implement that network layer.

A forced stop is another important boundary. Ultimate Character Controller Drive restores its own character state when force-stopped, but the stock EVP source disables vehicle input and returns camera ownership only in its normal `ExitVehicle` callback. Death, destruction, scene changes, or custom code that force-stops Drive while seated should perform equivalent EVP input and camera cleanup.

## Verify in Play Mode

1. Enter Play Mode without entering the vehicle. Vehicle Standard Input should be disabled, the parked vehicle should not respond to its axes, and the intended gameplay camera should be active.
2. Approach the entry collider. Drive's inherited **Detected Object** should show the vehicle.
3. Press the configured `Action` input. Confirm the character reaches the expected Move Towards Location or teleports, then aligns with **Driver Location**.
4. During the entry animation, the vehicle should remain disabled. It should accept steering, throttle, brake, and handbrake only after entry completes.
5. If **Use Vehicle Camera Controller** is enabled, confirm Edy's selected mode takes over after entry and Ultimate Character Controller camera look no longer competes. If it is disabled, confirm the Ultimate Character Controller camera remains in control.
6. Drive forward, reverse, steer, brake, use the handbrake, and reset the vehicle. Release every control and confirm its corresponding Vehicle Controller input returns to zero.
7. Press `Action` with a clear exit location. Vehicle input should stop and Ultimate Character Controller camera ownership should return as soon as exit begins; ordinary character movement should return when exit completes.
8. Block one exit location and try again. Drive should remain active until another configured location is clear.
9. Test death, forced ability stop, scene loading, and vehicle destruction while seated. Confirm the project returns vehicle input and camera ownership explicitly for each supported interruption.
10. For more than one vehicle or player, repeat the full test with each target and input owner. No other vehicle, character, or camera should respond.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports missing `EVP` types after import | Edy's Vehicle Physics may be absent, imported after the bridge, or incompatible with the bridge source | Install and compile the vehicle asset first, then reimport the current Ultimate Character Controller Version 3 integration. |
| The Console says EVP Drive Source must be attached to a vehicle with the Edy controller | **Vehicle Standard Input** may not be on the same GameObject as **EVP Drive Source**, or its **Target** cannot resolve Vehicle Controller | Put Vehicle Controller, Vehicle Standard Input, and EVP Drive Source on the vehicle root and assign **Target**. |
| Drive never detects the vehicle | The detected collider's layer may be excluded, the source may not be on a parent, or no clear Move Towards Location exists | Correct **Detect Layers**, move EVP Drive Source to the detected hierarchy, and add a clear entry or exit location. |
| The character enters but the vehicle does not respond | Vehicle Standard Input may not have enabled, its axis names may be absent, or entry may still be waiting for its Animator event | Inspect the component after entry, add `OnAnimatorEnteredVehicle`, and configure the named Input Manager axes. |
| The vehicle works with the old Input Manager but not Unity Input System | Vehicle Standard Input calls legacy `Input.GetAxis` directly | Enable and configure the compatible legacy input route, or adapt EVP Drive Source to enable a project-owned Input System provider. |
| The vehicle moves before the character enters | Another script or Vehicle Manager may be enabling or writing Vehicle Controller input | Give the bridge sole input ownership for this vehicle, or replace the stock handoff with an explicit manager integration. |
| Edy's camera never takes over | **Use Vehicle Camera Controller** may be disabled, the component may be absent or on an inactive GameObject at startup, or the source may have started before it existed | Add it to the active Ultimate Character Controller camera GameObject before Play Mode, enable the toggle, assign **Target**, and retest. |
| The Ultimate Character Controller and Edy cameras fight | Both camera controllers may be active, or **Use Vehicle Camera Controller** may be disabled while Edy's component remains enabled | Choose one owner. Let the bridge toggle Edy's camera when enabled, or disable Edy's component and keep the Ultimate Character Controller camera. |
| The camera follows the wrong vehicle | The stock bridge found one scene-wide camera whose **Target** still references another vehicle | Assign the intended target before entry or extend the Drive Source to update it for each vehicle. |
| Exit input does nothing | No Move Towards Location may be clear | Add another exit point or clear the overlap around its optional clearance collider. |
| Vehicle input or Edy's camera stays active after death or a forced stop | The normal `ExitVehicle` callback may have been bypassed | Add project cleanup that disables Vehicle Standard Input and Edy's camera and re-enables Ultimate Character Controller Camera Controller and Camera Controller Handler. |
| The character collides with a collider added after startup | EVP Drive Source caches active child colliders only once in `Start` | Keep required colliders active below the source at startup or update the custom source's collider list when the vehicle changes. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)

## Developer reference

`EVPDriveSource` implements Ultimate Character Controller's `IDriveSource`. It exposes **Driver Location**, **Animator ID**, and **Use Vehicle Camera Controller**, and supplies the vehicle GameObject, Transform, and cached child colliders to Drive.

Its lifecycle callbacks have deliberately small responsibilities:

- `EnterVehicle(Drive)` does nothing while the character approaches or animates into the seat.
- `EnteredVehicle(Drive)` stores the character and enables Vehicle Standard Input and the optional Edy camera handoff.
- `ExitVehicle(Drive)` disables vehicle input, returns camera ownership, and clears the stored character as soon as a valid exit starts.
- `ExitedVehicle(Drive)` does nothing after Ultimate Character Controller finishes restoring the character.

At startup, the source uses `GetComponent<VehicleStandardInput>()`, `GetComponentsInChildren<Collider>()`, and `FindObjectOfType<VehicleCameraController>()`. These lookups explain the same-GameObject input requirement, the startup collider snapshot, and the single scene-wide camera limitation.

Vehicle Standard Input sends values directly to `VehicleController.steerInput`, `throttleInput`, `brakeInput`, and `handbrakeInput`. Its `OnDisable` method resets all four to zero. A custom integration should preserve that zeroing behavior whenever driver ownership ends, including forced stops and interruption paths.

---

<a id="page-ultimate-character-controller-integrations-feel"></a>

# Feel

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/feel/)


Use the [Feel](https://assetstore.unity.com/packages/tools/particles-effects/feel-183370?aid=1100lGdc) integration to add an `MMF_Player` feedback sequence to an Ultimate Character Controller item use, character damage, item impact, or another deliberate gameplay event without replacing either system.

## Before you begin

- Start with a working Ultimate Character Controller Version 3 character and one working item. Verify the character and item in Play Mode before adding feedback.
- Install [Feel](https://assetstore.unity.com/packages/tools/particles-effects/feel-183370?aid=1100lGdc), add an **MMF Player** component, and build a small feedback sequence that works from Feel's own **Play** control.
- Import the Ultimate Character Controller Feel integration after both products compile. Use **Tools > Opsive > Ultimate Character Controller > Integrations Manager > Available Integrations**, or obtain the current package from the [Opsive Downloads page](https://opsive.com/downloads/).
- Back up the project before replacing an integration package.

The source-audited integration project contains Ultimate Character Controller `3.2.2`, Feel `3.16`, and Unity `2022.3.11f1`. The bridge does not declare a minimum or maximum Feel version. Current Feel documentation describes Feel 6 and still exposes `MMF_Player.PlayFeedbacks`, but that does not prove that every bridge package works unchanged with every later Feel release. Reimport the current bridge after upgrading either product and repeat the tests on this page.

## Prepare the MMF Player

1. Add **MMF Player** to the character, item action GameObject, or a dedicated feedback GameObject.
2. Add and configure the Feel feedbacks that should play together.
3. Disable **Auto Play on Start** and **Auto Play on Enable** when Ultimate Character Controller should be the only trigger. This prevents an automatic Feel play from being mistaken for a successful Ultimate Character Controller connection.
4. Enter Play Mode and use the MMF Player's **Initialization** and **Play** controls. Confirm the complete sequence works before connecting it to Ultimate Character Controller.
5. Keep a direct reference to this component available. The Ultimate Character Controller bridge searches only the same GameObject when **Player** is empty; it does not search children or the scene.

## Play feedback when an item is used

The bridge supplies item-use modules for Shootable, Melee, Magic, and Throwable actions. Each module runs when that action receives its normal Ultimate Character Controller use callback.

1. Select the item and find its **Shootable Action**, **Melee Action**, **Magic Action**, or **Throwable Action** component.
2. Open **Extra Module Group** and select **Add**.
3. Add the module that matches the action and the amount of the Feel sequence that should play:

   | Item action | Play the complete MMF Player | Play one feedback |
   | --- | --- | --- |
   | Shootable | **Play Feedbacks Shootable Module** | **Play Feedback Shootable Module** |
   | Melee | **Play Feedbacks Melee Module** | **Play Feedback Melee Module** |
   | Magic | **Play Feedbacks Magic Module** | **Play Feedback Magic Module** |
   | Throwable | **Play Feedbacks Throwable Module** | **Play Feedback Throwable Module** |

4. Assign the prepared MMF Player to **Player**. Assign it explicitly even when the component is on the same GameObject; this makes ownership clear when the item hierarchy changes.
5. Set **Intensity** to `1` for the normal Feel intensity, then tune it only after the sequence works.
6. For a complete sequence, leave **Revert** disabled for normal forward playback.
7. For one feedback, select it with **Feedback Index**, or set **Feedback Index** to `-1` and enter its exact **Feedback Label**.

Use a complete sequence for a coordinated response such as muzzle flash, camera impulse, sound, and haptics. Use one feedback when the same MMF Player contains several reusable responses and this item needs only one of them.

## Connect damage, impacts, and abilities

The bridge does not add a dedicated Ultimate Character Controller damage, impact, or ability module. Use the event already owned by that Ultimate Character Controller system, or add a small project adapter when the event must be filtered.

### Play feedback when a character takes damage

1. Select the character's **Character Health** component.
2. Open **Events**, then add a listener to **On Damage Event**.
3. Drag the GameObject containing the MMF Player into the listener.
4. Select **MMF Player > PlayFeedbacks()** as a static, parameterless call.
5. Damage the character twice in Play Mode. The sequence should play once for each accepted damage event.

Use **On Death Event** instead when the sequence should run only on death. The Ultimate Character Controller **Damaged Effect** field is not a reliable route with the audited bridge package; the character Effect limitation is described below.

### Play feedback at an item impact

1. Find the Impact Action Group used by the item's hit, projectile, or cast.
2. Add **Impact Unity Event** to that group.
3. In **On Impact Event**, drag the GameObject containing the MMF Player into the listener.
4. Select the parameterless **MMF Player > PlayFeedbacks()** call.
5. Hit a valid target in Play Mode and confirm the feedback plays at the same time as the other impact actions.

This route triggers the MMF Player, but it does not pass Ultimate Character Controller's impact position or strength into the parameterless Feel call. Use a project adapter when the feedback must use `ImpactCallbackContext` to move the player to the contact point or scale its intensity from the hit.

### Play feedback from an ability

Every ability has a **Start Effect** choice, and Ultimate Character Locomotion exposes **Events > On Ability Active Event**. The audited Feel bridge does not provide a working ability-specific adapter:

- Binding `MMF_Player.PlayFeedbacks()` directly to **On Ability Active Event** plays for every ability start and stop because that event reports both the ability and its active state.
- Selecting the bridge's character Effect as **Start Effect** does not replay the Feel sequence in the audited package.

For a production ability, use a small adapter that listens to **On Ability Active Event**, checks the intended ability and `active == true`, and then calls the assigned MMF Player. This keeps one clear trigger and avoids playing the sequence for unrelated abilities or for the stop transition.

## Character Effect boundary

The integration adds **Play Feedbacks** and **Play Feedback** to **Ultimate Character Locomotion > Effects**. In the audited Ultimate Character Controller `3.2.2` bridge, both classes call Feel from the Effect lifecycle `Start()` method. Ultimate Character Controller calls that method once while the character initializes. Later activation through an ability's **Start Effect**, Character Health's **Damaged Effect**, or `TryStartEffect` calls `EffectStarted()` instead, which these integration classes do not override.

As a result, the audited package plays a configured character feedback once at startup and does not play it again when the Effect is activated. Do not use that package's character Effect route for damage or ability feedback. If a newer downloaded bridge changes the callback to `EffectStarted()`, verify one startup, two activations, and one stop in Play Mode before relying on it.

## How it runs

1. During initialization, the bridge uses the assigned **Player** or looks for an MMF Player on the same GameObject. It calls the player's initialization method and disables the Ultimate Character Controller Effect or item module when no player can be resolved.
2. An item-use module receives Ultimate Character Controller's `UseItem` callback for its matching action type.
3. **Play Feedbacks** calls the MMF Player with the item action's Transform position, **Intensity**, and **Revert** choice. **Play Feedback** resolves one feedback by label or index and plays it with the same position and intensity.
4. Damage and impact Unity Events call the MMF Player directly when their owning Ultimate Character Controller system reports the event.
5. The bridge does not stop a running Feel sequence when an item use or ability ends. Configure Feel's own overlap, cooldown, duration, and stop behavior for repeated gameplay triggers.

## Key choices and limitations

| Choice | Use it when | Important consequence |
| --- | --- | --- |
| **Play Feedbacks** | The entire MMF Player is one coordinated gameplay response | Every feedback in the player is requested on each item use. |
| **Play Feedback** by index | The feedback list order is controlled and unlikely to change | Index `0` is the first feedback; reordering the list changes which feedback plays. |
| **Play Feedback** by label | A stable, descriptive Feel label should select the response | In the audited bridge, a valid index overwrites a label match despite the field tooltip. Set **Feedback Index** to `-1` when using **Feedback Label**. |
| **Intensity** `1` | The feedback should play at its authored strength | The audited bridge serializes `-1` as its default and passes it directly to Feel. Many feedbacks multiply their output by this value, so set and test it deliberately. |
| **Revert** disabled | The Feel sequence should use its normal direction | In Feel 3.16 the bridge's Boolean is passed as `forceRevert`, which toggles the player's direction. Enable it only after testing the intended reverse behavior. |
| Ultimate Character Controller Unity Event | Damage or an impact needs a no-code trigger | The parameterless call ignores Ultimate Character Controller's event data. Use an adapter when position, strength, ability identity, or active state matters. |

The supplied integration is local-only glue. Its character Effects are not network synchronized, and its item modules do not opt into Ultimate Character Controller module network synchronization. In a multiplayer project, trigger equivalent feedback for the intended local player or observer through the project's networking layer instead of assuming the bridge replicates it.

## Verify in Play Mode

1. Start with Feel's **Auto Play on Start** and **Auto Play on Enable** disabled. Nothing should play before the chosen Ultimate Character Controller trigger, except the audited character Effect startup behavior described above.
2. Use the item once. Confirm the intended MMF Player or single labeled feedback plays exactly once.
3. Use the item repeatedly. Confirm Feel's cooldown and overlap behavior match the intended rate and that the sequence does not stack unexpectedly.
4. Switch perspective and use the item again. Camera, UI, and haptic feedback should still target the intended local player.
5. For damage, apply two nonlethal hits and one lethal hit. **On Damage Event** should run for each accepted hit; **On Death Event** should run only when health reaches its death state.
6. For an impact, hit a valid target and then miss. The impact feedback should play only for the configured Impact Action Group.
7. For an ability adapter, start and stop the chosen ability and then activate a different ability. The feedback should play only on the intended start transition.
8. Test after death and respawn, item unequip and re-equip, and a scene reload. No stale player reference or duplicate event listener should remain.
9. Make a development build for the target platform and verify any Feel feedback that depends on haptics, render-pipeline features, audio, or a third-party package.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports missing `MoreMountains.Feedbacks` or Feel types | Feel may be absent, imported after the bridge, or incompatible with that bridge package | Install and compile Feel first, then import the current Ultimate Character Controller Version 3 integration again. Resolve the first Console error. |
| The Feel modules are missing from the item menu | The integration may not have compiled, or the selected action may not be Shootable, Melee, Magic, or Throwable | Confirm the bridge scripts compile and add the module whose suffix matches the item's action type. |
| The Console says an MMF Player must be assigned | **Player** is empty and no MMF Player exists on the action or character GameObject itself | Assign the MMF Player explicitly. Do not rely on a child or scene-wide search. |
| A sequence plays as soon as Play Mode starts | Feel auto-play may be enabled, or the audited Ultimate Character Controller character Effect may be calling Feel from lifecycle `Start()` | Disable Feel auto-play. Remove the character Effect route and use the intended item or Unity Event trigger. |
| An ability or **Damaged Effect** becomes active but no Feel feedback plays | The audited character Effect does not call Feel from `EffectStarted()` | Use the relevant Ultimate Character Controller Unity Event or a filtered adapter, or install and verify a bridge version that corrects the lifecycle callback. |
| The wrong individual feedback plays | **Feedback Index** may still be valid and therefore override the label in the audited source | Set the correct index, or set it to `-1` and use a unique exact **Feedback Label**. |
| A label cannot be found | The label may be misspelled, duplicated, or the index may be outside the list without a matching label | Use a unique Feel label, preserve its capitalization, and verify it on the assigned MMF Player. |
| The feedback is inverted, silent, or much stronger than expected | **Intensity** may still be `-1`, or **Revert** may be changing direction | Start with **Intensity** `1` and **Revert** disabled, then tune one choice at a time. |
| Damage feedback never runs | The listener may be on the wrong Health component, or the target may be invincible and reject the damage | Bind **Character Health > Events > On Damage Event** on the damaged character and confirm its health value actually changes. |
| Impact feedback runs at the item instead of the contact point | The parameterless MMF Player callback has no impact position | Use an adapter that reads `ImpactCallbackContext.ImpactCollisionData.ImpactPosition` and passes that position to Feel. |
| Every ability start and stop plays the same feedback | The MMF Player is bound directly to the unfiltered **On Ability Active Event** | Replace the direct listener with an adapter that checks the intended ability and the active Boolean. |
| A remote character's feedback is missing or plays on the wrong client | The supplied bridge does not synchronize the Effect or item module | Replicate the gameplay event through the project's network code, then play feedback only for the correct local observer. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Character Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)
- [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Feel MMF Player documentation](https://feel-docs.moremountains.com/mmf-player.html)

## Developer reference

The bridge consists of `FeelUtility`, two Ultimate Character Controller `Effect` subclasses, and eight item modules:

- `PlayFeedbacks` and `PlayFeedback` derive from Ultimate Character Controller `Effect`.
- The complete-sequence item classes derive from the corresponding `ShootableExtraModule`, `MeleeExtraModule`, `MagicExtraModule`, or `ThrowableExtraModule` and implement `IModuleUseItem`.
- The single-feedback item classes use the same four module bases and callback.

`FeelUtility.InitializePlayer` uses the assigned `MMF_Player`, otherwise calls `GetComponent<MMF_Player>()` on the owning Ultimate Character Controller GameObject, then calls `Initialization()`. `PlayFeedbacks` forwards the position, intensity, and revert Boolean to `MMF_Player.PlayFeedbacks`. `PlayFeedback` resolves a cached `MMFeedback` from the player's list and calls `MMFeedback.Play(position, intensity)`.

The audited single-feedback resolver checks **Feedback Label** first but then assigns the indexed feedback whenever **Feedback Index** is in range. This is why `-1` is required for label-only selection. The audited Effect classes override `Start()` instead of `EffectStarted()`, which is why `TryStartEffect`, ability **Start Effect**, and Character Health **Damaged Effect** do not replay them.

Useful Ultimate Character Controller event boundaries are `Health.OnDamageEvent`, `ImpactUnityEvent.OnImpactEvent`, and `UltimateCharacterLocomotion.OnAbilityActiveEvent`. The last event supplies `(Ability ability, bool active)`, so an ability-specific adapter should require both the target ability and `active == true`. An impact adapter can read `ImpactCallbackContext.ImpactCollisionData.ImpactPosition` and `ImpactStrength` before calling the MMF Player with project-defined intensity rules.

---

<a id="page-ultimate-character-controller-integrations-final-ik"></a>

# Final IK

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/final-ik/)

Use the [Final IK](https://assetstore.unity.com/packages/tools/animation/final-ik-14290?aid=1100lGdc) integration when RootMotion should solve the character's limbs, aim, look direction, grounding, or object interactions while Ultimate Character Controller continues to decide when those actions occur.

## Before you begin

- Start with a working Ultimate Character Controller Version 3 character. Confirm locomotion, animation, the camera or other look source, and one representative item or ability in Play Mode before replacing its IK.
- Install [Final IK](https://assetstore.unity.com/packages/tools/animation/final-ik-14290?aid=1100lGdc) before importing the Ultimate Character Controller integration. The bridge compiles against RootMotion types and cannot compile without them.
- Commit or back up the project. You will remove **Character IK** from the animated model and replace it with **Final IK Bridge**.
- Configure each RootMotion solver with the [Final IK documentation](https://www.root-motion.com/finalikdox/html/pages.html). The bridge connects Ultimate Character Controller to those solvers; it does not build or validate the Final IK rig for you.

The Ultimate Character Controller Version 3 integration catalog currently lists Final IK, but it does not declare a minimum or maximum Final IK version. The source snapshot verified for this page uses Ultimate Character Controller `3.2.0`, Final IK `2.2`, and Unity `2021.3.0f1`; the current Asset Store release is newer. Treat those numbers as an audited snapshot, not a compatibility matrix. After upgrading either product, import the current bridge and repeat the isolated Play Mode checks below before updating production scenes.

## Install and connect the bridge

1. Install Final IK and wait for Unity to compile without errors.
2. Open **Tools > Opsive > Ultimate Character Controller > Integrations Manager**, select **Available Integrations**, and find **Final IK**.
3. Use the **Integration** action to follow the current distribution route. If it opens the documentation route, sign in to the [Opsive Downloads page](https://opsive.com/downloads/) and obtain the Ultimate Character Controller Version 3 Final IK integration.
4. Import the integration after Final IK, then resolve every Console compile error before changing the character.
5. Select the animated character-model GameObject that has the **Animator** and **Animator Monitor** components. Do not add the bridge only to the Ultimate Character Controller locomotion root when the Animator is on a child model.
6. Remove **Character IK** from that model. Leave one IK provider on a model so items and abilities do not select competing owners.
7. Add **Final IK Bridge** to the same model GameObject.
8. Add and configure the RootMotion components needed for the scenarios in the next section. **Full Body Biped IK**, **Look At IK**, **Aim IK**, and **Interaction System** must be on the same GameObject as **Final IK Bridge** because the bridge discovers them there.
9. Repeat the replacement on every animated model that Ultimate Character Controller can activate. Configure only the Final IK solvers supported by that model's rig.

![Atlas character model selected with Final IK Bridge, Grounder Full Body Biped, Full Body Biped IK, Look At IK, and Aim IK on the same GameObject](https://opsive.com/wp-content/uploads/2019/01/FinalIKComponents.png?v=ab77da29da4e)

## Choose the Final IK components

Add only the systems the character needs:

| Goal | Components | What the bridge supplies |
| --- | --- | --- |
| Position an off-hand on an equipped item or apply Ultimate Character Controller limb offsets | **Full Body Biped IK** | Assigns the non-dominant hand and elbow targets, forwards final hand and foot adjustments, and updates the solver after animation. |
| Follow the camera, an AI look source, or a Look At ability target | **Look At IK** | Moves a runtime target from Ultimate Character Controller's current look source or explicit look target. |
| Aim an equipped item while Aim or Use is active | **Aim IK** | Assigns the active item transform and supplies the animated aim axis while the item is aiming or in use. |
| Place feet on uneven surfaces | **Full Body Biped IK** and **Grounder Full Body Biped** | The bridge updates the Full Body Biped solver. Grounder remains a Final IK-owned layer that modifies that solver through its callbacks. |
| Reach a button, handle, or other ability target | **Full Body Biped IK** and **Interaction System** | Maps an Ultimate Character Controller Ability IK Target to a Final IK Interaction Object and starts or stops the matching effector interaction. |

**Interaction System** requires **Full Body Biped IK**. The bridge does not directly adapt unrelated Final IK solvers such as VRIK, Biped IK, or Limb IK; those need their own project-specific ownership and testing.

## Configure the bridge

Keep the normal Ultimate Character Controller-owned route simple:

- Leave **Set Look At Target** enabled when Ultimate Character Controller should drive **Look At IK** from its current look source or a Look At ability. Leave **Set Aim Target** enabled when Ultimate Character Controller should drive **Aim IK** for equipped items.
- Assign **Head** when using Look At IK or Aim IK without Full Body Biped IK. When Full Body Biped IK is present, the bridge obtains the head from its biped references.
- Use **Look At Offset** to adjust where the body looks without changing the camera. **Look At Adjustment Speed** controls how quickly the generated target follows the requested direction.
- Keep **Active Look At State Name** set to `LookAt` when the existing Ultimate Character Controller state should activate for an explicit target, or use the exact name of the project's replacement state.
- Adjust **Animated Aim Direction** when the weapon animation's authored forward axis is not the model's forward axis. Start at `(0, 0, 1)` and change it only after observing a consistent aiming offset in Play Mode.
- Use **Position Spring** and **Rotation Spring** for Ultimate Character Controller secondary forces such as item recoil. Tune the visible response after the base pose and Final IK references are correct.

Disable **Set Look At Target** or **Set Aim Target** only when a custom system intentionally owns that Final IK target. That changes solver ownership and update order, so verify it as a separate integration rather than combining both owners by accident.

## Configure an interaction target

Use this setup when the Interact ability should place a hand or another limb on an object:

1. On the animated character model, add and configure **Full Body Biped IK**, **Interaction System**, and **Final IK Bridge** on the same GameObject.
2. On the exact target GameObject that represents the contact point, add Ultimate Character Controller's **Ability IK Target** and Final IK's **Interaction Object**. The bridge looks for the Interaction Object on the same GameObject as the target transform.
3. Set the Ability IK Target **Goal** to the intended hand, elbow, foot, or knee. Configure the Interaction Object's effector target and weight curves using the Final IK Interaction System workflow.
4. Add the target beneath the scene object's **Interactable** and test the complete Interact workflow: detection, optional Move Towards alignment, limb contact, object response, and release.

The bridge starts the Final IK interaction when Ultimate Character Controller activates the Ability IK Target and stops that effector when Ultimate Character Controller clears it. Ultimate Character Controller still owns ability timing; Final IK owns the resulting limb solve.

## How ownership works

**Final IK Bridge** replaces Ultimate Character Controller's built-in **Character IK** component as the model's IK provider. Ultimate Character Controller continues to own the gameplay intent: the current look source, equipped item, Aim and Use state, ability IK target, secondary forces, death, respawn, and active character model.

The bridge converts that intent into Final IK targets and updates the supported solvers after animation each frame. When the bridge owns the target, it disables the normal component update for Full Body Biped IK, Look At IK, or Aim IK as appropriate and invokes the solver itself. A disabled Final IK component checkbox during Play Mode can therefore be expected; do not re-enable it solely because the bridge is updating it manually.

RootMotion still owns solver references, weights, constraints, Interaction Object curves, Grounder configuration, and the final bone calculations. This division is why a clean Ultimate Character Controller setup and a separately valid Final IK rig are both required.

## Verify in Play Mode

1. Enter Play Mode in a small scene containing one character, one configured model, and only the Final IK systems needed for the test.
2. Confirm the Console has no missing RootMotion types, missing head error, invalid biped references, or Interaction System warnings.
3. Move and rotate the camera, or update the AI look source. With Look At IK configured, confirm the head and body follow smoothly without the camera direction changing.
4. Equip an item with a non-dominant hand target. With Full Body Biped IK configured, confirm the second hand reaches the item and releases correctly on unequip.
5. Start and stop Aim and Use. With Aim IK configured, confirm the solver follows the item only during the intended actions and returns to the animated pose afterward.
6. Trigger an Interact object with an Ability IK Target and Interaction Object. Confirm the intended limb reaches the contact point, the object responds once, and the limb releases when Interact finishes.
7. If Grounder is used, walk over a flat surface, a slope, and stairs. Confirm both feet settle without pulling the pelvis or legs into an unstable pose.
8. Test death and respawn, every perspective or model switch used by the project, and one scene reload. The active model should regain the same IK behavior without duplicate targets or solvers.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports missing `RootMotion.FinalIK` types after import. | Final IK is absent, imported after the bridge, or the imported bridge is not for Ultimate Character Controller Version 3. | Install Final IK first, then import the current Ultimate Character Controller Version 3 integration again and resolve the first Console error. |
| The bridge reports that no head is specified or remains inactive. | **Look At IK** or **Aim IK** is present without **Head** or valid Full Body Biped IK head references; the character may also have no attached look source. | Assign **Head** or repair the biped references, then confirm the player camera or AI look source attaches to the character. |
| The pose jitters or limbs are solved twice. | **Character IK** may still be present, more than one bridge may be active on the model, or a custom script may also own the Look At/Aim target. | Keep one CharacterIKBase owner per active model. Remove the competing component or return **Set Look At Target** and **Set Aim Target** to the Ultimate Character Controller-owned route. |
| The off-hand does not reach the equipped item. | Check the Full Body Biped IK hand references, the active model, and the item's non-dominant hand and elbow targets. | Repair the biped references and item targets, then retest equip and unequip on the model that is actually active. |
| Aim points consistently away from the reticle. | The weapon animation's forward axis does not match **Animated Aim Direction**, or Aim IK is not using the active item transform. | Correct the Aim IK setup, then tune **Animated Aim Direction** from its `(0, 0, 1)` starting value. |
| Look At IK does not follow the camera or AI. | Check **Set Look At Target**, **Head**, the attached look source, and whether the active model contains the bridge. | Restore the Ultimate Character Controller-owned target, assign the head, attach a working look source, and add the bridge to every switchable model that needs IK. |
| An Interact ability runs but the limb does not reach the object. | The model may lack **Interaction System** or **Full Body Biped IK**, or the contact GameObject may not contain both **Ability IK Target** and **Interaction Object**. | Put the required character components on the bridge GameObject and both target components on the same contact GameObject, then configure the Interaction Object's effector and curves. |
| Grounder has no effect. | **Grounder Full Body Biped** may not reference the model's Full Body Biped IK solver, or its Final IK grounding setup may be incomplete. | Assign the correct Full Body Biped IK component and validate Grounder independently on flat ground before testing it through the bridge. |
| IK works until the character model changes. | Only the original model contains the replacement CharacterIKBase and RootMotion solvers. | Repeat the bridge and solver setup on every model used by Model Manager, then verify each switch in Play Mode. |

## Related tasks

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/) explains the shared install, isolation, and upgrade workflow.
- [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/) covers the built-in Character IK route that this integration replaces.
- [Interact](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/) configures Interactable objects, Ability IK Targets, and interaction timing.
- [Look At](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/look-at/) supplies an explicit Ultimate Character Controller look target.
- [Model Switch](https://opsive.com/support/documentation/ultimate-character-controller/character/model-switch/) explains active character-model changes that require matching IK setup.
- [Springs](https://opsive.com/support/documentation/ultimate-character-controller/animation/springs/) explains the spring response used by secondary IK forces.

## Developer and source reference

`Opsive.UltimateCharacterController.Integrations.FinalIK.FinalIKBridge` derives from `CharacterIKBase` and reports `UseOnAnimatorIK` as false. It discovers `FullBodyBipedIK`, `LookAtIK`, `AimIK`, and `InteractionSystem` with `GetComponent` on its own GameObject, creates a runtime target for the Ultimate Character Controller-owned look and aim route, and updates supported solvers from `LateUpdate`.

The bridge listens for Ultimate Character Controller look-source, Aim, Use, equip, unequip, secondary-force, death, respawn, and Animator-snap events. It assigns the non-dominant item hand to Full Body Biped IK, maps Ability IK Target goals to Final IK effectors, disables itself on death, and resumes on respawn. Grounder Full Body Biped and Interaction System attach to the Full Body Biped solver's callbacks, so the bridge's manual solver update still drives those Final IK layers.

The released Ultimate Character Controller package inspected for this page is `3.2.0`. The separate Opsive bridge sample contains Final IK `2.2` and was saved with Unity `2021.3.0f1`; the [Final IK Asset Store listing](https://assetstore.unity.com/packages/tools/animation/final-ik-14290?aid=1100lGdc) currently reports version `2.5`. Neither the current Opsive integration catalog nor the bridge source declares a broader semantic compatibility range. Use the current integration package, keep the tested product pair recorded in the project, and repeat compilation plus the Play Mode checklist after either dependency changes.

---

<a id="page-ultimate-character-controller-integrations-fmod"></a>

# FMOD

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/fmod/)

Use the [FMOD](https://assetstore.unity.com/packages/tools/audio/fmod-for-unity-2-03-311497?aid=1100lGdc) integration when Ultimate Character Controller should keep choosing and timing gameplay sounds while FMOD owns the event, spatialization, routing, and final playback.

## Before you begin

- Start with a working Ultimate Character Controller Version 3 scene. Confirm at least one ability, item, health, footstep, or impact sound through the normal Opsive audio workflow before changing the scene's playback module.
- Install and configure [FMOD for Unity](https://assetstore.unity.com/packages/tools/audio/fmod-for-unity-2-03-311497?aid=1100lGdc) first. In Unity, use **FMOD > Edit Settings** to connect the built banks, **FMOD > Refresh Banks** after rebuilding them, and **FMOD > Event Browser** to confirm the intended events are available.
- Keep the FMOD for Unity integration on the same major line as the FMOD Studio project. Follow the [FMOD for Unity user guide](https://www.fmod.com/docs/2.03/unity/user-guide.html) for plugin, bank, platform, and licensing setup before troubleshooting the Ultimate Character Controller bridge.
- Commit or back up the project. Assigning the FMOD module changes the playback owner for every sound routed through the scene's Opsive Audio Manager.

The released bridge snapshot verified for this page uses Ultimate Character Controller `3.3.3`, Opsive Shared `2.1.0`, FMOD for Unity `2.02.33`, and Unity `2022.3.62f3`. The current public FMOD line is `2.03`, but the Opsive package does not declare a semantic minimum or maximum. Treat the snapshot as an audited configuration, not a compatibility matrix. For FMOD `2.03`, import the current bridge after FMOD and pass the isolated compilation and Play Mode checks below before changing a production scene.

## Install the Ultimate Character Controller bridge

1. Install FMOD for Unity and configure its banks. Resolve all FMOD initialization, bank-loading, and event-browser errors first.
2. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the FMOD integration. It is not included in the base product's Integrations folder before this download.
3. Import the downloaded package after FMOD has compiled. Importing it creates `Assets/Opsive/UltimateCharacterController/Integrations/FMOD` in the project.
4. Confirm that Unity imported `FMODAudioManagerModule.cs` and `FMODAudioManagerModule.asset`, then wait for compilation to finish.
5. If the scene does not have the standard manager object, open **Tools > Opsive > Ultimate Character Controller > Setup Manager**, select **Manager Setup**, and use **Add Managers**.
6. Select the scene's **Game** object and find its **Audio Manager** component.
7. Assign `FMODAudioManagerModule.asset` to **Audio Manager Module**.
8. Select the module asset. Assign **Default Audio Config** only when an Opsive audio request without its own Audio Config should use that shared set of placeholder clips.
9. Add at least one direct event mapping as described below, save the scene, and test that mapping before converting the rest of the project's sounds.

The included asset is the normal starting point. To maintain a separate mapping asset for another project or test scene, use **Assets > Create > Opsive > Audio > FMOD Audio Manager Module** and assign the new asset to **Audio Manager Module**.

## Map Ultimate Character Controller clips to FMOD events

The bridge preserves the Opsive Audio Clip Set and Audio Config workflow, but it uses each selected Unity AudioClip as an identifier. It does not play that clip's waveform.

For a direct mapping:

1. Create or reuse an Opsive Audio Config and add one placeholder AudioClip for each sound choice.
2. Select `FMODAudioManagerModule.asset` and expand **Audio Clip Event Mappings**.
3. Add an element, assign the placeholder to **Audio Clip**, and choose the FMOD event in **Event Reference**.
4. Repeat for every placeholder used by the test Audio Config.
5. Assign the Audio Config to the Ultimate Character Controller feature and trigger it in Play Mode.

Direct mappings are the safest route because the placeholder name and FMOD event hierarchy can change independently while the event reference remains explicit.

### Use a naming fallback

If a placeholder has no direct mapping, the module joins **Default Event Path Prefix** and `AudioClip.name`. The included default is `event:/`, so an AudioClip named `Footstep` resolves to `event:/Footstep`.

For a shared folder, set the prefix to a path such as `event:/Characters/Footsteps`. A placeholder named `Stone` then resolves to `event:/Characters/Footsteps/Stone`; the module inserts the missing slash when needed.

Use this fallback only when names and folders follow a controlled convention. A renamed AudioClip, a moved FMOD event, or a missing bank can make the path invalid without changing the Ultimate Character Controller Audio Config. Use a direct mapping for nested event structures and sounds maintained by different teams.

### Keep Opsive clip selection

Audio Config still chooses the placeholder before the bridge resolves an event:

- **Random** selects a random mapped placeholder.
- **Sequence** advances through the mapped placeholders in order.
- **Index** selects the placeholder at the current Audio Config index.

This lets existing ability, item, health, surface, and impact data keep its selection logic. The corresponding FMOD events own the actual audio content and their internal variations.

## How audio is routed

The scene **Audio Manager** remains the entry point used by Ultimate Character Controller. The FMOD module replaces its normal Unity AudioSource playback for every request that reaches that manager.

- Ultimate Character Controller owns when to request or stop a sound, which Audio Config or AudioClip is selected, and the supported volume, pitch, and delay overrides.
- The module resolves the placeholder to an FMOD event, creates an event instance, starts it immediately or after the requested delay, and tracks it against the originating GameObject.
- For a 3D FMOD event, normal playback attaches the instance to the GameObject so it follows the character, item, or moving object. Playback at a world position sets that initial position instead.
- A 2D FMOD event ignores the supplied GameObject or world position for spatial placement.
- FMOD owns event instruments, looping, parameters, buses, snapshots, effects, spatial behavior, and bank content.
- When Ultimate Character Controller stops tracked audio, **Allow Fadeout** chooses FMOD's fade-out stop mode; disable it only when that integration-wide stop should be immediate.
- **Cleanup Interval** controls how often completed instances are released. Keep the included `0.5` second value unless profiling shows a reason to change it; the Inspector prevents values below `0.1` seconds.

Keep one intended Audio Manager in the scene. This bridge is a scene-wide module, not a per-clip switch between FMOD and Unity AudioSource playback. If a particular system must keep using Unity audio, call that system separately or implement and test a project-owned hybrid module.

## Current limitations

The source-verified bridge forwards only Opsive clip selection, volume, pitch, and delay. Configure the following behavior in FMOD rather than expecting Unity AudioSource settings to transfer:

- **Audio Source Prefab**, **Output Override** or an Audio Mixer Group, **Stereo Pan**, **Spatial Blend**, and **Reverb Zone** do not configure the FMOD event.
- **Loop Override** does not make an event loop. Author looping in FMOD and ensure the Ultimate Character Controller feature stops the tracked event when the action ends.
- **Share Audio Source**, **Replace Previous Audio Source**, and **Copy Existing Audio Source Properties** describe the Unity AudioSource pool and do not control FMOD event instances.
- `PlayResult.AudioSource` is empty because FMOD playback does not return a Unity AudioSource. The module can still stop a matching tracked event through the Audio Config or returned PlayResult data.
- FMOD parameters, buses, snapshots, programmer sounds, and custom emitter behavior are not populated automatically from an Opsive Audio Config. Use FMOD components or project code for those features.
- Bank loading, platform binaries, listener setup, and FMOD Studio content remain FMOD responsibilities. The Ultimate Character Controller package supplies only the Audio Manager module.

When two identical events overlap on the same GameObject, stopping by Audio Config stops all tracked events for that config. Stopping by PlayResult stops one tracked event matching its clip and config; the PlayResult does not expose an FMOD event handle.

## Verify in Play Mode

1. Open a small scene with one **Audio Manager**, one Ultimate Character Controller character, one Audio Config, and one directly mapped FMOD event.
2. Enter Play Mode and confirm the Console has no missing `FMODUnity` types, bank-loading errors, invalid event-reference errors, or missing-mapping warnings.
3. Trigger the Ultimate Character Controller feature several times. Confirm the mapped event plays once per request and Random, Sequence, or Index chooses the expected placeholder.
4. Move the source GameObject while a 3D event plays. Confirm the sound follows it. Trigger a separate sound at a world position and confirm that event remains at the requested position.
5. Test one 2D event and confirm that moving the character does not spatialize it.
6. Apply distinct volume, pitch, and delay overrides in the Audio Config. Confirm those three values reach the FMOD event.
7. Start an event that Ultimate Character Controller later stops. Confirm **Allow Fadeout** produces the intended release and that the event does not continue after its gameplay owner ends.
8. Test an ability, item, health sound, footstep, and impact used by the project. Confirm every placeholder resolves through FMOD and that any default Unity AudioSource on the manager remains idle rather than playing the bridged requests.
9. Build for the target platform and verify bank inclusion, native FMOD libraries, listener behavior, and spatial playback outside the Editor.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports missing `FMODUnity` types after importing the bridge. | FMOD for Unity is absent, failed to compile, or was imported after the Ultimate Character Controller package. | Install and configure FMOD first, then reimport the current Ultimate Character Controller Version 3 `FMOD.unitypackage` and resolve the first Console error. |
| The Console reports `[FMOD] No event mapping was found for AudioClip 'SomeClip'`. | The placeholder has no valid direct mapping and the fallback path does not resolve to a loaded event. | Add the clip under **Audio Clip Event Mappings**, or correct **Default Event Path Prefix**, the AudioClip name, and the bank content. |
| An Event Reference is assigned but nothing plays. | The event may be absent from loaded banks, the FMOD plugin and Studio project may use different major lines, or FMOD may have failed to initialize. | Use **FMOD > Refresh Banks** and **FMOD > Event Browser**, match the FMOD major line, and resolve FMOD's first initialization or bank error. |
| Every request is silent after assigning the module. | **Audio Manager Module** may reference the wrong asset, or the selected Audio Config may contain no placeholder clips. | Assign the included `FMODAudioManagerModule.asset`, add mapped placeholders, and test one direct mapping in isolation. |
| A sound plays in 2D when it should follow the character. | The FMOD event itself is 2D; Unity **Spatial Blend** is not forwarded. | Make the event 3D in FMOD, rebuild and refresh the banks, then repeat the moving-GameObject test. |
| Volume or pitch changes, but pan, mixer, reverb, spatial blend, or looping does not. | Those Unity AudioSource settings are outside the module's forwarded values. | Author the behavior in the FMOD event, bus, or snapshot. Use Opsive overrides only for volume, pitch, and delay. |
| A looping event continues after its ability or item stops. | Looping is FMOD-owned and the Ultimate Character Controller feature may not issue a matching stop request. | Ensure the feature retains and stops the matching Audio Config or PlayResult, and configure the event's FMOD release behavior. |
| The wrong event plays when using the fallback. | Another event path may share the clip name, or **Default Event Path Prefix** points to the wrong folder. | Use a direct **Event Reference**, or make the prefix and placeholder naming convention unambiguous. |
| Audio works in the Editor but not in a build. | Banks or the target platform's native FMOD libraries may be missing, or the bank source may not be included by CI. | Follow the FMOD platform and build guidance, include the built banks and platform package, and test a development build before changing Ultimate Character Controller mappings. |

## Related tasks

- [Audio](https://opsive.com/support/documentation/ultimate-character-controller/audio/) explains Audio Clip Sets, Audio Config selection, and the default Unity AudioSource module that this integration replaces.
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/) covers the shared install, isolation, upgrade, and build workflow.
- [Character Foot Effects](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/character-foot-effects/) uses Audio Config assets for footsteps selected by the Surface System.
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) exposes damage, healing, and death audio that can route through this module.
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) describes the action modules that request item audio.
- [Master Audio](https://opsive.com/support/documentation/ultimate-character-controller/integrations/master-audio/) is the alternative scene-wide audio backend integration.

## Developer and source reference

`Opsive.Shared.Integrations.FMOD.FMODAudioManagerModule` derives from `AudioManagerModule`. The included source and asset are packaged at `Assets/Opsive/UltimateCharacterController/Integrations/FMOD/`; the create menu is **Assets > Create > Opsive > Audio > FMOD Audio Manager Module**.

The module resolves direct `AudioClip` to `FMODUnity.EventReference` mappings first, then calls `RuntimeManager.PathToEventReference` for the prefix-and-name fallback. It queries whether the event is 3D, attaches 3D instances with `RuntimeManager.AttachInstanceToGameObject`, applies volume and pitch, schedules delay through the Opsive Scheduler, and tracks instances per GameObject for stop and cleanup. Finished events are released on the configured cleanup interval, and instances associated with destroyed GameObjects are stopped and released.

The released source snapshot inspected for this page contains Ultimate Character Controller `3.3.3`, Opsive Shared `2.1.0`, FMOD for Unity `2.02.33`, and Unity `2022.3.62f3`. FMOD's [current Unity documentation](https://www.fmod.com/docs/2.03/unity/api.html) covers the `2.03` line and requires the FMOD for Unity major line to match the FMOD Studio project. The Opsive bridge has no declared cross-version guarantee, so record the tested FMOD/Ultimate Character Controller pair and rerun compilation, event resolution, stop behavior, and target-platform builds after either dependency changes.

---

<a id="page-ultimate-character-controller-integrations-fps-mesh-tool"></a>

# FPS Mesh Tool

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/fps-mesh-tool/)

Use [FPS Mesh Tool](https://assetstore.unity.com/packages/tools/modeling/fps-mesh-tool-28006?aid=1100lGdc) when a third-person skinned character mesh should be processed into a first-person-compatible prefab for an Ultimate Character Controller character that needs separate first-person rendering or body-part visibility.

## Prepare the source character

1. Back up the project and keep the unmodified source model and prefab.
2. Verify the source rig, Avatar, materials, blend shapes, and Animator in a normal Unity scene.
3. Build and test the Ultimate Character Controller character in third person before processing the mesh.
4. Open **Window > FPS Mesh Tool** and follow the tool's current workflow to create its processed prefab and generated mesh/material assets.

FPS Mesh Tool owns mesh processing. Ultimate Character Controller owns the character hierarchy, First Person Objects, Item Slots, camera, States, and perspective switching. Do not process the only copy of a production prefab.

## Connect the processed result to Ultimate Character Controller

1. Build or update the Ultimate Character Controller character with **First Person** or **Both** perspective support.
2. Put the processed first-person result under the character's **First Person Objects** hierarchy according to the FPS Mesh Tool integration workflow.
3. Match Item Slot IDs with the Character Item prefabs and the visible arms/body hierarchy.
4. Configure the intended first-person materials, shadows, hidden body parts, and first-person camera layers.
5. Build one simple item and verify equip, use, perspective switch, death, and respawn before converting the full loadout.

The current Ultimate Character Controller catalog routes to a provider video for this integration. Treat FPS Mesh Tool's installed UI and the package version used in the project as the authority for its processing options; Ultimate Character Controller does not ship the mesh-processing source in its integration folder.

## Verify in Play Mode

1. Switch between first and third person while idle and moving.
2. Confirm the first-person result has no missing renderer, doubled body, exposed hidden faces, pink material, or incorrect shadow.
3. Equip and use one item and confirm arms, item, and Animator remain aligned.
4. Test crouch, jump, camera pitch, death, and respawn for clipping or stale renderer state.
5. Make a target-platform build to verify generated meshes and materials are included.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Body parts appear twice in first person. | Check the original third-person renderer and processed first-person renderer visibility. | Give each perspective one intended visible renderer path. |
| The item or arms are offset. | Check First Person Objects hierarchy, Item Slot ID, Avatar, and Animator Controller. | Rebuild the hierarchy with matching slots and align the visible item under the correct first-person parent. |
| Materials are pink or shadows are wrong. | Check active render pipeline and the generated material/shader route. | Convert or regenerate materials for the active pipeline and retest in a build. |
| A later model import breaks the processed prefab. | Check whether the source mesh, bones, or generated assets were replaced. | Preserve generated assets and rerun the tool deliberately from the updated source model. |

## Related pages

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Common Character Setups](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/)
- [First Person Perspective Items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/first-person-perspective/)
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)

---

<a id="page-ultimate-character-controller-integrations-high-definition-render-pipeline"></a>

# High Definition Render Pipeline

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/high-definition-render-pipeline/)

Use the High Definition Render Pipeline (HDRP) support package when an Ultimate Character Controller Version 3 project runs in HDRP, especially when first-person arms and items must remain visible near walls without a second camera.

## Before you begin

- Back up or commit the project. Activating HDRP and converting materials can change many project assets.
- Install a released Ultimate Character Controller Version 3 package. Its Installer requires Unity 2021.3 or newer.
- Use the HDRP version supplied for the chosen Unity Editor. Unity couples Scriptable Render Pipeline major versions to Editor versions; do not select an arbitrary HDRP version because Ultimate Character Controller's minimum Unity version is satisfied.
- Make the character, Camera Controller, input, and one representative item work before converting the project. This gives you a known result to compare after the render-pipeline change.

The audited Ultimate Character Controller `3.2.0` source is in a Unity `2022.3.62f3` project, and the bundled HDRP shaders identify SRP `14.0.8`. Setup Manager does not enforce a maximum HDRP version: it detects HDRP's `CustomPassVolume` type and then imports the bundled support package. Treat a successful import as package detection, not as proof that an otherwise untested Unity, HDRP, and Ultimate Character Controller combination is compatible.

## Convert the project before importing Ultimate Character Controller support

Convert the base project first, then add the Ultimate Character Controller-specific assets. This keeps Unity's broad material conversion separate from the small Ultimate Character Controller support import.

1. In **Window > Package Manager**, install **High Definition RP** for the current Unity Editor.
2. Assign the HDRP Asset required by that Unity version and complete Unity's HDRP configuration checks. In HDRP 14, open **Window > Rendering > HD Render Pipeline Wizard**, select **HDRP**, and select **Fix All**.
3. Convert compatible Built-in Render Pipeline materials with **Edit > Rendering > Materials > Convert All Built-in Materials to HDRP**, or convert a controlled selection with **Convert Selected Built-in Materials to HDRP**.
4. Repair custom shaders and materials manually. Unity's converter does not convert every custom shader, particle shader, height-mapped material, or read-only package material.
5. Open a representative scene and confirm that its environment, character, items, effects, and UI render without pink materials or shader errors before importing the Ultimate Character Controller HDRP support package.

Follow Unity's [HDRP 14 conversion guide](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@14.0/manual/Upgrading-To-HDRP.html) when using Unity 2022.3. For another Unity release, use the matching HDRP manual because menu labels and upgrade tools can change.

## Import the HDRP support package

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and select **Project**.
2. Under **Render Pipeline**, select **HDRP** and select **Import**. If HDRP has not compiled, Setup Manager shows **HDRP Not Imported** and does not import the integration.
3. Confirm that `Assets/Opsive/UltimateCharacterController/Integrations/HDRP` contains **Overlay Pass**, **InvisibleShadowCasterHDRP**, and the supplied HDRP shader assets.
4. Drag **Overlay Pass** into the gameplay scene. The prefab contains a Global **Custom Pass Volume** that draws the Overlay layer, so keep one active instance in the loaded scene set rather than adding one per character or camera.

For a new project, **Update Buttons, Layers, and Render Pipeline** can import support for the already-active pipeline as part of the initial project update. Use the explicit **Render Pipeline > HDRP > Import** route when converting an existing project or reinstalling the support assets.

## Configure first-person overlay rendering

1. Select the camera with **Camera Controller** and expand **View Types**.
2. Select a first-person View Type, such as **First Person Combat**, and expand **Rendering**.
3. Set **Overlay Render Type** to **Render Pipeline**.
4. Keep **First Person Culling Mask** on the layer used by the first-person arms and items. The supplied setup uses **Overlay**.
5. Confirm that those first-person Renderers are on the same layer and that the normal scene **Culling Mask** does not render that layer as regular scene geometry.

![Camera Controller View Types with First Person Combat selected, First Person Culling Mask set to Overlay, and Overlay Render Type set to Render Pipeline](https://opsive.com/wp-content/uploads/2021/01/ViewTypeRPRenderType.png?v=da97892b2578)

Changing between **Second Camera** and **Render Pipeline** updates the other first-person View Types on the same Camera Controller. In **Render Pipeline** mode, Ultimate Character Controller removes the generated child first-person camera and temporarily adds **First Person Culling Mask** to the main camera while first person is active. The **Overlay Pass** then draws those objects with cleared depth so nearby scene geometry does not cut through them.

## Match the renderer and material setup

| Area | HDRP requirement | Expected result |
| --- | --- | --- |
| First-person arms and items | HDRP-compatible materials, Renderers on the Overlay layer, and **Cast Shadows** set to **Off** | The overlay remains visible near walls without adding a duplicate set of shadows. |
| Both first- and third-person perspectives | **Perspective Monitor > Invisible Material** uses **InvisibleShadowCasterHDRP** | The hidden third-person mesh can keep its intended shadow while the first-person mesh supplies the visible arms and item. |
| First-person-only character | Apply **InvisibleShadowCasterHDRP** to the third-person head, arms, body, or item Renderers that must be hidden | The first-person camera does not see unwanted third-person geometry. |
| Object Fader | The material supports transparency and **Color Property Name** matches its alpha-bearing color; standard HDRP materials use `_BaseColor` | Character and obstruction fades change alpha instead of turning pink or remaining opaque. |
| Surface Manager texture lookup | **Main Texture Property Name** matches the material's base texture; standard HDRP Lit uses `_BaseColorMap` | Texture-based Surface Type lookup reads the intended texture. |
| Ultimate Character Controller Surface Effect decals | A prefab with **MeshFilter**, **Renderer**, and an HDRP-compatible material | Impact marks and footprints spawn, fit the hit surface, and can be weathered by **Decal Manager**. |

The current Setup Manager initializes non-Built-in projects with `_BaseColor` for Object Fader and `_BaseMap` for Surface Manager. `_BaseMap` is the normal URP base texture name, while standard HDRP Lit uses `_BaseColorMap`; update **Surface Manager > Main Texture Property Name** when using HDRP Lit. Custom shaders can use different property names, so inspect the material rather than copying either value blindly.

Object Fader also needs its surface-mode fields to match the shader. Setup Manager supplies `_Surface` and `1` for non-Built-in pipelines, but standard HDRP shaders expose different internal surface properties. Follow the material-focused checks on [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/) and verify an actual fade before applying the settings to every material.

Ultimate Character Controller's **Decal Manager** does not spawn HDRP **Decal Projector** components. It places and pools a mesh decal prefab, checks the mesh corners against the hit surface, and fades its Renderer material. An HDRP Decal Projector prefab is therefore not a drop-in replacement for a prefab assigned to **Surface Effect > Decals**. Use an HDRP-compatible mesh material, then test both spawning and weathering.

## Verify in Play Mode

1. Enter Play Mode in a scene containing one active **Overlay Pass** and start in first person with an item equipped.
2. Move the arms and item close to a wall. They should remain fully visible, while scene geometry keeps normal depth and no child first-person camera is required.
3. Inspect the Game view for duplicated shadows. The third-person shadow can remain, but the first-person arms and item should not add a second shadow.
4. If both perspectives are available, switch to third person and back several times. The correct body should be visible in each perspective and the invisible shadow material should not appear as visible geometry.
5. Test an Object Fader material in third person. It should become transparent and restore its original material state.
6. Trigger one Surface Effect that uses a decal and one that resolves a Surface Type from a texture. The decal should render with its HDRP material, and the expected surface effect should play.
7. Enable one obvious HDRP post-processing override. It should affect the combined scene and first-person objects through the main camera.
8. Repeat the checks in a development build on every supported graphics API. A clean Scene view is not proof that the gameplay camera or player build uses the same render path.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| **HDRP Not Imported** appears after selecting **Import**. | HDRP may be installed but not compiled, or the active package may not expose `CustomPassVolume`. | Finish the Unity HDRP setup, resolve the first Console error, and reopen Setup Manager before importing again. |
| First-person arms or items clip into walls. | **Overlay Pass**, **Overlay Render Type**, the Overlay layer, or **First Person Culling Mask** is missing. | Import the support package, keep one active **Overlay Pass**, select **Render Pipeline**, and restore the expected layer masks. |
| First-person objects disappear entirely. | Their Renderer layer may not be included in **First Person Culling Mask**, or their shader may not render in the HDRP Custom Pass. | Restore the Overlay layer and test one standard HDRP-compatible material before repairing custom shaders. |
| Arms, items, or scene objects are pink. | A Built-in or custom shader was not converted, or the bundled Ultimate Character Controller HDRP shader is from an unverified SRP generation. | Use a material supported by the installed HDRP version. Reimport the matching Ultimate Character Controller support assets and validate the exact Unity, HDRP, and Ultimate Character Controller combination before upgrading production. |
| The view has duplicate first-person shadows. | One or more first-person Renderers still cast shadows. | Set **Cast Shadows** to **Off** on every Renderer under the first-person object hierarchy. |
| The third-person body is visible in first person or stops casting the intended shadow. | **Invisible Material** is absent, belongs to another render pipeline, or was not applied to a first-person-only body's hidden Renderers. | Assign **InvisibleShadowCasterHDRP** through **Perspective Monitor**, or apply it to the required hidden third-person Renderer materials. |
| Object Fader changes no alpha. | Its color or surface-mode property names do not exist on the HDRP shader, or the material is not configured for transparency. | Match the fields to the actual shader and confirm one material can fade before broadening the setup. |
| Surface effects use the fallback type on textured objects. | **Main Texture Property Name** may still be `_BaseMap` while the HDRP material uses `_BaseColorMap` or a custom name. | Enter the material's real base texture property on **Surface Manager** and repeat the representative impact. |
| An Ultimate Character Controller decal does not spawn or fade. | The assigned prefab may use an HDRP Decal Projector instead of the required mesh and Renderer, or its material may not support HDRP transparency. | Use a mesh decal prefab with **MeshFilter**, **Renderer**, and a compatible material; then test the Decal Manager limit and weathering path. |
| The overlay renders twice or produces unexpected ordering. | More than one active **Overlay Pass** may exist in additive scenes, or another Custom Pass may share the same stage. | Keep one Ultimate Character Controller Overlay Pass in the loaded scene set and review the priorities and injection points of other HDRP Custom Pass Volumes. |

## Related tasks

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [First Person View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/included-view-types/first-person/)
- [Post Processing](https://opsive.com/support/documentation/ultimate-character-controller/camera/post-processing/)
- [Object Fader](https://opsive.com/support/documentation/ultimate-character-controller/camera/object-fader/)
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)
- [Surface Manager](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/surface-manager/)
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)

## Developer and compatibility notes

The released Setup Manager detects HDRP by looking for `UnityEngine.Rendering.HighDefinition.CustomPassVolume`. It maintains the `ULTIMATE_CHARACTER_CONTROLLER_HDRP` compile symbol for the active build target and imports the bundled `HDRP.unitypackage`; it does not install HDRP, select an HDRP Asset, run Unity's material converter, or validate a semantic HDRP version range.

The bundled **Overlay Pass** is a Global `CustomPassVolume` with a Draw Renderers pass filtered to Ultimate Character Controller's Overlay layer. It targets the camera color and depth buffers, clears depth for the overlay draw, and requests the material's `Forward` pass. Custom first-person shaders must therefore be compatible with the installed HDRP Custom Pass path as well as render normally in HDRP.

In **Render Pipeline** mode, the first-person View Type includes its **First Person Culling Mask** in the main camera only while first person is active. Switching away removes that mask. This is why the HDRP route can render the scene and first-person overlay through one camera, and why missing layer or material support appears as invisible arms rather than as a missing child camera.

Unity 2022.2 and 2022.3 pair with SRP 14.x. The audited Ultimate Character Controller support shaders were generated for SRP `14.0.8`, but the Setup Manager has no version gate and the inspected project does not prove every later HDRP generation. Record the Unity, HDRP, and Ultimate Character Controller versions that pass this page's Play Mode and build checks, and repeat them after changing any member of that set.

---

<a id="page-ultimate-character-controller-integrations-horse-animset-pro"></a>

# Horse Animset Pro

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/horse-animset-pro/)


Use the [Horse Animset Pro](https://assetstore.unity.com/packages/3d/characters/animals/horse-animset-pro-riding-system-79902?aid=1100lGdc) generic integration when a visible Ultimate Character Controller rider should mount a Malbers horse, give Horse Animset Pro ownership of movement and mounted animation, then return to normal Ultimate Character Controller control after dismounting.

## Compatibility boundary

Horse Animset Pro and its Ultimate Character Controller bridge are maintained and distributed by Malbers Animations. They are not included in the Ultimate Character Controller package or installed through the Ultimate Character Controller Integrations Manager.

| Audited evidence | What it establishes |
| --- | --- |
| Ultimate Character Controller `3.2.0` | The Ultimate Character Controller release targeted by this guide. |
| Installed Horse Animset Pro rider source `4.4.2a` | The `MRider` behavior and Inspector workflow described below. |
| Malbers generic download labeled `HAP (4.4.2) UCC (3.0.8) Generic Integration` | The scene, prefabs, event, and Animator Controller audited for this workflow. Malbers' integration index describes this route as Ultimate Character Controller `3.08+`. |
| The older `Ride HAP.cs` bridge and its embedded Ultimate Character Controller `3.0.3` installer | A legacy implementation. Do not combine it with the generic bridge or import its old Ultimate Character Controller installer into an Ultimate Character Controller 3.2.0 project. |

The generic download does not declare a maximum Ultimate Character Controller version and does not explicitly name Ultimate Character Controller 3.2.0. The `3.08+` label is therefore not a blanket compatibility matrix. Import and validate the bridge in a copy or source-controlled branch of the actual project whenever Ultimate Character Controller, Horse Animset Pro, Cinemachine, or the bridge changes.

## Before you begin

- Install and test Ultimate Character Controller 3.2.0, including its required project layers, before adding the bridge.
- Install and test [Horse Animset Pro](https://assetstore.unity.com/packages/3d/characters/animals/horse-animset-pro-riding-system-79902?aid=1100lGdc) by itself. The horse must already move through the Malbers Animal Controller before Ultimate Character Controller is connected.
- Use a Humanoid Ultimate Character Controller rider with a visible third-person model, Animator, root Rigidbody, and main character collider. The official generic integration also requires the Ultimate Character Controller character to have a ragdoll.
- If the supplied **Mount Camera** and Cinemachine prefabs will be used, install the Cinemachine dependency required by the installed Horse Animset Pro release before importing the bridge. The generic package does not pin a Cinemachine version.
- Make project-owned copies of any Animator Controller or prefab that will be edited.

## Install the generic bridge

1. Download the package from Malbers' [Ultimate Character Controller 3.0.8 generic integration page](https://malbersanimations.gitbook.io/animal-controller/annex/integrations/opsive-integration-1). Choose the download whose label matches the installed Horse Animset Pro generation; do not substitute the similarly named legacy Ultimate Character Controller 3.0.3 integration.
2. Import in this order: Ultimate Character Controller 3.2.0, Horse Animset Pro, the required camera dependency, then the generic integration package. Allow Unity to compile after each product.
3. If an older integration is already present under `Assets/Malbers Animations/Horse AnimSet Pro/Integrations/Ultimate Character Controller`, inventory its scenes, prefabs, and `RideHAP` references before importing. A Unity package import does not delete obsolete assets. Keep one configured runtime route, and remove legacy components or source only after confirming that no project prefab or scene still references them.
4. Do not import `UltimateCharacterController3.0.3.unitypackage` or `UltimateCharacterController2.4.9.unitypackage` if either appears inside an older Horse Animset Pro installation. Keep the project's installed Ultimate Character Controller 3.2.0 package.
5. After import, inspect the supplied **HAP + Ultimate Character Controller new** scene, **Horse UCC** prefab, **Opsive Camera** prefab, **Mount Camera** prefab, **Opsive Mount** event, and **Demo HAP** Animator Controller. Resolve missing scripts and the first Console error before copying anything into a production scene.

The generic package is asset-based: it supplies a reference scene, prefabs, an event asset, and an Animator Controller. It does not add a `RideHAP` ability or another Ultimate Character Controller ride script.

## Configure the Ultimate Character Controller rider

1. Open **Tools > Opsive > Ultimate Character Controller > Character Manager** and build or update the playable Humanoid character with **Animator** and **Ragdoll** enabled. If the character already has a complete ragdoll, verify it instead of building a second one.
2. Confirm that the character walks, turns, animates, and uses its camera before adding Horse Animset Pro.
3. Add **MRider** to the same GameObject as the rider's **Animator** and root **Rigidbody**. The generic reference scene keeps Ultimate Character Controller's character components on this object as well; if the production hierarchy differs, compare every reference with the reference scene instead of relying on automatic lookup.
4. In **MRider**, keep **Parent to Mount** enabled as in the generic scene. Assign **Animator**, **Rigid Body**, **Rider's Root**, **Main Collider**, and the Horse Animset Pro **Collider Modifier** profile. The Main Collider must be the non-trigger collider that enters a horse's Mount Trigger.
5. Enable **Disable Components** and populate **Disable List** explicitly. The audited generic scene disables these six Ultimate Character Controller roles while mounted:
   - **Ultimate Character Locomotion Handler**
   - **Ultimate Character Locomotion**; the pinned reference scene may display its serialized migration component as **Legacy Character Locomotion**
   - **Character IK**
   - **Character Foot Effects**
   - **Perspective Monitor**
   - the active Opsive player-input implementation
6. For Ultimate Character Controller 3.2.0, use **Player Input Proxy > Player Input** to identify the concrete input behavior for the last entry, such as **Unity Input**, **Unity Input System**, or **Rewired Input**. Do not retain a missing reference copied from the Ultimate Character Controller 3.0.8 scene.
7. Do not leave **Disable List** empty. In the audited `MRider` source, an empty list disables every other Behaviour on the MRider GameObject while mounting, which can turn off unrelated Ultimate Character Controller systems.
8. Do not add Ultimate Character Controller's native **Ride** ability or the legacy **RideHAP** ability. The generic bridge uses `MRider` directly. The required Ultimate Character Controller **Ragdoll** ability is a separate prerequisite and remains in the character's normal ability list.

### Add the mounted Animator layer

1. Duplicate the rider's working Animator Controller and assign the copy to the Animator.
2. Select the MRider component. If the controller has no `Mounted` layer, select **Add Mounted Layer**.
3. Confirm that one `Mounted` layer was added and that the Horse Animset Pro parameters were merged into the controller. The button loads the `Layers/Mount v2` controller from Horse Animset Pro and edits the assigned controller in place.
4. Use the imported **Demo HAP** controller to validate the reference scene, not as an automatic replacement for a production controller with custom Ultimate Character Controller item and ability animation.

If **Add Mounted Layer** is not shown, MRider must be able to find an Animator on the same GameObject, and that Animator must use an editable Animator Controller. An Animator Override Controller or an unassigned runtime controller cannot receive the layer through this button.

## Configure the horse and cameras

1. Start with the imported **Horse UCC** prefab, or compare an existing Horse Animset Pro horse against it.
2. On a custom horse, verify the Malbers **Animal** (`MAnimal`) and **Mount** components. Assign **Mount > Mount Point** to the transform that anchors the seated rider.
3. Keep at least one child **Mount Trigger** with a trigger collider. Assign its parent Mount reference, mount-side ID, dismount-side ID, and whether that location may be used to dismount. MRider can mount only after its Main Collider enters one of these triggers.
4. Test the horse's own walk, turn, stop, and input without a rider. Horse movement remains owned by Horse Animset Pro after the rider mounts.
5. For the supplied camera handoff, keep one **Opsive Mount** event asset. In the generic scene, **MRider > On Start Mounting** invokes it with `true`, and **On End Dismounting** invokes it with `false`.
6. Use the imported **Opsive Camera** listener to deactivate the Ultimate Character Controller camera while mounted and restore it after dismount. Use **Mount Camera** to activate and target the horse camera, or replace both listeners with an equivalent project-owned handoff. Do not leave both camera pipelines active.

The provided Mount Camera contains references to Malbers' Cinemachine camera prefabs. A missing Cinemachine script must be resolved with the dependency that matches the installed HAP release, or the supplied camera handoff must be replaced; it is not a reason to downgrade Ultimate Character Controller.

## Configure mount and horse input

### Use Horse Animset Pro MInput

1. Open the MRider component menu and select **Create Mount Inputs**. The command adds **MInput** when it is absent.
2. Inspect the three generated rows:
   - `Mount` uses a button-down input and calls `MRider.MountAnimal()`. The audited source creates it on `F`, disables it when mounting starts, and enables it when dismounting ends.
   - `Dismount` calls `MRider.DismountAnimal()` after a `0.2` second long press. It starts inactive, enables when mounting ends, and disables when dismounting starts.
   - `Call Mount` uses a button-down input and calls `MRider.CallAnimalToggle()`.
3. Remap these prototype keys and activation rules for the project. Ensure one press cannot unintentionally run both Mount and Call Mount.
4. Configure the Horse Animset Pro input that drives `MAnimal` while riding. Ultimate Character Controller movement actions do not automatically drive the horse.

### Use project-owned input

Bind the project's input events to `MRider.MountAnimal()` and `MRider.DismountAnimal()` instead of creating an Ultimate Character Controller ride ability. For Unity Input System or another action-map workflow, keep separate on-foot and riding ownership: disable the gameplay map when mounting finishes, enable the horse's riding map, then reverse that handoff after dismounting. The generic package's Malbers **MInput** rows do not automatically edit an Ultimate Character Controller action asset or switch Ultimate Character Controller action maps.

Whichever route is chosen, only one system should read movement at a time. Ultimate Character Controller owns on-foot movement; Horse Animset Pro owns mounted movement.

## Editor checkpoint

Before entering Play Mode, verify all of the following:

- The Console is clear, and the generic integration scene contains no missing scripts or missing serialized references after Ultimate Character Controller migration.
- MRider, Animator, Rigid Body, Rider's Root, Main Collider, and Collider Modifier references are assigned.
- The rider controller contains exactly one `Mounted` layer and the parameters added by Horse Animset Pro.
- **Disable Components** is enabled and **Disable List** contains six valid project components, including the Ultimate Character Controller 3.2.0 input implementation rather than a stale Ultimate Character Controller 3.0.8 reference.
- The Ultimate Character Controller ability list contains Ragdoll but contains neither **RideHAP** nor native **Ride** for this workflow.
- The horse has Animal, Mount, a Mount Point, and at least one enabled Mount Trigger.
- One mount input path and one horse movement input path are active.
- The `Opsive Mount` event has one deliberate Ultimate Character Controller-camera listener and one deliberate mounted-camera listener, or the project has an equivalent camera handoff.

## How it runs

When the rider's Main Collider enters a Mount Trigger, Horse Animset Pro assigns that Mount and allows `MountAnimal()` to start. At the start of mounting, MRider disables the rider colliders, parents Rider's Root to the horse's Mount Point when **Parent to Mount** is enabled, disables every Behaviour in the explicit Disable List, and sends **On Start Mounting**. The generic event handoff disables the Ultimate Character Controller camera and enables the mount camera.

At the end of mounting, MRider marks the rider as on the horse, synchronizes rider Animator values from the Malbers Animal, reconnects the mounted collider, and enables the Dismount input. Horse Animset Pro then owns horse movement and rider alignment; Ultimate Character Controller's locomotion and input behaviors remain disabled.

Dismounting unparents Rider's Root at the start of the transition. At the end, MRider restores its Rigidbody settings, main and child colliders, every Behaviour in Disable List, and the Mount input, then sends **On End Dismounting**. The camera listener returns control to Ultimate Character Controller. A forced interruption that never reaches the end callback needs equivalent project cleanup.

## Verify in Play Mode

1. Start on foot and confirm Ultimate Character Controller movement, look input, abilities, and the Ultimate Character Controller camera work normally.
2. Approach one Mount Trigger with the rider's Main Collider. In **MRider > Debug**, confirm **Can Mount** becomes enabled and the expected **Mount Trigger** and current Mount are shown.
3. Press Mount. During the transition, confirm **Is Mounting** is enabled, the explicit Ultimate Character Controller Disable List is disabled, the Ultimate Character Controller camera turns off, and the mounted camera turns on.
4. Wait for the transition to complete. Confirm **Mounted**, **Is on Horse**, and **Is Riding** are enabled, the rider is aligned to Mount Point, and the Animator is in the `Mounted` layer.
5. Walk forward and backward, turn, accelerate, and stop with the Horse Animset Pro controls. The horse should move, while on-foot Ultimate Character Controller movement and look input should not move or rotate the rider independently.
6. Request a dismount from a valid Mount Trigger. With the generated default, hold Dismount for at least `0.2` seconds. Confirm **Is Dismounting** becomes enabled and the rider unparents at the intended side.
7. After the transition, confirm the Ultimate Character Controller locomotion and input behaviors, Rigidbody settings, colliders, Ultimate Character Controller camera, and Mount input are restored. Ordinary on-foot movement and abilities should work immediately.
8. Repeat on both sides of the horse, on a slope, after changing camera perspective, and after rapidly releasing movement before dismount. No second camera or Transform writer should remain active.
9. Test every supported forced exit, including rider death, horse destruction, scene loading, or a network ownership change. Each path must restore Ultimate Character Controller components, input, colliders, and the local camera exactly once.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports missing Ultimate Character Controller, Malbers, or camera types after import | The bridge may have been imported before its dependencies, legacy `RideHAP` source may target a different Ultimate Character Controller API, or the supplied camera may reference an absent Cinemachine release | Install and compile Ultimate Character Controller 3.2.0, HAP, and the matching camera dependency first. Remove only the unreferenced incompatible legacy route, then reimport the generic package. |
| The generic scene has missing references after import | The downloaded scene is serialized against Ultimate Character Controller 3.0.8 and may contain old component references | Open the scene in the backed-up test project, allow Ultimate Character Controller migration to finish, then replace every missing Disable List or camera reference with the Ultimate Character Controller 3.2.0 equivalent before saving a project-owned copy. |
| **Add Mounted Layer** is absent | MRider may not share a GameObject with Animator, the Animator Controller may be unassigned, or it may be an Animator Override Controller | Put MRider with the Animator used by the rider, assign an editable project-owned Animator Controller, and reopen the component. |
| Mount input does nothing and **Can Mount** stays disabled | The rider's Main Collider may not be entering an enabled Mount Trigger, or the trigger may not reference the intended Mount | Assign MRider's Main Collider, correct the trigger collider and layers, and assign the Mount before testing the input again. |
| Mount starts but never reaches **Is Riding** | The `Mounted` layer, its HAP state behaviors, parameters, or compatible rider clips may be absent | Add the layer from MRider to the production controller or compare it with **Demo HAP**, then restore the required HAP parameters and transitions. |
| The rider jitters, slides, or separates from the horse | Ultimate Character Controller and HAP may both be moving the rider because Disable List is incomplete, or native Ride/RideHAP is also active | Restore the six explicit Disable List roles and remove the competing Ride implementation. Let MRider own rider alignment while mounted. |
| The horse does not respond after mounting | The Horse Animset Pro riding input or action map may be inactive even though Ultimate Character Controller input was disabled | Enable and map the HAP riding input after mount completion, and confirm `MAnimal` responds before changing Ultimate Character Controller settings. |
| The camera disappears or two cameras fight | `Opsive Mount` may be missing a listener, the bool may be inverted incorrectly, or both camera owners may remain active | Copy the reference event wiring or implement one project handoff: Ultimate Character Controller camera off and mount camera on at start mount, then the reverse at end dismount. |
| Dismount input does nothing | The generated Dismount row may still be inactive, the long press may be shorter than `0.2` seconds, or no valid dismount trigger may be available | Finish the mount transition, hold the configured input, and add or enable a Mount Trigger that permits dismounting. |
| Ultimate Character Controller remains frozen after dismount | **On End Dismounting** may not have run, or a stale or missing component reference may prevent the intended restoration | Confirm the transition reaches MRider's end state, then restore the explicit Disable List references and add cleanup for every forced-interruption path. |
| The rider collides with the horse or dismounts in a bad pose | Main Collider, Collider Modifier, Mount Point, or trigger-side IDs may not match the rider and horse scale | Copy the corresponding references from the working generic scene, then resize and reposition the collider profile, Mount Point, and left/right triggers for the production models. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/)
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Native Ride ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/ride/)
- [Rideable](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/rideable/)
- [Malbers' general Horse Animset Pro integration guide](https://malbersanimations.gitbook.io/animal-controller/annex/integrations/general-hap-integration)

## Integration ownership and APIs

The generic package contains no Ultimate Character Controller `Ability` implementation. Horse Animset Pro's `MRider` owns the transition and rider root while mounted, its `Mount` and `MAnimal` components own the horse, and its input owns horse movement. Ultimate Character Controller is paused by disabling selected Behaviors; the `Opsive Mount` event performs only the sample's camera handoff.

The primary project integration points are:

- `MRider.MountAnimal()` and `MRider.DismountAnimal()` for explicit mount requests.
- `MRider.CallAnimalToggle()` for the optional call-mount input.
- **On Start Mounting**, **On End Mounting**, **On Start Dismounting**, and **On End Dismounting** for input, camera, item, UI, and interruption handling.
- MRider's runtime state, including **Can Mount**, **Can Dismount**, **Mounted**, **Is on Horse**, **Is Mounting**, **Is Riding**, **Is Dismounting**, Current Mount, and Mount Trigger, for diagnostics rather than a second movement controller.

The normal end-dismount callback restores the objects MRider owns: its Rigidbody and collider settings and every Behaviour in its Disable List. The listeners created by **Create Mount Inputs** then re-enable Mount input, and the generic scene's event listener restores the Ultimate Character Controller camera. The generic package does not define Ultimate Character Controller inventory policy. Use MRider events to unequip, hide, or constrain items before mounting and restore them after a completed or forced dismount.

The package also contains no Ultimate Character Controller Save System adapter. Persist a stable rider identity, mount identity, ownership, and a safe transform deliberately. Restoring the rider already mounted or midway through a transition requires project code; loading into a normal dismounted state is safer unless the complete MRider and horse state is reconstructed.

No network authority or replication layer is supplied. A multiplayer implementation must arbitrate one rider per mount, give one peer authority over rider and horse movement, synchronize mount and dismount transitions, and run camera switching only for the local owner. Do not let two peers, or Ultimate Character Controller and HAP on one peer, write the same rider Transform.

The legacy `RideHAP` class is a different bridge. It is a manually started and stopped Ultimate Character Controller Ability that listens to MRider events and copies the HAP rider pose into Ultimate Character Controller while disabling Ultimate Character Controller input, gravity, and collision. Those details explain old scenes, but they are not setup instructions for the generic package described on this page.

---

<a id="page-ultimate-character-controller-integrations-incontrol"></a>

# InControl

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/incontrol/)


Use the [InControl](https://assetstore.unity.com/packages/tools/input-management/incontrol-14695?aid=1100lGdc) integration when InControl should translate keyboard, mouse, controller, or touch input while Ultimate Character Controller continues to run the character, camera, abilities, and items. The integration replaces the character's Opsive Unity input component with **InControl Input**; it does not configure InControl's devices, bindings, UI navigation, or multiplayer joining for you.

## Before you begin

- Start with an Ultimate Character Controller Version 3 character that moves, looks, jumps, and uses one representative item before changing its input provider.
- Install [InControl from the Unity Asset Store](https://assetstore.unity.com/packages/tools/input-management/incontrol-14695?aid=1100lGdc) first and complete its own project setup. When using InControl's Unity Input Manager backend, its documented menu is **InControl > Setup Input Manager**. Add its runtime manager with **GameObject > InControl > Manager**.
- Commit or back up the project before importing the bridge or regenerating `ProjectSettings/InputManager.asset`.
- Use only one input provider for the character. Keeping Opsive **Unity Input**, Opsive **Unity Input System**, and **InControl Input** active together can duplicate actions or leave **Player Input Proxy** pointing to the wrong component.

The bundled Ultimate Character Controller Version 3 integration assembly declares no minimum or maximum InControl version. The Asset Store listed InControl `1.8.11` when this page was verified, but that current listing is not a compatibility guarantee for every Ultimate Character Controller Version 3 release. Import the installed pair, resolve compilation first, and run the Play Mode checks below before updating a production scene.

## Import the integration

1. Install InControl and wait for Unity to finish compiling.
2. Open **Tools > Opsive > Ultimate Character Controller > Integrations Manager**, select **Available Integrations**, find **InControl**, and use its **Integration** action to open the current distribution route.
3. Sign in to [Opsive Downloads](https://opsive.com/downloads/), download the InControl integration, and import it with **Assets > Import Package > Custom Package**. The bridge is not in the base product's Integrations folder before download; importing it creates `Assets/Opsive/Shared/Integrations/InControl`. Import InControl first because the bridge assembly compiles against its types.
4. Confirm that Unity has added `Assets/Opsive/Shared/Integrations/InControl` and that the Console has no missing `InControl` namespace, type, or assembly errors.

## Replace the character input provider

1. In the Hierarchy, expand the character and select its `<CharacterName>Input` child, such as `AtlasInput`.

   ![The AtlasInput child selected beneath the Atlas character with its legacy Unity Input component before replacement.](https://opsive.com/wp-content/uploads/2020/08/UnityInputGameObject.webp?v=3efba5fe6ff5)

2. Remove the existing Opsive **Unity Input** component. If the character used Unity's Input System, remove the Opsive **Unity Input System** component and disable or remove the Unity **Player Input** component that belonged to that route. Keep the input GameObject and the character's **Player Input Proxy**.
3. On the same input GameObject, select **Add Component**, search for **InControl Input**, and add it.
4. On the character, assign **Player Input Proxy > Player Input** to the new **InControl Input** component.
5. Ensure the scene contains the **InControl Manager** created by **GameObject > InControl > Manager**.
6. For a first test, set **InControl Input > Bindings Type** to `Opsive.Shared.Integrations.InControl.SampleBindings`.
7. If the Setup Manager previously added Ultimate Character Controller **Virtual Controls** or **On Screen Controls**, disable or remove that input UI while testing InControl. The supplied bridge does not translate those controls; use InControl's touch controls and include them in the selected bindings instead.

## Configure the bindings

The sample bindings are a starting point for a clean integration test. They map common Ultimate Character Controller names such as `Horizontal`, `Vertical`, `Mouse X`, `Mouse Y`, `Controller X`, `Controller Y`, `Jump`, `Fire1`, `Fire2`, `Reload`, `Action`, item selection, and perspective switching to keyboard, mouse, and controller controls.

For a production game, create a class that inherits InControl's `PlayerActionSet` and implements the integration's `IBindings` interface, then enter its full namespace and class name in **Bindings Type**. The class must:

- create its actions in `CreateBindings()`;
- return the matching action from `GetInputControl(string name)`; and
- use the exact names requested by the Ultimate Character Controller ability, item action, camera, or movement setting.

Follow InControl's [binding actions to controls](https://www.gallantgames.com/pages/incontrol-binding-actions-to-controls) workflow for the bindings themselves. Ultimate Character Controller reads each axis as one float, so build movement and look axes with InControl one-axis actions. A `TwoAxisInputControl` produces a warning and returns zero through this bridge; expose horizontal and vertical as separate one-axis controls instead.

The supplied **InControl Input** component enables **Disable Cursor** and **Enable Cursor With Escape** by default. This locks and hides the cursor while playing, releases it with Escape, and captures it again after a click outside UI. Disable or coordinate these options when a menu, pointer-driven game, or another camera system owns the cursor.

## Choose device, touch, and UI ownership

| Scenario | Recommended ownership |
| --- | --- |
| One local player | Leave the action set's InControl `Device` unassigned unless the game needs a fixed controller. InControl then chooses an active device when the action set is used. |
| Local split-screen | Give every character its own **InControl Input** component and binding instance, point each **Player Input Proxy** to its own component, and assign a different InControl device in code. The bridge has no **Player** or **Device** Inspector field and does not pair joining controllers. |
| Keyboard and mouse plus controller | Decide whether both should control the same player. The sample bindings include both, so copying them to multiple local players can make one keyboard control more than one character. |
| Touch controls | Use InControl's touch-control workflow and bind those controls to the same actions. Ultimate Character Controller's generated Virtual Controls and On Screen Controls target its Unity input providers, not this bridge. |
| Controller-driven menus | On the EventSystem, add **Add Component > Event > InControl Input Module** and disable or remove **Standalone Input Module**. By default this UI module reads InControl's current active device; per-player menus require their own deliberate action and ownership setup. |

See [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/) for camera, viewport, and HUD ownership. A second Camera Controller does not separate input devices.

## Verify in Play Mode

1. Enter Play Mode and confirm that the Console does not report **No bindings specified**, **No InControl Manager was found**, or an inability to create the configured `PlayerActionSet`.
2. Test movement and look with the intended keyboard, mouse, or controller. The character should respond once per input, and releasing an axis should return it to zero.
3. Test `Jump` and one representative ability or item action. The Ultimate Character Controller Inspector name and the binding name must produce the same action.
4. Press Escape and click back in the Game view to verify the intended cursor behavior. Open and close any full-screen menu and confirm gameplay input remains disabled only while that menu owns it.
5. If the game uses touch, test the InControl touch layout on the target device rather than relying on mouse simulation alone.
6. For split-screen, test every controller separately. One device should move only its assigned character, and each camera and HUD should continue following that same character after respawn and a scene reload.
7. Make a development build for the target platform and repeat the controller attach, detach, pause, and reconnect flows supported by that platform.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports missing `InControl` namespaces or assembly references. | The bridge was imported before InControl, or the installed InControl package does not provide the referenced runtime assembly. | Install InControl first, let it compile, then reimport the bundled Ultimate Character Controller Version 3 `InControl.unitypackage`. If the pair still fails, return to the last verified versions rather than editing assembly references blindly. |
| The Console reports **No bindings specified**. | **InControl Input > Bindings Type** is empty. | Enter the full type name, such as `Opsive.Shared.Integrations.InControl.SampleBindings`. |
| The Console reports that it cannot create the action set or that it does not implement `IBindings`. | The type name is misspelled, cannot be resolved, or the class does not inherit `PlayerActionSet` and implement `IBindings`. | Correct the namespace and class name, fix compilation, and use a class that implements both required contracts. |
| The Console reports **No InControl Manager was found**. | No enabled `InControlManager` exists when **InControl Input** awakens. | Add it with **GameObject > InControl > Manager**, then reload the scene or re-enter Play Mode. |
| The character does not respond, but InControl sees the device. | **Player Input Proxy > Player Input** may be empty, reference the removed provider, or point to another character's input object. | Assign this character's **InControl Input** component and disable competing providers. |
| One ability fails while movement works. | Its requested input name is absent from `GetInputControl`, differs in spacing or capitalization, or was not created by `CreateBindings()`. | Add the exact Ultimate Character Controller input name to the binding map and retest that one action. |
| The Console warns that Ultimate Character Controller does not support `TwoAxisInputControl`. | A movement or look name returns an InControl two-axis action. | Return two separate one-axis controls, such as horizontal and vertical, through separate Ultimate Character Controller names. |
| One controller moves multiple characters. | Their action sets have no fixed `Device`, include the same devices, or share global keyboard and mouse bindings. | Assign a distinct device to each action set after it initializes, restrict included devices where appropriate, and remove shared keyboard bindings from device-exclusive players. |
| Gamepad navigation does not operate a menu. | The EventSystem still uses a different input module, or **InControl Input Module** has not been given the intended submit, cancel, and move actions. | Configure InControl's UI module separately; the Ultimate Character Controller character bridge does not install or bind it. |
| Actions fire twice. | More than one Opsive input provider remains enabled or two proxies reference the same provider. | Keep one provider per player and verify each **Player Input Proxy** reference. |

## Related pages

- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Virtual Controls](https://opsive.com/support/documentation/ultimate-character-controller/input/virtual-controls/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)

## Developer reference

`Opsive.Shared.Integrations.InControl.InControlInput` derives from Opsive's `PlayerInput`. During `Awake()` it resolves **Bindings Type**, creates that `PlayerActionSet`, verifies `IBindings`, calls `CreateBindings()`, and checks for an `InControlManager`. Button reads map to `IsPressed`, `WasPressed`, and `WasReleased`; axis reads accept `OneAxisInputControl.Value` or `RawValue`.

The `ActionSet` property exposes the created `PlayerActionSet`. Assign a local player's device only after **InControl Input** has initialized successfully:

```csharp
using InControl;
using Opsive.Shared.Integrations.InControl;

public static void AssignDevice(InControlInput playerInput, InputDevice device)
{
    playerInput.ActionSet.Device = device;
}
```

InControl also exposes `IncludeDevices` and `ExcludeDevices` on the action set when a game needs a broader ownership policy. The supplied Ultimate Character Controller bridge does not provide an Inspector for those lists, a controller-join flow, binding persistence or rebinding UI, an InControl UI module, or touch controls. Build those responsibilities with InControl and keep Ultimate Character Controller connected through the character's **Player Input Proxy**.

For API behavior and action-set lifetime guidance, see InControl's [PlayerActionSet reference](https://www.gallantgames.com/incontrol-api/html/class_in_control_1_1_player_action_set.html). The discontinued open-source edition is frozen at `1.4.4`; current feature development is distributed through the Asset Store, so do not treat the GitHub edition as a current substitute for the installed package.

---

<a id="page-ultimate-character-controller-integrations-juicy-actions"></a>

# Juicy Actions

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/juicy-actions/)

Use the [Juicy Actions](https://assetstore.unity.com/packages/slug/269711?aid=1100lGdc) integration when reusable Action assets should request Ultimate Character Controller behavior or react to Ultimate Character Controller events without creating a separate scene script for every sequence.

## Install the integration

1. Install Juicy Actions and verify one Action Executor directly.
2. Sign in to [Opsive Downloads](https://opsive.com/downloads/), download the Juicy Actions integration, and import `UltimateCharacterControllerJuicyActions.unitypackage`. The bridge does not exist in the base product's Integrations folder before this download; importing it creates the integration files in the project.
3. Let Unity compile, then search the Juicy Actions selector for an Ultimate Character Controller action such as **Set Character Ability**.
4. Put the Action Executor on an object with an explicit reference to the target Ultimate Character Controller character.

## Choose an action or event

- **Character actions:** Add Character Force, Adjust Character Item Amount, Remove Character Item, Spawn Character Item, Set Character Ability, Set Character Animator Parameter, Set Character Attribute, Set Character Movement Type, and Wait For Character Event.
- **UCC event triggers:** Ability Active, Attribute Change, Camera View Type, Damage, Death, Gameplay Input, Grounded, Item Equip, Item Pickup, Jump, Land, Movement Type, Object Impact, and Respawn.
- **Blackboard and Conditions:** Character Blackboard Populator and Character Conditional Helper expose project-selected Ultimate Character Controller values and predicates to Juicy Actions.
- **Extension points:** Juicy Actions Ability and Juicy Actions Module let an Ultimate Character Controller Ability or modular item action participate in an Action sequence.

## Build a first workflow

1. Create an Action Executor that sets one named character Attribute or starts one known Ability.
2. Run it and confirm Ultimate Character Controller accepts the request and produces the visible result.
3. Add a matching Ultimate Character Controller event trigger, such as **Action On Land**, to start a second Action sequence.
4. Stop or disable the owner and confirm subscriptions and waits are released.
5. Add item, camera, or movement operations only after the first ownership boundary is stable.

## Verify in Play Mode

1. Inspect the requested Ability, Attribute, item amount, movement type, or Animator parameter before and after the Action.
2. Force Ultimate Character Controller to reject an ability request and confirm the sequence takes its intended failure path.
3. Fire the selected event twice and confirm the Action does not register duplicate callbacks.
4. Test death, respawn, perspective changes, and scene reload.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Ultimate Character Controller actions are absent. | Check Juicy Actions, the bridge package, and compilation. | Install the dependency first, remove duplicate bridge files, and reimport. |
| An Action changes the wrong character. | Check the target reference and Blackboard population. | Assign the intended Ultimate Character Controller root explicitly before using dynamic lookup. |
| An ability request has no effect. | Check Ultimate Character Controller ability presence, index, blockers, and normal Can Start rules. | Configure the ability through Ultimate Character Controller first, then request that working ability from Juicy Actions. |
| An event fires more than once. | Check duplicate trigger components and lifecycle registration. | Keep one event owner and verify it unregisters when disabled or destroyed. |

## Related pages

- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/)
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/)

---

<a id="page-ultimate-character-controller-integrations-master-audio"></a>

# Master Audio

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/master-audio/)

Use the [Master Audio](https://assetstore.unity.com/packages/tools/audio/master-audio-2022-aaa-sound-212962?aid=1100lGdc) integration when character abilities, damage, items, footsteps, and impacts should play through Master Audio Sound Groups. Ultimate Character Controller components keep their normal **Audio Config** fields, while Master Audio owns Variations, pooled voices, buses, spatial settings, and most playback behavior.

The Audio Manager has one active module. Replacing it routes every Opsive Shared audio request in the scene through Master Audio, including sounds from another installed Opsive product.

## Supported package boundary

The current local integration project was verified with Ultimate Character Controller 3.3.3, Opsive Shared 2.1.0, Unity 2022.3.62f3, and Master Audio 2024 v1.0.3. The bridge does not declare a minimum or maximum Master Audio version, so this is a source-verified combination rather than a general compatibility range. Import the package offered for the released Ultimate Character Controller Version 3 product, then compile and test the workflow on this page before migrating all project audio.

Master Audio includes a small `MA_Opsive.unitypackage` in its third-party integrations folder. That older bridge routes by Audio Clip name and does not include the current **Master Audio Config**, **Variation**, or **Require Group Name** workflow. Use the current Opsive `MasterAudio.unitypackage` from the [Opsive Downloads page](https://opsive.com/downloads/) and do not import both bridges.

## Before you begin

1. Back up or commit the project before replacing the scene's global audio module.
2. Install Master Audio and allow Unity to finish compiling.
3. Add and configure the Master Audio GameObject by following the [Master Audio documentation](https://www.dtdevtools.com/docs/masteraudio/TOC.htm).
4. In Master Audio's [Group Mixer](https://www.dtdevtools.com/docs/masteraudio/GroupMixer.htm), create at least one Sound Group with a playable Variation. Confirm that this group plays before connecting Ultimate Character Controller.
5. Open **Tools > Opsive > Ultimate Character Controller > Integrations Manager**, find **Master Audio**, and follow its download route. If downloading separately, use the package offered for Ultimate Character Controller Version 3 on Opsive Downloads.
6. Import `MasterAudio.unitypackage` with **Assets > Import Package > Custom Package**. Master Audio must already compile because the bridge directly references its runtime types.

After import, **Master Audio Manager Module** and **Master Audio Config** should appear under **Assets > Create > Opsive > Audio**.

## Route Ultimate Character Controller audio through Master Audio

1. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager**.
2. Under **Manager Setup**, select **Add Managers** if the scene does not already contain the normal Ultimate Character Controller managers.
3. In the Hierarchy, select the `Game` GameObject and locate its **Audio Manager** component.
4. Use the included `MasterAudioManagerModule` asset, or create one with **Assets > Create > Opsive > Audio > Master Audio Manager Module**.
5. Assign that asset to **Audio Manager Module** on the Audio Manager.
6. Keep **Require Group Name** enabled for an explicit setup. Every migrated Ultimate Character Controller audio hook must then use a **Master Audio Config** with **Audio Group Name** assigned.

Disable **Require Group Name** only for a clip-name fallback workflow. In that mode the bridge resolves the Ultimate Character Controller Audio Clip and asks Master Audio for a Sound Group whose name exactly matches the clip. It still does not play that Audio Clip directly, so the matching Sound Group and Variation must exist.

## Connect a character damage sound

This example routes the Health component's damage response through a Sound Group named `Character Hurt`.

1. In Master Audio, create the `Character Hurt` Sound Group and add one or more Variations. Configure the group's spatial, distance, bus, and voice settings for a world-space character sound.
2. In the Project window, select **Assets > Create > Opsive > Audio > Master Audio Config** and name the asset `CharacterHurtMasterAudio`.
3. Set **Audio Group Name** to `Character Hurt`.
4. Leave **Variation** set to **(Random Variation)** to let Master Audio choose according to the Sound Group, or select one Variation for a fixed result. Select **[Type In]** only when the intended **Variation Name** cannot be listed.
5. Use the inherited Audio Modifier only for **Volume Override**, **Pitch Override**, or **Delay Override** when this Ultimate Character Controller use should differ from the Sound Group defaults.
6. Select the character and open **Health > Audio > Take Damage**.
7. Assign `CharacterHurtMasterAudio` to **Audio Config**.

With **Require Group Name** enabled, the inline **Audio Clips** list is not needed for this route because the Master Audio Sound Group supplies the Variations. Keeping source clips elsewhere can still make it easier to return to the default Opsive module later.

## Connect abilities, items, and surfaces

Use the same Master Audio Config pattern anywhere Ultimate Character Controller exposes **Audio Config** or an Audio Clip Set:

- Assign configs to an ability's **Start** and **Stop** Audio Clip Sets for short activation feedback or a long-running ability sound.
- Use **Health > Audio > Heal** and **Death** for separate character groups, and the Respawner's **Respawn** Audio Clip Set for return feedback.
- Assign configs to item actions and effects for firing, reloading, melee, magic, pickup, and other item sounds.
- On a Surface Effect, assign a Master Audio Config to **Audio > Audio Config** for footsteps, impacts, or collisions. Master Audio receives the originating transform when available, otherwise the world hit position.

Changing **Audio Manager Module** is global rather than per sound. Audit each Opsive Audio Config and Audio Clip Set after the switch. With **Require Group Name** enabled, a remaining standard Audio Config or inline clip cannot identify a Master Audio Sound Group and will be silent.

## Choose pooling, loops, fades, and movement behavior

Master Audio owns the Variation Audio Sources, pooling, Sound Group voice limits, buses, 2D or 3D spatial behavior, reverb, and loop rules. Configure those choices on the Master Audio Sound Group and its Variations, not on the inherited Ultimate Character Controller Audio Source fields.

- Configure loops on the Master Audio Variation. The bridge does not use the Ultimate Character Controller **Loop Override**.
- Configure Variation fade-in and natural fade-out behavior in Master Audio. An Ultimate Character Controller stop request is abrupt: the supplied bridge does not call Master Audio's fade methods.
- The bridge starts transform-based audio at the transform's current location but does not use Master Audio's follow-transform API. Short actions such as footsteps and weapon impacts are a natural fit. A long or looping 3D sound on a moving character needs a project-specific module or a separate Master Audio setup that follows the transform.
- Stopping an Ultimate Character Controller sound calls Master Audio's stop-all operation for the source transform. Other Master Audio sounds triggered by that same transform stop too. Use separate playback transforms or a custom module when independent long-running sounds must stop separately.

## Editor checkpoint

Before entering Play Mode, confirm that:

- Master Audio and the Opsive bridge compile without errors;
- the scene has one active Master Audio GameObject and one Opsive **Audio Manager**;
- **Audio Manager Module** references `MasterAudioManagerModule`;
- **Require Group Name** matches the explicit-config or clip-name fallback workflow;
- each explicit **Master Audio Config** has a valid **Audio Group Name**;
- a selected **Variation** belongs to that Sound Group, or random Variation selection is intentional;
- every referenced Sound Group has at least one playable Variation; and
- Master Audio owns the intended bus, voice, pooling, spatial, loop, and fade settings.

## Verify in Play Mode

1. Damage the character without killing it. Confirm that `Character Hurt` plays once and Master Audio shows the active voice in the expected Sound Group.
2. Repeat the damage several times. A random config should follow the Sound Group's Variation rules; a fixed **Variation** should remain consistent.
3. Trigger one ability or item sound and confirm that it also routes through Master Audio. This verifies that the Audio Manager module is global rather than Health-specific.
4. Walk across a configured surface or trigger a configured impact. Confirm that the sound uses the intended world position and 3D distance behavior.
5. Test one loop or delayed sound. Confirm that Master Audio, plus any supported volume, pitch, or delay override, produces the intended result.
6. Stop a long-running ability sound while another sound is active on the same character transform. Confirm whether the bridge's stop-all behavior is acceptable for that design.
7. Reload the gameplay scene and repeat one character and one surface or item sound to verify initialization order in the real scene.

## Saving and multiplayer

The integration redirects runtime playback; it does not add save data. Keep Sound Groups and Master Audio Config assets in source control. Save user volume, bus, or audio-option choices through the project's normal settings system or the corresponding Master Audio workflow.

The bridge calls the local Master Audio API and does not use `MasterAudioMultiplayerAdapter` or replicate sounds. An Ultimate Character Controller networking add-on can replicate the gameplay event, but the project must decide which client plays the resulting audio. Trigger it on the appropriate authority or receiving clients to avoid silence or duplicate playback. Master Audio's optional multiplayer packages are separate and must match the installed Master Audio release.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Importing the bridge creates `DarkTonic.MasterAudio` errors | Master Audio may not be installed or compiling before the Opsive scripts. | Install and compile Master Audio first, then reimport the current Opsive bridge. |
| **Master Audio Config**, **Variation**, or **Require Group Name** is missing | The project may contain Master Audio's bundled `MA_Opsive.unitypackage` instead of the current Opsive package. | Remove the older bridge files and import the Ultimate Character Controller Version 3 `MasterAudio.unitypackage` from Opsive Downloads. Do not keep both. |
| No Ultimate Character Controller sound plays after assigning the module | Check the Master Audio GameObject, **Audio Manager Module**, Console, and requested Sound Group. | Keep both managers active, assign `MasterAudioManagerModule`, and fix the first runtime or missing-group error. |
| A direct Audio Clip worked before the module change but is now silent | **Require Group Name** is enabled and the Ultimate Character Controller hook has no Master Audio Config. | Assign a config with **Audio Group Name**, or use the fallback only after creating a same-named Sound Group for the clip. |
| **Audio Group Name** or **Variation** has no useful choices | The Master Audio GameObject, Sound Group, or Variations may not exist in the current scene. | Create or import them, then reselect the config so its Inspector can refresh the list. |
| The selected Variation does not play | Compare **Variation** or **Variation Name** with the direct children of the selected Sound Group. | Select an existing Variation or return to **(Random Variation)**. |
| A character sound is 2D, too quiet, or routed to the wrong bus | The inherited Ultimate Character Controller spatial and output fields do not drive this module. | Correct the Master Audio Sound Group and Variation Audio Source settings. |
| A looping sound stays behind when the character moves | The bridge uses position-at-start playback rather than Master Audio's follow-transform call. | Use a project-specific Audio Manager module or a direct Master Audio follow setup for that long-running sound. |
| Stopping one ability sound also stops another sound | Both sounds were triggered by the same character transform. | Use separate playback transforms or customize the module for group- or Variation-specific stopping. |
| A fade-out configured in Ultimate Character Controller is ignored | The bridge stops all sounds for the transform abruptly and does not use Ultimate Character Controller's loop or fade-style source overrides. | Configure natural fades in the Master Audio Variation, or customize the stop path when an interrupted sound must fade. |
| Audio plays twice in a networked game | More than one authority or client is responding to the replicated gameplay event. | Choose one replication/playback policy; the bridge itself does not suppress duplicate network calls. |

## Related pages

- [Ultimate Character Controller audio workflow](https://opsive.com/support/documentation/ultimate-character-controller/audio/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Jump ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/jump/)
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Ultimate Inventory System Master Audio integration](https://opsive.com/support/documentation/ultimate-inventory-system/integrations/master-audio/)
- [Master Audio Sound Groups](https://www.dtdevtools.com/docs/masteraudio/SoundGroups.htm)

## Developer and runtime reference

The bridge supplies `Opsive.Shared.Integrations.MasterAudio.MasterAudioManagerModule`, derived from `AudioManagerModule`, and `MasterAudioConfig`, derived from `AudioConfig`. Ultimate Character Controller continues to call `Opsive.Shared.Audio.AudioManager`; changing the manager module redirects existing Health, ability, item, respawn, and Surface Effect calls without replacing those components.

For transform playback the module calls `MasterAudio.PlaySound3DAtTransform`. For positioned playback it calls `MasterAudio.PlaySound3DAtVector3`. **Audio Group Name** supplies the Sound Group, and **Variation** optionally supplies one exact Variation. If the call neither plays nor schedules a voice, the bridge returns `PlayResult.None`.

The module applies volume, pitch, and delay overrides from the individual request first, then from the Master Audio Config. Master Audio owns looping, output routing, stereo pan, spatial blend, reverb, pooling, voice limits, and Variation Audio Sources. The inherited Opsive fields for Audio Source prefabs, sharing or replacing Audio Sources, copying source properties, output, loop, stereo pan, spatial blend, and reverb are not consumed by this module.

Both `Stop` overloads call `MasterAudio.StopAllSoundsOfTransform` and return no Audio Source, so a stop by config or `PlayResult` is not isolated to one Sound Group or Variation. The integration routes Opsive sound-effect playback; it does not turn Ultimate Character Controller audio fields into Master Audio playlists.

The current bridge package has no formal third-party version constraint. Its source and compile boundary were checked with Ultimate Character Controller 3.3.3, Opsive Shared 2.1.0, and Master Audio 2024 v1.0.3. Recheck this minimal workflow whenever upgrading any of those packages.

---

<a id="page-ultimate-character-controller-integrations-nwh-vehicle-physics"></a>

# NWH Vehicle Physics

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/nwh-vehicle-physics/)


Use the [NWH Vehicle Physics](https://assetstore.unity.com/packages/tools/physics/nwh-vehicle-physics-2-166252?aid=1100lGdc) integration when an Ultimate Character Controller character should enter a vehicle, hand driving input and camera control to NWH Vehicle Physics 2, then return to ordinary character control on exit.

## Supported package boundary

This guide is verified against the released Ultimate Character Controller Version 3 `NWHDriveSource` bridge and the checked-in NWH test project, whose AssetInfo reports `10.20f`. The bridge package was last source-updated in July 2023 and does not declare a minimum or maximum NWH version. NWH has published later releases, so this is not a blanket compatibility guarantee for every 13.x package.

Before upgrading an existing project, import the current Opsive bridge into a copy and confirm that NWH still exposes `NWH.Common.Vehicles.Vehicle` and `NWH.Common.Cameras.CameraChanger`. Follow the [NWH Vehicle Physics documentation and changelog](https://www.nwhvehiclephysics.com/doku.php/index) for package-specific vehicle setup and migration changes.

## Before you begin

- Build and test the Ultimate Character Controller Version 3 character, camera, and **Drive** ability before connecting the vehicle.
- Build and test the NWH vehicle on its own. Its wheels, Rigidbody, powertrain, input provider, and cameras remain NWH responsibilities.
- Decide which NWH input provider owns the vehicle controls. The bridge enables the NWH **Vehicle** component; it does not translate Ultimate Character Controller character input into NWH steering, throttle, or brake values.
- Add an NWH vehicle camera. The stock bridge disables the Ultimate Character Controller Camera Controller GameObject while driving and has no option to keep that camera active.

## Install the integration

1. Install [NWH Vehicle Physics 2](https://assetstore.unity.com/packages/tools/physics/nwh-vehicle-physics-2-166252?aid=1100lGdc) and verify a vehicle in Play Mode.
2. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the NWH Vehicle Physics integration. The bridge is not included in the base product's Integrations folder before this download.
3. Import the downloaded bridge after NWH has compiled. Importing it creates the integration files in the project.
4. Allow Unity to compile. Resolve the first Console error before continuing; the bridge requires both Ultimate Character Controller and the NWH `Vehicle` and `CameraChanger` APIs.
5. Confirm that **NWH Drive Source** is available from Add Component.

Reimport the current bridge after updating Ultimate Character Controller or NWH. If its source no longer compiles, restore the last working package combination or adapt the bridge to the installed NWH API before changing the scene setup.

## Connect the vehicle

1. Select the vehicle root containing NWH's **Vehicle Controller** component. Add **NWH Drive Source** to this same GameObject; the bridge looks for the NWH `Vehicle` component beside itself.
2. Create a child Transform named `Driver Location`. Position and rotate it where the character should sit, then assign it to **NWH Drive Source > Driver Location**.
3. Set **Animator ID**. Keep `0` when using the default Drive animation set, or use a distinct base ID when the Animator contains vehicle-specific Enter, Drive, and Exit states.
4. Add one or more **Move Towards Location** children beside doors or other safe entry and exit points. Drive requires at least one clear location even when **Teleport Enter Exit** is enabled.
5. Add the collider or trigger that Drive should detect. Put its actual layer in **Drive > Detect Layers**; do not assume an NWH prefab uses a particular layer.
6. Keep every vehicle collider that should ignore the seated character active below the NWH Drive Source GameObject when the scene starts. The bridge caches active child colliders once during `Start`.

The current bridge disables the NWH Vehicle component during `Start` and enables it after the character finishes entering. Do not follow older instructions to change NWH's removed **Awake On Start** option; that legacy screenshot and field no longer describe the audited package.

### Configure NWH input

Choose and configure an NWH input provider independently of the character's Ultimate Character Controller input:

- Use **Input System Vehicle Input Provider** for NWH's Unity Input System route, or **Input Manager Vehicle Input Provider** for its legacy Input Manager route. Configure the NWH actions or axes and verify them on a vehicle before adding Ultimate Character Controller.
- Leave the NWH Vehicle Controller's **Auto Set Input** enabled when it should collect values from the active scene provider. **Swap Input In R** is enabled by default and swaps throttle and brake while reversing.
- Disable **Auto Set Input** when AI or project code writes NWH vehicle input states directly.
- If the Ultimate Character Controller character also uses Unity Input System, install and configure the Ultimate Character Controller [Unity Input System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/input-system/) separately. That integration controls the character and the `Action` used to start or stop Drive; it does not configure NWH's vehicle action asset.

Use only one local provider for a single vehicle test. Multiple global providers can make it unclear which device is supplying NWH's combined input.

### Configure the NWH camera

1. Add **Camera Changer** below the vehicle root so it can find the parent Vehicle Controller.
2. Add the desired camera GameObjects below Camera Changer.
3. Leave **Auto Find Cameras** enabled to collect child cameras automatically, or disable it and populate **Cameras** manually.
4. Set **Current Camera Index** to the camera which should appear first.

NWH Drive Source finds the first Camera Changer below its GameObject. After entry, it disables the entire Ultimate Character Controller Camera Controller GameObject and enables the NWH Vehicle and Camera Changer. On exit, it disables the NWH camera GameObjects and re-enables the Ultimate Character Controller camera.

The stock source therefore requires an NWH camera for a visible driving view. If the project must keep an Ultimate Character Controller View Type while driving, create a project-specific `IDriveSource` which does not deactivate the Ultimate Character Controller camera; there is no Inspector toggle for that behavior.

## Configure the character

1. Add **Drive** under **Ultimate Character Locomotion > Abilities**. The default `Action` input starts and stops the ability.
2. For animated entry, add **Move Towards** above Drive and add `OnAnimatorEnteredVehicle` and `OnAnimatorExitedVehicle` to every reachable entry and exit animation.
3. Enable **Teleport Enter Exit** when the character should move immediately between a Move Towards Location and Driver Location without those animation events.
4. Configure **Object Detection**, **Detect Layers**, and optional **Object ID** so Drive detects the vehicle collider.
5. Choose item behavior with **Allow Equipped Slots**, **Can Aim**, and **Disable Mesh Renderers**. With the default empty allowed-slots mask, Drive blocks item abilities while seated. Use **Item Equip Verifier** when items should be unequipped before entry and restored afterward.
6. Follow the complete [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/) workflow for entry clearance, exit clearance, collision handling, animation events, and vehicle-specific Animator IDs.

NWH owns the controls after entry. Ultimate Character Controller's Drive ability still owns the seated character, entry and exit, item restrictions, collision ignores, and alignment with Driver Location.

## How it runs

1. During `Start`, NWH Drive Source caches its GameObject, Transform, and active child colliders. It finds the NWH Vehicle and first child Camera Changer, then disables both sides of the NWH vehicle view.
2. Ultimate Character Controller Drive detects the source and approaches or teleports to a Move Towards Location. NWH remains disabled while the character enters.
3. When entry finishes, Ultimate Character Controller calls `EnteredVehicle`. The bridge remembers the character, enables NWH's Vehicle component, disables the Ultimate Character Controller camera GameObject, and enables the NWH Camera Changer.
4. NWH's active input provider supplies steering, throttle, brake, and other vehicle controls. Ultimate Character Controller keeps the character aligned with Driver Location and ignores the cached vehicle colliders.
5. When a valid exit begins, Ultimate Character Controller calls `ExitVehicle`. The bridge disables NWH's Vehicle and cameras, returns the Ultimate Character Controller camera, and releases its character reference before the exit finishes.
6. Ultimate Character Controller completes the exit and restores the character's collision, parenting, movement, and configured items.

## Key choices and limitations

| Choice | Use it when | Important consequence |
| --- | --- | --- |
| **Teleport Enter Exit** | No enter or exit animations are available | Entry and exit are immediate, but a clear Move Towards Location is still required. |
| Animated entry and exit | The character should approach a door and play seated transitions | Animator events must call `OnAnimatorEnteredVehicle` and `OnAnimatorExitedVehicle` at the handoff points. |
| NWH Input System provider | The vehicle should use NWH's action asset and supported devices | It remains separate from the Ultimate Character Controller character's Input System integration. |
| NWH Input Manager provider | The vehicle should use NWH's legacy named inputs | Those inputs are global and do not inherit Ultimate Character Controller player ownership. |
| Automatic NWH input | A local player provider should control the vehicle | Keep **Auto Set Input** enabled and avoid competing scene providers. |
| AI or custom input | Code should write the vehicle controls | Disable **Auto Set Input** and assign the NWH states from the owning system. |
| Stock camera handoff | NWH child cameras should control the driving view | The bridge deactivates the complete Ultimate Character Controller Camera Controller GameObject while occupied. |

The stock bridge assumes one local driver. It contains no per-player device assignment, network ownership, vehicle-state replication, or save data. It also snapshots only colliders that are active below the source during `Start`.

A forced stop is another important boundary. Ultimate Character Controller restores its character-side Drive state when force-stopped, but NWH Drive Source performs its Vehicle and camera cleanup in the normal `ExitVehicle` callback. Death, destruction, scene changes, or custom code that interrupts Drive while seated should explicitly disable NWH vehicle control and restore the correct camera.

## Verify in Play Mode

1. Enter Play Mode without entering the vehicle. The NWH Vehicle and every NWH vehicle camera should be disabled, while the Ultimate Character Controller gameplay camera remains active.
2. Approach the entry collider. Drive's inherited **Detected Object** should show the intended vehicle.
3. Press the configured `Action` input. Confirm that the character reaches the expected Move Towards Location or teleports, then aligns with Driver Location.
4. During an entry animation, the vehicle should not accept driving input. It should enable only after the `OnAnimatorEnteredVehicle` event completes entry.
5. Confirm that the Ultimate Character Controller camera turns off and the camera at **Current Camera Index** turns on after entry. There should be one active Camera and one active Audio Listener.
6. Test steering, throttle, braking, reverse, and any configured camera-change input. Only the occupied vehicle should respond.
7. Press `Action` with a clear exit location. NWH control and cameras should turn off as exit begins; the Ultimate Character Controller camera and ordinary character movement should return.
8. Block one exit and retry. Drive should remain active until another Move Towards Location is clear.
9. Test death, a forced ability stop, scene loading, and vehicle destruction while seated. Confirm that project cleanup restores the camera and disables the NWH Vehicle in every supported interruption.
10. If the project supports saving or multiplayer, repeat the test after a save/load cycle and with every local or remote ownership role.

## Saving and multiplayer

NWH Drive Source does not save the current driver, Vehicle enabled state, vehicle transform, powertrain, input owner, camera owner, or item state. Save those through the project's vehicle and character save systems. A reliable baseline is to restore both character and vehicle unoccupied, unless the project deliberately reconstructs an occupied Drive session.

The bridge also sends no network messages. Ultimate Character Controller's multiplayer Drive path expects the `IDriveSource` to notify remote players, while NWH's optional multiplayer support manages its own Vehicle ownership and `MultiplayerIsRemote` behavior. A multiplayer project must coordinate those layers, assign input and cameras only to the local owner, replicate the vehicle through its chosen NWH networking package, and test entry and exit authority on every peer.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Unity reports missing NWH types after import | NWH may be absent, may not have compiled before the bridge, or may expose a later incompatible API | Install and compile NWH first, then import the current Ultimate Character Controller bridge. Compare its `Vehicle` and `CameraChanger` APIs before adapting the source. |
| The Console says NWH Drive Source requires a Vehicle | **NWH Drive Source** and NWH's Vehicle Controller may be on different GameObjects | Put NWH Drive Source on the same vehicle root as the component derived from `NWH.Common.Vehicles.Vehicle`. |
| Drive never detects the vehicle | The collider layer may be excluded, the source may not be on a detected parent, or no Move Towards Location may be clear | Correct **Detect Layers**, keep the source in the detected hierarchy, and add a clear entry or exit location. |
| The character enters but the vehicle does not respond | NWH Vehicle may not have enabled, no NWH provider may be active, **Auto Set Input** may be off, or animated entry may still be waiting | Inspect the components after entry, add `OnAnimatorEnteredVehicle`, configure one NWH provider, and enable **Auto Set Input** for player control. |
| The Ultimate Character Controller Input System works but the vehicle does not | The character and vehicle use separate input integrations | Configure NWH's Input System Vehicle Input Provider and its action asset in addition to Ultimate Character Controller's Input System integration. |
| The vehicle responds before entry or another vehicle also responds | Another script may enable NWH Vehicle, or a global input provider may be supplying more than the intended vehicle | Give the bridge sole enabled-state ownership and use an explicit per-vehicle or per-player NWH input route. |
| The screen goes blank after entry | The bridge disables the Ultimate Character Controller Camera Controller GameObject but did not find a usable child Camera Changer and camera | Put Camera Changer and its camera GameObjects below the vehicle root and verify **Current Camera Index** before entry. |
| Two Cameras or Audio Listeners remain active | An extra scene camera may be outside the NWH Camera Changer list, or another system may reactivate it | Choose one camera owner and include or disable every vehicle camera deliberately. |
| Exit input does nothing | No Move Towards Location may be clear | Add another exit point or clear the overlap around its optional clearance collider. |
| Vehicle control or the NWH camera remains active after death or a forced stop | The normal `ExitVehicle` callback may have been bypassed | Add interruption cleanup that disables the NWH Vehicle and cameras and reactivates the correct Ultimate Character Controller camera. |
| The seated character collides with a collider added after startup | NWH Drive Source caches active child colliders only once in `Start` | Keep required colliders active below the source at startup or refresh the collider list in a custom source when the vehicle changes. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/)
- [Move Towards](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/move-towards/)
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/)
- [Item Equip Verifier](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/item-equip-verifier/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Unity Input System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/input-system/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)

## Developer reference

`NWHDriveSource` implements Ultimate Character Controller's `IDriveSource`. Its Inspector exposes only **Driver Location** and **Animator ID**. It supplies the source GameObject, Transform, cached child colliders, and animation ID to Drive.

Its lifecycle callbacks divide the handoff as follows:

- `EnterVehicle(Drive)` does nothing while the character approaches or animates into the vehicle.
- `EnteredVehicle(Drive)` stores the character and enables the NWH Vehicle and camera handoff.
- `ExitVehicle(Drive)` disables NWH, returns the Ultimate Character Controller camera, and clears the stored character when a valid exit begins.
- `ExitedVehicle(Drive)` does nothing after Ultimate Character Controller finishes restoring the character.

At startup, the source uses `GetComponent<Vehicle>()`, `GetComponentsInChildren<Collider>()`, and `GetComponentInChildren<CameraChanger>()`. These calls explain the same-GameObject Vehicle requirement, the active startup collider snapshot, and the first-child Camera Changer behavior.

The bridge toggles `Vehicle.enabled`; it does not call NWH input APIs directly. NWH's **Auto Set Input** gathers values from its active input providers, while a custom or AI integration can disable that option and write NWH's vehicle input states itself. A custom source should preserve the same entry, normal exit, forced-stop, camera, input-owner, and remote-owner cleanup guarantees.

---

<a id="page-ultimate-character-controller-integrations-omni-animation-packs"></a>

# Omni Animation Packs

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/omni-animation-packs/)


Use the Omni Animation integration when the Ultimate Character Controller Animator logic already behaves correctly and you want Omni locomotion, knife, or pistol performances in its states. The integration is a set of editor-time Animation Replacement templates. It does not add a runtime bridge, replace the Ultimate Character Controller ability or item systems, or automatically retarget an incompatible rig.

## Compatibility boundary

This workflow was verified against Ultimate Character Controller 3.2.0 and the locally released Core Locomotion, Knife, and Pistol integration assets. The audited Omni assets identify their pack data as version 1.0. The current Unity Asset Store listings identify [Core Locomotion](https://assetstore.unity.com/packages/3d/animations/omni-animation-core-locomotion-pack-286945?aid=1100lGdc), [Knife](https://assetstore.unity.com/packages/3d/animations/omni-animation-knife-pack-277864?aid=1100lGdc), and [Pistol](https://assetstore.unity.com/packages/3d/animations/omni-animation-pistol-pack-276060?aid=1100lGdc) as version 1.0.1 with Unity 2021.3 as the original editor baseline.

Those facts are not an Ultimate Character Controller-to-Omni version matrix. Opsive supplies the Ultimate Character Controller replacement templates separately, and neither package declares a minimum or maximum compatible version of the other. After updating Ultimate Character Controller, an Omni pack, or a replacement template, repeat the Editor and Play Mode checks on a controller copy before updating production assets.

The integration covers the following supplied choices:

| Pack | Replacement Template | Populated mappings | Choose it for |
| --- | --- | ---: | --- |
| Core Locomotion | `CoreLocomotionAnimations` | 14 | The mapped idle, crouch, forward/backward, and strafe walk/run motions present in the selected controller. |
| Knife | `KnifeAnimations` | 34 | The standard knife stance and its mapped item actions. |
| Knife | `KnifeReverseGripAnimations` | 34 | The reverse-grip alternative. Start from an unchanged controller instead of applying both knife templates in sequence. |
| Pistol | `PistolHighReadyAnimations` | 31 | The High Ready pistol stance. |
| Pistol | `PistolLowReadyAnimations` | 31 | The Low Ready pistol stance. |
| Pistol | `PistolRelaxedAnimations` | 31 | The Relaxed pistol stance. |
| Pistol | `PistolTempleIndexAnimations` | 31 | The Temple Index pistol stance. |

A populated mapping is one source-to-replacement pair in the template, not a promise that every row exists in every controller. The Console replacement count can also be higher because one source clip may occur in multiple states or blend trees.

## Before you begin

- Install Ultimate Character Controller 3.2.0 and verify the unchanged character, Animator Controller, abilities, and items in Play Mode.
- Duplicate every Animator Controller that you intend to change into a project-owned folder. **Replace** edits the selected `.controller` asset in place and has no integration-specific rollback command.
- Commit or back up both the copied controllers and the Omni animation assets. **Replace Events** can change imported FBX clip event data shared by other controllers.
- Confirm which runtime Animator owns the body controller. First-person arms and animated visible items can use separate controllers and are not processed automatically.
- Decide whether each character is Humanoid or Generic. The supplied Omni clips and templates are configured for Humanoid retargeting; a Generic rig needs a matching hierarchy or a separate project-specific conversion.

## Install the packs and Ultimate Character Controller templates

Import dependencies in this order so the replacement assets can resolve their clip references:

1. Import and compile Ultimate Character Controller 3.2.0.
2. Import the required Omni pack from its Unity Asset Store listing: Core Locomotion, Knife, or Pistol. Allow Unity to finish importing before continuing. The pack manuals describe one-time scale warnings relative to the source rig as harmless.
3. Inspect the pack under `Assets/Opsive/OmniAnimation/Packs/<PackName>`. Each installed pack includes an `Animations` folder and a demo scene. The bundled demo scene uses URP, so a material or render-pipeline difference there is not evidence of an animation integration failure.
4. Sign in to the [Opsive Downloads page](https://opsive.com/downloads/) with the Ultimate Character Controller invoice and download the matching Omni Animation replacement-template package.
5. Import the replacement-template package after the Omni pack. Confirm the expected templates appear under `Assets/Opsive/UltimateCharacterController/Integrations` and that Unity reports no missing-script or missing-reference errors.

The downloaded integration contains replacement data only. Do not add Omni's demo `MotionController` component to the Ultimate Character Controller character.

## Choose and verify the animation rig

Each pack contains `Original` and `TPose` animation folders:

- **Original** uses the recorded Omni rig and copies its shared Humanoid Avatar. The pack manuals recommend this variant when in doubt, and every supplied Ultimate Character Controller replacement template references these `Original` clips.
- **TPose** includes a T-pose and creates a Humanoid Avatar from each model. Choose it when you need Unity's generated Avatar or are preparing a project-specific retargeting workflow. The supplied Ultimate Character Controller templates do not select these clips automatically; override each populated replacement row or create a project replacement template.

Before changing a controller, select representative FBX clips in the Project window and check **Rig > Animation Type: Humanoid**. Open **Configure** or use the animation preview to confirm that Unity has a valid Avatar and that the target character does not twist, collapse, or enter a bind pose. Keep the imported `Original` Avatar assignment intact unless a deliberate retargeting test proves another configuration is correct.

If the target is Generic, stop here unless the target skeleton matches the animation hierarchy. The Animation Replacer swaps clip references; it cannot convert Humanoid clips to a Generic rig.

## Replace the controller animations

1. Open **Tools > Opsive > Ultimate Character Controller > Animation Replacer**.
2. Assign the duplicated, project-owned `.controller` asset to **Animator Controller**. Select the controller used by the character body's Animator, not an unrelated demo, first-person arm, or item controller.
3. Assign one template from the compatibility table to **Replacement Template**. Use exactly one Knife grip or Pistol readiness variant on a fresh controller copy.
4. Decide whether to keep **Replace Events** enabled. It is enabled by default and is appropriate only when the replacement clips should inherit the source clips' events. Disable it when the Omni clips already contain approved events or the related Ultimate Character Controller actions use duration-based timing.
5. Review every populated row. Each row is labelled with the original clip and can be overridden. Clear a replacement to keep that source clip unchanged; add a `TPose` clip manually when using that variant.
6. Select **Replace**. Confirm the Console reports `<count> animation clips were replaced.` A zero count means the selected controller did not contain the exact source clip references mapped by the template.
7. Open the copied Animator Controller. Inspect changed states and nested blend trees, then review the version-control diff. Parameters, transitions, layers, masks, state behaviours, and state settings should remain unchanged; only intended Motion references should differ.
8. Assign the edited copy to the character model's active **Animator > Controller** field. Repeat the process separately for any other body controller that should use the pack.

For a complete explanation of the tool, including custom templates and event transfer, see [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/).

## Editor checkpoint

Before entering Play Mode, confirm all of the following:

- The active character model uses the edited controller copy, and the original controller remains available for comparison.
- The expected template was applied once. Knife grip and Pistol readiness variants have not been stacked on the same controller.
- Every intended row resolves to an `Original` clip, or to a manually selected `TPose` clip when that variant is deliberate.
- Representative clips preview on the character with a valid Humanoid Avatar and without a bind pose or distorted limbs.
- Controller parameters, transitions, layers, Avatar Masks, and StateMachineBehaviours match the original controller.
- Imported replacement clips have the intended loop, root-transform, and Animation Event settings.
- No Omni demo `MotionController` is attached to the Ultimate Character Controller character.
- The Console has no missing-reference, Avatar, or Animator errors.

## Verify in Play Mode

Keep the unchanged and edited controller copies available and compare the same inputs with each. This separates a replacement problem from an existing character, item, or ability setup problem.

1. With Core Locomotion applied, test idle, walk, run, sprint if configured, forward and backward movement, strafing, crouch, starts, stops, turns, jump, fall, and landing. Check every supported movement type and camera perspective used by the character.
2. Watch feet and capsule motion while starting, stopping, turning, moving on slopes, stepping off edges, and colliding. There should be no double movement, cumulative drift, unexpected rotation, or change in gravity behavior.
3. With a Knife template applied, test equip, idle, aim if configured, every attack, moving attacks, crouched use, interruption, and unequip. Confirm the selected normal or reverse grip remains consistent through the full action.
4. With a Pistol template applied, test equip, idle, aim, fire, reload, movement while aiming, interruption, and unequip. Confirm the chosen readiness pose returns after every action.
5. Exercise any Ultimate Character Controller ability whose state uses a replaced clip. Verify that it starts and ends once, transitions back to locomotion, and does not remain waiting for an Animation Event.
6. For every event-driven item or ability action, confirm the gameplay event occurs once at the visible contact, fire, reload, equip, or completion frame. Relative event transfer does not guarantee semantic timing on a differently paced performance.
7. If the character supports first person and third person, test both. These packs target the Humanoid body controller; separate Generic first-person arms should remain unchanged unless their own compatible clips were processed deliberately.
8. Repeat rapid input, action interruption, item switching, and a scene save/load or respawn flow used by the project. The controller should return to a valid idle or locomotion state.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| A downloaded template has missing references or leaves every replacement row empty. | Confirm the matching Omni pack was imported before the Ultimate Character Controller template package and that its `Original` animation folder is present. | Reimport the Omni pack, then reimport the matching Opsive replacement-template package. Do not remap missing references by guesswork. |
| **Replace** reports `0`. | Check that **Animator Controller** is the project-owned controller containing the exact Ultimate Character Controller source clips referenced by the template. | Select the controller actually assigned to the runtime body Animator, review the populated rows, and run **Replace** again. |
| Only some motions changed. | The selected controller may not use every source clip in the template, or another layer/controller may use different clip assets. | Inspect the active state and blend tree, replace the remaining state deliberately, and process each separate compatible controller on its own copy. |
| The character twists, collapses, or shows a bind pose. | Inspect the replacement clip's Humanoid Avatar and preview it on the target model. | Restore the controller copy, correct the rig/Avatar setup, and prove the clip in preview before replacing it again. |
| Selecting `TPose` seems to have no effect. | The supplied Ultimate Character Controller templates reference `Original` clips. | Override the replacement rows with the corresponding `TPose` clips or create a project-specific Animation Replacements asset. |
| The wrong Knife grip or Pistol readiness pose appears. | Check whether the wrong template was selected or multiple stance templates were applied sequentially. | Restore a clean controller copy and apply exactly one matching stance template. |
| A replaced action never completes, fires twice, or occurs at the wrong frame. | Check **Replace Events**, the imported replacement clip's event list, and the Ultimate Character Controller trigger's expected event name or duration. | Restore the approved event data, add or move the event to the visible action frame, or deliberately configure duration timing. |
| Existing Omni events disappeared. | **Replace Events** can replace an imported target clip's event list with the source list. | Restore the FBX importer data from version control or a clean package import, disable **Replace Events**, and retain the approved events manually. |
| Movement slides, rotates twice, or travels farther than the capsule. | Check the clip's root-transform import settings, Ultimate Character Controller's root-motion configuration, and the character for Omni's demo `MotionController`. | Remove the demo controller, make Ultimate Character Controller the sole movement owner, and configure each replacement as in-place or root-motion animation to match the original Ultimate Character Controller state. |
| First-person arms do not change. | Check whether the character uses a separate Generic arm Animator Controller. | Keep the Humanoid Omni clips on the body. Replace the arm controller only with clips authored or converted for that exact arm rig. |
| Another character or controller changes unexpectedly. | It may share the edited controller or an imported replacement clip whose events were changed. | Restore the shared asset, make project-specific controller or clip copies where licensing and import structure permit, and repeat the change on those assets. |

## Related pages

- [Replacing Animations](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/replacing-animations/) covers the Animation Replacer, custom mappings, and event-copy rules.
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/) explains the Ultimate Character Controller layers, transitions, and customization boundary.
- [Animation Event Trigger](https://opsive.com/support/documentation/ultimate-character-controller/animation/animation-event-trigger/) explains event-driven and duration-driven action timing.
- [Character Item Support](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/item-support/) covers the character-side setup required before testing Knife or Pistol animations.

## Developer and runtime ownership notes

In Ultimate Character Controller 3.2.0, `AnimationReplacer` traverses every Animator Controller layer, nested state machine, state, and nested blend tree. It changes every Motion reference whose exact source clip has a non-null mapping, marks the selected controller dirty, and logs the number of replacements. It does not create a controller, modify transition logic, or install a runtime integration API.

With **Replace Events** enabled, Ultimate Character Controller copies each source event's function name, parameters, message options, and normalized position to the replacement clip through its `ModelImporter`. This replaces the imported target clip's event list and does not write events to a standalone `.anim` asset. A shared imported clip therefore has one event list across every controller that references it.

Ultimate Character Controller remains responsible for character movement, collision, gravity, abilities, and root-motion application. Omni's demo `MotionController` also consumes `Animator.deltaPosition` and `Animator.deltaRotation`; attaching it to an Ultimate Character Controller character creates competing movement owners. The replacement templates add no event bus, input route, runtime download, or service dependency.

The integration adds no save data and no network messages. A save system continues to persist the project's normal Ultimate Character Controller state, not a selected Omni template. Every network participant must ship the same controller and licensed animation assets, while authority, prediction, ability replication, and respawn restoration remain responsibilities of the selected Ultimate Character Controller networking integration and project code.

---

<a id="page-ultimate-character-controller-integrations-playmaker"></a>

# PlayMaker

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/playmaker/)


Use the [PlayMaker](https://assetstore.unity.com/packages/tools/visual-scripting/playmaker-368?aid=1100lGdc) integration to start Ultimate Character Controller abilities, change states and attributes, control items, and branch an FSM from Ultimate Character Controller results without writing a separate script for each workflow.

## Supported package boundary

The released Ultimate Character Controller Version 3 integration is a **PlayMaker 1** custom-action package. Its 28 actions inherit from PlayMaker 1's `FsmStateAction` and use `OnEnter`, `OnUpdate`, and `Finish`. The current [PlayMaker 1 Asset Store listing](https://assetstore.unity.com/packages/tools/visual-scripting/playmaker-368?aid=1100lGdc) reports 1.9.10f1, but the Opsive bridge was last source-updated in April 2023 and declares no minimum or maximum PlayMaker 1 version. Import and compile the exact package combination before updating a production project.

This bridge does **not** support PlayMaker 2. Hutong Games states that [PlayMaker 2 is not backward compatible with PlayMaker 1](https://hutonggames.com/playmaker/docs/welcome/installation/), and PlayMaker 2 uses a different custom-action lifecycle and editor API. Keep an existing Ultimate Character Controller project on PlayMaker 1, or port the Opsive actions before moving that project to PlayMaker 2.

## Before you begin

- Build and test the Ultimate Character Controller Version 3 character before adding an FSM. The integration controls existing Ultimate Character Controller components; it does not create the character, abilities, items, attributes, or states.
- Install PlayMaker 1 and complete its installer before importing the Opsive bridge. Do not import PlayMaker 1 and PlayMaker 2 into the same project.
- Decide where the FSM should live. Put **PlayMaker FSM** on the character when most actions use that character, or put it on a separate controller and assign **Target Game Object** explicitly.
- Add every ability, effect, item-set category, attribute, and named state that the FSM will reference before configuring actions.

## Install the integration

1. Install PlayMaker 1 and confirm that a simple PlayMaker FSM runs in Play Mode.
2. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the PlayMaker integration. The bridge is not included in the base product's Integrations folder before this download.
3. Import the downloaded bridge after PlayMaker has compiled. Importing it creates the integration files in the project.
4. Allow Unity to compile. Resolve the first Console error before building an FSM; the action scripts require the `HutongGames.PlayMaker` and Ultimate Character Controller assemblies.
5. Open the PlayMaker **Action Browser**, search for **Ultimate Character Controller**, and confirm that the Opsive actions appear in that category.

The bridge adds PlayMaker actions and custom action editors. It does not add a required runtime component beyond the ordinary PlayMaker FSM and the Ultimate Character Controller components used by each action.

## Start an ability from an FSM

This is the smallest useful test because it verifies action discovery, character targeting, Ultimate Character Controller ability lookup, and PlayMaker transitions.

1. Add the Ultimate Character Controller ability that the FSM should control, such as **Jump**, to **Ultimate Character Locomotion > Abilities**.
2. Add **PlayMaker FSM** to the character and open the FSM editor.
3. Create a state named `Start Jump`, then add **Ultimate Character Controller > Start Stop Ability** from the Action Browser.
4. Leave **Target Game Object** at the owner when the FSM is on the character. Otherwise, assign the character GameObject.
5. Set **Ability Type** to **Jump**.
6. Leave **Priority Index** at `-1` when only one Jump ability exists. If multiple abilities use the same type, enter the Ultimate Character Controller ability index that should be controlled.
7. Keep **Start** enabled and assign separate **Success Event** and **Failure Event** transitions.
8. Enter Play Mode and activate the `Start Jump` state. The success branch should run only when Ultimate Character Controller's normal ability rules allow Jump to start.

Use another **Start Stop Ability** action with **Start** disabled when the FSM should request a stop. The action calls Ultimate Character Controller's normal `TryStartAbility` or `TryStopAbility` path, so ability conflicts, start conditions, movement state, and other Ultimate Character Controller rules still apply.

## Control an Ultimate Character Controller state

Use **Set State** when an FSM should apply several Inspector values as one named configuration rather than changing individual component fields.

1. Create and verify the named state and its preset through the Ultimate Character Controller [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/).
2. Add **Ultimate Character Controller > Set State** to a PlayMaker state.
3. Set **Target Game Object** to the object containing the state, enter the exact **State Name**, and leave **Active** enabled to activate it.
4. Add another Set State action with the same name and **Active** disabled on the transition that should release the state.
5. In Play Mode, watch the Ultimate Character Controller State list and the affected Inspector values as the FSM enters and leaves those states.

The bridge deliberately does not contain one action for every Ultimate Character Controller field. Prefer a named state when designers need a reusable group of values, and use a dedicated action when the change represents a runtime operation such as starting an ability or applying damage.

## Work with attributes and health

The character or target object must already contain the relevant **Attribute Manager** or **Health** component.

- **Get Attribute Value** reads the current **Value**, **Min Value**, or **Max Value** into a PlayMaker float. **Attribute Name** defaults to `Health`, and **Every Frame** is off by default.
- **Set Attribute Value** writes the selected Value, Min Value, or Max Value. Keep **Every Frame** off for a one-time change.
- **Damage** and **Heal** call the target's Health component with a positive **Amount**. Enabling **Every Frame** applies that amount on every update, not once per second.
- **Is Alive** stores a Boolean and can send **Alive Event** or **Dead Event**.
- **Has Taken Damage** stores the attacker and sends **Damaged Event** or **Not Damaged Event**. It detects damage from the current or immediately preceding frame while the action is active; it is not a history query.

Use the [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/) and [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) pages to create and verify the underlying Ultimate Character Controller data before reading it from PlayMaker.

## Control items and inventory

Configure the character's item definitions, Item Set Manager, categories, abilities, slots, and action IDs before adding these actions.

- **Adjust Item Identifier Amount** adds or removes the specified **Item Definition** amount from the target Inventory. **Amount** defaults to `0`; use a negative value to remove inventory.
- **Get Item Identifier Amount** stores the amount for an Item Definition in a PlayMaker integer.
- **Start Equip Unequip** selects an **ItemSet Category** and **Item Set Index**, then asks the matching Equip Unequip ability to change sets.
- **Start Item Set Ability** selects an **Ability Type** and **ItemSet Category** and sends success or failure. See the current source limitation below before using it with more than one item-set ability in a category.
- **Start Stop Use** finds a Use ability by **Slot ID** and **Action ID**. **Slot ID** defaults to `-1`, **Action ID** to `0`, **Start** to enabled, and **Wait For Use Complete** to enabled.
- **Reload** finds the Reload ability with the requested Slot ID and Action ID and is compiled only when the Ultimate Character Controller shooter feature is present.

Use the [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/) workflow to confirm that the same operation works through Ultimate Character Controller before asking an FSM to control it.

## Other included workflows

The action category also contains focused helpers for common Ultimate Character Controller operations:

| Goal | Actions | Important setup |
| --- | --- | --- |
| Inspect or control abilities | **Is Ability Active**, **Is Ability Enabled**, **Set Ability Enabled**, **Start Stop Ability** | Select the ability type; use **Priority Index** only when duplicate types exist. |
| Inspect or control effects | **Is Effect Active**, **Start Stop Effect** | The effect must already exist under Ultimate Character Locomotion. See the current editor limitation below. |
| Aim and move the character | **Set Aim Target**, **Set Move With Object Target**, **Set Position And Rotation** | The target requires Local Look Source, Move With Object, or Ultimate Character Locomotion respectively. |
| Assign or change the camera | **Assign Character**, **Toggle Perspective** | Assign Character targets the Camera Controller. Toggle Perspective compiles only when both first- and third-person features are installed. |
| Change the character model | **Change Model** | The target requires Model Manager; the shipped action accepts model indexes greater than `0`. |
| Use the Opsive object pool | **Instantiate Object**, **Destroy Object** | Store the instantiated GameObject when another state must destroy it later. |
| Send a name-only Opsive event | **Execute Event** | Do not use the shipped action without reviewing the current source defect below. |

## How targeting and transitions run

Most actions resolve **Target Game Object** when their PlayMaker state begins. An unassigned target means the GameObject that owns the FSM. Actions then find the required Ultimate Character Controller component on that object and either finish immediately or remain active when **Every Frame** or a wait option is enabled.

**Success Event**, **Failure Event**, **Active Event**, and similar fields send PlayMaker FSM events. They do not broadcast Ultimate Character Controller events. **Execute Event** is the exception: it sends a name-only event through the Opsive EventHandler to the selected GameObject.

Polling actions such as Is Ability Active, Is Ability Enabled, Is Effect Active, Get Attribute Value, Is Alive, and Has Taken Damage can run every frame. Keep that option off when a single snapshot is sufficient, and transition out of a polling state when its result is no longer needed.

## Current bridge limitations

- The package is written for PlayMaker 1 and cannot be treated as a PlayMaker 2 action pack.
- The bridge contains no action for every Ultimate Character Controller Inspector field. Use Ultimate Character Controller states for grouped configuration changes.
- **Execute Event** in the shipped source invokes the named event twice when **Every Frame** is disabled and never calls `Finish`. Do not use it unchanged for a one-shot event.
- The custom editor for **Start Stop Effect** populates **Effect Type** from Ultimate Character Controller ability classes instead of effect classes. Use **Is Effect Active** for inspection, or correct and retest the Start Stop Effect editor before relying on it.
- **Start Item Set Ability** displays **Ability Type**, but its runtime lookup selects the first Item Set ability matching the chosen category and does not use the selected type. Do not place multiple candidate item-set abilities in that category without adapting the action.
- With **Wait For Use Complete** enabled, **Start Stop Use** waits for completion but does not send its configured Success or Failure Event. Disable that option when the FSM transition depends on the result event, or adapt the action.
- Several actions return early when their required component, ability, item definition, or target is missing. Some of those paths do not call `Finish`, so an FSM can appear stuck until the setup is corrected.

## Verify in Play Mode

1. Open the Action Browser and confirm all expected actions appear under **Ultimate Character Controller** with no compile errors.
2. Run the Start Jump test. Confirm that a valid start follows **Success Event** and an intentionally blocked start follows **Failure Event**.
3. Activate and deactivate a named Ultimate Character Controller state. Confirm the State list and preset values change only on the intended GameObject.
4. Read `Health` with Get Attribute Value, apply one Damage action, and read it again. The amount should change once, not on every frame.
5. Use Is Alive and Has Taken Damage while the target receives damage. Confirm the PlayMaker events and attacker variable change on the expected frame.
6. Add one inventory item, query its amount, equip a known item set, and use the configured Slot ID and Action ID. Confirm the character's Ultimate Character Controller abilities remain the runtime owner of those operations.
7. Repeat one action from an FSM on another GameObject with **Target Game Object** assigned explicitly. Only the assigned character should respond.
8. Test every failure transition by disabling an ability, omitting a required item, or choosing a blocked action. The FSM should leave the state deliberately rather than remaining active without feedback.
9. If the project saves or networks gameplay, repeat the tests after load and for every local, authoritative, and remote role.

## Saving and multiplayer

The bridge does not persist PlayMaker states, FSM variables, active Ultimate Character Controller states, attributes, inventory, or ability progress. Save PlayMaker data and Ultimate Character Controller runtime data through their respective project save systems, then restore them in a defined order. A reliable baseline is to restore the Ultimate Character Controller character first and let the FSM resume from a neutral state rather than replaying one-shot actions during load.

The actions also send no network messages and perform no authority checks. Execute gameplay-changing actions only for the character's authoritative owner, then replicate the resulting Ultimate Character Controller ability, item, attribute, state, or transform through the project's supported multiplayer layer. A PlayMaker event is local unless the project explicitly sends it across the network.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Opsive actions do not appear | PlayMaker may not have compiled before the bridge, or PlayMaker 2 may be installed | Use PlayMaker 1, complete its installer, then reimport the current Ultimate Character Controller Version 3 integration. |
| Unity reports missing `HutongGames.PlayMaker` types | The bridge was imported before PlayMaker 1 or the PlayMaker installer was not completed | Finish the PlayMaker 1 installation, allow Unity to compile, then reimport the bridge. |
| The FSM controls the wrong object | **Target Game Object** may still use the FSM owner | Put the FSM on the Ultimate Character Controller character or assign the intended character, camera, inventory, or state owner explicitly. |
| Start Stop Ability does nothing | The selected ability type may not exist, the duplicate-type index may be wrong, or Ultimate Character Controller may reject its start rules | Add and enable the ability, keep **Priority Index** at `-1` for one instance, and wire both result events. |
| An action state never finishes | A required target, ability, effect, or look source may be missing, or the shipped Execute Event action may be in use | Inspect the Console and action fields, assign the missing dependency, avoid the unmodified Execute Event action, and add an explicit timeout around project-critical actions. |
| An attribute result never changes | The Attribute Manager may be absent or **Attribute Name** may not match exactly | Add the attribute, use its exact name, and store the result in a compatible PlayMaker float. |
| Damage or inventory changes repeat rapidly | **Every Frame** may be enabled | Disable it for one-shot changes, or scale the operation deliberately in a custom continuous action. |
| Item equip or use does not start | The category, Item Set Index, Slot ID, or Action ID may not match the character's configured abilities | Inspect the character's Item Set Manager and item abilities, then enter those exact identifiers. |
| Toggle Perspective is missing | Both first- and third-person scripting defines may not be present | Use a character package with both perspectives, or control the installed View Type through a project-specific workflow. |
| Change Model does nothing for index `0` | The shipped action rejects model indexes less than or equal to zero | Choose a valid available model index above zero or adapt the action if the first entry must be selected. |
| Execute Event fires twice or the state remains active | The shipped one-shot implementation has a source defect | Avoid the action unchanged; correct it to execute once and call `Finish`, then test the named receiver. |
| PlayMaker and Ultimate Character Controller work locally but not for remote players | The integration has no networking or ownership logic | Run actions on the authoritative owner and use the selected Ultimate Character Controller/network integration to replicate the result. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [Effects](https://opsive.com/support/documentation/ultimate-character-controller/character/effects/)
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/)

## Developer reference

Every shipped action uses `[ActionCategory("Ultimate Character Controller")]`. Most resolve the target with `Fsm.GetOwnerDefaultTarget`, cache the relevant Ultimate Character Controller component, and use PlayMaker fields for inputs, stored results, and transition events.

The 28 action sources are grouped as follows:

- Character and camera: `AssignCharacter`, `ChangeModel`, `SetAimTarget`, `SetMoveWithObjectTarget`, `SetPositionAndRotation`, and `TogglePerspective`.
- Abilities and effects: `IsAbilityActive`, `IsAbilityEnabled`, `SetAbilityEnabled`, `StartStopAbility`, `IsEffectActive`, and `StartStopEffect`.
- Items and inventory: `AdjustItemIdentifierAmount`, `GetItemIdentifierAmount`, `StartEquipUnequip`, `StartItemSetAbility`, `StartStopUse`, and conditionally compiled `Reload`.
- Attributes and health: `Damage`, `Heal`, `GetAttributeValue`, `SetAttributeValue`, `HasTakenDamage`, and `IsAlive`.
- State and events: `SetState` and `ExecuteEvent`.
- Pooling: `InstantiateObject` and `DestroyObject`.

`Reload` is wrapped in `ULTIMATE_CHARACTER_CONTROLLER_SHOOTER`. `TogglePerspective` is wrapped in both `FIRST_PERSON_CONTROLLER` and `THIRD_PERSON_CONTROLLER`. The custom action editors provide type and Item Set category popups from the current project; the Item Set category popup requires an initialized Item Set Manager in the scene, and Start Stop Effect has the type-popup defect described above.

When porting to PlayMaker 2, do not mechanically copy these classes. PlayMaker 2 replaces the `FsmStateAction` lifecycle and its `OnEnter`, `OnUpdate`, and `Finish` pattern with its newer action, parameter, update-mode, and editor APIs. Preserve the Ultimate Character Controller operation and result semantics while rebuilding each action against the PlayMaker 2 API.

---

<a id="page-ultimate-character-controller-integrations-quest-machine"></a>

# Quest Machine

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/quest-machine/)


Use the [Quest Machine](https://assetstore.unity.com/packages/tools/game-toolkits/quest-machine-39834?aid=1100lGdc) integration when quests should respond to an Ultimate Character Controller character's inventory or attributes, and when quest rewards should add items or change attribute values. Quest Machine owns the quest and dialogue; Ultimate Character Controller continues to own character interaction, movement, items, attributes, camera, and input.

For example, a knight can offer a shotgun quest through the normal Ultimate Character Controller Interact ability. Quest Machine watches the player's Ultimate Character Controller inventory, advances the quest after a shotgun is collected, and removes the shotgun when it is handed in.

## Supported package boundary

This page covers Ultimate Character Controller Version 3 and the Pixel Crushers Quest Machine bridge. As of August 2026, the Asset Store lists Quest Machine `1.2.72`, and Pixel Crushers has announced `1.2.73`. The Ultimate Character Controller Version 3 bridge source inspected for this page is dated January 2023 and does not declare a minimum or maximum Quest Machine version.

Quest Machine's [current documentation](https://www.pixelcrushers.com/quest_machine/Quest_Machine_Manual.pdf) still lists Ultimate Character Controller support, but that is not a compatibility guarantee for every later patch combination. Install the current bridge from [Opsive Downloads](https://opsive.com/downloads/) for the versions in the project. After upgrading Ultimate Character Controller, Quest Machine, or the bridge, repeat the compile, interaction, inventory-condition, and save tests on this page.

## Before you begin

- Start with a working Ultimate Character Controller Version 3 character. Verify movement, camera, input, and the Interact ability before adding quests.
- Add an inventory and the attributes that quests will read or change. Verify those systems independently first.
- Set up Quest Machine with a quest database and a small quest that can run without the Ultimate Character Controller bridge.
- Back up the project before importing or replacing an integration package.
- If the game will save progress, decide which single Pixel Crushers **Save System** object will own saving before adding savers.

## Install the integration

1. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the Quest Machine integration. The bridge is not included in the base product's Integrations folder before this download.
2. Import the downloaded package after both products compile. Importing it creates the integration files in the project.
3. Allow Unity to compile. Resolve the first Console error before configuring the scene; the bridge requires both Quest Machine and Ultimate Character Controller assemblies.
4. Confirm that the imported support contains **Greet Quest Giver**, **Quest Giver Interactable Target**, the Ultimate Character Controller quest actions and conditions, and the **Opsive Ultimate Character Controller Quest Machine Example** scene.
5. Run the supplied example once before adapting it. The **Get Shotgun** quest is a useful smoke test for interaction, an inventory condition, and an item-removal action.

Do not rely on an old copied support folder after upgrading either product. Reimport the bridge intended for the installed releases, compile, and retest the sample flow.

## Configure the scene and player

1. Add Quest Machine's normal configuration prefab to the scene and assign the project's quest database using the Quest Machine workflow.
2. Add **Quest Journal** to the Ultimate Character Controller player.
3. Keep the player tagged `Player` if bridge fields will leave **Character Name** blank. In a scene with more than one Ultimate Character Controller character, enter an explicit character GameObject name in every quest condition and action instead.
4. On **Ultimate Character Locomotion > Abilities**, add **Greet Quest Giver**.
5. Keep **Start Type** and **Stop Type** set to **Manual**. Quest Machine dialogue messages start and stop this ability; the ability does not initiate the conversation itself.
6. Choose the conversation handoff:
   - **Hide UI** hides the Ultimate Character Controller gameplay UI while the quest dialogue is open.
   - **Disable Gameplay Input** prevents the character from moving or using gameplay actions during dialogue.
   - **Detach Camera** temporarily removes the character from the active Ultimate Character Controller Camera Controller so the dialogue can own the shot.
   The inspected bridge enables all three choices by default.
7. Keep the standard Ultimate Character Controller **Interact** ability and its `Action` input. Interact detects and activates the quest giver; **Greet Quest Giver** only manages the character while the dialogue UI is open.

### Configure the greeting input state

The ability activates an Ultimate Character Controller state named `GreetingQuestGiver` for the duration of the conversation.

- If the character uses Ultimate Character Controller's legacy **Unity Input** component, add a state named `GreetingQuestGiver` and apply the imported `GreetingQuestGiverUnityInputPreset` as its preset.
- If the project uses Unity Input System or another input integration, configure an equivalent `GreetingQuestGiver` state in the provider that owns gameplay input and the cursor. The supplied preset targets **Unity Input** and should not be assumed to configure another provider.
- Test mouse, keyboard, and gamepad separately. The selected dialogue UI and input provider still own navigation and cursor behavior.

## Configure a quest giver

1. Select the NPC or object that should offer the quest.
2. Add Quest Machine's **Quest Giver** component and configure its identity, dialogue UI, and quests through the normal Quest Machine workflow.
3. Add **Quest Giver Interactable Target** to the same GameObject. This component requires **Quest Giver** and starts its player dialogue when Ultimate Character Controller interacts.
4. Add Ultimate Character Controller's **Interactable** component and assign **Quest Giver Interactable Target** in **Targets**.
5. On the player's Interact ability, choose an **Object Detection** mode, **Detect Layers**, and distance that can find the Interactable.
6. Enter Play Mode and approach the NPC. Confirm that Ultimate Character Controller shows the quest giver's ID as the interaction message before testing the quest dialogue.

The bridge's interactable target always reports that it can be used. Put gameplay restrictions such as distance, line of sight, cooldown, or actor state in Ultimate Character Controller's detection/ability setup or in a project-specific target extension.

## Build a Get Shotgun test quest

Use the supplied **Get Shotgun Quest** as a reference instead of starting with a large production quest:

1. Create or select a shotgun item type that is available to the player's Ultimate Character Controller inventory and Item Collection.
2. Create a short quest that the configured quest giver can offer.
3. On the stage that waits for the item, add **UCC Item Count Quest Condition**.
4. Leave **Character Name** blank for a single `Player`-tagged character, select the shotgun **Item Type**, choose **At Least**, and set **Required Value** to `1`.
5. On the hand-in or completion stage, add **Add UCC Item Quest Action** for the same item and set **Amount** to `-1`. A negative amount removes the item.
6. Register the quest in the active quest database, enter Play Mode, accept it, pick up the shotgun, return to the giver, and complete the hand-in.

The expected sequence is visible without code: the quest becomes active, the item condition becomes true after pickup, the return dialogue becomes available, and the shotgun is removed when the completion action runs.

## Choose quest conditions and actions

The bridge adds two conditions and two actions to Quest Machine's condition/action selectors.

| Integration type | Important fields | Result |
| --- | --- | --- |
| **UCC Item Count Quest Condition** | **Character Name**, **Item Type**, **Mode**, **Required Value** | Becomes true when the Ultimate Character Controller inventory count is **At Least** or **At Most** the required value. It checks immediately and then listens for pickup and removal changes. |
| **UCC Attribute Quest Condition** | **Character Name**, **Attribute Name**, **Mode**, **Required Value** | Becomes true when the named Ultimate Character Controller attribute is **At Least** or **At Most** the required value. It checks immediately and listens for that attribute to change. |
| **Add UCC Item Quest Action** | **Character Name**, **Item Type**, **Amount** | Adds a positive amount or removes a negative amount. Removing an equipped matching item unequips it first. An amount of `0` does nothing. |
| **Set UCC Attribute Quest Action** | **Character Name**, **Attribute Name**, **Operation**, **Value** | Uses **Set To Value**, **Modify By Value**, or **Randomize** to change the named Ultimate Character Controller attribute. |

Leave **Character Name** blank only when the first `Player`-tagged object with **Ultimate Character Locomotion** is unambiguously the intended character. The item integrations also require an inventory and access to the matching Item Collection. Attribute names must exactly match an attribute on the character's **Attribute Manager**.

Use the attribute action for quest meters and deliberate direct value changes. Setting the `Health` attribute this way does not run Ultimate Character Controller's normal damage or healing pipeline, so it does not provide attacker, impact, damage, or death semantics. Use the [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/) workflow or a custom quest action when those semantics matter.

## How it runs

1. Ultimate Character Controller's Interact ability detects **Interactable** and calls **Quest Giver Interactable Target**.
2. The target asks Quest Machine's **Quest Giver** to start dialogue with the player.
3. Quest Machine's greeting message starts **Greet Quest Giver**. Ultimate Character Controller applies the selected UI, gameplay-input, camera, and `GreetingQuestGiver` state choices.
4. Quest Machine owns the dialogue and quest graph. Its Ultimate Character Controller conditions read inventory or attribute values and become true when their configured threshold is met.
5. Quest Machine executes the configured Ultimate Character Controller actions when the quest reaches those stages. Ultimate Character Controller owns the resulting inventory or attribute value.
6. When the quest dialogue UI closes, the bridge stops **Greet Quest Giver** and restores the character's Ultimate Character Controller UI, input, camera, and greeting state.

## Save quest and character progress

Quest Machine and Ultimate Character Controller save different data. Configure both deliberately:

1. Keep one Pixel Crushers **Save System** object in the game. Do not add a second Save System component to the Quest Machine object.
2. On **Quest Journal**, assign a unique **Key**, enable **Include In Saved Game Data**, and choose whether completed quests should be remembered.
3. Add **UCC Saver** to the Ultimate Character Controller player and give it a different unique **Key**.
4. Enable only the Ultimate Character Controller categories the save should include: **Save Perspective**, **Save Mouse Settings**, **Save Position**, **Save Attributes**, and **Save Inventory**. The inspected bridge enables all five by default.
5. Save after changing every enabled category, change them again, and load. Confirm that Quest Machine restores the journal while **UCC Saver** restores only the selected character categories.

For item types that can be picked up at runtime but are absent from the starting inventory:

1. Select **Create > Pixel Crushers > Dialogue System > UCC Saver Runtime Pickups**. The legacy `Dialogue System` menu name is used by the shared Pixel Crushers support asset even in a Quest Machine project.
2. Add those item types to **Runtime Items**.
3. Assign the asset to **UCC Saver > Runtime Pickups**.

If Ultimate Inventory System owns inventory saving, keep its saver and disable **Save Inventory** on **UCC Saver** so two systems do not restore the same inventory. Follow the [Ultimate Inventory System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) for the installed versions.

The **UCC Saver** does not automatically preserve arbitrary active abilities, effects, Ultimate Character Controller states, or project-specific item-module data. Its attribute data is restored by array order, so do not reorder the character's attributes between saving and loading without a migration plan.

## Key choices and limitations

| Choice | Use it when | Important consequence |
| --- | --- | --- |
| Leave **Character Name** blank | There is exactly one intended Ultimate Character Controller character tagged `Player` | The bridge uses the first matching character it finds. This is ambiguous for multiple players. |
| Enter an explicit character name | A quest addresses a particular NPC, companion, or local player | The name must match the target GameObject exactly. Renaming that object breaks the lookup. |
| Keep the Ultimate Character Controller camera attached | Quest dialogue should use the normal gameplay view | Disable **Detach Camera** and do not ask another camera system to control the same shot. |
| Let quest dialogue own the camera | Dialogue needs its own framing | Enable **Detach Camera** and provide a working dialogue camera. The stock bridge finds the first active Ultimate Character Controller Camera Controller. |
| Change an attribute directly | A quest updates a meter, cost, or reward value | **Set UCC Attribute Quest Action** changes the attribute value without the richer Health damage/healing context. |
| Save inventory through **UCC Saver** | Ultimate Character Controller is the only inventory owner | Enable **Save Inventory** and test runtime item types, slots, equipped items, and ammunition. |
| Save inventory through Ultimate Inventory System | Ultimate Inventory System owns inventory persistence | Disable **Save Inventory** on **UCC Saver** and keep the Ultimate Inventory System save integration. |

The stock interactable target rejects a non-local network character when Ultimate Character Controller multiplayer support is compiled, but it does not synchronize quest state, dialogue, inventory actions, camera ownership, or saved data. Multiplayer and split-screen projects need an explicit per-player quest, camera, input, save, and network-authority design.

The January 2023 bridge source inspected for this page registers the item-count condition for `OnInventoryPickupItem` but unregisters `OnInventoryPickupItemType` when checking stops. That mismatch can leave a pickup listener registered. Before shipping a quest that repeatedly starts and stops **UCC Item Count Quest Condition**, import the latest bridge and verify its `StopChecking()` implementation, or apply a reviewed local fix.

## Verify in Play Mode

1. Approach the quest giver. The Ultimate Character Controller interaction prompt should appear for the intended NPC.
2. Press the Action input. The quest dialogue should start once, and **Greet Quest Giver** should become active.
3. Confirm that gameplay input, Ultimate Character Controller UI, cursor, and camera follow the selected greeting settings.
4. Accept the test quest. It should appear in the player's Quest Journal.
5. Pick up the required item. **UCC Item Count Quest Condition** should advance the quest at the configured threshold.
6. Return to the giver and complete the quest. A negative **Add UCC Item Quest Action** amount should remove the intended item once.
7. Close the dialogue. The same character should regain Ultimate Character Controller input, UI, camera ownership, and the previous greeting state.
8. Repeat with every supported input device. Test the correct cursor and UI navigation behavior for each one.
9. Save while the quest is active and after changing every enabled **UCC Saver** category. Change the state, load, and verify the journal and character data separately.
10. If the game has multiple players or cameras, repeat the entire flow for each owner. Do not accept a result that affects the first player or camera by accident.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The Ultimate Character Controller quest actions, conditions, or greeting ability are missing | The bridge may not be imported, one product may be absent, or the package may not match the installed releases | Install both products first, then import the current Quest Machine bridge through **Integrations Manager** and resolve the first Console error. |
| The interaction prompt never appears | The Interact ability may not detect the giver's collider/layer, or **Interactable > Targets** may not contain the integration target | Correct **Object Detection**, **Detect Layers**, and range, then assign **Quest Giver Interactable Target** in **Targets**. |
| The prompt appears but dialogue does not start | **Quest Giver**, **Quest Giver Interactable Target**, the dialogue UI, or the quest database may be incomplete | Put both Quest Machine components on the same object, assign its quest/dialogue configuration, and test the ordinary Quest Machine greeting first. |
| The player can move or use items during dialogue | **Greet Quest Giver** may be absent, **Disable Gameplay Input** may be disabled, or the dialogue UI close/open messages may not be reaching it | Add the ability with Manual start/stop, enable the required handoff choices, and confirm it becomes active when greeting begins. |
| The camera goes blank or does not return | **Detach Camera** may be enabled without a dialogue camera, or another system may compete for the first Ultimate Character Controller Camera Controller | Configure one camera owner for the conversation, or disable **Detach Camera** to keep the Ultimate Character Controller camera attached. |
| The cursor or UI navigation is wrong | The active input provider may not have the `GreetingQuestGiver` state, or the legacy Unity Input preset may have been applied to a different provider | Configure the named state on the actual provider and test mouse and gamepad independently. |
| An item condition never becomes true | The character lookup, **Item Type**, inventory, Item Collection, **Mode**, or **Required Value** may not match the runtime character | Use an explicit character name when needed and inspect the actual Ultimate Character Controller inventory count for the selected item type. |
| An attribute condition or action cannot find its value | **Attribute Name** is case-sensitive or the target has no **Attribute Manager** | Enter the exact configured attribute name and confirm it exists on the selected character. |
| A quest changes Health but no damage or death response occurs | The quest action changes the raw attribute rather than calling Ultimate Character Controller's Health damage/healing workflow | Use a custom quest action that calls the intended Health API when combat semantics are required. |
| The wrong character receives an item or attribute change | **Character Name** is blank in a scene with several `Player`-tagged Ultimate Character Controller characters | Enter an explicit character GameObject name or replace the stock lookup with a project-specific player resolver. |
| Quest progress loads but character state does not | Quest Journal may be saved while **UCC Saver** or its category is missing | Add **UCC Saver** with a unique key and enable the exact Ultimate Character Controller categories that should be restored. |
| Character state loads but quest progress does not | **Quest Journal** may not have a unique key or **Include In Saved Game Data** may be disabled | Correct the journal save settings and test a new save slot. |
| Inventory is duplicated or overwritten after loading | **UCC Saver** and Ultimate Inventory System may both be restoring inventory | Choose one inventory save owner. Disable **Save Inventory** on **UCC Saver** when Ultimate Inventory System owns persistence. |
| A runtime pickup disappears after loading | Its item type may be absent from the assigned runtime-pickups asset | Add the item to **UCC Saver Runtime Pickups > Runtime Items** and assign the asset to **UCC Saver**. |
| Item-condition callbacks continue after a quest stops checking | The installed bridge may contain the pickup-event unregistration mismatch described above | Update the bridge or correct and review `UCCItemCountQuestCondition.StopChecking()`, then test repeated quest activation and cancellation. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Interact ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/interact/)
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Attributes](https://opsive.com/support/documentation/ultimate-character-controller/attributes/)
- [Health](https://opsive.com/support/documentation/ultimate-character-controller/attributes/health/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Unity Input System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/input-system/)
- [Ultimate Inventory System integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/)
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)
- [Quest Machine manual](https://www.pixelcrushers.com/quest_machine/Quest_Machine_Manual.pdf)

## Developer reference

The bridge keeps a narrow ownership boundary:

- `QuestGiverInteractableTarget` implements Ultimate Character Controller's interactable target and message interfaces, then calls Quest Machine's `StartDialogueWithPlayer()`. Its multiplayer guard only rejects a known non-local interactor; it does not replicate the interaction.
- `GreetQuestGiver` listens for Quest Machine greeting and dialogue-closed messages. It sends Ultimate Character Controller UI and gameplay-input events, toggles the `GreetingQuestGiver` state, and optionally detaches the first active `CameraController` until dialogue closes.
- `QuestDialogueUIMonitor` sends the close message when the selected quest dialogue UI GameObject is disabled.
- `QuestMachineUCCUtility` resolves a blank character name to the first `Player`-tagged object with `UltimateCharacterLocomotion`; a supplied name uses an exact GameObject lookup.
- `UCCItemCountQuestCondition` and `UCCAttributeQuestCondition` check once, then listen for Ultimate Character Controller inventory or attribute events until Quest Machine marks the condition true.
- `AddUCCItemQuestAction` changes the selected Ultimate Character Controller item amount. `SetUCCAttributeQuestAction` writes the selected attribute directly.
- `UCCSaver` contributes selected Ultimate Character Controller position, perspective, mouse-input, attribute, and inventory data to Pixel Crushers' Save System. Quest Journal remains responsible for quest progress.

Create a custom Quest Machine condition or action when a quest must start or stop an Ultimate Character Controller ability, activate an Ultimate Character Controller state, send an event with project-specific data, apply Health damage/healing semantics, resolve a network player, or persist custom item-module state. Keep Quest Machine responsible for quest decisions and call Ultimate Character Controller's supported systems to perform the character-side result.

---

<a id="page-ultimate-character-controller-integrations-rayfire"></a>

# RayFire

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/rayfire/)


Use the [RayFire](https://assetstore.unity.com/packages/tools/game-toolkits/rayfire-2-342492?aid=1100lGdc) integration in an existing, version-matched project when an Ultimate Character Controller weapon impact should add damage to a RayFire object and let RayFire decide when and how that object breaks.

This is a legacy integration boundary. Read the compatibility section before purchasing RayFire, upgrading either product, or importing the bridge into a new project.

## Compatibility boundary

The original [RayFire for Unity](https://assetstore.unity.com/packages/tools/game-toolkits/rayfire-for-unity-obsolete-148690?aid=1100lGdc) line is now marked obsolete. Its final Asset Store release is `1.89`. The current product is the separate [RayFire 2](https://assetstore.unity.com/packages/tools/game-toolkits/rayfire-2-342492?aid=1100lGdc), which is at `2.12` as of August 2026.

The [Ultimate Character Controller 3.0.5 release notes](https://opsive.com/news/ultimate-character-controller-3-0-5-released/) record a RayFire integration update, but the released Ultimate Character Controller Version 3 source inspected for this page does not contain the RayFire integration package or its source. The existing public integration record names `RayFireImpact` and **Damage Multiplier**, but it does not declare a supported RayFire version range or confirm RayFire 2 compatibility.

Do not assume that the legacy bridge supports RayFire 2 because the products share a name. Before using this workflow:

1. Open [Opsive Downloads](https://opsive.com/downloads/) and confirm that the account offers a RayFire integration intended for Ultimate Character Controller Version 3.
2. Inspect the package notes or source for the RayFire generation it targets.
3. Import it into a version-controlled test project containing the installed Ultimate Character Controller and RayFire versions.
4. Continue only if Unity compiles and the `RayFireImpact` component appears without missing scripts.

If the package targets the obsolete RayFire API, keep it with the matching legacy project. For RayFire 2, obtain an explicitly compatible bridge or implement a small project-owned impact receiver against RayFire 2's current API.

## Before you begin

- Start with a working Ultimate Character Controller Version 3 character and an item that can hit an ordinary collider.
- Configure one simple RayFire object and prove that RayFire can demolish or shatter it without Ultimate Character Controller.
- Use an isolated test scene with one weapon, one collider, and one destructible object before testing fragments, clusters, explosions, pooling, or networking.
- Back up the project before importing or replacing the integration package.

## Install the legacy bridge

1. Install Ultimate Character Controller Version 3 and the version of RayFire that the bridge package explicitly supports.
2. Download the RayFire integration from [Opsive Downloads](https://opsive.com/downloads/). The package is not present in the released Ultimate Character Controller V3 integration directory inspected for this page, so do not expect the local **Integrations Manager** to prove compatibility.
3. Import the bridge and allow Unity to compile.
4. Resolve the first Console error before configuring a target. Missing `RayFire` types normally indicate that the required RayFire generation is absent or that the bridge targets a different API.
5. Confirm that **Add Component** offers `RayFireImpact` and that its Inspector exposes **Damage Multiplier**.

The available public documentation does not state the imported **Damage Multiplier** default. Keep the package's own value for the first smoke test, then tune it from an observed RayFire damage change instead of copying an assumed number.

## Configure the Ultimate Character Controller impact

Ultimate Character Controller must send its object-impact event. A visible hit effect or ordinary Ultimate Character Controller damage does not prove that this event is enabled.

1. Select the character item or spawned object that produces the hit.
2. Open the impact-action group that actually runs for that hit. A shootable, melee item, projectile, and explosion can each use a different group.
3. Add or select **Simple Damage**.
4. Set **Damage Amount** to a small, easy-to-measure test value.
5. Keep **Set Damage Impact Data** enabled so the impact context carries the damage value. This is enabled by default in the released Ultimate Character Controller V3 source.
6. Enable **Invoke On Object Impact**. This is disabled by default in the released Ultimate Character Controller V3 source.
7. Enter Play Mode and use **Debug Impact Context** temporarily if needed to confirm that the intended collider, impact point, and damage data reach the impact action.

When **Use Context Data** is enabled, **Simple Damage** uses damage and force values already supplied by the weapon or an earlier impact action. When it is disabled, the local **Simple Damage** values are used. Choose one clear damage owner so the RayFire result does not change unexpectedly when the item configuration changes.

## Configure a legacy RayFire target

These steps describe the contract documented for the original RayFire integration. Use the Inspector labels in the installed RayFire version when they differ.

1. Configure the object with RayFire's **Rayfire Rigid** or the legacy shatter workflow and prove that its selected demolition type works through RayFire alone.
2. If the RayFire object should accumulate hits, enable its damage feature and set an intentional maximum-damage threshold in RayFire.
3. Add `RayFireImpact` to the GameObject that owns the collider receiving the Ultimate Character Controller hit. When the RayFire component and collider share a GameObject, this is normally the RayFire object itself.
4. If the object is already fragmented and the parent has no collider, add `RayFireImpact` only to the child collider objects that should accept hits.
5. Set **Damage Multiplier** relative to the Ultimate Character Controller test value. For example, fire once and compare RayFire's damage before and after the hit, then adjust the multiplier until the observed change matches the design.
6. Do not place receivers on both a child collider and its parent Rigidbody until you have confirmed that one hit is not being processed twice.

### Choose a scenario

- **Repeated weapon damage:** use a RayFire rigid object with damage enabled and a threshold high enough to observe several hits before demolition.
- **One-hit breakable:** use a low RayFire threshold or the matching legacy shatter workflow. Verify the installed bridge's shatter behavior; the current bridge source was not available for this page.
- **Pre-fragmented wall:** place receivers on the fragment colliders that are actually hit. Start with one fragment before rolling the setup across the wall.
- **Explosion:** confirm that the explosion's own impact-action group enables **Set Damage Impact Data** and **Invoke On Object Impact**. Do not assume that configuring the weapon's direct-hit group also configures the explosion.

## How it runs

1. An Ultimate Character Controller item, projectile, melee hit, or explosion creates an **Impact Callback Context** for the collision.
2. **Simple Damage** supplies the selected damage data and, when enabled, invokes `OnObjectImpact` on the hit target.
3. `RayFireImpact` receives that event on its GameObject and applies the integration's **Damage Multiplier** to the bridge's RayFire-side result.
4. RayFire remains responsible for activation, accumulated damage, the demolition threshold, fragment generation, physics, fading, and reset behavior.

The documented bridge is an impact adapter, not a second destruction system. Ultimate Character Controller decides that a hit occurred and provides the impact context; RayFire decides what that hit does to the destructible object.

## Damage, force, and destruction ownership

Keep these responsibilities separate while tuning:

| Responsibility | Owner | What to verify |
| --- | --- | --- |
| Hit detection and impact context | Ultimate Character Controller item, projectile, melee, or explosion module | The correct collider, point, direction, strength, and damage data are present. |
| Object-impact notification | Ultimate Character Controller **Simple Damage** | **Invoke On Object Impact** is enabled in the impact group that actually ran. |
| Damage conversion | `RayFireImpact` | One Ultimate Character Controller hit changes RayFire damage once, scaled by **Damage Multiplier**. |
| Activation and demolition | RayFire | The installed RayFire object's damage, simulation, and demolition settings allow the result. |
| Fragment physics and cleanup | RayFire or project code | Fragments move, fade, reset, pool, or unload according to the chosen RayFire workflow. |

Ultimate Character Controller **Simple Damage** can also apply **Impact Force** to an ordinary Rigidbody. RayFire may apply its own motion when it activates or demolishes an object. If fragments launch too far or move twice, reduce the competing force path and retest with one owner at a time.

## Pooling, saving, and networking

The documented integration does not add pooling, saved destruction state, or network replication.

- **Pooling and reset:** RayFire-generated fragments are not automatically Ultimate Character Controller Object Pool objects. Use the installed RayFire version's reset/pooling workflow or replace the entire destructible prefab through project code. Test a second destruction after reset, not just the first one.
- **Saving:** decide whether a save records the object as intact, damaged, or destroyed. Restore that state with a project-specific saver or a supported RayFire snapshot/reset feature. The bridge does not add this data to Ultimate Character Controller saves.
- **Networking:** run destruction on the chosen authority and replicate a stable result or deterministic destruction command. A local `OnObjectImpact` callback does not synchronize RayFire fragments, damage, or cleanup to other clients.

For large destructible scenes, budget fragment count, collider count, runtime fragmentation, and cleanup independently of Ultimate Character Controller. The bridge removes neither RayFire's simulation cost nor the cost of placing a receiver on many fragment colliders.

## Verify in Play Mode

1. Trigger the RayFire object through RayFire alone. Confirm that its demolition type, fragments, physics, and reset work before testing Ultimate Character Controller.
2. Hit the object once with the configured Ultimate Character Controller source. Confirm that the expected **Simple Damage** group runs and invokes `OnObjectImpact`.
3. Inspect RayFire's current damage. It should change once. Record the observed change before tuning **Damage Multiplier** because the unavailable bridge source does not reveal which impact value it consumes.
4. Repeat the hit until the RayFire threshold is reached. The object should remain intact before the threshold and demolish through RayFire when the threshold is met.
5. Hit a child collider and the parent collider separately. Each physical hit should be counted once.
6. Compare a direct weapon hit, projectile, melee hit, and explosion separately when the game supports them. Each path has its own impact configuration.
7. Reset or respawn the object and destroy it again. Check damage reset, fragment cleanup, and receiver registration.
8. Save and load before and after destruction if the game persists world state.
9. In a networked game, repeat on the server/host and every client. All peers should agree on the intact/destroyed state and cleanup.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| `RayFireImpact` is missing | The bridge may not be imported, or it may not compile with the installed RayFire generation | Verify the download is intended for Ultimate Character Controller V3 and that RayFire is installed first. Resolve the first Console error. |
| Importing the bridge produces missing RayFire types | The package may target the obsolete RayFire API while the project uses RayFire 2 | Do not rename types blindly. Obtain a RayFire 2-compatible bridge or write a small receiver against RayFire 2's documented API. |
| The weapon hits and spawns effects, but RayFire receives nothing | The active **Simple Damage** group may not enable **Invoke On Object Impact** | Enable the option on the exact direct-hit, projectile, melee, or explosion group that runs. |
| The object-impact event fires but RayFire damage does not change | The receiver may be on a different GameObject, RayFire damage may not be configured, or the installed bridge may expect different impact data | Place the receiver on the hit collider object, verify RayFire's own damage workflow, and inspect the installed bridge before changing the Ultimate Character Controller impact data. |
| Damage changes but the object never breaks | RayFire's damage feature, threshold, simulation type, or demolition type may prevent demolition | Prove the same object can demolish through RayFire alone, then retest the bridge. |
| One hit adds damage twice | Receivers may exist on both the collider and its attached Rigidbody/parent target | Keep one intended receiver path and test the hierarchy one collider at a time. |
| The object breaks on the first small hit | **Damage Multiplier** may be too high, RayFire's threshold may be too low, or the hit may be processed more than once | Measure the damage change from one hit, correct duplicate receivers, then tune the threshold and multiplier. |
| Fragments move with excessive force | Ultimate Character Controller **Impact Force** and RayFire activation/demolition motion may both contribute | Set one force path to zero or a small value, then add the second only when its effect is understood. |
| A pooled or respawned object starts damaged or no longer reacts | RayFire damage/reset state or the receiver lifecycle may not have been restored | Use the supported RayFire reset workflow, confirm damage returns to its initial value, and run a second destruction test. |
| Destruction disappears after loading or differs across clients | The bridge does not persist or replicate RayFire state | Add project-owned save/network state for the destructible object and run impacts on the chosen authority. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Impact Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/action-modules-groups/impact-actions/)
- [Shootable items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/)
- [Melee items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/)
- [Projectiles](https://opsive.com/support/documentation/ultimate-character-controller/objects/trajectory-object/projectile/)
- [Explosions](https://opsive.com/support/documentation/ultimate-character-controller/objects/explosions/)
- [Object Pool](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/object-pool/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [RayFire Unity documentation](https://rayfirestudios.com/category/online-help-unity/)

## Developer reference

In the released Ultimate Character Controller V3 source, `SimpleDamage` defaults **Set Damage Impact Data** to `true`, **Invoke On Object Impact** to `false`, **Damage Amount** to `10`, **Impact Force** to `2`, and **Impact Force Frames** to `15`. Treat those as Ultimate Character Controller defaults only; no RayFire-side default was source-verified for the unavailable bridge.

When object-impact notification is enabled, Ultimate Character Controller invokes the callback on the impact collider GameObject, its attached Rigidbody GameObject when different, and the original impact target when different. This is why receiver placement matters and why duplicating `RayFireImpact` through a hierarchy can process one physical hit more than once.

A project-owned RayFire 2 adapter can register for Ultimate Character Controller's `OnObjectImpact` event with an `ImpactCallbackContext`. Read the hit object, collider, position, direction, and strength from `ImpactCollisionData`; treat `ImpactDamageData` as optional; then call only the API supported by the installed RayFire 2 release. Unregister the handler with the same event signature when the receiver is destroyed.

The legacy bridge source was not available in the released Ultimate Character Controller V3 checkout or public package record inspected for this page. Its exact RayFire method calls, RayFire 2 behavior, **Damage Multiplier** default, pooling hooks, save hooks, and network behavior are therefore intentionally not claimed here.

---

<a id="page-ultimate-character-controller-integrations-realistic-car-controller"></a>

# Realistic Car Controller

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/realistic-car-controller/)


Use the [Realistic Car Controller](https://assetstore.unity.com/packages/tools/physics/realistic-car-controller-16296?aid=1100lGdc) integration when an Ultimate Character Controller character should enter a standard RCC vehicle, hand driving control to RCC, and return to normal character control after exiting.

The integration supplies `RCCDriveSource`. Ultimate Character Controller's **Drive** ability handles detecting, entering, seating, and exiting the character; RCC remains responsible for vehicle physics, controls, and its optional vehicle camera.

## Compatibility boundary

The released Ultimate Character Controller Version 3 checkout inspected for this page includes `RealisticCarController.unitypackage`. Its source implements `RCCDriveSource` against the `RCC_CarControllerV4` and `RCC_Camera` APIs, but the package does not declare a minimum or maximum RCC version.

[Realistic Car Controller](https://assetstore.unity.com/packages/tools/physics/realistic-car-controller-16296?aid=1100lGdc) is now at `5.0.0`, a major update released in May 2026. The inspected Opsive bridge predates that release, so its presence in the Ultimate Character Controller package and **Integrations Manager** does not by itself prove RCC V5 compatibility. Before updating a working project or starting with RCC V5:

1. Import RCC and the Opsive bridge into a version-controlled test project.
2. Confirm that `RCCDriveSource` compiles without missing RCC types.
3. Confirm that the vehicle still contains `RCC_CarControllerV4` and that an RCC camera, when used, exposes the API expected by the bridge.
4. Complete the enter, drive, camera, and exit tests on this page before moving the setup into the production scene.

Do not rename missing RCC types merely to make the bridge compile. Use a bridge explicitly compatible with the installed RCC release or implement a project-owned `IDriveSource` against that release. Realistic Car Controller Pro uses a different API and the separate [`RCCPDriveSource` integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/realistic-car-controller-pro/).

## Before you begin

- Create and test a vehicle with RCC alone. It should steer, brake, and use its intended camera before Ultimate Character Controller is connected.
- Create a working Ultimate Character Controller Version 3 character with the [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/).
- Add a detection collider or trigger for the vehicle and at least one **Move Towards Location** for entry and exit.
- Create and assign the Physic Material that RCC uses for the vehicle. `RCCDriveSource` reads and changes its bounciness at runtime, so this reference cannot be empty.
- Back up the project before changing RCC or replacing the bridge.

## Install the bridge

1. Install and verify the intended RCC release first.
2. In Unity, select **Tools > Opsive > Ultimate Character Controller > Integrations Manager**.
3. Open **Available Integrations** and locate **Realistic Car Controller**. The **Integration** button opens the setup documentation; it does not import the bridge.
4. Download the Ultimate Character Controller Version 3 Realistic Car Controller integration from [Opsive Downloads](https://opsive.com/downloads/), then import `RealisticCarController.unitypackage`.
5. Allow Unity to compile and resolve the first Console error before continuing.
6. Confirm that **Add Component** offers **RCC Drive Source** and that the component shows **Vehicle Layers**, **Physics Material**, **Driver Location**, **Animator ID**, and **Use Car Camera Controller**.

If the package does not compile with the installed RCC generation, stop at this point. The remaining steps cannot correct an API mismatch.

## Set up the vehicle

1. Select the vehicle GameObject that owns `RCC_CarControllerV4`. Add **RCC Drive Source** to that same GameObject; the bridge searches there rather than through the parent hierarchy.
2. Set **Vehicle Layers** to the RCC physics layers that should ignore Ultimate Character Controller's **SubCharacter** layer. The packaged default contains seven masks for project layers 8 through 14. Check the layer names in the current project instead of assuming those numbers still belong to RCC.
3. Assign **Physics Material**. The bridge stores its starting bounciness, sets bounciness to `0` while the vehicle is inactive, and restores the stored value while the character drives.
4. Create a child Transform at the seated position and rotation, then assign it to **Driver Location**.
5. Set **Animator ID** when this vehicle needs a distinct character entry, seated, or exit animation set. Leave it at `0` only when the character Animator is built for that value.
6. Add one or more [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) components below the Drive Source GameObject. Place them at valid door-side entry and exit positions.
7. Put the vehicle's detection collider on a layer included by the Drive ability's **Detect Layers** and make sure the Drive Source is on that object or a parent.
8. Finish the character-side entry, exit, animation, visibility, and item choices on the [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/) page.

Avoid sharing one mutable Physic Material between independently controlled vehicles until the behavior has been tested. Because the bridge changes the material's bounciness, one vehicle can affect another vehicle that uses the same runtime material instance.

## Choose the camera owner

**Use Car Camera Controller** is enabled by default.

- **Use the RCC camera:** keep the option enabled and place one `RCC_Camera` in the scene. After entry completes, the bridge disables the character's Ultimate Character Controller Camera Controller GameObject, enables the RCC camera, and targets the entered vehicle. When exit begins, it switches back to the Ultimate Character Controller camera.
- **Keep the Ultimate Character Controller camera:** disable the option. The bridge leaves both camera systems alone, so configure the active Ultimate Character Controller view type to follow the moving character and vehicle presentation appropriately.
- **Multiple local vehicles:** the bridge uses the first `RCC_Camera` it finds rather than a per-vehicle camera reference. Use one intentional local RCC camera or replace the camera handoff with project-owned logic.

The bridge temporarily disables the RCC camera's **TPS Auto Focus** while that camera is inactive and restores the previous value when RCC takes camera control.

## Choose character input and item behavior

`RCCDriveSource` does not translate Ultimate Character Controller input into RCC input. It enables the RCC vehicle controller after the character is seated, at which point RCC reads its own configured controls.

- Use the Drive ability's input for entering and exiting, and configure steering, throttle, brake, and other vehicle controls in RCC.
- Use **Allow Equipped Slots**, **Can Aim**, and **Disable Mesh Renderers** on Drive to decide whether the character keeps items, can aim, or remains visible while seated.
- Test overlapping bindings deliberately. An input used both to exit and to operate the vehicle can trigger both systems during the same frame.

## How it runs

At scene start, `RCCDriveSource` collects the vehicle's child colliders, finds `RCC_CarControllerV4`, records the assigned Physic Material's bounciness, configures the requested layer collision ignores, and disables RCC vehicle control. If RCC owns the camera, the bridge also disables the found RCC camera.

The Drive ability moves or teleports the character into place. Once entry completes, `EnteredVehicle` enables the RCC controller, restores the vehicle material's bounciness, and hands the camera to RCC when requested. Ultimate Character Controller keeps the character aligned to **Driver Location** and ignores collisions with the colliders reported by the Drive Source.

When a valid exit begins, `ExitVehicle` disables RCC control, sets the material's bounciness to `0`, restores the Ultimate Character Controller camera when needed, and releases the stored character reference. The Drive ability then completes the character's exit and restores ordinary locomotion, collision, items, and animation ownership.

## Verify in Play Mode

1. Start away from the vehicle. Confirm that RCC does not accept driving input before the character enters.
2. Approach the detection volume and confirm the Drive ability identifies the vehicle.
3. Enter the vehicle. Confirm the character uses the intended Move Towards Location or immediate-entry option and reaches **Driver Location**.
4. After entry completes, confirm that RCC accepts steering, throttle, and brake input and that the character does not push against the vehicle colliders.
5. If RCC owns the camera, confirm that the Ultimate Character Controller camera turns off, the RCC camera turns on, and the RCC camera targets the entered vehicle. If Ultimate Character Controller owns the camera, confirm there is still only one active audio listener and intended gameplay camera.
6. Test the selected item, aiming, and mesh-renderer behavior while seated.
7. Exit at every configured location. Confirm RCC input stops as exit begins, the intended camera returns, and the character can move normally after the exit completes.
8. Enter a second time. Confirm the vehicle material, controls, colliders, and camera reset correctly.
9. Repeat with every supported input device. For split-screen or networking, repeat for each player and authority role rather than treating a single local test as sufficient.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The bridge produces missing-type compiler errors | The inspected bridge expects `RCC_CarControllerV4` and `RCC_Camera`; the installed RCC release may expose a different API | Use a version-matched bridge or implement `IDriveSource` for the installed RCC release. Do not rename RCC classes blindly. |
| `RCCDriveSource` reports that the RCC controller is missing | **RCC Drive Source** and the RCC controller may be on different GameObjects | Put both components on the same vehicle GameObject. |
| Play Mode throws an error while the bridge starts | **Physics Material** or another required reference may be empty | Assign the vehicle's Physic Material and **Driver Location**, then retry in an isolated scene. |
| The vehicle never moves | Entry may not have completed, RCC input may be unconfigured, or another script may keep the controller disabled | Confirm Drive reaches its seated state, then test RCC's own input setup with the enabled vehicle controller. |
| The vehicle moves before entry | Another component may re-enable RCC after `RCCDriveSource` disables it | Give one system ownership of the RCC controller and disable automatic vehicle activation that bypasses the Drive Source. |
| The character collides with or pushes the vehicle | **Vehicle Layers** may not match the current RCC layer setup | Replace the packaged layer masks with the actual RCC physics layers in this project and retest each collider. |
| The character sits at the origin or faces the wrong way | **Driver Location** is missing or misaligned | Assign a dedicated child Transform and align its position and forward direction to the seat. |
| The camera does not switch to RCC | **Use Car Camera Controller** may be disabled, no `RCC_Camera` may exist, or the bridge may find the wrong camera | Enable the option, keep one intentional local RCC camera, and verify it can target the RCC vehicle without Ultimate Character Controller. |
| The Ultimate Character Controller camera does not return after exit | The exit may have been interrupted before the bridge callback or another script may control the camera GameObjects | Confirm Drive reaches a valid exit, then trace camera ownership so only one handoff controls each camera. |
| Exiting does nothing | Drive requires at least one clear Move Towards Location even for immediate entry and exit | Add or clear an exit location below the Drive Source hierarchy. |
| Another vehicle's grip changes | Several vehicles may share the Physic Material whose bounciness the bridge changes | Give independently controlled vehicles separate runtime material instances or replace the shared-material behavior. |

## Saving, networking, and multiple players

The inspected bridge does not save vehicle state, select network authority, synchronize RCC input, or replicate camera ownership.

- Save the vehicle Transform, RCC-specific state, damage, fuel, and occupied/unoccupied state through the project's save system. Restore the Ultimate Character Controller Drive state and camera only through a tested re-entry workflow.
- Let the chosen server or vehicle owner drive the authoritative RCC simulation, then synchronize it through the networking solution used by the project.
- Apply camera and input handoff only for the owning local player. The bridge's scene-wide `RCC_Camera` lookup and GameObject activation are not a split-screen or multiplayer ownership system.
- Decide what happens when a player disconnects, dies, unloads the scene, or saves while seated. The bridge contains no recovery policy for those cases.

## Related pages

- [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/)
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/)
- [Camera Controller](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Animator parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Realistic Car Controller Pro](https://opsive.com/support/documentation/ultimate-character-controller/integrations/realistic-car-controller-pro/)
- [Official Realistic Car Controller documentation](https://www.bonecrackergames.com/realistic-car-controller/)

## Developer reference

The packaged `RCCDriveSource` implements `IDriveSource` and exposes the vehicle GameObject, Transform, child colliders, **Driver Location**, and **Animator ID** to the Drive ability. `EnterVehicle` and `ExitedVehicle` do not add bridge behavior. RCC control is enabled in `EnteredVehicle` and disabled in `ExitVehicle`.

The serialized bridge defaults are:

| Field | Packaged default |
| --- | --- |
| **Vehicle Layers** | Seven masks targeting project layers 8 through 14 |
| **Physics Material** | Unassigned |
| **Driver Location** | Unassigned |
| **Animator ID** | `0` |
| **Use Car Camera Controller** | Enabled |

The bridge calls `Physics.IgnoreLayerCollision` between Ultimate Character Controller's **SubCharacter** layer and every configured vehicle layer. This changes the project-wide runtime layer pair, not only collisions for the selected vehicle.

The current Ultimate Character Controller integration manifest still lists Realistic Car Controller asset ID `16296`, and [Ultimate Character Controller 3.0.10 release notes](https://opsive.com/news/ultimate-character-controller-3-0-10-released/) record an RCC integration update. Neither source declares RCC V5 support. The exact compatibility boundary for a newer RCC release must therefore be proven by compiling the packaged source and completing the runtime checks above.

---

<a id="page-ultimate-character-controller-integrations-realistic-car-controller-pro"></a>

# Realistic Car Controller Pro

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/realistic-car-controller-pro/)


Use the [Realistic Car Controller Pro](https://assetstore.unity.com/packages/tools/physics/realistic-car-controller-pro-178967?aid=1100lGdc) integration when an Ultimate Character Controller character should enter an RCC Pro vehicle, hand driving control to RCC Pro, and return to normal character control after exiting.

The packaged component is `RCCProDriveSource`. Ultimate Character Controller's **Drive** ability handles detecting, entering, seating, and exiting the character; RCC Pro remains responsible for vehicle physics, input, and its optional vehicle camera.

## Compatibility and availability

The local bridge package inspected for this page is named `RealisticCarControllerPro.unitypackage`. It contains `RCCProDriveSource`, which targets the `RCCP_CarController` and `RCCP_Camera` APIs. The package is dated February 2025 and contains no minimum or maximum RCC Pro version metadata.

Current publisher sources describe newer July 2026 releases: the [Unity Asset Store](https://assetstore.unity.com/packages/tools/physics/realistic-car-controller-pro-178967?aid=1100lGdc) lists `2.55.0.LTS`, while the [RCC Pro publisher page](https://www.bonecrackergames.com/realistic-car-controller-pro/) advertises `2.60.0`. Neither source declares compatibility with this Opsive bridge.

The current Ultimate Character Controller Version 3 **Integrations Manager** manifest does not list RCC Pro, although this documentation page and the inspected local package exist. Before planning around the integration:

1. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and confirm that the Ultimate Character Controller Version 3 RCC Pro package is available to the project.
2. Check any package notes for the RCC Pro release it targets.
3. Import RCC Pro and the bridge into a version-controlled test project.
4. Continue only when `RCCProDriveSource` compiles without missing RCC Pro types and passes the runtime checks below.

Do not substitute the standard RCC integration. It uses different controller and camera classes. If the available bridge does not match the installed RCC Pro release, use a compatible package or implement a project-owned `IDriveSource` against that release.

## Before you begin

- Create and test an RCC Pro vehicle without Ultimate Character Controller. Steering, braking, and the intended RCC Pro camera should work first.
- Create a working Ultimate Character Controller Version 3 character with the [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/).
- Add a vehicle detection collider or trigger and at least one **Move Towards Location** for entering and exiting.
- Create and assign the Physic Material used by the vehicle. `RCCProDriveSource` reads and changes its bounciness at runtime, so the reference cannot be empty.
- Back up the project before importing or replacing the bridge.

## Install the bridge

1. Install the intended RCC Pro release and use its setup workflow to create a working vehicle.
2. Confirm that the vehicle has `RCCP_CarController` and can be controlled through RCC Pro alone.
3. Download the Ultimate Character Controller Version 3 RCC Pro integration from [Opsive Downloads](https://opsive.com/downloads/). Do not use the **Integrations Manager** entry for standard **Realistic Car Controller** as a substitute.
4. Import `RealisticCarControllerPro.unitypackage` and allow Unity to compile.
5. Resolve the first Console error before configuring the vehicle. Missing `RCCP` types indicate a package or API mismatch, not an Inspector setup problem.
6. Confirm that **Add Component** offers **RCC Pro Drive Source** and that its Inspector shows **Vehicle Layers**, **Physics Material**, **Driver Location**, **Animator ID**, and **Use Car Camera Controller**.

The old page called the component `RCCPDriveSource`. The inspected packaged class is `RCCProDriveSource`; use the class that actually arrives in the verified package.

## Set up the vehicle

1. Select the vehicle GameObject that owns `RCCP_CarController`. Add **RCC Pro Drive Source** to that same GameObject; the bridge searches there rather than through a parent.
2. Set **Vehicle Layers** to the RCC Pro physics layers that should ignore Ultimate Character Controller's **SubCharacter** layer. The packaged default contains four masks for project layers 15 through 18. Verify the actual layer names in the project instead of assuming those numbers still belong to RCC Pro.
3. Assign **Physics Material**. The bridge stores its starting bounciness, sets bounciness to `0` while the vehicle cannot be controlled, and restores the stored value while the character drives.
4. Create a child Transform at the driver's seated position and rotation, then assign it to **Driver Location**.
5. Set **Animator ID** when this vehicle needs its own character entry, seated, or exit animation set. Leave `0` only when the character Animator is built for that value.
6. Add one or more [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/) components below the Drive Source GameObject. Place them at clear door-side entry and exit positions.
7. Put the detection collider on a layer included by the Drive ability's **Detect Layers**. Ensure the Drive Source is on that object or a parent so Drive can find it.
8. Complete the character's entry, exit, animation, visibility, and item choices on the [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/) page.

Avoid sharing one mutable Physic Material between independently controlled vehicles until the behavior has been tested. The bridge changes the material's bounciness, so one vehicle can affect another that uses the same runtime material instance.

## Choose the camera owner

**Use Car Camera Controller** is enabled by default.

- **Use the RCC Pro camera:** keep the option enabled and place one `RCCP_Camera` in the scene. After entry completes, the bridge disables the character's Ultimate Character Controller Camera Controller GameObject, enables the RCC Pro camera, and targets the entered `RCCP_CarController`. When exit begins, it switches back to the Ultimate Character Controller camera.
- **Keep the Ultimate Character Controller camera:** disable the option. The bridge leaves both camera systems unchanged, so configure the active Ultimate Character Controller view type for the desired vehicle framing.
- **Multiple local vehicles:** the bridge uses the first `RCCP_Camera` found in the scene instead of a serialized per-vehicle reference. Use one intentional local camera or replace the handoff with project-owned selection logic.

The bridge temporarily disables the RCC Pro camera's **TPS Auto Focus** while that camera is inactive and restores the previous value when RCC Pro takes camera control.

## Choose character input and item behavior

`RCCProDriveSource` does not translate Ultimate Character Controller input into RCC Pro input. After entry completes it calls `SetCanControl(true)` on `RCCP_CarController`; RCC Pro then reads its own configured controls.

- Use Drive's input for entering and exiting. Configure steering, throttle, brake, camera, and mobile controls in RCC Pro.
- Use **Allow Equipped Slots**, **Can Aim**, and **Disable Mesh Renderers** on Drive to decide whether the character keeps items, can aim, or remains visible while seated.
- Test overlapping bindings. An input assigned both to a vehicle action and to exiting can reach both systems during the same frame.

The bridge does not equip, unequip, hide, save, or synchronize items itself. Those choices remain with the Ultimate Character Controller Drive and item systems.

## How it runs

At scene start, `RCCProDriveSource` collects the vehicle's child colliders, requires `RCCP_CarController` on the same GameObject, records the assigned Physic Material's bounciness, configures the requested layer collision ignores, and calls `SetCanControl(false)`. If RCC Pro owns the camera, the bridge also disables the found RCC Pro camera.

The Drive ability moves or teleports the character into place. Once entry completes, `EnteredVehicle` stores the character, restores the vehicle material's bounciness, calls `SetCanControl(true)`, and hands the camera to RCC Pro when requested. Ultimate Character Controller keeps the character aligned to **Driver Location** and ignores collisions with the colliders reported by the Drive Source.

When a valid exit begins, `ExitVehicle` calls `SetCanControl(false)`, sets the material's bounciness to `0`, restores the Ultimate Character Controller camera when needed, and releases the stored character reference. Drive then completes the character's exit and restores ordinary locomotion, collision, items, and animation ownership.

## Verify compilation and Play Mode behavior

1. Import both products into a clean test project and confirm that Unity compiles with no missing `RCCP_CarController`, `RCCP_Camera`, or other RCC Pro API errors.
2. Start away from the vehicle. Confirm that the vehicle does not accept driving input before the character enters.
3. Approach the detection volume and confirm that Drive identifies the vehicle.
4. Enter the vehicle. Confirm the character uses the intended Move Towards Location or immediate-entry option and reaches **Driver Location**.
5. After entry completes, confirm that RCC Pro accepts steering, throttle, and brake input and that the character does not push against the vehicle colliders.
6. If RCC Pro owns the camera, confirm that the Ultimate Character Controller camera turns off, the RCC Pro camera turns on, and it targets the entered vehicle. With the Ultimate Character Controller camera retained, confirm that only the intended gameplay camera and audio listener remain active.
7. Test the chosen item, aiming, and character visibility behavior while seated.
8. Exit from every configured location. RCC Pro control should stop as exit begins, the intended camera should return, and the character should move normally after exit completes.
9. Enter again and repeat the test. Confirm that control, bounciness, colliders, and camera state reset correctly.
10. Repeat for every supported input device. In split-screen or multiplayer, test each local player and authority role separately.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Importing the bridge produces missing `RCCP` types | The installed RCC Pro API may not match the February 2025 bridge | Obtain a version-matched bridge or implement `IDriveSource` for the installed RCC Pro release. Do not rename RCC Pro classes blindly. |
| **RCC Pro Drive Source** is absent but **RCCP Drive Source** is expected | The old page used a different class name | Inspect the imported package. The locally inspected class is `RCCProDriveSource`; remove stale or duplicate bridge scripts before retrying. |
| The Console says that the RCC controller is missing | The Drive Source and `RCCP_CarController` may be on different GameObjects | Put both components on the same vehicle GameObject. |
| Play Mode throws an error during bridge startup | **Physics Material** or another required reference may be empty | Assign the vehicle's Physic Material and **Driver Location**, then retry in an isolated scene. |
| The vehicle never responds after entry | Drive may not have reached the seated state, RCC Pro input may be unconfigured, or another script may call `SetCanControl(false)` | Confirm `EnteredVehicle` ran, then test the same RCC Pro controls with the vehicle explicitly controllable. |
| The vehicle responds before entry | Another RCC Pro manager or project script may call `SetCanControl(true)` after bridge initialization | Give one system control ownership and disable automatic activation that bypasses the Drive Source. |
| The character collides with or pushes the vehicle | **Vehicle Layers** may not match the current RCC Pro project layers | Replace the packaged masks with the RCC Pro physics layers actually used by the vehicle and retest its child colliders. |
| The character sits at the origin or faces the wrong way | **Driver Location** is missing or misaligned | Assign and orient a dedicated seat Transform. |
| The camera does not switch to RCC Pro | **Use Car Camera Controller** may be disabled, no `RCCP_Camera` may exist, or the bridge may find the wrong camera | Enable the option, keep one intentional local RCC Pro camera, and prove that camera can target the vehicle without Ultimate Character Controller. |
| The Ultimate Character Controller camera does not return | Exit may be blocked or interrupted, or another script may control the camera GameObjects | Confirm Drive begins a valid exit and trace camera ownership so only one handoff controls each camera. |
| Exit input does nothing | Drive still requires at least one clear Move Towards Location | Add or clear an exit location below the Drive Source hierarchy. |
| Another vehicle's grip changes | Several vehicles may share the Physic Material whose bounciness the bridge changes | Give independently controlled vehicles separate runtime material instances or replace the shared-material behavior. |

## Saving, networking, and multiple players

The inspected bridge contains no save integration, authority check, network messages, player-camera selection, or RCC Pro synchronization code. RCC Pro may supply its own networking add-ons, but importing one does not automatically network the Ultimate Character Controller entry and exit workflow.

- Save the vehicle Transform, RCC Pro-specific state, damage, fuel, and occupied/unoccupied state through the project's save system. Restore the player through a tested Drive re-entry workflow.
- Choose one server or owning client to control the authoritative RCC Pro simulation, then synchronize it through the project's networking solution.
- Apply input and camera handoff only for the owning local player. The bridge's scene-wide `RCCP_Camera` lookup is not a split-screen ownership system.
- Define recovery for disconnecting, dying, unloading the scene, or saving while seated. The bridge has no policy for those cases.

## Related pages

- [Drive ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/detect-object-ability-base/drive/)
- [Move Towards Location](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/move-towards-location/)
- [Camera Controller](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Animator parameters](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-parameters/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Standard Realistic Car Controller](https://opsive.com/support/documentation/ultimate-character-controller/integrations/realistic-car-controller/)
- [Official Realistic Car Controller Pro documentation](https://www.bonecrackergames.com/realistic-car-controller-pro/)

## Developer reference

The packaged `RCCProDriveSource` implements `IDriveSource` and exposes the vehicle GameObject, Transform, child colliders, **Driver Location**, and **Animator ID** to Drive. `EnterVehicle` and `ExitedVehicle` do not add bridge behavior. RCC Pro control is enabled in `EnteredVehicle` and disabled in `ExitVehicle`.

The serialized bridge defaults are:

| Field | Packaged default |
| --- | --- |
| **Vehicle Layers** | Four masks targeting project layers 15 through 18 |
| **Physics Material** | Unassigned |
| **Driver Location** | Unassigned |
| **Animator ID** | `0` |
| **Use Car Camera Controller** | Enabled |

The bridge calls `Physics.IgnoreLayerCollision` between Ultimate Character Controller's **SubCharacter** layer and every configured vehicle layer. This changes the project-wide runtime layer pair rather than only the colliders on the selected vehicle.

The inspected package was not compiled against the current July 2026 RCC Pro release during this documentation update, and neither the package nor the current Opsive integration manifest provides a supported version range. Compatibility must therefore be established through the clean-project compile check and full entry/drive/exit test above.

---

<a id="page-ultimate-character-controller-integrations-rewired"></a>

# Rewired

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/rewired/)


Use the [Rewired](https://assetstore.unity.com/packages/tools/utilities/rewired-21676?aid=1100lGdc) integration when Rewired should own the player, device, action maps, and runtime rebinding while Ultimate Character Controller continues to request movement, look, ability, and item inputs by name.

The bridge adds **Rewired Input** as an Ultimate Character Controller `PlayerInput` implementation. It does not configure device ownership, UI navigation, touch controls, split-screen cameras, or saved bindings by itself.

## Compatibility boundary

The packaged Ultimate Character Controller Version 3 bridge source was last updated in 2023 and declares no minimum or maximum Rewired version. It uses the longstanding `ReInput.players.GetPlayer`, `Player.GetButton`, `Player.GetAxis`, and Rewired mouse APIs. The current [Rewired documentation](https://guavaman.com/projects/rewired/docs/) identifies version `1.1.62.7`, also listed by the Asset Store in March 2026, but neither source states that this particular Opsive bridge was tested against it.

Rewired supplies different installations for different Unity generations. Install the Rewired branch intended for the project's Unity version, then compile the Opsive bridge in a clean test project before replacing input in the main scene. Rewired's own integration list describes the Ultimate Character Controller package as a third-party integration maintained outside Rewired.

The inspected bridge also calls `UnityEngine.Input` directly for Escape, mouse-button cursor capture, and inherited joystick-connected detection. A Rewired release that can use Unity's newer input backend does not remove those bridge-side calls. Test the project's **Active Input Handling** setting on every target platform, and adapt the bridge if that setting makes the legacy calls unavailable.

## Before you begin

- Set up and test the Ultimate Character Controller character, camera, abilities, and items with one existing input implementation first.
- Install [Rewired](https://assetstore.unity.com/packages/tools/utilities/rewired-21676?aid=1100lGdc) and complete its installer for the current Unity version.
- Decide which Rewired Player owns each local character and which devices that Player may use.
- Make a backup before replacing the Rewired Input Manager or importing a sample configuration into an existing Rewired project.

## Install Rewired and the bridge

1. Import Rewired, then run **Window > Rewired > Setup > Run Installer** if its installer does not start automatically.
2. Open **Window > Rewired > Help > About** and confirm the installed Rewired version and Unity branch before continuing.
3. In Ultimate Character Controller, open **Tools > Opsive > Ultimate Character Controller > Integrations Manager** and select **Available Integrations**.
4. Locate **Rewired**. The **Integration** button opens this documentation and **Asset Store** opens Rewired; neither button imports the Opsive package.
5. Download the Ultimate Character Controller Version 3 Rewired integration from [Opsive Downloads](https://opsive.com/downloads/) and import `Rewired.unitypackage` after Rewired is installed.
6. Resolve the first compiler error. Continue only when **Add Component** offers **Rewired Input** with no missing Rewired types.

The package contains the bridge script, one Ultimate Character Controller **Rewired Input Manager** prefab, and separate **Rewired Input Manager Solo** and **Rewired Input Manager Co-op** prefabs under the Ultimate Inventory System folder. For an Ultimate Character Controller-only setup, use the prefab under `Assets/Opsive/Shared/Integrations/Rewired/UltimateCharacterController`, not an inventory-system prefab chosen only by its name.

## Configure the Rewired Input Manager

### Start from the supplied Ultimate Character Controller configuration

For a new Rewired project, drag **Rewired Input Manager** from the integration's `UltimateCharacterController` folder into the scene. The supplied prefab is marked to persist between scene loads and contains one game Player named `Player0`, plus example keyboard, mouse, and joystick maps for common Ultimate Character Controller action names such as `Horizontal`, `Vertical`, `Mouse X`, `Mouse Y`, `Controller X`, `Controller Y`, `Jump`, `Fire1`, `Reload`, `Action`, item selection, and perspective switching.

Treat this prefab as a starting configuration, not a required source of truth. Keep only one active Rewired Input Manager. Adding the persistent prefab to several scenes can create competing managers when scenes change.

### Keep an existing Rewired configuration

Do not replace a working Rewired Input Manager merely to obtain the Ultimate Character Controller actions. Add the Ultimate Character Controller-requested action names to the existing manager, create keyboard, mouse, joystick, or custom-controller maps, and assign those maps to the intended Players.

Every name requested by Ultimate Character Controller must match a Rewired Action exactly, including spaces and capitalization. Changing a key or controller element through Rewired is safe; renaming the Action without updating the Ultimate Character Controller Inspector is not.

## Replace the character input component

1. In Edit Mode, expand the character and select its input GameObject. A character named `Atlas` commonly starts with an `AtlasInput` child.

   ![The AtlasInput child selected beneath the Atlas character with its legacy Unity Input component ready to be replaced.](https://opsive.com/wp-content/uploads/2020/08/UnityInputGameObject.webp?v=3efba5fe6ff5)

2. Remove the existing Opsive input implementation from that GameObject, such as **Unity Input System** or legacy **Unity Input**. Keep the input GameObject.
3. Add **Rewired Input** to the same GameObject.
4. Set **Player ID** to the intended Rewired Player ID. The packaged default is `0`.
5. Select the character root. On **Player Input Proxy**, assign the new **Rewired Input** component to **Player Input**.
6. Keep **Horizontal Look Input Name** and **Vertical Look Input Name** matched to Rewired Actions. The inherited defaults are `Mouse X` and `Mouse Y`.
7. Enter Play Mode once and confirm that the proxy moves the input GameObject beneath Ultimate Character Controller's persistent scheduler while continuing to route input to the original character. Do not use its runtime hierarchy position as the player-ownership rule.

## Assign players and devices

Rewired owns controller assignment; **Player ID** only tells this bridge which Rewired Player to read.

- **Single player:** use one Rewired Player, usually ID `0`, and assign the keyboard, mouse, and desired joysticks to it.
- **Local split-screen:** create one Rewired Player per character, give each character its own **Rewired Input** and **Player Input Proxy** reference, and set a different **Player ID** on each bridge. Complete the matching camera, viewport, and HUD setup on [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/).
- **Shared keyboard:** map distinct keys to the intended Players deliberately. The bridge does not divide a keyboard or prevent the same device from controlling several Players.
- **Connect and reconnect:** configure Rewired's controller assignment and reassignment policy. The bridge keeps reading the selected Player, so device changes must update that Player's controllers rather than silently changing the character's **Player ID**.

The supplied Ultimate Character Controller manager prefab defines only one gameplay Player. It is not a ready-made split-screen configuration.

## Configure Unity UI and touch controls

### Unity UI

**Rewired Input** controls Ultimate Character Controller gameplay, not the EventSystem. To navigate Unity UI through Rewired:

1. Select the scene's **EventSystem**.
2. Disable or remove the ordinary **Standalone Input Module**.
3. Add **Rewired Standalone Input Module**.
4. Create the UI Actions requested by that module, map them to the intended Players, and configure which Player IDs may control the UI.

Use separate menu Actions rather than movement and gameplay Actions when rebinding must not leave a player unable to navigate the menu. See Rewired's [Standalone Input Module guide](https://guavaman.com/projects/rewired/docs/RewiredStandaloneInputModule.html) for multi-player EventSystems and Player Mouse setup.

### Touch controls

Build touch controls through Rewired and its custom-controller workflow. Then enable **Enable Touch Controls** on **Rewired Input**. This field does not create or bind any controls; it makes the bridge report that the pointer is not over UI so Rewired's touch controls can continue driving gameplay.

Remove or disable Ultimate Character Controller virtual controls generated for **Unity Input System** or legacy **Unity Input**. Those controls target different input implementations and do not become Rewired controls when this checkbox is enabled.

Test ordinary menus after enabling the option. Because the bridge bypasses its normal pointer-over-UI check, a gameplay action can also respond while the player touches UI unless the menu disables gameplay input or the Rewired maps are switched appropriately.

## Configure rebinding and persistence

Use Rewired's [Control Mapper](https://guavaman.com/projects/rewired/docs/ControlMapper.html) or a project-owned Rewired mapping screen. The bridge continues requesting the same Action name, so a changed key, button, or axis takes effect without changing Ultimate Character Controller.

The supplied Ultimate Character Controller Rewired Input Manager prefab does not include a `UserDataStore` component. Add an appropriate Rewired [User Data Store](https://guavaman.com/projects/rewired/docs/UserDataStore.html) when mappings, calibration, input behavior, or optional controller assignments must persist. Decide when the game saves and loads this data; the Ultimate Character Controller bridge neither invokes the store nor migrates saved maps after the Rewired manager's defaults change.

## Cursor behavior

The integration-specific defaults are:

| Field | Packaged default | Behavior |
| --- | --- | --- |
| **Player ID** | `0` | Reads that Rewired Player. |
| **Disable Cursor** | Enabled | Locks and hides the cursor while the component is active. |
| **Enable Cursor With Escape** | Enabled | Releases the cursor when the physical Escape key is pressed. |
| **Prevent Look Vector Changes** | Enabled | Stops look updates while the cursor is released. |
| **Enable Touch Controls** | Disabled | Uses the normal pointer-over-UI check. |

Escape and the mouse buttons are read through `UnityEngine.Input`, not a Rewired Action. Rebinding an action named `Unlock Cursor` in the sample manager does not change this code path. Use a project-owned cursor action or bridge extension when cursor release must be fully rebindable.

## How it runs

On `Awake`, **Rewired Input** obtains the Rewired Player identified by **Player ID**. Ultimate Character Controller then asks the component for named buttons and axes through the common `IPlayerInput` interface. The bridge forwards those calls to the selected Rewired Player and obtains the mouse position from that Player's assigned Rewired mouse.

Changing **Player ID** through the component property during Play Mode immediately selects the new Rewired Player. Changing controller ownership within Rewired does not require replacing the bridge because the same Player object receives its new devices and maps.

The inherited Ultimate Character Controller input layer still owns look smoothing, tap and double-press timing, death disabling, gameplay-input events, and the `ConnectedController` state. In the inspected bridge, connected-controller detection comes from the global `UnityEngine.Input.GetJoystickNames` result rather than the selected Rewired Player. Do not use that state as proof that a particular Player owns a joystick.

## Verify compilation and Play Mode behavior

1. Confirm that Rewired and `RewiredInput.cs` compile with no missing types in the target Unity version.
2. Enter Play Mode with one Rewired Input Manager and one character using **Rewired Input**. Confirm that `Horizontal`, `Vertical`, the two look Actions, `Jump`, `Fire1`, `Reload`, and `Action` reach the intended character.
3. Change a keyboard or controller element assignment while keeping the Rewired Action name. The corresponding Ultimate Character Controller behavior should follow the new assignment.
4. Press Escape, then click outside UI. Confirm the cursor releases, look pauses, and the cursor recaptures according to the configured fields.
5. Open a menu. Confirm the Rewired UI module navigates and submits through the intended Player while gameplay input is disabled or its maps are inactive.
6. Disconnect and reconnect each controller. Confirm Rewired restores the intended Player ownership and only that character responds.
7. For split-screen, test one device at a time. Each device should move, look, use items, and navigate only the intended character and UI.
8. Test touch controls on the target device, not only with a mouse in the Editor. Confirm touches do not leak through menus into gameplay.
9. Change a binding, restart the build, and confirm the selected User Data Store restores it.
10. Repeat the test in a development build for every target platform and **Active Input Handling** configuration the project supports.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Importing the bridge produces missing `Rewired` types | Rewired may be absent, installed for another Unity generation, or incompletely installed | Install the correct Rewired branch first and rerun **Window > Rewired > Setup > Run Installer**, then reimport the bridge. |
| **Rewired Input** cannot find its Player | **Player ID** may not exist or the Rewired Input Manager may initialize incorrectly | Keep one active manager, create that Player in Rewired, and use its exact ID. |
| The character does not respond but Rewired sees the device | An Ultimate Character Controller input name may not match a Rewired Action, its Controller Map may be disabled, or **Player Input Proxy** may reference the old component | Match the Action name, enable the map for the selected Player, and assign **Rewired Input** on the proxy. |
| Two characters respond to one device | They may share **Player ID**, or Rewired may assign the device to both Players | Give each bridge the intended Player ID and correct the device and map ownership in Rewired. |
| The mouse cannot aim or move the cursor | The selected Player may not own the Rewired mouse | Assign the mouse to that Player or provide a Player Mouse workflow appropriate for the game. |
| Gameplay works but menus do not | The EventSystem may still use Unity's input module or its UI Action names may be unmapped | Add **Rewired Standalone Input Module**, create matching UI Actions, and assign their maps to the intended Players. |
| A binding change disappears after restart | The Rewired Input Manager may have no User Data Store, or saved data may not be loaded | Add and configure a `UserDataStore`, save at the required lifecycle points, and test a clean restart. |
| New default mappings do not appear during development | Previously saved Rewired user data may override the manager's changed defaults | Clear the test save or migrate the saved maps according to Rewired's User Data Store guidance. |
| Ultimate Character Controller virtual controls do nothing | They were generated for Unity Input System or legacy Unity Input, not Rewired | Remove them and build the touch layout through Rewired; then enable **Enable Touch Controls**. |
| Touching a menu also triggers gameplay | **Enable Touch Controls** makes the bridge ignore its normal pointer-over-UI block | Disable gameplay input while the menu owns input or switch the selected Rewired map category. |
| The cursor shortcut or controller-connected state behaves differently from Rewired | Those bridge paths still use `UnityEngine.Input` globally | Test **Active Input Handling** and replace the cursor or device-state path when per-player Rewired behavior is required. |

## Saving and networking boundaries

The bridge reads local input only. It does not save Rewired data, assign network authority, transmit input, or distinguish a local owner from a remote character.

- Add **Rewired Input** only for the owning local character, or ensure the networking layer disables the input GameObject for remote characters.
- Keep Player IDs and device assignment as local-session data unless the game's own profile system intentionally persists them.
- Save mappings through Rewired's User Data Store, not the Ultimate Character Controller save system unless a project-specific adapter explicitly connects them.
- In split-screen networking, establish local Rewired ownership before mapping each local character to its network object and camera.

## Related pages

- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Virtual Controls](https://opsive.com/support/documentation/ultimate-character-controller/input/virtual-controls/)
- [Split Screen](https://opsive.com/support/documentation/ultimate-character-controller/camera/split-screen/)
- [Camera Controller](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Events](https://opsive.com/support/documentation/ultimate-character-controller/programming-concepts/events/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
- [Rewired documentation](https://guavaman.com/projects/rewired/docs/)

## Developer reference

The packaged source is `Assets/Opsive/Shared/Integrations/Rewired/RewiredInput.cs`. `RewiredInput` derives from Ultimate Character Controller's `PlayerInput` and forwards `GetButton`, `GetButtonDown`, `GetButtonUp`, `GetAxis`, and `GetAxisRaw` to the selected `Rewired.Player`. Its `PlayerID` property changes the selected Player immediately during Play Mode.

The component overrides `GetMousePosition` with `m_Player.controllers.Mouse.screenPosition`. It overrides `IsPointerOverUI` only when **Enable Touch Controls** is enabled, returning `false` rather than querying the EventSystem.

The inspected integration package contains no custom rebinding UI, `UserDataStore`, Rewired UI input module, networking implementation, or save adapter. Those responsibilities remain with Rewired and project code. Because no supported Rewired range is encoded in the package, compile and runtime verification remain the compatibility test for the installed Rewired and Unity versions.

---

<a id="page-ultimate-character-controller-integrations-state-designer"></a>

# State Designer

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/state-designer/)

Use the [State Designer](https://assetstore.unity.com/packages/tools/visual-scripting/state-designer-dots-powered-finite-state-machines-369152?aid=1100lGdc) integration when a finite state machine should choose an AI or gameplay mode while Ultimate Character Controller owns locomotion, collision, animation, abilities, items, health, attributes, and effects.

## Before you begin

- Install released Ultimate Character Controller Version 3 and State Designer, then verify both products independently.
- Build the character as an **AI Agent** when State Designer will control a non-player character.
- Configure and test navigation, items, health, and the required abilities before requesting them from a State Machine.
- Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the matching State Designer integration after both products compile. The bridge is not included in either base product's Integrations folder before this download. Importing `UltimateCharacterControllerStateDesigner.unitypackage` creates the integration files in the project.

## Build a first Patrol, Chase, and Attack flow

1. Add a State Machine to the AI character and create Patrol, Chase, and Attack States.
2. Use project sensing Conditions to choose a target. The Ultimate Character Controller bridge does not add sight or hearing.
3. In Chase, set the navigation destination and let Ultimate Character Controller's pathfinding movement ability apply final motion.
4. In Attack, use **Set Aim Target**, then **Start Stop Ability** or **Start Stop Use** for the configured item slot and action.
5. On State exit, stop abilities that should not remain active and clear temporary aim or target data.
6. Use **Is Ability Active**, **Is Effect Active**, **Is Alive**, or other integration Conditions to drive transitions instead of reading Animator state directly.

## Available Ultimate Character Controller nodes

- **Abilities and effects:** Start Stop Ability, Is Ability Active, Start Stop Effect, and Is Effect Active.
- **Items and aiming:** Set Aim Target, Start Stop Use, Reload, Start Equip Unequip, Start Item Set Ability, and Get Item Identifier Amount.
- **Health and state:** Damage, Heal, Is Alive, Has Taken Damage, Get Attribute Value, Set State, and Execute Event.

These nodes call Ultimate Character Controller systems; they do not replace Ultimate Character Controller validation. An Action can fail when a required component is missing or Ultimate Character Controller rejects the requested ability.

## Verify in Play Mode

1. Watch the active State and Ultimate Character Controller's active abilities together.
2. Confirm Patrol and Chase move through one authority and use the expected movement animation.
3. Confirm Attack aims at the intended object and controls the expected item slot and action.
4. Force Ultimate Character Controller to block an ability and confirm the State Machine follows its fallback.
5. Test State exit, interruption, death, respawn, perspective changes, and scene reload.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Ultimate Character Controller nodes are absent from the State Palette. | Check compilation, both products, and the imported bridge package. | Install both dependencies first, remove duplicate bridge scripts, and reimport the matching package. |
| The character does not move. | Check the navigation owner, baked navigation data, AI Agent setup, and pathfinding movement ability. | Let State Designer choose the destination and let Ultimate Character Controller apply final movement. |
| Use or Reload targets the wrong item. | Check active item set, Slot ID, and Action ID. | Select the exact equipped item action rather than relying on the first available ability. |
| A State exits but an ability remains active. | Check the State exit Actions and the ability's normal Stop Type. | Stop the ability explicitly or configure the intended Ultimate Character Controller stop rule. |

## Related pages

- [State Designer integration guide](https://opsive.com/support/documentation/state-designer/integrations/ultimate-character-controller/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/)
- [NavMeshAgent Movement](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/navmeshagent-movement/)
- [Use](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/item-abilities/use/)

---

<a id="page-ultimate-character-controller-integrations-ultimate-inventory-system"></a>

# Ultimate Inventory System

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/)


Use the [Ultimate Inventory System](https://assetstore.unity.com/packages/tools/game-toolkits/ultimate-inventory-system-166053?aid=1100lGdc) integration when Ultimate Inventory System should own a character's Items, Item Collections, inventory UI, and saved inventory data while Ultimate Character Controller equips, animates, and uses the corresponding Character Items.

For example, an Ultimate Inventory System Iron Sword can move from a Bag into an equipment collection, cause its Ultimate Character Controller Character Item prefab to appear in the correct hand, activate a valid Ultimate Character Controller Item Set, and return to the Bag when unequipped. The integration keeps those two representations synchronized; it is not a second inventory to maintain beside Ultimate Inventory System.

## Compatibility boundary

The checked-in Ultimate Character Controller Version 3 installer inspected for this page identifies itself as integration `3.0.5`. Its Integration Inspector requires:

- Ultimate Character Controller `3.0.10+`
- Ultimate Inventory System `1.2.16+`

The current public releases are [Ultimate Character Controller `3.3.6`](https://opsive.com/news/ultimate-character-controller-3-3-6-released/) and [Ultimate Inventory System `1.3.8`](https://opsive.com/news/ultimate-inventory-system-1-3-8-released/). The [Ultimate Inventory System `1.3.6` release notes](https://opsive.com/news/ultimate-inventory-system-1-3-6-released/) also state that this integration was updated. Because that refreshed package is distributed through Opsive Downloads and may be newer than the checked-in installer, do not treat the `3.0.10` and `1.2.16` minimums as a tested maximum-version guarantee. Recheck the downloaded package's version block under **Tools > Opsive > Ultimate Inventory System > Integrations Manager > Integration Inspectors > Ultimate Character Controller** after updating either product.

Ultimate Character Controller Version 4 and Ultimate Inventory System Version 2 use different development APIs and are outside this page's scope. The exact labels and APIs below were verified against the source-visible `3.0.5` bridge; if a newer downloaded bridge reports different requirements or controls, its Inspector and source take precedence.

The integration is compiled directly against Ultimate Character Controller, Ultimate Inventory System, and Opsive Shared. It does not include compatibility shims for missing products or later major versions, so install both products and let them compile before importing the bridge.

## Understand which system owns each job

| Job | Runtime owner |
| --- | --- |
| Item identity, quantity, mutable attributes, categories, definitions, currencies, and collections | Ultimate Inventory System **Inventory** and its Inventory Database |
| Bag, equipment, hotbar, shop, crafting, and other inventory UI | Ultimate Inventory System UI and Item Actions |
| Translating Ultimate Inventory System equippable Items into Ultimate Character Controller Character Items and Item Sets | **Character Inventory Bridge** and **Inventory Item Set Manager** |
| Visible Character Item prefabs, item slots, equip/use abilities, animation, and item states | Ultimate Character Controller Version 3 |
| Inventory contents and active Item Set indexes across save/load | **Inventory Bridge Saver** with **Inventory System Manager Item Saver** |

An Item in the Ultimate Inventory System **Default** collection is owned but not equipped. An Item in a collection listed under **Bridge Item Collection Names** is available to Ultimate Character Controller and may be soft equipped. It becomes actively equipped only when the corresponding Ultimate Character Controller Item Set is active.

Use the **Equippable** category only for Items that require an Ultimate Character Controller Character Item, such as weapons, shields, usable tools, or a gameplay ability represented by a Character Item. Ordinary ammo, materials, consumables, and Ultimate Inventory System-only armor should not inherit from **Equippable**.

## Before you begin

- Install Ultimate Character Controller Version 3 and Ultimate Inventory System Version 1, then resolve all compiler errors.
- Create and test the Ultimate Character Controller character with **Tools > Opsive > Ultimate Character Controller > Character Manager** before converting it.
- Decide which Ultimate Inventory System Inventory Database and Inventory System Manager the scene will use.
- Save the scene and create a source-control checkpoint. **Setup Character** removes the standard Ultimate Character Controller Inventory and Item Set Manager and replaces them with the integrated components.
- Start with one simple single-slot weapon. Add multi-slot weapons, armor, ammo persistence, and menus only after that first item equips correctly.

## Install the integration

1. Sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the current Ultimate Inventory System integration for Ultimate Character Controller Version 3. The bridge is not included in either base product's Integrations folder before this download.
2. Import the downloaded package after both products compile. Importing it creates `Assets/Opsive/UltimateCharacterController/Integrations/UltimateInventorySystem` in the project. Remove duplicate scripts from an older bridge before importing a replacement.
3. Open **Tools > Opsive > Ultimate Inventory System > Integrations Manager**.
4. Select **Integration Inspectors**, then **Ultimate Character Controller**.
5. Record the integration version and requirements shown by the downloaded package. The inspected `3.0.5` package reports Ultimate Character Controller `3.0.10+` and Ultimate Inventory System `1.2.16+`.

The package includes a reference scene at `Assets/Opsive/UltimateCharacterController/Integrations/UltimateInventorySystem/Demo/Demo.unity`. Use it to inspect collection layouts, Item Set Rules, Item Actions, pickups, bindings, and ammo modules. Copy the pattern into project-owned assets rather than editing the integration demo or database directly.

## Prepare the database and scene

### Duplicate the supplied database

The supplied `EmptyCharacterInventoryDatabase` is the safest starting point because it already contains the bridge's required category and attribute structure.

1. Open **Tools > Opsive > Ultimate Inventory System > Main Manager**.
2. Assign `EmptyCharacterInventoryDatabase` from the integration's `EmptyDatabase` folder to **Database**.
3. Open the options menu beside **Database** and select **Duplicate**.
4. Save the duplicated database in a project-owned folder outside the integration package and keep it selected in the Main Manager.
5. Under **Setup > Scene Setup**, add or update the Ultimate Inventory System scene components.
6. Select the scene's **Inventory System Manager** and confirm that **Database** references the same duplicated asset.

Do not duplicate only the main `.asset` in the Project window. The Main Manager's **Duplicate** command copies the database-owned categories and definitions into a coherent new database.

The supplied database establishes these integration conventions:

| Category | Purpose |
| --- | --- |
| **Equippable** | Abstract parent for every Item that can create an Ultimate Character Controller Character Item. |
| **Single Item** | Inherits **Equippable** and supplies one Item Definition `GameObject` Attribute named `Prefabs`. |
| **Multi Item** | Inherits **Equippable** and supplies a `GameObject[]` Item Definition Attribute named `Prefabs`. |
| **Ammo** | Parent for ammo Item Definitions stored as Ultimate Inventory System quantities. |
| **Item With Ammo** | Supplies a mutable Item Attribute named `AmmoData` for the ammo definition, clip size, and rounds currently loaded. |

You may add more categories and multiple inheritance for the game's organization. Keep the **Equippable** relationship and the `Prefabs` Attribute type intact unless the matching **Character Item Prefabs Attribute Name** on every bridge is deliberately changed.

## Connect a character

1. Put the finished Ultimate Character Controller character in the scene.
2. Ensure the Ultimate Inventory System Main Manager and the scene's Inventory System Manager both reference the intended database.
3. Open **Tools > Opsive > Ultimate Inventory System > Integrations Manager**.
4. Select **Integration Inspectors > Ultimate Character Controller > Character Setup**.
5. Assign the scene object to **Character**. **Setup Character** is enabled only when the object has **Ultimate Character Locomotion**.
6. Select **Setup Character** and wait for the success message.
7. Select the character and inspect every component and collection before creating Items.

Character Setup creates these Ultimate Inventory System Item Collections:

| Collection | Type and purpose |
| --- | --- |
| **Default** | Main Item Collection for owned Items that are not currently equipped. |
| **Equippable Slots** | Equipped Item Slot Collection with generated **Primary**, **Secondary**, and **Tactical** slots. |
| **Equippable** | Additional bridge Item Collection for equippable Items that do not use that slot layout. |
| **Loadout** | Character Loadout Item Collection for Items granted by the configured loadout rather than restored save contents. |

It also adds **Character Inventory Bridge**, **Inventory Item Set Manager**, **Inventory Identifier**, **Item User**, **Currency Owner**, **Inventory Interactor**, and **Inventory Bridge Saver**. Existing Ultimate Character Controller Item Set abilities remain on the character; setup attempts to remap their categories to the selected Ultimate Inventory System database and logs a warning when a match cannot be found.

![Character Inventory Bridge with the Equippable category, Prefabs attribute name, Default collection, bridge collections, and Loadout collection configured.](https://opsive.com/wp-content/uploads/2021/04/chrome_0mqVNqjbJy.png?v=913358976517)

Review these bridge fields first:

- **Equippable Category** points to the database's **Equippable** category.
- **Character Item Prefabs Attribute Name** is `Prefabs`.
- **Default Item Collection Name** is `Default`.
- **Bridge Item Collection Names** contains every collection that should make Character Items available to Ultimate Character Controller, normally `Equippable Slots` and `Equippable`.
- **Loadout Item Collection Names** contains `Loadout` or the exact project-owned loadout names.
- **Inventory Identifier > ID** is unique for every persistent character Inventory.
- **Item User > Inventory Input** resolves the same Opsive player-input component that controls the Ultimate Character Controller character.

Collection names are exact runtime identifiers. Renaming a collection without updating the bridge, Item Actions, UI, saver assumptions, and Item Set Rules breaks the ownership chain.

## Create the first equippable item

Use a single Iron Sword to prove the full workflow before adding special cases.

1. Open **Tools > Opsive > Ultimate Character Controller > Item Manager** and create the Iron Sword's Ultimate Character Controller Character Item prefab. Configure its slot, perspective objects, Item Actions, Animator IDs, and events as described in [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/).
2. In the Ultimate Inventory System database, create or choose a Sword category that inherits from **Equippable** and **Single Item**. Use **Multi Item** only when one Ultimate Inventory System Item Definition needs more than one Ultimate Character Controller Character Item prefab, such as the same weapon in either hand.
3. Create the **Iron Sword** Item Definition. Under its inherited Item Definition Attributes, assign the Ultimate Character Controller Character Item prefab to `Prefabs`.
4. On **Character Inventory Bridge**, confirm that **Character Item Prefabs Attribute Name** is also `Prefabs`.
5. On **Inventory Item Set Manager**, add a rule that accepts the Iron Sword in the Character Item's Ultimate Character Controller slot.
6. Add the integration's **Character Equip Unequip** Item Action to the Ultimate Inventory System Item Action Set used by the equipment menu.
7. Give the character one Iron Sword in **Default** and complete the Play Mode checks below.

![An Ultimate Inventory System Item Action Set using Character Equip Unequip with separate Equip and Unequip labels.](https://opsive.com/wp-content/uploads/2021/04/EquipUnequipItemAction.png?v=3fc046861f23)

The Ultimate Inventory System Item Definition replaces the old Ultimate Character Controller Item Type as the integrated Item's identity. Do not create a second Ultimate Character Controller Item Type and try to keep it synchronized with the Ultimate Inventory System definition. The Character Item prefab supplies Ultimate Character Controller behavior; the Ultimate Inventory System Item carries identity, amount, and persistent attributes.

## Choose the Item Set Rule

**Inventory Item Set Manager** recomputes Item Sets whenever an Ultimate Inventory System Item enters or leaves a bridge collection. Choose the narrowest rule that expresses the intended loadout:

| Rule | Use it when |
| --- | --- |
| **Item Category Item Set Rule** | Any Item inheriting a category may occupy a slot, such as any one-handed blade in the right hand. It also supports definition and category exceptions. |
| **Item Definition Item Set Rule** | One exact definition or exact combination needs its own Item Set, state, or animation behavior. |
| **Item Slot Collection Item Set Rule** | The Ultimate Inventory System Item Slot Collection itself should map directly to Ultimate Character Controller slots. Its default collection name is `Equippable Slots`. |

![Inventory Item Set Manager with category-based rules grouped for equippable weapons, grenades, and magic.](https://opsive.com/wp-content/uploads/2021/04/GcYxwxE9rs.png?v=db419baa34f0)

Keep separate Item Set groups only when more than one set may be active at the same time. For example, a weapon group and a magic group can combine independently without authoring every weapon-plus-magic permutation.

Set each rule's state deliberately. Ultimate Character Controller applies that state while the generated Item Set is active, so a Bow, Sword and Shield, or Body setup can select its matching Animator and ability presets. Use [Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) for the underlying Ultimate Character Controller behavior.

### Understand soft and active equipment

- **Unequipped:** the Item is normally in **Default** and has no active Character Item.
- **Soft equipped:** the Item is in a bridge collection, so the bridge can create its Character Item, but its Item Set is not active. This is useful for a holstered weapon.
- **Active equipped:** the Item is in a bridge collection and its Item Set is active, so Ultimate Character Controller equips and can use its Character Item.

The default **Character Equip Unequip** action moves an Item between **Default** and a bridge collection and asks Ultimate Character Controller to equip or unequip it. Its advanced **Not Move Equip** option changes only active versus soft-equipped state; use that option only when another workflow already owns the collection move.

## Bind Item attributes to Character Item behavior

Persistent values should live on the Ultimate Inventory System Item, not only on a spawned Character Item prefab.

- Use Ultimate Inventory System **Item Binding** when a top-level component property should read or write an Item Attribute.
- Use the integration's **Item Object Binding** inside an Ultimate Character Controller State Object binding list when an Item Attribute should drive a property on an Item Action Module, Impact Action, Item Effect, or another bound State Object.
- The Attribute value type and target property type must match.
- The spawned Character Item needs an **Item Object** that resolves the Ultimate Inventory System Item before its bindings can update.

Good binding candidates include damage, impact force, color, durability, or a project-specific modifier. First prove the prefab with fixed values; then move only the values that genuinely need to persist or vary per Ultimate Inventory System Item into Attributes.

## Configure a shootable weapon and ammo

Use Ultimate Inventory System Items for reserve ammunition and the integration's `AmmoData` Attribute when a weapon's loaded rounds and clip size must stay with that individual Item.

1. Create an ammo Item Definition under the **Ammo** category, such as **Rifle Bullet**. Store its reserve quantity in the character's normal Ultimate Inventory System Inventory.
2. Make the weapon's category inherit from both **Single Item** or **Multi Item** and **Item With Ammo** so it remains equippable and its runtime Item has a mutable `AmmoData` Attribute.
3. Set `AmmoData` to the ammo Item Definition, clip size, and starting clip amount.
4. On the Ultimate Character Controller Shootable Action, add **Inventory Item Ammo** to the Ammo Module Group.
5. Enable **Use Ammo Data** and keep **Ammo Data Attribute Name** as `AmmoData`, or assign **Ammo Item Definition** directly when every instance of that weapon uses the same ammo and no per-Item choice is required.
6. Leave **Ammo Item Collection Names** empty to use the Inventory's Main collection, or list the exact collections that may supply reserve ammunition.
7. Add **Inventory Ammo Data Clip** to the Clip Module Group and use the same **Ammo Data Attribute Name**.
8. If the Ultimate Inventory System inventory view shows weapon ammunition, add **Weapon Ammo Item View Module** to the Item View and connect its loaded, clip-size, reserve-count, and optional ammo-icon controls.

![An Ultimate Character Controller Shootable Action configured with Inventory Item Ammo and Inventory Ammo Data Clip using the AmmoData Item Attribute.](https://opsive.com/wp-content/uploads/2021/04/Unity_tS7EpGE4Mv.png?v=393fe6176281)

**Inventory Item Ammo** consumes Ultimate Inventory System ammo Items. **Inventory Ammo Data Clip** writes the changing loaded count back to the weapon Item's `AmmoData` Attribute. Together they allow a partially loaded weapon to keep its own clip when it is unequipped, transferred, saved, and restored.

## Configure pickups and drops

Choose one interaction model for each pickup:

- Use the integration's **Inventory Item Pickup** when the object should be collected through Ultimate Character Controller's Pickup ability.
- Use an ordinary Ultimate Inventory System pickup or Inventory Interactable when Ultimate Inventory System interaction should own the collection step.

To create an integration pickup:

1. Open **Tools > Opsive > Ultimate Inventory System > Integrations Manager**.
2. Under **Ultimate Character Controller > Item Pickup Setup**, assign the Ultimate Character Controller prefab to **Character Item** and an optional visible object to **Pickup Model Object**.
3. Select **Setup Item Pickup** and save the generated prefab in a project-owned folder.
4. On **Inventory Item Pickup**, choose whether to **Equip On Pickup**, **Pickup Item Copies**, and **Remove Items On Pickup**.
5. Confirm that the pickup's Ultimate Inventory System Inventory contains the intended Item and amount.

The setup creates the required collider, trigger, Ultimate Inventory System Inventory, **Inventory Item Pickup**, and Ultimate Character Controller trajectory support. When a Character Item was supplied, it also assigns the generated prefab to that Character Item's **Drop Prefab** and seeds the pickup Inventory with its Item Definition.

For character-driven dropping, configure **Character Inventory Bridge > Item Drop**:

- **Inventory Item Pickup Prefab** is the generic drop prefab and must contain an Ultimate Inventory System Inventory and **Inventory Item Pickup**.
- **Drop Using Character Item When Possible** uses the active Character Item's **Drop Prefab** when available; otherwise the generic prefab is used.
- **Item Drop Position Offset** controls the spawn offset from the character.

Use the integration's **Character Drop** or **Character Quantity Drop** Item Action so the bridge can unequip, remove, and create the correct pickup in one workflow.

## Equip clothes and skinned armor

Pure clothing and armor should normally remain an Ultimate Inventory System equipment workflow rather than becoming Ultimate Character Controller Character Items.

1. Create a separate Ultimate Inventory System Item Slot Collection such as `Armor Equipped` with purpose **Equipped** and an Item Slot Set for Head, Chest, Legs, or the slots the game needs.
2. Do not make those armor categories inherit from the bridge's **Equippable** category unless the item genuinely needs Ultimate Character Controller Item Actions and abilities.
3. Add Ultimate Inventory System **Equipper** to the character and point **Equipment Item Collection ID** to `Armor Equipped`.
4. Use the same Item Slot Set on the collection, Equipper, and equipment UI.
5. Assign the armor visual through `EquipmentPrefab`. Add `UsableItemPrefab` only when the Ultimate Inventory System Equipper workflow also needs a functional Item Object.
6. Enable **Skinned Equipment** for deforming armor and verify its bones against the character rig.
7. Use Ultimate Inventory System **Move To Collection Item Action** for armor. Reserve **Character Equip Unequip** for bridge Items that must activate an Ultimate Character Controller Item Set.

This separation prevents a shirt or helmet from accidentally becoming an active weapon while still allowing Ultimate Inventory System to display, save, and rebuild the equipped visuals. Follow [Equipping Items](https://opsive.com/support/documentation/ultimate-inventory-system/item-objects/equipping-items/) for the complete Equipper workflow.

## Configure inventory actions, UI, and input

Build the Bag, equipment, hotbar, and menu with Ultimate Inventory System. Use integration actions only where the operation must pass through Ultimate Character Controller:

| Ultimate Inventory System Item Action | Result |
| --- | --- |
| **Character Equip Unequip** | Moves and equips, unequips, or changes active versus soft-equipped state through the bridge. |
| **Character Use** | Equips an Item when necessary and starts its Ultimate Character Controller Use ability. If the action had to equip the Item first, it unequips it after use completes. |
| **Character Drop** | Drops the selected Item through the character bridge. |
| **Character Quantity Drop** | Opens the quantity picker when needed, then drops that amount through the bridge. |
| **Character Modify Attribute** | Changes one named Ultimate Character Controller Attribute from Ultimate Inventory System Item Attribute values and can consume the Item. |
| **Character Modify Attributes** | Applies multiple configured Ultimate Inventory System-to-Ultimate Character Controller Attribute changes in one use. |

Use ordinary Ultimate Inventory System actions for Ultimate Inventory System-only operations such as moving armor between Bag and an armor Item Slot Collection.

The integration also supplies **Character Equipped Select Item View Module** to distinguish unequipped, soft-equipped, and active-equipped Item Views, and **Weapon Ammo Item View Module** to display current shootable ammo.

Character Setup assigns the detected Opsive player input to **Item User > Inventory Input**. Verify that reference after conversion, particularly when the project uses Unity's Input System or a third-party input integration. Do not leave two active `IPlayerInput` implementations on one player.

For a full-screen menu:

1. Use Ultimate Inventory System **Enable Disable Inventory Input** to disable gameplay inventory handlers while the menu is enabled and restore them when it closes.
2. Keep the menu's EventSystem, UI input module, and close action active.
3. Use **Display Panel Manager Handler** for the panel shortcuts and cursor behavior.
4. Test that Ultimate Character Controller movement and Item Actions stop while the menu owns input and resume after it closes.

See [Ultimate Inventory System Input](https://opsive.com/support/documentation/ultimate-inventory-system/input/) for backend, EventSystem, action-map, and local-player ownership setup.

## Apply Item-driven character states

Use **Item To Character State Binding** when owning or equipping an Item should activate one or more Ultimate Character Controller states without creating a custom script.

1. Add a string Item Attribute such as `State` to the relevant Ultimate Inventory System category or definition.
2. Add **Item To Character State Binding** to the character.
3. Assign **Inventory Bridge**, set **Item Collection Name** to the collection to watch, and set **State Attribute Name** to `State`.
4. Put one or more Ultimate Character Controller state names in the Item Attribute. Separate multiple names with commas.

The component reevaluates the watched collection whenever it changes, activates states named by current Items, and deactivates states that are no longer present. Use a dedicated collection when a state should apply only while equipped rather than merely owned. See [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) for state and preset behavior.

## Save the integrated Inventory

Use **Inventory Bridge Saver** on the converted character. Do not also add the standard Ultimate Inventory System **Inventory Saver** to that Inventory; it does not preserve the bridge's active Item Set state and is not compatible with this character workflow.

1. Set up the Ultimate Inventory System **Save System Manager**.
2. Add **Inventory System Manager Item Saver** so mutable and unique Ultimate Inventory System Items are serialized once.
3. Keep **Inventory Bridge Saver** on the same GameObject as the bridged Ultimate Inventory System Inventory and Ultimate Character Controller character.
4. Give every saved character a unique **Inventory Identifier > ID**.
5. Keep the Item Collection order and Item Set group structure stable after shipping save files.
6. Save with an Item equipped, change both its collection and active Item Set, then load the same slot.

**Inventory Bridge Saver** records each non-Loadout collection by index and the active Item Set index for each group. During loading it unequips and clears the previous bridge state, restores the saved Items, waits one frame for Character Items to initialize, and then restores the active Item Sets. Loadout collections are deliberately handled as loadout rather than saved inventory contents.

Follow [Ultimate Inventory System Save System](https://opsive.com/support/documentation/ultimate-inventory-system/save-system/) for save slots, UI, and custom save-system nesting.

## Migrate an existing Ultimate Character Controller item setup

Treat migration as a change of inventory ownership, not a field-for-field conversion.

1. Make every existing Ultimate Character Controller Item a tested Character Item prefab using the current [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) workflow.
2. Record its slot, Animator IDs, Item Actions, Item Set rules, loadout, pickup prefab, and state dependencies.
3. Create a project checkpoint, select the Ultimate Inventory System database, and run **Setup Character**.
4. Create one Ultimate Inventory System Item Definition per inventory identity and assign the corresponding Character Item prefab through `Prefabs`.
5. Rebuild or review the rules on **Inventory Item Set Manager**. Resolve every category-remapping warning from Character Setup.
6. Replace direct Ultimate Character Controller inventory grants with Ultimate Inventory System loadouts, pickups, shops, crafting, or project code.
7. Replace UI equip/drop/use actions with the integration actions where Ultimate Character Controller must participate.
8. Validate saving with **Inventory Bridge Saver** before removing the old scene or prefab setup.

Do not copy an old Item's scene instance into the Ultimate Inventory System pickup **Drop Prefab**. An Ultimate Character Controller Character Item prefab runs on the character; a pickup prefab is a world object with its own Inventory and pickup component.

## Editor checkpoint

Before entering Play Mode, confirm that:

- the Integration Inspector's version and requirement block has been reviewed and the bridge has no compile errors;
- the Main Manager and scene Inventory System Manager use the same project-owned database;
- the character has Ultimate Inventory System **Inventory**, **Character Inventory Bridge**, **Inventory Item Set Manager**, **Item User**, and **Inventory Bridge Saver**;
- **Default**, **Equippable Slots**, **Equippable**, and **Loadout** exist in the expected order and match the bridge's names;
- **Equippable Category** and every Item Set group category belong to the current database;
- every equippable definition inherits from **Single Item** or **Multi Item** and its `Prefabs` value has the correct type;
- each Character Item prefab has the intended Ultimate Character Controller slot and a matching Item Set Rule;
- the Ultimate Inventory System Item Action Set uses **Character Equip Unequip** for weapons;
- **Item User > Inventory Input** points to the correct local player's Opsive input;
- each **Inventory Identifier** ID is unique;
- ammo Attribute and module names match exactly when a shootable weapon uses Ultimate Inventory System ammo; and
- the Save System Manager has **Inventory System Manager Item Saver**, with no standard **Inventory Saver** on the bridged character.

## Verify in Play Mode

1. Start with one Iron Sword in **Default**. Confirm that the Ultimate Inventory System Bag shows it and no sword is active on the character.
2. Invoke **Character Equip Unequip**. Confirm that the Item moves into the intended bridge collection, the correct Character Item appears in its Ultimate Character Controller slot, and the expected Item Set becomes active.
3. Use the sword through normal character input. Confirm that Ultimate Character Controller owns the Use ability and animation while the Ultimate Inventory System Item remains available to UI and bindings.
4. Unequip the sword. Confirm that it returns to **Default** and the Character Item and active Item Set change as intended.
5. Put the weapon in a bridge collection without activating its set. Confirm that the UI reports soft equipped and that it cannot be used as the active Item.
6. For a shootable weapon, fire and reload. Confirm that reserve Ultimate Inventory System ammo decreases and `AmmoData` keeps the loaded count after unequipping and re-equipping the weapon.
7. Pick up and drop one equippable Item. Confirm that the world object, Ultimate Inventory System quantity, bridge collection, Character Item, and Item Set each change once.
8. Equip Ultimate Inventory System-only armor. Confirm that Equipper creates the visual without activating an Ultimate Character Controller weapon Item Set.
9. Open the inventory menu. Confirm that gameplay input stops, UI input and the close action remain available, and the cursor follows the menu state.
10. Save with an Item equipped and a partially loaded clip, change the Inventory, then load. Confirm that collection contents, mutable Item data, and active Item Set return together.
11. Repeat equip, UI, pickup, and save checks for every local player. Each player's input, Inventory Identifier, UI owner, and Inventory must remain separate.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The integration is missing or reports unresolved types | Bridge version, installed product versions, and duplicate old integration files | Install the product versions required by the downloaded bridge, remove the old copy, then reimport after both products compile. For the inspected `3.0.5` bridge, the minimums are Ultimate Character Controller `3.0.10` and Ultimate Inventory System `1.2.16`. |
| **Setup Character** is disabled | The assigned object may not be a scene object with **Ultimate Character Locomotion** | Build or update the Ultimate Character Controller character, place it in the scene, and assign its root. |
| Character Setup warns that **Ammo** or **Equippable** cannot be found | The selected database lacks the expected categories or the scene uses another database | Duplicate `EmptyCharacterInventoryDatabase`, assign that database to both managers, or add the exact categories before converting. |
| Character Setup stops while configuring input | The packaged setup path may not resolve the character's current Opsive input implementation | Do not add a second input backend merely to hide the error. Keep the existing player input, verify which conversion components were added, assign it to **Item User > Inventory Input**, and use a bridge update or project fix for the setup path. |
| An Item exists in Ultimate Inventory System but no Character Item appears | Category inheritance, `Prefabs` spelling and type, assigned prefab, and bridge Attribute name | Inherit from **Single Item** for `GameObject` or **Multi Item** for `GameObject[]`, assign the prefab, and keep the bridge name synchronized. |
| The Character Item appears but never becomes active | Bridge collection, Character Item slot, Item Set group category, and rule | Put the Item in a listed bridge collection and make the rule, category, and slot agree. |
| The UI changes equipment but the character does not | The UI may use ordinary **Move To Collection** instead of the integration action | Use **Character Equip Unequip** for Ultimate Character Controller weapons and confirm the target collection is listed under **Bridge Item Collection Names**. |
| A holstered Item is treated as unequipped or active at the wrong time | Collection membership and the **Not Move Equip** choice may not match the intended soft-equip flow | Keep the Item in a bridge collection for soft equipment and change only its active Item Set when appropriate. |
| The wrong hand or weapon combination activates | Character Item slot and Item Set Rule slots or exceptions | Correct the prefab slot and use a category, definition, or slot-collection rule that permits only the intended combination. |
| Ammo never decreases or reload finds no reserve | Ammo Item Definition, source collection names, and **Inventory Item Ammo** configuration | Put the correct ammo Item in a searched collection and match the definition or `AmmoData` Attribute. |
| A weapon loses its loaded rounds when switched or loaded | Missing mutable `AmmoData`, missing **Inventory Ammo Data Clip**, or wrong Attribute name | Add the Item-level Attribute and clip module, use the same name, and save mutable Items with **Inventory System Manager Item Saver**. |
| Dropping logs that the pickup prefab is missing or has no Inventory | **Inventory Item Pickup Prefab**, Character Item **Drop Prefab**, and required pickup components | Assign a generated integration pickup or another prefab containing Ultimate Inventory System Inventory and **Inventory Item Pickup**. |
| Armor enters the weapon bridge or activates an Item Set | Armor category or UI action may use the Ultimate Character Controller bridge workflow | Remove the **Equippable** inheritance, use a separate Ultimate Inventory System Item Slot Collection and Equipper, and use **Move To Collection**. |
| Item Actions or menu shortcuts do not respond | **Item User > Inventory Input**, active input backend, panel owner, and gameplay-input state | Assign the correct local `IPlayerInput`, remove competing input owners, and restore gameplay input when the menu closes. |
| Loading duplicates Items or restores the wrong active set | Standard **Inventory Saver**, missing manager Item saver, changed collection order, or non-unique identifier | Keep only **Inventory Bridge Saver** on the character, add **Inventory System Manager Item Saver**, preserve order, and use a unique ID. |

## Related pages

- [Ultimate Inventory System-side character-controller workflow](https://opsive.com/support/documentation/ultimate-inventory-system/integrations/opsive-character-controllers/)
- [Ultimate Character Controller Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)
- [Ultimate Character Controller Character Items](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/)
- [Ultimate Character Controller Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/)
- [Ultimate Inventory System Item Categories](https://opsive.com/support/documentation/ultimate-inventory-system/editor-window/item-category/)
- [Ultimate Inventory System Item Definitions](https://opsive.com/support/documentation/ultimate-inventory-system/editor-window/item-definition/)
- [Ultimate Inventory System Item Collections](https://opsive.com/support/documentation/ultimate-inventory-system/inventory/item-collections/)
- [Ultimate Inventory System Item Actions](https://opsive.com/support/documentation/ultimate-inventory-system/item-actions/)
- [Ultimate Inventory System Item Pickups](https://opsive.com/support/documentation/ultimate-inventory-system/item-objects/item-pickups/)
- [Ultimate Inventory System Equipper](https://opsive.com/support/documentation/ultimate-inventory-system/item-objects/equipping-items/)
- [Ultimate Inventory System Input](https://opsive.com/support/documentation/ultimate-inventory-system/input/)
- [Ultimate Inventory System Save System](https://opsive.com/support/documentation/ultimate-inventory-system/save-system/)
- [Ultimate Character Controller State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/)
- [Ultimate Character Controller Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)

## Developer reference

The current runtime types use different `Item` and `Inventory` names across the two products. Alias them explicitly in integration code:

```csharp
using InventoryItem = Opsive.UltimateInventorySystem.Core.Item;
using Inventory = Opsive.UltimateInventorySystem.Core.InventoryCollections.Inventory;
using ItemCollection = Opsive.UltimateInventorySystem.Core.InventoryCollections.ItemCollection;
using CharacterItem = Opsive.UltimateCharacterController.Items.CharacterItem;
```

`CharacterInventoryBridge` exposes the main project extension points: `MoveItemToEquippable`, `MoveItemToDefault`, `MoveEquip`, `Equip`, `IsItemActive`, `GetActiveInventoryItem`, `GetInventoryItem`, and `DropItem`. Use `MoveEquip` when code owns both the collection move and active equip request. Use `Equip` only when the Item is already in a bridge collection.

The bridge source is under `Assets/Opsive/UltimateCharacterController/Integrations/UltimateInventorySystem/Scripts`. Important extension types include:

- `CharacterInventoryBridge` and `InventoryItemSetManager`
- `ItemCategoryItemSetRule`, `ItemDefinitionItemSetRule`, and `ItemSlotCollectionItemSetRule`
- `CharacterEquipUnequipItemAction`, `CharacterUseItemAction`, `CharacterDropItemAction`, and `CharacterQuantityDropItemAction`
- `ItemObjectBinding` and `ItemToCharacterStateBinding`
- `InventoryItemAmmo` and `InventoryAmmoDataClip`
- `InventoryItemPickup`
- `CharacterEquippedSelectItemViewModule` and `WeaponAmmoItemViewModule`
- `InventoryBridgeSaver`

The integration-specific save lifecycle events are `OnInventoryBridgeSaverWillLoad` and `OnInventoryBridgeSaverLoaded`, declared in `IntegrationEventNames`. The bridge does not add network replication or authority. In a multiplayer project, make the Ultimate Inventory System inventory transaction authoritative, replicate Item and collection state through the networking layer, and let each owning client rebuild the local Ultimate Character Controller Character Item and Item Set representation.

---

<a id="page-ultimate-character-controller-integrations-uma"></a>

# UMA

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/uma/)


Use the [UMA](https://assetstore.unity.com/packages/tools/uma-2-unity-multipurpose-avatar-35611?aid=1100lGdc) integration when an avatar assembled by UMA must move, animate, use Items, and interact as an Ultimate Character Controller Version 3 character.

Choose the edit-time **Bone Builder** workflow for a character that you want to finish with the Ultimate Character Controller managers. Choose **UMA Character Builder** only when UMA must create the avatar in Play Mode and the project can perform any additional setup after creation.

## Compatibility boundary

The current Opsive documentation declares UMA `2.8+` as the minimum. The packaged `UMA.unitypackage` inspected for this page was updated in the Ultimate Character Controller Version 3 repository on August 20, 2025, but it contains no version Inspector or tested maximum-version declaration.

UMA now also has a separate [3.x release line](https://github.com/umasteeringgroup/UMA/releases). The checked-in Opsive package predates that release line, so this page does not claim UMA 3 compatibility. Confirm compilation and both workflows with the exact UMA and Ultimate Character Controller packages in the project before upgrading either product. The imported bridge source and its download notes take precedence if the supported boundary changes.

The integration is a plain Unity package, not an Integration Inspector. After UMA and Ultimate Character Controller compile, sign in to [Opsive Downloads](https://opsive.com/downloads/) and download the UMA integration. It is not included in the base product's Integrations folder before download. Its current source-visible components are **UMA Character Builder**, **UMA Ability Builder**, **UMA Item Pickup**, and **UMA First Person Base Object**.

## Choose a setup workflow

| Workflow | Choose it when | Important consequence |
| --- | --- | --- |
| **Bone Builder** | The character can exist in the editor before Play Mode and needs normal Ultimate Character Controller manager setup. | UMA generates the bones first; the Ultimate Character Controller Character and Item Managers can then configure the character like another humanoid model. This is the recommended route for Items, detailed abilities, ragdoll, and inspector-driven customization. |
| **UMA Character Builder** | The avatar must be generated from an UMA recipe at runtime. | The bridge creates a new Ultimate Character Controller root after UMA raises `CharacterCreated`. Setup is intentionally limited to the fields exposed by the runtime builder, so project code usually completes advanced configuration. |

Do not combine the workflows on the same avatar. **UMA Character Builder** exits when the generated UMA GameObject already contains **Ultimate Character Locomotion**.

## Before you begin

- Install UMA first, then Ultimate Character Controller Version 3, and resolve all compiler errors before importing the bridge.
- Run the Ultimate Character Controller [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/) so the Character, SubCharacter, Overlay, and related layers exist.
- Use a humanoid UMA avatar with a valid Avatar and an Ultimate Character Controller Animator Controller. Runtime Item slots and collider positioning depend on Unity's humanoid Head, Hips, and Hand bones.
- Create the Ultimate Character Controller Item Collection and Item Set Rule assets before enabling runtime Item support.
- Place and configure an Ultimate Character Controller Camera Controller before relying on **Assign Camera**. The UMA bridge assigns an existing camera; it does not create one.
- Save the scene and create a source-control checkpoint before changing the UMA avatar hierarchy or converting an existing character.

## Install the integration

1. Download the UMA integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import the downloaded package after both UMA and Ultimate Character Controller compile. Importing it creates `Assets/Opsive/UltimateCharacterController/Integrations/UMA` in the project.
3. Remove an older copy of `Assets/Opsive/UltimateCharacterController/Integrations/UMA` before importing a replacement package.
4. In **Add Component**, confirm that **UMA Character Builder**, **UMA Ability Builder**, **UMA Item Pickup**, and **UMA First Person Base Object** are available.
5. Reopen the Console and resolve missing UMA or Ultimate Character Controller types before configuring a character.

There is no UMA Integration Inspector or setup wizard in this package. Importing the Unity package is the complete installation step.

## Build an editor-configured character

Use Bone Builder when the generated skeleton can be prepared in the editor.

1. Place the UMA **Dynamic Character Avatar** prefab in the scene.
2. Open UMA's **Bone Builder** from the UMA toolbar.
3. Assign the scene avatar to **UMA GameObject** and select **Generate Bones**.
4. Open **Tools > Opsive > Ultimate Character Controller > Character Manager** and build the character with the generated UMA model.
5. Select the child that contains **Dynamic Character Avatar**.
6. In **Dynamic Character Avatar**, set **Additional Utility Recipes** to an empty list.
7. Under **Race Animation Controllers**, assign the Ultimate Character Controller controller to **Default Animator Controller**.
8. Under **Advanced Options**, enable **Keep Avatar** and **Keep Animator Controller**, then assign the same controller to **Animation Controller**.
9. On the child's **Animator**, assign the same asset to **Controller**.
10. Finish the character through the Ultimate Character Controller Character and Item Managers, then save the configured prefab or scene object.

![Dynamic Character Avatar configured with no additional utility recipes, the Demo controller, Keep Avatar, Keep Animator Controller, and the matching Animator Controller.](https://opsive.com/wp-content/uploads/2019/02/BoneBuilderDynamicCharacterAvatar.png?v=435329685519)

The three controller references must agree. Otherwise UMA can replace the controller after Ultimate Character Controller has configured the Animator, leaving the character visible but unable to drive the expected Ultimate Character Controller parameters.

## Build a character at runtime

Use this workflow when the avatar does not exist in its final form until UMA finishes generation.

1. Place the UMA **Dynamic Character Avatar** prefab in the scene.
2. Apply the same **Additional Utility Recipes**, **Default Animator Controller**, **Keep Avatar**, **Keep Animator Controller**, **Animation Controller**, and **Animator > Controller** settings used by the Bone Builder workflow.
3. Add **UMA Character Builder** to the same GameObject as **Dynamic Character Avatar**.
4. Enable **Add First Person Perspective**, **Add Third Person Perspective**, or both. Keep only movement types installed by the project's Ultimate Character Controller perspective packages.
5. Assign the Ultimate Character Controller **Animator Controller**.
6. Enable **Add Items** only when **Item Collection** and **Item Set Rule** reference project assets intended for this character.
7. Choose whether the builder should add **Health**, **Unity IK**, **Foot Effects**, and **Standard Abilities**.
8. For an AI character, enable **AI Agent** and optionally **Add Nav Mesh Agent**. For a player, leave **AI Agent** disabled.
9. If both perspectives are enabled, choose **Start First Person Perspective**.
10. Enable **Assign Camera** only for a player that should take ownership of the existing Ultimate Character Controller Camera Controller.
11. Add a listener to **Character Created** for setup that must use the newly created Ultimate Character Controller root.

![UMA Character Builder configured for first- and third-person movement, Items, health, Unity IK, foot effects, standard abilities, camera assignment, and a Character Created event.](https://opsive.com/wp-content/uploads/2019/02/UMACharacterBuilder.png?v=7d80b48d6fc3)

When UMA raises `DynamicCharacterAvatar.CharacterCreated`, the bridge:

1. removes a Capsule Collider directly on the generated avatar because Ultimate Character Controller creates its own collider structure;
2. creates a new GameObject at the avatar's position and rotation;
3. reparents the UMA-generated avatar beneath that new object;
4. uses Ultimate Character Controller's runtime Character Builder to add locomotion, movement types, the Animator Monitor, colliders, optional systems, and input or AI support;
5. assigns an existing Camera Controller when requested; and
6. invokes **Character Created**, then destroys **UMA Character Builder**.

The object supplied to **Character Created** is the new Ultimate Character Controller root. Scene, save, camera, networking, and gameplay references that still point to the original Dynamic Character Avatar point to the model child rather than the controllable character.

## Choose runtime options

### Perspectives and movement types

**First Person Movement Type** and **Third Person Movement Type** are fully qualified class-name strings. The packaged defaults are:

- `Opsive.UltimateCharacterController.FirstPersonController.Character.MovementTypes.Combat`
- `Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.Adventure`

**First Person Hidden Object Names** contains paths relative to the generated UMA model, such as `Head`. Ultimate Character Controller marks the resolved objects as third-person objects. Assign **Invisible Shadow Castor Material** when the first-person body should cast a shadow while its renderers are hidden.

### Items

With **Add Items** enabled, the runtime builder adds Ultimate Character Controller Inventory, Item Set Manager, Item Placement, the standard Item abilities, and Character Item Slots on the humanoid hands. It then initializes the Animator Monitor's Item parameters.

The builder does not create Character Item prefabs, Item Categories, or project-specific Item Sets. Prepare those assets separately. Use **UMA Item Pickup** only when one or more existing Ultimate Character Controller Item Pickup objects should grant their Items after creation.

### Abilities, health, IK, and foot effects

**Add Standard Abilities** adds Jump, Fall, Move Towards, Speed Change, and Height Change. It does not add every included ability and it does not create a Ragdoll setup.

**UMA Ability Builder** can add additional ability types by class-name string after the character is created, but it does not configure their fields. Treat it as a starting point for a project-specific builder rather than a substitute for the Character Manager.

**Add Health** adds the Character Attribute Manager, Character Health, and Character Respawner. **Add Unity IK** adds Character IK, and **Add Foot Effects** adds Character Foot Effects. Verify all bone-dependent behavior after UMA has produced the final skeleton.

### Player input, AI, and camera

The current **UMA Character Builder** custom Inspector does not expose its serialized **Add Input System** choice or an Input Actions field. Its default player path therefore builds the legacy Unity Input component. A project that uses Unity's Input System or another input integration should prefer Bone Builder or replace and configure input from **Character Created**, then verify **Player Input Proxy**. See [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/).

An AI build adds the local look source, removes player input handlers, and can add Nav Mesh Agent Movement. **Assign Camera** is skipped for AI agents. For a player, it only assigns an Ultimate Character Controller Camera Controller that `CameraUtility` can already find.

## Add generated first-person arms

The runtime bridge can use another UMA avatar as a generated first-person base object:

1. Place a second **Dynamic Character Avatar** in the scene for the arms or first-person body.
2. Add **UMA First Person Base Object** to it.
3. Set **Local Position**, **Local Rotation**, and its **Animator Controller**.
4. Add child paths to **Item Slot Locations** for each hand or other Item attachment point.
5. Add that component to the main **UMA Character Builder > First Person Base Objects** list.

After both avatars are ready, the component moves the first-person avatar beneath Ultimate Character Controller's First Person Objects root, assigns the Overlay layer, gives it a unique First Person Base Object ID, adds an Animator and Child Animator Monitor when configured, and creates Character Item Slots at the resolved paths. It then destroys itself.

Use [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/) for the Ultimate Character Controller Animator and Item requirements. A generic arms recipe is valid, but it still needs the expected humanoid animation and Item attachment structure.

## Handle later UMA avatar changes

The packaged bridge is an initial-construction bridge, not a continuous avatar-update adapter. **UMA Character Builder**, **UMA Ability Builder**, **UMA Item Pickup**, and **UMA First Person Base Object** each destroy themselves after their one-time work.

Wardrobe or material changes are safe only when they preserve the Ultimate Character Controller root, Animator, required humanoid bones, Item Slot paths, and collider references. A later UMA race or recipe rebuild that replaces the Animator or skeleton is not automatically rebound to Animator Monitor, Character IK, Character Foot Effects, collider positioning, Character Item Slots, or first-person objects.

For a project that rebuilds those objects after initial creation, listen to the appropriate UMA update event in project code and revalidate or rebind every affected Ultimate Character Controller component. Do not call the one-shot builder repeatedly on an existing Ultimate Character Controller character.

## Save and network runtime avatars

The package contains no UMA recipe saver, Ultimate Character Controller save orchestration, network authority, or replication code.

- Save the UMA recipe or avatar identity with UMA's supported workflow and save Ultimate Character Controller gameplay state with the project's chosen save system.
- During loading, recreate the UMA avatar, wait for **Character Created**, capture the new Ultimate Character Controller root, and only then restore Ultimate Character Controller state that depends on locomotion, Items, or abilities.
- For networking, create or assign the network identity and ownership against the new Ultimate Character Controller root after the event. Replicate the recipe and gameplay state through the selected networking solution.
- Do not use the original Dynamic Character Avatar reference as the persistent Ultimate Character Controller character reference after runtime construction.

## Editor checkpoint

Before entering Play Mode, confirm that:

- UMA, Ultimate Character Controller, and the imported bridge compile without errors;
- the project uses either Bone Builder or UMA Character Builder for this avatar, not both;
- **Dynamic Character Avatar** keeps the Ultimate Character Controller Avatar and Animator Controller;
- its UMA and Animator controller fields reference the same Ultimate Character Controller Animator Controller;
- runtime movement-type strings resolve to installed Ultimate Character Controller classes;
- **Item Collection** and **Item Set Rule** are assigned when **Add Items** is enabled;
- the player or AI choice matches the planned input and camera ownership;
- a Unity Input System or third-party input project has an explicit post-build input plan;
- **Character Created** captures the new Ultimate Character Controller root for dependent systems;
- the scene has the required Ultimate Character Controller layers and an existing Camera Controller when **Assign Camera** is enabled; and
- ragdoll, save, networking, and later UMA skeleton rebuilds have project-specific handling when required.

## Verify in Play Mode

1. Enter Play Mode and wait for UMA to finish. Confirm that one new parent object contains **Ultimate Character Locomotion** and that the generated UMA avatar is its model child.
2. Confirm that the Ultimate Character Controller root has one intended Rigidbody and collider hierarchy. The model should not retain a competing root Capsule Collider.
3. Move and rotate the player, or drive the AI. Confirm that the expected movement type is active and the Animator uses the Ultimate Character Controller controller.
4. Confirm that the camera follows the new root for a player and remains unassigned for an AI agent.
5. If Items are enabled, equip and use one Character Item. Confirm that hand slots, Item Sets, Item abilities, and Animator parameters update.
6. If both perspectives are enabled, switch perspectives. Confirm that the hidden model paths, shadow material, first-person base object, and Item Slots behave correctly.
7. Damage and respawn a character when **Add Health** is enabled. Test ragdoll only after a separate ragdoll setup has been added.
8. Change the UMA wardrobe and then perform any supported avatar rebuild. Confirm that the Animator, IK, feet, collider, and Items still reference valid objects.
9. Save and reload or spawn through the networking layer. Confirm that dependent systems use the new Ultimate Character Controller root returned by **Character Created**.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The bridge does not compile | Import order, duplicate old bridge files, and the exact UMA/Ultimate Character Controller versions | Install UMA and Ultimate Character Controller first, remove the previous `Integrations/UMA` folder, then import the matching bridge. Do not assume the unverified UMA 3 boundary. |
| Bone Builder creates bones but Ultimate Character Controller animation does not run | **Default Animator Controller**, **Animation Controller**, **Keep Avatar**, **Keep Animator Controller**, and **Animator > Controller** | Assign the same Ultimate Character Controller controller in all three locations and enable both keep options. |
| UMA reports a hierarchy-name conflict | Duplicate generated and Ultimate Character Controller Item placement object names | Rename only the conflicting Item placement objects to unique names such as `RightItems` and `LeftItems`, then update any paths or references that used the old names. |
| No runtime Ultimate Character Controller character is created | **UMA Character Builder** location, the UMA `CharacterCreated` event, and an existing **Ultimate Character Locomotion** on the generated object | Put the builder on the same Dynamic Character Avatar, remove a competing prebuilt Ultimate Character Controller setup, and confirm UMA completes generation once. |
| Another system still controls the model child | Its character reference was captured before runtime construction | Subscribe to **Character Created** and replace the reference with the event's new Ultimate Character Controller root. |
| A movement type cannot be found | Fully qualified class name and installed first- or third-person package | Use an exact current Ultimate Character Controller Version 3 type name or choose the Bone Builder workflow and configure it with Character Manager. |
| The player uses the wrong input backend | The runtime Inspector does not expose the current Input System setup fields | Replace and configure input after **Character Created**, including **Player Input Proxy**, or use Bone Builder. Do not leave competing player-input components active. |
| The camera remains on the previous target | **AI Agent**, **Assign Camera**, and whether an Ultimate Character Controller Camera Controller exists | Disable AI for a player, create/configure the camera first, or assign its **Character** from **Character Created**. |
| Item slots or first-person arms are missing | Humanoid hand bones, **Add Items**, **First Person Base Objects**, and exact child paths | Use a valid humanoid Avatar, assign Item assets, and correct the first-person Item Slot paths. |
| IK, footsteps, Items, or colliders fail after changing race | UMA may have replaced bones or the Animator after the one-shot bridge finished | Preserve the skeleton where possible or rebind the affected Ultimate Character Controller components from a project-specific UMA update listener. |
| Ragdoll is absent | The runtime builder has no Ragdoll option | Use Bone Builder and the normal Ultimate Character Controller ragdoll workflow, or implement and verify a project-specific post-build setup. |
| Loading or networking targets the wrong GameObject | Saved or replicated identity points to the original Dynamic Character Avatar | Wait for **Character Created**, then restore or bind state to the returned Ultimate Character Controller root. |

## Related pages

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/)
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/)
- [Animator Controller](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/animator-controller/)
- [First Person Arms](https://opsive.com/support/documentation/ultimate-character-controller/animation/animator/first-person-arms/)
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Artificial Intelligence](https://opsive.com/support/documentation/ultimate-character-controller/artificial-intelligence/)
- [Inverse Kinematics](https://opsive.com/support/documentation/ultimate-character-controller/inverse-kinematics/)
- [Ragdoll](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/included-abilities/ragdoll/)
- [Layer Manager](https://opsive.com/support/documentation/ultimate-character-controller/layer-manager/)
- [Ultimate Character Controller Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)

## Developer reference

The packaged source is under `Assets/Opsive/UltimateCharacterController/Integrations/UMA`:

- `UMACharacterBuilder` listens to `DynamicCharacterAvatar.CharacterCreated`, creates the new Ultimate Character Controller root, calls Ultimate Character Controller's runtime `CharacterBuilder`, invokes its own event, and destroys itself.
- `UMAAbilityBuilder` resolves each **Ability Types** entry with `TypeUtility.GetType`, adds the ability, and destroys itself.
- `UMAItemPickup` calls each assigned Ultimate Character Controller `ItemPickup.DoItemPickup` against the newly created Inventory and destroys itself.
- `UMAFirstPersonBaseObject` waits for its UMA object and the Ultimate Character Controller First Person Objects root, creates the first-person identifiers and Item Slots, and destroys itself.

**Character Created** is a `UnityEvent<GameObject, UMAData>`. The `GameObject` argument is the new Ultimate Character Controller root; `UMAData` describes the generated model. Use this event as the synchronization point for custom abilities, input replacement, save restoration, network ownership, camera assignment, and references held by other gameplay systems.

---

<a id="page-ultimate-character-controller-integrations-universal-render-pipeline"></a>

# Universal Render Pipeline

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/integrations/universal-render-pipeline/)

Use the Universal Render Pipeline support package when the Ultimate Character Controller project runs URP and first-person objects, materials, camera stacking, post processing, decals, or shaders must use the URP path.

## Import URP support

1. Install the intended Unity Universal Render Pipeline package and assign the URP Render Pipeline Asset in Project Settings.
2. Let Unity finish converting the project and confirm an ordinary scene renders correctly.
3. Open **Tools > Opsive > Ultimate Character Controller > Setup Manager** and select **Project**.
4. Under **Render Pipeline**, choose **URP** and select **Import**. The manager enables the Ultimate Character Controller URP scripting symbol for the active build target and imports the matching support package.
5. Resolve material or shader errors before configuring the character camera.

## Configure first-person rendering

1. Select the first-person View Type and set **Overlay Render Type** to **Render Pipeline**.
2. Configure the main/overlay camera relationship required by the installed Ultimate Character Controller and URP versions.
3. Put first-person objects on the intended layer and confirm the camera renderer/layer masks include that layer only where expected.
4. Configure post processing on the correct camera or volume route; do not duplicate it across cameras without testing the combined result.
5. Verify Object Fader, decals, particles, transparent materials, shadows, and the invisible shadow-caster material used by the character setup.

## Verify in Play Mode

1. Switch between first and third person and confirm cameras render the intended layers.
2. Aim an item close to a wall and check clipping, transparency, shadows, and post processing.
3. Spawn a decal, particle, projectile, and explosion and confirm each uses a URP-compatible material.
4. Change quality level and target platform, then repeat in a Development Build.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Materials are pink. | Check the active URP Asset and whether Ultimate Character Controller URP support was imported after URP. | Activate URP first, then import the matching support package and convert project materials deliberately. |
| First-person objects are missing or render twice. | Check Overlay Render Type, camera stack, renderer, and layer masks. | Use one intended URP overlay route and remove the duplicate camera/layer ownership. |
| Post processing differs by perspective. | Check which camera and volume layer owns the effect. | Configure the effect on the camera path active for both perspectives or explicitly mirror the intended settings. |
| The integration works in Editor but not after a build-target switch. | Check the Ultimate Character Controller URP scripting symbol for the current target. | Reopen Setup Manager after switching targets and reimport/refresh the pipeline support when required. |

## Related pages

- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Post Processing](https://opsive.com/support/documentation/ultimate-character-controller/camera/post-processing/)
- [High Definition Render Pipeline](https://opsive.com/support/documentation/ultimate-character-controller/integrations/high-definition-render-pipeline/)

---

<a id="page-ultimate-character-controller-videos"></a>

# Videos

[View this page online](https://opsive.com/support/documentation/ultimate-character-controller/videos/)

Use the video library to watch complete Ultimate Character Controller workflows, then use the written documentation beside each topic for the exact fields, menu paths, prerequisites, and supported behavior in the current Version 3 package.

## Start here

For a new project, follow this compact route:

1. Read [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) before adding UCC to an existing project.
2. Complete [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) once without customization.
3. Open the [Ultimate Character Controller video library](https://opsive.com/videos/?pid=25992) and choose the video that matches the task, keeping the related written page open as the current reference.

The external library is maintained separately from these docs, so individual titles, destinations, and recording versions can change. The written UCC documentation is the source of truth for current labels and Version 3 behavior.

## Find a route by task

### Project and scene setup

The video library currently includes **Project & Scene Setup**. Use it for the overall sequence, then confirm the current steps in:

- [Importing](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/importing/) for package and project prerequisites.
- [Quick Setup](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/quick-setup/) for managers, camera, and a playable character.
- [Demo Scene](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/demo-scene/) for learning from the supplied example.
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) when the video and the project's input backend differ.

### Character and camera

The library currently groups **First Person Character Creation**, **Third Person Character Creation**, and **Character Templates** around character setup. Pair them with:

- [Character Creation](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/) for the current manager workflow.
- [Character Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/character/character-creation/common-setups/) for common body and perspective choices.
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/) and [View Types](https://opsive.com/support/documentation/ultimate-character-controller/camera/view-types/) for camera ownership, perspective, and framing.
- [Movement Types](https://opsive.com/support/documentation/ultimate-character-controller/character/movement-types/) for how player input becomes character movement.

Choose the character perspective first, then configure its camera View Type and Movement Type. A creation video may demonstrate all three, but they remain separate runtime choices.

### Abilities and items

The current external index includes item-type and first-/third-person item creation, assault-rifle, sword, basic and advanced grenade, and item-set-rule videos. Use these written routes for their current configuration:

- [Abilities](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/) and [Creating a New Ability](https://opsive.com/support/documentation/ultimate-character-controller/character/abilities/new-ability/) for character behavior.
- [Item Creation](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/) for the shared creation workflow.
- [Item Creation Common Setups](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-creation/common-setups/) for perspective and item-shape decisions.
- [Item Set Rules](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/item-set-rules/) for what can be equipped together.
- [Item Actions](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/) for the modular runtime action model.
- [Shootable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/shootable/), [Melee](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/melee/), and [Throwable](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/character-item/item-actions/usable/throwable/) for the current action-specific fields.

Treat a weapon video as an end-to-end example, not as a substitute for the current action-module reference. Stop at each major checkpoint and verify the item in both the intended perspective and Play Mode before adding optional effects.

### Systems and integrations

The video index currently includes a two-part Ultimate Inventory System integration walkthrough. For that integration and other project systems, start with:

- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/) for the current integration catalog and prerequisites.
- [Ultimate Inventory System Integration](https://opsive.com/support/documentation/ultimate-character-controller/integrations/ultimate-inventory-system/) for the UCC-to-UIS connection.
- [Surface System](https://opsive.com/support/documentation/ultimate-character-controller/surface-system/) for material-specific footsteps and impacts.
- [State System](https://opsive.com/support/documentation/ultimate-character-controller/state-system/) for conditional property changes.
- [Animation](https://opsive.com/support/documentation/ultimate-character-controller/animation/) for Animator and animation-event requirements.
- [Input](https://opsive.com/support/documentation/ultimate-character-controller/input/) for input backend and control setup.

Integration recordings are especially sensitive to package-version and third-party UI changes. Follow the current integration page for supported versions and import steps before reproducing a video's Inspector settings.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| A menu item from the video is missing | The recording targets an earlier UCC release or a different installed controller package | Open the matching written page and use its current manager or asset-creation path. |
| A component or field has a different name | The recording predates the Version 3 modular workflow | Configure the current component or action module; do not add a legacy duplicate. |
| The scene does not match the recording | The render pipeline, input backend, sample version, or perspective differs | Return to Importing and Quick Setup, align those prerequisites, and repeat only the relevant section. |
| A character moves but the camera does not follow correctly | Character perspective, Camera View Type, and Movement Type do not form the intended combination | Review Character Creation, View Types, and Movement Types together, then retest in a clean Play Mode session. |
| An item works in only one perspective | The first- or third-person visible object and perspective properties are incomplete | Use Item Creation Common Setups and the relevant usable-action page to finish the intended perspective. |
| An integration option or installer is absent | The installed integration or third-party version differs from the recording | Use the current Integrations page and that integration's written prerequisites; do not reuse an archived package. |
| The basic result works but effects or animations do not | The video moved past a missing Animator, event, State, Surface, audio, or prefab reference | Verify the base action first, then add one optional system at a time from its written page. |

## Related documentation

- [Getting Started](https://opsive.com/support/documentation/ultimate-character-controller/getting-started/)
- [Component Overview](https://opsive.com/support/documentation/ultimate-character-controller/component-overview/)
- [Character](https://opsive.com/support/documentation/ultimate-character-controller/character/)
- [Camera](https://opsive.com/support/documentation/ultimate-character-controller/camera/)
- [Items and Inventory](https://opsive.com/support/documentation/ultimate-character-controller/items-inventory/)
- [Integrations](https://opsive.com/support/documentation/ultimate-character-controller/integrations/)
