teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

タッチ用コードとの差異についてコメント、マウス用コードのRotate版を検討

2018/11/04 09:16

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -35,4 +35,53 @@
35
35
  this.transform.rotation = Quaternion.Euler(xAngle, yAngle, zAngle) * beganRot;
36
36
  }
37
37
  }
38
+ ```
39
+
40
+ #追記
41
+
42
+ タッチ用コードでは[deltaPosition](https://docs.unity3d.com/ja/current/ScriptReference/Touch-deltaPosition.html)を使っているのがポイントですね。
43
+ 上で申しあげたように、`Rotate`は現在の姿勢を基準に回転を追加する動作となります。`deltaPosition`は「前フレームの指の位置からの差分」(「タッチを開始した位置からの差分」ではない点にご注意ください)を示しており、これをもとに求めた角度を使って`Rotate`で回しているのでうまくいっていると考えられます。
44
+ 最初に挙げた例と同様に考えると...
45
+
46
+ - 画面上端中央にタッチする。
47
+ - そのまま真下にすばやくスワイプし(1フレームで一気に動かしたものとご想像ください)、画面中央で指を止める。
48
+ `deltaPosition`には指の移動量が入っている。画面高さの半分の距離を移動したので、求めた`mouseDeltaPositionY`は`-0.5`、`xAngle`は`-45.0`となる。
49
+ `this.transform.Rotate(-45, 0, 0, Space.World);`が実行され、45°回転する。
50
+ - このまま画面中央から指を動かさなかった場合、次のフレームの`deltaPosition`は移動なしのためゼロベクトルを示す。
51
+ 求められる回転角も0°なので、そのまま指を動かさず触れ続けていても、先の例のように回転し続けてしまうことはない。
52
+
53
+ マウス版コードの書き換え案ですが、こちらもタッチ版と同じように、角度算出の基となるポインタ座標差分を「ドラッグ開始時の位置からの差分」ではなく「前フレームの位置からの差分」に変更すれば`Rotate`を使用できるはずです。
54
+ 下記のような形ではいかがでしょうか?
55
+
56
+ ```C#
57
+ Vector2 prevPos; // 覚えておく座標を「マウスボタン押し下げ時の座標」から「前回の座標」に変更...フィールド名を使用目的に沿った名前に変えた
58
+ float mouseDeltaPositionX, mouseDeltaPositionY;
59
+ float xAngle, yAngle, zAngle = 0;
60
+
61
+ void Update()
62
+ {
63
+ if (Input.GetMouseButtonDown(0))
64
+ {
65
+ // フィールド名が「prevPos」に変わっただけで、ボタン押し下げ時に最初の座標を覚えておくのは変わらない
66
+ prevPos = Input.mousePosition;
67
+ }
68
+ else if (Input.GetMouseButton(0))
69
+ {
70
+ // ここも同じく名前が「prevPos」に変わっただけだが、意味合いとしては「前フレームとのポインタ位置差分を求める」となる
71
+ mouseDeltaPositionX = (Input.mousePosition.x - prevPos.x) / Screen.width;
72
+ mouseDeltaPositionY = (Input.mousePosition.y - prevPos.y) / Screen.height;
73
+
74
+ // ポインタ位置差分を求めた後で、現在のポインタ位置をprevPosに代入し、次回のUpdate実行に備える
75
+ // この「現在のポインタ位置」が、次フレームでは「前フレームのポインタ位置」となる
76
+ prevPos = Input.mousePosition;
77
+
78
+ // 以降の処理は変更なし
79
+
80
+ float xAngle = mouseDeltaPositionY * 90;
81
+ float yAngle = -mouseDeltaPositionX * 90;
82
+
83
+ //回転
84
+ this.transform.Rotate(xAngle, yAngle, zAngle, Space.World);
85
+ }
86
+ }
38
87
  ```