Files
AppleHillsProduction/Assets/Editor/SceneObjectLocatorWindow.cs
tschesky 63cb3f1a8c Revamp the settings system (#7)
- A Settings Provider system to utilize addressables for loading settings at runtime
- An editor UI for easy modifications of the settings objects
- A split out developer settings functionality to keep gameplay and nitty-gritty details separately
- Most settings migrated out of game objects and into the new system
- An additional Editor utility for fetching the settings at editor runtime, for gizmos, visualization etc

Co-authored-by: Michal Pikulski <michal.a.pikulski@gmail.com>
Co-authored-by: AlexanderT <alexander@foolhardyhorizons.com>
Reviewed-on: #7
2025-09-24 13:33:43 +00:00

177 lines
6.0 KiB
C#

using UnityEditor;
using UnityEngine;
using UnityEditor.SceneManagement;
using System.Collections.Generic;
using System.Linq;
using Interactions;
using PuzzleS;
public class SceneObjectLocatorWindow : EditorWindow
{
private enum Tab { Puzzles, Items }
private Tab currentTab = Tab.Puzzles;
private List<ObjectiveStepBehaviour> puzzleBehaviours = new List<ObjectiveStepBehaviour>();
private List<PickupInfo> pickupInfos = new List<PickupInfo>();
private Vector2 scrollPos;
[MenuItem("AppleHills/Scene Object Locator")]
public static void ShowWindow()
{
var window = GetWindow<SceneObjectLocatorWindow>("Scene Object Locator");
window.minSize = new Vector2(600, 400);
window.maxSize = new Vector2(1200, 800);
window.position = new Rect(120, 120, 700, 500);
}
private void OnEnable()
{
RefreshSceneObjects();
EditorSceneManager.sceneOpened += (scene, mode) => RefreshSceneObjects();
EditorSceneManager.activeSceneChanged += (oldScene, newScene) => RefreshSceneObjects();
}
private void OnDisable()
{
EditorSceneManager.sceneOpened -= (scene, mode) => RefreshSceneObjects();
EditorSceneManager.activeSceneChanged -= (oldScene, newScene) => RefreshSceneObjects();
}
private void RefreshSceneObjects()
{
puzzleBehaviours = FindObjectsByType<ObjectiveStepBehaviour>(FindObjectsInactive.Include, FindObjectsSortMode.None).ToList();
var pickups = FindObjectsByType<Pickup>(FindObjectsInactive.Include, FindObjectsSortMode.None);
pickupInfos.Clear();
foreach (var pickup in pickups)
{
var go = pickup.gameObject;
bool hasSlot = go.GetComponent<ItemSlot>() != null;
pickupInfos.Add(new PickupInfo
{
pickup = pickup,
hasSlot = hasSlot
});
}
Repaint();
}
private void OnGUI()
{
currentTab = (Tab)GUILayout.Toolbar((int)currentTab, new[] { "Puzzles", "Items" });
GUILayout.Space(8);
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
if (currentTab == Tab.Puzzles)
DrawPuzzleTab();
else
DrawItemsTab();
EditorGUILayout.EndScrollView();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Refresh"))
{
RefreshSceneObjects();
}
}
private void DrawPuzzleTab()
{
if (puzzleBehaviours.Count == 0)
{
EditorGUILayout.HelpBox("No ObjectiveStepBehaviour objects found in the scene.", MessageType.Info);
return;
}
foreach (var obj in puzzleBehaviours)
{
if (obj == null) continue;
var go = obj.gameObject;
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField($"GameObject: {go.name}", EditorStyles.boldLabel);
EditorGUILayout.LabelField($"Path: {GetHierarchyPath(go)}");
if (obj.stepData != null)
{
EditorGUILayout.LabelField($"Step: {obj.stepData.displayName} ({obj.stepData.stepId})");
}
else
{
EditorGUILayout.LabelField("Step: [None]", EditorStyles.miniLabel);
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Ping Object", GUILayout.Width(120)))
{
Selection.activeObject = go;
EditorGUIUtility.PingObject(go);
}
if (obj.stepData != null && GUILayout.Button("Ping StepSO", GUILayout.Width(120)))
{
Selection.activeObject = obj.stepData;
EditorGUIUtility.PingObject(obj.stepData);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
GUILayout.Space(4);
}
}
private void DrawItemsTab()
{
if (pickupInfos.Count == 0)
{
EditorGUILayout.HelpBox("No Pickup objects found in the scene.", MessageType.Info);
return;
}
foreach (var info in pickupInfos)
{
if (info.pickup == null) continue;
var go = info.pickup.gameObject;
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField($"GameObject: {go.name}", EditorStyles.boldLabel);
EditorGUILayout.LabelField($"Path: {GetHierarchyPath(go)}");
string types = "";
if (info.hasCombine) types += "Combine";
if (info.hasSlot) types += (types.Length > 0 ? ", " : "") + "Slot";
EditorGUILayout.LabelField($"Types: {(string.IsNullOrEmpty(types) ? "Pickup" : types)}");
if (info.pickup.itemData != null)
{
EditorGUILayout.LabelField($"Item: {info.pickup.itemData.itemName}");
}
else
{
EditorGUILayout.LabelField("Item: [None]", EditorStyles.miniLabel);
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Ping Object", GUILayout.Width(120)))
{
Selection.activeObject = go;
EditorGUIUtility.PingObject(go);
}
if (info.pickup.itemData != null && GUILayout.Button("Ping ItemData", GUILayout.Width(120)))
{
Selection.activeObject = info.pickup.itemData;
EditorGUIUtility.PingObject(info.pickup.itemData);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
GUILayout.Space(4);
}
}
private string GetHierarchyPath(GameObject go)
{
string path = go.name;
Transform t = go.transform.parent;
while (t != null)
{
path = t.name + "/" + path;
t = t.parent;
}
return path;
}
private class PickupInfo
{
public Pickup pickup;
public bool hasCombine;
public bool hasSlot;
}
}