internal static void SetupIDs(NetworkIdentity identity)
        {
            var         wrapper = new IdentityWrapper(identity);
            PrefabStage stage;

            if (PrefabUtility.IsPartOfPrefabAsset(identity.gameObject))
            {
                wrapper.ClearSceneId();
                AssignAssetID(identity);
            }
            // Unity calls OnValidate for prefab and other scene objects based on that prefab
            //
            // are we modifying THIS prefab, or just a scene object based on the prefab?
            //   * GetCurrentPrefabStage = 'are we editing ANY prefab?'
            //   * GetPrefabStage(go) = 'are we editing THIS prefab?'
            else if ((stage = PrefabStageUtility.GetCurrentPrefabStage()) != null)
            {
                // nested if, we want to do nothing if we are not the prefab being edited
                if (PrefabStageUtility.GetPrefabStage(identity.gameObject) != null)
                {
                    wrapper.ClearSceneId();
                    AssignAssetID(identity, GetStagePath(stage));
                }
            }
            else if (SceneObjectWithPrefabParent(identity, out GameObject parent))
            {
                AssignSceneID(identity);
                AssignAssetID(identity, parent);
            }
            else
            {
                AssignSceneID(identity);
                wrapper.PrefabHash = 0;
            }
        }
        /// <summary>
        /// Ensures that a NetworkIdentity has a Random Unique ID
        /// </summary>
        /// <param name="identity"></param>
        /// <remarks>
        /// We use a random id here instead of index because the order of `FindObjectOfType` might change if something in the scene changes
        /// <para>
        /// Id must be assigned at edit time. This is to make sure they are the the same between builds
        /// </para>
        /// </remarks>
        static void AssignSceneID(NetworkIdentity identity)
        {
            // Only generate at editor time
            if (Application.isPlaying)
            {
                return;
            }

            var wrapper = new IdentityWrapper(identity);

            if (wrapper.SceneId == 0 || IsDuplicate(identity, wrapper.SceneId))
            {
                // clear in any case, because it might have been a duplicate
                wrapper.ClearSceneId();

                // Dont generate when building
                // this Will Cause a new Random ID for each build
                // we need to generate it as edit time
                if (BuildPipeline.isBuildingPlayer)
                {
                    throw new InvalidOperationException($"Scene {identity.gameObject.scene.path} needs to be opened and resaved before building, because the scene object {identity.name} has no valid sceneId yet.");
                }

                int randomId = GetRandomUInt();

                // only assign if not a duplicate of an existing scene id (small chance, but possible)
                if (!IsDuplicate(identity, randomId))
                {
                    wrapper.SceneId = randomId;
                }
            }

            // Add to dictionary so we can keep track of ID for duplicates
            sceneIds[wrapper.SceneId] = identity;
        }