質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.39%
Unreal Engine

Unreal Engineは、Epic Games社によって開発されたゲームエンジンです。高レベルの移植性を持っており、様々なプラットフォームのゲーム開発が可能。GitHubアカウントを登録すれば無料でダウンロードできます。

UE4

UE4はUnreal Engine(アンリアルエンジン)の第4世代です。 UEは、Epic Gamesより開発されたゲームエンジンです。

Q&A

解決済

2回答

10494閲覧

UE4.25 GCが破棄するオブジェクトの仕組みについて知りたい

torano

総合スコア92

Unreal Engine

Unreal Engineは、Epic Games社によって開発されたゲームエンジンです。高レベルの移植性を持っており、様々なプラットフォームのゲーム開発が可能。GitHubアカウントを登録すれば無料でダウンロードできます。

UE4

UE4はUnreal Engine(アンリアルエンジン)の第4世代です。 UEは、Epic Gamesより開発されたゲームエンジンです。

0グッド

0クリップ

投稿2020/05/27 10:23

編集2020/05/30 07:07

何がしたいか

UE4のGC、ガベージコレクションの仕組みを知りたくて検証用のプロジェクトをつくってみたのですが思ったようにいかないので困っています。そのプロジェクトでは一定時間おきに破棄される変数をつくりどのタイミングで破棄されるか確認をしています。

まず自分のGCの理解ですが、下記の参考サイトを見て自分は以下のような場合にGCによって意図せずに変数が破棄されてしまう場合がある、と理解しました。

  • NewObjectを使って変数を動的に生成する
  • ActorやComponent以外のUPROPERTYをつけていないUObject(またはそれを継承したクラス)のメンバー変数を宣言する

参考にしたサイト
Real Unreal Engine C++ 2017-12 (part-1/5) - C++ ときどき ごはん、わりとてぃーぶれいく☆
凡人の活動記録: UE4のUObjectを継承したオブジェクトについて

そこで理解が本当にあっているか確認するための以下のようなプロジェクトをつくりました。

確認用のプロジェクト

以下のように2つのUObjectをつくりました。UGC_Checker::Initialize()ではNewObjectを使ってNon_UP_TestClassとUP_TestClassを初期化しています。Non_UP_TestClassはUPROPERTYをつけていないのでGCで破棄されるが、UP_TestClassは残るという予想です。

C++

1UCLASS() 2class UE_GC_CHECK_API UTestClass : public UObject 3{ 4 GENERATED_BODY() 5 6 UTestClass(); 7 int Value; 8}; 9 10UCLASS(BlueprintType) 11class UE_GC_CHECK_API UGC_Checker : public UObject 12{ 13 GENERATED_BODY() 14 15 UTestClass* Non_UP_TestClass; 16 17 UPROPERTY() 18 UTestClass* UP_TestClass; 19 20public: 21 UFUNCTION(BlueprintCallable) 22 void Initialize(); 23 24 UFUNCTION(BlueprintCallable) 25 UTestClass* GetNonUPTestClass(); 26} 27 28// .cppの中身 29void UGC_Checker::Initialize() 30{ 31 Non_UP_TestClass = NewObject<UTestClass>(this); 32 UP_TestClass = NewObject<UTestClass>(this); 33} 34 35UTestClass* UGC_Checker::GetNonUPTestClass() 36{ 37 return Non_UP_TestClass; 38}

そして別にアクターのC++クラスをつくりました。BeginPlayでGC_Checker_InstanceをNewObjectし、Initialize関数を実行しています。

C++

1UCLASS(Blueprintable) 2class UE_GC_CHECK_API AGC_Checker_Actor : public AActor 3{ 4 GENERATED_BODY() 5 6public: 7 // Sets default values for this actor's properties 8 AGC_Checker_Actor(); 9 10protected: 11 // Called when the game starts or when spawned 12 virtual void BeginPlay() override; 13 14public: 15 // Called every frame 16 virtual void Tick(float DeltaTime) override; 17 18 UPROPERTY(VisibleAnywhere, BlueprintReadOnly) 19 UGC_Checker* GC_Checker_Instance; 20};

このアクターのBlueprintをつくり、これは以下のように設定しました。
イメージ説明
アクターをレベルに配置し実行してみましたが、ずっとNon_UP_TestClass: Validと表示されたままです。

設定のEngine > Garbage Collection > Time Between Purging Pending Kill Objectsは61.099998なので、1分ちょいごとにGCがおこっているはずなのですが、数分たってもNon_UP_TestClassは破棄されないようです。

また検索している最中に同じようなことをしているサイトをみつけました。
[Unreal C++]意図しないガベージコレクションを起こす
そこで記事に書いてある通り(ただしTArray<class UGameVar> GetGameVariables() const;はポインターなくてエラーになっていたのでTArray<class UGameVar*> GetGameVariables() const;としました。)に試してみたのですがずっとValidのままです。

エンジン自体に何かしらの変更があったのか、それとも私のやっている何かが間違っているのでしょうか。
回答よろしくお願いします。

環境

UE4 4.25
Windows 10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

こちらの環境では下記のような挙動をしました
4.24→GCが二回走った時点でクラッシュ
4.25→クラッシュ自体起こらず(IsNotValidにもならず)
確かなことは言えませんが4.25からUPROPERTYが廃止(FPROPERTYに移行)などあり、
もしかしたらその影響でGCの対象・非対象の動きも変わっているのかもしれません

投稿2020/05/30 05:35

編集2020/05/30 05:36
MMashiro

総合スコア2378

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torano

2020/05/30 08:02

UPropertyがFPropertyに変更されたんですね。 FPropertyがUObject継承しなくなったり、new/deleteしなきゃいけなくなったり、宣言時にはUPROPERTY() TFieldPath<FProperty> MemberVariable;としなくなったりと変更があったみたいですが、今回の例だとそもそもUObject継承したクラスを使っているのでFPropertyとはそんなに関係ないような気がしましたがどうなんでしょうね。。(とりあえずUPROPERTY() TFieldPath<UTestClass>で宣言してみましたがやっぱりエラーが出ますし。) リリースノートやUnreal Engine JPのYoutubeチャンネルの解説みてみても解決方法は見つけられませんでした。
MMashiro

2020/05/30 12:15

自分もそこまでGCの挙動に関して詳しくないので確証はないです。 (あくまで4.25かつ手元で再現ができなくなったというだけです) より詳しい情報が欲しい場合はteratailよりAnswerHubでご質問される方が回答を得られる可能性が高いかもしれません
torano

2020/05/30 12:27

わかりました、そちらに行ってみます。ありがとうございます。
guest

0

自己解決

C++スクリプト側でnullチェックやったりIsValid()関数使ってもPending Killになるのが確認できなかったのですが、IsValidLowLevel()を使ってみると予期した通りUPROPERTYなしのUObjectがすぐfalseを返すようになりました。

4.25だから、というのは関係なかったみたいです。

投稿2020/05/31 15:51

編集2020/05/31 16:05
torano

総合スコア92

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問