[About game save in C++] I traverse all the actors in the world through FActorIterator It in the savegame function in SGameModeBase.cpp, and store the Name and Transfrom of the actor with the USGameplayInterface interface into TArray SavedActors in SSaveGame.h (debug It shows that it is indeed saved). When loading the game, it does exist in TArray SavedActors, but when I also use FActorIterator It to traverse the actors used in the world, I will find that there are no actors with the USGameplayInterface interface on the field, so the actors with the USGameplayInterface interface on the field will not be synchronized. . I followed the tutorial, but I couldn’t synchronize the position. The breakpoint could appear UE_LOG(LogTemp, Log, TEXT(“Loaded SaveGame Data.”)) but I couldn’t break to the code after ‘continue’.Could it be caused by the crash of FActorIterator It? Or any other problem, please solve it!!!ORZ
SGameModeBase.cpp***
void ASGameModeBase::WriteSaveGame()
{
for(int32 i = 0; i < GameState->PlayerArray.Num(); i++)
{
ASPlayerState* PS = Cast(GameState->PlayerArray[i]);
if (PS)
{
PS->SavePlayerState(CurrentSaveGame);
break;//singgle player only at this point
}
}
CurrentSaveGame->SavedActors.Empty();
//Iterate the entire world of actors
for (FActorIterator It(GetWorld()); It; ++It)
{
AActor* Actor = *It;
//Only interested in our 'gameplay actor'
if (!Actor->Implements<USGameplayInterface>())
{
continue;
}
FActorSaveData ActorData;
ActorData.ActorName = Actor->GetName();
ActorData.Transfrom = Actor->GetActorTransform();
//Pass the array to fill with data from Actor
FMemoryWriter MemWriter(ActorData.ByteData);
FObjectAndNameAsStringProxyArchive Ar(MemWriter,true);
//Find only variables with UPROPERTY(SaveGame)
Ar.ArIsSaveGame = true;
//Converts Actor's SaveGame UPROPERTIES into binary array
Actor->Serialize(Ar);
CurrentSaveGame->SavedActors.Add(ActorData);
}
UGameplayStatics::SaveGameToSlot(CurrentSaveGame,SlotName,0);
}
void ASGameModeBase::LoadSaveGame()
{
if (UGameplayStatics::DoesSaveGameExist(SlotName, 0))
{
CurrentSaveGame = Cast(UGameplayStatics::LoadGameFromSlot(SlotName, 0));
if (CurrentSaveGame == nullptr)
{
UE_LOG(LogTemp, Warning, TEXT(“Failed to load SaveGame Data.”));
return;
}
UE_LOG(LogTemp, Log, TEXT("Loaded SaveGame Data."));
//Iterate the entire world of actors
for (FActorIterator It(GetWorld()); It; ++It)
{
AActor* Actor = *It;
if (!Actor->Implements<USGameplayInterface>())
{
continue;
}
for (FActorSaveData ActorData : CurrentSaveGame->SavedActors)
{
if (ActorData.ActorName == Actor->GetName())
{
Actor->SetActorTransform(ActorData.Transfrom);
FMemoryReader MemReader(ActorData.ByteData);
FObjectAndNameAsStringProxyArchive Ar(MemReader,true);
Ar.ArIsSaveGame = true;
//Convert binary array back into actor's variables.
Actor->Serialize(Ar);
ISGameplayInterface::Execute_OnActorLoaded(Actor);
break;
}
}
}
}
else
{
CurrentSaveGame = Cast<USSaveGame>(UGameplayStatics::CreateSaveGameObject(USSaveGame::StaticClass()));
UE_LOG(LogTemp, Log, TEXT("Created New SaveGame Data."));
}
}
SSaveGame.h***
include “CoreMinimal.h”
include “GameFramework/SaveGame.h”
include “SSaveGame.generated.h”
USTRUCT()
struct FActorSaveData
{
GENERATED_BODY()
public:
UPROPERTY()
FString ActorName;
UPROPERTY()
FTransform Transfrom;
UPROPERTY()
TArray<uint8> ByteData;
};
UCLASS()
class ACTIONROGUELIKE_API USSaveGame : public USaveGame
{
GENERATED_BODY()
public:
UPROPERTY()
int32 Credits;
UPROPERTY()
TArray<FActorSaveData> SavedActors;
};
SPlayerState.cpp*
void ASPlayerState::SavePlayerState_Implementation(USSaveGame* SaveObject)
{
if (SaveObject)
{
SaveObject->Credits = Credits;
}
}
void ASPlayerState::LoadPlayerState_Implementation(USSaveGame* SaveObject)
{
if (SaveObject)
{
Credits = SaveObject->Credits;
}
}