DestroyActorした後もデータは残ってる問題
「一昨日書いた変数を空っぽにする方法なんだけど、妹の要望が変数を空にするだけだったから、Nullを入れとけばいいという話をしたんだけど、アクタそのものを削除したいという場合はちょっと話が違ってくる」
妹「アクタそのものを削除するというと、ぶつかったら消えるやつみたいな?」
nullをセットしても…
アクタは消えない
「そうそう。非表示とかじゃなくてエディタのアウトライナからも居なくなるようなケース。この場合、変数の方をいくらNullにしても、アクタ自体は残ったままになる」
妹「それは……そういうものなのでは?」
「でも普通のクラスだとこういう仕様にはなってない。それを入れてた変数をNullにすれば、ブループリントからアクセスする手段がなくなるから、もう要らなくなったんだと判断して、ガベージコレクションの対象になる。前にちょっと話したメモリ上のゴミ収集」
妹「でもアクタって変数に入れないこともあるよね? 弾とかスポーンさせても、別にどこにもセットしてない。それで要らない物と言われると困るような? 弾用の配列とか作らないといけなくなる」
「多分そういうことで特殊な仕様なんだろうと思う。内部的には弾用というか、アクタ用の専用配列があるんだと思う。他の変数を全部Nullに変えてもそこには残ってるから、ガベージコレクションの対象にならない。アクタを列挙するノードがあるから、変数になくてもアクセスする手段もある」
妹「ふんふん、でもDestroyActorで消せるから大丈夫でしょ。それで消したことあるし」
「そう、アクタに関してはSwawnActorとDestroyActorという専用命令があって、それを使う。使うんだけど、実は消した後のアクタって、ちょっとおかしなことになってる」
DestroyActorでアクタは消える
消えてるのに何故かGetDisplayが使えて、消したアクタの名前が出てくる
「DestroyActorはアクタを削除するノードだし、内部的なアクタ配列からも削除されてアウトライナからも見えないんだけど、でもアクタのデータ自体は残ってる。データが残ってるから名前も出てくる。DestroyActorの直後だけじゃなくずっと残る」
妹「オバケ……」
「削除済みアクタとNullは別物だから、「=」を使ってNullと比較するとFalseになる。代わりにIsValidを使えば、Nullでも削除済みアクタでも同じ用に判定出来る。それと、そのままだと"変数にSETされたアクタ"だから、ガベージコレクションの対象にならなくて、メモリの無駄が生じることになる」
妹「ひょっとして削除した後にNullをセットした方がいい?」
「Nullをセットするか、別のアクタをセットすると、ゾンビになったアクタは消えていく。普通は使ってるうちに別のがセットされるだろうから、IsValidのチェック忘れなければそんなに実害はないと思うけど。配列の場合はその項目をRemoveすればい