・前回までで、電池を生成することができるようになりました。
・今回は、電池を回収する機能を追加していきます。

・回収のためのコードは、PickupクラスとCharacterクラスに書きます。
・Pickupは、回収された時のリアクションを決めて、Characterは回収の関数を呼びだします。
〇電池回収時のリアクション関数
Pickup.h
UFUNCTION(BlueprintNativeEvent)
void WasCollected(); //ピックアップ回収時に呼ばれる関数
※完成形
・BlueprintNativeEvent:C++で基本的な実装を行い、Blueprintでロジックを拡張するために、オーバーライドして使用することが出来る。

〇C++側での実装は「"関数名"_Implementation」という記述をする
Pickup.h
virtual void WasCollected_Implementation();
※完成形
・BlueprintNativeEventであるため、Implementation(訳:実装)の宣言をする必要がある。
・宣言では、virtualを使って、子クラスでオーバーライドできるようにしている。
・WasCollectedを呼びだすと、一度の呼び出しで「コードの実装」と「BPの実装」の両方を呼ぶ。

〇回収した物のデバック用文字列を表示させる
Pickup.cpp
void APickup::WasCollected_Implementation()
{
FString PickupDebugString = GetName();
UE_LOG(LogClass, Log, TEXT("YOU have collected %s"), *PickupDebugString);
}
※完成形
・回収したピックアップの名前を取得(GetName)し、アウトプットログに表示する。
・UE_LOGについてのリンク
Just a moment...

〇BatteryPickup.hで、WasCollected_Implementationをオーバーライドする
・少しだけ特別な機能(消去)を持たせる。
BatteryPickup.h
void WasCollected_Implementation() override;
※完成形
・他クラスから呼びだせるようにpublic指定子

〇WasCollected_Implementationのオーバーライド(電池が回収されたときの動作)
BatteryPickup.cpp
void ABatteryPickup::WasCollected_Implementation()
{
/* ベースとなるピックアップの機能を使う。親の関数を呼び出す */
Super::WasCollected_Implementation();
/* 電池を破棄する */
Destroy();
}
※完成形
・Superを使うことで親クラスの機能を使い、更にコード(Destroy関数)を追加することで派生クラス特有の機能としている。
※1・・・親のPickupクラスにDestroy機能を持たせなかったのは、例えばパワーアップアイテムのように、少しの間だけ非アクティブになり、その後再度アクティブになるような挙動が必要になるかもしれなかったため。「破棄機能」は全体に適用しないで、電池にだけ持たせるようにした。

〇ビルド
・ここまでのコードでエラーが無いことを確認し、次へ進む。
【ここまで出来たこと】
・PickupクラスのWasCollected_Implementation関数と、BatteryPickupクラスのWasCollected_Implementation関数を実装したが、まだこれらの関数を呼び出すものは実装していない。
【これからやること】
・まず、大きな球体(SphereCollision)をCharacterに追加する。
・その球体が、ピックアップのいくつかと重なった場合、その範囲内にあるピックアップ物のWasCollectedを呼び出すようにする。そのための関数をCharacter側に追加する。
〇ここからは、「BatteryCollectorCharacter」クラスで作業を行っていきます。
〇回収用の球体を作る
BatteryCollectorCharacter.h
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USphereComponent* CollectionSphere;
※完成形
・「BatteryCollectorCharacter」は、Thirdpersonテンプレートを作った時に作成されたCharacterなので、Chatacterクラスの機能が既に備わっている。それに足りない機能を足すだけ。

〇回収用の球体変数のアクセサ関数(ゲッター)を作る
BatteryCollectorCharacter.hの下の方
FORCEINLINE class USphereComponent* GetSphereComponent() const { return CollectionSphere; }
※完成形
・直前のコード(下図では68行目のGetFollowCamera関数)をコピー&ペーストして改良・改修。

〇CollectionSphereの生成
BatteryCollectorCharacter.cpp
#include "Components/SphereComponent.h"
// コンストラクタで、CollectionSphereの生成
CollectionSphere = CreateDefaultSubobject<USphereComponent>(TEXT("CollectionSphere"));
CollectionSphere->SetupAttachment(RootComponent);
CollectionSphere->SetSphereRadius(200.0f);
※完成形
・SphereComponent用のIncludeファイルを追加。

・コンストラクタで、CollectionSphereの生成を追加

〇ビルド
・エラーが無ければOK。
〇今回やったこと。
・ベースのPickupと、BatteryPickupに回収の関数を追加。
・回収するために、Character側にCollectionSphereを追加。
・次は、回収関数を作ることで、ピックアップ物と相互作用(インタラクト)を出来るようにしていきます。
・以上、お疲れ様でした。
【参考までに】
〇コンソールコマンドで、コリジョンを表示してみる。
・テストプレイ>UEエディタの下「Cmd」があるので、「show collision」とタイピングする。

キャラクターに、大きなSphereCollisionが付いていることが確認出来ます。
