unityでFPS視点で動かすシステムを作ろう

unity

こんにちはR&Rです。今回はFPS視点の作り方を備忘録的に書いていこうかなと思います。

今回はマウスで視点移動し、キーボードで移動を行います。

完成イメージ

playerの配置

1.まずはこのように空のオブジェクト(Player)を作成し、その下にplayerのモデルを置きます。今回は簡易的にカプセルを配置しました。

親オブジェクトを空のオブジェクトにすることで後々武器を持たせたりなど応用が利きます。

2.Playerオブジェクト(親オブジェクト)の方に、[Character Controller]をアタッチし、[PlayerController1]という名のスクリプトを作成しアタッチします。ここで、子オブジェクトであるカプセルのcolldeirは削除してあげます。(Charactor Controllerがその役割を果たすので)

3.CharactorController1は次のようになります。

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

public class playerController1 : MonoBehaviour
{
    public float moveSpeed;
    public CharacterController charaCon;

    private Vector3 moveInput;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        moveInput.x = Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime;
        moveInput.z = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;

        charaCon.Move(moveInput);
    }
}

最後に[PlayerController]に設定できるCharaConに親オブジェクトである[Player]を入れれば完成です。

これでplayerを動かすことができます。

カメラの設定

1.カメラをPlyaerオブジェクトの子オブジェクトとして設定します。そして、このカメラをplayerの目線の位置にもってきてください。これでplayerに追従する形でカメラが移動します。しかし、視点の向きを変えることはできない状態です。

2.カメラがマウスにあわせて視点移動できるようにコードを書き足していきます。

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

public class playerController1 : MonoBehaviour
{
    public float moveSpeed;
    public CharacterController charaCon;
    private Vector3 moveInput;

    public Transform camTrans;
    public float mouseSensitivity;
    public bool invertX;
    public bool invertY;
   
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        moveInput.x = Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime;
        moveInput.z = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;

        charaCon.Move(moveInput);

        //カメラの回転制御
        Vector2 mouseInput = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"))*mouseSensitivity;
        if (invertX)//マウス反転したいなら。
        {
            mouseInput.x = -mouseInput.x;
        }
        if (invertY)
        {
            mouseInput.y = -mouseInput.y;
        }
        transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + mouseInput.x, transform.rotation.eulerAngles.z);
        camTrans.rotation = Quaternion.Euler(camTrans.rotation.eulerAngles + new Vector3(-mouseInput.y, 0f, 0f));
    }
}

これでマウスの動きに合わせてカメラの視点が移動します。また、mouseSensivityを設定したことで感度の調整も可能にしました。

移動の向きを合わせる

マウスに合わせて視点を動かしながらplayerの移動が可能になりましたが、向いてる方向≠まっすとなっているため、向いている方向にまっすぐ進んでくれません。playerの体の向きと首(camera)の向きはそれぞれ別なのでCameraだけまわしている状態です。これを一致させます。

コードを修正+追加していきます

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

public class playerController1 : MonoBehaviour
{
    public float moveSpeed;
    public CharacterController charaCon;
    private Vector3 moveInput;

    public Transform camTrans;
    public float mouseSensitivity;
    public bool invertX;
    public bool invertY;
   
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
     ここ2行をコメントアウト
        //moveInput.x = Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime;
        //moveInput.z = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;

        Vector3 verMove = transform.forward * Input.GetAxis("Vertical");
        Vector3 horiMove = transform.right *Input.GetAxis("Horizontal");

        moveInput = horiMove + verMove;
    moveInput.Normalize();
        moveInput = moveInput * moveSpeed;

        charaCon.Move(moveInput*Time.deltaTime);

        //カメラの回転制御
        Vector2 mouseInput = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"))*mouseSensitivity;
        if (invertX)//マウス反転したいなら。
        {
            mouseInput.x = -mouseInput.x;
        }
        if (invertY)
        {
            mouseInput.y = -mouseInput.y;
        }
        transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + mouseInput.x, transform.rotation.eulerAngles.z);
        camTrans.rotation = Quaternion.Euler(camTrans.rotation.eulerAngles + new Vector3(-mouseInput.y, 0f, 0f));
    }
}

これでマインクラフトやCODのような動きができるようになりました!カメラの回転の計算部分がかなり複雑になっちゃいました。

重力をつけよう

1.PlayerControllerに次のようにコードを追加します。

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

public class playerController1 : MonoBehaviour
{
    public float moveSpeed,gravityModifier,jumpPower;; //速度と重力の大きさ,ジャンプ力
    public CharacterController charaCon;
    private Vector3 moveInput;

    public Transform camTrans;
    public float mouseSensitivity;
    public bool invertX;
    public bool invertY;
   
  private bool canJump;
    public Transform groundCheckPoint;
    public LayerMask whatIsGround;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //moveInput.x = Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime;
        //moveInput.z = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;


        //store y velocity 
        float ystore = moveInput.y;

        Vector3 verMove = transform.forward * Input.GetAxis("Vertical");
        Vector3 horiMove = transform.right *Input.GetAxis("Horizontal");

        moveInput = horiMove + verMove;
        moveInput.Normalize();
        moveInput = moveInput * moveSpeed;

        moveInput.y = ystore;
        moveInput.y += Physics.gravity.y * gravityModifier*Time.deltaTime;

        if (charaCon.isGrounded)
        {
            moveInput.y = Physics.gravity.y * gravityModifier*Time.deltaTime;
        }

 //ジャンプ
        canJump = Physics.OverlapSphere(groundCheckPoint.position, .25f, whatIsGround).Length > 0; //地面についていて0.25経ったら
        if (Input.GetKeyDown(KeyCode.Space) && canJump)
        {
            moveInput.y = jumpPower;
        }
        charaCon.Move(moveInput*Time.deltaTime);

        charaCon.Move(moveInput*Time.deltaTime);

        //カメラの回転制御
        Vector2 mouseInput = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"))*mouseSensitivity;
        if (invertX)//マウス反転したいなら。
        {
            mouseInput.x = -mouseInput.x;
        }
        if (invertY)
        {
            mouseInput.y = -mouseInput.y;
        }
        transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + mouseInput.x, transform.rotation.eulerAngles.z);
        camTrans.rotation = Quaternion.Euler(camTrans.rotation.eulerAngles + new Vector3(-mouseInput.y, 0f, 0f));
    }
}

2.[Player]オブジェクトの下に[GroundCheck]という空のオブジェクトをつけます。これをPlayerControllerの中に入れます。右図のような感じになるはずです。このGroundCheckとうのはplayerが[Ground]というLyaerにいるかどうかを判定するものです。というわけで、[what is Ground]をGroundにしてあげましょう。

3.Groundレイヤーは左の図のように追加する必要があります。[Edit Layers]→[Layers]の好きなところに「Ground」と入力してあげます。これで先ほどのnothingをGroundに変えれるはずです。地面オブジェクトのレイヤーを変えるのを忘れないでください。

コメント

タイトルとURLをコピーしました