Unity

【Unity】オンラインFPSゲームの作り方#4【プレイヤーの実装】

本記事内には、アフィリエイトリンクを含む場合があります

ここでは、プレイヤーを作成します。

今回作るゲームは、初心者でも気軽に作れるゲームを目指すため、
複雑なモデルではなく、キューブでできたプレイヤーモデルです。

ここでは、アニメーションをしないプレイヤーキャラクターを作成します。アニメーションのあるキャラクターの場合、特にFPSでは、プレイヤーの作成がとても複雑になってきます。その方法は、後日落ち着いたときに^^

まずは基礎を学びましょう!

1.プレイヤーモデルの作成

まず、空のオブジェクト(Empty Object)を作り、「PlayerPrefab」と名付けます。
さらに、その中に空のオブジェクト「Model」を作ります。
(いずれもTransformはオール0です)

1-1.身体とカメラ

下準備は以上で、
「Model」を右クリックして「3D Object」の「Cube」を作成していきます。
(モデルはCubeで作成するので、超簡単!)

頭、胴体、手さえ作成すれば、十分キャラクターになります^^
それぞれのCubeのTransformは、次のように設定します。

頭(Head)
Position:Yのみ0.4(他は0)
Scale:XYZ全て0.75

胴体(Body)
Position:Yのみ-0.6
Scale:X0.9、Y1.3、Z0.7

ここで、手を作っていく前に、「PlayerPrefab」の中にCameraを生成します。
(両手は常にカメラに追従させ、画面に映るようにしたいからです)

CameraのTransformは
Position:X0、Y0.3、Z0.15
Scale:XYZは全て1

さらに、ClippingPlanesのNearを0.5にします
(これはカメラに自分のHeadやBodyが映って、画面が見えづらくなってしまうのを防ぐためです【公式参考】)

Cameraを作成したら、そこで右クリックから、手となるCubeを作成していきます。

右手(RightArm)
Position:X0.5、-0.55、0.35
Scale:X0.3、Y0.3、Z0.8

左手(LeftArm)
Position:X0、-0.55、0.4
Rotation:Y45
Scale:X0.3、Y0.3、Z0.9

カメラに微妙に両手が見えているはずです。

1-2.武器

Cameraの中に、空のゲームオブジェクトを「Weapon」と名付けてを作成します。

Weapon
Position:X0.4、Y-0.4、Z1
Scale:全て1

これは、今後いろんな武器を装填していくための入れモノとして
考えてもらえばよいかと思います。

武器は、アセット「Modern Weapons Pack」の「Ak-47」を使います。
同フォルダの「FBX」_「Ak-47」ファイルを
シーンの「Weapon」にドラッグ&ドロップします。

これで、プレイヤーの見た目(モデル)は完成しました。

2.プレイヤーのコンポーネント設定

2-1.Collider

プレイヤーに、オブジェクトなどに対する当たり判定を付けます。

現在、頭・胴体・両手のCubeには、
デフォルトでBox Colliderのコンポーネントがアタッチされています。

これは不要なので、右クリックからRemove Componentで削除します。

次に、
PlayerPrefabに、Add ComponentからCapsule Colliderを追加します。

図のようなパラメーターに設定すると、モデルの大きさに対応します。

図には、次のRigidbodyも含めてます^^;

2-2.Rigidbody

Rigidbodyは、オブジェクトに重力の影響を与える剛体のコンポーネントです。
公式参考

PlayerPrefabにColliderと同じように、追加しましょう。

パラメーターはConstraintsのFreeze Rotationのみ変更します。
XYZにチェックをすることで、どの方向にも回転しないようにします。

次の項目で触れますが、
本ゲームは、このRigidbodyに力を加えて、プレイヤーの動きを制御していきます。

Freeze Rotationにチェックを入れないと、
他のオブジェクトや坂道などで、自然発生的にプレイヤー(のcollider)が回転して倒れてしまうのです。

Massは、後々ゲームをしながら適宜調整を計ればよいのですが、
5くらいがよいかと思います。

2-3.動きを制御するScript(Movement Controller.cs)

プレイヤーをパソコンのキー入力で動かすためにScriptを作成します。

「Scripts」フォルダ内で、「MovementController」という名のC#Scriptを作成し、PlayerPrefabにアタッチします。

コード内容は次の通り↓

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MovementController : MonoBehaviour
{
    [SerializeField]float speed = 5f; //Inspectorで調整可
    
    private Vector3 velocity = Vector3.zero; //初期値ゼロ

    private Rigidbody rb; //宣言のみ

    // Start is called before the first frame update
    private void Start()
    {
        rb = GetComponent<Rigidbody>(); //自分のRigidbodyを取得
    }

    // Update is called once per frame
    private void Update()
    {
        float _xMovement = Input.GetAxis("Horizontal"); //宣言して左右キー(A,Dキー)の入力値を紐づけ
        float _zMovement = Input.GetAxis("Vertical"); //宣言して上下キー(W,Sキー)の入力値を紐づけ

        Vector3 _movementHorizontal = transform.right * _xMovement; //Vector3の水平方向に変換
        Vector3 _movementVertical = transform.forward * _zMovement; //Vector3の垂直方向に変換

        Vector3 _movementVelocity = (_movementHorizontal + _movementVertical).normalized * speed;//ベクトルを足して正規化(直線方向へ)、変数を宣言
        velocity = _movementVelocity; //velocityに値を代入
    }

    private void FixedUpdate()
    {
        if(velocity!= Vector3.zero) //velocityに入力値があれば
        {
            rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime); //MovePositionメソッドを呼び、移動させる値を渡す
        }
    }
}

