本講座では、UnityとC#を用いて3DFPSゲームを作成していきます。
前回は、スマホ用の設定、そしてスマホ用のUIを配置、移動スティックやジャンプボタンのガワの作成まで行いました。
前回の記事:
ここまでだとまだ実際にスティック移動したりジャンプボタン押下によるジャンプを実装していない状態です。
そこで、スマホ用UIを使って移動、ジャンプ、攻撃などができるように処理を作成していきます。
またマルチタップにも対応させ、移動しながら攻撃したり、移動しながらカメラを動かしたりする処理を実装します。
今回の講座でスマホ対応を完了したFPSゲームができあがります。講座の最後に完成版プロジェクトファイルもお渡しします。
スマホボタンを押したときにFPS主観カメラでジャンプさせる処理を実装
ではまずは簡単なジャンプができるようにしていきましょう。
AppPlayerController.csにコードを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
public class AppPlayerController : MonoBehaviour { ・・・ void Update() { if( mobileUi.IsAnyButtonPushing() == false ) { ・・・ if( Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor ) { // ジャンプ処理. if( Input.GetKeyDown( KeyCode.Space ) == true && isJumping == false ) { isJumping = true; rigid.AddForce( rigid.gameObject.transform.up * jumpPower, ForceMode.Impulse ); } } } ・・・ } ・・・ // --------------------------------------------------------------------------------- /// <summary> /// スマホ用ジャンプボタンクリック. /// </summary> // --------------------------------------------------------------------------------- public void OnMobileUiJumpButtonClicked() { // ジャンプ処理. // if( Input.GetKeyDown( KeyCode.Space ) == true && isJumping == false ) 削除. if (isJumping == false) { isJumping = true; rigid.AddForce(rigid.gameObject.transform.up * jumpPower, ForceMode.Impulse); Debug.Log("Jump(M)" + isJumping); } } } |
「Update()」関数の追加はありませんが、元々のジャンプ処理も併せて確認しておきましょう。
追加する関数は「OnMobileUiJumpButtonClicked()」関数です。
まずは元のジャンプ処理の「if( Input.GetKeyDown( KeyCode.Space ) == true && isJumping == false )」の処理を丸々コピーします。
そして条件の「Input.GetKeyDown( KeyCode.Space ) == true」を削除して、「isJumping==false」のみにします。これでOKです。
Unityに戻って、「MobileUI/JumpButton」の「Button」コンポーネントの「OnClick」イベントに、「Player」をドラック&ドロップして、「OnMobileUiJumpButtonClicked()」関数を登録しましょう。
これでジャンプは完成です。再生して、ジャンプボタンを押してみましょう。
移動スティック押下による移動処理の実装
次に移動処理です。移動処理は「AppPlayerController」の「FixedUpdate()」で実装しているので、そこでプラットフォームによる分岐を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
public class AppPlayerController : MonoBehaviour { ・・・ void FixedUpdate() { if( gameController != null && gameController.CurrentGameParam.State != AppGameController.GameState.Play ) return; if ( Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor ) { // 左右上下のキー入力を取得. var horizontal = Input.GetAxis( "Horizontal" ); var vertical = Input.GetAxis( "Vertical" ); // いずれかの入力があった場合. if( horizontal != 0 || vertical!= 0 ) { // カメラの角度を取得(Vector3). var cameraRotationEul = Camera.main.transform.rotation.eulerAngles; // Y軸回転以外は0に変更. cameraRotationEul.x = 0; cameraRotationEul.z = 0; var cameraRotation = Quaternion.Euler( cameraRotationEul ); // 入力値に係数をかけ、三次元ベクトルのX,Zの値として値を作成. var forceX = horizontal * moveSpeed; var forceZ = vertical * moveSpeed; var force = cameraRotation * new Vector3( forceX, 0, forceZ ); // リジッドボディに力を加える. rigid.AddForce( force, ForceMode.Force ); // 移動速度を制限. MoveResistance(); } else { // 停止力. StopForce(); } } else { // 削除. // var horizontal = Input.GetAxis( "Horizontal" ); // var vertical = Input.GetAxis( "Vertical" ); // いずれかの入力があった場合. // if( horizontal != 0 || vertical!= 0 ) 変更. if( mobileUi.StickPosition.x != 0 || mobileUi.StickPosition.y != 0 ) { // カメラの角度を取得(Vector3). var cameraRotationEul = Camera.main.transform.rotation.eulerAngles; // Y軸回転以外は0に変更. cameraRotationEul.x = 0; cameraRotationEul.z = 0; var cameraRotation = Quaternion.Euler( cameraRotationEul ); // 入力値に係数をかけ、三次元ベクトルのX,Zの値として値を作成. // var forceX = horizontal * moveSpeed; 変更. // var forceZ = vertical * moveSpeed; 変更. var forceX = mobileUi.StickPosition.x * moveSpeed; var forceZ = mobileUi.StickPosition.y * moveSpeed; var force = cameraRotation * new Vector3( forceX , 0 , forceZ ); // リジッドボディに力を加える. rigid.AddForce( force , ForceMode.Force ); // 移動速度を制限. MoveResistance(); } else { // 停止力. StopForce(); } } } ・・・ } |
まずは最初に「if( gameController != null && gameController.CurrentGameParam.State != AppGameController.GameState.Play ) return;」を追加しておきます。
一つ目の条件「gameContorller != null」はNullチェックです。「gameController.CurrentGameParam.State != AppGameController.GameState.Play」はステイトが「Play」つまりゲーム中のみ実行できるようにします。
これはPC、スマホ関係なく「ゲーム中のみ処理を行う」というあっていい処理なので最初に実行しておきます。
続いて、移動処理の前に「if ( Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor )」を加えて全ての処理をエディター用にします。PC用にビルドしたい場合はここの条件にPCも加えてください。
そしてこのif文の「else」の括弧内に一旦丸々PC用の処理をコピーしましょう。そこから変更部分を解説していきます。
まず最初の「horizontal」「vertical」はPC入力なので削除します。そしていずれかの入力があった時「if( horizontal != 0 || vertical!= 0 )」の条件を「mobileUi.StickPosition.x != 0 || mobileUi.StickPosition.y != 0」に変更します。この「mobileUi.StickPosition」は「AppMobileUiController」でスティックの入力を「0〜1」にして保管している値です。
括弧内の力を算出する「var forceX = horizontal * moveSpeed」、「var forceZ = vertical * moveSpeed」をそれぞれスティック入力に変更し「var forceX = mobileUi.StickPosition.x * moveSpeed」、「var forceZ = mobileUi.StickPosition.y * moveSpeed」に変更します。
ざっくりいえば、キーボード入力値をスティック入力値に変更しているだけです。書き方を工夫すればもっと短く書けますが、今回はわかりやすいように丸々条件分岐しています。
では、Unityエディタに戻って再生してスティックで移動できるか確かめてみましょう。
スマホタップによるFPSゲームの攻撃・カメラ回転の処理の作り方
お気づきの方もいるかもしれませんが、攻撃・カメラ回転、つまりボタン以外のところをスマホ操作でタップした場合、特に処理を変えなくてもちゃんと回転、攻撃できていると思います。
カメラの回転・攻撃は「Input.GetMouseButtonDown()」や「Input.mousePosition」などマウスの値を使っていますが、実はこれらはスマホタッチの場合も有効です。
しかし、両手で操作したり何本か指を使って操作しても複数の指の同時操作に対応していないので1本の指の値しか取得できません。
ここからは複数の指を使ってタップした場合にも対応できるようにスマホ用に処理を変更します。
スマホ版対応に向けて処理の整理・リファクタリング
では、まずはそれを追加するにあたり、ちょっと見にくくなってきているのでPC用のカメラ、攻撃処理を一つの関数にまとめましょう。
最後に スマホ版FPSゲームが完成!次回はVR化に挑戦!
ここまででスマホ対応の完了です。
Unity入門の森、次回の新作講座の「FPSゲームの作り方講座」に取り組み、スマホアプリ化対応まで行うとこんな感じになります。
残りはVR化対応のパートです。引き続き執筆がんばります!#Unity入門の森#ゲームの作り方#IndieGameDev pic.twitter.com/s6ztSOkJFi
— ばこ@Unity入門の森 (@bako_XRgame) November 17, 2022
こんな感じの動きが実現できているでしょうか?(この動画では調整のため2体敵を倒したらクリアになってます笑)
ここまでで、一旦弓を使ったFPS(一人称シューティング)の講座の区切りとなります。
操作性の向上や、デバイスによるUIの調整などまだまだ各々で改良できるところはたくさんあるはず!
細かい調整をご自身でやってみるとより良いゲームができるのではないかと思います。ぜひオリジナルFPSゲームに昇華させてみてください!
次回はちょっと特殊ですが、VRへの対応をしていきます。これはVRのHMD(ヘッドマウントディスプレイ)を持っていないと試せないのですが、お持ちの方は是非挑戦してみてください。
次回の記事:
コメント