public static void SetupButtons(Type type, object value, ReferenceChain refChain) { if (TypeUtil.IsTextureType(type) && value != null) { var texture = (Texture)value; if (GUILayout.Button("Preview")) { TextureViewer.CreateTextureViewer(refChain, texture); } if (GUILayout.Button("Dump .png")) { TextureUtil.DumpTextureToPNG(texture); } } else if (TypeUtil.IsMeshType(type) && value != null) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(null, (Mesh)value, null); } if (((Mesh)value).isReadable) { if (GUILayout.Button("Dump .obj")) { var outPath = refChain.ToString().Replace(' ', '_'); DumpUtil.DumpMeshAndTextures(outPath, value as Mesh); } } } if (GUILayout.Button("Copy")) { _buffer = value; } }
internal static void OnSceneTreeMessage(ReferenceChain refChain, string message) { GUILayout.BeginHorizontal(); GUILayout.Space(ModTools.Instance.config.sceneExplorerTreeIdentSpacing * refChain.Ident); GUILayout.Label(message); GUILayout.EndHorizontal(); }
public void Show(ReferenceChain refChain, bool hideUnrelatedSceneRoots = true, string updatedSearchString = "", bool addChainToHistory = true) { if (refChain == null) { Logger.Error("SceneExplorer: Show(): Null refChain"); return; } if (refChain.Length == 0) { Logger.Error("SceneExplorer: Show(): Invalid refChain, expected Length >= 0"); return; } if (refChain.FirstItemType != ReferenceChain.ReferenceType.GameObject) { Logger.Error($"SceneExplorer: Show(): invalid chain type for element [0] - expected {ReferenceChain.ReferenceType.GameObject}, got {refChain.FirstItemType}"); return; } EnqueueShowRefChainRequest(new List <ReferenceChain> { refChain }, hideUnrelatedSceneRoots, updatedSearchString, addChainToHistory); Visible = true; }
public void RemoveWatch(ReferenceChain refChain) { if (watches.Contains(refChain)) { watches.Remove(refChain); } }
public bool IsSameChain(ReferenceChain other) { if (other == null) { throw new ArgumentNullException(nameof(other)); } if (Length != other.Length) { return(false); } if (ReferenceEquals(this, other)) { return(true); } for (var i = 0; i < Length; ++i) { if (chainTypes[i] != other.chainTypes[i]) { return(false); } if (chainObjects[i] != other.chainObjects[i]) { return(false); } } return(true); }
private static void SetupSegmentButtons(ReferenceChain refChain, NetInfo.Segment segmentInfo) { try { Debug.Log("SetupSegmentButtons() called"); if (segmentInfo.m_mesh != null && segmentInfo.m_mesh.isReadable && GUILayout.Button("Dump")) { var outPath = refChain.ToString().Replace(' ', '_'); DumpUtil.DumpMeshAndTextures( outPath, segmentInfo.m_mesh, segmentInfo.m_material); DumpUtil.DumpMeshAndTextures( outPath + "_lod", segmentInfo.m_lodMesh, segmentInfo.m_lodMaterial); } SetupMeshPreviewButtons(name: null, segmentInfo.m_mesh, segmentInfo.m_material, segmentInfo.m_lodMesh, segmentInfo.m_lodMaterial); Debug.Log("SetupSegmentButtons() successful"); } catch (Exception ex) { Debug.LogException(ex); } }
public static void SetUpCollectionNavigation( string collectionLabel, SceneExplorerState state, ReferenceChain refChain, ReferenceChain oldRefChain, int collectionSize, out uint arrayStart, out uint arrayEnd) { GUILayout.BeginHorizontal(); SceneExplorerCommon.InsertIndent(refChain.Indentation); GUILayout.Label($"{collectionLabel} size: {collectionSize}"); if (!state.SelectedArrayStartIndices.TryGetValue(refChain.UniqueId, out arrayStart)) { state.SelectedArrayStartIndices.Add(refChain.UniqueId, 0); } if (!state.SelectedArrayEndIndices.TryGetValue(refChain.UniqueId, out arrayEnd)) { state.SelectedArrayEndIndices.Add(refChain.UniqueId, 32); arrayEnd = 32; } arrayStart = GUIControls.NumericValueField($"{oldRefChain}.arrayStart", "Start index", arrayStart); arrayEnd = GUIControls.NumericValueField($"{oldRefChain}.arrayEnd", "End index", arrayEnd); GUILayout.Label("(32 items max)"); var pageSize = (uint)Mathf.Clamp(arrayEnd - arrayStart + 1, 1, Mathf.Min(32, collectionSize - arrayStart, arrayEnd + 1)); if (GUILayout.Button("◄", GUILayout.ExpandWidth(false))) { arrayStart -= pageSize; arrayEnd -= pageSize; } if (GUILayout.Button("►", GUILayout.ExpandWidth(false))) { arrayStart += pageSize; arrayEnd += pageSize; } arrayStart = (uint)Mathf.Clamp(arrayStart, 0, collectionSize - pageSize); arrayEnd = (uint)Mathf.Max(0, Mathf.Clamp(arrayEnd, pageSize - 1, collectionSize - 1)); if (arrayStart > arrayEnd) { arrayEnd = arrayStart; } if (arrayEnd - arrayStart > 32) { arrayEnd = arrayStart + 32; arrayEnd = (uint)Mathf.Max(0, Mathf.Clamp(arrayEnd, 32, collectionSize - 1)); } state.SelectedArrayStartIndices[refChain.UniqueId] = arrayStart; state.SelectedArrayEndIndices[refChain.UniqueId] = arrayEnd; GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); }
internal static void OnSceneTreeMessage(ReferenceChain refChain, string message) { GUILayout.BeginHorizontal(); InsertIndent(refChain.Indentation); GUILayout.Label(message); GUILayout.EndHorizontal(); }
internal static bool SceneTreeCheckDepth(ReferenceChain refChain) { if (refChain.CheckDepth()) { OnSceneTreeMessage(refChain, "Hierarchy too deep, sorry :("); return(false); } return(true); }
private static void SetupMeshButtons(ReferenceChain refChain, Mesh mesh) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(null, mesh, null); } if (mesh.isReadable && GUILayout.Button("Dump mesh")) { var outPath = refChain.ToString().Replace(' ', '_'); DumpUtil.DumpMeshAndTextures(outPath, mesh); } }
private static void OnSceneTreeReflectUnityEngineVector3(ReferenceChain refChain, string name, ref Vector3 vec) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } vec = GUIControls.CustomValueField( refChain.UniqueId, name, GUIControls.PresentVector3, vec, MainWindow.Instance.Config.TreeIdentSpacing * refChain.Indentation); }
public static void SetupJumpButton(object value, ReferenceChain refChain) { if (!GUILayout.Button(">", GUILayout.ExpandWidth(false))) { return; } var sceneExplorer = Object.FindObjectOfType <SceneExplorer>(); if (sceneExplorer == null) { return; } sceneExplorer.Show(ReferenceChainBuilder.Optimize(refChain, value)); }
public ReferenceChain Clone() { var clone = new ReferenceChain { Length = Length }; for (var i = 0; i < Length; i++) { clone.chainObjects[i] = chainObjects[i]; clone.chainTypes[i] = chainTypes[i]; } clone.IndentationOffset = IndentationOffset; return(clone); }
public ReferenceChain Reverse() { var copy = new ReferenceChain { Length = Length, IndentationOffset = IndentationOffset, }; for (var i = 0; i < Length; i++) { copy.chainObjects[Length - i - 1] = chainObjects[i]; copy.chainTypes[Length - i - 1] = chainTypes[i]; } return(copy); }
public static void OnSceneTreeComponent(SceneExplorerState state, ReferenceChain refChain, Component component) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } if (component == null) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "null"); return; } GUILayout.BeginHorizontal(); GUILayout.Space(ModTools.Instance.config.sceneExplorerTreeIdentSpacing * refChain.Ident); if (Util.ComponentIsEnabled(component)) { GUI.contentColor = ModTools.Instance.config.enabledComponentColor; } else { GUI.contentColor = ModTools.Instance.config.disabledComponentColor; } if (state.currentRefChain == null || !state.currentRefChain.Equals(refChain.Add(component))) { if (GUILayout.Button(">", GUILayout.ExpandWidth(false))) { state.currentRefChain = refChain.Add(component); state.currentRefChain.IdentOffset = -(refChain.Length + 1); } } else { GUI.contentColor = ModTools.Instance.config.selectedComponentColor; if (GUILayout.Button("<", GUILayout.ExpandWidth(false))) { state.currentRefChain = null; } } GUILayout.Label(component.GetType().ToString()); GUI.contentColor = Color.white; GUILayout.EndHorizontal(); }
private Type GetWatchType(ReferenceChain watch) { switch (watch.LastItem) { case FieldInfo fieldInfo: return(fieldInfo.FieldType); case PropertyInfo fieldInfo: return(fieldInfo.PropertyType); case uint _: return(GetWatchType(watch.SubChain(watch.Length - 1)).GetElementType()); default: return(watch.LastItem.GetType()); } }
private static void SetupNodeButtons(ReferenceChain refChain, NetInfo.Node nodeInfo) { if (nodeInfo.m_mesh != null && nodeInfo.m_mesh.isReadable && GUILayout.Button("Dump")) { var outPath = refChain.ToString().Replace(' ', '_'); DumpUtil.DumpMeshAndTextures( outPath, nodeInfo.m_mesh, nodeInfo.m_material); DumpUtil.DumpMeshAndTextures( outPath + "_lod", nodeInfo.m_lodMesh, nodeInfo.m_lodMaterial); } SetupMeshPreviewButtons(name: null, nodeInfo.m_mesh, nodeInfo.m_material, nodeInfo.m_lodMesh, nodeInfo.m_lodMaterial); }
private static void OnSceneTreeReflectUnityEngineVector3 <T>(ReferenceChain refChain, T obj, string name, ref UnityEngine.Vector3 vec) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } GUIControls.Vector3Field(refChain.ToString(), name, ref vec, ModTools.Instance.config.sceneExplorerTreeIdentSpacing * refChain.Ident, () => { try { ModTools.Instance.watches.AddWatch(refChain); } catch (Exception ex) { Log.Error("Exception in ModTools:OnSceneTreeReflectUnityEngineVector3 - " + ex.Message); } }); }
public static void OnSceneTreeComponent(SceneExplorerState state, ReferenceChain refChain, Component component) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } if (component == null) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "null"); return; } GUILayout.BeginHorizontal(); SceneExplorerCommon.InsertIndent(refChain.Indentation); GUI.contentColor = GameObjectUtil.ComponentIsEnabled(component) ? MainWindow.Instance.Config.EnabledComponentColor : MainWindow.Instance.Config.DisabledComponentColor; if (state.CurrentRefChain?.IsSameChain(refChain) != true) { if (GUILayout.Button(">", GUILayout.ExpandWidth(false))) { var sceneExplorer = Object.FindObjectOfType <SceneExplorer>(); sceneExplorer.Show(refChain, false); } } else { GUI.contentColor = MainWindow.Instance.Config.SelectedComponentColor; state.PreventCircularReferences.Add(component.gameObject); if (GUILayout.Button("<", GUILayout.ExpandWidth(false))) { state.CurrentRefChain = null; } } GUILayout.Label(component.GetType().ToString()); GUI.contentColor = Color.white; GUILayout.EndHorizontal(); }
public static void OnSceneTreeReflectUnityEngineTransform(ReferenceChain refChain, Transform transform) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } if (transform == null) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "null"); return; } var position = transform.position; OnSceneTreeReflectUnityEngineVector3(refChain.Add("position"), "position", ref position); transform.position = position; var localPosition = transform.localPosition; OnSceneTreeReflectUnityEngineVector3(refChain.Add("localPosition"), "localPosition", ref localPosition); transform.localPosition = localPosition; var localEulerAngles = transform.localEulerAngles; OnSceneTreeReflectUnityEngineVector3(refChain.Add("localEulerAngles"), "localEulerAngles", ref localEulerAngles); transform.localEulerAngles = localEulerAngles; var rotation = transform.rotation; OnSceneTreeReflectUnityEngineQuaternion(refChain.Add("rotation"), "rotation", ref rotation); transform.rotation = rotation; var localRotation = transform.localRotation; OnSceneTreeReflectUnityEngineQuaternion(refChain.Add("localRotation"), "localRotation", ref localRotation); transform.localRotation = localRotation; var localScale = transform.localScale; OnSceneTreeReflectUnityEngineVector3(refChain.Add("localScale"), "localScale", ref localScale); transform.localScale = localScale; }
public static void ExpanderControls(SceneExplorerState state, ReferenceChain refChain, Type type, object o = null) { GUI.contentColor = Color.white; if (TypeUtil.IsSpecialType(type) || o != null && TypeUtil.IsEnumerable(o)) { return; } if (state.ExpandedObjects.Contains(refChain.UniqueId)) { if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) { state.ExpandedObjects.Remove(refChain.UniqueId); } } else if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) { state.ExpandedObjects.Add(refChain.UniqueId); } }
public static void OnSceneTreeReflectICollection(SceneExplorerState state, ReferenceChain refChain, System.Object myProperty) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } var collection = myProperty as ICollection; if (collection == null) { return; } var oldRefChain = refChain; var collectionSize = collection.Count; if (collectionSize == 0) { GUILayout.BeginHorizontal(); GUI.contentColor = Color.yellow; GUILayout.Label("Collection is empty!"); GUI.contentColor = Color.white; GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); return; } int arrayStart; int arrayEnd; GUICollectionNavigation.SetUpCollectionNavigation("Collection", state, refChain, oldRefChain, collectionSize, out arrayStart, out arrayEnd); int count = 0; foreach (var value in collection) { if (count < arrayStart) { count++; continue; } refChain = oldRefChain.Add(count); var type = value.GetType(); GUILayout.BeginHorizontal(); GUILayout.Space(ModTools.Instance.config.sceneExplorerTreeIdentSpacing * refChain.Ident); GUIExpander.ExpanderControls(state, refChain, type); GUI.contentColor = ModTools.Instance.config.typeColor; GUILayout.Label(type.ToString() + " "); GUI.contentColor = ModTools.Instance.config.nameColor; GUILayout.Label($"{oldRefChain.LastItemName}.[{count}]"); GUI.contentColor = Color.white; GUILayout.Label(" = "); GUI.contentColor = ModTools.Instance.config.valueColor; GUILayout.Label(value == null ? "null" : value.ToString()); GUI.contentColor = Color.white; GUILayout.FlexibleSpace(); GUIButtons.SetupButtons(type, value, refChain); GUILayout.EndHorizontal(); if (!TypeUtil.IsSpecialType(type) && state.expandedObjects.ContainsKey(refChain)) { if (value is GameObject) { var go = value as GameObject; foreach (var component in go.GetComponents <Component>()) { GUIComponent.OnSceneTreeComponent(state, refChain, component); } } else if (value is Transform) { GUITransform.OnSceneTreeReflectUnityEngineTransform(refChain, (Transform)value); } else { GUIReflect.OnSceneTreeReflect(state, refChain, value); } } count++; if (count > arrayEnd) { break; } } }
public static void OnSceneTreeReflectICollection(SceneExplorerState state, ReferenceChain refChain, object myProperty, TypeUtil.SmartType elementSmartType = TypeUtil.SmartType.Undefined) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } if (!(myProperty is ICollection collection)) { return; } var oldRefChain = refChain; var collectionSize = collection.Count; if (collectionSize == 0) { GUILayout.BeginHorizontal(); GUI.contentColor = Color.yellow; GUILayout.Label("Collection is empty!"); GUI.contentColor = Color.white; GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); return; } var collectionItemType = collection.GetType().GetElementType(); var flagsField = collectionItemType?.GetField("m_flags"); var flagIsEnum = flagsField?.FieldType.IsEnum == true && Type.GetTypeCode(flagsField.FieldType) == TypeCode.Int32; GUICollectionNavigation.SetUpCollectionNavigation("Collection", state, refChain, oldRefChain, collectionSize, out var arrayStart, out var arrayEnd); uint count = 0; foreach (var value in collection) { if (count < arrayStart) { count++; continue; } refChain = oldRefChain.Add(count); GUILayout.BeginHorizontal(GUIWindow.HighlightStyle); SceneExplorerCommon.InsertIndent(refChain.Indentation); var isNullOrEmpty = value == null || flagIsEnum && Convert.ToInt32(flagsField.GetValue(value)) == 0; var type = value?.GetType() ?? collectionItemType; if (type != null) { if (!isNullOrEmpty) { GUIExpander.ExpanderControls(state, refChain, type); } GUI.contentColor = MainWindow.Instance.Config.TypeColor; GUILayout.Label(type.ToString() + " "); } GUI.contentColor = MainWindow.Instance.Config.NameColor; GUILayout.Label($"{oldRefChain.LastItemName}.[{count}]"); GUI.contentColor = Color.white; GUILayout.Label(" = "); GUI.contentColor = MainWindow.Instance.Config.ValueColor; GUILayout.Label(value == null ? "null" : isNullOrEmpty ? "empty" : value.ToString()); GUI.contentColor = Color.white; GUILayout.FlexibleSpace(); if (!isNullOrEmpty) { GUIButtons.SetupCommonButtons(refChain, value, count, elementSmartType); } if (value != null) { GUIButtons.SetupJumpButton(value, refChain); } GUILayout.EndHorizontal(); if (!isNullOrEmpty && !TypeUtil.IsSpecialType(type) && state.ExpandedObjects.Contains(refChain.UniqueId)) { GUIReflect.OnSceneTreeReflect(state, refChain, value, false); } count++; if (count > arrayEnd) { break; } } }
public static void OnSceneTreeReflectProperty(SceneExplorerState state, ReferenceChain refChain, System.Object obj, PropertyInfo property) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } if (obj == null || property == null) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "null"); return; } var hash = refChain.GetHashCode().ToString(); GUILayout.BeginHorizontal(); GUILayout.Space(ModTools.Instance.config.sceneExplorerTreeIdentSpacing * refChain.Ident); bool propertyWasEvaluated = false; object value = null; Exception exceptionOnGetting = null; if (property.CanRead && ModTools.Instance.config.sceneExplorerEvaluatePropertiesAutomatically || state.evaluatedProperties.ContainsKey(refChain)) { try { value = property.GetValue(obj, null); propertyWasEvaluated = true; } catch (Exception e) { exceptionOnGetting = e; } if (value != null && exceptionOnGetting == null) { GUIExpander.ExpanderControls(state, refChain, property.PropertyType, obj); } } GUI.contentColor = Color.white; if (!property.CanWrite) { GUI.enabled = false; } if (ModTools.Instance.config.sceneExplorerShowModifiers) { GUI.contentColor = ModTools.Instance.config.memberTypeColor; GUILayout.Label("property "); if (!property.CanWrite) { GUI.contentColor = ModTools.Instance.config.keywordColor; GUILayout.Label("const "); } } GUI.contentColor = ModTools.Instance.config.typeColor; GUILayout.Label(property.PropertyType.ToString() + " "); GUI.contentColor = ModTools.Instance.config.nameColor; GUILayout.Label(property.Name); GUI.contentColor = Color.white; GUILayout.Label(" = "); GUI.contentColor = ModTools.Instance.config.valueColor; if (!ModTools.Instance.config.sceneExplorerEvaluatePropertiesAutomatically && !state.evaluatedProperties.ContainsKey(refChain)) { GUI.enabled = true; if (GUILayout.Button("Evaluate")) { state.evaluatedProperties.Add(refChain, true); } } else { if (!propertyWasEvaluated && property.CanRead) { try { value = property.GetValue(obj, null); propertyWasEvaluated = true; } catch (Exception e) { exceptionOnGetting = e; } } if (exceptionOnGetting != null) { GUI.contentColor = Color.red; GUILayout.Label("Exception happened when getting property value"); GUI.contentColor = Color.white; GUI.enabled = true; GUIStackTrace.StackTraceButton(new StackTrace(exceptionOnGetting, true)); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); return; } if (value == null || !TypeUtil.IsSpecialType(property.PropertyType)) { if (property.CanRead) { GUILayout.Label(value == null ? "null" : value.ToString()); } else { GUILayout.Label("(no get method)"); } GUI.contentColor = Color.white; } else { try { var newValue = GUIControls.EditorValueField(refChain, hash, property.PropertyType, value); if (newValue != value) { property.SetValue(obj, newValue, null); } } catch (Exception) { if (property.CanRead) { GUILayout.Label(value == null ? "null" : value.ToString()); } else { GUILayout.Label("(no get method)"); } GUI.contentColor = Color.white; } } } GUI.enabled = true; GUI.contentColor = Color.white; GUILayout.FlexibleSpace(); if (GUILayout.Button("Watch")) { ModTools.Instance.watches.AddWatch(refChain); } GUIButtons.SetupButtons(property.PropertyType, value, refChain); object paste = null; var doPaste = property.CanWrite; if (doPaste) { doPaste = GUIButtons.SetupPasteButon(property.PropertyType, out paste); } GUILayout.EndHorizontal(); if (value != null && state.expandedObjects.ContainsKey(refChain)) { if (value is GameObject) { var go = value as GameObject; foreach (var component in go.GetComponents <Component>()) { GUIComponent.OnSceneTreeComponent(state, refChain, component); } } else if (value is Transform) { GUITransform.OnSceneTreeReflectUnityEngineTransform(refChain, (Transform)value); } else { GUIReflect.OnSceneTreeReflect(state, refChain, value); } } if (doPaste) { try { property.SetValue(obj, paste, null); } catch (Exception e) { Log.Warning(e.Message); } } }
public void AddWatch(ReferenceChain refChain) { watches.Add(refChain); Visible = true; }
private void ProcessShowRequest(ShowRequest request) { if (state.CurrentRefChain != null && request.AddChainToHistory) { state.RefChainHistory.Add(state.CurrentRefChain); } if (request.HideUnrelatedSceneRoots) { sceneTreeScrollPosition = Vector2.zero; sceneRoots.Clear(); ClearExpanded(); } searchDisplayString = request.UpdatedSearchString; ReferenceChain currentRefChain = null; var singleRefChain = request.ReferenceChains.Count == 1; foreach (var refChain in request.ReferenceChains) { var rootGameObject = (GameObject)refChain.GetChainItem(0); if (!sceneRoots.ContainsKey(rootGameObject)) { sceneRoots.Add(rootGameObject, true); } var expandedRefChain = ReferenceChainBuilder.ForGameObject(rootGameObject); if (!state.ExpandedGameObjects.Contains(expandedRefChain.UniqueId)) { state.ExpandedGameObjects.Add(expandedRefChain.UniqueId); } if (!singleRefChain) { continue; } for (var i = 1; i < refChain.Length; i++) { var breakLoop = false; switch (refChain.GetChainItemType(i)) { case ReferenceChain.ReferenceType.GameObject: var go = (GameObject)refChain.GetChainItem(i); expandedRefChain = expandedRefChain.Add(go); if (!state.ExpandedGameObjects.Contains(expandedRefChain.UniqueId)) { state.ExpandedGameObjects.Add(expandedRefChain.UniqueId); } break; case ReferenceChain.ReferenceType.Component: var component = (Component)refChain.GetChainItem(i); expandedRefChain = expandedRefChain.Add(component); if (currentRefChain != null) { breakLoop = true; } break; case ReferenceChain.ReferenceType.Field: var field = (FieldInfo)refChain.GetChainItem(i); expandedRefChain = expandedRefChain.Add(field); if (!state.ExpandedObjects.Contains(expandedRefChain.UniqueId)) { state.ExpandedObjects.Add(expandedRefChain.UniqueId); } break; case ReferenceChain.ReferenceType.Property: var property = (PropertyInfo)refChain.GetChainItem(i); expandedRefChain = expandedRefChain.Add(property); if (!state.ExpandedObjects.Contains(expandedRefChain.UniqueId)) { state.ExpandedObjects.Add(expandedRefChain.UniqueId); } break; case ReferenceChain.ReferenceType.EnumerableItem: var index = (uint)refChain.GetChainItem(i); uint startIndex; if (state.SelectedArrayStartIndices.TryGetValue(expandedRefChain.UniqueId, out startIndex)) { startIndex = Math.Min(index, startIndex); } else if (index > 16) { startIndex = index - 16; } else { startIndex = 0; } uint endIndex; if (state.SelectedArrayEndIndices.TryGetValue(expandedRefChain.UniqueId, out endIndex)) { endIndex = Math.Max(index, endIndex); } else { endIndex = startIndex + 31; } state.SelectedArrayStartIndices[expandedRefChain.UniqueId] = startIndex; state.SelectedArrayEndIndices[expandedRefChain.UniqueId] = endIndex; expandedRefChain = expandedRefChain.Add(index); if (!state.ExpandedObjects.Contains(expandedRefChain.UniqueId)) { state.ExpandedObjects.Add(expandedRefChain.UniqueId); } break; } if (breakLoop) { break; } } if (currentRefChain == null) { currentRefChain = refChain.Clone(); currentRefChain.IndentationOffset = refChain.Length; } } state.CurrentRefChain = currentRefChain; }
public static void OnSceneTreeReflect(SceneExplorerState state, ReferenceChain refChain, System.Object obj, bool rawReflection = false) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } if (obj == null) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "null"); return; } Type type = obj.GetType(); if (!rawReflection) { if (state.preventCircularReferences.ContainsKey(obj.GetHashCode())) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "Circular reference detected"); return; } state.preventCircularReferences.Add(obj.GetHashCode(), true); if (type == typeof(UnityEngine.Transform)) { GUITransform.OnSceneTreeReflectUnityEngineTransform(refChain, (UnityEngine.Transform)obj); return; } if (TypeUtil.IsList(obj)) { GUIList.OnSceneTreeReflectIList(state, refChain, obj); return; } if (TypeUtil.IsCollection(obj)) { GUICollection.OnSceneTreeReflectICollection(state, refChain, obj); return; } if (TypeUtil.IsEnumerable(obj)) { GUIEnumerable.OnSceneTreeReflectIEnumerable(state, refChain, obj); return; } if (type == typeof(Material)) { GUIMaterial.OnSceneReflectUnityEngineMaterial(state, refChain, (UnityEngine.Material)obj); return; } if (type == typeof(Mesh)) { if (!((Mesh)obj).isReadable) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "Mesh is not readable"); return; } } } var members = TypeUtil.GetAllMembers(type, ModTools.Instance.config.sceneExplorerShowInheritedMembers); if (ModTools.Instance.config.sceneExplorerSortAlphabetically) { Array.Sort(members, (info, info1) => string.Compare(info.Name, info1.Name, StringComparison.Ordinal)); } foreach (MemberInfo member in members) { if (member.MemberType == MemberTypes.Field && ModTools.Instance.config.sceneExplorerShowFields) { var field = (FieldInfo)member; try { GUIField.OnSceneTreeReflectField(state, refChain.Add(field), obj, field); } catch (Exception ex) { SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching field \"{field.Name}\" - {ex.Message}\n{ex.StackTrace}"); } } else if (member.MemberType == MemberTypes.Property && ModTools.Instance.config.sceneExplorerShowProperties) { var property = (PropertyInfo)member; try { GUIProperty.OnSceneTreeReflectProperty(state, refChain.Add(property), obj, property); } catch (Exception ex) { SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching property \"{property.Name}\" - {ex.Message}\n{ex.StackTrace}"); } } else if (member.MemberType == MemberTypes.Method && ModTools.Instance.config.sceneExplorerShowMethods) { var method = (MethodInfo)member; try { GUIMethod.OnSceneTreeReflectMethod(refChain.Add(method), obj, method); } catch (Exception ex) { SceneExplorerCommon.OnSceneTreeMessage(refChain, $"Exception when fetching method \"{method.Name}\" - {ex.Message}"); } } } }
public static void OnSceneReflectUnityEngineMaterial(SceneExplorerState state, ReferenceChain refChain, Material material) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } if (material == null) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "null"); return; } ReferenceChain oldRefChain = refChain; foreach (var prop in textureProps) { if (!material.HasProperty(prop)) { continue; } var value = material.GetTexture(prop); if (value == null) { continue; } refChain = oldRefChain.Add(prop); var type = value.GetType(); GUILayout.BeginHorizontal(); GUILayout.Space(ModTools.Instance.config.sceneExplorerTreeIdentSpacing * (refChain.Ident + 1)); GUIExpander.ExpanderControls(state, refChain, type); GUI.contentColor = ModTools.Instance.config.typeColor; GUILayout.Label(type.ToString() + " "); GUI.contentColor = ModTools.Instance.config.nameColor; GUILayout.Label(prop); GUI.contentColor = Color.white; GUILayout.Label(" = "); GUI.contentColor = ModTools.Instance.config.valueColor; GUILayout.Label(value.ToString()); GUI.contentColor = Color.white; GUILayout.FlexibleSpace(); GUIButtons.SetupButtons(type, value, refChain); object paste; var doPaste = GUIButtons.SetupPasteButon(type, out paste); GUILayout.EndHorizontal(); if (!TypeUtil.IsSpecialType(type) && state.expandedObjects.ContainsKey(refChain)) { GUIReflect.OnSceneTreeReflect(state, refChain, value); } if (doPaste) { material.SetTexture(prop, (Texture)paste); } } foreach (string prop in colorProps) { if (!material.HasProperty(prop)) { continue; } Color value = material.GetColor(prop); refChain = oldRefChain.Add(prop); var type = value.GetType(); GUILayout.BeginHorizontal(); GUILayout.Space(ModTools.Instance.config.sceneExplorerTreeIdentSpacing * (refChain.Ident + 1)); GUIExpander.ExpanderControls(state, refChain, type); GUI.contentColor = ModTools.Instance.config.typeColor; GUILayout.Label(type.ToString() + " "); GUI.contentColor = ModTools.Instance.config.nameColor; GUILayout.Label(prop); GUI.contentColor = Color.white; GUILayout.Label(" = "); var f = value; GUI.contentColor = ModTools.Instance.config.valueColor; var propertyCopy = prop; GUIControls.ColorField(refChain.ToString(), "", ref f, 0.0f, null, true, true, color => { material.SetColor(propertyCopy, color); }); if (f != value) { material.SetColor(prop, f); } GUI.contentColor = Color.white; GUILayout.FlexibleSpace(); GUIButtons.SetupButtons(type, value, refChain); object paste; var doPaste = GUIButtons.SetupPasteButon(type, out paste); GUILayout.EndHorizontal(); if (!TypeUtil.IsSpecialType(type) && state.expandedObjects.ContainsKey(refChain)) { GUIReflect.OnSceneTreeReflect(state, refChain, value); } if (doPaste) { material.SetColor(prop, (Color)paste); } } GUIReflect.OnSceneTreeReflect(state, refChain, material, true); }
public static void SetupButtons(Type type, object value, ReferenceChain refChain) { if (value is VehicleInfo) { var info = (VehicleInfo)value; if (info.m_mesh != null) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(info.name, info.m_mesh, info.m_material); } } if (info.m_lodMesh != null) { if (GUILayout.Button("Preview LOD")) { MeshViewer.CreateMeshViewer(info.name + "_LOD", info.m_lodMesh, info.m_lodMaterial); } } } else if (value is NetInfo) { SetupPlopButton(value); } else if (value is BuildingInfo) { var info = (BuildingInfo)value; SetupPlopButton(value); if (info.m_mesh != null) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(info.name, info.m_mesh, info.m_material); } } if (info.m_lodMesh != null) { if (GUILayout.Button("Preview LOD")) { MeshViewer.CreateMeshViewer(info.name + "_LOD", info.m_lodMesh, info.m_lodMaterial); } } } else if (value is PropInfo) { var info = (PropInfo)value; SetupPlopButton(value); if (info.m_mesh != null) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(info.name, info.m_mesh, info.m_material); } } if (info.m_lodMesh != null) { if (GUILayout.Button("Preview LOD")) { MeshViewer.CreateMeshViewer(info.name + "_LOD", info.m_lodMesh, info.m_lodMaterial); } } } else if (value is TreeInfo) { var info = (TreeInfo)value; SetupPlopButton(value); if (info.m_mesh != null) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(info.name, info.m_mesh, info.m_material); } } } else if (value is CitizenInfo) { var info = (CitizenInfo)value; if (info.m_lodMesh != null) { if (GUILayout.Button("Preview LOD")) { MeshViewer.CreateMeshViewer(info.name, info.m_lodMesh, info.m_lodMaterial); } } } else if (value is MilestoneInfo) { var info = (MilestoneInfo)value; if (GUILayout.Button("Unlock")) { var wrapper = new MilestonesWrapper(UnlockManager.instance); wrapper.UnlockMilestone(info.name); } } else if (value is NetInfo.Segment) { var info = (NetInfo.Segment)value; if (info.m_mesh != null) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(null, info.m_mesh, info.m_material); } if (GUILayout.Button("Preview LOD")) { MeshViewer.CreateMeshViewer(null, info.m_lodMesh, info.m_lodMaterial); } } } else if (value is NetInfo.Node) { var info = (NetInfo.Node)value; if (info.m_mesh != null) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(null, info.m_mesh, info.m_material); } if (GUILayout.Button("Preview LOD")) { MeshViewer.CreateMeshViewer(null, info.m_lodMesh, info.m_lodMaterial); } } } else if (TypeUtil.IsTextureType(type) && value != null) { var texture = (Texture)value; if (GUILayout.Button("Preview")) { TextureViewer.CreateTextureViewer(refChain, texture); } if (GUILayout.Button("Dump .png")) { TextureUtil.DumpTextureToPNG(texture); } } else if (TypeUtil.IsMeshType(type) && value != null) { if (GUILayout.Button("Preview")) { MeshViewer.CreateMeshViewer(null, (Mesh)value, null); } if (((Mesh)value).isReadable) { if (GUILayout.Button("Dump .obj")) { var outPath = refChain.ToString().Replace(' ', '_'); DumpUtil.DumpMeshAndTextures(outPath, value as Mesh); } } } if (GUILayout.Button("Copy")) { _buffer = value; } }
public static void OnSceneTreeReflectProperty(SceneExplorerState state, ReferenceChain refChain, object obj, PropertyInfo property, TypeUtil.SmartType smartType = TypeUtil.SmartType.Undefined, int nameHighlightFrom = -1, int nameHighlightLength = 0) { if (!SceneExplorerCommon.SceneTreeCheckDepth(refChain)) { return; } if (obj == null || property == null) { SceneExplorerCommon.OnSceneTreeMessage(refChain, "null"); return; } GUILayout.BeginHorizontal(GUIWindow.HighlightStyle); SceneExplorerCommon.InsertIndent(refChain.Indentation); object value = null; Exception exceptionOnGetting = null; if (property.CanRead && MainWindow.Instance.Config.EvaluateProperties || state.EvaluatedProperties.Contains(refChain.UniqueId)) { try { value = property.GetValue(obj, null); } catch (Exception e) { exceptionOnGetting = e; } if (value != null && exceptionOnGetting == null) { GUIExpander.ExpanderControls(state, refChain, property.PropertyType, obj); } } GUI.contentColor = Color.white; if (!property.CanWrite) { GUI.enabled = false; } if (MainWindow.Instance.Config.ShowModifiers) { GUI.contentColor = MainWindow.Instance.Config.MemberTypeColor; GUILayout.Label("property "); if (!property.CanWrite) { GUI.contentColor = MainWindow.Instance.Config.KeywordColor; GUILayout.Label("const "); } } GUI.contentColor = MainWindow.Instance.Config.TypeColor; GUILayout.Label(property.PropertyType.ToString() + " "); GUI.contentColor = MainWindow.Instance.Config.NameColor; GUIMemberName.MemberName(property, nameHighlightFrom, nameHighlightLength); GUI.contentColor = Color.white; GUILayout.Label(" = "); GUI.contentColor = MainWindow.Instance.Config.ValueColor; if (exceptionOnGetting != null) { GUI.contentColor = Color.red; GUILayout.Label("Exception happened when getting property value"); GUI.contentColor = Color.white; GUI.enabled = true; if (exceptionOnGetting.InnerException != null) { GUIStackTrace.StackTraceButton(new StackTrace(exceptionOnGetting.InnerException, true), exceptionOnGetting.InnerException.Message); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); return; } if (!MainWindow.Instance.Config.EvaluateProperties && !state.EvaluatedProperties.Contains(refChain.UniqueId)) { GUI.enabled = true; if (GUILayout.Button("Evaluate")) { state.EvaluatedProperties.Add(refChain.UniqueId); } } else if (value == null || !TypeUtil.IsSpecialType(property.PropertyType)) { if (property.CanRead) { GUILayout.Label(value == null ? "null" : value.ToString()); } else { GUILayout.Label("(no get method)"); } GUI.contentColor = Color.white; } else { try { var newValue = GUIControls.EditorValueField(refChain.UniqueId, property.PropertyType, value); if (newValue != value) { property.SetValue(obj, newValue, null); } } catch (Exception) { if (property.CanRead) { GUILayout.Label(value == null ? "null" : value.ToString()); } else { GUILayout.Label("(no get method)"); } GUI.contentColor = Color.white; } } GUI.enabled = true; GUI.contentColor = Color.white; GUILayout.FlexibleSpace(); GUIButtons.SetupCommonButtons(refChain, value, valueIndex: 0, smartType); object paste = null; var doPaste = property.CanWrite; if (doPaste) { doPaste = GUIButtons.SetupPasteButon(property.PropertyType, value, out paste); } if (value != null) { GUIButtons.SetupJumpButton(value, refChain); } GUILayout.EndHorizontal(); if (value != null && state.ExpandedObjects.Contains(refChain.UniqueId)) { GUIReflect.OnSceneTreeReflect(state, refChain, value, false); } if (doPaste) { try { property.SetValue(obj, paste, null); } catch (Exception e) { Logger.Warning(e.Message); } } }