Unityで特定のオブジェクトに向かって重力を変更する方法は?


14

Unityには2つの球体があります。1つはサイズが1000倍、もう1つはサイズが1倍です。だから私は、より小さな球体をより大きな球体に引き付けたいと思っています。それではどうすればいいですか。リジッドボディを使用すると、重力によってダウンする可能性があることを知っています。しかし、重力の角度を大きな球体に向けて変更するにはどうすればよいですか?

回答:


19

Unity物理エンジンの重力は一方向にのみ移動し、[編集]-> [プロジェクト設定]メニューの[物理]メニューで制御されます。

ここに画像の説明を入力してください

それ以外のことをしたい場合は、独自の重力を実装する必要があります。

基本的に、重心にしたいオブジェクトに球体コライダーを追加できます。コライダーは、オブジェクトがそのオブジェクトの重力の影響を受ける領域全体を囲む必要があります。オブジェクトがこの「影響範囲」と衝突するたびに、力を適用します。影響範囲内にある限り、力を加え続けます。

使用する重力定数は微調整できますが、実際の世界での計算に使用される標準的な定数は次のとおりです。

F = Gm1m2 / r2

綴りは次のとおりです。

力= 重力定数 *オブジェクト1の質量*オブジェクト2の質量/ 2つのオブジェクト間の距離の2乗。

重力定数は9.81ではないことに注意してください。それは地球の表面の重力によって引き起こされる加速です。


1

重力方程式に頼る必要はありません。重力による加速度は質量に関係なく一定です。したがって、あなたがしたいことは、小さなオブジェクトを各フレームの大きなオブジェクトに向かって加速することだけです。

コードは次のようになります。

public void FixedUpdate()
{
    rigidbody.velocity += gravitationalAcceleration * Time.fixedTime * (largeObject.transform.position - transform.position);
}

1

実際、私は現在重力に基づいたゲームに取り組んでいます。単純に、星を配置して楕円軌道とパチンコ効果でプレーヤーを動かします。重力を無効にして、次のコードを使用しました。

using UnityEngine;
using System.Collections;

public class PlanetGrav : MonoBehaviour {

    //Declare Variables:

//Strength of attraction from your sphere (obviously, it can be any type of game-object)
    public float StrengthOfAttraction;

//Obviously, you won't be using planets, so change this variable to whatever you want
    GameObject planet;

    //Initialise code:
    void Start () 
    {
        //Again, you can change the tag to whatever you want.
        planet = GameObject.FindGameObjectWithTag("Planet");
    }

    //Use FixedUpdate because we are controlling the orbit with physics
    void FixedUpdate () {
        //Declare Variables:

    //magsqr will be the offset squared between the object and the planet
        float magsqr;

        //offset is the distance to the planet
        Vector3 offset;

        //get offset between each planet and the player
        offset = planet.transform.position - transform.position;

            //My game is 2D, so  I set the offset on the Z axis to 0
            offset.z = 0;

            //Offset Squared:
            magsqr = offset.sqrMagnitude;

            //Check distance is more than 0 to prevent division by 0
            if (magsqr > 0.0001f)
            {
//Create the gravity- make it realistic through division by the "magsqr" variable

rigidbody2D.AddForce((StrengthOfAttraction * offset.normalized / magsqr) * rigidbody2D.mass);
            }
        }
    }
}

PS元々はすべての惑星の配列をループしていたコード:これは編集されているため、完全に正しいとは限りません。でも大丈夫なはずです。


0

私はZero-Gに基づいた同様のプロジェクトに取り組んでおり、すべてのゲームオブジェクトが、体積、密度、質量、エネルギー、伝導率に基づいて重力と電磁力の両方を生成し、それらに反応する必要があります。私はスクリプト作成は比較的初心者ですが、上記のスクリプトにいくつかの変更を加えて、3D空間で動作するようにしました(重力に関する限り...ほとんど...):

using UnityEngine;
using System.Collections;

public class DynamicWeightAnalysis : MonoBehaviour {

//Declare Variables:
//BBB adding volume calculations
//NOPE
//BBB adding density (...does nothing yet...)
public float density;

//BBB NOPE!

//Strength of attraction from your game-object, ideally this will be derived from a calculation involving the objects volume and density, but for now it's entered from the inspector)
public float RelativeWeight;

//BBB Here, we name our target object (s)
GameObject blockALPHA;

//Initialise code:
void Start () 
{
    //BBB here, we define our target object by searching for its tag (setup in editor)
    blockALPHA = GameObject.FindGameObjectWithTag("Block ALPHA");
}

//Use FixedUpdate because we are controlling the orbit with physics
void FixedUpdate () {
    //Declare Variables:

    //magsqr will be the offset squared between the object and the planet
    float magsqr;

    //offset is the distance to the planet
    Vector3 offset;

    //get offset between each planet and the player
    offset = blockALPHA.transform.position - transform.position;

    //Offset Squared:
    magsqr = offset.sqrMagnitude;

    //Check distance is more than 1 to prevent division by 0 (because my blocks are all 1x1x1 so, any closer than 1 and they'd be intersecting)
    if (magsqr > 1f)
    {
        //Create the gravity- make it realistic through division by the "magsqr" variable

        GetComponent<Rigidbody>().AddForce((RelativeWeight * offset.normalized / magsqr) * GetComponent<Rigidbody>().mass);
    }
}
}

ご覧のとおり、私はまだ作業中です。基本的に、これまでに追加された「BBB」という注釈が付いたものは、まだ希望どおりに機能していません。しかし、現状では、私の「ブロックアルファ」オブジェクトは、かなり予測可能な方法で3Dで他の「ブロックアルファ」オブジェクトと重力的に相互作用することができます。(ただし、2つ以上のブロックを配置する場合、最後のブロックは常に「アトラクタ」であり、衝突が発生するまで静止したままになります。作業中です...感謝します:))


1
質問したい場合は、質問として投稿してください。回答に埋めないでください。

私の悪い、それを大事にしてくれてありがとう、二度と起こらないだろう:)
ヴィニーリアルハードインクヴィンス

0

惑星/大きな球体をサークルコライダーで持ち、子供を与えます。ここで、惑星には惑星または静的な宇宙オブジェクトのタグを付け、子には影響範囲のラベルを付ける必要があります。これで、小さなオブジェクトには、剛体とisTriggerのある球が必要になります。

エンター/エンターステイトリガーを使用して、惑星にスクリプトを配置します。それが影響範囲である場合は、それに向かって引っ張る必要があります。

それ以外の場合は、他の方法で行うことができます。しかし、いずれにせよ、重力の引力を惑星ごとに異なるようにしたいので、これはおそらくより良いでしょう。


-2

他の人が言ったように、団結の重力は特定の方向に向かっているだけなので、代わりに重力を完全に無効にし、小さな球体を巨大な球体に向かって動かす力をスクリプト化する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.