public override void OnInspectorGUI() { this.m_Target = (PunSceneSettings)this.target; // error checking _duplicateScenesDefinition = m_Target.MinViewIdPerScene.GroupBy(x => x.sceneName) .Where(g => g.Count() > 1) .Select(y => y.Key) .ToList(); _duplicateViewIdDefinition = m_Target.MinViewIdPerScene.GroupBy(x => x.minViewId) .Where(g => g.Count() > 1) .Select(y => y.Key) .ToList(); DrawSceneSettingsList(); foreach (string dup in _duplicateScenesDefinition) { EditorGUILayout.LabelField("Found duplicates for scene", dup); } foreach (SceneSetting sceneSettings in m_Target.MinViewIdPerScene) { if (_duplicateViewIdDefinition.Contains(sceneSettings.minViewId)) { GUILayout.Label("Found view Id duplicates '" + sceneSettings.minViewId + "' for scene: " + sceneSettings.sceneName); } if (sceneSettings.minViewId > PhotonNetwork.MAX_VIEW_IDS) { GUILayout.Label(sceneSettings.sceneName + " view Id can not exceed the max view Id " + PhotonNetwork.MAX_VIEW_IDS); } if (sceneSettings.minViewId < 1) { GUILayout.Label(sceneSettings.sceneName + " view Id can not be less than 1"); } if (sceneSettings.sceneAsset == null && !string.IsNullOrEmpty(sceneSettings.sceneName)) { GUILayout.Label("'" + sceneSettings.sceneName + "' scene is missing in the project"); } } _firstTime = false; }
public static int MinViewIdForScene(string scene) { if (string.IsNullOrEmpty(scene)) { return(0); } PunSceneSettings pss = Instance; if (pss == null) { Debug.LogError("pss cant be null"); return(0); } foreach (SceneSetting setting in pss.MinViewIdPerScene) { if (setting.sceneName.Equals(scene)) { return(setting.minViewId); } } return(0); }
// called in editor, opens wizard for initial setup, keeps scene PhotonViews up to date and closes connections when compiling (to avoid issues) private static void OnProjectChanged() { PunSceneSettings.SanitizeSettings(); if (PhotonNetwork.PhotonServerSettings == null) { PhotonNetwork.CreateSettings(); if (PhotonNetwork.PhotonServerSettings == null) { Debug.LogError("CreateSettings() failed to create PhotonServerSettings."); return; } } // serverSetting is null when the file gets deleted. otherwise, the wizard should only run once and only if hosting option is not (yet) set if (!PhotonNetwork.PhotonServerSettings.DisableAutoOpenWizard) { ShowRegistrationWizard(); PhotonNetwork.PhotonServerSettings.DisableAutoOpenWizard = true; PhotonEditor.SaveSettings(); } }
private static int MinSceneViewId(PhotonView view) { int result = PunSceneSettings.MinViewIdForScene(view.gameObject.scene.name); return(result); }
// this method corrects the IDs for photonviews in the scene and in prefabs // make sure prefabs always use viewID 0 // make sure instances never use a owner // this is a editor class that should only run if not playing internal static void HierarchyChange() { if (Application.isPlaying) { //Debug.Log("HierarchyChange ignored, while running."); CheckSceneForStuckHandlers = true; // done once AFTER play mode. return; } if (CheckSceneForStuckHandlers) { CheckSceneForStuckHandlers = false; PhotonNetwork.InternalCleanPhotonMonoFromSceneIfStuck(); } HashSet <PhotonView> pvInstances = new HashSet <PhotonView>(); HashSet <int> usedInstanceViewNumbers = new HashSet <int>(); bool fixedSomeId = false; //// the following code would be an option if we only checked scene objects (but we can check all PVs) //PhotonView[] pvObjects = GameObject.FindSceneObjectsOfType(typeof(PhotonView)) as PhotonView[]; //Debug.Log("HierarchyChange. PV Count: " + pvObjects.Length); string levelName = SceneManagerHelper.ActiveSceneName; #if UNITY_EDITOR levelName = SceneManagerHelper.EditorActiveSceneName; #endif int minViewIdInThisScene = PunSceneSettings.MinViewIdForScene(levelName); //Debug.Log("Level '" + Application.loadedLevelName + "' has a minimum ViewId of: " + minViewIdInThisScene); PhotonView[] pvObjects = Resources.FindObjectsOfTypeAll(typeof(PhotonView)) as PhotonView[]; foreach (PhotonView view in pvObjects) { // first pass: fix prefabs to viewID 0 if they got a view number assigned (cause they should not have one!) if (PhotonEditorUtils.IsPrefab(view.gameObject)) { if (view.ViewID != 0 || view.prefixField != -1) { #if !UNITY_2018_3_OR_NEWER Debug.LogWarning("PhotonView on persistent object being fixed (id and prefix must be 0). Was: " + view); #endif view.ViewID = 0; view.prefixField = -1; EditorUtility.SetDirty(view); // even in Unity 5.3+ it's OK to SetDirty() for non-scene objects. fixedSomeId = true; } } else { // keep all scene-instanced PVs for later re-check pvInstances.Add(view); } } Dictionary <GameObject, int> idPerObject = new Dictionary <GameObject, int>(); // second pass: check all used-in-scene viewIDs for duplicate viewIDs (only checking anything non-prefab) // scene-PVs must have user == 0 (scene/room) and a subId != 0 foreach (PhotonView view in pvInstances) { if (view.OwnerActorNr > 0) { Debug.Log("Re-Setting Owner ID of: " + view); } view.Prefix = -1; // TODO: prefix could be settable via inspector per scene?! if (view.ViewID != 0) { if (view.ViewID < minViewIdInThisScene || usedInstanceViewNumbers.Contains(view.ViewID)) { view.ViewID = 0; // avoid duplicates and negative values by assigning 0 as (temporary) number to be fixed in next pass } else { usedInstanceViewNumbers.Add(view.ViewID); // builds a list of currently used viewIDs int instId = 0; if (idPerObject.TryGetValue(view.gameObject, out instId)) { view.InstantiationId = instId; } else { view.InstantiationId = view.ViewID; idPerObject[view.gameObject] = view.InstantiationId; } } } } // third pass: anything that's now 0 must get a new (not yet used) ID (starting at 0) int lastUsedId = (minViewIdInThisScene > 0) ? minViewIdInThisScene - 1 : 0; foreach (PhotonView view in pvInstances) { if (view.ViewID == 0) { Undo.RecordObject(view, "Automatic viewID change for: " + view.gameObject.name); // Debug.LogWarning("setting scene ID: " + view.gameObject.name + " ID: " + view.subId.ID + " scene ID: " + view.GetSceneID() + " IsPersistent: " + EditorUtility.IsPersistent(view.gameObject) + " IsSceneViewIDFree: " + IsSceneViewIDFree(view.subId.ID, view)); int nextViewId = PhotonViewHandler.GetID(lastUsedId, usedInstanceViewNumbers); view.ViewID = nextViewId; int instId = 0; if (idPerObject.TryGetValue(view.gameObject, out instId)) { view.InstantiationId = instId; } else { view.InstantiationId = view.ViewID; idPerObject[view.gameObject] = nextViewId; } lastUsedId = nextViewId; fixedSomeId = true; } } if (fixedSomeId) { //Debug.LogWarning("Some subId was adjusted."); // this log is only interesting for Exit Games } }