如何在Unity中更改对某些对象的重力?


14

我在Unity中有两个领域。一个是大小的1000倍,另一个是大小的1倍。因此,我希望将较小的球体吸引到较大的球体中。那么我该怎么做。我知道它可以通过使用刚体在重力作用下下降。但是,如何改变朝向大球面的重力角?

Answers:


19

Unity物理引擎中的重力仅沿一个方向运行,并在“编辑”->“项目设置”菜单中的“物理”菜单中进行控制。

在此处输入图片说明

如果您想做其他事情,则必须实现自己的重力。

基本上,您可以在要成为重心的对象上添加一个球体碰撞器。对撞机应涵盖您希望物体受其重力影响的整个区域。每当物体与该“影响范围”碰撞时,您都对其施加力。只要它在势力范围内,您就继续对其施加力。

您可以调整您使用的重力常数,但是在现实世界中用于计算的标准常数是:

F = Gm1m2 / r2

阐明是:

力= 重力常数 *对象1的质量*对象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”注释的功能都无法按我的意愿运行。但就目前而言,它允许我的“ block ALPHA”对象以一种相当可预测的方式在3d中与其他“ block ALPHA”对象进行重力交互。(尽管,当放置两个或更多块时,最后一个始终是“吸引子”,并且将保持静止直到发生碰撞。我正在努力……将不胜感激:))希望能有所帮助。


1
如果您想提一个问题,请将其发布为一个问题,不要将其掩埋在答案中。

我的不好,谢谢您的照顾,不会再发生:)
Vinny Real Hard Ink Vince Vince

0

让这个行星/大球与一个对撞机相撞,给它一个孩子。现在,应该将行星标记为行星或静态宇宙物体,并将孩子标记为影响区域。现在,小物体应该具有刚体和带有isTrigger的球体。

在进入/进入停留触发器上将脚本放到地球上,如果它是影响范围,则应将其拉向该范围。

否则,您可以采用其他方法。但无论如何,这可能会更好,因为您最有可能希望使各个星球的引力不同。


-2

其他人说的,统一的重力仅朝某个方向,因此也许您应该完全禁用重力,并编写一种使小球向大球运动的力。


-2

如果要更改特定平面的重力,可以使用此脚本附加到平面。

using UnityEngine;

public class ChangeGavityToThisObject : MonoBehaviour
{

    private Quaternion rot;
    private Vector3 gravityValue;

    void Start()
    { 
        gravityValue = Physics.gravity;      
    }

    void Update()
    {
        rot = GetComponent<Transform>().rotation;
        Physics.gravity = rot * gravityValue;
    }
}

GetComponent正在更新中,因为我想在游戏中更改此平面的旋转可能性。


1
这改变了全球重力的方向。不只是针对一个对象。
菲利普
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.