Edited at

惑星から万有引力を受ける物体をUnity上で実装

More than 1 year has passed since last update.


Unityで万有引力って?

1週間ゲームジャムというものに参加しようと思ったのでゲームを作ろうとしたのですがかなり大きな壁にぶつかりました

ちなみに作ろうとおもったゲームは宇宙空間で引力で引っ張られる状態のロケット:rocket:を制御するゲームです

まあワケワカランとは思いますが、リンクを張りましたのでぜひプレイしてみてください

で、このゲームにおいて重要なものがあります

それは

万有引力!

ですね

じつはすでに重力であればGravityという項目がUnityにはありますので、実装は不要です

しかし、Gravityは以下に示す左の絵の矢印のような感じになります。私がほしいのは右の絵のような感じです。

これを実装するにはどうしたら良いでしょうね(・・;)

想像もできませんが、やるしかねぇ!:hugging:

今回のゲームでは、複数の惑星からロケット一つが力を受ける形を考えています

つまり惑星同士が引き合うものではありません

(ちなみにこの記事を書きながらいろいろやった後に気づいたのですが、すでに万有引力に関しては書かれている方がいらっしゃいました:sweat:

以下のリンクがその記事です.私の記事より短くてわかりやすっ!

[Unity] 惑星に向かって物体が落ちるようにする)


いざ実践!

万有引力を作るためにはその式が必要ですよね(^o^)

万有引力の式は以下で与えられます

image.png

これをC#のスクリプトで書いていきます

書いたコードはこちらです


Universal_gravity.cs

public class UniversalGravitation : MonoBehaviour {

public static float G = 6.67259f; //万有引力定数の定義
Rigidbody rocket_body;
public GameObject rocket; //Unity上でロケットにあたるものをドラッグ&ドロップ
Rigidbody planet_body;
// Use this for initialization
void Start () {
rocket_body = rocket.GetComponent<Rigidbody>(); //
planet_body = this.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update () {
Vector3 vec_direction = this.transform.position - rocket.transform.position; //ロケットから見た惑星の位置
Vector3 Univ_gravity = G * vec_direction.normalized * (planet_body.mass * rocket_body.mass) / (vec_direction.sqrMagnitude); //万有引力の計算
rocket_body.AddForce(Univ_gravity); //ロケットに万有引力を掛ける
}
}

万有引力の法則の式があるので、あとは惑星から見たロケットの位置をベクトルで表すことができれば、そのベクトルの単位ベクトルと大きさが分かれば案外簡単ですね.

今にして思えば、これは惑星の方にアタッチしたスクリプトですが、もしかしてロケット側に入れたほうが簡単だった?(;´∀`)

導入したものが以下の動画です

IMAGE ALT TEXT HERE

(画像クリックで再生します)

ちなみに上記のrocketにしっかりロケットのオブジェクトを関連付けすれば以下の動画のように複数の大きさ、質量の違う惑星の間も動くようになります(^q^)

IMAGE ALT TEXT HERE

(画像クリックで再生します)

一応今回の目的は達成ですかね

しかしこの方法は

「惑星が増えたら毎回ロケットの設定がめんどい」

「ロケットが増えたら更にめんどい」などの問題がありますね(´・ω・`)

素直にこちらのようにロケットに万有引力のスクリプトをアタッチするほうが簡単そうですねぇ・・・

でも万有引力はロケットにかかってるけど、惑星の質量が生み出す力だから惑星にアタッチするのが自然だと思ったんですぐすん(´;ω;`)

というわけで、幾つかの方法があるとは思いますが私のやりかたはこんなかんじでした

およみくださってありがとうございます!