Unreal Engineで登山システム用のモーションコンポーネントを作成する

画像



こんにちは私の名前はドミトリーです。 私は趣味としてアンリアルエンジンでコンピューターゲームを作っています。



ご存知のように、Mirror's edge 2は最近リリースされましたが、批評家のレビューから判断すると、ゲームは非常に弱いことが判明しました。 そして、おそらくあなたはすでにミラーのエッジを作りたいと思っていました。 したがって、今日は、キャラクターがミラーの端のヒロインのように動くようにモーションコンポーネントを作成する方法を説明します。



これは、キャラクターを許可するモーションコンポーネント(以下、CDと呼びます)の作成について説明します。

1)壁にバウンスします。

2)壁に沿って走る。

3)小さな障害物を飛び越える

4)連続走行で加速を行う

5)Shiftキーを押しながらタックルをする

6)傾斜面を下にスライド

7)また、インタラクティブなロープオブジェクトを作成します。



すべてのソースは記事の最後に記載されています。





動きのコンポーネントについて初めて聞く場合は、すべてが非常に詳細なEpic Gamesのレッスンを受けることをお勧めします。



UCharacterMovementComponentをCDのベースオブジェクトとして使用しましたが、このモーションコンポーネントはすでにキャラクターの歩行、水泳、飛行を許可しています。



