Skip to content

TweenUpdaterSystem Optimisation#7644

Open
GBirch33 wants to merge 1 commit intodevfrom
chore/tweenupdatersystem_optimisation
Open

TweenUpdaterSystem Optimisation#7644
GBirch33 wants to merge 1 commit intodevfrom
chore/tweenupdatersystem_optimisation

Conversation

@GBirch33
Copy link
Collaborator

@GBirch33 GBirch33 commented Mar 18, 2026

Pull Request Description

What does this PR change?

This PR optimises the tween update pipeline, addressing per-frame CPU cost in TweenSequenceUpdaterSystem and TweenUpdaterSystem. Profiling identified the hottest areas as: redundant ECS archetype traversals, repeated interface dispatch to resolve ISceneStateProvider.IsCurrent, unnecessary delegate
allocations, and pool rent/release churn inside the CRDT writer on every frame per active tween.

Changes

TweenSequenceUpdaterSystem

  • Merged the former UpdatePBTweenSequence and UpdateTweenSequenceState queries into a single query, halving ECS archetype traversal for sequence entities each frame.
  • Replaced two separate sequence list scans (SequenceRequiresMaterial + SequenceHasTransformTweens) with a single combined AnalyzeSequence pass that early-exits once both flags are resolved.
  • Replaced foreach iteration over pbTweenSequence.Sequence (a protobuf RepeatedField) with an indexed for loop to avoid enumerator allocation on every dirty frame.

TweenUpdaterSystem + TweenSequenceUpdaterSystem

  • sceneStateProvider.IsCurrent is now cached once at the top of Update() into a per-frame isCurrentScene field, eliminating repeated interface dispatch per active tween entity per frame.

TweenSDKComponentHelper

  • All helper methods that previously threaded ISceneStateProvider through the call chain now accept a pre-resolved bool isCurrentScene, consistent with the above.
  • Fixed a non-static lambda in WriteSDKTransformUpdateInCRDT — since the lambda captures no variables, making it static eliminates a heap-allocated delegate per call (i.e., every frame per active transform tween).

OutgoingCRDTMessagesProvider

  • AddPutMessage<TMessage, TData> now checks whether a PUT_COMPONENT message for the same entity+component key is already pending in the outgoing queue. If so, the existing pooled message object is updated in place rather than renting a new one, releasing the old one, and replacing the entry. Since CRDT
    serialisation runs less frequently than the frame loop, this is the hot path for all continuously-updating components (tweens, transforms). This eliminates the pool rent + release cycle on every frame for active tweens.
  • The DELETE → PUT edge case is handled correctly: if the existing pending message is a DELETE, a new message is rented and replaces it as before.

Test Instructions

Prerequisites

  • A scene or SDK playground with active PBTween and/or PBTweenSequence entities (both transform and texture tweens if possible)
  • Unity Profiler available for before/after comparison (optional but recommended)

Test Steps

  1. Load a scene containing entities with active PBTween components (move, rotate, scale, and/or texture tweens).
  2. Load a scene containing entities with active PBTweenSequence components.
  3. Observe that tweens animate correctly — position, rotation, scale, and texture offsets all update as expected.
  4. Verify that tween state transitions (active → completed, active → paused) are reported correctly to the SDK.
  5. Verify that sequences with looping (TlYoyo, TlRestart) behave correctly.
  6. Verify that sequences containing texture tweens correctly load and animate material offsets.
  7. Confirm no regressions against existing tween tests (TweenUpdaterSystemShould, TweenSequenceSystemShould, TweenSDKComponentHelperShould).

Additional Testing Notes

  • The OutgoingCRDTMessagesProvider change is not tween-specific — any system that calls PutMessage repeatedly for the same entity+component within a single CRDT batch will benefit. Watch for unexpected behaviour in other CRDT-writing systems if any edge cases were missed.
  • The DELETE then PUT within the same frame case should be verified if there is an existing test for component removal followed by re-add on the same entity in the same frame.

@GBirch33 GBirch33 requested review from a team as code owners March 18, 2026 14:06
@github-actions
Copy link
Contributor

github-actions bot commented Mar 18, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant