Unityで万有引力

Unityでは、rigidbodyコンポーネントをオブジェクトにつけることで物理演算を適用させられる。rigidbodyコンポーネントにはgravityというチェックボックスがあり、チェックするとその物体は重力で下に落ちるようになる。しかし、画面中央に表示した星に物が落ちていく状況など、重力が下方向に働いてほしくない場面もある。この記事では簡単に万有引力を実装するコンポーネントのC#コード例を載せる。

参考にしたもの

コード例

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gravity : MonoBehaviour {
    //万有引力
    public static float G = 6.67259f * Mathf.Pow(10,-11); //万有引力定数6.67259×10^-11
    //public GameObject satellite = null;の行は、このスクリプトが衛星にアペンドされるものであり、thisで参照できるため必要ない
    Rigidbody satelliteRig = null;//惑星を回る人工衛星のゲームオブジェクトを初期化
    public GameObject earth = null; //重力源のゲームオブジェクトを初期化
    Rigidbody earthRig = null; //重力源のゲームオブジェクトのRigidboodyコンポーネントを初期化

    //初速
    public Vector3 v0 = new Vector3(0, 0, 0);//空のベクトルを作成

    //最初に一回だけ実行されるスクリプト
    void Start () {
        //万有引力
        satelliteRig = this.GetComponent<Rigidbody>();//アペンドされたオブジェクトからRigidbodyコンポーネントを呼び出してくる
        earthRig = earth.GetComponent<Rigidbody>();//重力源からRigidbodyコンポーネントを呼び出してくる

        //初速
        satelliteRig.AddForce(v0, ForceMode.VelocityChange);//衛星に初速を与える
    }

    //フレーム毎に実行されるスクリプト
    void Update () {
        Vector3 vec_direction = earth.transform.position - this.transform.position; //衛星から見た地球の方向ベクトルを計算
        Vector3 Univ_gravity = G * vec_direction.normalized * (earthRig.mass * satelliteRig.mass) / (vec_direction.sqrMagnitude); //万有引力を計算
        satelliteRig.AddForce(Univ_gravity); //衛星に万有引力をかける
    }
}

使い方

キーボード操作可能にする

using UnityEngine;

public class PlayerScript : MonoBehaviour
{
    Vector3 velocity; // オブジェクトの速度

    float speed = 0.01f;

    void Update()
    {
        // キー入力に基づいて速度ベクトルを変更
        if (Input.GetKey(KeyCode.W))
        {
            velocity += transform.up * speed * Time.deltaTime;
        }

        if (Input.GetKey(KeyCode.S))
        {
            velocity -= transform.up * speed * Time.deltaTime;
        }

        if (Input.GetKey(KeyCode.D))
        {
            velocity += transform.right * speed * Time.deltaTime;
        }

        if (Input.GetKey(KeyCode.A))
        {
            velocity -= transform.right * speed * Time.deltaTime;
        }

        // 速度ベクトルを使って位置を更新
        transform.position += velocity;
    }
}

使い方

軌跡を表示する

軌跡を表示させたいオブジェクトを選択し、inspector viewのadd componentからtrail rendererを追加する


完成図

追記

UpdateじゃなくてFixedUpdateを使うとゲーム内時間で更新されるためラグっても軌道が乱れない