主なコンテンツ

〜主なコンテンツ〜

1. Unityで製作したゲームと製作Tips
  1. 三月精チャレンジ(東方Project二次創作)
    1. 作り方
  2. 英語学習2D(オリジナルスマホアプリ)
2. UE4
3. ゲームアプリ見学
4. Bitbucket & SourceTreeでの一連の流れ
  1. 前半
  2. 後半
5. Tips
  1. UnityのTips
  5. SQL文のTips
  6. Final IK
  7. GearVR+Unity

2023年2月6日月曜日

40. Character Movement

 おかえり。


これで、スプリング アームとカメラ コンポーネントにキャラクターができました。


プロジェクトとプログラムの入力、キャラクターの移動機能を構成する必要があります。


始めましょう。


そのため、プロジェクトにはいくつかの入力が必要になります。 そのために、編集とプロジェクト設定に進みます。


ここから、入力を選択して、アクション マッピングと AXIS マッピングを展開します。


ここで、軸マッピングにいくつかのアクションが見られます。これらは、ラーニング キット ゲームからいくつかのアセットを移行したときに作成されました。


プロジェクト設定からこれらの軸マッピングをすべて削除します。 これをすべてゼロから行いましょう。


アクション マッピングでは、ジャンプできるようにしたいと考えています。

ジャンプ アクション マッピングを作成し、これをスペースバーにマッピングします。 このアイコンをクリックしてスペースバーを押すと、スペースバーをジャンプ アクション マッピングにリンクできます。


AXIS マッピングでは、これらのいくつかが必要になります。


1 つ追加して、これを MoveForward と呼びます。 そして、これを W キーにマッピングしたいと思います。 また、これを S キーにマップし、スケールを -1 にして後方に移動します。 これで、MoveForward ができました。


MoveRight も必要です。 そこで、MoveRight を追加して、これを D キーにマップします。 また、スケール -1 の A キーにマップしたいと思います。


これで左右に移動できるようになります。


ここで、前進と右への移動に加えて、マウスを使用してカメラを回転できるようにしたいと考えています。 そこで、さらに 2 つの軸マッピングを追加し、そのうちの 1 つを [Turn] と呼びます。


このために、マウスの x 軸をマップし、look up という別の軸を作成して、これをマウスの y 軸にマップします。

ここで、マウスの y 軸のスケールを -1 に設定します。


そうすれば、マウスを前方に動かすと、下ではなく上を向くようになります。


したがって、これらのアクションと軸のマッピングがあります。


文字クラスでこれらのマッピングにバインドする関数をいくつか作成できます。


これが BlasterCharacter.h で、動きを処理する関数をいくつか作成します。


ここで、子クラスからこれらにアクセスしたい場合に備えて、これらを保護されたセクションに貼り付けます。 BlasterCharacter から派生する可能性があります。


そして、float を取る MoveForward という関数を作成します。 この値を呼び出します。これは、軸のマッピングのための軸の値です。


MoveRight という void 関数も作成し、そのために value という float を追加します。


次に、Turn と LookUp が必要です。


そこで、value という float を持つ Turn という関数と、value という float を持つ LookUp という関数を作成します。


そして、これらは私たちの基本的な動きを処理します。


これらを定義していきましょう。


ここに関数の定義があります。

ところで、これは現時点でのレビューです。 以前にこれを行ったことがなく、私たちが行っていることについて少し理解していない場合は、他の C++ Unreal Engine コースの 1 つを受講することをお勧めします。ここでは、ここで行っていることをより詳細に説明します。 少なくとも一度はこれを行ったことがあると思います。


キャラクターを立ち上げて機能させるには、このレビュー資料のいくつかを通過する必要があります.


Unreal Engine のマルチプレイヤーに関連するいくつかの新しい機能に入る前に、関数の動きができたので、setupPlayerInputComponent 関数を取得して、beginPlay の下にカット アンド ペーストします。


