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; }