Skip to content

Game.Rendering.RelativeObjectSystem

Assembly: Game
Namespace: Game.Rendering

Type: public class RelativeObjectSystem

Base: GameSystemBase

Summary:
RelativeObjectSystem is a rendering/animation-focused ECS system used by the game to update entities that are positioned relative to other entities (Relative component). It integrates with the rendering & pre-culling pipeline and the animated system to: - Compute world transforms for entities that are defined relative to a parent (e.g., props, passengers, sub-objects). - Update interpolated transforms for smooth rendering/interpolation. - Update and drive per-entity animations (including special driving animations and steering blending). - Propagate transform updates down to nested sub-objects. The system schedules two Burst-compiled jobs: UpdateRelativeTransformDataJob (parallel, deferred using PreCullingData index) and UpdateQueryTransformDataJob (IJobChunk) and wires job dependencies with PreCullingSystem and AnimatedSystem.


Fields

  • private RenderingSystem m_RenderingSystem
    Reference to the global RenderingSystem used to obtain frame indices, frameTime, frameDelta, and frame LOD info.

  • private PreCullingSystem m_PreCullingSystem
    Reference to the PreCullingSystem used to read per-frame culling data (PreCullingData list).

  • private AnimatedSystem m_AnimatedSystem
    Reference to the AnimatedSystem used to set and write animation frames and obtain AnimationData.

  • private CameraUpdateSystem m_CameraUpdateSystem
    Reference to the camera updater; used to obtain camera position/direction and LOD parameters.

  • private BatchDataSystem m_BatchDataSystem
    Reference to the batch data system used to query level-of-detail information.

  • private EntityQuery m_RelativeQuery
    (Declared but not populated in OnCreate) potential query for relative objects.

  • private EntityQuery m_InterpolateQuery
    EntityQuery used when scheduling UpdateQueryTransformDataJob. Matches entities with Temp + Relative and (optionally) InterpolatedTransform, excluding Deleted.

  • private uint m_PrevFrameIndex
    Frame index for the previous update; used for interpolation/update-frame detection.

  • private TypeHandle __TypeHandle
    Internal struct storing ComponentLookup/BufferLookup/TypeHandle instances used to set up job data.

Properties

  • None (no public properties exposed by this class).

Nested Types / Jobs (high level)

  • private struct UpdateRelativeTransformDataJob : IJobParallelForDefer
    Burst-compiled parallel job that iterates over a NativeList (deferred indexing) and:
  • Filters pre-culling entries to those that are NearCamera, InterpolatedTransform and Relative.
  • Resolves the parent entity (owner or current vehicle).
  • Computes relative world transform using GetRelativeTransform (supports bone attachments and sub-mesh offsets).
  • Updates InterpolatedTransform for the entity.
  • If entity has animations, calculates update frames and updates interpolated animation frames via UpdateInterpolatedAnimations.
  • Recursively updates sub-object transforms (UpdateTransforms). Important data used: many ComponentLookup/BufferLookup handles (Owner, Relative, PrefabRef, BoneHistory, SubMesh, Animated, InterpolatedTransform, CullingInfo, etc.), random seed, animation data, camera/LOD params and PreCullingData.

  • private struct UpdateQueryTransformDataJob : IJobChunk
    Burst-compiled IJobChunk that processes a chunk of entities:

  • For entities with InterpolatedTransform and certain Temp flags, computes transforms from owner (like in the parallel job) and resets animation state where needed.
  • Copies transforms from original entity (Temp.m_Original) when appropriate.
  • Initializes or synchronizes Animated buffers (animation indices, times) and sets animation frames via AnimatedSystem.AnimationData.SetAnimationFrame.
  • Updates sub-object transforms recursively. This job complements the deferred parallel job to ensure entities matched by the m_InterpolateQuery get consistent transforms/animation states.

  • private struct TypeHandle
    Internal container of ComponentLookup/BufferLookup/EntityTypeHandle/SharedComponentTypeHandle/ComponentTypeHandle instances. It has a __AssignHandles(ref SystemState state) method used to bind the handles from the system state.

Constructors

  • public RelativeObjectSystem()
    Default public constructor. The system uses OnCreate to obtain references to other systems and set up queries.

