public bool GetSceneMessage(out LiveLinkSceneMsg msg)
        {
            var loadedScenes     = _LoadedScenesQuery.ToComponentDataArray <SceneReference>(Allocator.TempJob);
            var removedScenes    = _UnloadedScenesQuery.ToComponentDataArray <LiveLinkPatcher.LiveLinkedSceneState>(Allocator.TempJob);
            var newRemovedScenes = SubtractArrays(removedScenes, m_PreviousRemovedScenes);

            var noNewUnloads  = newRemovedScenes.Length == 0;
            var sameLoadState = loadedScenes.ArraysEqual(m_PreviousScenes.AsArray());

            if (noNewUnloads && sameLoadState)
            {
                loadedScenes.Dispose();
                removedScenes.Dispose();
                newRemovedScenes.Dispose();
                msg = default;
                return(false);
            }

            msg.LoadedScenes  = loadedScenes.Reinterpret <Hash128>();
            msg.RemovedScenes = newRemovedScenes.Reinterpret <Hash128>();

            m_PreviousScenes.Clear();
            m_PreviousRemovedScenes.Clear();
            m_PreviousScenes.AddRange(loadedScenes);
            m_PreviousRemovedScenes.AddRange(removedScenes);
            removedScenes.Dispose();

            return(true);
        }
        unsafe public static LiveLinkSceneMsg FromMsg(byte[] buffer, Allocator allocator)
        {
            fixed(byte *ptr = buffer)
            {
                var reader           = new UnsafeAppendBuffer.Reader(ptr, buffer.Length);
                LiveLinkSceneMsg msg = default;

                msg.Deserialize(ref reader, allocator);
                return(msg);
            }
        }