jpnSkill&Container - B477042/GraduationProject GitHub Wiki

About Skill&Container

Skillの拡張性に重点を置いて設計をしました。 これらのSkillActorを管理するためにContainerというComponentを作り、WeakPointerで制御できるように作りました。 SkillにぴったりのContainerを作ったり汎用Containerとして処理した場合もありました。

Skill Actor & Container

SkillActor.h


protected:
UCLASS()
class ESCAPEGAME_API ASkillActor : public AActor
{
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	USceneComponent* Root;

	//形態として使用できる主なエフェクト
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "effect")
	UParticleSystemComponent* VFX_Main;

	//命中時エフェクト
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "effect")
	UParticleSystemComponent* VFX_Hit;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Collision")
	USphereComponent* MainCollision;

	//当たればする音
	UPROPERTY(BlueprintReadWrite, VisibleAnywhere, Category = "Contents")
	UAudioComponent* SFX_Hit;
	//あたりを通りかかった時に出る音
	UPROPERTY(BlueprintReadWrite, VisibleAnywhere, Category = "Contents")
	UAudioComponent* SFX_Passing;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"), Category = Info)
		float Damage;
}

Skillを表現するためにMeshを使うよりもParticleが最も適切ですから、ParticleとSoundを制御する機能を搭載しました。

Component_SkillContainer.h

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ESCAPEGAME_API UComponent_SkillContainer : public UActorComponent
{
public:	

	virtual void UseSkill(const AActor& TargetActor,const FVector& Direction , int n_Count=1) PURE_VIRTUAL(UComponent_SkillContainer::UseSkill,  );

protected:
	void clear();


	UPROPERTY(EditAnywhere,  Category = "contents", meta = (AllowPrivateAccess = "true"))
		TArray< TWeakObjectPtr< ASkillActor > > SkillObjects;
	UPROPERTY(VisibleAnywhere, Category = "contents", meta = (AllowPrivateAccess = "true"))
		TWeakObjectPtr < ASkillActor> CurrentIndex;
	UPROPERTY(VisibleAnywhere, Category = "contents", meta = (AllowPrivateAccess = "true"))
		int Index;
	//配列初期化サイズです。 伸びはしません
	UPROPERTY(VisibleAnywhere, Category = "contents", meta = (AllowPrivateAccess = "true"))
		int ArraySize;
}

Skill Objectをスポンサーしてコンポーネントに追加する方法を採用しました。 UseSkillという関数をPurevirtual形式で宣言し、下位コンポーネントが自分の目的に合う形態の関数を宣言するようにしました。

Skill Actor & Containerを実現する際に集中した点

下位クラスは、どのような特性を持ってゲームを構成するかを考えながら、共通する点を見つけて作成しました。 SkillはVFXとSFXを中心に、ContainerはこのSkillactorをオブジェクトフーリングで管理する技法を使うように作りました。 この二つのクラスを作る目的は、相続を通じた拡張でコードを減らし、Castを通じた制御を楽にするためです。 この目的に合った内容になっています。

下位クラスについて

  • Projectile系列を除いた下位Skillactorは、それぞれの使用時に呼び出し方法と効果を発揮して、どのアセットを利用するかが作成されました。Projectile系列Skillを使用する場合、GunnerのMag Componentのように設定しました。
  • SKill container系列クラスの場合、Ownerの使用要請が発生すると、今使用可能なSkill actorのうちの1つのactorにTransform情報を送信します。 この情報をもとに、Container内部でSkillに命令を下す方法で実現しました。

作成する際に集中した点

  • 相続に基づき、skillを追加しやすくするために集中しました。 コードのリサイクルが可能な相続の特性を利用したコード管理で、生産性を上げたかったです。
  • 相続を適用させる前は、それぞれのクラスを別に作って共通する部分を繰り返し作成しました。 その結果、新しいSkillと管理するComponentを作成するたびに時間が長くかかりました。

作成する際に難しかった点

  • 相続を適用させる前、でたらめに作ったクラスの共通点を把握する過程が難しかったです。 共通の特性を考えられなくて生産性が落ちる方式で作ったので色んな問題がありました。 継承を適用させようと考えたきっかけは、このタイプのActorとComponentを思ったより頻繁に作ることになると気づいた時点でした。 当時、3種類のSkillがあり、このスキルはそれぞれ独立した状態でした。こうやって追加したらきりがないと 思いました。それを解決する方法として相続が思い浮かび、それぞれのスキルの共通する部分を整理しました。 この内容をもとに、ActorはSkillActorにComponentはContainerに相続させました。 この過程で、設計の重要性と生産性を上げる方法として相続を使用することができるという点を学びました。