Rigidbodyをスクリプトで操作したい人
ゲームキャラクターとかをとりあえず動かしたいから、使えるコードが欲しい。
Colliderの設定とか意味分からん、Rigidbodyだけだと何がダメなの?
こういったご要望にお応えします。
本記事の内容
●Rigidbodyサンプルコードの詳細
●UnityでのRigidbodyの役割
この記事を書いている私は12才からフルスクラッチでゲームを作っています。
またコンパイラを専門として情報理工学の博士まで進学、中退をしており、プログラミング言語の文法にも関わる論文を書いていました。
本記事ではサクっと使える実行済みのコードを紹介します。
加えて物理をしっかり意識した理解が出来るよう、応用的な知識にも触れていきたいと思います。
※実行環境:Unity2021.3.1f1
コピペしよう、Rigidbodyでよく使うコード
物体同士が衝突するなどの実装をしたい場合は、必ず両方にCollider系のコンポーネントをアタッチしてください。
片方ない、両方ない場合はすり抜けます。
逆にそういう演出をしたい場合はcolliderをアタッチしないのもアリです。
移動
//力や力積など、物理的な量を加える _rigidbody.AddForce(_vector3, _forceMode); //物体のワールド座標を移動させる、Transformコンポーネントと同様 _rigidbody.MovePosition(_vector3);
パラメータ関連
//速度を取得、変更 _rigidbody.velocity = _vector3; //質量を取得、変更 _rigidbody.mass = _float; //重力や衝突での力を受けなくなる _rigidbody.isKinematic = _bool;
●_vector3
Vector3のインスタンス変数名
●_forceMode
列挙型ForceModeの変数
●_float
質量などに使用するfloat型変数
物理的なリアリティを追求するのであれば、1.0fを1kgと考えて指定することをオススメします
●_bool
bool型変数
インスペクタでは、
●チェックなし:false
と考えましょう
Rigidbodyサンプルコードの詳細
AddForce
AddForceを日本語通りに解釈すると「力を加える」ですが、これは大嘘です。
具体例と物理法則を紹介するので、落ち着いて理解を深めましょう。
解説のため重心に直接作用する力のみでお話を単純化します。
空気抵抗などはムシです。
①ForceMode.Force
力を加える計算をします。
以下の運動方程式のとおりです。
$$ma = mg + f$$
$$a = g + \frac{f}{m}$$
a:加速度、Rigidbodyの変数としては提供されていないようです
f:Vector3の内容
ばねなど、運動方程式に書き加えられるものを厳密に実装する時はこれで良いと思います。
式の通り、重いものほど加速が鈍くなります。
②ForceMode.Acceleration
加速度に直接計算を行います。
以下の運動方程式のように無理やり表すことが出来ます。
$$ma = mg + mf$$
$$a = g + f$$
a:加速度、Rigidbodyの変数としては提供されていないようです
f:Vector3の内容
月に行くなど、重力をリアルタイムで変更する場合に便利です。
式の通り、どのような重さの物でも等しく加速します。
③ForceMode.Impulse
力積を加える計算をします。
以下の運動量計算のとおりです。
$$I = mv’ – mv$$
$$v’ = v + \frac{I}{m}$$
v:AddForce実行前の_rigidbody.velocity
v’:AddForce実行後の_rigidbody.velocity
I:Vector3の内容
ボールの発射などに使えます。
式の通り、重いものほど速度変化が鈍くなります。
④ForceMode.VelocityChange
速度に直接計算を行います。
以下の運動量計算のように無理やり表すことが出来ます。
$$mI = mv’ – mv$$
$$v’ = v + I$$
v:AddForce実行前の_rigidbody.velocity
v’:AddForce実行後の_rigidbody.velocity
I:Vector3の内容
物理現象としてはなかなかフィクションの領域だと思います。
単純にはアクションゲームでのジャンプなど、ジャンプの高さが一定にならないと困るものなどはVelocityChangが利くと思います。
仮にForceMode.Impulseで実装をしてしまうと、体重の重いキャラほどジャンプが低くなるなどの現象が起きてしまうので調整が少しややこしそうです。
ちなみにやっていることは_rigidbody.velocityへの代入とほぼ同じです。
特段理由がない限り_rigidbody.velocityで実装する方が分かりやすいと思います。
UnityでのRigidbodyの役割
物理演算を行うことです。
ただし、Colliderもある意味では物理演算に寄与するのでそこの区別をつけておきましょう。
この辺りは高校物理の範囲を学んでおくと直感的な理解が出来ると思います。
Rigidbodyに対してColliderは何をやっている?
Colliderは物理演算を行う際の座標計算を担当します。
当たり判定などに使われる理由はまさにこれです。
例えばCubeにCapsule Colliderをアタッチすると、見た目は立方体なのに動きはカプセルな物体が出現します。
つまるところColliderは物理演算に必要な力が、
②どちらに向いているか
を計算する役割と考えて差し支えないと思います。
Rigidbodyの関数からさらに理解を深める
Colliderの計算より、Rigidbodyには力のかかる座標と大きさが渡されることになります。
実はこういった発想の関数がRigidbodyに備わっています。
ズバリAddForceAtPositionです。
関数AddForceAtPositionは引数で、力のベクトル、力の位置、ForceModeを指定します。
完全に一致ですね。
この関数を手打ちで利用することも出来るかもしれませんが、それぐらいだったらColliderに任せた方がいいですよね。
手打ちするならそもそもUnityでなくてよいワケで…。
こういった処理をまとめた後に移動と回転の運動方程式を処理するのが、Rigidbodyの立場と考えることが出来ます。
今回はこんな感じです!
Unityはいいぞ。
コメント