Features
Built-in features
These features are part of KCC internal implementation. Default state is defined by KCCSettings.Features
and is also configurable in KCC inspector.
Active features for current fixed/render update can be modified from IBeginMove
stage by calling KCC.EnforceFeature()
and KCC.SuppressFeature()
.
Continuous Collision Detection (CCD)
- Divides movement to smaller steps based on desired velocity.
- The maximum distance traveled in single step is 25-75% of radius and is controlled by
KCCSettings.CCDRadiusMultiplier
property. - 75% is good in most cases, lower this value only if you have problems with KCC running through geometry.
- Before lowering
CCDRadiusMultiplier
try to increaseKCCSettings.MaxPenetrationSteps
(improves quality of depenetration).
Prediction Correction
- Enables smooth correction of predicted position error.
- The prediction error occurs when movement is simulated differently on server compared to client. There are various sources of error - floating point error accumulation, different physics engine state, different input handling due to game state, …
- Another source of error is different result from render update predictions compared to fixed update.
- This feature affects only visual/render, data in fixed update snaps to new state received from server.
- Enforcing/Suppressing this feature takes effect at the beginning of the next render update.
- Speed of prediction correction is controlled by
KCCSettings.PredictionCorrectionSpeed
.
Following image shows character path in fixed updates (red), render updates (green) and prediction correction (yellow) in action:
Anti-Jitter
- Enables render position distance tolerance to smooth out jitter.
- Distance is defined by
KCCSettings.AntiJitterDistance
(X for horizontal axis, Y for vertical axis). - Higher values may introduce noticeable delay when switching move direction and character visual may not align with ground (for example after jump)
Following image shows a top-down view with KCC and Transform positions represented by points on an XZ plane.
- Green points represent positions stored in
KCCData.TargetPosition
. These are synchronized to theTransform
component. - Blue points represent positions stored only in
KCCData.TargetPosition
. Because they are inside the anti-jitter area (gray circle) of previous position, they are not synchronized to theTransform
component => instead the old (green point) value is used. - When the
KCCData.TargetPosition
moves outside of the current anti-jitter area (red arrow), the area follows the point so it stays within the distance and the new position is synchronized toTransform
.
Feature processors
These features have separate implementation which makes them very easy to strip or replace by a different implementation.
Environment Processor
- Default processor packed with KCC addon.
- Defines behavior for grounded and floating state.
- Projected movement along ground tangent.
- Simple acceleration and friction model.
- Custom Gravity.
- Jump multiplier.
- Implements
IPrepareData
stage which executes 6 custom stages for fine-grained control of desired velocity (some of them are also implemented by the Environment Processor itself):ISetGravity
- dedicated stage to calculateKCCData.Gravity
.ISetDynamicVelocity
- dedicated stage to calculateKCCData.DynamicVelocity
.ISetKinematicDirection
- dedicated stage to calculateKCCData.KinematicDirection
.ISetKinematicTangent
- dedicated stage to calculateKCCData.KinematicTangent
.ISetKinematicSpeed
- dedicated stage to calculateKCCData.KinematicSpeed
.ISetKinematicVelocity
- dedicated stage to calculateKCCData.KinematicVelocity
.
- Implements
IAfterMoveStep
stage - used to recalculate properties after each move step (for example projection of kinematic velocity on ground). - The
EnvironmentProcessor
prefab is located atAssets\Photon\FusionAddons\KCC\Prefabs
.
Speed of the character is defined by this processor and can be used on scene objects to simulate behavior in various environments like water, mud, ice.
Step Up Processor
- Allows detection of steps (geometry which blocks horizontal movement, with walkable surface at some height).
- If a step is detected, the KCC moves upwards until it gets grounded.
- Maximum step height is defined by
Step Height
. - Forward step check distance is controlled by
Step Depth
. - The upward movement is equal to unapplied horizontal movement.
- The speed of upward movement is multiplied by
Step Speed
to compensate for loss of horizontal velocity. - The
StepUpProcessor
prefab is located atAssets\Photon\FusionAddons\KCC\Prefabs
.
Following image shows process of detecting steps:
- Upward check when the character is blocked by an obstacle in horizontal direction.
- Forward check to detect if the space in front of the character is collision free.
- Ground snap check to detect if the ground is walkable.
- The character moves upwards as long as all 3 checks pass.
Ground Snap Processor
- Allows keeping grounded state when the contact with ground is lost (stairs, uneven terrain).
- Pushes character closer to ground if gravity is not enough.
- Maximum snap distance is defined by
Snap Distance
. - The movement speed towards ground is defined by
Snap Speed
. - The
GroundSnapProcessor
prefab is located atAssets\Photon\FusionAddons\KCC\Prefabs
.
Following image shows process of ground snapping:
The character is virtually pushed downwards until one of following conditions are met:
- The character hits walkable ground => KCC keeps grounded and moves towards the ground.
- The character hits non-walkable surface and cannot slide along it => KCC loses grounded state.
Snap Distance
is reached => KCC loses grounded state.
Platform Processor
- Tracks platform objects and propagates position/rotation changes to KCC.
- Snaps KCC proxy to a tracked platform(s) by interpolating between world-space and platform-space.
- Each KCC must have a unique instance of
PlatformProcessor
(for example child object of a player prefab). - Duration of transition from world-space to platform-space is defined by
PlatformSpaceTransitionDuration
. - Duration of transition from platform-space to world-space is defined by
WorldSpaceTransitionDuration
. - The
PlatformProcessor
prefab is located atAssets\Photon\FusionAddons\KCC\Prefabs
.
Typical setup requires following steps:
- Drag & drop
PlatformProcessor
prefab under your Player/KCC prefab as a child object. - Link the processor instance to
Processors
property in KCC settings. - Now the KCC will be able to track and propagate movement from all platforms.
There are some requirements and restrictions to correctly track a platform:
- The platform object must have
NetworkObject
andRigidbody
(kinematic) components. - The platform script must implement
IPlatform
interface. - The platform script be a KCC processor.
- In host mode, movement of the platform must be predicted on all (server and clients).
- Execution order of the platform script must be lower than
PlatformProcessor
so it's executed first.
Following code shows an example of a platform script:
C#
[DefaultExecutionOrder(-1000)]
[RequireComponent(typeof(Rigidbody))]
public sealed class PlatformMovement : NetworkTRSPProcessor, IPlatform, IBeforeAllTicks
{
public Transform Transform;
public Rigidbody Rigidbody;
public override void Spawned()
{
// Enable simulation also for proxy object.
Runner.SetIsSimulated(Object, true);
}
public override void FixedUpdateNetwork()
{
CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation);
// Set network state of NetworkTRSP.
State.Position = nextPosition;
State.Rotation = nextRotation;
// Update engine components.
Transform.position = nextPosition;
Transform.rotation = nextRotation;
Rigidbody.position = nextPosition;
}
public override void Render()
{
CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation);
// Update only engine components, do not store in network state.
Transform.position = nextPosition;
Transform.rotation = nextRotation;
Rigidbody.position = nextPosition;
}
void IBeforeAllTicks.BeforeAllTicks(bool resimulation, int tickCount)
{
// Restore state of the object before simulation.
Transform.SetPositionAndRotation(State.Position, State.Rotation);
Rigidbody.position = State.Position;
}
private void CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation)
{
nextPosition = State.Position;
nextRotation = State.Rotation;
// Movement based on waypoints, AnimationClip, ...
}
}
It is crucial to respect execution order (IPlatform
=> PlatformProcessor
=> Player
=> KCC
) to get smooth and error-free movement propagation:
- Update of all
IPlatform
scripts - calculating new position/rotation values and updatingTransform
andRigidbody
components. - Update of all
PlatformProcessor
scripts - processing of all trackedIPlatform
objects, propagation of theirTransform
changes since last update to KCCTransform
andKCCData
. After this step all platforms are processed and characters moved. - Update of all
Player
scripts - settings input values forKCC
movement. - Update of all
KCC
scripts - predicted movement and interpolation.
The process above ensures that any KCC moves and collides with most up-to-date state of platforms and other KCCs.
⚠️ Platform examples can be found in Sample Project.
Back to top