udpate 0.6.2
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b93e95735924284ba5561cdcb1af3dc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XericLibrary.Runtime.Blueprint;
|
||||
|
||||
namespace XericLibraryEditor.Bluprint.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 蓝图右键菜单项 —— 通过 GameObject 菜单快捷创建蓝图示例。
|
||||
/// </summary>
|
||||
public static class BlueprintMenuItems
|
||||
{
|
||||
private const string MenuRoot = "GameObject/Xeric Library/Blueprint/";
|
||||
|
||||
[MenuItem(MenuRoot + "UI Graph Bp", false, 10)]
|
||||
private static void CreateUIGraphBlueprint()
|
||||
{
|
||||
var go = CreateBlueprintGameObject("Blueprint Graph (UI)");
|
||||
|
||||
var canvas = go.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
|
||||
go.AddComponent<CanvasScaler>();
|
||||
go.AddComponent<GraphicRaycaster>();
|
||||
|
||||
go.AddComponent<GraphTheoryBlueprintComponent>();
|
||||
|
||||
Selection.activeGameObject = go;
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create UI Graph Blueprint");
|
||||
}
|
||||
|
||||
[MenuItem(MenuRoot + "UI Graph Bp (QuickGraph)", false, 11)]
|
||||
private static void CreateUIQuickGraphBlueprint()
|
||||
{
|
||||
var go = CreateBlueprintGameObject("Blueprint Graph - QuickGraph (UI)");
|
||||
|
||||
var canvas = go.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
|
||||
go.AddComponent<CanvasScaler>();
|
||||
go.AddComponent<GraphicRaycaster>();
|
||||
|
||||
var comp = go.AddComponent<GraphTheoryBlueprintComponent>();
|
||||
comp.ThemeName = "QuickGraph";
|
||||
|
||||
Selection.activeGameObject = go;
|
||||
Undo.RegisterCreatedObjectUndo(go, "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>();
|
||||
|
||||
Selection.activeGameObject = go;
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create World Space Graph Blueprint");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef23c61b0362b8b4e99796655c109d78
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a618e02e848483d82f62c25637f3719
|
||||
timeCreated: 1783824464
|
||||
@@ -0,0 +1,236 @@
|
||||
#if UNITY_EDITOR && ENABLE_INPUT_SYSTEM
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
|
||||
namespace XericLibrary.Runtime.Blueprint.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 蓝图 InputAction 模板生成器。
|
||||
/// 右键 Project 窗口 → Xeric Library / Input Action Template / BlueprintAction
|
||||
/// 即可创建预设 InputActionAsset,内含蓝图所有的 Actions 和绑定。
|
||||
/// </summary>
|
||||
public static class BlueprintInputActionTemplate
|
||||
{
|
||||
private const string MenuPath = "Assets/Create/Xeric Library/Input Action Template/BlueprintAction";
|
||||
private const string DefaultFileName = "BlueprintActions";
|
||||
|
||||
[MenuItem(MenuPath, priority = 1100)]
|
||||
public static void CreateBlueprintInputActionAsset()
|
||||
{
|
||||
var asset = ScriptableObject.CreateInstance<InputActionAsset>();
|
||||
|
||||
var map = asset.AddActionMap(BlueprintInputConstants.MapName);
|
||||
|
||||
var binding = InputBinding.MaskByGroup("Keyboard&Mouse");
|
||||
var gamepadBinding = InputBinding.MaskByGroup("Gamepad");
|
||||
|
||||
// ── 指针位置 ──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.Point,
|
||||
type: InputActionType.Value,
|
||||
binding: "<Mouse>/position",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── 滚轮 ──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.ScrollWheel,
|
||||
type: InputActionType.Value,
|
||||
binding: "<Mouse>/scroll",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── 左键 ──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.LeftClick,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Mouse>/leftButton",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── 右键 ──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.RightClick,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Mouse>/rightButton",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── 中键 ──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.MiddleClick,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Mouse>/middleButton",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── Shift ──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.Shift,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Keyboard>/leftShift",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── Ctrl ──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.Ctrl,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Keyboard>/leftCtrl",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── Alt ──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.Alt,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Keyboard>/leftAlt",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── Pan(平移:方向键 + Shift+滚轮 → 水平, Alt+滚轮 → 垂直)──
|
||||
var panAction = map.AddAction(
|
||||
BlueprintInputConstants.Pan,
|
||||
type: InputActionType.Value,
|
||||
binding: null); // 多个 composite,需手动绑定
|
||||
|
||||
// 键盘方向键 Vector2
|
||||
var kbCompositeIndex = panAction.AddCompositeBinding("2DVector")
|
||||
.With("Up", "<Keyboard>/upArrow")
|
||||
.With("Down", "<Keyboard>/downArrow")
|
||||
.With("Left", "<Keyboard>/leftArrow")
|
||||
.With("Right", "<Keyboard>/rightArrow");
|
||||
ApplyGroupToLastBindings(panAction, binding.ToString());
|
||||
|
||||
// 手柄左摇杆
|
||||
panAction.AddCompositeBinding("2DVector")
|
||||
.With("Up", "<Gamepad>/leftStick/up")
|
||||
.With("Down", "<Gamepad>/leftStick/down")
|
||||
.With("Left", "<Gamepad>/leftStick/left")
|
||||
.With("Right", "<Gamepad>/leftStick/right");
|
||||
ApplyGroupToLastBindings(panAction, gamepadBinding.ToString());
|
||||
|
||||
// ── Zoom(缩放:滚轮 + Ctrl热键)──
|
||||
var zoomAction = map.AddAction(
|
||||
BlueprintInputConstants.Zoom,
|
||||
type: InputActionType.Value);
|
||||
|
||||
zoomAction.AddCompositeBinding("1DAxis")
|
||||
.With("Positive", "<Mouse>/scroll/up")
|
||||
.With("Negative", "<Mouse>/scroll/down");
|
||||
ApplyGroupToLastBindings(zoomAction, binding.ToString());
|
||||
|
||||
// Ctrl 组合(多一层)
|
||||
zoomAction.AddCompositeBinding("1DAxis")
|
||||
.With("Positive", "<Keyboard>/ctrl")
|
||||
.With("Negative", "<Keyboard>/ctrl");
|
||||
ApplyGroupToLastBindings(zoomAction, binding.ToString());
|
||||
|
||||
// ── FocusHome(Ctrl + H)──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.FocusHome,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Keyboard>/h",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── Undo(Ctrl + Z)──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.Undo,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Keyboard>/z",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── Redo(Ctrl + Y)──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.Redo,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Keyboard>/y",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// ── NavigateParent(Tab)──
|
||||
map.AddAction(
|
||||
BlueprintInputConstants.NavigateParent,
|
||||
type: InputActionType.Button,
|
||||
binding: "<Keyboard>/tab",
|
||||
interactions: null,
|
||||
processors: null,
|
||||
groups: binding.ToString());
|
||||
|
||||
// 保存资产 —— .inputactions 文件需以 JSON 文本形式写入,
|
||||
// 再由 AssetDatabase.ImportAsset 触发 InputActionImporter 解析。
|
||||
string folderPath = GetSelectedFolderPath();
|
||||
string assetPath = AssetDatabase.GenerateUniqueAssetPath(
|
||||
Path.Combine(folderPath, $"{DefaultFileName}.inputactions"));
|
||||
|
||||
string json = asset.ToJson();
|
||||
System.IO.File.WriteAllText(assetPath, json);
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
var imported = AssetDatabase.LoadAssetAtPath<InputActionAsset>(assetPath);
|
||||
EditorGUIUtility.PingObject(imported);
|
||||
Debug.Log($"[Blueprint] InputAction 模板已创建: {assetPath}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 action 最后一个 binding(及所有 composite part)的 groups 设为指定值。
|
||||
/// </summary>
|
||||
private static void ApplyGroupToLastBindings(InputAction action, string groups)
|
||||
{
|
||||
int count = action.bindings.Count;
|
||||
int compositeStart = -1;
|
||||
for (int i = count - 1; i >= 0; i--)
|
||||
{
|
||||
if (action.bindings[i].isComposite)
|
||||
{
|
||||
compositeStart = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (compositeStart < 0) return;
|
||||
|
||||
for (int i = compositeStart; i < count; i++)
|
||||
action.ChangeBinding(i).WithGroup(groups);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前选中的 Project 窗口文件夹路径。
|
||||
/// </summary>
|
||||
private static string GetSelectedFolderPath()
|
||||
{
|
||||
string path = "Assets";
|
||||
var selected = Selection.activeObject;
|
||||
if (selected != null)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(selected);
|
||||
if (!string.IsNullOrEmpty(assetPath))
|
||||
{
|
||||
if (AssetDatabase.IsValidFolder(assetPath))
|
||||
return assetPath;
|
||||
return Path.GetDirectoryName(assetPath);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be6718b37ded78141820ec5058fba150
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,8 +2,8 @@
|
||||
"name": "Lrss3.SesothoLine.Editor",
|
||||
"rootNamespace": "SesothoLineEditor",
|
||||
"references": [
|
||||
"Lrss3.SesothoLine",
|
||||
"Lrss3.Deconstruction"
|
||||
"Lrss3.Deconstruction",
|
||||
"Unity.InputSystem"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user