ここでは、プレイヤーを作成します。
今回作るゲームは、初心者でも気軽に作れるゲームを目指すため、
複雑なモデルではなく、キューブでできたプレイヤーモデルです。
まずは基礎を学びましょう!
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生成、を実装していきたいと思います!!
(オンラインゲームを作っている実感が得られます^^)