using System; using System.Collections.Generic; using System.Linq; using UnityExplorer.Helpers; using UnityExplorer.UI; using UnityExplorer.Unstrip.LayerMasks; using TMPro; using UnityEngine; using UnityEngine.UI; using UnityExplorer.Inspectors.GOInspector; namespace UnityExplorer.Inspectors { public class GameObjectInspector : InspectorBase { public override string TabLabel => $" [G] {TargetGO?.name}"; public static GameObjectInspector ActiveInstance { get; private set; } public GameObject TargetGO; // sub modules private static ChildList s_childList; private static ComponentList s_compList; private static GameObjectControls s_controls; // static UI elements (only constructed once) private static bool m_UIConstructed; private static GameObject s_content; public override GameObject Content { get => s_content; set => s_content = value; } public static TMP_InputField m_nameInput; private static string m_lastName; public static TMP_InputField m_pathInput; private static string m_lastPath; private static GameObject m_pathGroupObj; private static Text m_hiddenPathText; private static Toggle m_enabledToggle; private static Text m_enabledText; private static bool? m_lastEnabledState; private static Dropdown m_layerDropdown; private static int m_lastLayer = -1; private static Text m_sceneText; private static string m_lastScene; public GameObjectInspector(GameObject target) : base(target) { ActiveInstance = this; TargetGO = target; if (!TargetGO) { ExplorerCore.LogWarning("GameObjectInspector cctor: Target GameObject is null!"); return; } // one UI is used for all gameobject inspectors. no point recreating it. if (!m_UIConstructed) { m_UIConstructed = true; s_childList = new ChildList(); s_compList = new ComponentList(); s_controls = new GameObjectControls(); ConstructUI(); } } public override void SetContentActive() { base.SetContentActive(); ActiveInstance = this; } public override void SetContentInactive() { base.SetContentInactive(); ActiveInstance = null; } internal void ChangeInspectorTarget(GameObject newTarget) { if (!newTarget) return; this.Target = this.TargetGO = newTarget; } // Update public override void Update() { base.Update(); if (m_pendingDestroy || ActiveInstance != this) return; RefreshTopInfo(); s_childList.RefreshChildObjectList(); s_compList.RefreshComponentList(); s_controls.RefreshControls(); if (GameObjectControls.s_sliderChangedWanted) { GameObjectControls.UpdateSliderControl(); } } private void RefreshTopInfo() { if (m_lastName != TargetGO.name) { m_lastName = TargetGO.name; m_nameInput.text = m_lastName; } if (TargetGO.transform.parent) { if (!m_pathGroupObj.activeSelf) m_pathGroupObj.SetActive(true); var path = TargetGO.transform.GetTransformPath(true); if (m_lastPath != path) { m_lastPath = path; m_pathInput.text = path; m_hiddenPathText.text = path; } } else if (m_pathGroupObj.activeSelf) m_pathGroupObj.SetActive(false); if (m_lastEnabledState != TargetGO.activeSelf) { m_lastEnabledState = TargetGO.activeSelf; m_enabledToggle.isOn = TargetGO.activeSelf; m_enabledText.text = TargetGO.activeSelf ? "Enabled" : "Disabled"; m_enabledText.color = TargetGO.activeSelf ? Color.green : Color.red; } if (m_lastLayer != TargetGO.layer) { m_lastLayer = TargetGO.layer; m_layerDropdown.value = TargetGO.layer; } if (m_lastScene != TargetGO.scene.name) { m_lastScene = TargetGO.scene.name; if (!string.IsNullOrEmpty(TargetGO.scene.name)) m_sceneText.text = m_lastScene; else m_sceneText.text = "None (Asset/Resource)"; } } // UI Callbacks private static void OnApplyNameClicked() { if (ActiveInstance == null) return; ActiveInstance.TargetGO.name = m_nameInput.text; } private static void OnEnableToggled(bool enabled) { if (ActiveInstance == null) return; ActiveInstance.TargetGO.SetActive(enabled); } private static void OnLayerSelected(int layer) { if (ActiveInstance == null) return; ActiveInstance.TargetGO.layer = layer; } internal static void OnBackButtonClicked() { if (ActiveInstance == null) return; ActiveInstance.ChangeInspectorTarget(ActiveInstance.TargetGO.transform.parent.gameObject); } #region UI CONSTRUCTION private void ConstructUI() { var parent = InspectorManager.Instance.m_inspectorContent; s_content = UIFactory.CreateScrollView(parent, out GameObject scrollContent, new Color(0.1f, 0.1f, 0.1f)); var scrollGroup = scrollContent.GetComponent(); scrollGroup.childForceExpandHeight = true; scrollGroup.childControlHeight = true; scrollGroup.spacing = 5; ConstructTopArea(scrollContent); s_controls.ConstructControls(scrollContent); var midGroupObj = ConstructMidGroup(scrollContent); s_childList.ConstructChildList(midGroupObj); s_compList.ConstructCompList(midGroupObj); } private void ConstructTopArea(GameObject scrollContent) { // path row m_pathGroupObj = UIFactory.CreateHorizontalGroup(scrollContent, new Color(0.1f, 0.1f, 0.1f)); var pathGroup = m_pathGroupObj.GetComponent(); pathGroup.childForceExpandHeight = false; pathGroup.childForceExpandWidth = false; pathGroup.childControlHeight = false; pathGroup.childControlWidth = true; pathGroup.spacing = 5; var pathRect = m_pathGroupObj.GetComponent(); pathRect.sizeDelta = new Vector2(pathRect.sizeDelta.x, 20); var pathLayout = m_pathGroupObj.AddComponent(); pathLayout.minHeight = 20; pathLayout.flexibleHeight = 75; var backButtonObj = UIFactory.CreateButton(m_pathGroupObj); var backButton = backButtonObj.GetComponent