Methods

  • protected override void OnCreate()
    Obtains references to other systems:
  • RenderingSystem, PreCullingSystem, AnimatedSystem, CameraUpdateSystem, BatchDataSystem.
  • Creates m_InterpolateQuery: All = Temp + Relative, Any = InterpolatedTransform, None = Deleted. Called when the system is created.

  • protected override void OnUpdate()
    Core update that:

  • Requests culling data from PreCullingSystem (and its job dependency).
  • Requests AnimationData writer from AnimatedSystem (and its dependency).
  • Obtains camera position/direction and LOD parameters via CameraUpdateSystem (if available).
  • Constructs UpdateRelativeTransformDataJob instance and schedules it over PreCullingData (deferred parallel).
  • Schedules UpdateQueryTransformDataJob over m_InterpolateQuery (IJobChunk) with the deferred job as dependency.
  • Passes resulting job handle to PreCullingSystem.AddCullingDataReader and AnimatedSystem.AddAnimationWriter; sets base.Dependency.
  • Updates m_PrevFrameIndex.

  • private static Transform GetRelativeTransform(Relative relative, Entity parent, ref BufferLookup<BoneHistory> boneHistoryLookup, ref ComponentLookup<PrefabRef> prefabRefLookup, ref BufferLookup<SubMesh> subMeshLookup)
    Resolves the relative Transform of an entity:

  • If relative references a bone index, uses the bone history matrix to transform relative position & rotation.
  • If additional sub-mesh offset index is present, applies sub-mesh position/rotation offset from the parent's prefab sub-meshes.
  • Returns computed Transform (position + quaternion rotation).
  • Falls back to relative.m_Position/m_Rotation if bone index not valid.

  • public static void UpdateDrivingAnimationBody(Entity entity, in CharacterElement characterElement, DynamicBuffer<AnimationClip> clips, ref ComponentLookup<Human> humanLookup, ref BufferLookup<AnimationMotion> motionLookup, InterpolatedTransform oldTransform, InterpolatedTransform newTransform, ref Animated animated, ref Random random, float3 velocity, float steerAngle, AnimatedPropID propID, float updateFrameToSeconds, float speedDeltaFactor, float deltaTime, int updateFrameChanged, bool instantReset)
    High-level driving animation logic for a character body:

  • Determines current activity (Driving vs Standing) based on forward velocity & steering.
  • Chooses appropriate driving/steering animation clips and handles clip transitions/indices, interpolation and timing.
  • Performs clip swapping when update frames indicate a change or when clip conditions require it.
  • Advances clip times based on deltaTime and whether movement speed slots are zero. This is a key static helper used by both jobs to update per-character driving animation states.

  • public static void UpdateDrivingClips(Entity entity, ref AnimationClip clip, ref AnimationClip clipI, ref short clipIndex, ref short clipIndexI, ref float movementSpeed, ref float interpolation, DynamicBuffer<AnimationClip> clips, ref ComponentLookup<Human> humanLookup, float steerAngle, AnimatedPropID propID, ActivityType targetActivity)
    Helper used by UpdateDrivingAnimationBody:

  • Based on steerAngle selects appropriate left/right/idle animation types, finds clips using ObjectInterpolateSystem.FindAnimationClip, sets clip indices and interpolation values.
  • Handles clipI (steering helper clip for smooth transitions) and movementSpeed / interpolation parameters.

  • public static float GetTargetRotation(in AnimationClip clip, float def, float prev)
    Returns the target rotation threshold for steer-based blending:

  • Uses clip.m_TargetValue if set, otherwise default def.
  • Ensures value is at least prev + 1 degree (in radians).

  • private void __AssignQueries(ref SystemState state)
    Currently creates/disposes an empty EntityQueryBuilder (no queries assigned in this method). Used by OnCreateForCompiler path.

  • protected override void OnCreateForCompiler()
    Helper used by generated/compiled systems:

  • Calls __AssignQueries and assigns component/buffer/type handles from __TypeHandle to the system state.

  • Misc (job Execute/UpdateTransforms)
    The nested jobs implement many internal helpers:

  • UpdateTransforms(ownerTransform, subObjects) — recursively updates InterpolatedTransform for sub-objects that have Relative component, converting local-to-world transform using ObjectUtils.LocalToWorld.
  • UpdateInterpolatedAnimations(...) — handles per-entity animation update when PreCullingFlags.Animated is set, including computing LOD priority and calling AnimatedSystem.AnimationData.SetAnimationFrame.

Usage Example

// This system is created/managed by the World. Example: get reference to the system and call a static helper.
var relSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<Game.Rendering.RelativeObjectSystem>();

// Call a static helper directly (e.g., to compute a target rotation) — most interactions are internal to the ECS pipeline.
float targetRotation = Game.Rendering.RelativeObjectSystem.GetTargetRotation(myClip, math.radians(5f), 0f);

// Note: RelativeObjectSystem is intended to run inside the game's ECS update loop; user mods should generally not invoke its OnUpdate manually.
// If you want to influence behavior, modify components (Relative, Transform, Animated buffers, Temp flags, etc.) so the system processes entities naturally.

Notes / Implementation details ({{ YOUR_INFO }}): - The system heavily relies on PreCullingData flags to limit work to near-camera and relevant entities. PreCullingFlags used include NearCamera, InterpolatedTransform, Relative, Temp, Animated and NearCameraUpdated. - Bone attachments and sub-mesh offsets are supported: Relative entries can reference a bone (BoneHistory) and optionally a sub-mesh index from the parent's prefab to apply additional transform offsets. - Animation integration uses Animated buffers and AnimatedSystem.AnimationData to compute and set per-submesh/character animation frames. Characters with multiple SubMeshGroups use CharacterElement and style-based AnimationClip buffers. - The two main jobs are Burst-compiled for performance and are scheduled with proper job dependencies; the system registers readers/writers with PreCullingSystem and AnimatedSystem so these systems can manage proper synchronization. - Most methods and jobs assume many ComponentLookup/BufferLookup handles are set via the internal TypeHandle during system creation; modders should be careful when adding/removing components that could change query behavior.