Content is user-generated and unverified.
// ======================================== // 方法1: GameInstanceでの実装 // ======================================== // MyGameInstance.h #pragma once #include "CoreMinimal.h" #include "Engine/GameInstance.h" #include "MyGameInstance.generated.h" UCLASS() class MYGAME_API UMyGameInstance : public UGameInstance { GENERATED_BODY() public: UMyGameInstance(); protected: virtual void Init() override; virtual void Shutdown() override; private: // アプリケーション終了時のデリゲート FDelegateHandle OnExitHandle; UFUNCTION() void OnApplicationWillTerminate(); }; // MyGameInstance.cpp #include "MyGameInstance.h" #include "Engine/Engine.h" #include "Framework/Application/SlateApplication.h" #include "HAL/PlatformFilemanager.h" UMyGameInstance::UMyGameInstance() { } void UMyGameInstance::Init() { Super::Init(); // アプリケーション終了時のデリゲートをバインド if (FSlateApplication::IsInitialized()) { OnExitHandle = FSlateApplication::Get().OnApplicationActivationStateChanged().AddUObject( this, &UMyGameInstance::OnApplicationWillTerminate); } // 別の方法: エンジンのデリゲート使用 FCoreDelegates::OnExit.AddUObject(this, &UMyGameInstance::OnApplicationWillTerminate); UE_LOG(LogTemp, Warning, TEXT("GameInstance initialized")); } void UMyGameInstance::Shutdown() { // 終了時の処理 OnApplicationWillTerminate(); // デリゲートのクリーンアップ if (FSlateApplication::IsInitialized() && OnExitHandle.IsValid()) { FSlateApplication::Get().OnApplicationActivationStateChanged().Remove(OnExitHandle); } Super::Shutdown(); } void UMyGameInstance::OnApplicationWillTerminate() { // 標準出力への書き込み printf("Application is terminating...\n"); fprintf(stdout, "Cleanup complete. Game session ended.\n"); fflush(stdout); // UE_LOGも使用可能 UE_LOG(LogTemp, Warning, TEXT("Application terminating - Final cleanup")); // デバッグ出力(開発時のみ) #if UE_BUILD_DEBUG || UE_BUILD_DEVELOPMENT FString ExitMessage = FString::Printf(TEXT("Exit Time: %s"), *FDateTime::Now().ToString()); UE_LOG(LogTemp, Log, TEXT("%s"), *ExitMessage); #endif } // ======================================== // 方法2: カスタムEngineクラスでの実装 // ======================================== // MyGameEngine.h #pragma once #include "CoreMinimal.h" #include "Engine/GameEngine.h" #include "MyGameEngine.generated.h" UCLASS() class MYGAME_API UMyGameEngine : public UGameEngine { GENERATED_BODY() public: virtual void PreExit() override; virtual void FinishDestroy() override; }; // MyGameEngine.cpp #include "MyGameEngine.h" #include "HAL/PlatformFilemanager.h" void UMyGameEngine::PreExit() { // アプリケーション終了前の処理 printf("=== APPLICATION SHUTDOWN SEQUENCE INITIATED ===\n"); fprintf(stdout, "Engine PreExit called\n"); // ファイルへの書き込みも可能 FString LogPath = FPaths::ProjectLogDir() / TEXT("shutdown.log"); FString ShutdownLog = FString::Printf( TEXT("Application shutdown at: %s\n"), *FDateTime::Now().ToString() ); FFileHelper::SaveStringToFile(ShutdownLog, *LogPath, FFileHelper::EEncodingOptions::AutoDetect, &IFileManager::Get(), FILEWRITE_Append); fflush(stdout); Super::PreExit(); } void UMyGameEngine::FinishDestroy() { printf("Engine cleanup completed\n"); fflush(stdout); Super::FinishDestroy(); } // ======================================== // 方法3: グローバル関数での実装 // ======================================== // MyApp.cpp (プロジェクトのメインファイル) #include "CoreMinimal.h" #include "RequiredProgramMainCPPInclude.h" // グローバル終了ハンドラ void GlobalExitHandler() { printf("\n=== GLOBAL EXIT HANDLER CALLED ===\n"); printf("Application terminated gracefully\n"); printf("Thank you for using our application!\n"); fflush(stdout); } // アプリケーション開始時に登録 void RegisterExitHandler() { // C標準ライブラリのatexit使用 atexit(GlobalExitHandler); // またはUnreal Engineのデリゲート使用 FCoreDelegates::OnExit.AddStatic(GlobalExitHandler); } // ======================================== // 方法4: PlayerControllerでの実装 // ======================================== // MyPlayerController.h #pragma once #include "CoreMinimal.h" #include "GameFramework/PlayerController.h" #include "MyPlayerController.generated.h" UCLASS() class MYGAME_API AMyPlayerController : public APlayerController { GENERATED_BODY() public: AMyPlayerController(); protected: virtual void BeginDestroy() override; virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; }; // MyPlayerController.cpp #include "MyPlayerController.h" AMyPlayerController::AMyPlayerController() { // コンストラクタでの初期化 } void AMyPlayerController::BeginDestroy() { printf("PlayerController being destroyed\n"); fprintf(stdout, "Player session ended\n"); fflush(stdout); Super::BeginDestroy(); } void AMyPlayerController::EndPlay(const EEndPlayReason::Type EndPlayReason) { FString ReasonString; switch(EndPlayReason) { case EEndPlayReason::Destroyed: ReasonString = TEXT("Destroyed"); break; case EEndPlayReason::LevelTransition: ReasonString = TEXT("Level Transition"); break; case EEndPlayReason::EndPlayInEditor: ReasonString = TEXT("End Play in Editor"); break; case EEndPlayReason::RemovedFromWorld: ReasonString = TEXT("Removed from World"); break; case EEndPlayReason::Quit: ReasonString = TEXT("Application Quit"); break; default: ReasonString = TEXT("Unknown"); break; } printf("EndPlay called with reason: %s\n", TCHAR_TO_ANSI(*ReasonString)); fflush(stdout); Super::EndPlay(EndPlayReason); } // ======================================== // 追加: プロジェクト設定での登録方法 // ======================================== /* Config/DefaultEngine.ini に以下を追加: [/Script/EngineSettings.GameMapsSettings] GameInstanceClass=/Script/MyGame.MyGameInstance または [/Script/Engine.Engine] GameEngine=/Script/MyGame.MyGameEngine */
Content is user-generated and unverified.
    UE アプリ終了時標準出力サンプル | Claude