ここで、
キー入力はUpdateメソッド、
Rigidbodyを動かすような物理挙動はFixedUpdateメソッド
に記載しています。
(2つの違いについてはこちら(別サイト)参照)

このScriptによって、PlayerPrefabは
「AWSD」または「←↑↓→」で動くようになります。

2-4.視点を制御するScript(Movement Controller.cs追記)

次に、視点を制御します。

マウスカーソルの動きに応じて視点を制御するために、
同Scriptに追記します。

留意しておきたい点は
左右
の視点の制御は
Rigidbody(PlayerPrefabそのもの)の回転によって行っていますが、
上下の視点の制御は
PlayerPrefab配下のCameraの回転によって行っていることです。

追記箇所のみ「//~」を付してます↓

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MovementController : MonoBehaviour
{
    [SerializeField]float speed = 5f;

    [SerializeField]private float lookSensitivity = 3f; //Inspectorで調整可    
    [SerializeField]GameObject fpsCamera; //Inspectorで紐づけ

    private Vector3 velocity = Vector3.zero;

    private Vector3 rotation = Vector3.zero; //初期値ゼロ
    private float CameraUpAndDownRotation = 0f; //視点上下用の変数
    private float CurrentCameraUpAndDownRotation = 0f; //視点上下用の変数

    private Rigidbody rb;

    // Start is called before the first frame update
    private void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    private void Update()
    {
        float _xMovement = Input.GetAxis("Horizontal");
        float _zMovement = Input.GetAxis("Vertical");

        Vector3 _movementHorizontal = transform.right * _xMovement;
        Vector3 _movementVertical = transform.forward * _zMovement;

        Vector3 _movementVelocity = (_movementHorizontal + _movementVertical).normalized * speed;
        velocity = _movementVelocity;

        float _yRotation = Input.GetAxis("Mouse X"); //マウスカーソルの水平の動きを入力値として紐づけ
        Vector3 _rotationVector = new Vector3(0, _yRotation,0) * lookSensitivity; //y値のみ変動するVector3変数を宣言
        rotation = _rotationVector; //rotationに値を代入

        float _cameraUpDownRotation = Input.GetAxis("Mouse Y") * lookSensitivity; //マウスカーソルの垂直の動きを入力値として紐づけ
        CameraUpAndDownRotation = _cameraUpDownRotation;
    }

    private void FixedUpdate()
    {
        if(velocity!= Vector3.zero)
        {
            rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
        }
        rb.MoveRotation(rb.rotation*Quaternion.Euler(rotation)); //MoveRotationメソッドを呼び、回転させる値を渡す

        if(fpsCamera!= null) //Cameraがあるならば
        {
            CurrentCameraUpAndDownRotation -= CameraUpAndDownRotation; //正の値を負に(カーソルのほうを向く回転値へ)
            CurrentCameraUpAndDownRotation = Mathf.Clamp(CurrentCameraUpAndDownRotation,-80,80); //値の最小最大を設定
            fpsCamera.transform.localEulerAngles = new Vector3(CurrentCameraUpAndDownRotation,0,0); //x軸にのみカメラを回転させる
        }
    }
}

ちなみに

Quaternionに関しては、かなり複雑なので、
気になる方は、こちら(XR-Hub)をじっくり参考ください^^;

ここでは頻出のQuternion.Eulerを使っています。
(rotation)のように、Vector3の情報をもつrotationを引数にすることで、
このとき、y軸回転のみを行わせています。

コードができたならば、
InspectorのFps Cameraに、Cameraをドラッグ&ドロップして、紐づけます。

ここまできたならば、
GameSceneにて、実行ボタンを押し、
キー入力、マウスカーソルの動きで動作するか確認しましょう。

以上で、
プレイヤーモデルとその基本的な挙動が実装できました。

次は、シューティングアクション!
といきたいところですが・・・

先に、Photonサーバーにユーザーが入室して
それぞれのPlayerPrefab生成、を実装していきたいと思います!!
(オンラインゲームを作っている実感が得られます^^)

【Unity】オンラインFPSゲームの作り方#5【サーバーに連携するプレイヤーとUIの設定】前回、PlayerPrefabを作成し、それを動かすところまで実装しました。 プレイヤブルキャラクターとして、最低限の機能をもった...
ABOUT ME
いなも@システマライフハッカー
”仙豆”を開発することを夢見て、健康食品会社で働いていたものの、2016年に出会ったロシアの武術”システマ”こそ、その糸口があると感銘し、勝手にシステマ普及活動を始める。 一方で、クリエイティブなモノ作りが好きで、DX社会で楽しみを見出せる"Unity”を活かして、”スマートかつ快適な暮らし”のヒントを発信している。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA