〇今回は、電池のスポーンボリューム(生成体)を作っていきます。
※電池のようなピックアップ物(シリンダー)を、上空から一定間隔で落ちてくるようにします。
・前回は、下図のようにキューブとシリンダー(電池)を直接レベルに配置して落下テストを行いましたが、これら(「Pickup_BP」と「Battery_BP」)は仮置きしただけなので、2つ共削除しておいてください。

〇電池の生成体(スポーンボリューム)作成前に、必要な要素を洗い出す
・ピックアップ物を「生成」するための設定情報。
1. 場所(どこに)
2. 物(何を)
3. タイミング(いつ)
・まず最初に、スポーンさせる「場所」の設定を行っていきます。
※ここでは、SpawnVolumeはBP化せずに、直接レベルに配置して使うことにします。
(多様なワークフローを学んで欲しいため)
〇SpawnVolumeクラスの作成
・BatteryCollectorフォルダで右クリック>「新規C++クラス」を選択。

・親クラス:Actor
・「次へ」ボタンをクリック
※SpawnVolumeはレベルに配置するものなので、Actorにする。

・ファイル名:SpawnVolume
・「クラスを作成」ボタンをクリック
※SpawnVolume.hとSpawnVolume.cppが生成されます。

〇生成場所を指定するために、BoxComponentを使う。
※UPROPERTYは、Pickup.hで設定済みのものをコピーして、Categoryのみ「Spawnning」に変更しています。
SpawnVolume.h
private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Spawnning", meta = (AllowPrivateAccess = "true"))
class UBoxComponent* WhereToSpawn;
※完成形


〇WhereToSpawn変数のゲッターをpublicセクションに記述
※privateの変数を、publicの関数でアクセスする。
SpawnVolume.h
FORCEINLINE class UBoxComponent* GetWhereToSpawn() const { return WhereToSpawn; }
※完成形

※「Pickup.h」で以前に記述したコードが似ているので、コピーして変更しても良いです。

【説明:FORCEINLINEが使えないケース】
・Pickupクラスでは、同じような関数「IsAlive」がありましたが、FORCEINLINEを使っていません。
UFUNCTIONマクロがある場合、その関数をFORCEINLINEにすることができないためです。
※IsActive関数は、Blueprintで使うことを想定したため、FORCEINLINEを使用していません。

〇コンストラクタでUBoxComponent生成
SpawnVolume.cpp
#include "Components/BoxComponent.h"
ASpawnVolume::ASpawnVolume()
{
PrimaryActorTick.bCanEverTick = false;
WhereToSpawn = CreateDefaultSubobject<UBoxComponent>(TEXT("WhereToSpawn"));
RootComponent = WhereToSpawn;
}
※完成形
・下図で4箇所、追加修正

〇スポーンボリューム内でランダムな地点を見つける関数(ピックアップをスポーンする場所)を追加
SpawnVolume.h
UFUNCTION(BlueprintPure, Category = "Spawning")
FVector GetRandomPointInVolume();
※戻り値はベクターで、ボリューム内の地点を表す。
※BlueprintPure:実行ピンを持たないノード。
※UFUNCTIONは、「Pickup.h」内の記述済みのコードを再利用。
※完成形

〇GetRandomPointInVolumeの関数定義
SpawnVolume.cpp
#include "Kismet/KismetMathLibrary.h" //追加:RandomPointInBoundingBox用
FVector ASpawnVolume::GetRandomPointInVolume()
{
FVector SpawnOrigin = WhereToSpawn->Bounds.Origin; //中心
FVector SpawnExtent = WhereToSpawn->Bounds.BoxExtent; //ボックスの範囲(半径)
return UKismetMathLibrary::RandomPointInBoundingBox(SpawnOrigin, SpawnExtent);
}
※完成形

〇ここまでで一旦ビルド。
・エラーがなければOKです。
【参考までに:BlueprintでBoxComponentから敵を生成するロジック】
※「RandomPointInBoundingBox」ノードを使って、Box内からランダムな位置を返しています。

・今回は、ピックアップ物の「生成場所」に関する処理が完成しました。
・次回は、スポーンする「物」関する処理を追加していきます。
・以上、お疲れ様でした。