Entity updating

if i make multiple transform updates per frame to the same gameobject (such as multiple position changes, or a position and rotation, etc), do the entities update multiple times per call as well or are they flagged to be updated at some later point?

They’re flagged as dirty when modified, and once per frame (after the late update), we transmit their changed state to their equivalents in RealityKit.

1 Like

i don’t suppose it is possible to hook into this update to see what it believes has changed?

Not at present; we use an internal API. If that’s something you’re interested in support for, you could submit it to the road map.

would checking Transform.hasChanged has been set when at the end of a frame and clearing it for the next frame effectively be the same? would i be right to assume there are no checks to see if the values have changed, just that the transform or its parts have been assigned to / modified? so for example setting an transform to identity on two separate frames would yield an update to an entity on both frames despite it not changing

No; if the local transform is set to the same value, then there should not be an update. That’s true for Transform.hasChanged as well as PolySpatial, so yes, you should be able to read/clear Transform.hasChanged to determine whether PolySpatial is transferring a transform. It sounds like the documentation is incorrect or out of date for this:

So setting, for instance, transform.position will always set hasChanged on the transform, regardless of there being any actual change.

It’s pretty easy to verify (in 2022.3 and Unity 6) that this isn’t the case; the following code prints “Transform changed.” twice (once for the initial transform, once for the change):

using UnityEngine;

class TestTransformsChanged : MonoBehaviour
{
    void Update()
    {
        if (transform.hasChanged)
        {
            transform.hasChanged = false;
            Debug.Log("Transform changed.");
        }
        transform.position = new Vector3(1, 2, 3);
        transform.localScale = new Vector3(1, 2, 3);
        transform.rotation = Quaternion.Euler(10f, 20f, 30f);
    }
}

Similarly, it doesn’t continue to send the transforms via PolySpatial.

1 Like

when does the synchronisation occur? you said after late update, but is that prior to Application.onBeforeRender? for example if i wanted to schedule a job and wait for completion at the last possible moment would i use that callback or a component with a lateupdate configured to update after all other scripts?

does this synchronisation include data being passed from the cpu to gpu such as mesh data being updated, or is that updated right away?

also is it possible to prevent an entity being created / updated for a gameobject? like if i were to mark it static, or a specific tag

I wouldn’t think Application.onBeforeRender is called at all. VisionOS apps using MR/PolySpatial operate in batch mode, so the typical rendering pipeline isn’t active. The synchronization happens immediately after LateUpdate, so that’s the latest point you can make changes that will be picked up.

Yes, it includes both changes to GameObjects/Components and to resources like meshes/textures/materials/etc.

There’s an Ignored Objects Layer Mask setting that lets you filter objects for synchronization based on layers, though note that A. you can’t change the layer at runtime and expect it to start/stop being replicated; the check happens when the object is created, and B. if an object is replicated, then all of its ancestors must also be replicated. Objects flagged as static are still replicated (because they might have non-static children).

1 Like

I had checked before I originally posted and saw that onBeforeRender was getting called, but none of the other render pipeline callbacks do which is what i expected.
I thought whilst it is called by the name it is that it is perhaps more a post update for any last minute changes would would happen before it goes on to render in the usual order of events.
i’ll stick with a late update on a component ordered to be last

just to double check, given that children could be reparented, do all the children of an ignored layer mask gameobject need to be on that mask as well or does it get applied to them automatically when their parent is set to it?

EDIT: Sorry i misread ancestors as descedants, you already answered it

Yes, all the children need to be on masked-out layers as well. The masked-outness isn’t inherited.

1 Like