UE5学习51.ToCompactString() 向量—字符串//ToCompactString()void UMover_2::BeginPlay(){Super::BeginPlay(); FVector MyVector FVector(0,0,0);//MyVector继承Vector其中有ToCompactString函数可以调用 FVector* P_MyVector MyVector; P_MyVector-X 100; P_MyVector-Y 100; P_MyVector-Z 100; UE_LOG(LogTemp, Warning, TEXT(MyVector is %s),*MyVector.ToCompactString());//和指针无关只是转换成正确的格}2.Actor组件控制父类Actor我们期望用组件控制Actor就可以在Mover的cpp中GetOwner函数获取父类Actor的地址之后解引用就可以调用该Actor中函数GetOwner()//返回一个指向该组件的Actor的指针通过组件mover让父类Actor移动//.hFVector StartLocation; UPROPERTY(EditAnywhere) FVector MovingVelocity FVector(0.0f, 0.0f, 0.0f); UPROPERTY(EditAnywhere) float SetMovingDistance 0.0f;//.cppvoid UMover::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction){Super::TickComponent(DeltaTime, TickType, ThisTickFunction); FVector CurrentLocation GetOwner()-GetActorLocation(); float MovingDistance FVector::Dist(StartLocation, CurrentLocation); if (SetMovingDistance MovingDistance) { CurrentLocation CurrentLocation (DeltaTime * MovingVelocity); GetOwner()-SetActorLocation(CurrentLocation); }}要把父类组件调成可移动3.用数学函数实现移动移动代码的改进FMath::VInterpConstantTo需要头文件#include “Math/UnrealMathUtility.h”用恒定的步长从当前向量插值到目标向量//.h(部分)UPROPERTY(EditAnywhere,BlueprintReadOnly,CategoryMove) FVector MoveOffset;//某个轴移动多少距离 UPROPERTY(EditAnywhere,BlueprintReadOnly,CategoryMove) float MoveTime 4.0f; UPROPERTY(EditAnywhere,BlueprintReadOnly,CategoryMove) bool ShouldMove false; FVector TargetLocation; FVector StartLocation;//cpp#include “Mover.h”#include “Math/UnrealMathUtility.h”void UMover_2::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction){Super::TickComponent(DeltaTime, TickType, ThisTickFunction); if (ShouldMove true) { FVector Current_Location GetOwner()-GetActorLocation(); float Speed MoveOffset.Length() / MoveTime;//MoveOffset.Length()以浮点数的形式返回这个向量的长度 FVector New_Location FMath::VInterpConstantTo(Current_Location, TargetLocation, DeltaTime, Speed); GetOwner()-SetActorLocation(New_Location); } else { }}相比之前的移动代码更加好控制逻辑更加自洽4.实现踏板开门效果shouldmove为真门开shouldmove为假门关情况1为真目标位置 起始位置 移动偏移量情况2为假目标位置 起始位置所以现在shouldmove控制的是移动方向也就是是否开关门所以我们可以搞个新的组件为Oppen_Close//基于mover组件进行魔改//错误写法void UOpen_Close::BeginPlay(){Super::BeginPlay(); StartLocation GetOwner()-GetActorLocation(); TargetLocation StartLocation MoveOFFset;//这行得写到if为真的情况下}// Called every framevoid UOpen_Close::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction){Super::TickComponent(DeltaTime, TickType, ThisTickFunction); if (shouldmove) { //如果这里重新定义TargetLocation那么我门刚开始的时候设置为开门那么门会开。我们关门也会关但是当我门再次把Open_Close设为真的时候门是不会开的因为我们没有重新设置TargetLocation所以用的还是else中的TargetLocation也就是StartLocation所以函数中传的参数都是StartLocation就不会移动了 } else { UE_LOG(LogTemp, Warning, TEXT(%d), shouldmove); TargetLocation StartLocation; } FVector CurrentLocation GetOwner()-GetActorLocation(); float speed MoveOFFset.Length() / MoveTime;//MoveOFFset.Length()返回浮点数移动长度/时间速度 FVector NewLocation FMath::VInterpConstantTo(CurrentLocation, TargetLocation, DeltaTime, speed); //FMath::VInterpConstantTo当前位置目标位置DeltaTime速度 GetOwner()-SetActorLocation(NewLocation);}//正确写法void UOpen_Close::BeginPlay(){Super::BeginPlay(); StartLocation GetOwner()-GetActorLocation();}void UOpen_Close::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction){Super::TickComponent(DeltaTime, TickType, ThisTickFunction); if (shouldmove) { //计算目标位置 TargetLocation StartLocation MoveOFFset; } else { TargetLocation StartLocation; } FVector CurrentLocation GetOwner()-GetActorLocation(); float speed MoveOFFset.Length() / MoveTime; FVector NewLocation FMath::VInterpConstantTo(CurrentLocation, TargetLocation, DeltaTime, speed); GetOwner()-SetActorLocation(NewLocation);}但是上述代码仍然有问题即使我们到达了目标位置但是我们还是会重新设置新的位置它严重影响性能。5.两个向量比较 Equals()//.hUPROPERTY(VisibleAnywhere) bool ReachTarget false;//.cppif (shouldmove){ //计算目标位置 TargetLocation StartLocation MoveOFFset; } else { TargetLocation StartLocation; } FVector CurrentLocation GetOwner()-GetActorLocation(); ReachTarget CurrentLocation.Equals(TargetLocation);//用于判断两个向量是否相等 if (ReachTarget true) { //到达目标位置 GEngine-AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT(reach the target)); } else { //未到达目标位置 float speed MoveOFFset.Length() / MoveTime; FVector NewLocation FMath::VInterpConstantTo(CurrentLocation, TargetLocation, DeltaTime, speed); GetOwner()-SetActorLocation(NewLocation); }psvoid UMover_2::BeginPlay(){Super::BeginPlay(); AActor* MyOwnerPtr GetOwner(); UE_LOG(LogTemp, Warning, TEXT(%s),*MyOwnerPtr-GetActorNameOrLabel()); UE_LOG(LogTemp, Warning, TEXT(%s),*MyOwnerPtr-GetName());}GetActorNameOrLabel()优先返回你在场景大纲Outliner中手动设置的、方便人类阅读的名称如 SM_CastleWallEntranceDoor。GetName()返回引擎底层自动生成的对象标识符通常带有类型后缀、随机哈希码或序列号如 StaticMeshActor_525 或 BP_TestingTargetDummy_C_UAID_2CF05D6D…
阅读完成 · 觉得有帮助?