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