還沒有時間寫詳細過程,先附上程式碼,之後要寫結案報告時一起寫。

下面是標頭檔

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SlimeVR2.generated.h"

UCLASS()
class TRACKERTOCSV_API ASlimeVR2 : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ASlimeVR2();

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	UStaticMeshComponent* Slime;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FloatingActor")
	float FloatSpeed = 20.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FloatingActor")
	float RotationSpeed = 20.0f;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};

下面是程式

// Fill out your copyright notice in the Description page of Project Settings.


#include "SlimeVR2.h"

FString SlimeVR_data_all = "";
FString SlimeVR_data_Tracker = "";
FString SlimeVR_data_MPU6050 = "";
FString SlimeVR_data_MPU6050Temp = "";
FString SlimeVR_TextPath = FPaths::ProjectDir();
TArray<FString> SlimeVR_TextLines;

// Sets default values
ASlimeVR2::ASlimeVR2()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

    Slime = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
    Slime->SetupAttachment(RootComponent);

    static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Pipe_180.Shape_Pipe_180"));

    if (CubeVisualAsset.Succeeded())
    {
        Slime->SetStaticMesh(CubeVisualAsset.Object);
        Slime->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
    }
}

// Called when the game starts or when spawned
void ASlimeVR2::BeginPlay()
{
    SlimeVR_TextLines = {};

    //取得現在時間作為檔名
    FDateTime SlimeVR_nowTime = FDateTime::Now();
    int32 Y = SlimeVR_nowTime.GetYear();
    int32 M = SlimeVR_nowTime.GetMonth();
    int32 D = SlimeVR_nowTime.GetDay();
    int32 H = SlimeVR_nowTime.GetHour();
    int32 i = SlimeVR_nowTime.GetMinute();
    int32 s = SlimeVR_nowTime.GetSecond();
    int32 ms = SlimeVR_nowTime.GetMillisecond();
    FString SlimeVR_timestamp = FString::Printf(TEXT("%04d-%02d-%02d %02d_%02d_%02d"), Y, M, D, H, i, s);
    SlimeVR_TextPath = FPaths::ProjectDir() + TEXT("outputCsv/SlimeVR_" + SlimeVR_timestamp + ".csv");
    SlimeVR_TextPath = FPaths::ConvertRelativePathToFull(SlimeVR_TextPath);
    //UE_LOG(LogTemp, Warning, TEXT("save path: %s"), *TextPath);

    //加入CSV的第一列
    SlimeVR_TextLines.Add(TEXT("Timestamp, RotationPitch, RotationRoll, RotationYaw"));

    int c = 1;

	Super::BeginPlay();
	
}

// Called every frame
void ASlimeVR2::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

    //取得目前時間戳記
    FDateTime SlimeVR_nowTime = FDateTime::Now();
    int32 Y = SlimeVR_nowTime.GetYear();
    int32 M = SlimeVR_nowTime.GetMonth();
    int32 D = SlimeVR_nowTime.GetDay();
    int32 H = SlimeVR_nowTime.GetHour();
    int32 i = SlimeVR_nowTime.GetMinute();
    int32 s = SlimeVR_nowTime.GetSecond();
    int32 ms = SlimeVR_nowTime.GetMillisecond();
    FString SlimeVR_timestamp = FString::Printf(TEXT("%04d-%02d-%02d %02d:%02d:%02d.%03d"), Y, M, D, H, i, s, ms);

    ///取得目前Tracker資料
    FVector SlimeVR_NewLocation = GetActorLocation();
    FRotator SlimeVR_NewRotation = GetActorRotation();

    //列印資料在螢幕上
    if (GEngine) {
        GEngine->ClearOnScreenDebugMessages();

        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("(%f %f, %f)"), SlimeVR_NewLocation.X, SlimeVR_NewLocation.Y, SlimeVR_NewLocation.Z));
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("SlimeVR: (%f %f, %f)"), SlimeVR_NewRotation.Pitch, SlimeVR_NewRotation.Roll, SlimeVR_NewRotation.Yaw));
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Time: %s"), *SlimeVR_timestamp));
        //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Some debug message!"));
    }

    //GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, message);
    //TextLines.Add(TEXT("Test"));
    SlimeVR_data_all = FString::Printf(TEXT("%s, %f, %f, %f"), *SlimeVR_timestamp, SlimeVR_NewRotation.Pitch, SlimeVR_NewRotation.Roll, SlimeVR_NewRotation.Yaw);
    SlimeVR_TextLines.Add(FString::Printf(TEXT("%s"), *SlimeVR_data_all));
}

void ASlimeVR2::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    FFileHelper::SaveStringArrayToFile(SlimeVR_TextLines, *SlimeVR_TextPath);
    Super::EndPlay(EndPlayReason);
}