26
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

タイプ別TPS視点の作り方(in Unity3D with C#)

Last updated at Posted at 2018-11-09

前書き

今回紹介する議題は他のサイトや、他Qiitaユーザーの皆様も紹介されている「Unity3dでTPS視点操作をどのように実装するか?」です。今回紹介する視点操作は以下のとおりです。

  • シューティング系
  • メタルギアソリッド系

注意:正規表現があまりキレイなコードではありません。ご指摘いただけますと幸いです。
gif内でカメラ操作がカクついているのは、トラックボールマウスを使用しているからです。

Unity3Dでの視点操作の種類別コード

シューティング系

良くTPSシューティングゲームに採用されているカメラ操作方法です。PUBGやFortnightの標準操作はこれですね。マウスをY軸(上下)方向に動かすとはカメラは上下に動き、X軸に動かすと__キャラクターの向きが左右に動きます__

参考画像
Desktop 2018.11.09 - 16.31.35.07.DVR-60-6-1541755929085.1.gif

MouseController.cs
using UnityEngine;

public class MouseController : MonoBehaviour
{
    [SerializeField]
    private Transform character;    //キャラクターをInspectorウィンドウから選択してください
    [SerializeField]
    private Transform pivot;    //キャラクターの中心にある空のオブジェクトを選択してください

    void Start()
    {
        //エラーが起きないようにNullだった場合、それぞれ設定
        if(character == null)
            character = transform.parent;
        if(pivot == null)
            pivot = transform;
    }
    //カメラ上下移動の最大、最小角度です。Inspectorウィンドウから設定してください
    [Range(-0.999f, -0.5f)]
    public float maxYAngle = -0.5f;
    [Range(0.5f, 0.999f)]
    public float minYAngle  = 0.5f;
    // Update is called once per frame
    void Update()
    {
        //マウスのX,Y軸がどれほど移動したかを取得します
        float X_Rotation = Input.GetAxis("Mouse X");
        float Y_Rotation = Input.GetAxis("Mouse Y");
        //Y軸を更新します(キャラクターを回転)取得したX軸の変更をキャラクターのY軸に反映します
        character.transform.Rotate(0, X_Rotation, 0);

        //次はY軸の設定です。
        float nowAngle = pivot.transform.localRotation.x;
        //最大値、または最小値を超えた場合、カメラをそれ以上動かない用にしています。
        //キャラクターの中身が見えたり、カメラが一回転しないようにするのを防ぎます。
        if (-Y_Rotation != 0)
        {
            if (0 < Y_Rotation)
            {
                if (minYAngle <= nowAngle)
                {
                    pivot.transform.Rotate(-Y_Rotation, 0, 0);
                }
            }
            else
            {
                if (nowAngle <= maxYAngle)
                {
                    pivot.transform.Rotate(-Y_Rotation, 0, 0);
                }
            }
        }
    }
}

上記のスクリプトを動かしたいカメラにアタッチし、unitychanの胴体の中心部分に空のオブジェクトを作成(Pivotと呼びます)し、カメラをその子要素にしてください。↓
キャプチャ.JPG

その後InspectorウィンドウからCharacterPivotにそれぞれのオブジェクトを設定してください。
上のGifではunitychan本体Characterに、上で作ったPivotpivotに設定しました。↓
キャプチャ.JPG

Pivotがあることで、カメラが上下に移動しても、しっかりとキャラクターを映す様になっています。TPSの目的は可愛い/カッコいいキャラクターが画面に映ることも利点の一つですからね。多くの紹介サイトではこれを忘れています。

Min Y AngleMax Y Angleですが、これを調整することで、カメラの上下移動範囲を広げることが出来ます。カメラ操作でもっと上まで見えるようにしたかったら、Max Y Angleを大きく設定するといいでしょう。

メタルギア・ソリッド系

メタルギア・ソリッドVを参考にしたカメラ操作方法です。スニーキングミッションは隠れることが重要で、後ろに敵が居るか確認したいときなどに視点を移動すると体の向きが変わり、物音を発したりや体が物陰からはみ出てしまうと大問題です。そのため、このカメラ操作で
はマウスをY軸(上下)方向に動かすとはカメラは上下に動き、X軸に動かすと__カメラがキャラクターの周りを回ります__

参考画像
Desktop 2018.11.09 - 17.26.21.10.DVR-9-7-1541759252669.1.gif

MetalGearMouseController.cs
using UnityEngine;

public class MetalGearMouseController : MonoBehaviour
{

    [SerializeField]
    private Transform pivot = null;
    void Start()
    {
        if (pivot == null)
            pivot = transform.parent;
    }

    [Range(-0.999f, -0.5f)]
    public float minYAngle = -0.5f;
    [Range(0.5f, 0.999f)]
    public float maxYAngle = 0.5f;
    void Update()
    {
        //マウスのX,Y軸がどれほど移動したかを取得します
        float X_Rotation = Input.GetAxis("Mouse X");
        float Y_Rotation = Input.GetAxis("Mouse Y");
        //Y軸を更新します(キャラクターを回転)取得したX軸の変更をキャラクターのY軸に反映します
        pivot.transform.Rotate(0, X_Rotation, 0);

        //次はY軸の設定です。
        float nowAngle = pivot.transform.localRotation.x;
        //最大値、または最小値を超えた場合、カメラをそれ以上動かない用にしています。
        //カメラが一回転しないようにするのを防ぎます。
        if (-Y_Rotation != 0)
        {
            if (0 < Y_Rotation)
            {
                if (minYAngle <= nowAngle)
                {
                    pivot.transform.Rotate(Y_Rotation, 0, 0);
                }
            }
            else
            {
                if (nowAngle <= maxYAngle)
                {
                    pivot.transform.Rotate(Y_Rotation, 0, 0);
                }
            }
        }
        //操作していると、Z軸がだんだん動いていくので、0に設定してください。
        pivot.eulerAngles = new Vector3(pivot.eulerAngles.x, pivot.eulerAngles.y, 0f);
    }
}

Inspectorウィンドウからの設定方法は上記シューティング系コードとほぼ同じです。ですが、今回はCharacterを回転させる必要がないので、Pivotのみとなっております。

終わりに

QiitaのMDってアンダーライン出来ないんですね…。また、マウスX,YがTransformのX,yと逆になっているのに、なぜ正しく動くのか謎です…ご存知の方はぜひ教えてください。

26
27
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?