回答編集履歴

1

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

2018/11/04 09:16

投稿

Bongo
Bongo

スコア10807

test CHANGED
@@ -73,3 +73,101 @@
73
73
  }
74
74
 
75
75
  ```
76
+
77
+
78
+
79
+ #追記
80
+
81
+
82
+
83
+ タッチ用コードでは[deltaPosition](https://docs.unity3d.com/ja/current/ScriptReference/Touch-deltaPosition.html)を使っているのがポイントですね。
84
+
85
+ 上で申しあげたように、`Rotate`は現在の姿勢を基準に回転を追加する動作となります。`deltaPosition`は「前フレームの指の位置からの差分」(「タッチを開始した位置からの差分」ではない点にご注意ください)を示しており、これをもとに求めた角度を使って`Rotate`で回しているのでうまくいっていると考えられます。
86
+
87
+ 最初に挙げた例と同様に考えると...
88
+
89
+
90
+
91
+ - 画面上端中央にタッチする。
92
+
93
+ - そのまま真下にすばやくスワイプし(1フレームで一気に動かしたものとご想像ください)、画面中央で指を止める。
94
+
95
+ `deltaPosition`には指の移動量が入っている。画面高さの半分の距離を移動したので、求めた`mouseDeltaPositionY`は`-0.5`、`xAngle`は`-45.0`となる。
96
+
97
+ `this.transform.Rotate(-45, 0, 0, Space.World);`が実行され、45°回転する。
98
+
99
+ - このまま画面中央から指を動かさなかった場合、次のフレームの`deltaPosition`は移動なしのためゼロベクトルを示す。
100
+
101
+ 求められる回転角も0°なので、そのまま指を動かさず触れ続けていても、先の例のように回転し続けてしまうことはない。
102
+
103
+
104
+
105
+ マウス版コードの書き換え案ですが、こちらもタッチ版と同じように、角度算出の基となるポインタ座標差分を「ドラッグ開始時の位置からの差分」ではなく「前フレームの位置からの差分」に変更すれば`Rotate`を使用できるはずです。
106
+
107
+ 下記のような形ではいかがでしょうか?
108
+
109
+
110
+
111
+ ```C#
112
+
113
+ Vector2 prevPos; // 覚えておく座標を「マウスボタン押し下げ時の座標」から「前回の座標」に変更...フィールド名を使用目的に沿った名前に変えた
114
+
115
+ float mouseDeltaPositionX, mouseDeltaPositionY;
116
+
117
+ float xAngle, yAngle, zAngle = 0;
118
+
119
+
120
+
121
+ void Update()
122
+
123
+ {
124
+
125
+ if (Input.GetMouseButtonDown(0))
126
+
127
+ {
128
+
129
+ // フィールド名が「prevPos」に変わっただけで、ボタン押し下げ時に最初の座標を覚えておくのは変わらない
130
+
131
+ prevPos = Input.mousePosition;
132
+
133
+ }
134
+
135
+ else if (Input.GetMouseButton(0))
136
+
137
+ {
138
+
139
+ // ここも同じく名前が「prevPos」に変わっただけだが、意味合いとしては「前フレームとのポインタ位置差分を求める」となる
140
+
141
+ mouseDeltaPositionX = (Input.mousePosition.x - prevPos.x) / Screen.width;
142
+
143
+ mouseDeltaPositionY = (Input.mousePosition.y - prevPos.y) / Screen.height;
144
+
145
+
146
+
147
+ // ポインタ位置差分を求めた後で、現在のポインタ位置をprevPosに代入し、次回のUpdate実行に備える
148
+
149
+ // この「現在のポインタ位置」が、次フレームでは「前フレームのポインタ位置」となる
150
+
151
+ prevPos = Input.mousePosition;
152
+
153
+
154
+
155
+ // 以降の処理は変更なし
156
+
157
+
158
+
159
+ float xAngle = mouseDeltaPositionY * 90;
160
+
161
+ float yAngle = -mouseDeltaPositionX * 90;
162
+
163
+
164
+
165
+ //回転
166
+
167
+ this.transform.Rotate(xAngle, yAngle, zAngle, Space.World);
168
+
169
+ }
170
+
171
+ }
172
+
173
+ ```