こうすることで、ここで関数をアクセス マッピングにバインドしているため、プレーヤー入力コンポーネントの設定を確認できます。


これで、これらの移動関数は非常に単純になり、前進します。


文字コントローラーが null ではなく、値がゼロでないことを確認します。


したがって、コントローラーが null ポインターと等しくなく、値が 0.f と等しくない場合を言います。


そのため、Character クラスには、AController 型の controller と呼ばれる継承された変数があります。


ここで、この IF チェックを行う場合、どの方向が前方であるかを調べる必要があり、コントローラーの回転を使用してこの値を見つけます。


getActorForwardVector を使用して前方方向を取得しないのはなぜですか? これは、アクティブな前方ベクトルがキャラクターの前方方向であるためです。


より具体的には、カプセルであるルート コンポーネントの前方ベクトルです。 ただし、コントローラーの回転を変更します。


コントローラーはルート コンポーネントとは異なる回転を持つ可能性があり、キャラクターの前方方向ではなく、コントローラーの前方方向に移動したいと考えています。 そこで、コントローラーを前方に向けます。


ローカル変数を宣言しましょう。 const FRotator になります。 これを YawRotation と呼びます。 これは、ヨーのピッチがゼロの FRotator になります。 そこで、ヨーイングのピッチには 0.f を使用します。 しかしヨーに関しては、私はコントローラのヨーが好きなので、controller->getControlRotation と言って、その回転からヨーを取得します。


前述のように、ロールとピッチに 0.f を使用します。 したがって、この回転 F rotator はピッチとロールに対してゼロであり、コントローラーの回転ヨーです。


次に、この FRotator を使用して前方ベクトルを取得し、方向を取得します。これが FVector になります。 そこで、const FVector を作成します。 そして、これを単に「方向」と呼ぶことにします。


  FRotation 行列を使用してヨー回転から前方ベクトルを取得することで、これを初期化します。 そのため、回転を使用して FRotationMatrix を作成できます。


FRotationMatrix は、行列と呼ばれる単純な数学的構造です。 ローテーターから回転行列を作成でき、その回転行列には情報が含まれています。 FRotationMatrix で getUnitAxis という関数を使用できます。


ここで、getUnitAxis と getUnitAxes があることに注意してください。 getUnitAxis が必要で、これに値を渡します。値は EAxis::X になります。 EAxis は名前空間であり、この「列挙型」定数 X が含まれています。


私たちが行っているのは、x 軸を指定して、それを単位軸と呼んでいることだけです。 この背後にある数学を理解する必要はありません。 FRotator から FRotationMatrix を作成し、それを単位軸と呼び、FVector を返すことだけを知っておく必要があります。


このベクトルは、回転の方向を表します。 これで、ピッチとヨーの回転がゼロになります。 したがって、このベクトルは地面に平行で、コントローラーのヨーに対応する方向を指しています。

これが前進したい方向なので、キャラクターの継承関数 addMovementInput を呼び出し、方向と値を渡します。


ここで、方向の大きさは問題ではないことに注意することが重要です。 たとえば、方向を 2 倍することでこれをスケーリングできると考えていて、それが移動速度を 2 倍にする場合、それは機能しません。 AddMovementInput は単に方向と値を取り、その方向にキャラクターが移動する結果になります。


ただし、速度と加速度は characterMovementComponent から取得されます。 キャラクターをより速く動かしたい場合は、characterMovementComponent の変数を変更する必要があります。 したがって、これで先に進むことができます。


moveRight で同じコードを使用します。 回転行列から x 軸を取得するのではなく、重要な違いが 1 つあります。 y 軸を取得します。 これにより、ヨー回転に対応する前方ベクトルではなく、正しいベクトルが得られます。 他のすべては同じです。


回転と見上げがさらに簡単になりました。 turn 関数の addControllerYawInput を呼び出すだけで、マウスを左右に動かしながら値を渡します。 値は、マウスを動かしてコントローラーを追加する速度を表します。 ヨー入力は、コントローラーの回転にヨーを追加します。


