// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/SplineComponent.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MeshMovingOnSplineClass.generated.h"
/**
*
*/
UCLASS()
class TCPCONNENT_API UMeshMovingOnSplineClass : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static void MeshOnSplineMoving(int32 MeshCount,UInstancedStaticMeshComponent* InstancedStaticMesh,USplineComponent* spline,float Speed = 1);
static FTransform SpawnTransform;
static float InitSpeed;
static FVector SplineVector;
static FRotator SplineRotator;
static FVector SplineScale;
static FTransform UpdateTransform;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "MeshMovingOnSplineClass.h"
#include "Components/InstancedStaticMeshComponent.h"
float UMeshMovingOnSplineClass::InitSpeed;
FTransform UMeshMovingOnSplineClass::SpawnTransform;
FVector UMeshMovingOnSplineClass::SplineVector;
FRotator UMeshMovingOnSplineClass::SplineRotator;
FVector UMeshMovingOnSplineClass::SplineScale = FVector(1,1,1);
FTransform UMeshMovingOnSplineClass::UpdateTransform;
void UMeshMovingOnSplineClass::MeshOnSplineMoving(int32 MeshCount, UInstancedStaticMeshComponent* InstancedStaticMesh,
USplineComponent* spline, float Speed)
{
if (InstancedStaticMesh->GetInstanceCount() < MeshCount)
{
for (int i = InstancedStaticMesh->GetInstanceCount(); i < MeshCount; i++)
{
InstancedStaticMesh->AddInstance(SpawnTransform,true);
}
}
InitSpeed = InitSpeed + Speed;
for (int j = 0; j < MeshCount; j++)
{
float AA = spline->GetSplineLength() / MeshCount;
float BB = j * AA;
float CC = BB + InitSpeed;
float DD = fmodf(CC,spline->GetSplineLength());
SplineVector = spline->GetWorldLocationAtDistanceAlongSpline(DD);
SplineRotator = spline->GetWorldRotationAtDistanceAlongSpline(DD);
UpdateTransform.SetLocation(SplineVector);
UpdateTransform.SetRotation(SplineRotator.Quaternion());
UpdateTransform.SetScale3D(SplineScale);
InstancedStaticMesh->UpdateInstanceTransform(j,UpdateTransform,true,true,false);
}
}
if (InstancedStaticMesh->GetInstanceCount() < MeshCount)
{
for (int i = InstancedStaticMesh->GetInstanceCount(); i < MeshCount; i++)
{
InstancedStaticMesh->AddInstance(SpawnTransform, true);
}
}
InitSpeed = InitSpeed + Speed;
float AA;
float BB;
float CC;
float DD;
if (Speed >= 0)
{
// Speed为正数,向前循环移动逻辑
for (int j = 0; j < MeshCount; j++)
{
AA = spline->GetSplineLength() / MeshCount;
BB = j * AA;
CC = BB + InitSpeed;
DD = fmodf(CC, spline->GetSplineLength());
SplineVector = spline->GetWorldLocationAtDistanceAlongSpline(DD);
SplineRotator = spline->GetWorldRotationAtDistanceAlongSpline(DD);
UpdateTransform.SetLocation(SplineVector);
UpdateTransform.SetRotation(SplineRotator.Quaternion());
UpdateTransform.SetScale3D(SplineScale);
InstancedStaticMesh->UpdateInstanceTransform(j, UpdateTransform, true, true, false);
}
}
else
{
// Speed为负数,向后循环移动逻辑
for (int j = MeshCount - 1; j >= 0; j--)
{
AA = spline->GetSplineLength() / MeshCount;
BB = (MeshCount - 1 - j) * AA;
CC = spline->GetSplineLength() - (BB + (-InitSpeed));
DD = fmodf(CC, spline->GetSplineLength());
SplineVector = spline->GetWorldLocationAtDistanceAlongSpline(DD);
SplineRotator = spline->GetWorldRotationAtDistanceAlongSpline(DD);
UpdateTransform.SetLocation(SplineVector);
UpdateTransform.SetRotation(SplineRotator.Quaternion());
UpdateTransform.SetScale3D(SplineScale);
InstancedStaticMesh->UpdateInstanceTransform(j, UpdateTransform, true, true, false);
}
}
正反方向循环移动
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/SplineComponent.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"
/**
*
*/
UCLASS()
class TANKCARBIG_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static void MeshOnSplineMoving(int32 MeshCount,UInstancedStaticMeshComponent* InstancedStaticMesh,USplineComponent* spline,float Speed = 1);
static FTransform SpawnTransform;
static float InitSpeed;
static FVector SplineVector;
static FRotator SplineRotator;
static FVector SplineScale;
static FTransform UpdateTransform;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyBlueprintFunctionLibrary.h"
#include "Components/InstancedStaticMeshComponent.h"
float UMyBlueprintFunctionLibrary::InitSpeed;
FTransform UMyBlueprintFunctionLibrary::SpawnTransform;
FVector UMyBlueprintFunctionLibrary::SplineVector;
FRotator UMyBlueprintFunctionLibrary::SplineRotator;
FVector UMyBlueprintFunctionLibrary::SplineScale = FVector(1,1,1);
FTransform UMyBlueprintFunctionLibrary::UpdateTransform;
void UMyBlueprintFunctionLibrary::MeshOnSplineMoving(int32 MeshCount,
UInstancedStaticMeshComponent* InstancedStaticMesh, USplineComponent* spline, float Speed)
{
if (InstancedStaticMesh->GetInstanceCount() < MeshCount)
{
for (int i = InstancedStaticMesh->GetInstanceCount(); i < MeshCount; i++)
{
InstancedStaticMesh->AddInstance(SpawnTransform, true);
}
}
InitSpeed = InitSpeed + Speed;
for (int j = (Speed >= 0? 0 : MeshCount - 1);
(Speed >= 0 && j < MeshCount) || (Speed < 0 && j >= 0);
j += (Speed >= 0? 1 : -1))
{
float AA = spline->GetSplineLength() / MeshCount;
float BB;
float CC;
float DD;
if (Speed >= 0)
{
// Speed为正数,向前循环移动逻辑
BB = j * AA;
CC = BB + InitSpeed;
DD = fmodf(CC, spline->GetSplineLength());
}
else
{
// Speed为负数,向后循环移动逻辑
// 考虑Speed绝对值较大时的情况,先计算理论上的累计偏移量
float totalOffset = (-InitSpeed) + ((MeshCount - 1 - j) * AA);
// 处理循环,确保总偏移量在样条线长度范围内
totalOffset = fmodf(totalOffset, spline->GetSplineLength());
// 计算实际位置,从样条线末尾往前推
CC = spline->GetSplineLength() - totalOffset;
DD = fmodf(CC, spline->GetSplineLength());
BB = (MeshCount - 1 - j) * AA;
}
// 获取当前实例在样条线上的位置和旋转
SplineVector = spline->GetWorldLocationAtDistanceAlongSpline(DD);
SplineRotator = spline->GetWorldRotationAtDistanceAlongSpline(DD);
// 设置更新实例的变换
UpdateTransform.SetLocation(SplineVector);
UpdateTransform.SetRotation(SplineRotator.Quaternion());
UpdateTransform.SetScale3D(SplineScale);
// 更新实例的变换
InstancedStaticMesh->UpdateInstanceTransform(j, UpdateTransform, true, true, false);
}
}