486 lines
18 KiB
C#
486 lines
18 KiB
C#
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;
|
||
// }
|
||
}
|
||
}
|
||
} |