Jak zmienić grawitację w kierunku określonego obiektu w Jedności?


14

Mam dwie sfery w Jedności. Jeden ma rozmiar 1000x inny ma rozmiar 1x. Chcę więc, aby mniejsza sfera była przyciągana do większej sfery. Jak mam to zrobić? Wiem, że może spływać grawitacyjnie za pomocą sztywnego ciała. Ale jak zmienić kąt grawitacji w kierunku dużej kuli?

Odpowiedzi:


19

Grawitacja w silniku fizyki Unity idzie tylko w jednym kierunku i jest kontrolowana w menu Fizyka w menu Edycja-> Ustawienia projektu.

wprowadź opis zdjęcia tutaj

Jeśli chcesz zrobić coś innego, musisz wdrożyć własną grawitację.

Zasadniczo możesz dodać zderzak kuli do obiektu, który ma być środkiem ciężkości. Zderzak powinien obejmować cały obszar, w którym grawitacja tego obiektu ma mieć wpływ na obiekty. Ilekroć obiekt zderza się z tą „strefą wpływów”, przykładasz do niego siłę. Nadal przykładasz do niego siłę, o ile znajduje się ona w strefie wpływów.

Używana przez ciebie stała grawitacyjna może zostać przez ciebie poprawiona, ale standardowa używana do obliczeń w realnym świecie to:

F = Gm1m2 / r2

Określono, że:

Siła = stała grawitacyjna * masa obiektu 1 * masa obiektu 2 / odległość między dwoma obiektami podniesiona do kwadratu.

Zwróć uwagę, że stała grawitacyjna nie wynosi 9,81. Takie jest przyspieszenie wywołane grawitacją na powierzchni ziemi.


1

Nie ma potrzeby odwoływania się do równania grawitacyjnego. Przyspieszenie ziemskie jest stałe bez względu na masę, więc wszystko, co chcesz zrobić, to przyspieszać małe obiekty w kierunku dużych obiektów w każdej klatce.

Kod wyglądałby mniej więcej tak:

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

1

W rzeczywistości pracuję obecnie nad grą opartą na grawitacji: po prostu umieszczasz gwiazdy, aby poruszać swoim graczem przez eliptyczne orbity i efekt procy. Wyłączyłem grawitację i użyłem tego kodu:

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 Kod pierwotnie zapętlony przez tablicę wszystkich planet: jest edytowany i dlatego może nie być w pełni poprawny. Jednak powinno być dobrze.


0

Pracowałem nad podobnym projektem opartym na Zero-G, w którym potrzebuję wszystkich obiektów gry do generowania i reagowania zarówno na siłę grawitacyjną, jak i elektromagnetyczną w oparciu o ich objętość, gęstość, masę, energię i przewodność. Jestem stosunkowo nowy w skryptowaniu, ale wprowadziłem kilka modyfikacji powyższego skryptu, aby działał dla mnie w przestrzeni 3D (jeśli chodzi o grawitację ... prawie ...):

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);
    }
}
}

Jak widać, wciąż nad tym pracuję, w zasadzie wszystkie moje dotychczasowe dodatki, opatrzone adnotacją „BBB”, nie działają jeszcze tak, jak bym chciał. Ale na obecnym etapie pozwala moim „blokowym ALPHA” oddziaływać grawitacyjnie w 3d z innymi obiektami „blokowymi ALPHA” w dość przewidywalny sposób. (chociaż, przy umieszczaniu dwóch lub więcej bloków, ostatni jest zawsze „atraktorem” i pozostanie nieruchomy aż do wystąpienia kolizji. nad którym pracuję ... pomoc byłaby mile widziana :)) Mam nadzieję, że to pomaga ..


1
Jeśli chcesz zadać pytanie, opublikuj je jako pytanie, nie chowaj go w swojej odpowiedzi.

moje złe, dzięki za opiekę, to się więcej nie powtórzy :)
Vinny Real Hard Ink Vince

0

Miej planetę / dużą kulę ze zderzaczem kół, daj mu dziecko. Teraz planeta powinna być oznaczona jako planeta lub statyczny obiekt kosmiczny, a dziecko powinno zostać oznaczone jako Obszar wpływu. Teraz mały obiekt powinien mieć sztywne ciało i kulę z isTrigger.

Umieść skrypt na planecie za pomocą wyzwalacza „enter / enterstay”, jeśli jest to sfera wpływów, należy go do tego przyciągnąć.

W przeciwnym razie możesz to zrobić na odwrót. Ale w każdym razie byłoby to prawdopodobnie lepsze, ponieważ najprawdopodobniej chcesz, aby przyciąganie grawitacyjne różniło się w zależności od planety.


-2

Co powiedzieli inni, grawitacja na jedności jest tylko w określonym kierunku, więc może zamiast tego powinieneś całkowicie wyłączyć grawitację i napisać siłę, która porusza małą kulę w kierunku ogromnej.


-3

Jeśli chcesz zmienić grawitację dla konkretnej płaszczyzny, możesz użyć tego skryptu dołączonego do płaszczyzny.

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 jest w aktualizacji, ponieważ chcę umożliwić zmianę obrotu tej płaszczyzny w grze.


1
Zmienia to kierunek globalnej grawitacji. Nie tylko dla jednego obiektu.
Philipp
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.