UCLASS() class CLIMBINGSYSTEM_API UClimbingPawnMovementComponent : public UCharacterMovementComponent { GENERATED_UCLASS_BODY() public: UFUNCTION(BlueprintCallable, Category = "ClimbingMovement") void SetClimbMode(EClimbingMode _ClimbingMode); UFUNCTION(BlueprintPure, Category = "ClimbingMovement") EClimbingMode GetClimbingMode() const; UFUNCTION(BlueprintPure, Category = "ClimbingMovement") bool CanSetClimbMode(EClimbingMode ClimbingMode); /*Offset from top of climbing surfase*/ UPROPERTY(Category = "ClimbingMovement|Climb", EditAnywhere, BlueprintReadWrite) int32 ClimbDeltaZ; /*Velocyty of climb movement*/ UPROPERTY(Category = "ClimbingMovement|Climb", EditAnywhere, BlueprintReadWrite) float ClimbVelocyty; /*Velocyty of jump from climb state*/ UPROPERTY(Category = "ClimbingMovement|Climb", EditAnywhere, BlueprintReadWrite) float ClimbJumpVelocyty; /*Angle from center when state can change in degres*/ UPROPERTY(Category = "ClimbingMovement|WallRun", EditAnywhere, BlueprintReadWrite) float WallRunLimitAngle; /*Offset from Wall when Wall Run*/ UPROPERTY(Category = "ClimbingMovement|WallRun", EditAnywhere, BlueprintReadWrite) int32 WallOffset; /*Fall Gravity Scale when charecter run on wall*/ UPROPERTY(Category = "ClimbingMovement|WallRun", EditAnywhere, BlueprintReadWrite) float WallRunFallGravityScale; /*Multiplier input vector when charecter run on wall*/ UPROPERTY(Category = "ClimbingMovement|WallRun", EditAnywhere, BlueprintReadWrite) int32 WallRunInputVelocyty; /*Velocyty of jump near wall*/ UPROPERTY(Category = "ClimbingMovement|WallRun", EditAnywhere, BlueprintReadWrite) float WallRunJumpZVelocyty; /*Velocyty of jump from wall run state*/ UPROPERTY(Category = "ClimbingMovement|WallRun", EditAnywhere, BlueprintReadWrite) float WallRunJumpVelocyty; /*Offset from rope of zip line*/ UPROPERTY(Category = "ClimbingMovement|ZipLine", EditAnywhere, BlueprintReadWrite) int32 ZipLineDeltaZ; /*Velocyty*/ UPROPERTY(Category = "ClimbingMovement|ZipLine", EditAnywhere, BlueprintReadWrite) float ZipLineVelocyty; /*Velocyty of jump from Zip Line state*/ UPROPERTY(Category = "ClimbingMovement|ZipLine", EditAnywhere, BlueprintReadWrite) float ZipLineJumpVelocyty; /*Angle of surfase when character slide*/ UPROPERTY(Category = "ClimbingMovement|InclinedSlide", EditAnywhere, BlueprintReadWrite) float InclinedSlideAngle; UPROPERTY(Category = "ClimbingMovement|InclinedSlide", EditAnywhere, BlueprintReadWrite) float InclinedSlideVelosytyForward; UPROPERTY(Category = "ClimbingMovement|InclinedSlide", EditAnywhere, BlueprintReadWrite) float InclinedSlideVelosytyRight; UPROPERTY(Category = "ClimbingMovement|InclinedSlide", EditAnywhere, BlueprintReadWrite) float InclinedJumpVelocyty; /*Velocyty of Run movement*/ UPROPERTY(Category = "ClimbingMovement", EditAnywhere, BlueprintReadWrite) float RunSpeed; /*delay before Run movement in sec*/ UPROPERTY(Category = "ClimbingMovement", EditAnywhere, BlueprintReadWrite) float RunDelay; /*Velocyty of jump near wall*/ UPROPERTY(Category = "ClimbingMovement", EditAnywhere, BlueprintReadWrite) float UnderWallJumpZVelocyty; UPROPERTY(Category = "ClimbingMovement", EditAnywhere, BlueprintReadWrite) FRuntimeFloatCurve SlideVelocytyCurve; /*UCharacterMovementComponent Interfase*/ virtual bool DoJump(bool bReplayingMoves) override; virtual float GetMaxSpeed() const override; virtual void BeginPlay() override; virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; private: EClimbingMode ClimbingMode; EClimbingMode LastClimbingMode; bool BlockClimb; bool BlockWallRun; bool BlockInclinedSlide; FTimerHandle RunTimerHandle; bool bIsRun; float MinSlideTime; float MaxSlideTime; FTimerHandle InclinedSlideTimerHandle; void SetRun(); void DefineClimbMode(); bool SetMode(EClimbingMode ClimbingMode); void UnSetMode(EClimbingMode ClimbingMode); void UnBlockInclinedSlide(); void UnblockClimbState(); void UnblockWallRunState(); bool CheckDeltaVectorInCurrentState(const FVector& InputDeltaVector, FVector& CheckDeltaVector, FRotator& CheckRotation); //Check climb is possibly from Approximate coordinate and return realy coordinate bool CheckDeltaVectorInCurrentState(FVector& CheckDeltaVector, FRotator& CheckRotation); //Check climb is possibly in current character location coordinate and return realy coordinate bool CheckDeltaVectorInCurrentState();//Check climb is possibly in current character location without return new coordinates void MoveTo(const FVector& Delta, const FRotator& NewRotation); };
      
      







したがって、見てのとおり、CDはClimbingMode変数の値に応じて、1つまたは別の動作モデルを決定する有限状態マシンです。 そして今、主な方法について:

DoJump-キャラクターがジャンプしている場合に呼び出されます。

TickComponent-最も重要な関数であり、すべてのフレームが呼び出されます。 これは、メインコードが機能する場所です。

SetClimbMode-CDをある状態から別の状態に切り替えます

DefineClimbMode-CDを切り替える状態を決定します。

CanSetClimbMode-CDが現時点で目的の状態に切り替えることができるかどうかを決定します。

CheckDeltaVectorInCurrentState-キャラクターが移動するベクトルを取得し、キャラクターが新しい座標で指定された状態を維持できる場合、true、指定された座標、およびキャラクターの回転角をfalseで返します。

MoveTo-キャラクターを希望の位置に移動します。



UCharacterMovementComponentオブジェクトは、ACharacterオブジェクトと連携してのみ機能します。 したがって、キャラクターのクラスはACharacterから派生します。

 UCLASS() class CLIMBINGSYSTEM_API AClimbingCharacter : public ACharacter { GENERATED_BODY() public: UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly) USpringArmComponent* CameraSpringArm; UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly) UCameraComponent* Camera; // Sets default values for this pawn's properties //AClimbingCharacter(); AClimbingCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); // Called when the game starts or when spawned virtual void BeginPlay() override; // Called every frame virtual void Tick( float DeltaSeconds ) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override; void MoveForward(float AxisValue); void MoveRight(float AxisValue); void CameraPitch(float AxisValue); void CameraYaw(float AxisValue); UFUNCTION(BlueprintCallable, Category = "Pawn|Character") virtual void Jump() override; UFUNCTION(BlueprintCallable, Category = "ClimbingCharacter") void ChangeView(bool FistPirson); void SwitchView(); void CrouchFunk(); void UnCrouchFunk(); virtual void NotifyActorBeginOverlap(AActor* OtherActor) override; private: /** Pointer to climbing movement component*/ UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) class UClimbingPawnMovementComponent* ClimbingMovement; class AOverlapObject* OverlopObject; class AZipLine* ZipLine; bool bFistPirsonView; USkeletalMeshComponent* ClimbMesh; UCapsuleComponent* ClimbCapsule; friend class UClimbingPawnMovementComponent; };
      
      







