Kanda Interactions 0.7.1
Loading...
Searching...
No Matches
Moving Entities

Movables are fundamental to our interaction framework. They provide a flexible way to manage the movement of entities in both local and networked contexts, with support for smooth interpolation and world space transformations.

Core Systems

Local Movement

The LocalMovableSystem handles non-networked entities in client simulation. This system is suitable for UI elements, local effects, or any entities that don't need network synchronization.

Replicated Movement

The PredictedMovableSystem processes networked entities (ghosts) in both client and server simulations. This system handles predicted movement and input replication, making it ideal for player-controlled objects or synchronized game elements.

Key Features

  • Local and world space movement
  • Optional smoothing for gradual interpolation
  • Input-driven movement for player-controlled ghosts
  • Networked prediction and replication support

Intended Use

Basic Local Movement

For non-networked entities, add a Movable component:

var entity = EntityManager.CreateEntity(typeof(LocalTransform), typeof(LocalToWorld), typeof(Movable));
EntityManager.SetComponentData(entity, Movable.FromPositionRotation(
new float3(1, 2, 3),
quaternion.identity
));

The LocalMovableSystem will automatically update the entity's LocalTransform to match the target.

Networked Movement

For networked entities that need prediction and replication, make sure the entity is a ghost prefab.

var entity = EntityManager.Instantiate(myMovableGhost);
EntityManager.SetComponentData(entity, Movable.FromPositionRotation(
new float3(1, 2, 3),
quaternion.identity
));

The PredictedMovableSystem will handle movement prediction and synchronization.

World Space Movement

For entities that need to move in world space (e.g., within a hierarchy), set WorldSpace = true:

EntityManager.SetComponentData(
entity,
Movable.FromPositionRotation(
new float3(1, 2, 3),
quaternion.identity,
worldSpace: true
)
);

If your movables are root-level entities, use local space movement for improved performance.

Smooth Movement

For gradual, interpolated movement, combine Movable with a SmoothMovable component:

EntityManager.AddComponentData(entity, new SmoothMovable
{
SmoothingTimeSeconds = 0.5f
});

This works with both local and replicated movables. Smoothing is based on tracking how many network ticks have passed, making it near-deterministic on the server and client.

Input-Driven Movement

For player-controlled networked entities, use the MovableInput component:

// Entity must be a predicted ghost
EntityManager.AddComponent<MovableInput>(entity);

The PredictedMovableSystem will apply inputs to the Movable when the local player owns the ghost. This input will be predicted on the client and validated on the server.

MovableInput is only processed for entities that have both PredictedGhost and GhostOwnerIsLocal components.

Lock Movable

In some cases, you may want to lock entity movement to a certain axis. For example, you may want a dialog UI to follow a player's head, but not "roll" with the head rotation, keeping it horizontally aligned with other UIs.

To do this we provide LockMovable where you can set up which axis we want to lock the position or rotation for.

EntityManager.AddComponentData(attachedEntity, new LockMovable() {
Rotation = LockAxis.Z
});

Performance Considerations

Using Movable Systems

When an entity has a Movable component, either LocalMovableSystem or PredictedMovableSystem will "own" its movement, updating the LocalTransform based on the Movable target. This is ideal when you need:

  • Smooth interpolation
  • Movement locking
  • World space transformations
  • Client prediction and replication
  • Input-driven movement

Be aware that directly modifying the LocalTransform of a Movable entity will result in systems "fighting" for its placement.

Disabling Movement

The Movable component is an IEnableableComponent. You can temporarily disable it to bypass movement processing:

EntityManager.SetComponentEnabled<Movable>(entity, false);

While the component is disabled, you are free to manipulate its LocalTransform. Once re-enabled, the entity will "snap back" to the target position/rotation of the Movable component.

Direct Transform Manipulation

For entities that don't require the features provided by the movable systems, simply don't add the Movable component. Then the LocalTransform component for these entities can be modified directly:

// Simple direct movement without Movable
EntityManager.SetComponentData(entity,
LocalTransform.FromPosition(new float3(1, 2, 3))
);

Choose the approach that best fits your specific use case:

  • Use local movables for local player parts, non-networked UI and effects
  • Use replicated movables for predicted networked movement
  • Use direct transform manipulation for optimized or specialized movement

For most scenarios, the movable systems provide a good balance of features and performance.