udpate 0.6.2
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
using UnityEngine;
|
||||
using XericLibrary.Runtime.Blueprint.Render;
|
||||
|
||||
namespace XericLibrary.Runtime.Blueprint
|
||||
{
|
||||
/// <summary>
|
||||
/// QuickGraph 输入交互工具 —— 处理画布平移、缩放和节点选择。
|
||||
/// <para>中键拖拽 = 平移;左键点击 = 选择;滚轮 = 缩放。</para>
|
||||
/// <para>快捷键(新输入系统):方向键 = 平移,Ctrl+± = 缩放,Ctrl+H = 归位。</para>
|
||||
/// </summary>
|
||||
[BlueprintTool(phase: ToolPhase.PreUpdate, order: 50)]
|
||||
[BlueprintTheme("QuickGraph")]
|
||||
public class QuickGraphInputTool : BlueprintTool
|
||||
{
|
||||
// ---------- 配置(从 ToolConfigAssets 读取) ----------
|
||||
private QuickGraphInputConfig Config
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ToolConfig is QuickGraphInputConfig external)
|
||||
return external;
|
||||
if (_defaultConfig == null)
|
||||
_defaultConfig = ScriptableObject.CreateInstance<QuickGraphInputConfig>();
|
||||
return _defaultConfig;
|
||||
}
|
||||
}
|
||||
private static QuickGraphInputConfig _defaultConfig;
|
||||
|
||||
// ---------- 视图状态 ----------
|
||||
private Vector2 _targetPanOffset;
|
||||
private float _targetZoomLevel = 1f;
|
||||
private bool _viewInitialized;
|
||||
|
||||
// 用于检测帧间变化
|
||||
private Vector2 _prevPanOffset;
|
||||
private float _prevZoomLevel;
|
||||
|
||||
// ---------- 拖拽状态 ----------
|
||||
private bool _isDragging;
|
||||
private int _activeDragButton = -1;
|
||||
private Vector2 _dragStartPan;
|
||||
|
||||
// ---------- 选择状态 ----------
|
||||
private BlueprintElementBase _hoveredElement;
|
||||
private BlueprintElementBase _selectedElement;
|
||||
|
||||
// ===== 更新(平滑插值 + 键盘轮询) =====
|
||||
|
||||
public override void OnUpdate(float deltaTime)
|
||||
{
|
||||
if (Graph?.Canvas == null) return;
|
||||
|
||||
var cfg = Config;
|
||||
var canvas = Graph.Canvas;
|
||||
|
||||
// ── 同步缩放范围 ──
|
||||
canvas.MinZoom = cfg.MinZoom;
|
||||
canvas.MaxZoom = cfg.MaxZoom;
|
||||
|
||||
if (!_viewInitialized)
|
||||
{
|
||||
_targetPanOffset = canvas.PanOffset;
|
||||
_targetZoomLevel = canvas.ZoomLevel;
|
||||
_prevPanOffset = _targetPanOffset;
|
||||
_prevZoomLevel = _targetZoomLevel;
|
||||
_viewInitialized = true;
|
||||
}
|
||||
|
||||
// ── 键盘轮询(新输入系统 Pan 动作值) ──
|
||||
_targetPanOffset += BlueprintInputManager.LastPanDirection
|
||||
* cfg.KeyboardPanSpeed * deltaTime;
|
||||
|
||||
// ── 键盘轮询(新输入系统 Zoom 动作值) ──
|
||||
// zoomInput 对键盘按键是 ±1(按下一下),对轴是 0~1 连续值。
|
||||
// 统一按一个 scroll notch = 120 缩放,scale = 120 / ZoomDivisor
|
||||
float zoomInput = BlueprintInputManager.LastZoomAxis;
|
||||
if (!Mathf.Approximately(zoomInput, 0f))
|
||||
{
|
||||
float oldZoom = _targetZoomLevel;
|
||||
_targetZoomLevel = Mathf.Clamp(
|
||||
_targetZoomLevel + zoomInput / cfg.ZoomDivisor,
|
||||
canvas.MinZoom, canvas.MaxZoom);
|
||||
// 以鼠标焦点为中心缩放(键盘无光标,从鼠标读取)
|
||||
ApplyZoomFocus(ref _targetPanOffset, _targetZoomLevel, oldZoom);
|
||||
// 归零,避免持续累加
|
||||
BlueprintInputManager.LastZoomAxis = 0f;
|
||||
}
|
||||
|
||||
// ── 平滑插值到目标值 ──
|
||||
canvas.PanOffset = Vector2.Lerp(
|
||||
canvas.PanOffset, _targetPanOffset, cfg.PanLerpSpeed * deltaTime);
|
||||
canvas.ZoomLevel = Mathf.Lerp(
|
||||
canvas.ZoomLevel, _targetZoomLevel, cfg.ZoomLerpSpeed * deltaTime);
|
||||
|
||||
// ── 标记脏 ──
|
||||
if (canvas.PanOffset != _prevPanOffset || !Mathf.Approximately(canvas.ZoomLevel, _prevZoomLevel))
|
||||
{
|
||||
Graph.MarkDirty();
|
||||
_prevPanOffset = canvas.PanOffset;
|
||||
_prevZoomLevel = canvas.ZoomLevel;
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 鼠标移动 =====
|
||||
|
||||
public override void OnPointerMove(Vector2 canvasPoint, Vector2 delta)
|
||||
{
|
||||
if (Graph == null || _isDragging) return;
|
||||
|
||||
var hit = Graph.HitTest(canvasPoint);
|
||||
_hoveredElement = hit as BlueprintElementBase;
|
||||
}
|
||||
|
||||
// ===== 鼠标按下 =====
|
||||
|
||||
public override void OnPointerDown(Vector2 canvasPoint, int mouseButton)
|
||||
{
|
||||
if (Graph == null) return;
|
||||
|
||||
if (mouseButton == 2) // 中键 → 平移
|
||||
{
|
||||
_isDragging = true;
|
||||
_activeDragButton = 2;
|
||||
_dragStartPan = _targetPanOffset;
|
||||
}
|
||||
// 左键点击选择由元素层的 IBlueprintEventHandler.OnPointerDown 处理
|
||||
}
|
||||
|
||||
// ===== 鼠标释放 =====
|
||||
|
||||
public override void OnPointerUp(Vector2 canvasPoint, int mouseButton)
|
||||
{
|
||||
if (_isDragging && _activeDragButton == mouseButton)
|
||||
{
|
||||
_isDragging = false;
|
||||
_activeDragButton = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 拖拽 =====
|
||||
|
||||
public override void OnPointerDrag(Vector2 canvasPoint, Vector2 delta, int mouseButton)
|
||||
{
|
||||
if (Graph?.Canvas == null) return;
|
||||
|
||||
if (mouseButton == 2) // 中键拖拽 = 平移
|
||||
{
|
||||
_targetPanOffset += delta * Graph.Canvas.ZoomLevel;
|
||||
Graph.MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 滚轮 =====
|
||||
|
||||
public override void OnScroll(Vector2 canvasPoint, Vector2 scrollDelta)
|
||||
{
|
||||
if (Graph == null) return;
|
||||
|
||||
float oldZoom = _targetZoomLevel;
|
||||
|
||||
_targetZoomLevel = Mathf.Clamp(
|
||||
_targetZoomLevel + scrollDelta.y / Config.ZoomDivisor,
|
||||
Graph.Canvas.MinZoom, Graph.Canvas.MaxZoom);
|
||||
|
||||
if (!Mathf.Approximately(oldZoom, _targetZoomLevel))
|
||||
{
|
||||
// 以鼠标光标为中心缩放
|
||||
_targetPanOffset += canvasPoint * (oldZoom - _targetZoomLevel);
|
||||
Graph.MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 快捷键(仅新输入系统) =====
|
||||
|
||||
public override void OnAction(string actionName)
|
||||
{
|
||||
if (Graph?.Canvas == null) return;
|
||||
|
||||
switch (actionName)
|
||||
{
|
||||
case BlueprintInputConstants.FocusHome:
|
||||
ResetView();
|
||||
break;
|
||||
case BlueprintInputConstants.Undo:
|
||||
break; // TODO
|
||||
case BlueprintInputConstants.Redo:
|
||||
break; // TODO
|
||||
case BlueprintInputConstants.NavigateParent:
|
||||
break; // TODO
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 辅助 =====
|
||||
|
||||
public void ResetView()
|
||||
{
|
||||
_targetPanOffset = Vector2.zero;
|
||||
_targetZoomLevel = 1f;
|
||||
Graph?.MarkDirty();
|
||||
}
|
||||
|
||||
private void SelectElement(BlueprintElementBase element)
|
||||
{
|
||||
_selectedElement = element;
|
||||
}
|
||||
|
||||
/// <summary>当前悬停的元素(可能为 null)</summary>
|
||||
public BlueprintElementBase HoveredElement => _hoveredElement;
|
||||
|
||||
/// <summary>当前选中的元素(可能为 null)</summary>
|
||||
public BlueprintElementBase SelectedElement => _selectedElement;
|
||||
|
||||
// ===== 以鼠标焦点为中心缩放(键盘调用 — 自行读取鼠标位置) =====
|
||||
|
||||
private void ApplyZoomFocus(ref Vector2 panOffset, float newZoom, float oldZoom)
|
||||
{
|
||||
if (Graph?.Canvas == null) return;
|
||||
|
||||
// 通过 BlueprintUGUIInputManager 获取统一鼠标位置(已被 BlueprintInputReceiver 每帧刷新)
|
||||
Vector2 canvasCursor = Graph.Canvas.ScreenToCanvas(BlueprintUGUIInputManager.MousePosition);
|
||||
panOffset += canvasCursor * (oldZoom - newZoom);
|
||||
}
|
||||
|
||||
// =====(旧 ZoomFocusAdjust 已删除 — 替代为 ApplyZoomFocus,OnScroll 直接内联 canvasPoint 计算)=====
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user