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

回答編集履歴

1

使い勝手の改善案を追記

2018/02/24 04:21

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -4,4 +4,99 @@
4
4
 
5
5
  __Rigidbody.rotationによって、物理エンジンによるRigidbodyの回転を取得・設定できます。Rigidbody.rotationによりRigidbodyの回転を変更した場合、transformは次回の物理シミュレーションステップの後に更新されます。この方法はTransform.rotationでの回転更新よりも高速です。Transform.rotationによる回転更新の場合、アタッチされているすべてのColliderについて、Rigidbodyに対する相対回転の再計算が発生するためです。__
6
6
 
7
- とのことでした。Transform.rotationによる回転は明確に禁止されているわけではないようですが、やや非効率的になる様子ですね。
7
+ とのことでした。Transform.rotationによる回転は明確に禁止されているわけではないようですが、やや非効率的になる様子ですね。
8
+
9
+ ### [追記]
10
+
11
+ 確かにRotateが使えないのは不便かもしれませんね。下記のようなスクリプトを作ってみるのはいかがでしょう?
12
+
13
+ ```C#
14
+ using UnityEngine;
15
+
16
+ public static class RigidbodyExtensions
17
+ {
18
+ /// <summary>
19
+ /// Rigidbodyを回転します。
20
+ /// </summary>
21
+ /// <param name="rigidbody">回転対象のRigidbody。</param>
22
+ /// <param name="eulerAngles">オイラー角による回転量。</param>
23
+ /// <param name="relativeTo"><c>Space.Self</c>の場合はRigidbodyのローカル軸に対して、<c>Space.World</c>の場合はワールド軸に対して回転を適用します。</param>
24
+ /// <param name="isMovingMode"><c>true</c>の場合は、rotationへの回転設定の代わりにMoveRotationを使用して回転します。</param>
25
+ public static void Rotate(
26
+ this Rigidbody rigidbody,
27
+ Vector3 eulerAngles,
28
+ Space relativeTo = Space.Self,
29
+ bool isMovingMode = false)
30
+ {
31
+ rigidbody.Rotate(Quaternion.Euler(eulerAngles), relativeTo, isMovingMode);
32
+ }
33
+
34
+ /// <summary>
35
+ /// Rigidbodyを回転します。
36
+ /// </summary>
37
+ /// <param name="rigidbody">回転対象のRigidbody。</param>
38
+ /// <param name="xAngle">X軸周り回転量。</param>
39
+ /// <param name="yAngle">Y軸周り回転量。</param>
40
+ /// <param name="zAngle">Z軸周り回転量。</param>
41
+ /// <param name="relativeTo"><c>Space.Self</c>の場合はRigidbodyのローカル軸に対して、<c>Space.World</c>の場合はワールド軸に対して回転を適用します。</param>
42
+ /// <param name="isMovingMode"><c>true</c>の場合は、rotationへの回転設定の代わりにMoveRotationを使用して回転します。</param>
43
+ public static void Rotate(
44
+ this Rigidbody rigidbody,
45
+ float xAngle,
46
+ float yAngle,
47
+ float zAngle,
48
+ Space relativeTo = Space.Self,
49
+ bool isMovingMode = false)
50
+ {
51
+ rigidbody.Rotate(Quaternion.Euler(xAngle, yAngle, zAngle), relativeTo, isMovingMode);
52
+ }
53
+
54
+ /// <summary>
55
+ /// Rigidbodyを回転します。
56
+ /// </summary>
57
+ /// <param name="rigidbody">回転対象のRigidbody。</param>
58
+ /// <param name="axis">回転軸。</param>
59
+ /// <param name="angle">回転量。</param>
60
+ /// <param name="relativeTo"><c>Space.Self</c>の場合はRigidbodyのローカル軸に対して、<c>Space.World</c>の場合はワールド軸に対して回転を適用します。</param>
61
+ /// <param name="isMovingMode"><c>true</c>の場合は、rotationへの回転設定の代わりにMoveRotationを使用して回転します。</param>
62
+ public static void Rotate(
63
+ this Rigidbody rigidbody,
64
+ Vector3 axis,
65
+ float angle,
66
+ Space relativeTo = Space.Self,
67
+ bool isMovingMode = false)
68
+ {
69
+ rigidbody.Rotate(Quaternion.AngleAxis(angle, axis), relativeTo, isMovingMode);
70
+ }
71
+
72
+ /// <summary>
73
+ /// Rigidbodyを回転します。
74
+ /// </summary>
75
+ /// <param name="rigidbody">回転対象のRigidbody。</param>
76
+ /// <param name="rotation">クォータニオンによる回転。</param>
77
+ /// <param name="relativeTo"><c>Space.Self</c>の場合はRigidbodyのローカル軸に対して、<c>Space.World</c>の場合はワールド軸に対して回転を適用します。</param>
78
+ /// <param name="isMovingMode"><c>true</c>の場合は、rotationへの回転設定の代わりにMoveRotationを使用して回転します。</param>
79
+ public static void Rotate(
80
+ this Rigidbody rigidbody,
81
+ Quaternion rotation,
82
+ Space relativeTo = Space.Self,
83
+ bool isMovingMode = false)
84
+ {
85
+ var newRotation = relativeTo == Space.Self ? rigidbody.rotation * rotation : rotation * rigidbody.rotation;
86
+ if (isMovingMode)
87
+ {
88
+ rigidbody.MoveRotation(newRotation);
89
+ }
90
+ else
91
+ {
92
+ rigidbody.rotation = newRotation;
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ これで下図のように、RigidbodyにRotateメソッドが追加されたかのように使えるかと思います。
99
+
100
+ ![プレビュー](978637a5ade8d42fedfb13d8cdedbd8c.png)
101
+
102
+ ※おそらくちゃんと回転してくれるとは思いますが、もし動作がおかしいなどありましたらお知らせください。