_13194319
(うりゅー_13)
January 24, 2023, 7:10pm
1
本文:
C++からブループリントのパス経由でACharacterクラスのスポーンができず困っています。
エラー内容としてはアクセス違反で強制終了しますが、スポーンしたアクターがNULLポインタになることが原因であることまでは突き止めました。
現状ACharacterクラスではなく、AActorやAPawnクラスならスポーンができています。
どなたかご教示いただけますでしょうか。
以下、ソースコード(+BP)とその説明
ソースコードのようにブループリントクラスが置いてある場所のパスを指定してロードし、そこからスポーンさせようとしています。aがACharacterクラスだとnullptrになってしまいます。
また、ブループリントクラスはACharacterクラスを継承した独自のEnemyCharacterクラスを継承して作成しています。コリジョンの問題かとも思ったのですが違いそうなので困っています。
High500
(High500)
January 24, 2023, 7:43pm
2
Translation: Can anyone help?
Full Text:
I’m having trouble spawning ACharacter classes from C++ via Blueprint path.
As for the error content, it is forcibly terminated due to an access violation, but we found out that the cause is that the spawned actor becomes a NULL pointer.
Currently, AActor and APawn classes can spawn instead of ACharacter classes.
Can someone tell me?
Below is the source code (+BP) and its explanation.
Like the source code, I specify the path where the blueprint class is located, load it, and try to spawn it from there. If a is an ACharacter class, it will be nullptr.
Also, the Blueprint class inherits from its own EnemyCharacter class, which inherits from the ACharacter class. I thought it might be a collision problem, but it seems to be different, so I’m in trouble.
T_Sumisaki
(T_Sumisaki)
January 25, 2023, 1:21am
3
まず前提として、C++コード内に直接アセットパスを埋め込むのは非推奨である 、ということをご理解ください
提示されている情報からは、 Charger_BP
がACharacterを継承したクラスである、という確認が取れません
写っているのは Corpse_Spear_BP
という別のBPのようです
まずは本当にACharacterを継承しているか確認してみてください
_13194319
(うりゅー_13)
January 25, 2023, 9:54am
4
回答ありがとうございます。
まず前提として、C++コード内に直接アセットパスを埋め込むのは非推奨である 、ということをご理解ください
そうなんですね。最近趣味で始めたのであまり知識がありません。よろしければ参考までに推奨方法を教えていただけますでしょうか。(情報が載っているサイトでも)
提示されている情報からは、 Charger_BP
がACharacterを継承したクラスである、という確認が取れません
写っているのは Corpse_Spear_BP
という別のBPのようです
まずは本当にACharacterを継承しているか確認してみてください
載せている画像では確かに判別できませんでした、申し訳ございません。以下の画像でどうでしょうか。
_13194319
(うりゅー_13)
January 25, 2023, 9:56am
5
新規ユーザのためメディアが1枚まで、という表記がでたのでぶら下げる形でブループリントの親クラスとして使っているEnemyCharacterのヘッダも載せておきます。
T_Sumisaki
(T_Sumisaki)
January 25, 2023, 11:59am
6
アセットパスをハードコードしてしまうと、UnrealEngineの参照管理のサポート(ロード、パッケージ等)を受けられなくなります
C++では設定せず、 UPROPERTY
を通してBP側に参照の設定先を公開し、BP側で具体的なアセットを指定するのが良いでしょう
模範解答のスニペットが公開されているので参考にしてください
アセットパスをハードコードしてはいけない理由については、下記のスレッドが参考になるかと思います
Ah, I see. Thank you.
The system I’m trying to create is one where I store information (Such as DataTables holding Item Data) in some custom project settings. Item objects then pull the info from there, using FObjectFinder (although the ref paths are now saved in a Config file).
Faced with best practices in memory management, would a system like this be worth pursuing? Should I have the Item Info DataTable as a variable in the Item Object?
What is currently in my Item Object Constructor:
FS…
No. Did you miss my post?
Definitely not. If the FObjectFinder isn’t static, then it is invoked for every call to the constructor. It’s “one time” for instances (though in truth, the constructor is not guaranteed to be called) but you’re still senselessly doing the same object find/load for each call to the constructor. If it is static, then it is invoked once (for the CDO) and the result persists for all instances.
void myobject::a()
{
static ConstructorHelpers::FObjectFinder<UBlueprint> …
手元で再現を試みていますが、提示されているコードでは事象は再現しませんでした
もう少し詳しい情報が必要です
類似事象としては、(0,0,0)付近がCollisionで埋められている場合に、Spawnが成功せず、結果nullになるケースが確認できました
これに該当する場合、回避するのであれば、Locationを確実に空いている場所に指定するか、SpawnInfoを使って SpawnCollisionHandlingOverride
を AlwaysSpawn
に設定する必要があります
1 Like
_13194319
(うりゅー_13)
January 25, 2023, 12:55pm
7
アセットパスをハードコードしてしまうと、UnrealEngineの参照管理のサポート(ロード、パッケージ等)を受けられなくなります
C++では設定せず、 UPROPERTY を通してBP側に参照の設定先を公開し、BP側で具体的なアセットを指定するのが良いでしょう
丁寧に教えてくださり、ありがとうございます。提示していただいたスレッドも参考にさせていただきます。
類似事象としては、(0,0,0)付近がCollisionで埋められている場合に、Spawnが成功せず、結果nullになるケースが確認できました
これに該当する場合、回避するのであれば、Locationを確実に空いている場所に指定するか、SpawnInfoを使って SpawnCollisionHandlingOverride
を AlwaysSpawn
に設定する必要があります
おそらくこれが原因っぽいです。確かにバトル画面では(0,0,0)に敵キャラを移すカメラアクターが存在していて、コリジョンで埋められています。また、敵キャラはスポーンさせた後に位置を変えようとしている(提示したコードの後に書かれている)ので、コリジョンがあると判断されてスポーンしないと推測できます。
また、SpawnCollisionHandlingOverride
を AlwaysSpawn
に以前したときに、敵とのエンカウント方法がシンボルエンカウント(接触したら画面遷移)で、ゲームを始めた時に毎回プレイヤーと敵のスポーン場所が同じでフィールド画面が表示されないという問題に遭遇してしまったため、Try to Adjust Location, Don't Spawn
に設定しています。
ゲームシステムの話は余談になってしまいましたが、私もコリジョンの可能性を疑って、アクタをスポーンさせるときにLocationを指定してスポーンするように変えようと思ったのですが、上手く調べることができず断念してしまった記憶があります。よろしければ、そういった方法を教えていただけないでしょうか。(あるいはカメラの位置を変えたほうがいいのでしょうか?)
_13194319
(うりゅー_13)
January 25, 2023, 1:21pm
8
追記です
どうやらブループリントのキャラの設定(メッシュかカプセルコンポーネント)が悪いらしく、強制的にスポーンさせると体が地面に埋まっていました。
おそらくこっちが本当の原因かと思います。。。
ACharacterクラスにすると、自動的に追加されるカプセルコンポーネントが地面に埋まっていて動かせず、メッシュに合わせられないのですが、これはどのようにするのが正解なのでしょうか。参考までに画像を貼っておきます。
長文で申し訳ありません。
T_Sumisaki
(T_Sumisaki)
January 25, 2023, 1:37pm
9
Try to Adjust Location, but Always Spawn
であれば、Collisionの埋まりを回避しつつ、かつ必ずSpawnする、という状態になります
CharacterのSkeletalMeshは足元(≒root)をCapsuleの下端まで位置を下げるのが基本です
ThirdPersonTemplateの構成を参考にすると良いでしょう
シンボルエンカウントの場合、最初にシンボルがSpawnする位置は決まっている(Playerと同じ場所にSpawnすることはない)はずなので、まずはそちらから解決するほうが良いでしょう
いわゆるSpawnerのようなものを作るとよいかと思います
Spawnerを使わず一括で生成するにしても、PlayerStartのような、場所を指定するための専用のActorを用意し、そこから位置情報を取得するようにするほうが、レベルデザインをする上でも楽になるかと思います
_13194319
(うりゅー_13)
January 25, 2023, 3:50pm
10
CharacterのSkeletalMeshは足元(≒root)をCapsuleの下端まで位置を下げるのが基本です
ThirdPersonTemplateの構成を参考にすると良いでしょう
ありがとうございます、ThirdPesonと同じように設定して、Always Spawn にしたら無事スポーンしました!
シンボルエンカウントの場合、最初にシンボルがSpawnする位置は決まっている(Playerと同じ場所にSpawnすることはない)はずなので、まずはそちらから解決するほうが良いでしょう
いわゆるSpawnerのようなものを作るとよいかと思います
Spawnerを使わず一括で生成するにしても、PlayerStartのような、場所を指定するための専用のActorを用意し、そこから位置情報を取得するようにするほうが、レベルデザインをする上でも楽になるかと思います
なるほど。ご指摘ありがとうございます。Player Startをそのままレベルにおいているので、そこから位置情報を取得するようにします。
長々とお付き合いいただきありがとうございました。大変助かりました。