1
0

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.

[Unity] ゲームパッドで視点操作とカメラ移動の同期2(FPS的操作)

Last updated at Posted at 2019-04-08

#はじめに
*注意*この記事はプログラミングの基礎知識がある前提で進みます。
レベルとしてはC++でちょっと書いたことあるよとか、Javaならいじったことあるぜ、って人ならば十分に理解できるでしょう。
あと高校数学の知識を必要とします。
それと、その1を見ないと多分意味わからないから見てね。

#視点操作とカメラ移動の同期編
やっとタイトルが出てきましたね。
前回はこんなコードで終了しましたね。

move
void update(){
    float dx = Input.GetAxis("Horizontal");
    float dz = Input.GetAxis("Vertical");

    transform.Translate(dx, 0, dz, 0.0F);
}

さあ、何故ダメなのかを答え合わせしよう。
実際にやってみた人ならばわかるだろうが、カメラの視点とカメラの移動が同期されていないのです。

さてここからは最も重要な範囲であり、最も退屈な理論の時間です。

###同期の理論
カメラの移動はカメラの視点に同期する必要があると思いました。
じゃあどうして同期してやればいいでしょう。
私が思いついた方法を説明します。

実はその1で sight_x の範囲を 0 ~ 360にしましたね。
その理由が今回、その値を利用して方角を決めるからなのです。
sight_x は z軸方向を正方向つまり 0度と定めた角度なのです。

####上下入力があった場合
ではまず左スティックの上下入力があった場合を考えてみましょう。
zahyo1.JPG
カメラが向いている方向が sight_x度方向であるとして、ベクトルの移動量が1であるとすると

1^2 = x方向の移動量^2 + y方向の移動量^2

                     つまり

1 = sin(sight\_x)^2 + cos(sight\_x)^2

      入力量は常に1または-1であるとは限らないので、入力量を両辺にかける

z^2 = (zsin(sight\_x))^2 + (zcos(sight\_x))^2

       したがって各成分を分解してみると、z軸方法の移動量をdz1とすると

dz1 = zcos(sight\_x)

                 x軸方法の移動量をdx1とすると

dx1 = zsin(sight\_x)

                 となることがわかりました。
####左右入力があった場合
これはカメラが向いている方向から右に90度方向に進めばいいということになります。
ということは気づいた方もいると思いますが、sight_x90を足せばいいということです。

1 = sin(sight\_x+90)^2 + cos(sight\_x+90)^2

            先ほどの理論より、x軸方向の移動量を掛けると

x^2 = (xsin(sight\_x+90))^2 + (xcos(sight\_x+90))^2

       したがって各成分を分解してみると、z軸方法の移動量をdz2とすると

dz2 = xcos(sight\_x+90)

                 x軸方法の移動量をdx1とすると

dx2 = xsin(sight\_x+90)

                 となることがわかりました。
#結果
上下左右の入力から求めた移動量をあわせるとz軸方向の移動量をdzx軸方向の移動量をdxとすると、

dz = dz1 + dz2 = zcos(sight\_x) + xcos(sight\_x+90)
dx = dx1 + dx2 = zsin(sight\_x) + xsin(sight\_x+90)

となります。お疲れさまでした、理論は終わりです。

#実行
さあ、長い理論にお付き合いいただきましたので、さっそく使っていただきましょう。
先ほどの移動量の式をコードに変換すると

float dx = Mathf.Sin(sight_x * Mathf.Deg2Rad) * z + Mathf.Sin((sight_x + 90f) * Mathf.Deg2Rad) * x;
float dz = Mathf.Cos(sight_x * Mathf.Deg2Rad) * z + Mathf.Cos((sight_x + 90f) * Mathf.Deg2Rad) * x;

このコードを追加して、コードを完成させると


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

public class クラス名 : MonoBehaviour
{

    void Start()
    {

    }

    float sight_x = 0;
    float sight_y = 0;

    void controller()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
        float angleH = Input.GetAxis("Horizontal2") * 5.0f;
        float angleV = Input.GetAxis("Vertical2") * 5.0f;

        if (sight_x >= 360)
        {
            sight_x = sight_x - 360;
        }
        else if (sight_x < 0){
            sight_x = 360 - sight_x;
        }
        sight_x = sight_x + angleH;

        if (sight_y > 80)
        {
            if (angleV < 0)
            {
                sight_y = sight_y + angleV;
            }
        }
        else if (sight_y < -90)
        {
            if (angleV > 0)
            {
                sight_y = sight_y + angleV;
            }
        }
        else
        {
            sight_y = sight_y + angleV;
        }

        float dx = Mathf.Sin(sight_x * Mathf.Deg2Rad) * z + Mathf.Sin((sight_x + 90f) * Mathf.Deg2Rad) * x;

        float dz = Mathf.Cos(sight_x * Mathf.Deg2Rad) * z + Mathf.Cos((sight_x + 90f) * Mathf.Deg2Rad) * x;

        transform.Translate(dx, 0, dz, 0.0F);

        transform.localRotation = Quaternion.Euler(sight_y, sight_x, 0);

        //Debug.Log("sight_x:sight_y \n" + sight_x + " : " + sight_y);
        Debug.Log("dx:dz \n" + dx + " : " + dz);
    }

    void Update()
    {
        controller();
    }
}

よく頑張りました、これで視点操作とカメラ移動の同期を終了します。
何かわからないことがあればコメントで遠慮せずに尋ねてください。
私はすべてのプログラマーの味方でありたいと思っていますので。   それではさようならっ!!

#あとがき(自己紹介です、読まなくてもいいです)
私はVonletと申します。
プログラミング、電子工作、作曲などを生きがいにしています。
一番わかりやすいものでしたら、

マクドナルド(シオンタウン店)
https://www.nicovideo.jp/watch/sm34895662

FutureHouse神社(bootleg).dondiablo
https://www.nicovideo.jp/watch/sm34666016

などを作って恥を晒しています。よろしければ見に行ってやってください。

最後に自分のSNSを載せておきます
YouTube : https://www.youtube.com/channel/UCvL2cxUWsnBDT95jSq1G9QQ
Twitter : https://twitter.com/Vonlet
ニコニコ動画 : https://www.nicovideo.jp/user/87637963
Sound Cloud : https://soundcloud.com/8yve6bc8icio

1
0
6

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?