ue4绘制线的三种方式

第一种方式,是用样条线,简明扼要,但是打包后就消失了。

	AActor* actor = world->SpawnActor< AActor>(ActorClass);
	actor->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
	USplineComponent* splineComponent = this->GenerateSplineComponent(info, radius,actor);
	splineComponent->AttachToComponent(actor->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
	TArray<FVector> posArray;
			USplineComponent* splineComponent = this->GenerateSplineComponent(posArray,actor);
	splineComponent->AttachToComponent(actor->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);

USplineComponent* MyActor::GenerateSplineComponent(TArray< FVector> posArray, AActor* actor)
{

TArray<FVector> posXYZArray;
USplineComponent* splineTrack = NewObject<USplineComponent>(actor, TEXT("Spline"));
splineTrack->RegisterComponent();
//设置样本条的颜色
splineTrack->SetUnselectedSplineSegmentColor(FLinearColor(0.0f, 0.0f, 1.0f));
//设置样条线的粗细或者宽度
splineTrack->ScaleVisualizationWidth = 70.0f;
splineTrack->SetSplineLocalPoints(posArray);
splineTrack->SetDrawDebug(true);
splineTrack->UpdateSpline();
splineTrack->SetHiddenInGame(false);

return splineTrack;

}

第二种方式是用ULineBatchComponent画线,这个是世界坐标系的,也就是说,即使父子节点,也不能用相对位置。好处是,是实体,可以从样条线中获取位置。关键就在于FSplinePositionLinearApproximation::Build()这个方法。这个方法有三个参数,第三个参数,可以在保持曲线不变的情况下,控制点的数量,这就很好了,比如,如果近处需要100个点,那么远处10个点就Ok了。

ULineBatchComponent* MyActor::GetBatchLineComponentFromSplineComponent(
AActor* parentActor,
USplineComponent* splineComponent)
{
if (nullptr == splineComponent)
{
return nullptr;
}
TArray< FSplinePositionLinearApproximation> outputSpline;
outputSpline.Empty();
FSplinePositionLinearApproximation::Build(splineComponent->SplineCurves, outputSpline);
int pointNumber = outputSpline.Num();
if ( 0 == pointNumber)
{
return nullptr;
}

ULineBatchComponent* lineBatchComponent = NewObject<ULineBatchComponent>(parentActor, TEXT("Line"));
lineBatchComponent->RegisterComponent();
TArray<FBatchedLine> batchLineArray;
batchLineArray.Empty();
for (int ptID = 0; ptID < pointNumber - 1; ptID++)
{
	
	FVector line_startPos = outputSpline[ptID].Position + _worldLocation;
	FVector line_endPos = outputSpline[ptID+1].Position + _worldLocation;

	FBatchedLine line = FBatchedLine(line_startPos, line_endPos, FLinearColor::Red, 0, 10, 0);
	batchLineArray.Add(line);
}
lineBatchComponent->BatchedLines.Empty();
lineBatchComponent->DrawLines(batchLineArray);

return lineBatchComponent;

}

void FSplinePositionLinearApproximation::Build(const FSplineCurves& InCurves, TArray< FSplinePositionLinearApproximation>& OutPoints, float InDensity)
{
OutPoints.Reset();

const float SplineLength = InCurves.GetSplineLength();
int32 NumLinearPoints = FMath::Max((int32)(SplineLength * InDensity), 2);

for (int32 LinearPointIndex = 0; LinearPointIndex < NumLinearPoints; ++LinearPointIndex)
{
	const float DistanceAlpha = (float)LinearPointIndex / (float)NumLinearPoints;
	const float SplineDistance = SplineLength * DistanceAlpha;
	const float Param = InCurves.ReparamTable.Eval(SplineDistance, 0.0f);
	OutPoints.Emplace(InCurves.Position.Eval(Param, FVector::ZeroVector), Param);
}

OutPoints.Emplace(InCurves.Position.Points.Last().OutVal, InCurves.ReparamTable.Points.Last().OutVal);

}

第三个方式就是用USplineMeshComponent,按照样条线的各段生成mesh就可以了。

void MyActor::GenerateSplineMeshComponentFromSplineComponent(AActor* parentActor, USplineComponent* splineComponent)
{
if (nullptr == splineComponent)
{
return ;
}
for (int i = 0; i < splineComponent->GetNumberOfSplinePoints() - 1; i++)
{
USplineMeshComponent* splineMesh = NewObject< USplineMeshComponent>(parentActor, TEXT(“SplineMesh” + i));
splineMesh->RegisterComponent();
splineMesh->AttachToComponent(parentActor->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
splineMesh->SetStaticMesh(_splineStaticMesh);

	splineMesh->SetMobility(EComponentMobility::Type::Movable);
	FVector pointLocationStart, pointTangentStart, pointLocationEnd, pointTangentEnd;
	splineComponent->GetLocalLocationAndTangentAtSplinePoint(i, pointLocationStart, pointTangentStart);
	splineComponent->GetLocalLocationAndTangentAtSplinePoint(i + 1, pointLocationEnd, pointTangentEnd);

	splineMesh->SetStartAndEnd(pointLocationStart, pointTangentStart, pointLocationEnd, pointTangentEnd);
}

}

猜你喜欢

转载自blog.csdn.net/directx3d_beginner/article/details/126418815
今日推荐