Files
XericLibrary-WebGL-Publish/Editor/Blueprint/BlueprintMenuItems.cs
T
lrss3 7f3a12cae0 # update 0.6.2.1
更新了蓝图组件相关的用法。
2026-07-15 10:36:16 +08:00

166 lines
5.4 KiB
C#
Raw 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 UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using XericLibrary.Runtime.Blueprint;
namespace XericLibraryEditor.Bluprint.Editor
{
/// <summary>
/// 蓝图右键菜单项 —— 通过 GameObject 菜单/Gizmo 快捷创建蓝图场景对象。
/// <para>
/// 创建逻辑:
/// <list type="number">
/// <item>检查选中节点是否已在 Canvas 子级下;若否则新建 Canvas(1024×720)。</item>
/// <item>在 Canvas 下创建背景 Image 子项(1024×720,中心对齐)。</item>
/// <item>在 Canvas 下创建蓝图组件子项。</item>
/// </list>
/// </para>
/// </summary>
public static class BlueprintMenuItems
{
private const string MenuRoot = "GameObject/Xeric Library/Blueprint/";
private const string BackgroundGoName = "__Bp_GridBackground";
// ========== 菜单项 ==========
[MenuItem(MenuRoot + "UI Graph Bp", false, 10)]
private static void CreateUIGraphBlueprint()
{
var parent = GetOrCreateCanvasParent();
var bg = CreateBackgroundImage(parent);
var bpGo = CreateChild(parent, "Blueprint Graph (UI)");
bpGo.transform.SetParent(bg.transform, false);
bpGo.AddComponent<GraphTheoryBlueprintComponent>();
Finish(bpGo, "Create UI Graph Blueprint");
}
[MenuItem(MenuRoot + "UI Graph Bp (QuickGraph)", false, 11)]
private static void CreateUIQuickGraphBlueprint()
{
var parent = GetOrCreateCanvasParent();
var bg = CreateBackgroundImage(parent);
var bpGo = CreateChild(parent, "Blueprint Graph - QuickGraph (UI)");
bpGo.transform.SetParent(bg.transform, false);
var comp = bpGo.AddComponent<GraphTheoryBlueprintComponent>();
comp.ThemeName = "QuickGraph";
Finish(bpGo, "Create UI QuickGraph Blueprint");
}
[MenuItem(MenuRoot + "World Space Graph Bp", false, 12)]
private static void CreateWorldSpaceGraphBlueprint()
{
var go = CreateBlueprintGameObject("Blueprint Graph (World)");
go.AddComponent<GraphTheoryBlueprintComponent>();
Finish(go, "Create World Space Graph Blueprint");
}
// ========== 工具方法 ==========
/// <summary>
/// 确保存在 Canvas 父节点。
/// 当前选中节点已在 Canvas 子级下 → 直接返回根 Canvas。
/// 否则 → 新建 Canvas 并设为父级。
/// </summary>
private static Transform GetOrCreateCanvasParent()
{
var active = Selection.activeTransform;
if (active != null)
{
var existingCanvas = active.GetComponentInParent<Canvas>();
if (existingCanvas != null)
return existingCanvas.transform;
// 如果选中对象不是 Canvas 但已有 Canvas 同级或父级
existingCanvas = Object.FindObjectOfType<Canvas>();
if (existingCanvas != null)
return existingCanvas.transform;
}
else
{
// 场景中没有任何选中对象,找现有的 Canvas
var existingCanvas = Object.FindObjectOfType<Canvas>();
if (existingCanvas != null)
return existingCanvas.transform;
}
// 真的没有 Canvas → 新建一个
var canvasGo = new GameObject("Blueprint Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
var canvas = canvasGo.GetComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
var rt = canvasGo.GetComponent<RectTransform>();
rt.sizeDelta = new Vector2(1024, 720);
rt.anchorMin = new Vector2(0.5f, 0.5f);
rt.anchorMax = new Vector2(0.5f, 0.5f);
rt.pivot = new Vector2(0.5f, 0.5f);
if (Selection.activeTransform != null)
canvasGo.transform.SetParent(Selection.activeTransform, false);
canvasGo.transform.SetAsLastSibling();
return canvasGo.transform;
}
/// <summary>
/// 创建背景 Image 子项,1024×720,中心对齐,启用射线检测。
/// 如果同层级下已有同名的背景对象,跳过创建。
/// </summary>
private static GameObject CreateBackgroundImage(Transform parent)
{
// 不重复创建
var existing = parent.Find(BackgroundGoName);
if (existing != null)
return existing.gameObject;
var bgGo = new GameObject(BackgroundGoName, typeof(Image), typeof(Mask));
var bgRt = bgGo.GetComponent<RectTransform>();
bgRt.SetParent(parent, false);
// 撑满父节点
bgRt.anchorMin = Vector2.zero;
bgRt.anchorMax = Vector2.one;
bgRt.offsetMin = Vector2.zero;
bgRt.offsetMax = Vector2.zero;
bgRt.pivot = new Vector2(0.5f, 0.5f);
var image = bgGo.GetComponent<Image>();
image.raycastTarget = true;
image.color = new Color(0.15f, 0.15f, 0.17f, 1f);
bgGo.transform.SetAsFirstSibling();
return bgGo;
}
private static GameObject CreateChild(Transform parent, string name)
{
var go = new GameObject(name, typeof(RectTransform));
var rt = go.GetComponent<RectTransform>();
rt.SetParent(parent, false);
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.one;
rt.offsetMin = Vector2.zero;
rt.offsetMax = Vector2.zero;
rt.SetAsLastSibling();
return go;
}
private static GameObject CreateBlueprintGameObject(string name)
{
var go = new GameObject(name);
if (Selection.activeTransform != null)
go.transform.SetParent(Selection.activeTransform, false);
go.transform.SetAsLastSibling();
return go;
}
private static void Finish(GameObject go, string undoName)
{
Selection.activeGameObject = go;
Undo.RegisterCreatedObjectUndo(go, undoName);
// 也注册父级 Canvas 的撤销
var canvas = go.GetComponentInParent<Canvas>();
if (canvas != null)
Undo.RegisterCreatedObjectUndo(canvas.gameObject, undoName);
}
}
}