そして、ここに最初の問題があります。 実際、ACharacterオブジェクトは、コンストラクターでUCharacterMovementComponentオブジェクトを生成します。 しかし、必要なのはUCharacterMovementComponentではなく、UClimbingPawnMovementComponentです。 ACharacterでUClimbingPawnMovementComponentを生成するには、AClimbingCharacterコンストラクターを以下から変更する必要があります。

 AClimbingCharacter::AClimbingCharacter(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) {
      
      





これについて:

 AClimbingCharacter::AClimbingCharacter(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer.SetDefaultSubobjectClass<UClimbingPawnMovementComponent>(ACharacter::CharacterMovementComponentName)) {
      
      





これで、ACharacterは必要なものを生成します。



これはおもしろいです 。おそらく「スーパー」という言葉に気づいたでしょう。それはどういう意味ですか? Superという単語は、使用されるオブジェクトの基本クラスの名前を置き換えます。 つまり、Super :: Tick()と記述すると、オブジェクトの基本クラスからTickメソッドを呼び出したことになります。



次に、主な方法について説明します。



ChangeViewメソッドに魅了されている必要があります。 はい、Fボタンを押すと、一人称視点から三人称視点に切り替えることができます。 これはキヤノンとは異なりますが。



MoveForward、MoveRight、CameraPitch、CameraYaw、CrouchFunk、UnCrouchFunk、Jumpメソッドは、キーボードとマウスの入力を担当します。



NotifyActorBeginOverlapメソッドは、キャラクターが他のオブジェクトを横切るとトリガーされます。 すべての対話型オブジェクトについて、基本クラスAOverlapObjectを作成しましたが、次のとおりです。

 UCLASS() class CLIMBINGSYSTEM_API AOverlapObject : public AActor { GENERATED_BODY() public: enum EClimbingMode GetObjectType() const; protected: UPROPERTY(Category = ObjectType, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) TEnumAsByte<enum EClimbingMode> ObjectType; };
      
      





このオブジェクトには、EClimbingMode型の変数が含まれています。



これまで、インタラクティブオブジェクトを1つだけ作成しましたが、AZipLineは、キャラクターがそれをつかんでロールダウンするロープです。 ミラーのエッジでプレイした場合、あなたは私が話していることを理解しています。

 UCLASS() class CLIMBINGSYSTEM_API AZipLine : public AOverlapObject { GENERATED_BODY() public: AZipLine(); virtual void OnConstruction(const FTransform& Transform) override; virtual void PostEditMove(bool bFinished) override; /** The main skeletal mesh associated with this Character (optional sub-object). */ UPROPERTY(Category = ZipLine, VisibleDefaultsOnly, BlueprintReadOnly) class UStaticMeshComponent* StartBase; UPROPERTY(Category = ZipLine, VisibleDefaultsOnly, BlueprintReadOnly) class UStaticMeshComponent* EndBase; UPROPERTY(Category = ZipLine, VisibleDefaultsOnly, BlueprintReadOnly) class USplineComponent* Spline; UPROPERTY(Category = ZipLine, VisibleDefaultsOnly, BlueprintReadOnly) USceneComponent* Pivot; UPROPERTY(Category = ZipLine, VisibleDefaultsOnly, BlueprintReadOnly) UBoxComponent* EndBox; UPROPERTY(Category = ZipLine, EditAnywhere, BlueprintReadOnly) UStaticMesh* RopeMesh; UPROPERTY(Category = ZipLine, EditAnywhere, BlueprintReadOnly) float SplineHeight; #if WITH_EDITORONLY_DATA UPROPERTY() class UArrowComponent* ArrowComponent; #endif protected: TArray<class USplineMeshComponent*> AddedSplineMeshComponents; void SetupSpline(); };
      
      







OnConstructionメソッドは、ブループリントのConstructionScript関数に似ており、ectorが移動または変更されたときにも呼び出されます。 確かに、ブループリントですべての追加されたオブジェクトが再構築のたびに自動的に破棄される場合、c ++では自分でオブジェクトを破棄する必要がある場合、わずかな違いがあります。



小さなデモ:



実際、これについてはソースが約束したとおりです。 人気のある需要により、私はそれらをgithubに投稿しました。



All Articles