(このブログではOculus Riftを使ってます。Vive Proを使う場合は適宜読み替えてください)
Robo Recallみたいに銃が持ちたいので作ってみました。
![VRGunTest_Moment.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539108/886d74d7-3645-8b51-0597-bc68702f3b40.jpeg)軽い解説
最初にキューブなどを持つときの仕組みについて軽く解説を。
GrabLeftかGrabRightが呼ばれるとBP_MotionControllerの関数GrabActorが実行されます。
今回の解説で重要な所だけ抜き出すと、GrabActorはまず初めにBP_MotionControllerの周りに掴めるものがないか調べるためにGetActorNearHandという関数を呼びます。
GetActorNearHandは「GrabSphereにOverlapしている」Actorの中から、「PickUpInterfaceが実装されている」かつ「(GrabSphereとそのActorの距離)<(NearestOverlap)」を満たすActorを選別し、GrabSphereから一番近いところにある条件を満たしたActorを返します。
そしてGrabActorに戻り、返り値に何らかのActorがあればそのActorが持っているPickup関数を実行します。
Pickup関数を実行したActorは持とうとした手のBP_MotionControllerに自身をAttachします。
![VRRotate - Unreal Editor 2019_10_16 22_11_58 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539108/9743b50e-7ccd-deae-934d-05b587ec3eb9.png)実践
という事でこれを組みなおしていきます。
まずはラーニングにある「シューターゲーム」から、Weaponsフォルダにある「Rifle」、Sounds->Weapon_AssaultRifleにある「AssaultRifle_Equip_Stereo_Cue」、「AssaultRifle_Shot01_Stereo」をインポートしてきます。
次にプロジェクト設定->インプットから「GrabLeft」「GrabRight」をそれぞれの「MotionController Grip 1」に変え、「UseAttachedActorLeft」「 UseAttachedActorRight」を追加します。(キーは「MotionController Trigger」)
次に「Rifle」に物理アセットを追加します。アセットを右クリックして作成する->物理アセット->作成と割り当てを選び、Primitive TypeをSingle Convex Hullに変えて「アセットを作成」を選びます。後は特にいじらなくても大丈夫です。
後はPickupActorInterfaceにUseという関数を1つ足します。インプットやアウトプットはいりません。Pickup関数にインプットを一つ足し、名前を「SocketName」、変数を「名前(Name)」にします。
次に銃のActorを作っていきます。クラスは「SkeletalMeshActor」、名前はここでは「BP_PickGun」とします。作成したら開き、「SkeletalMeshComponent」に先ほどインポートした「Rifle」を、クラス設定->インターフェイスにPickupActorInterfaceを追加します。続いてコンポーネントタブから「SkeletalMeshComponent」を選び、Simulate PhysicsとGenerate Overlap Eventsをオンにして一度コンパイルします。
イベントグラフを下の通りに組んでいきます。SpawnSoundAtLocationには、Pickupに「 AssaultRifle_Equip_Stereo_Cue 」、Useに「 AssaultRifle_Shot01_Stereo 」を割り当ててます。
次に「MannequinHand_Right_Skeleton」にソケットを追加していきます。UE4のVRテンプレートでは右手のスケルトンだけ用意し、左手をスポーンする時はZ軸に-1.0をかけて反転しています。そのため右手のスケルトンに右手・左手のソケットを追加します。ソケットの位置はそれぞれで調整してください。左手のソケットは特別な調整をしないのなら、右手のソケットをコピペしてRelative RotationのYに180を足し、Relative ScaleのZに-1.0を入れると簡単に作れます。ここで追加したSocketの名前は後で使うのでメモ帳にでもコピーしとくと後が楽です。
次に「BP_MotionController」を少しいじります。GrabActor関数を開き、Pickup関数の周りを下のようにします。「選択」に先ほど作ったソケットの名前を、False->(右手のソケット名)、True->(左手のソケット名)、という風に入れます。
そして「ReleaseActor」を開き、MotionControllerをHandMeshに変えます。
後はUseAttachedActor関数を作ります。
最後にMotionControllerPawnのイベントグラフに以下を足して完成です。