通常 Unity 内では Physics.gravity を使用して重力の向きと強さを設定できます。普通のゲームであればこれ一つで事足りると思いますが重力の発生源を二つ以上にしたい場合や、小惑星など特殊な環境を舞台にしたゲームを作る場合に不便です。
というわけで簡単にそれっぽいものを作って見ました。
Test GravityPhysics.gravity の代わりに AddForce を使用して重力を再現しています。Cube が惑星より遠ければスイングバイで加速してどこかへ飛んでいきますが近いと惑星に衝突します。
引力の強さを求める式は Wikipedia 読んでもなんだかよくわかりませんが、F:引力の大きさ, G:万有引力定数, M,m:物体の質量, r:距離 とすると以下の式になるようです。
F = GMm / r^2
今回は試しにやるので質量とかは適当な値(A)を入れて、単純に距離の二乗の反比例としています。つまりこう。
F = A / r^2
で、これを使ってスクリプトを書く。
public class Cube : MonoBehaviour {
private float gravity = 8000;
public GameObject target1;
private Vector3 pos1;
private float distance1;
private Vector3 t1Angle;
void Start () {
target1 = GameObject.Find("Sphere1");
pos1 = target1.transform.position;
}
void Update () {
distance1 = Vector3.Distance(pos1, transform.position);
t1Angle = target1.transform.position - transform.position;
rigidbody.AddForce(t1Angle.normalized * (gravity / Mathf.Pow(distance1, 2)));
}
}
さきほどのサンプルでランダムで出力している Cube に適応しているスクリプトの一部です。惑星 Sphere1 の位置を取得し、Cube の位置と Sphere1 の位置から AddForce するべき方向を決めています。
さらに、Sphere1 と Cube の距離を計測した結果を先ほどの引力を求める式に当てはめます。
サンプルでは2つ惑星をかなり近い距離においているのでだいぶ変な動きになりますが、一つだけなら運が良ければ衛星みたいに長時間周回し続けるような Cube も出てきます。
しかし思いついて作ってみたは良いが何に使えるかな。。