# 常用操作

# 获取物体

获取物体的常用操作有两种:

void AMyActor::GetAllActor()
{
    for (TObjectIterator<AMyCustomActor> ActorItr; ActorItr; ++ActorItr)
    {
        GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("TObjectIterator,not with world:%s"), *ActorItr->GetFullName()));
    }
    
    for (TActorIterator<AMyCustomActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
    {
        GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("TActorIterator:%s"), *ActorItr->GetName()));
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

注意这两种的区别,如果有一个蓝图继承了AMyCustomActor并且在编辑器中打开了,这时第一种方法遍历便能遍历出这个蓝图打开的对应类。而第二种方法,只能遍历出运行时的AMyCustomActor。

# 移动物体

移动物体到指定地点。

# MoveComponentTo

使用该方法将当前物体移动到目标点。

FLatentActionInfo LatentInfo;
LatentInfo.CallbackTarget=this;
UKismetSystemLibrary::MoveComponentTo(GetWorld()->GetFirstPlayerController()->GetPawn()->GetRootComponent(),targetActor->GetActorLocation(),FRotator::ZeroRotator,false,false,1.0f,false,EMoveComponentAction::Move,LatentInfo);
1
2
3

如果要移动到目标点后执行某些逻辑,这个时候就需要设置一个回调函数:

FLatentActionInfo LatentInfo;
LatentInfo.CallbackTarget=this;
LatentInfo.ExecutionFunction=FName("EndFunc");
LatentInfo.Linkage = 0;
LatentInfo.UUID = 0; 
UKismetSystemLibrary::MoveComponentTo(targetActor3->GetRootComponent(),targetActor2->GetActorLocation(),FRotator::ZeroRotator,false,false,1.0f, false,EMoveComponentAction::Move, LatentInfo);


UFUNCTION()
void EndFunc();

