Files
back_cantanBuilding/Assets/Scripts/HexGrid/Editor/HexMapEditorWindow.cs
2026-05-26 16:15:54 +08:00

486 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using HexGrid.Math;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace HexGrid.Editor
{
public class HexMapEditorWindow: EditorWindow
{
private const string WindowName = "HexMapEditor";
//
private GameObject _tileRoot;
//
private GameObject _prefabTileRoot;
private Transform _rootForDelTrans;
// 当前的数量
private int buttonCount = 0;
private int selectedButton = 0;
private string[] buttonLabels = {"选项1", "选项2", "选项3", "选项4"};
private int selectedIndex = 0;
private List<string> buttonList = new List<string>();
private string newButtonName = "新按钮";
[MenuItem("Tools/HexMap/Editor")]
static void OpenWindow()
{
// 创建窗口
var window = GetWindow<HexMapEditorWindow>(WindowName);
window.Show();
}
private void OnGUI()
{
HexMath.SetHexMapOrigin(Vector3.zero);
HexMath.SetGridSize(1.52f);
//EditorGUILayout.Label("编辑器设置", EditorStyles.boldLabel);
// GUILayout.Label("编辑器设置", EditorStyles.boldLabel);
// PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
GameObject mapRootGo;
if (!prefabStage)
{
var sceneName = SceneManager.GetActiveScene().name;
GUILayout.Label($"场景名: {sceneName}",EditorStyles.boldLabel);
_tileRoot = EditorGUILayout.ObjectField("地图节点",_tileRoot,typeof(GameObject),true) as GameObject;
mapRootGo = _tileRoot;
_rootForDelTrans = null;
}
else
{
var prefabName = PrefabStageUtility.GetCurrentPrefabStage()?.prefabContentsRoot?.name?? "";
GUILayout.Label("Prefab 编辑模式");
GUILayout.Label($"prefabName: {prefabName}",EditorStyles.boldLabel);
_prefabTileRoot = EditorGUILayout.ObjectField("Prefab地图节点",_prefabTileRoot,typeof(GameObject),true) as GameObject;
mapRootGo = _prefabTileRoot;
_rootForDelTrans = PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot.transform;
}
EditorGUILayout.Space(5f);
EditorGUILayout.Space(10);
if (GUILayout.Button("检查",GUILayout.Height(30)))
{
if (!mapRootGo)
{
EditorUtility.DisplayDialog("提示", "请设置地图节点", "确定");
return;
}
CheckFatherTile(mapRootGo.transform);
}
EditorGUILayout.Space();
if (GUILayout.Button("添加到Top",GUILayout.Height(30)))
{
if (!mapRootGo)
{
EditorUtility.DisplayDialog("提示", "请设置地图节点", "确定");
return;
}
// ApplySettings(mapRootGo);
MoveTerrainToMap(mapRootGo.transform);
}
EditorGUILayout.Space();
if (GUILayout.Button("从Top移除父类",GUILayout.Height(30)))
{
if (!_tileRoot)
{
EditorUtility.DisplayDialog("提示", "请设置地图节点", "确定");
return;
}
RemoveFromTop();
}
// EditorGUILayout.Space(10);
// GUILayout.Label("动态按钮创建示例", EditorStyles.boldLabel);
// EditorGUILayout.Space(5);
//
//
// GUILayout.Label("动态 Selection Grid 示例", EditorStyles.boldLabel);
//
// // 添加按钮的控制区域
// GUILayout.BeginHorizontal();
// newButtonName = GUILayout.TextField(newButtonName, GUILayout.Width(150));
// if (GUILayout.Button("添加按钮", GUILayout.Width(80)))
// {
// AddButton(newButtonName);
// }
// GUILayout.EndHorizontal();
//
// GUILayout.Space(10);
//
// // 只有当列表中有按钮时才显示 SelectionGrid
// if (buttonList.Count > 0)
// {
// // 将 List 转换为数组传给 SelectionGrid[1][2]
// selectedIndex = GUILayout.SelectionGrid(
// selectedIndex,
// buttonList.ToArray(), // 转换为数组
// 3, // 每行3个按钮
// GUILayout.Height(100)
// );
//
// // 确保选中索引在有效范围内
// if (selectedIndex >= buttonList.Count)
// {
// selectedIndex = buttonList.Count - 1;
// }
//
// GUILayout.Space(10);
// GUILayout.Label($"当前选中: {buttonList[selectedIndex]} (索引: {selectedIndex})");
//
// // 删除选中的按钮
// if (GUILayout.Button("删除选中的按钮"))
// {
// RemoveSelectedButton();
// }
// }
// else
// {
// GUILayout.Label("暂无按钮,请添加新按钮");
// }
//
// // 清空所有按钮
// if (buttonList.Count > 0 && GUILayout.Button("清空所有"))
// {
// ClearAll();
// }
// // 主按钮 - 用于创建新按钮
// if (GUILayout.Button("点击创建新按钮", GUILayout.Height(30)))
// {
// CreateNewButton();
// }
//
// // 使用ScrollView以防按钮过多
// if (buttonCount > 0)
// {
// GUILayout.Label($"已创建 {buttonCount} 个按钮:");
//
// // 显示所有动态创建的按钮
// for (int i = 0; i < buttonCount; i++)
// {
// int index = i; // 捕获当前索引
// if (GUILayout.Button($"动态按钮 #{index + 1}", GUILayout.Height(25)))
// {
// OnDynamicButtonClick(index);
// }
// }
// }
//
// EditorGUILayout.Space(10);
// // 清除所有按钮
// if (buttonCount > 0 && GUILayout.Button("清除所有按钮"))
// {
// buttonCount = 0;
// Repaint();
// }
//
// // 使用水平布局
// GUILayout.BeginHorizontal();
// if (GUILayout.Button("创建普通按钮", GUILayout.Width(120),GUILayout.Height(120)))
// {
// // CreateButton("普通");
// }
// if (GUILayout.Button("创建特殊按钮", GUILayout.Width(120)))
// {
// // CreateButton("特殊");
// }
// GUILayout.EndHorizontal();
// // 使用SelectionGrid创建按钮组
// int selected = GUILayout.SelectionGrid(-1, new string[] {"按钮1", "按钮2", "按钮3","按钮4"}, 3,
// GUILayout.Width(300), // 设置总宽度为200
// GUILayout.Height(100) // 设置总高度为100
// );
//
// if (selected >= 0)
// {
// Debug.Log($"选择了按钮 {selected + 1}");
// }
//
// GUILayout.Label("带样式的 Selection Grid");
//
// // 创建自定义样式
// GUIStyle gridStyle = new GUIStyle(GUI.skin.button);
//
// // 未选中按钮样式
// gridStyle.normal.textColor = Color.gray;
//
// // 选中按钮样式on前缀表示选中状态
// gridStyle.onNormal.textColor = Color.cyan;
// gridStyle.fontStyle = FontStyle.Bold;
//
// // 创建带自定义样式的选择网格
// selectedButton = GUILayout.SelectionGrid(
// selectedButton,
// buttonLabels,
// 3, // 每行2个按钮
// gridStyle, // 使用自定义样式[1][2]
// GUILayout.Width(300),
// GUILayout.Height(100)
// );
//
// GUILayout.Space(10);
// GUILayout.Label($"当前选中: {buttonLabels[selectedButton]}");
}
void AddButton(string name)
{
buttonList.Add($"{name} {buttonList.Count + 1}");
Repaint();
}
void RemoveSelectedButton()
{
if (selectedIndex >= 0 && selectedIndex < buttonList.Count)
{
buttonList.RemoveAt(selectedIndex);
// 调整选中索引
if (selectedIndex >= buttonList.Count && buttonList.Count > 0)
{
selectedIndex = buttonList.Count - 1;
}
Repaint();
}
}
void ClearAll()
{
buttonList.Clear();
selectedIndex = 0;
Repaint();
}
private void CreateNewButton()
{
buttonCount++;
Debug.Log($"创建了新按钮,当前按钮总数:{buttonCount}");
Repaint(); // 重绘窗口以显示新按钮
}
private void OnDynamicButtonClick(int index)
{
Log($"点击了动态按钮 #{index + 1}");
}
private static void Log(string s)
{
Debug.Log($"<color=yellow>FishingChallengeManager -> {s} </color>");
}
private void RemoveFromTop()
{
if (Selection.gameObjects.Length == 0)
{
Debug.LogWarning("请先选择一个或多个对象");
return;
}
var list = new List<Object>();
foreach (var t in Selection.gameObjects)
{
var paGameObj = t.transform.parent?.gameObject;
if (paGameObj && paGameObj.name.StartsWith("top"))
{
Undo.SetTransformParent(t.transform, null, "Remove Parent of " + t.gameObject.name ?? "");
t.transform.SetParent(_rootForDelTrans, true);
list.Add(t);
}
}
Selection.objects = list.ToArray();
FocusSelectinHierarchy();
}
private void Test()
{
// var enumerable = Selection.gameObjects.Select(elem => elem.transform).ToList();
// var mapRoot = _tileRoot.transform;
// foreach (var child in enumerable)
// {
// // child.SetParent(mapRoot,true);
// Undo.SetTransformParent(child,mapRoot,$"Reparent {child.gameObject.name}");
// child.SetParent(mapRoot,true);
// }
// var obj = Selection.activeGameObject;
// EditorApplication.delayCall += () =>
// {
// EditorGUIUtility.PingObject(obj);
// Selection.activeGameObject = obj;
// };
}
private void CheckFatherTile(Transform mapRoot)
{
var mapTiles = mapRoot.GetComponentsInChildren<Transform>(true);
var list = new List<Object>();
var enumerable = Selection.gameObjects.Where(elem => elem.transform != mapRoot).Select(elem => elem.transform).ToList();
foreach (var pos in enumerable.Select(child => HexMath.PixelToAxial(child.position)))
{
foreach (Transform tile in mapTiles)
{
// if(tile.Equals(mapRoot)) continue;
// if()
var hexGridController = tile.GetComponent<HexGridTiler>();
if(!hexGridController) continue;
var tilePos = HexMath.PixelToAxial(tile.position);
if (tilePos.Equals(pos))
{
var onTop = tile.Find("on/top");
ExpandParentHierarchy(onTop);
list.Add(tile.gameObject);
break;
}
}
}
list.AddRange(Selection.objects);
Selection.objects = list.ToArray();
FocusSelectinHierarchy();
}
//
private void MoveTerrainToMap(Transform mapRoot)
{
Undo.IncrementCurrentGroup();
Undo.SetCurrentGroupName("Reparent");
var mapTiles = mapRoot.GetComponentsInChildren<Transform>(true);
var list = new List<GameObject>();
var enumerable = Selection.gameObjects.Select(elem => elem.transform).ToList();
foreach (var child in enumerable)
{
var pos = HexMath.PixelToAxial(child.position);
foreach (Transform tile in mapTiles)
{
var tilePos = HexMath.PixelToAxial(tile.position);
if (tilePos.Equals(pos))
{
var onTop = tile.Find("on/top");
Undo.SetTransformParent(child,onTop,$"$Reparent {child.gameObject.name}");
child.SetParent(onTop,true);
list.Add(child.gameObject);
break;
}
}
// var tile = HexMath.PixelToAxial(terr.position)
}
Selection.objects = list.ToArray();
FocusSelectinHierarchy();
}
private static void ExpandParentHierarchy(Transform target)
{
if (!target) return;
List<GameObject> path = new List<GameObject>();
Transform current = target;
// 收集从目标到根的路径
path.Add(current.gameObject);
// 从根到目标依次展开
for (int i = path.Count - 1; i >= 0; i--)
{
// 使用内部方法展开 Hierarchy 中的对象
var type = typeof(EditorWindow).Assembly.GetType("UnityEditor.SceneHierarchyWindow");
var window = EditorWindow.GetWindow(type);
var expandMethod = type.GetMethod("SetExpandedRecursive");
if (expandMethod != null)
{
expandMethod.Invoke(window, new object[] { path[i].GetInstanceID(), true });
}
}
}
private void FocusSelectinHierarchy()
{
SceneView sceneView = SceneView.lastActiveSceneView;
sceneView.Focus();
sceneView.FrameSelected();
var selected = Selection.activeGameObject;
if (selected)
{
// EditorGUIUtility.PingObject(selected);
EditorApplication.delayCall += () =>
{
// ExpandParentHierarchy(selected.transform);
EditorGUIUtility.PingObject(selected);
};
}
}
private void ApplySettings(Transform mapRoot)
{
MoveTerrainToMap(mapRoot);
// PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
//
// GameObject prefabRoot = prefabStage.prefabContentsRoot;
//
// Debug.Log($"当前Prefab根节点: {prefabRoot.name}");
// // 选中根节点
// Selection.activeGameObject = prefabRoot;
// 检查是否在Prefab模式
// PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
// if (prefabStage != null)
// {
// // 在Prefab模式中
// GameObject prefabRoot = prefabStage.prefabContentsRoot;
// Debug.Log($"Prefab根节点: {prefabRoot.name}");
// Selection.activeGameObject = prefabRoot;
// }
// else
// {
// // 在场景模式中
// Scene activeScene = SceneManager.GetActiveScene();
// GameObject[] sceneRoots = activeScene.GetRootGameObjects();
//
// Debug.Log($"场景 '{activeScene.name}' 的根节点:");
// foreach (var root in sceneRoots)
// {
// Debug.Log($"- {root.name}");
// }
// Selection.objects = sceneRoots;
// }
// GameObject[] rootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects();
//
// foreach (GameObject root in rootGameObjects)
// {
// Debug.Log("根节点: " + root.name);
// }
// if (Selection.activeGameObject)
// {
// Undo.RecordObject(Selection.activeGameObject, "Apply Settings");
// // 应用设置到选中的对象
// // Selection.activeGameObject.name = objectName;
// }
}
}
}