E Story 故事编辑器开发笔记 #8 创建和删除连线

创建连线

通过视图操作创建

打开StoryGraphView.cs,新增以下方法,随后在目标节点的某个端口上按住鼠标左键不松,移动到另一个节点的端口上松开即可创建连线:

C#
public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter)
{
    // 获取所有端口
    List result = ports.ToList();
    // 执行筛选
    result = result.Where
    (
                   // 两个端口的逻辑方向不能相同(即数据流向是输入还是输出)
        endport => endport.direction != startPort.direction 
                   // 两个端口不能为同一个端口
                   && endport.node != startPort.node
    ).ToList();

    return result;
}

通过代码创建

打开StoryGraphView.cs,新增以下方法,随后在有需要的地方调用即可:

C#
// 创建连线
public Edge CreateEdge(Port lastOutput, Port nextInput)
{
    Edge edge = lastOutput.ConnectTo(nextInput);
    AddElement(edge);
    return edge;
}

删除连线

选中连线后直接删除

选中要删除的连线,直接点击键盘Delete键,或点击鼠标右键弹出上下文菜单后再点击Delete按钮即可删除。

删除节点时自动删除

在删除了某个节点后,与此节点相关的连线会自动删除。

选中节点后手动删除

打开BaseNode.cs,新增以下方法:

C#
// 绘制上下文菜单
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
    evt.menu.AppendAction("清除输入连接",
        action => DisconnectedInputPorts(),
        HasInputConnection() ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);

    evt.menu.AppendAction("清除输出连接",
        action => DisconnectedOutputPorts(),
        HasOutputConnection() ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);

    evt.menu.AppendAction("清除所有连接",
        action => DisconnectedAllPorts(),
        HasAnyConnection() ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);

    evt.menu.AppendSeparator();
}

// 是否有任何连接
public bool HasAnyConnection()
{
    return HasInputConnection() || HasOutputConnection();
}

// 是否有上行连接
public bool HasInputConnection()
{
    if (inputContainer.childCount == 0)
    {
        return false;
    }

    Port port = (Port)inputContainer.Children().First();
    return port.connected;
}

// 是否有下行连接
public bool HasOutputConnection()
{
    if (outputContainer.childCount == 0)
    {
        return false;
    }

    foreach (Port port in outputContainer.Children().ToList())
    {
        if (port.connected)
        {
            return true;
        }
    }

    return false;
}

// 断开所有连接
public void DisconnectedAllPorts()
{
    DisconnectedInputPorts();
    DisconnectedOutputPorts();
}

// 断开输入连接
private void DisconnectedInputPorts()
{
    DisconnectPorts(inputContainer);
}

// 断开输出连接
private void DisconnectedOutputPorts()
{
    DisconnectPorts(outputContainer);
}

// 断开目标端口连接
private void DisconnectPorts(VisualElement container)
{
    foreach (Port port in container.Children())
    {
        DisconnectPort(port);
    }
}

// 断开目标端口连接
protected void DisconnectPort(Port port)
{
    if (port.connected)
    {
        graphView.DeleteElements(port.connections.ToList());
    }
}

测试效果

最终窗口效果如下:

相关链接

留下评论