void AMyPawnMoveTest::EndFunc()
{
    UE_LOG(LogTemp,Warning,TEXT("finish move!"));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 路径

# 常用路径

打印出虚幻中常用的路径:

UE_LOG(LogTemp, Warning, TEXT("EngineDir: %s"), *FPaths::EngineDir());
UE_LOG(LogTemp, Warning, TEXT("EngineSavedDir: %s"), *FPaths::EngineSavedDir());
UE_LOG(LogTemp, Warning, TEXT("EngineIntermediateDir: %s"), *FPaths::EngineIntermediateDir());
UE_LOG(LogTemp, Warning, TEXT("ProjectDir: %s"), *FPaths::ProjectDir());
UE_LOG(LogTemp, Warning, TEXT("ProjectContentDir: %s"), *FPaths::ProjectContentDir());
UE_LOG(LogTemp, Warning, TEXT("ProjectConfigDir: %s"), *FPaths::ProjectConfigDir());
UE_LOG(LogTemp, Warning, TEXT("ProjectSavedDir: %s"), *FPaths::ProjectSavedDir());
UE_LOG(LogTemp, Warning, TEXT("ProjectIntermediateDir: %s"), *FPaths::ProjectIntermediateDir());

FString TestFilename(TEXT("ParentDirectory/Directory/FileName.extion"));
FString Extension = FPaths::GetExtension(TestFilename);
FString BaseFilename = FPaths::GetBaseFilename(TestFilename);
FString CleanFilename = FPaths::GetCleanFilename(TestFilename);
FString Directory = FPaths::GetPath(TestFilename);
bool bFileExists = FPaths::FileExists(TestFilename);
bool bDirectoryExists = FPaths::DirectoryExists(Directory);

UE_LOG(LogTemp, Warning, TEXT("TestFilename: %s"), *TestFilename);
// 获取文件扩展名
UE_LOG(LogTemp, Warning, TEXT("Extension: %s"), *Extension);
// 获取文件名,不带扩展名
UE_LOG(LogTemp, Warning, TEXT("BaseFilename: %s"), *BaseFilename);
// 获取文件名,带扩展名
UE_LOG(LogTemp, Warning, TEXT("CleanFilename: %s"), *CleanFilename);
// 获取路径文件夹,去除CleanFilename后的路径
UE_LOG(LogTemp, Warning, TEXT("Directory: %s"), *Directory);
// 检测文件是否存在
UE_LOG(LogTemp, Warning, TEXT("FileExists: %s"), bFileExists ? TEXT("True") : TEXT("False"));
// 检测文件夹是否存在
UE_LOG(LogTemp, Warning, TEXT("DirectoryExists: %s"), bDirectoryExists ? TEXT("True") : TEXT("False"));

// 路径拼接
FString NewFilePath = FPaths::Combine(Directory, TEXT("NewFilePath.txt"));
// 简便写法
FString NewFilePathEasy = Directory / TEXT("NewFilePath.txt");
// 相对路径转换为绝对路径
FString FullPath = FPaths::ConvertRelativePathToFull(FPaths::EngineDir());
UE_LOG(LogTemp, Warning, TEXT("NewFilePath: %s"), *NewFilePath);
UE_LOG(LogTemp, Warning, TEXT("NewFilePathEasy: %s"), *NewFilePathEasy);
UE_LOG(LogTemp, Warning, TEXT("FullPath: %s"), *FullPath);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

它的执行结果为:

LogTemp: Warning: EngineDir: ../../../Engine/
LogTemp: Warning: EngineSavedDir: C:/Users/xie/AppData/Local/UnrealEngine/4.26/Saved/
LogTemp: Warning: EngineIntermediateDir: ../../../Engine/Intermediate/
LogTemp: Warning: ProjectDir: X:/temp/PythonTest/
LogTemp: Warning: ProjectContentDir: X:/temp/PythonTest/Content/
LogTemp: Warning: ProjectConfigDir: X:/temp/PythonTest/Config/
LogTemp: Warning: ProjectSavedDir: X:/temp/PythonTest/Saved/
LogTemp: Warning: ProjectIntermediateDir: X:/temp/PythonTest/Intermediate/
LogTemp: Warning: TestFilename: ParentDirectory/Directory/FileName.extion
LogTemp: Warning: Extension: extion
LogTemp: Warning: BaseFilename: FileName
LogTemp: Warning: CleanFilename: FileName.extion
LogTemp: Warning: Directory: ParentDirectory/Directory
LogTemp: Warning: FileExists: False
LogTemp: Warning: DirectoryExists: False
LogTemp: Warning: NewFilePath: ParentDirectory/Directory/NewFilePath.txt
LogTemp: Warning: NewFilePathEasy: ParentDirectory/Directory/NewFilePath.txt
LogTemp: Warning: FullPath: C:/Program Files/Epic Games/UE_4.26/Engine/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 时间操作

# 基本时间

下面是获取当前日期和时间:

FDateTime Time = FDateTime::Now();
int64 Timestamp = Time.ToUnixTimestamp();
UE_LOG(LogTemp, Warning, TEXT("%d"), Timestamp);
int year = Time.GetYear();
int month = Time.GetMonth();
int day = Time.GetDay();
int hour = Time.GetHour();
int minute = Time.GetMinute();
int second = Time.GetSecond();
UE_LOG(LogTemp, Warning, TEXT("时间:%d, %d, %d, %d, %d, %d"), year, month, day, hour, minute, second);
//格化式时间
UE_LOG(LogTemp,Warning,TEXT("time:%s"),*FDateTime::Now().ToString(TEXT("%Y-%m-%d-%H-%M-%S")));
1
2
3
4
5
6
7
8
9
10
11
12

# 时间戳

下面是获取时间戳:

int64 MyCommonTools::GetCurrentTimeStamp()
{
    //FDateTime Time = FDateTime::Now();
    FDateTime Time = FDateTime::UtcNow();
    //Get the timestamp
    int64 Timestamp = Time.ToUnixTimestamp();
    return Timestamp;
}
1
2
3
4
5
6
7
8

# 摄像机

# 相对位置

总是对当前物体创建一个相对位置,后面摄像机可以移动到这个位置上:

AActor* AMyActor::GetCameraPos()
{
    if(cameraPos==nullptr)
    {
        cameraPos= GetWorld()->SpawnActor(AActor::StaticClass());
        USceneComponent* NewCustomActorRoot = NewObject<USceneComponent>(cameraPos);
        cameraPos->SetRootComponent(NewCustomActorRoot);
        //cameraPos->SetActorLabel(TEXT("attachedActor"));
        
        cameraPos->AttachToActor(this,FAttachmentTransformRules::KeepRelativeTransform);
        cameraPos->SetActorRelativeLocation(FVector(-357.960846,-22629.145508,13800.901367));
        cameraPos->SetActorRelativeRotation(FRotator(-20,90,0));
    }
    return cameraPos;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 移动摄像机

下面是一个封装的移动摄像机基本位置:

void MyCommonTools::ChangeCameraControl(UWorld* targetWorld,AActor* targetActor,bool bBackToPlayerControl)
{
    APlayerController* targetPlayerController =	UGameplayStatics::GetPlayerController(targetWorld,0);
    
    if(targetActor == nullptr)
    {
        targetPlayerController->SetViewTargetWithBlend(targetPlayerController, 1, EViewTargetBlendFunction::VTBlend_Linear);	
        DebugLog("target Actor is nullptr!");
        return;
    }
    
    
    if(bBackToPlayerControl)
    {
        targetPlayerController->GetPawn()->SetActorLocation(targetActor->GetActorLocation());
        targetPlayerController->SetControlRotation(targetActor->GetActorRotation());
        targetPlayerController->SetViewTargetWithBlend(targetPlayerController, 1, EViewTargetBlendFunction::VTBlend_Linear);	
    }else
    {
        targetPlayerController->SetViewTargetWithBlend(targetActor, 1, EViewTargetBlendFunction::VTBlend_Linear,0.5,true);
        targetPlayerController->GetPawn()->SetActorLocation(targetActor->GetActorLocation());
        targetPlayerController->SetControlRotation(targetActor->GetActorRotation());
    }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 是否在视野

查看某个物体是否在视野内,参考资料:

bool AMyActor::IsInScrrenViewport(const FVector& WorldPosition)
{
    APlayerController *Player = UGameplayStatics::GetPlayerController(this, 0);
    ULocalPlayer* const LP = Player ? Player->GetLocalPlayer() : nullptr;
    if (LP && LP->ViewportClient)
    {
        // get the projection data
        FSceneViewProjectionData ProjectionData;
        if (LP->GetProjectionData(LP->ViewportClient->Viewport, eSSP_FULL, /*out*/ ProjectionData))
        {
            FMatrix const ViewProjectionMatrix = ProjectionData.ComputeViewProjectionMatrix();
            FVector2D ScreenPosition;
            bool bResult = FSceneView::ProjectWorldToScreen(WorldPosition, ProjectionData.GetConstrainedViewRect(), ViewProjectionMatrix, ScreenPosition);
            if (bResult && ScreenPosition.X > ProjectionData.GetViewRect().Min.X && ScreenPosition.X < ProjectionData.GetViewRect().Max.X
                && ScreenPosition.Y > ProjectionData.GetViewRect().Min.Y && ScreenPosition.Y < ProjectionData.GetViewRect().Max.Y)
            {
                return true;
            }
        }
    }
    return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22