当前位置: 首页 > 工具软件 > GraphView > 使用案例 >

Unity Event Graph: GraphView

夏侯旻
2023-12-01

Field&Property

/// <summary>
/// GraphWindow
/// </summary>
private GraphWindow m_GraphWindow;
/// <summary>
/// Node搜索窗口
/// </summary>
private SearchWindowProvider m_SearchWindow;
/// <summary>
/// 每个Node的NodeView
/// </summary>
public Dictionary<Node, NodeView> nodeViewsPerNode = new Dictionary<Node, NodeView>();
/// <summary>
/// Graph
/// </summary>
public Graph graph { get { return m_GraphWindow.graph; } }

public GraphView()
{
    viewTransformChanged += ViewTransformChangedCallback;
    graphViewChanged += GraphViewChangedCallback;
    AddManipulators();
    InitializeView();

    Undo.undoRedoPerformed += Reload;
}
~GraphView()
{
    Undo.undoRedoPerformed -= Reload;
}

Method

AddManipulators

/// <summary>
/// 添加鼠标操作到窗口
/// </summary>
private void AddManipulators()
{
    this.AddManipulator(new ContentDragger());
    this.AddManipulator(new SelectionDragger());
    this.AddManipulator(new RectangleSelector());
    this.AddManipulator(new ClickSelector());
}

InitializeView

/// <summary>
/// 初始化窗口
/// </summary>
private void InitializeView()
{
    //加载USS文件
    this.styleSheets.Add(Resources.Load<StyleSheet>("GraphView"));

    //网格背景
    GridBackground gridBackground = new GridBackground();
    gridBackground.name = "GridBackground";
    Insert(0, gridBackground);

    //设施缩放的范围
    this.SetupZoom(0.5f, 2.0f);

    //填充整个窗口
    this.StretchToParentSize();

    //添加创建Node搜索窗口
    m_SearchWindow = new SearchWindowProvider();
    m_SearchWindow.OnSelect = OnSelect;
    nodeCreationRequest = (NodeCreationContext context) =>
    { SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), m_SearchWindow); };
}

Initialize

/// <summary>
/// 初始化Graph
/// </summary>
/// <param name="graphWindow"></param>
public void Initialize(GraphWindow graphWindow)
{
    m_GraphWindow = graphWindow;

    UpdateViewTransform(graph.position, graph.scale);
    Reload();
}

Reload

/// <summary>
/// 重新绘制用于撤销回调
/// </summary>
public void Reload()
{
    Debug.Log("Reload");

    RemoveNodeView();
    RemovePortView();

    InitializeNodeView();
    InitializePortView();
}

RemoveNodeView

/// <summary>
/// 移除所有NodeView
/// </summary>
public void RemoveNodeView()
{
    foreach (var node in nodeViewsPerNode)
    {
        NodeView nodeView = node.Value;
        nodeView.OnRemove();
        RemoveElement(nodeView);
    }
    nodeViewsPerNode.Clear();
}

RemovePortView

/// <summary>
/// 移除所有NodeView
/// </summary>
public void RemovePortView()
{
    var edges = this.edges;
    edges.ForEach((edge) =>
    {
        RemoveElement(edge);
    });
}

InitializeNodeView

/// <summary>
/// 初始化所有NodeView
/// </summary>
public void InitializeNodeView()
{
    var nodes = graph.GetComponentsInChildren<Node>();
    foreach (var node in nodes)
    {
        var nodeView = AddNodeView(node, node.position);
        nodeView.Initialize(node, this);
        nodeViewsPerNode.Add(node, nodeView);
    }
}

InitializePortView

/// <summary>
/// 初始化所有PortView
/// </summary>
public void InitializePortView()
{
    foreach (var node in nodeViewsPerNode)
    {
        node.Value.InitializePortView();
    }
}

OnSelect

/// <summary>
/// 当选择创建Node时
/// </summary>
/// <param name="SearchTreeEntry"></param>
/// <param name="context"></param>
/// <returns></returns>
private bool OnSelect(SearchTreeEntry SearchTreeEntry, SearchWindowContext context)
{
    var node = AddNode(SearchTreeEntry.userData as Type);

    var windowRoot = m_GraphWindow.rootVisualElement;
    var windowMousePosition = windowRoot.ChangeCoordinatesTo(windowRoot.parent, context.screenMousePosition - m_GraphWindow.position.position);
    var graphMousePosition = this.contentViewContainer.WorldToLocal(windowMousePosition);

    var nodeView = AddNodeView(node, graphMousePosition);
    nodeViewsPerNode.Add(node, nodeView);

    return true;
}

AddNode

/// <summary>
/// 添加Node
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
Node AddNode(Type type)
{
    var obj = new GameObject(type.Name);
    Undo.RegisterCreatedObjectUndo(obj, $"Create:{obj.name}");

    var component = obj.AddComponent(type);

    obj.transform.parent = graph.transform;

    return component as Node;
}

AddNodeView

/// <summary>
/// 添加NodeView
/// </summary>
/// <param name="node"></param>
/// <param name="pos"></param>
/// <returns></returns>
NodeView AddNodeView(Node node, Vector2 pos)
{
    Type nodeViewType = m_SearchWindow.GetNodeView(node.GetType());
    var nodeView = System.Activator.CreateInstance(nodeViewType) as NodeView;

    nodeView.Initialize(node, this);
    nodeView.SetPosition(new Rect(pos, new Vector2(100, 100)));
    nodeView.RefreshPorts();
    nodeView.RefreshExpandedState();

    AddElement(nodeView);
    return nodeView;
}

GetCompatiblePorts

/// <summary>
/// 当选择Port是返回所有可以连接的Port
/// </summary>
/// <param name="startPort"></param>
/// <param name="nodeAdapter"></param>
/// <returns></returns>
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter)
{
    return base.GetCompatiblePorts(startPort, nodeAdapter);
}

ViewTransformChangedCallback

/// <summary>
/// 移动缩放回调
/// </summary>
/// <param name="graphView"></param>
private void ViewTransformChangedCallback(GraphViewBase graphView)
{
    Undo.RecordObject(graph, $"{graph.name} Transform Change");

    graph.position = graphView.viewTransform.position;
    graph.scale = graphView.viewTransform.scale;

    EditorUtility.SetDirty(graph);
}

GraphViewChangedCallback

/// <summary>
/// 当界面变化是回调
/// </summary>
/// <param name="graphViewChange"></param>
/// <returns></returns>
private GraphViewChange GraphViewChangedCallback(GraphViewChange graphViewChange)
{
    return graphViewChange;
}

BuildContextualMenu

/// <summary>
/// 添加右键菜单事件
/// </summary>
/// <param name="evt"></param>
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
    base.BuildContextualMenu(evt);
    evt.menu.AppendAction("Test", TestBuildContextualMenu);
}

/// <summary>
/// 右键菜单Test
/// </summary>
/// <param name="obj"></param>
private void TestBuildContextualMenu(DropdownMenuAction obj)
{
    Debug.Log("右键菜单Test");
}

 类似资料:

相关阅读

相关文章

相关问答