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?
Grawitacja w silniku fizyki Unity idzie tylko w jednym kierunku i jest kontrolowana w menu Fizyka w menu Edycja-> Ustawienia projektu.
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.
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.
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;publicclassPlanetGrav:MonoBehaviour{//Declare Variables://Strength of attraction from your sphere (obviously, it can be any type of game-object)publicfloatStrengthOfAttraction;//Obviously, you won't be using planets, so change this variable to whatever you wantGameObject planet;//Initialise code:voidStart(){//Again, you can change the tag to whatever you want.
planet =GameObject.FindGameObjectWithTag("Planet");}//Use FixedUpdate because we are controlling the orbit with physicsvoidFixedUpdate(){//Declare Variables://magsqr will be the offset squared between the object and the planetfloat magsqr;//offset is the distance to the planetVector3 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 0if(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.
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;publicclassDynamicWeightAnalysis:MonoBehaviour{//Declare Variables://BBB adding volume calculations//NOPE//BBB adding density (...does nothing yet...)publicfloat 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)publicfloatRelativeWeight;//BBB Here, we name our target object (s)GameObject blockALPHA;//Initialise code:voidStart(){//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 physicsvoidFixedUpdate(){//Declare Variables://magsqr will be the offset squared between the object and the planetfloat magsqr;//offset is the distance to the planetVector3 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" variableGetComponent<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 ..
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.
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.
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.
źródło
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.
źródło
Jeśli chcesz zmienić grawitację dla konkretnej płaszczyzny, możesz użyć tego skryptu dołączonego do płaszczyzny.
GetComponent jest w aktualizacji, ponieważ chcę umożliwić zmianę obrotu tej płaszczyzny w grze.
źródło