1.3 从0创建蓝图编辑器-创建节点之间的连接线

一、让节点可以相互连接

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_MAKEAB能随意连接(N:N)
CONNECT_RESPONSE_DISALLOWAB不能连接(0:0)
CONNECT_RESPONSE_BREAK_OTHERS_AA只能连接一次(1:N)
CONNECT_RESPONSE_BREAK_OTHERS_BB只能连接一次(N:1)
CONNECT_RESPONSE_BREAK_OTHERS_ABAB都只能连接一次(1:1)
CONNECT_RESPONSE_MAKE_WITH_CONVERSION_NODE通过中间强制转换节点或其他转换节点进行连接

结果:

CONNECT_RESPONSE_MAKE在这里插入图片描述

二、设置连接线样式

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()——逻辑处理

前三节类、函数关系梳理:XMind

类、函数之间的关系梳理

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值