一、让节点可以相互连接
UTestGraphSchema重写CanCreateConnection函数制定连接规则
TestGraphSchema.h
/**
* Determine if a connection can be created between two pins.
* @param A The first pin.
* @param B The second pin.
* @return An empty string if the connection is legal, otherwise a message describing why the connection would fail.
*/
// 制定Pin之间的连接规则.
virtual const FPinConnectionResponse CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const override;
TestGraphSchema.cpp
const FPinConnectionResponse UTestGraphSchema::CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const
{
//ECanCreateConnectionResponse类型制定两个Pin之间的连接方式
return FPinConnectionResponse(CONNECT_RESPONSE_MAKE, TEXT("can implemented by this schema"));
}
ECanCreateConnectionResponse
ECanCreateConnectionResponse | 描述 |
---|---|
CONNECT_RESPONSE_MAKE | AB能随意连接(N:N) |
CONNECT_RESPONSE_DISALLOW | AB不能连接(0:0) |
CONNECT_RESPONSE_BREAK_OTHERS_A | A只能连接一次(1:N) |
CONNECT_RESPONSE_BREAK_OTHERS_B | B只能连接一次(N:1) |
CONNECT_RESPONSE_BREAK_OTHERS_AB | AB都只能连接一次(1:1) |
CONNECT_RESPONSE_MAKE_WITH_CONVERSION_NODE | 通过中间强制转换节点或其他转换节点进行连接 |
结果:
二、设置连接线样式
1、新建一个None类,手动继承自 FConnectionDrawingPolicy
警告:
应在.cs文件中添加GraphEditor模块才能正常继承自FConnectionDrawingPolicy
FConnectionDrawingPolicy不属于UObject体系
MyConnectionDrawingPolicy.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "ConnectionDrawingPolicy.h"
/**
*
* need include module:"GraphEditor"
*/
class TESTGRAPHANDBLUEPRINT_API FMyConnectionDrawingPolicy:public FConnectionDrawingPolicy
{
public:
/**
* @Param InBackLayerID 线的ID
* @Param InFrontLayerID 箭头ID
* @Param InZoomFactor 缩放系数
* @Param InClippingRect 当前视口
* @Param InDrawElements 要绘制的元素
* @Param InGraphObj 所属图表
*/
FMyConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements,UEdGraph *InGraphObj);
virtual ~FMyConnectionDrawingPolicy();
// Give specific editor modes a chance to highlight this connection or darken non-interesting connections
//线的外观
virtual void DetermineWiringStyle(UEdGraphPin* OutputPin, UEdGraphPin* InputPin, /*inout*/ FConnectionParams& Params) override;
//线的逻辑
virtual void DrawConnection(int32 LayerId, const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params) override;
protected:
UEdGraph* GraphObj;
TMap<UEdGraphNode*, int32> EdNodeWidgetMap;
};
MyConnectionDrawingPolicy.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "FMyConnectionDrawingPolicy.h"
#include "ConnectionDrawingPolicy.h"
#include "EdGraph/EdGraph.h"
#include "DrawElements.h"
static const FLinearColor DefaultWiringColor(1.f, 0.f, 0.f);
FMyConnectionDrawingPolicy::FMyConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj)
:FConnectionDrawingPolicy(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements), GraphObj(InGraphObj)
{
}
FMyConnectionDrawingPolicy::~FMyConnectionDrawingPolicy()
{
}
void FMyConnectionDrawingPolicy::DetermineWiringStyle(UEdGraphPin* OutputPin, UEdGraphPin* InputPin, FConnectionParams& Params)
{
Params.WireThickness = 5.f;
Params.WireColor = DefaultWiringColor;
#if 0
//限制淡化效果只有在拖动线时才出现,使平时指向箭头处无用
if (HoveredPins.Num()>0)
{
//当鼠标处在箭头处时提供淡化颜色和增加线条宽度的效果
ApplyHoverDeemphasis(OutputPin, InputPin, Params.WireThickness, Params.WireColor);
}
#endif
}
void FMyConnectionDrawingPolicy::DrawConnection(int32 LayerId, const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params)
{
//获取起点终点距离
const FVector2D Delta = End - Start;
const FVector2D DirDelta = Delta.GetSafeNormal();
//设置粗细颜色
FLinearColor WireColor = FLinearColor::Blue;
//画线
FSlateDrawElement::MakeDrawSpaceSpline(
DrawElementsList, //视口元素
LayerId, //层级ID
Start, DirDelta, //开始Pos,开始Direction
End, DirDelta, //结束Pos,结束Direction
Params.WireThickness, //粗细
ESlateDrawEffect::None, //
Params.WireColor //颜色
);
//制作动态效果
#if 1
//生成一个从起点到终点的样条曲线SplineReparamTable,并获取该样条曲线长度SplineLength
FInterpCurve<float> SplineReparamTable;
float SplineLength = MakeSplineReparamTable(Start, DirDelta, End, DirDelta, SplineReparamTable);
//计算气泡间隔、速度、大小
const float BubbleSpacing = 40.f * ZoomFactor;
const float BubbleSpeed = 100.f * ZoomFactor;
const FVector2D BubbleSize = BubbleImage->ImageSize * ZoomFactor * 0.2f * Params.WireThickness;
//渲染时间 = 渲染完成时时间-渲染开始时时间
float DeltaTime = (FPlatformTime::Seconds() - GStartTime);
//偏移
//Fmod(A,B) 将A/B的结果转变为一段一段的值(1/2=0 , 2/1=2, 2.5/1=2)
const float BubbleOffset = FMath::Fmod(DeltaTime * BubbleSpeed, BubbleSpacing);
//气泡数量
const int32 BubblesNum = FMath::CeilToInt(SplineLength / BubbleSpacing);
//气泡绘制
for (int32 i = 0; i < BubblesNum; ++i) {
const float Distance = ((float)i * BubbleSpacing) + BubbleOffset;
if (Distance<SplineLength)
{
const float Alpha = SplineReparamTable.Eval(Distance, 0.f);
FVector2D BubblePos = FMath::CubicInterp(Start, DirDelta, End, DirDelta, Alpha);
BubblePos -= (BubbleSize * 0.5f);
FSlateDrawElement::MakeBox(
DrawElementsList,
LayerId,
FPaintGeometry(BubblePos, BubbleSize, ZoomFactor),
BubbleImage,
ESlateDrawEffect::None,
Params.WireColor
);
}
}
#endif
}
结果:
附
Tips:
DetermineWiringStyle()的功能更多地是为DrawConnection()准备连接线的各项参数。
DetermineWiringStyle()——数据准备,DrawConnection()——逻辑处理