LookUp は単純に addControllerPitchInput を呼び出し、ここに値を渡します。 したがって、基本的な移動関数があり、これらを軸マッピングにバインドする必要があります。


タイプ UInputComponent のオブジェクトにアクセスできるため、セットアップ プレーヤー入力コンポーネントでそれを行うことができます。 これが playerInputComponent です。 もちろん、playerInputComponent には bindAxis があります。 今 bindAxis は FName を取ります。


ここで実際の FName を渡すか、その中に文字列を含むテキスト マクロを渡すことができます。 または、単に通常の文字列を使用することもできます。リテラル バインド アクセスは、その軸名に対してこれらすべてを受け入れます。 これで moveForwards ができたので、それから始めることができます。


2 番目の入力は、このキャラクターになるユーザー オブジェクトです。


そして、ABlasterCharacter::MoveForward になるバインド先の関数のアドレスが必要です。


次に、moveRight に対して同様の方法で他の軸マッピングをバインドします。 文字列を moveRight に変更し、関数を moveRight 関数に変更できます。


「turn」と「lookUp」もあります。 それでは、それらも見つけてみましょう。 ターンにはターン軸マッピングが必要であり、ターン関数をバインドし、ルックアップまたはルックアップ軸マッピングにバインドし、ルックアップ関数を使用しています。


これで、ジャンプに関するアクション マッピングもできました。 今のところ、キャラクターの継承されたジャンプ機能を直接バインドするだけです。 これを一番上に挙げてみましょう。


playerInputComponent と言います。 bind アクションを使用します。 アクション名は「ジャンプ」。


EInputEvent があります。 これが、使用できるキー イベントです。 IE_Pressed ユーザー オブジェクトはこれで、関数は単純に ACharacter::Jump です。


後で、追加の機能が必要になる可能性があるため、ジャンプ機能をオーバーライドしますが、今のところは、キャラクターのジャンプ機能で十分です。 そのため、移動を設定し、移動関数を入力にバインドしました。


これをコンパイルしてみましょう。


エディターに戻って、キャラクター クラスをここに置いておきます。


プレーヤーの開始もまだ使用していません。


私はワールドに実際の BP_BlasterCharacter を持っています。最後のビデオでは、詳細パネルに移動し、自動所有プレイヤーをプレイヤー 0 に設定しました。


そうすれば、Play を押すと、実際にプレーヤーを所有していることになり、動き回ることができます。


もちろん、アニメーション ブループリントを使用していないため、キャラクターは固く、アニメーション ポーズすらありません。


それが私たちの次のステップになるでしょう。


キャラクターのセットアップの基本はほぼ終わりました。キャラクターを動かせたら、マルチプレイヤー プログラミングの概念を学び始めることができます。


そのため、この講義では、基本的なキャラクターの動きのアクションとアクセスのマッピングを設定し、それらの動き関数を作成してマッピングにバインドしました。


そして、実際にキャラクターとコントローラーを動かし、ひいてはスプリング アームとカメラを動かしています。


繰り返しますが、これはすべてあなたのためのレビューです。


キャラクター設定の基本はほぼ完了しており、すぐにマルチプレイヤー プログラミングに取りかかることができます。


また後で。


Welcome back.


Now we have our character in our spring arm and camera components.


We now need to configure the inputs for our project and program, our movement functionality for the character.


Let's get started.


So we're going to need some inputs for our project. And to do that, we'll go to edit and project settings.


From here, we can select input and let's expand our action mappings and our AXIS mappings.


Now I see some action in axis mappings here, and these were created when we migrated over some assets from learning kit games.


I'm going to go ahead and delete all of these axis mappings from our project settings. Let's do this all from scratch.


Now for action mappings, we do want to be able to jump.

