CesiumGlobeAnchor.Sync() getting called too many times

I recently updated CesiumUnity from v1.8.0 to v1.14.1 and I am seeing some poor performance on the Quest 3. I made a development build and looked at the Unity profiler to see where the bottleneck is. I found that CesiumGlobeAnchor.Sync() is getting called ~300 times per frame which is odd because I only have ~20 CesiumGlobeAnchor in the scene.

I’m not explicitly calling CesiumGeoreference.AddGlobeAnchor anywhere, so quite I’m confused by this call stack. Any idea what would cause this?

I’m periodically logging how many I have in the scene to be sure:

var globeAnchors = FindObjectsOfType<CesiumGlobeAnchor>(true);
                Debug.Log($"globeAnchors.Length = {globeAnchors.Length}");
                foreach (var globeAnchor in globeAnchors)
                {
                    LogInfo($"{globeAnchor.gameObject.name} - active? {globeAnchor.gameObject.activeInHierarchy}");
                }

This yields a log like this:

[2025-01-09 18:28:02.139]-> [Cs]globeAnchors.Length = 23
[2025-01-09 18:28:02.140]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.142]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.143]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.145]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.146]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.148]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.149]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.151]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.153]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.154]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.156]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.159]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.161]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.163]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.164]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.167]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.169]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.171]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.173]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.174]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.175]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.176]-> [Cs]MapAttacher(Clone) - active? False
[2025-01-09 18:28:02.178]-> [Cs]FlockAnchor 1 - active? True

That is odd! Sync is called by a few other things besides CesiumGeoreference, namely OnTransformParentChanged, which could explain the issue - but the callstack seems to point to it being MoveOrigin itself calling Sync 338 times. If you put a breakpoint near the for loop in CesiumGeoreference, do you see 338 items in the _globeAnchors hash set? I wouldn’t expect duplicates, given that it’s a HashSet, but that would be the first place I’d check.

If you can get some sort of minimal example together to replicate this issue that you can send over, I’d love to take a closer look.

1 Like

OK, yeah that makes sense. Just enabled Show Tiles In Hierarchy.

So then if this is normal behavior, why the decline in performance? I’ll compare a few versions today and get back to you.

I should note that the way we’ve setup locomotion is always to keep the playspace stationary and to call georeference.SetOriginLongitudeLatitudeHeight once per frame while moving. This seemed to be more straightforward to setup than origin shifting, though I could see how origin shifting would be more performant if it doesn’t do these calculations every frame.

Is origin shifting the obvious way to go for performance, or would you expect this method to work fine? The time in the profile is exaggerated because of deep profiling, but it is yielding ~20 - 30fps at times without profiling so this is clearly an issue.

Oh yeah, good call! Got a bunch of these. So are there CesiumGlobeAnchors on each of the tiles?

Scene path:
[SCENE]/[MapService]/MapHolder/[CesiumMap](Clone)/CesiumGeoreference/Google Photorealistic 3D Tiles/https://tile.googleapis.com/v1/3dtiles/datasets/CgA/files/UlRPVEYubm9kZWRhdGEucGxhbmV0b2lkPWVhcnRoLG5vZGVfZGF0YV9lcG9jaD05NTUscGF0aD0yMTQyNDM0MTUxNzM1MzQyNzA1LGNhY2hlX3ZlcnNpb249NixhbGlnbm1lbnRfdmVyc2lvbj1ST0NLVFJFRV85OTJfR09PR0xFX0RBVFVNXzIwMjQxMDA4VDA3NTNaX2dlbmVyYXRlZF9hdF8yMDI1MDEwN1QxMzA3Wg.glb?session=CLTt-5K81snVSBDVgIa8Bg&key=AIzaSyBPE2U_VMHHmM9KpwhBIrd15e2WEgiYwhU/Mesh 0 Primitive 0

I made another development build with v1.8.0 and same behavior but
CesiumGlobeAnchor.Sync looks to be a bit more efficient. More calls but less time than latest version.

(I wanted to try a few versions by checking out cesium-unity in my Packages directory instead of using UPM but having trouble with the build.)