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

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

ただいまの
回答率

90.75%

  • C#

    6556questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    3580questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

Unity-回転範囲制限付きのカメラが逆回転する

解決済

回答 3

投稿 編集

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

hgwr

score 58

Unity3Dについてです。
マウスのドラッグに応じてカメラが回転するスクリプトを書いたのですが、回転が設定した範囲制限に達すると、たまに逆回転し始めることがあります。

public class CameraController : MonoBehaviour {

    [SerializeField]
    private float RotSpeed;

    private Vector3 last;
    private Vector3 delta;


    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {


        if (Input.GetMouseButtonDown(0))
        {
            last = Input.mousePosition;
        }else if (Input.GetMouseButton(0))
        {
            delta = Input.mousePosition - last;

            var preEA = transform.localEulerAngles;

            preEA += new Vector3(-delta.y * RotSpeed, delta.x * RotSpeed, 0);

            if (preEA.x > 74.9f&&preEA.x<75.1f)
            {
                preEA.x = 75;
            }else if (preEA.x<265.1f&&preEA.x>264.9f)
            {
                preEA.x = 265;
            }


            transform.localEulerAngles = preEA;


            last = Input.mousePosition;

        }

    }
}

イメージ説明

これは何が原因なのでしょうか?

また、回転の範囲制限についてなのですが、範囲制限に達するとカメラが細かく振動してしまうのを防ぐにはどうすればよいですか?
入力でカメラがわずかに制限を超える→制限に応じて引き戻される
の繰り返しが起きて振動しているのだとは思いますが、対策が思い浮かびません。

回答よろしくお願いします。

追記:
以下がうまくいったコードです。

public class CameraController : MonoBehaviour {

    [SerializeField]
    private float RotSpeed;

    private Vector3 last;
    private Vector3 delta;


    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {


        if (Input.GetMouseButtonDown(0))
        {
            last = Input.mousePosition;
        }else if (Input.GetMouseButton(0))
        {
            delta = Input.mousePosition - last;

            var preEA = transform.localEulerAngles;

            preEA += new Vector3(-delta.y * RotSpeed, delta.x * RotSpeed, 0);

            if (preEA.x > 75 && preEA.x < 285)
            {
                if (delta.y > 0)
                {
                    preEA.x = 285;
                }
                else if(delta.y<0)
                {
                    preEA.x = 75;
                }
            }


            transform.localEulerAngles = preEA;


            last = Input.mousePosition;

        }

    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • negitama

    2018/05/12 03:12

    質問者さんのスクリプト、変数 currentEA が定義されていないので動かないですね。動いている版のものを貼り付けてください。

    キャンセル

  • hgwr

    2018/05/12 11:27

    すいません、preEAの間違いですね。直しておきます。

    キャンセル

回答 3

checkベストアンサー

0

■たまに逆回転する
74.9 〜 75.1 なら 75 にする
264.9 〜 265.1 なら 265 にする
となっていますが、入力値によっては「この条件分岐に当てはまらずに通過する」可能性があるかと思います。

1フレーム目:74.0 →条件には入らないのでそのまま
2フレーム目:74.8 →条件には入らないのでそのまま
3フレーム目:75.6 →条件には入らないのでそのまま
これは恐らく想定外の状況だと思うのですがいかがでしょうか?(大小逆かもしれませんが)

■範囲制限に達すると振動する
上記に影響されている可能性が高そうなのでまずはこちらを修正してみてください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/12 12:30

    指摘してくださったことを参考にあれこれ試してみたところ、追記したコードでうまく動いてくれました。
    マウスドラッグの方向で場合分けする感じです。
    回答ありがとうございました、勉強になりましたm(__)m

    キャンセル

0

Mathf.Clampを利用してはどうでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/12 12:32

    Clampはすでに試したのですが、うまくいきませんでした。
    制限したい範囲が0~75と285~360と地続きになっていないからだと思います。

    キャンセル

  • 2018/05/12 13:07

    すみません、コードをよく読んでいませんでした。
    75~285の範囲と勘違いしていました。

    キャンセル

0

細かく振動する件についてだけコメントします。

私も同じようなものを作ったことがありますが、「特定の高さ以上(以下)では入力を処理しない」、という考え方をとりました。
入力を受け取って処理をしてあとで、上下限を超えていたら範囲内に収める、という処理にすると、その動きが繰り返されて細かく振動してしまうためです。

参考コード(質問者さんのコードとは全く別の物です)

        //上下キーでカメラを上下に移動する
        if ( Input.GetKey ( KeyCode.UpArrow ) )
        {
            // 対象物との高さの差が上限を超えない範囲でのみ、入力を処理する
            if ( transform.position.y < target.position.y + yOffsetMax )
            {
                transform.Translate ( Vector3.up * verticalMoveSpeed * Time.deltaTime );
            }
        }
        else if ( Input.GetKey ( KeyCode.DownArrow ) )
        {
            if ( transform.position.y > target.position.y - yOffsetMax )
            {
                transform.Translate ( -Vector3.up * verticalMoveSpeed * Time.deltaTime );
            }
        }


質問者さんの場合は角度で処理を行って、その角度に制限を付けようとしていると思いますが、同じような考え方を適用できるのではないでしょうか。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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

  • C#

    6556questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    3580questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。