So I'm going to make a jump action mapping and map this to the spacebar. I can click this icon and hit the spacebar to link up the spacebar to our jump action mapping.


Now for our AXIS mappings, we're going to want a few of these.


I'm going to add one and call this MoveForward. And I want to map this to the W key. I'd also like to map this to the S key with a scale of -1 that'll be for moving backwards. Now we have a MoveForward.


We're also going to need a MoveRight. So I'm going to add MoveRight and map this one to the D key. I'd also like to map it to the A key with a scale of -1.


That way we'll be able to move left and right.


Now, in addition to move forward and move right, we want to be able to use the mouse to rotate our camera. So I'm going to add two more axis mappings and I'm going to call one of them [Turn].


And for this, I'm going to map our mouse x axis and I'll create another one called look up and map this to the mouse y axis.

Now, I like to set this scale to -1 for the mouse y axis.


That way, when I move the mouse forward will look up instead of down and so on.


So we have these action and axis mappings.


We can create some functions to bind to these mappings in our character class.


Now here's BlasterCharacter.h, and we're going to want to create some functions to handle movement.


Now, I'll stick these in the protected section just in case we'd like to access these from a child class. We may derive from BlasterCharacter down the line.


And I'll make a function called MoveForward, which takes a float. we'll call this value and that's for the axis value, for our axis mapping.


I'll create a void function called MoveRight as well, and we'll add a float called value for that.


And then we need Turn and LookUp.


So we're going to create a function called Turn.

So we're going to create a function called Turn with a float called value, and a function called LookUp with a float called value.


And these will handle our basic movement.


Let's go ahead and define these.


So we have the function definitions here.

Now, by the way, this should be review for you at this point. If you haven't done this before and you're a little foggy on what we're doing, I recommend you take one of my other C++ Unreal Engine courses where we go into much more detail describing what we're doing here. I'm expecting that you've done this at least once before.


We do need to get through some of this review material to get our character up and working.


Before we get to some of the new stuff pertaining to Unreal Engine multiplayer, now we have our movement of functions and I'm going to take my setupPlayerInputComponent function and cut and paste it right here under beginPlay.


That way we can see set a player input component as we're binding our functions to our access mappings here.


Now these movement functions are going to be quite simple and move forward.


We're going to make sure that our characters controller isn't null and that our value isn't zero.


So we're going to say if controller is not equal to null pointer and value is not equal to 0.f.


So the Character class has an inherited variable called controller of type AController.


Now, if we make it into this IF check, we need to find out which way is forward and we're going to use our controller rotation to find this value.


Now I get a lot of questions asking how come we don't just use getActorForwardVector to get our forward direction? And that's because our active forward vector is the forward direction for the character.


More specifically, it's the forward vector for the root component, which is the capsule. But we're going to be changing our controller rotation.


Our controller may have a different rotation than our route component, and we want to move forward in the controllers forward direction, not the character's forward direction. So we're going to get our controllers forward direction.


Let's declare a local variable. It's going to be a const FRotator. And I'm going to call this YawRotation. And this is going to be an FRotator with a zero for the pitch in yaw. So I'm going to use 0.f for pitch in yaw. But for the yaw, I like the controllers yaw, So I'm going to say controller->getControlRotation and from that rotation I'm going to get the yaw.


Now I'm going to use 0.f for the role and pitch as I mentioned. So this your rotation F rotator is zero for the pitch and role and it's your is our controllers rotation yaw.


Now we're going to use this FRotator to get a forward vector to get a direction and that's going to be an FVector. So I'm going to make an const FVector. And I'm simply going to call this "direction".


 and I'm going to initialize this by getting the forward vector from yaw rotation using FRotation matrix. so I can create an FRotationMatrix using your rotation.


Now an FRotationMatrix is simply a mathematical construct called a matrix. You can create a rotation matrix from a rotator, and that rotation matrix contains information. We can use a function on FRotationMatrix called getUnitAxis.


