// ---------------------------------------------------------------------------- // // PhotonNetwork Framework for Unity - Copyright (C) 2019 Exit Games GmbH // // // Custom inspector for the PunSceneSettings component. // // developer@exitgames.com // ---------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEngine; namespace Photon.Pun { [CustomEditor(typeof(PunSceneSettings))] internal class PunSceneSettingsInspector : Editor { private PunSceneSettings m_Target; private bool isOpen; private List _duplicateScenesDefinition; private List _duplicateViewIdDefinition; private SerializedProperty listProperty; private SerializedProperty _sceneSettings_i; private SerializedProperty sceneNameProperty; private SerializedProperty sceneAssetProperty; private SerializedProperty minViewIdProperty; private bool _firstTime; 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; } private void OnEnable() { _firstTime = true; } private void DrawSceneSettingsList() { GUILayout.Space(5); // check for changes ( from undo for example) this.serializedObject.Update(); listProperty = this.serializedObject.FindProperty("MinViewIdPerScene"); if (listProperty == null) { return; } float containerElementHeight = 44; float containerHeight = listProperty.arraySize * containerElementHeight; isOpen = PhotonGUI.ContainerHeaderFoldout("Scene Settings (" + listProperty.arraySize + ")", this.serializedObject.FindProperty("SceneSettingsListFoldoutOpen").boolValue); this.serializedObject.FindProperty("SceneSettingsListFoldoutOpen").boolValue = isOpen; if (isOpen == false) { containerHeight = 0; } Rect containerRect = PhotonGUI.ContainerBody(containerHeight); if (isOpen == true) { for (int i = 0; i < listProperty.arraySize; ++i) { Rect elementRect = new Rect(containerRect.xMin, containerRect.yMin + containerElementHeight * i, containerRect.width, containerElementHeight); { Rect texturePosition = new Rect(elementRect.xMin + 6, elementRect.yMin + elementRect.height / 2f - 1, 9, 5); ReorderableListResources.DrawTexture(texturePosition, ReorderableListResources.texGrabHandle); Rect propertyPosition = new Rect(elementRect.xMin + 20, elementRect.yMin + 3, elementRect.width - 45, 16); _sceneSettings_i = listProperty.GetArrayElementAtIndex(i); sceneNameProperty = _sceneSettings_i.FindPropertyRelative("sceneName"); sceneAssetProperty = _sceneSettings_i.FindPropertyRelative("sceneAsset"); minViewIdProperty = _sceneSettings_i.FindPropertyRelative("minViewId"); string _sceneName = sceneNameProperty.stringValue; SceneAsset _sceneAsset = m_Target.MinViewIdPerScene[i].sceneAsset; // check if we need to find the scene asset based on the scene name. This is for backward compatibility or when the scene asset was deleted if (_firstTime) { if (_sceneAsset == null && !string.IsNullOrEmpty(_sceneName)) { string[] guids = AssetDatabase.FindAssets(_sceneName + " t:SceneAsset"); foreach (string guid in guids) { string path = AssetDatabase.GUIDToAssetPath(guid); if (Path.GetFileNameWithoutExtension(path) == _sceneName) { sceneAssetProperty.objectReferenceValue = AssetDatabase.LoadAssetAtPath( AssetDatabase.GUIDToAssetPath(guid)); break; } } } } bool _missingSceneAsset = _sceneAsset == null && !string.IsNullOrEmpty(_sceneName); // if we don't have a scene asset for the serialized scene named, we show an error. if (_missingSceneAsset || (sceneNameProperty!=null && _duplicateScenesDefinition!=null && _duplicateScenesDefinition.Contains(sceneNameProperty.stringValue)) ) { GUI.color = Color.red; } EditorGUI.BeginChangeCheck(); string _label = _missingSceneAsset ? "Scene Asset: Missing '" + _sceneName + "'" : "Scene Asset"; EditorGUI.PropertyField(propertyPosition,sceneAssetProperty, new GUIContent(_label)); if (EditorGUI.EndChangeCheck()) { _sceneAsset = sceneAssetProperty.objectReferenceValue as SceneAsset; if (_sceneAsset == null && !string.IsNullOrEmpty(sceneNameProperty.stringValue)) { sceneNameProperty.stringValue = null; } else if (sceneNameProperty.stringValue != _sceneAsset.name) { sceneNameProperty.stringValue = _sceneAsset.name; } } // EditorGUI.PropertyField(propertyPosition, sceneNameProperty, // new GUIContent("Scene Name")); GUI.color = Color.white; if ( minViewIdProperty.intValue<1 || minViewIdProperty.intValue> PhotonNetwork.MAX_VIEW_IDS) { GUI.color = Color.red; } Rect secondPropertyPosition = new Rect(elementRect.xMin + 20, elementRect.yMin + containerElementHeight/2, elementRect.width - 45, 16); EditorGUI.PropertyField(secondPropertyPosition, _sceneSettings_i.FindPropertyRelative("minViewId"), new GUIContent("Minimum View ID")); GUI.color = Color.white; //Debug.Log( listProperty.GetArrayElementAtIndex( i ).objectReferenceValue.GetType() ); //Rect statsPosition = new Rect( propertyPosition.xMax + 7, propertyPosition.yMin, statsIcon.width, statsIcon.height ); //ReorderableListResources.DrawTexture( statsPosition, statsIcon ); Rect removeButtonRect = new Rect( elementRect.xMax - PhotonGUI.DefaultRemoveButtonStyle.fixedWidth, elementRect.yMin + 2, PhotonGUI.DefaultRemoveButtonStyle.fixedWidth, PhotonGUI.DefaultRemoveButtonStyle.fixedHeight); if (GUI.Button(removeButtonRect, new GUIContent(ReorderableListResources.texRemoveButton), PhotonGUI.DefaultRemoveButtonStyle)) { listProperty.DeleteArrayElementAtIndex(i); Undo.RecordObject(this.m_Target, "Removed SceneSettings Entry"); } if (i < listProperty.arraySize - 1) { texturePosition = new Rect(elementRect.xMin + 2, elementRect.yMax, elementRect.width - 4, 1); PhotonGUI.DrawSplitter(texturePosition); } } } } if (PhotonGUI.AddButton()) { this.listProperty.InsertArrayElementAtIndex(Mathf.Max(0, listProperty.arraySize - 1)); _sceneSettings_i = this.listProperty.GetArrayElementAtIndex(listProperty.arraySize - 1); sceneNameProperty = _sceneSettings_i.FindPropertyRelative("sceneName"); sceneAssetProperty = _sceneSettings_i.FindPropertyRelative("sceneAsset"); minViewIdProperty = _sceneSettings_i.FindPropertyRelative("minViewId"); sceneAssetProperty.objectReferenceValue = null; sceneNameProperty.stringValue = ""; minViewIdProperty.intValue = 1; Undo.RecordObject(this.m_Target, "Added SceneSettings Entry"); } this.serializedObject.ApplyModifiedProperties(); } } }