The Ultimate Character Controller (UCC) is architected around a state-driven, highly extensible framework that decouples character movement, combat, and input processing. At its core, the system avoids tight class coupling through an event-driven messaging layer combined with a modular Ability System. Instead of hardcoding movement state machines into monolithic components, every discrete action—such as jumping, vaulting, sliding, or equipping weapons—is implemented as a encapsulated subclass of the core Ability base class.
The character motor relies on custom kinematic velocity integration rather than standard rigidbodies, giving the software author absolute control over collision response, step handling, slope calculation, and ground alignment. Raycast-based ground detection utilizes non-allocating physics batching to prevent garbage collector pressure during high-frequency execution frames.
ScriptableObject data containers, allowing global tuning without re-compiling scene references.EventHandler system that avoids expensive runtime C# Reflection and string lookups.To extend default movement behaviors, developers inherit from Ability and override execution lifecycle callbacks. The snippet below demonstrates a bespoke mobility ability utilizing the internal kinematic locomotion motor:
using UnityEngine;
using Opsive.UltimateCharacterController.Character.Abilities;
public class CustomDashAbility : Ability
{
[SerializeField] protected float m_DashForce = 15f;
[SerializeField] protected float m_DashDuration = 0.35f;
private float m_StartTime;
public override bool IsConcurrent => true;
public override bool CanStartAbility()
{
return base.CanStartAbility() && m_CharacterLocomotion.Grounded;
}
protected override void AbilityStarted()
{
base.AbilityStarted();
m_StartTime = Time.time;
}
public override void UpdatePosition()
{
base.UpdatePosition();
if (Time.time < m_StartTime + m_DashDuration)
{
// Apply custom kinematic velocity override
m_CharacterLocomotion.MotorRotation = Quaternion.LookRotation(m_CharacterLocomotion.TargetLookDirection);
m_CharacterLocomotion.AddForce(m_CharacterLocomotion.Transform.forward * m_DashForce, 1, true, true);
}
else
{
StopAbility();
}
}
}
The toolkit heavily customizes the Unity Editor workflow using custom property drawers, GUI wizards, and context-sensitive inspectors. The central configuration hub is managed via the Main Manager Editor Window, which streamlines setup operations into distinct setup pipelines: Character Creation, Item Definition, Surface Definition, and State Configuration.
Each component exposes customized drawers that provide contextual UI elements based on state presets. The Ultimate Character Locomotion component dynamically reorganizes inspector properties according to active categories (Abilities, Movement, Effects, Animator Parameters). Instead of cluttering components with long arrays, abilities are presented in reorderable list views where priority execution order is dictated from top to bottom.
Properties inside the inspector can be dynamically overridden at runtime using the asset's State System. When specific conditions are met (e.g., character enters water, toggles a scope, or switches to a crouch state), property modifications defined inside lightweight Preset files are dynamically injected over base values. This removes the necessity for custom coding when tweaking variables like FOV, locomotion speed multipliers, or IK weight balancing.
Setting up a functional character controller requires configuring core project settings, generating runtime manager instances, and assigning animator structures through the automated wizard suite.
Navigate to the top menu bar under Tools -> Opsive -> Ultimate Character Controller -> Main Manager. Select the Setup tab and instantiate the global managers. This populates your scene with crucial singletons:
GlobalManager: Handles global lifecycle triggers and deterministic update loops.SurfaceManager: Maps physics materials and audio/VFX impact effects to footstep audio and bullet hits.SpawnManager: Controls dynamic entity spawning and instantiation points.In the Main Manager window, select the Character tab. Assign your target model prefab (Mecanim Humanoid or Generic rig) and specify the perspective mode (First Person, Third Person, or Dual Perspective). Click Create Character. The wizard automatically appends core components, including:
UltimateCharacterLocomotionItemHandlerCharacterLayerManagerAnimator with configured animator controllersTo communicate with external systems (such as custom UI or quest logs), subscribe to the framework's internal EventHandler pipeline as shown below:
using UnityEngine;
using Opsive.UltimateCharacterController.Events;
public class PlayerHealthObserver : MonoBehaviour
{
[SerializeField] private GameObject m_CharacterGameObject;
private void OnEnable()
{
EventHandler.RegisterEvent<float, Vector3, Vector3>(m_CharacterGameObject, "OnHealthDamage", OnTakeDamage);
EventHandler.RegisterEvent(m_CharacterGameObject, "OnDeath", OnCharacterDeath);
}
private void OnDisable()
{
EventHandler.UnregisterEvent<float, Vector3, Vector3>(m_CharacterGameObject, "OnHealthDamage", OnTakeDamage);
EventHandler.UnregisterEvent(m_CharacterGameObject, "OnDeath", OnCharacterDeath);
}
private void OnTakeDamage(float amount, Vector3 point, Vector3 direction)
{
Debug.Log($"Character took {amount} damage at position {point}");
}
private void OnCharacterDeath()
{
Debug.Log("Character has died. Triggering game over UI.");
}
}
Because the toolkit coordinates complex physics calculations, animation IK layer passes, camera collision sweeps, and hit registration simultaneously, optimizing runtime performance requires adherence to specific architecture rules.
The framework achieves zero per-frame runtime allocations during standard movement execution loops by caching internal array allocations and avoiding allocations in collision sweeps. Collision detection utilizes pre-allocated arrays alongside non-allocating variants like Physics.OverlapCapsuleNonAlloc and Physics.RaycastNonAlloc. However, developers must take care when creating custom abilities or registering string-based custom parameters, ensuring delegates are cached to prevent runtime closure allocations.
To avoid visual jitter during rapid camera movement, synchronization between physics execution and render cycles must be configured carefully:
Update Location.FixedUpdate when running physics-heavy interactions to match Unity's fixed timestep.EventHandler requires dynamic code generation preservation via a custom link.xml file to prevent dynamic link stripping errors on mobile platforms.| Category | Tools / Game Toolkits |
|---|---|
| Latest Version | v3.3.6 (2 tracked releases) |
| File Size | 581.30 MB |
| Added to Platform | February 5, 2026 |
| Views | 28 views |
| Downloads | 6 downloads |
| Favourites | 2 favourites |
| Official Store | Buy Original License on Unity Asset Store → |
| Issue with Package? | Report Broken Link → |