大家都知道在U3D瞬移很好做,用steamvr提供的脚本或者用VRTK加上寻路网格就可以轻松完成
那么在UE4中呢
下面我们共同研究一线 在UE4中如何利用寻路网格做vr瞬移
首先构建一个C++类继承于SceneComponent类
我将其命名为RunebergVR_Teleporter
讲头文件改为
include “Components/ActorComponent.h”
include “Components/SplineComponent.h”
include “Components/SplineMeshComponent.h”
include “RunebergVR_Teleporter.generated.h”
为了省事。。额。。我还是决定上代码吧
头文件如下利用SplineMesh的特性形成弯曲的曲线,在CPP中实现具体实现原始点到终点的弯曲
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Components/ActorComponent.h"
#include "Components/SplineComponent.h"
#include "Components/SplineMeshComponent.h"
#include "RunebergVR_Teleporter.generated.h"
UENUM(BlueprintType)
enum class EMoveDirectionEnum : uint8
{
MOVE_FORWARD UMETA(DisplayName = "Towards Player"),
MOVE_BACKWARD UMETA(DisplayName = "Away from Player"),
MOVE_LEFT UMETA(DisplayName = "Left of Player"),
MOVE_RIGHT UMETA(DisplayName = "Right of Player"),
MOVE_CUSTOM UMETA(DisplayName = "Use a Custom Rotation for Direction")
};
UCLASS(ClassGroup = (VR), meta = (BlueprintSpawnableComponent))
class VRTELEP_API URunebergVR_Teleporter : public USceneComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
URunebergVR_Teleporter();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
// The teleport beam's mesh
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Beam Parameters")
class UStaticMesh* TeleportBeamMesh = nullptr;
/** The teleport beam's Launch Velocity Magnitude - higher number increases range of teleport */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Beam Parameters")
float BeamMagnitude = 500.f;
/** A location offset from the parent mesh origin where the teleport beam will start */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Beam Parameters")
FVector BeamLocationOffset = FVector::ZeroVector;
/** For ray type beam, ensure the lenth of the beam reaches target location instantenously. Uses RayScaleRate as base length unit */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Beam Parameters")
bool RayInstantScale = true;
/** How much the ray will scale up until it reaches target location */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Beam Parameters")
float RayScaleRate = 1.f;
/** The teleport beam's navigation mesh tolerance - fine tune to fit your nav mesh bounds */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Beam Parameters")
FVector BeamHitNavMeshTolerance = FVector(10.f, 10.f, 10.f);
/** The teleport beam's custom gravity */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Beam Parameters")
float ArcOverrideGravity = 0.f;
// The teleport target stuff
/** Additional offset of pawn (internal offsets are Steam: 112, Rift: 250) */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Target Parameters")
FVector TeleportTargetPawnSpawnOffset = FVector(0.f, 0.f, 0.f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Target Parameters")
float FloorIsAtZ = 0.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Target Parameters")
class UStaticMesh* TeleportTargetMesh = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Target Parameters")
FVector TeleportTargetMeshScale = FVector(1.f, 1.f, 1.f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Target Parameters")
FVector TeleportTargetMeshSpawnOffset = FVector(0.f, 0.f, 5.f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Target Parameters")
class UParticleSystem* TeleportTargetParticle = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Target Parameters")
FVector TeleportTargetParticleScale = FVector(1.f, 1.f, 1.f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR - Teleport Target Parameters")
FVector TeleportTargetParticleSpawnOffset = FVector(0.f, 0.f, 0.f);
/** Check to see if an active teleport mode is turned on */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "VR - Read Only")
bool IsTeleporting = false;
// Show the teleportation arc trace
UFUNCTION(BlueprintCallable, Category = "VR")
bool ShowTeleportArc();
// Show the teleportation ray trace
UFUNCTION(BlueprintCallable, Category = "VR")
bool ShowTeleportRay();
// Remove the teleportation arc trace
UFUNCTION(BlueprintCallable, Category = "VR")
bool HideTeleportArc();
// Remove the teleportation ray trace
UFUNCTION(BlueprintCallable, Category = "VR")
bool HideTeleportRay();
// Show marker in the world
UFUNCTION(BlueprintCallable, Category = "VR")
bool ShowMarker();
// Move Marker
UFUNCTION(BlueprintCallable, Category = "VR")
bool MoveMarker(EMoveDirectionEnum MarkerDirection = EMoveDirectionEnum::MOVE_FORWARD, int Rate = 25, FRotator CustomDirection = FRotator::ZeroRotator);
// Remove marker
UFUNCTION(BlueprintCallable, Category = "VR")
bool HideMarker();
// Teleport
UFUNCTION(BlueprintCallable, Category = "VR")
bool TeleportNow();
private:
// Teleport target height offset - defaults to SteamVR
FVector PawnHeightOffset = FVector(0.f, 0.f,0.f);
// Teleport targetting mode
int TeleportMode = -1;
// Teleport Arc constants
const float ArcRadius = 0.f;
const float MaxSimTime = 2.f;
const float SimFrequency = 30.f;
// Teleport Arc spline parameters
USplineComponent* ArcSpline = nullptr;
TArray ArcPoints;
TArray ArcSplineMeshes;
TArray > ArcObjectTypesToIgnore;
FVector RayMeshScale = FVector(1.0f, 1.0f, 1.0f);
FVector RayMeshScale_Max = FVector(1.0f, 1.0f, 1.0f);
bool bIsBeamTypeTeleport = false;
float RayNumOfTimesToScale = 0.f;
float RayNumOfTimesToScale_Actual = 0.f;
float RayDistanceToTarget = 0.f;
// TeleportRay mesh
UStaticMeshComponent* RayMesh = nullptr;
// Teleport target location
FVector TargetLocation = FVector::ZeroVector;
FRotator TargetRotation = FRotator::ZeroRotator;
bool bIsTargetLocationValid = false;
// Spawned visible components for targetting marker
UParticleSystemComponent* TargetParticleSystemComponent = nullptr;
UStaticMeshComponent* TargetStaticMeshComponent = nullptr;
// Draw teleport arc
void DrawTeleportArc();
// Clear teleport arc spline
void ClearTeleportArc();
// Draw teleport ray
void DrawTeleportRay();
// Clear teleport arc spline
void ClearTeleportRay();
// Spawn target location marker
void SpawnTargetMarker(FVector MarkerLocation = FVector::ZeroVector, FRotator MarkerRotation = FRotator::ZeroRotator);
// Show target location marker
void SetTargetMarkerVisibility(bool MakeVisible = false);
// Show target location marker
void SetTargetMarkerLocationAndRotation(FVector MarkerLocation = FVector::ZeroVector, FRotator MarkerRotation = FRotator::ZeroRotator);
// Remove target location marker
void RemoveTargetMarker();
};
CPP文件
// Fill out your copyright notice in the Description page of Project Settings.
#include "VRTeleP.h"
#include "Engine.h"
#include "CoreUObject.h"
#include "RunebergVR_Teleporter.h"
#include "Kismet/KismetMathLibrary.h"
#include "IHeadMountedDisplay.h"
// Sets default values for this component's properties
URunebergVR_Teleporter::URunebergVR_Teleporter()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// Auto Activate this component
bAutoActivate = true;
}
// Called when the game starts
void URunebergVR_Teleporter::BeginPlay()
{
Super::BeginPlay();
// Ensure target marker is not visible at start
SetVisibility(false, true);
// Set object types for the teleport arc to ignore
ArcObjectTypesToIgnore.Add(EObjectTypeQuery::ObjectTypeQuery1); // World static objects
// Create teleport arc spline
ArcSpline = NewObject(GetAttachParent());
ArcSpline->RegisterComponentWithWorld(GetWorld());
ArcSpline->SetMobility(EComponentMobility::Movable);
ArcSpline->AttachToComponent(GetAttachParent(), FAttachmentTransformRules::KeepRelativeTransform);
// Adjust pawn spawn target offset based on HMD
static const FName HMDName = GEngine->HMDDevice->GetDeviceName();
if (GEngine->HMDDevice.IsValid())
{
// Override height offset for Oculus Rift
if (HMDName == FName(TEXT("OculusRift")))
{
PawnHeightOffset.Z = 262.f;
}
}
}
// Called every frame
void URunebergVR_Teleporter::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (IsTeleporting && bIsBeamTypeTeleport)
{
if (TeleportMode == 0)
{
DrawTeleportArc();
}
else if (TeleportMode == 1)
{
DrawTeleportRay();
}
}
}
// Draw Teleport Arc
void URunebergVR_Teleporter::DrawTeleportArc()
{
// Set Teleport Arc Parameters
FPredictProjectilePathParams Params = FPredictProjectilePathParams(
ArcRadius,
FVector(GetAttachParent()->GetComponentLocation().X + BeamLocationOffset.X,
GetAttachParent()->GetComponentLocation().Y + BeamLocationOffset.Y,
GetAttachParent()->GetComponentLocation().Z + BeamLocationOffset.Z),
GetAttachParent()->GetForwardVector() * BeamMagnitude,
MaxSimTime);
Params.bTraceWithCollision = true;
Params.bTraceComplex = false;
Params.DrawDebugType = EDrawDebugTrace::None;
Params.DrawDebugTime = 0.f;
Params.SimFrequency = SimFrequency;
Params.ObjectTypes = ArcObjectTypesToIgnore;
Params.OverrideGravityZ = ArcOverrideGravity;
Params.bTraceWithChannel = false;
// Do the arc trace
FPredictProjectilePathResult PredictResult;
bool bHit = UGameplayStatics::PredictProjectilePath(this, Params, PredictResult);
// Show Target Marker (if a valid teleport location)
if (bHit)
{
TargetLocation = GetWorld()->GetNavigationSystem()->ProjectPointToNavigation(
this,
PredictResult.HitResult.Location,
(ANavigationData*)0, 0,
BeamHitNavMeshTolerance);
// Check if arc hit location is within the nav mesh
if (!PredictResult.HitResult.Location.Equals(TargetLocation, 0.0001f))
{
TargetLocation = PredictResult.HitResult.Location;
TargetRotation = UKismetMathLibrary::FindLookAtRotation(TargetLocation, GetOwner()->GetActorLocation());
SetTargetMarkerLocationAndRotation(TargetLocation, TargetRotation);
// Set Target Marker Visibility
SetTargetMarkerVisibility(true);
bIsTargetLocationValid = true;
}
else
{
// Set Target Marker Visibility
SetTargetMarkerVisibility(false);
bIsTargetLocationValid = false;
}
}
else
{
// Set Target Marker Visibility
SetTargetMarkerVisibility(false);
bIsTargetLocationValid = false;
}
// Set the teleport arc points
if (ArcSpline)
{
// Clean-up old Spline
ClearTeleportArc();
// Set the point type for the curve
ArcSpline->SetSplinePointType(ArcPoints.Num() - 1, ESplinePointType::CurveClamped, true);
for (const FPredictProjectilePathPointData& PathPoint : PredictResult.PathData)
{
// Add the point to the arc spline
ArcPoints.Add(PathPoint.Location);
ArcSpline->AddSplinePoint(PathPoint.Location, ESplineCoordinateSpace::Local, true);
}
}
// Populate arc points with meshes
if (TeleportBeamMesh)
{
for (int32 i = 0; i < ArcPoints.Num() - 2; i++)
{
// Add the arc mesh
USplineMeshComponent* ArcMesh = NewObject(ArcSpline);
ArcMesh->RegisterComponentWithWorld(GetWorld());
ArcMesh->SetMobility(EComponentMobility::Movable);
//ArcMesh->AttachToComponent(ArcSpline, FAttachmentTransformRules::KeepRelativeTransform);
ArcMesh->SetStaticMesh(TeleportBeamMesh);
ArcSplineMeshes.Add(ArcMesh);
// Bend mesh to conform to arc
ArcMesh->SetStartAndEnd(ArcPoints[i],
ArcSpline->GetTangentAtSplinePoint(i, ESplineCoordinateSpace::Local),
ArcPoints[i + 1],
ArcSpline->GetTangentAtSplinePoint(i + 1, ESplineCoordinateSpace::Local),
true);
}
}
}
// Clear Teleport arc
void URunebergVR_Teleporter::ClearTeleportArc()
{
// Clear Arc
ArcPoints.Empty();
ArcSpline->ClearSplinePoints();
for (int32 i = 0; i < ArcSplineMeshes.Num(); i++)
{
if (ArcSplineMeshes[i])
{
ArcSplineMeshes[i]->DestroyComponent();
}
}
ArcSplineMeshes.Empty();
}
// Show the teleportation arc trace
bool URunebergVR_Teleporter::ShowTeleportArc()
{
if (!IsTeleporting)
{
TeleportMode = 0;
IsTeleporting = true;
bIsBeamTypeTeleport = true;
SpawnTargetMarker();
return true;
}
return false;
}
// Remove the teleportation arc trace
bool URunebergVR_Teleporter::HideTeleportArc()
{
if (IsTeleporting)
{
TeleportMode = -1;
IsTeleporting = false;
bIsBeamTypeTeleport = false;
ClearTeleportArc();
// Clear Target Marker
RemoveTargetMarker();
return true;
}
return false;
}
// Remove the teleportation ray trace
bool URunebergVR_Teleporter::HideTeleportRay()
{
if (IsTeleporting)
{
TeleportMode = -1;
IsTeleporting = false;
bIsBeamTypeTeleport = false;
ClearTeleportRay();
RayMeshScale = FVector(1.0f, 1.0f, 1.0f);
// Clear Target Marker
RemoveTargetMarker();
return true;
}
return false;
}
// Clear Teleport ray
void URunebergVR_Teleporter::ClearTeleportRay()
{
if (RayMesh)
{
// Remove ray mesh component
RayMesh->DestroyComponent();
RayMesh = nullptr;
}
}
// Draw Teleport Ray
void URunebergVR_Teleporter::DrawTeleportRay()
{
// Setup ray trace
FCollisionQueryParams Ray_TraceParams(FName(TEXT("Ray_Trace")), true, this->GetOwner());
Ray_TraceParams.bTraceComplex = true;
Ray_TraceParams.bTraceAsyncScene = true;
Ray_TraceParams.bReturnPhysicalMaterial = false;
// Initialize Hit Result var
FHitResult Ray_Hit(ForceInit);
// Get Target Location
TargetLocation = FVector(GetAttachParent()->GetComponentLocation().X + BeamLocationOffset.X,
GetAttachParent()->GetComponentLocation().Y + BeamLocationOffset.Y,
GetAttachParent()->GetComponentLocation().Z + BeamLocationOffset.Z) +
(GetAttachParent()->GetComponentRotation().Vector() * BeamMagnitude);
// Do the ray trace
bool bHit = GetWorld()->LineTraceSingleByObjectType(
Ray_Hit,
GetAttachParent()->GetComponentLocation(),
FVector(GetAttachParent()->GetComponentLocation().X + BeamLocationOffset.X,
GetAttachParent()->GetComponentLocation().Y + BeamLocationOffset.Y,
GetAttachParent()->GetComponentLocation().Z + BeamLocationOffset.Z) +
(GetAttachParent()->GetComponentRotation().Vector() * BeamMagnitude),
ECC_WorldStatic,
Ray_TraceParams
);
// Reset Target Marker
SetTargetMarkerVisibility(false);
bIsTargetLocationValid = false;
// Check if we hit a possible location to teleport to
if (bHit)
{
// Check if target location is within the nav mesh
FVector tempTargetLocation = GetWorld()->GetNavigationSystem()->ProjectPointToNavigation(
this,
Ray_Hit.ImpactPoint,
(ANavigationData*)0, 0,
BeamHitNavMeshTolerance);
if (!tempTargetLocation.Equals(Ray_Hit.ImpactPoint, 0.0001f))
{
// Set Target Marker Visibility
TargetLocation = Ray_Hit.ImpactPoint;
TargetRotation = UKismetMathLibrary::FindLookAtRotation(TargetLocation, GetOwner()->GetActorLocation());
SetTargetMarkerLocationAndRotation(TargetLocation, TargetRotation);
SetTargetMarkerVisibility(true);
bIsTargetLocationValid = true;
}
}
// Draw ray mesh
ClearTeleportRay();
if (TeleportBeamMesh)
{
// Spawn the beam mesh
RayMesh = NewObject(GetAttachParent());
RayMesh->RegisterComponentWithWorld(GetWorld());
RayMesh->SetMobility(EComponentMobility::Movable);
RayMesh->AttachToComponent(GetAttachParent(), FAttachmentTransformRules::KeepRelativeTransform);
RayMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
RayMesh->SetStaticMesh(TeleportBeamMesh);
RayMesh->AddLocalOffset(BeamLocationOffset);
RayMesh->SetWorldRotation(UKismetMathLibrary::FindLookAtRotation(FVector(GetAttachParent()->GetComponentLocation().X + BeamLocationOffset.X,
GetAttachParent()->GetComponentLocation().Y + BeamLocationOffset.Y,
GetAttachParent()->GetComponentLocation().Z + BeamLocationOffset.Z), TargetLocation));
// Scale the beam mesh
if (RayInstantScale)
{
// Calculate how long the beam should be using RayScaleRate as the base unit
RayMeshScale = FVector(FVector::Distance(GetComponentLocation(), TargetLocation) * RayScaleRate, 1.f, 1.f);
RayMesh->SetWorldScale3D(RayMeshScale);
}
else
{
// Scale beam mesh gradually until it reaches the target location
RayDistanceToTarget = FVector::Distance(GetComponentLocation(), TargetLocation);
RayNumOfTimesToScale = RayDistanceToTarget;
if (RayNumOfTimesToScale_Actual < RayNumOfTimesToScale)
{
// We haven't reached the target location yet, set the mesh scale
RayMesh->SetWorldScale3D(RayMeshScale);
RayMeshScale.X = RayMeshScale.X + RayScaleRate;
// Update temp scale variables
RayMeshScale_Max = RayMeshScale;
RayNumOfTimesToScale_Actual += RayScaleRate;
}
else
{
// Scale mesh to max possible size to hit target location
RayMesh->SetWorldScale3D(RayMeshScale_Max);
}
}
}
}
// Show the teleportation ray trace
bool URunebergVR_Teleporter::ShowTeleportRay()
{
if (!IsTeleporting)
{
TeleportMode = 1;
IsTeleporting = true;
bIsBeamTypeTeleport = true;
SpawnTargetMarker();
RayNumOfTimesToScale_Actual = 0.f;
return true;
}
return false;
}
// Teleport object
bool URunebergVR_Teleporter::TeleportNow()
{
// Only teleport if targetting is enabled
if (IsTeleporting && bIsTargetLocationValid) {
// Teleport
GetAttachParent()->GetOwner()->SetActorLocation(TargetLocation + PawnHeightOffset + TeleportTargetPawnSpawnOffset, false, nullptr, ETeleportType::None);
// Remove teleport artifacts
switch (TeleportMode)
{
case 0:
HideTeleportArc();
break;
case 1:
HideTeleportRay();
break;
case 2:
HideMarker();
default:
break;
}
// Reset Teleport mode
TeleportMode = -1;
return true;
}
return false;
}
// Show the teleport target marker
bool URunebergVR_Teleporter::ShowMarker()
{
if (!IsTeleporting)
{
// Calculate Target Location
TargetLocation = GetAttachParent()->GetComponentLocation() + (GetAttachParent()->GetComponentRotation().Vector() * BeamMagnitude);
// Check if target location is within the nav mesh
FVector tempTargetLocation = GetWorld()->GetNavigationSystem()->ProjectPointToNavigation(
this,
TargetLocation,
(ANavigationData*)0, 0,
BeamHitNavMeshTolerance);
if (!tempTargetLocation.Equals(TargetLocation, 0.0001f))
{
// Set Target Marker Visibility
TargetRotation = UKismetMathLibrary::FindLookAtRotation(TargetLocation, GetOwner()->GetActorLocation());
SetTargetMarkerLocationAndRotation(TargetLocation, TargetRotation);
SetTargetMarkerVisibility(true);
bIsTargetLocationValid = true;
}
else
{
return false;
}
// Set teleport parameters
TeleportMode = 2;
IsTeleporting = true;
bIsBeamTypeTeleport = false;
bIsTargetLocationValid = true;
// Show target marker
SpawnTargetMarker();
TargetRotation = UKismetMathLibrary::FindLookAtRotation(TargetLocation, GetOwner()->GetActorLocation());
TargetLocation.Z = FloorIsAtZ;
// Calculate Rotation of marker to face player and set the new transform
SetTargetMarkerLocationAndRotation(TargetLocation, TargetRotation);
// Make target marker visible
SetTargetMarkerVisibility(true);
return true;
}
return false;
}
// Remove Marker
bool URunebergVR_Teleporter::HideMarker()
{
if (IsTeleporting)
{
TeleportMode = -1;
IsTeleporting = false;
bIsBeamTypeTeleport = false;
bIsTargetLocationValid = false;
// Clear Target Marker
RemoveTargetMarker();
return true;
}
return false;
}
// Move marker
bool URunebergVR_Teleporter::MoveMarker(EMoveDirectionEnum MarkerDirection, int Rate, FRotator CustomDirection)
{
// Only move marker if it is visible and active
if (IsTeleporting) {
switch (MarkerDirection)
{
case EMoveDirectionEnum::MOVE_FORWARD:
TargetLocation = FVector(TargetLocation + (TargetRotation.Vector() * Rate));
TargetLocation.Z = FloorIsAtZ;
SetTargetMarkerLocationAndRotation(TargetLocation, TargetRotation);
break;
case EMoveDirectionEnum::MOVE_BACKWARD:
TargetLocation = TargetLocation + (TargetRotation.Vector() * -Rate);
TargetLocation.Z = FloorIsAtZ;
SetTargetMarkerLocationAndRotation(TargetLocation, TargetRotation);
break;
case EMoveDirectionEnum::MOVE_LEFT:
// Tilt original marker location to point Westwards
CustomDirection = TargetRotation;
CustomDirection.Yaw += 90.0f;
// Calculate target location
TargetLocation = TargetLocation + (CustomDirection.Vector() * Rate);
TargetLocation.Z = FloorIsAtZ;
SetTargetMarkerLocationAndRotation(TargetLocation, TargetRotation);
break;
case EMoveDirectionEnum::MOVE_RIGHT:
// Tilt original marker location to point Eastwards
CustomDirection = TargetRotation;
CustomDirection.Yaw += 90.0f;
// Calculate target location
TargetLocation = TargetLocation + (CustomDirection.Vector() * -Rate);
TargetLocation.Z = FloorIsAtZ;
SetTargetMarkerLocationAndRotation(TargetLocation, FRotator::ZeroRotator);
break;
case EMoveDirectionEnum::MOVE_CUSTOM:
TargetLocation = FVector(TargetLocation + (CustomDirection.Vector() * Rate));
TargetLocation.Z = FloorIsAtZ;
SetTargetMarkerLocationAndRotation(TargetLocation, TargetRotation);
break;
default:
break;
}
return true;
}
return false;
}
// Show target location marker
void URunebergVR_Teleporter::SpawnTargetMarker(FVector MarkerLocation, FRotator MarkerRotation)
{
// Activate Particle System if available
if (TeleportTargetParticle) {
TargetParticleSystemComponent = UGameplayStatics::SpawnEmitterAtLocation(this, TeleportTargetParticle, MarkerLocation, MarkerRotation);
TargetParticleSystemComponent->SetWorldScale3D(TeleportTargetParticleScale);
TargetParticleSystemComponent->SetVisibility(false);
TargetParticleSystemComponent->SetMobility(EComponentMobility::Movable);
}
// Show Static Mesh if available
if (TeleportTargetMesh) {
// Create new static mesh component and attach to actor
TargetStaticMeshComponent = NewObject(this);
TargetStaticMeshComponent->RegisterComponentWithWorld(GetWorld());
TargetStaticMeshComponent->SetSimulatePhysics(false);
TargetStaticMeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
TargetStaticMeshComponent->SetMobility(EComponentMobility::Movable);
TargetStaticMeshComponent->AttachToComponent(GetOwner()->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
//Set Mesh
TargetStaticMeshComponent->SetVisibility(false);
TargetStaticMeshComponent->SetWorldScale3D(TeleportTargetMeshScale);
TargetStaticMeshComponent->SetStaticMesh(TeleportTargetMesh);
}
}
// Remove target location marker
void URunebergVR_Teleporter::RemoveTargetMarker()
{
// Destroy Particle System if available
if (TargetParticleSystemComponent) {
TargetParticleSystemComponent->DestroyComponent();
TargetParticleSystemComponent = nullptr;
}
// Destroy Static Mesh if available
if (TargetStaticMeshComponent) {
TargetStaticMeshComponent->DestroyComponent();
TargetStaticMeshComponent = nullptr;
}
bIsTargetLocationValid = false;
}
// Show target location marker
void URunebergVR_Teleporter::SetTargetMarkerVisibility(bool MakeVisible)
{
// Activate Particle System if available
if (TargetParticleSystemComponent) {
TargetParticleSystemComponent->SetVisibility(MakeVisible);
}
// Show Static Mesh if available
if (TargetStaticMeshComponent) {
TargetStaticMeshComponent->SetVisibility(MakeVisible);
}
}
// Move target location marker
void URunebergVR_Teleporter::SetTargetMarkerLocationAndRotation(FVector MarkerLocation, FRotator MarkerRotation)
{
// Activate Particle System if available
if (TargetParticleSystemComponent) {
TargetParticleSystemComponent->SetWorldLocation(MarkerLocation + TeleportTargetParticleSpawnOffset);
TargetParticleSystemComponent->SetWorldRotation(MarkerRotation);
}
// Show Static Mesh if available
if (TargetStaticMeshComponent) {
TargetStaticMeshComponent->SetWorldLocation(MarkerLocation + TeleportTargetMeshSpawnOffset);
TargetStaticMeshComponent->SetWorldRotation(MarkerRotation);
}
}
以为这样就可以在蓝图里调用了吗,还不能,我们得干点别的事情哦
找到工程配置例如我的如图
讲PublicDependencyModuleNames.AddRange()内容改为如图
好了 现在就可以调用了