Now notice there is getUnitAxis and getUnitAxes. We need getUnitAxis and we're going to pass in a value to this and the value is going to be EAxis::X. EAxis is a namespace and it contains this "enum" constant X.


All we're doing is we're calling it unit axis, specifying the x axis. Now you don't really need to understand the math behind this. All you need to know is that we're creating an FRotationMatrix from an FRotator, and then we're calling it unit axis and this is going to return an FVector.


This vector represents the direction of this, your rotation. Now your rotation is zeroed out in the pitch and yaw. So this vector is parallel to the ground, pointed in the direction corresponding to the yaw of our controller.

This is the direction we want to move forward in so we can call our characters inherited function, addMovementInput and we'll pass in direction and value.

Now it's important to note that the magnitude of direction doesn't matter here. If you're thinking you can scale this by multiplying direction by two, for example and that one would double your movement speed, that's not how it works. AddMovementInput simply takes the direction and the value and results in the character moving in that direction.

But the speed and acceleration are retrieved from the characterMovementComponent. If you want your character to move faster, you need to change variables in the characterMovementComponent. So this takes care of moving forward. 

We're going to use the same code in moveRight. with one key difference rather than getting the x axis from the rotation matrix. We're going to get the y axis. That's going to give us the right vector rather than the forward vector corresponding to yaw rotation. Everything else is the same.

Now turn and look up are even simpler. We're simply going to call addControllerYawInput for the turn function and we're going to pass in value that way as we move the mouse left and right. Value will represent how fast we're moving that mouse and add controller. Yaw Input is going to add yaw to our controller rotation.

LookUp is simply going to call, addControllerPitchInput and we'll pass value in here. So we have our basic movement functions and we need to bind these to our axis mappings.

We can do that in setup player input component as we have access to an object of type UInputComponent. This is our playerInputComponent. And playerInputComponent of course has bindAxis. Now bindAxis takes an FName.

Now we can pass in an actual FName here, or we can pass in the text macro with a string, Inside of it. Or we could simply use a regular string, literal bind access will accept all of these for that axis name. Now we have moveForwards so we can start with that one.

And our second input is the user object that's going to be this character.

And we need the address of the function where binding that's going to be ABlasterCharacter::MoveForward.

Now we're going to bind our other axis mappings in a similar manner for moveRight. We can change the string to moveRight and change the function to the moveRight function.

We also have "turn" and "lookUp". So let's go ahead and find those as well. For turn we need the turn axis mapping and we're binding the turn function and for look up or binding to the look up axis mapping and using the lookup function.

Now we also have an action mapping as for jumping. For now, we're simply going to bind the character's inherited jump function directly. Let's pick this up at the top.

We're going to say playerInputComponent. We're going to use bind action. The action name is "Jump".

and we have EInputEvent. That's the key event we can use. IE_Pressed the user object is this and the function can simply be ACharacter::Jump.

Now later on, we're going to override the jump function as we may want additional functionality, but  for now, the character's jump function will do. So, We've set up movement and bound movement functions to the inputs.

Let's go ahead and compile this.

And back here and the Editor, I have my character class just sitting here.

We're not even using the player start just yet.

I have a actual BP_BlasterCharacter in the World and in the last video we went to the details panel and set auto possessed player to player zero.

And that way when we press Play, we're actually possessing the player and we can move around.

And of course our character is stiff because we're not using an animation Blueprint, so it doesn't even have an animation pose.

So that's going to be our next step.

We're almost done with the basics of setting up our character, and once we have our character moving, we can start learning the concepts of multiplayer programming.

So in this lecture, we set up the action and access mappings for basic character movement and created those movement functions and bound them to our mappings.

And we're actually moving the character and the controller and by extension, the spring arm and camera.

So again, this should all be a review for you.

We're almost done with the basics of character setup, and we'll be able to get into multiplayer programming very shortly.

I'll see you soon.

0 件のコメント:

コメントを投稿