/// <summary> /// Updates an active batched anim controller. /// </summary> /// <param name="instance">The controller to update.</param> /// <param name="dt">The time since the last update.</param> private static void UpdateActive(KBatchedAnimController instance, float dt) { Transform transform; var batch = instance.batch; var visType = instance.visibilityType; bool visible = instance.IsVisible(); // Check if moved, do this even if offscreen as it may move the anim on screen if (batch != null && (transform = instance.transform).hasChanged) { var lastChunk = instance.lastChunkXY; Vector3 pos = transform.position, posWithOffset = pos + instance.Offset; float z = pos.z; Vector2I cellXY; bool always = visType == KAnimControllerBase.VisibilityType.Always; transform.hasChanged = false; // If this is the only anim in the batch, and the Z coordinate changed, // override the Z in the batch if (batch.group.maxGroupSize == 1 && instance.lastPos.z != z) { batch.OverrideZ(z); } instance.lastPos = posWithOffset; // This is basically GetCellXY() with less accesses to __instance.transform if (Grid.CellSizeInMeters == 0.0f) { // Handle out-of-game cellXY = new Vector2I((int)posWithOffset.x, (int)posWithOffset.y); } else { cellXY = Grid.PosToXY(posWithOffset); } if (!always && lastChunk != KBatchedAnimUpdater.INVALID_CHUNK_ID && KAnimBatchManager.CellXYToChunkXY(cellXY) != lastChunk) { // Re-register in a different batch instance.DeRegister(); instance.Register(); } else if (visible || always) { // Only set dirty if it is on-screen now - changing visible sets dirty // If it moved into a different chunk, Register sets dirty instance.SetDirty(); } } // If it has a batch, and is active if (instance.batchGroupID != KAnimBatchManager.NO_BATCH) { var anim = instance.curAnim; var mode = instance.mode; bool force = instance.forceRebuild, stopped = instance.stopped; float t = instance.elapsedTime, increment = dt * instance.playSpeed; // Suspend updates if: not currently suspended, not force update, and one // of (paused, stopped, no anim, one time and finished with no more to play) if (!instance.suspendUpdates && !force && (mode == KAnim.PlayMode.Paused || stopped || anim == null || (mode == KAnim.PlayMode.Once && (t > anim. totalTime || anim.totalTime <= 0f) && instance.animQueue.Count == 0))) { instance.SuspendUpdates(true); } if (visible || force) { var aem = instance.aem; var handle = instance.eventManagerHandle; instance.curAnimFrameIdx = instance.GetFrameIdx(t, true); // Trigger anim event manager if time advanced more than 0.01s if (handle.IsValid() && aem != null) { float elapsedTime = aem.GetElapsedTime(handle); if (Math.Abs(t - elapsedTime) > 0.01f) { aem.SetElapsedTime(handle, t); } } instance.UpdateFrame(t); // Time can be mutated by UpdateFrame if (!stopped && mode != KAnim.PlayMode.Paused) { instance.SetElapsedTime(instance.elapsedTime + increment); } instance.forceRebuild = false; } else if (visType == KAnimControllerBase.VisibilityType.OffscreenUpdate && !stopped && mode != KAnim.PlayMode.Paused) { // If invisible, only advance if offscreen update is enabled instance.SetElapsedTime(t + increment); } } }