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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

2973閲覧

マウスドラッグにあわせてオブジェクトを回転させたい

hogehoge23

総合スコア14

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/07/29 16:24

お世話になっております。Unityでオブジェクトを回転させて落とすというざっくりテトリスのようなゲームを作成しています。
現在、マウスのドラッグで座標のx軸の移動量を見てオブジェクトの回転を実装しています。

cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Test : MonoBehaviour 6{ 7 Vector3 firstPos; 8 Vector3 lastPos; 9 10 // Update is called once per frame 11 void Update() 12 { 13 if (Input.GetMouseButtonDown(0)) { 14 firstPos = Input.mousePosition; 15 }else if (Input.GetMouseButton(0)) { 16 lastPos = Input.mousePosition; 17 18 var dic = lastPos - firstPos; 19 20 if(dic.x > 1.0f) { 21 gameObject.transform.Rotate(0, 0, -1); 22 }else if(dic.x < -1.0f) { 23 gameObject.transform.Rotate(0, 0, 1); 24 } 25 } 26 } 27}

これはこれで操作方法の1つとしてはアリかなとも思っているのですが、できればOffice製品とか、それこそUnityでオブジェクトを回転モードで回す際みたいに、ドラッグしてぐるっと円を描くように動かすとそれに応じて回転するような動きを作りたいと考えています。

イメージ説明

たとえばこんな感じで、下からドラッグを初めて時計回りでぐるっと上に引っ張れば、オブジェクトもそれに連動して時計回りにドラッグに連動して回転していく、といった感じです。

#改善案 ― ためしたこと
調べてみた結果、ドラッグした2点間の角度を求めてそれをオブジェクトの回転に反映させれば良さそうだということがわかったので
開始点と現在点に対して、オブジェクトの中央からベクトルを作り、その2つのベクトルの角度を足してみたのですが
これだと一定方向にしか回転しないのと、回転がキツすぎて操作しづらすぎるのでうまくいきませんでした。

cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Test : MonoBehaviour 6{ 7 Vector3 firstPos; 8 Vector3 lastPos; 9 10 // Update is called once per frame 11 void Update() 12 { 13 if (Input.GetMouseButtonDown(0)) { 14 firstPos = Input.mousePosition; 15 }else if (Input.GetMouseButton(0)) { 16 lastPos = Input.mousePosition; 17 18 var firstVec = firstPos - gameObject.transform.position; 19 var lastVec = lastPos - gameObject.transform.position; 20 var angleTwoVec = Vector3.Angle(firstVec, lastVec); 21 22 gameObject.transform.rotation = Quaternion.Euler(0, 0, gameObject.transform.rotation.eulerAngles.z + angleTwoVec); 23 } 24 } 25}

左右ともに切り替えてドラッグして回転できるような操作が理想なのですが、どのように改善すれば実現できますでしょうか? お知恵をお借りできれば幸いです。よろしくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Unity : マウスで物体を回転させる|こんぶ|noteで、回転の向きを2つの方向の外積のZ成分の向きで判定する方法が紹介されていました。
あるいは、Vector2.SignedAngleを使ってもよさそうですね。

回転がキツすぎる...とおっしゃるのは、もしかして「ドラッグ中にマウスポインタを静止させても回り続けてしまい、ドラッグ量が大きいほど回転速度が速くなってしまう」という症状でしょうか?
だとすると、ご提示のコードでは現在のZ回転角に対して求めた角度差を加算していますので、そのような動きになったものと考えられます。

下記のように変更してみましたが、いかがでしょうか?
上記で申し上げた点に加えて、念のためInpput.mousePositionをワールド座標に変換するようにしていますが、もしあらかじめワールド座標とスクリーン座標が一致するようカメラを設定しているのでしたら不要かもしれません。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Test : MonoBehaviour 6{ 7 // 覚えておくのをfirstVecに変更、型もVector3からVector2に変更 8 Vector2 firstVec; 9 10 // ドラッグ開始時のZ回転角を記憶しておくためのfloatを追加 11 float initialAngleZ; 12 13 // Input.mousePositionはスクリーン座標なのでワールド座標に変換したい 14 // そこでメインカメラを取得しておき、ScreenToWorldPointを使うことにする 15 Camera mainCamera; 16 17 void Awake() 18 { 19 mainCamera = Camera.main; 20 } 21 22 // Update is called once per frame 23 void Update() 24 { 25 if (Input.GetMouseButtonDown(0)) { 26 firstVec = (Vector2)mainCamera.ScreenToWorldPoint(Input.mousePosition) - (Vector2)transform.position; 27 initialAngleZ = transform.eulerAngles.z; 28 } else if (Input.GetMouseButton(0)) { 29 var lastVec = (Vector2)mainCamera.ScreenToWorldPoint(Input.mousePosition) - (Vector2)transform.position; 30 31 // SignedAngleに変更し、符号付きの角度差を求める 32 var angleTwoVec = Vector2.SignedAngle(firstVec, lastVec); 33 34 // 「現在のZ回転角」ではなく、「ドラッグ開始時のZ回転角」に対して角度差を加算するように変更 35 transform.rotation = Quaternion.Euler(0, 0, initialAngleZ + angleTwoVec); 36 } 37 } 38}

投稿2019/07/29 21:46

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問