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

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

ただいまの
回答率

88.81%

【Unity3D】 フリックしてオブジェクトを90度回転させたい

解決済

回答 1

投稿

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

Taku.

score 16

やりたいこと

フリックして3Dのオブジェクトをフリック方向に合わせて90度回転させたいです。

課題

フリックしてオブジェクトが反転したときに動作が逆になってしまいます。
下にフリックしてオブジェクトが下を向いたときに、右にフリックすると右方向ではなく左方向を向いてしまったり、それらが重なると下にフリックしたのに右に回転したりしてしまいます。

現状のコード

using UnityEngine;
using DG.Tweening;

public class CubeMover : MonoBehaviour
{
    GameObject Cube;
    Vector2 _direction; 
    Vector3 _rotation;
    string Direction;
    bool _canmove  = true;
    bool _ismove = false;

    // Start is called before the first frame update
    void Start()
    {
        Cube = GameObject.FindGameObjectWithTag("Cube");
    }

    void Update()
    {
        if (Input.touchCount > 0) 
        {
            Touch touch = Input.GetTouch(0);

            if (Input.GetTouch(0).phase == TouchPhase.Began)
            {
                _direction = Vector2.zero;
                _rotation = Cube.transform.localEulerAngles;

                if(!_ismove){
                    _canmove = true;
                }
            }

            if (Input.GetTouch(0).phase == TouchPhase.Moved)
            {
                _direction = touch.deltaPosition;
                if (_direction.magnitude < 30.0f){
                    return;
                }else{
                    float x = _direction.x;
                    float y = _direction.y;

                    float abs_x = Mathf.Abs(_direction.x); 
                    float abs_y = Mathf.Abs(_direction.y); 

                    if(abs_x > abs_y)
                    {
                        if(x > 0)
                        {
                            Direction = "right";
                        }
                        else
                        {
                            Direction = "left";
                        }
                    }
                    else
                    {
                        if(y > 0)
                        {
                            Direction = "up";
                        }
                        else
                        {
                            Direction = "down";
                        }
                    } 

                    if(_canmove)
                    {
                        _canmove = false;
                        _ismove = true;
                        Move();
                    }                  
                }
            }
            if (Input.GetTouch(0).phase == TouchPhase.Ended)
            {
                _direction = Vector2.zero;
            }
        }
    }

    void Move()
    {
        float duration = 0.2f; 
        Vector3 _left = new Vector3(0,0,90);
        Vector3 _right = new Vector3(0,0,-90);
        Vector3 _up = new Vector3(90,0,0);
        Vector3 _down = new Vector3(-90,0,0);

        switch (Direction){
            case "up":
            Cube.transform.DORotate(_rotation + _up , duration)
            .OnComplete(() => {
                _ismove = false;
            });
            break;

            case "down":
            Cube.transform.DORotate(_rotation + _down , duration)
            .OnComplete(() => {
                _ismove = false;
            });
            break;

            case "right":
            Cube.transform.DORotate(_rotation + _right , duration)
            .OnComplete(() => {
                _ismove = false;
            });
            break;

            case "left":
            Cube.transform.DORotate(_rotation + _left , duration)
            .OnComplete(() => {
                _ismove = false;
            });
            break;
        }
    }

}

ご教授頂ければ幸いです。よろしくお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

カメラの視点が常に一定なのでしたら、キューブの回転をワールド空間を基準に決定してみてはいかがでしょうか?
たとえば下記のようにしてみてはいかがでしょう。すみませんがDOTweenは使用経験が浅く、効果的な方法を見落としているかもしれませんので参考程度でお願いします。
こうしたらもっといいんじゃないか...といった点がありましたら、ぜひ改造を加えてしまってください。

using UnityEngine;
using DG.Tweening;

public class CubeMover : MonoBehaviour
{
    GameObject Cube;
    Vector2 _direction;
    Quaternion _rotation; // Vector3をQuaternionに変更
    string Direction;
    bool _canmove  = true;
    bool _ismove = false;

    void Start()
    {
        Cube = GameObject.FindGameObjectWithTag("Cube");
    }

    void Update()
    {
        if (Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);

            if (touch.phase == TouchPhase.Began)
            {
                _direction = Vector2.zero;
                _rotation = Cube.transform.rotation; // ワールド空間における姿勢を覚えておく

                if(!_ismove){
                    _canmove = true;
                }
            }

            if (touch.phase == TouchPhase.Moved)
            {
                _direction = touch.deltaPosition;
                if (_direction.magnitude < 30.0f){
                    return;
                }
                else
                {
                    float x = _direction.x;
                    float y = _direction.y;

                    float abs_x = Mathf.Abs(_direction.x);
                    float abs_y = Mathf.Abs(_direction.y);

                    if(abs_x > abs_y)
                    {
                        if(x > 0)
                        {
                            Direction = "right";
                        }
                        else
                        {
                            Direction = "left";
                        }
                    }
                    else
                    {
                        if(y > 0)
                        {
                            Direction = "up";
                        }
                        else
                        {
                            Direction = "down";
                        }
                    } 

                    if(_canmove)
                    {
                        _canmove = false;
                        _ismove = true;
                        Move();
                    }
                }
            }

            if (touch.phase == TouchPhase.Ended)
            {
                _direction = Vector2.zero;
            }
        }
    }

    void Move()
    {
        float duration = 0.2f; 
        Vector3 _left = new Vector3(0, 0, 90);
        Vector3 _right = new Vector3(0, 0, -90);
        Vector3 _up = new Vector3(90, 0, 0);
        Vector3 _down = new Vector3(-90, 0, 0);

        // 現在の姿勢に対して90°回転をワールド空間基準で合成し、DORotateQuaternionで回す
        switch (Direction){
            case "up":
                Cube.transform.DORotateQuaternion(Quaternion.Euler(_up) * _rotation, duration)
                    .OnComplete(() => {
                        _ismove = false;
                    });
                break;

            case "down":
                Cube.transform.DORotateQuaternion(Quaternion.Euler(_down) * _rotation, duration)
                    .OnComplete(() => {
                        _ismove = false;
                    });
                break;

            case "right":
                Cube.transform.DORotateQuaternion(Quaternion.Euler(_right) * _rotation, duration)
                    .OnComplete(() => {
                        _ismove = false;
                    });
                break;

            case "left":
                Cube.transform.DORotateQuaternion(Quaternion.Euler(_left) * _rotation, duration)
                    .OnComplete(() => {
                        _ismove = false;
                    });
                break;
        }
    }
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/08/12 12:38

    思った通りに機能させることができました!
    Quaternion.AngleAxisを使って試して駄目だったのですが、Quaternion.Eulerを用いるのがこの場合正しい方法なのですね!
    大変助かりました!ありがとうございます!

    キャンセル

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

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

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