質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

VRの一人称の視点(カメラ)の角度制限について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 978

nabesi

score 13

一人称の視点(カメラ)の角度制限についての質問です。

現在VR内でキャラクターを動かすスクリプトを作成しています。
下記コードは頭を前後に傾けると前や後ろに進み、頭を左右に傾けると左右に曲がれる動きなのですが、VR酔い防止の為、左右の傾きに角度制限をつけたいと思っています。(現在は地面すれすれまで傾けることができます)

Mathf.Clampなどを試してみましたが上手くいきません。
下記コードへの角度制限の付け方を教えてください。よろしくお願いします。

public class GazeController : MonoBehaviour
{
    new Rigidbody rigidbody;      //リジッドボディーを使用
    new GameObject camera;        //カメラ

    //初期化
    void Start()
    {
        this.rigidbody = GetComponent<Rigidbody>();
        this.camera = GameObject.Find("Main Camera");
    }

    //定期的に呼ばれる
    void FixedUpdate()
    {
        //Player操作
        float x = camera.transform.localEulerAngles.x;
        float z = camera.transform.localEulerAngles.z;

        if (x < 180) x += 360;
        if (z < 180) z += 360;

        float h = (Math.Min((360f - z), 45f) / 45f) * 1f;
        float v = (Math.Min((z - 360f), 10f) / 10f) * 5f;


        //Playerの向きと加速度の指定
        if (v != 0f)
        {
            this.gameObject.transform.Rotate(0, (v > 0) ? h : -h, 0);
        }

        this.rigidbody.velocity = this.gameObject.transform.rotation * 
     new Vector3(0, 0, v);
        }


追記

using System;
using UnityEngine;

//Playerへアタッチするスクリプト
//MainCameraはPlayerの子要素

public class GazeController : MonoBehaviour
{
    new Rigidbody rigidbody;      //リジッドボディーを使用
    public new GameObject camera;        //カメラ

    //初期化
    void Start()
    {
        this.rigidbody = GetComponent<Rigidbody>();
        this.camera = GameObject.Find("Main Camera");
    }

    //定期的に呼ばれる
    void FixedUpdate()
    {
        PlayerController();
    }

     private void PlayerController()
    {  //cameraのVector3をlocalupへ取得
        var localup = camera.transform.rotation * Vector3.up;

        var frontangle = Mathf.Atan2(localup.y, localup.z) * Mathf.Rad2Deg; //上下角度
        var sideangle = Mathf.Atan2(localup.y, localup.x) * Mathf.Rad2Deg; //左右角度

        //取得した数値が360になるように270を足す( Debug.Logで数値を確認)
        if (frontangle < 180) frontangle += 270;
        if (sideangle < 180) sideangle += 270;

        // 最小値を返す関数、最初は(frontangle - 360f)=0からのスタートとする
        float FB = (Math.Min((frontangle - 360f), 10f) / 10f) * 5f ; //上下角度
        float LR = (Math.Min((360f - sideangle), 15f) / 15f) * 1f; //左右角度
        Debug.Log("FB:" + FB); //Angle数値の確認用
        Debug.Log("LR:" + LR);


        //Playerの向きと加速度の指定
        //前後
        this.rigidbody.velocity = this.gameObject.transform.rotation * new Vector3(0, 0, FB);

        //左右
        if (FB != 0f)
        {
            this.gameObject.transform.Rotate(0, (FB > 0) ? LR : -LR, 0); 
        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

要するに、自分の頭をジョイスティックに見立てて操作する、ということですね。

ただ、角度を正しく求める、という部分に問題があるように見えます。
オイラー角(localEulerAngles)は、3つ揃って意味があるので、1つだけ取り出すということをしてはいけません。
なぜなら、回転としては等しいのに、オイラー角のx,y,zが異なる事があるからです。
要は、x軸を中心に45度回転させても、x=45ではない値になることがあります。

そこで、角度を求めたいときは、基準となるベクトルを回転させて、
基準ベクトルとの角度を求めることで対応します。

具体的にはこんな感じです。

var localup = transform.rotation * Vector3.up;

var frontangle = Mathf.Atan2(localup.y, localup.z) * Mathf.Rad2Deg;
var sideangle = Mathf.Atan2(localup.y, localup.x) * Mathf.Rad2Deg;

後は、頻繁に動くと鬱陶しいので遊びをつける(少しだけなら傾けても移動や回転をしないようにする)とか
一定角度以上は1以上にならない、などをつければいいと思います

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/10 00:04

    ご回答いただきまして、ありがとうございます。教えていただいたコードを元にスクリプトを修正してPlayerを操作するところまではできました。しかし質問内容の回転限度の制御まではまだ上手くいっていませんので、もう少し頑張ってみます。また、追加でアドバイスなどがありましたら是非お願いします!
    修正したコードは追加でアップしました。

    キャンセル

check解決した方法

0

GoogleVRのスクリプトを使用していたのですが、そちらのスクリプトを書き換えたらできました。ご回答いただきましてありがとうございました。
イメージ説明
このスクリプトの
イメージ説明
こちらの部分です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る