Staram się stworzyć efekt podobny do efektu Mario Galaxy lub Geometry Wars 3, w którym podczas spaceru po planecie grawitacja wydaje się dostosowywać i nie spada ona z krawędzi obiektu, tak jak gdyby grawitacja został naprawiony w jednym kierunku.
(źródło: gameskinny.com )
Udało mi się wdrożyć coś zbliżonego do tego, czego szukam, stosując podejście, w którym obiekt, który powinien mieć grawitację, przyciąga do siebie inne sztywne ciała, ale używając wbudowanego silnika fizyki dla Unity, stosując ruch z AddForce i podobne, Po prostu nie mogłem sprawić, by ruch był odpowiedni. Nie mogłem zmusić gracza do poruszania się wystarczająco szybko, gdyby gracz nie zaczął odlatywać z powierzchni obiektu i nie mogłem znaleźć odpowiedniej równowagi przyłożonej siły i grawitacji, aby to uwzględnić. Moje obecne wdrożenie jest adaptacją tego, co zostało znalezione tu
Wydaje mi się, że rozwiązanie prawdopodobnie nadal wykorzystywałoby fizykę, aby uziemić gracza na obiekcie, gdyby miał opuścić powierzchnię, ale gdy gracz zostanie uziemiony, istnieje sposób, aby zrzucić gracza na powierzchnię i wyłączyć fizykę i kontrolować gracza za pomocą innych środków, ale tak naprawdę nie jestem pewien.
Jakie podejście należy zastosować, aby przyciągnąć gracza do powierzchni przedmiotów? Pamiętaj, że rozwiązanie powinno działać w przestrzeni 3D (w przeciwieństwie do 2D) i powinno być możliwe do wdrożenia przy użyciu darmowej wersji Unity.
Odpowiedzi:
Udało mi się osiągnąć to, czego potrzebowałem, przede wszystkim przy pomocy tego wpisu na blogu dotyczącego łamigłówki na powierzchni i wymyśliłem własne pomysły na ruch gracza i kamerę.
Przyciąganie odtwarzacza do powierzchni obiektu
Podstawowa konfiguracja składa się z dużej kuli (świata) i mniejszej kuli (gracza), oba z dołączonymi zderzakami kul.
Większość wykonywanych prac polegała na dwóch następujących metodach:
The
Vector3 movementDirection
Parametr jest tak jak się wydaje, w kierunku będziemy zmierzać nasz zawodnik w tej ramce, a wyliczenia tego wektora, a skończyło się stosunkowo prosta w tym przykładzie był nieco trudne dla mnie, aby dowiedzieć się, w pierwszej kolejności. Więcej na ten temat później, ale pamiętaj, że jest to znormalizowany wektor w kierunku, w którym gracz przesuwa tę ramkę.Przechodząc, najpierw sprawdzamy, czy promień pochodzący z hipotetycznej przyszłej pozycji skierowanej w stronę wektora w dół graczy (-transform.up) uderza w świat za pomocą WorldLayerMask, która jest publiczną właściwością LayerMask skryptu. Jeśli chcesz bardziej złożonych kolizji lub wielu warstw, będziesz musiał zbudować własną maskę warstwy. Jeśli raycast z powodzeniem trafi w coś, hitInfo służy do odzyskania normalnego i hit point, aby obliczyć nową pozycję i obrót gracza, który powinien znajdować się bezpośrednio na obiekcie. Przesunięcie pozycji gracza może być wymagane w zależności od wielkości i pochodzenia danego obiektu gracza.
Wreszcie, tak naprawdę zostało to przetestowane i prawdopodobnie działa dobrze tylko na prostych obiektach, takich jak kule. Ponieważ post na blogu, na którym oparłem swoje rozwiązanie, sugeruje, prawdopodobnie będziesz chciał wykonać wiele raycastów i uśrednić je dla swojej pozycji i rotacji, aby uzyskać znacznie lepsze przejście podczas poruszania się w bardziej złożonym terenie. Mogą być też inne pułapki, o których w tym momencie nie myślałem.
Kamera i ruch
Gdy gracz przyklejał się do powierzchni obiektu, kolejnym zadaniem do wykonania był ruch. Początkowo zaczynałem od ruchu względem gracza, ale zacząłem napotykać problemy na biegunach kuli, w których nagle zmieniły się kierunki, powodując, że mój gracz szybko zmieniał kierunek w kółko, nie pozwalając mi nigdy przekroczyć biegunów. Skończyło się na tym, że moi gracze poruszali się względem kamery.
To, co zadziałało dobrze dla moich potrzeb, to mieć kamerę, która ściśle śledziłaby gracza w oparciu wyłącznie o pozycję gracza. W rezultacie, mimo że kamera technicznie się obraca, naciśnięcie w górę zawsze przesuwało odtwarzacz w kierunku góry ekranu, w dół w dół i tak dalej z lewej i prawej strony.
Aby to zrobić, w kamerze, w której obiektem docelowym był gracz, wykonano:
Wreszcie, aby przesunąć gracza, wykorzystaliśmy transformację kamery głównej, aby za pomocą naszych kontrolek ruchy w górę, ruchy w dół itp. I tu właśnie wywołujemy UpdatePlayerTransform, który unieruchamia naszą pozycję do obiektu świata.
Aby zaimplementować bardziej interesującą kamerę, ale elementy sterujące będą w przybliżeniu takie same, jak tutaj, możesz łatwo zaimplementować kamerę, która nie jest renderowana, lub po prostu inny atrapa obiektu, aby wyłączyć ruch, a następnie użyć bardziej interesującej kamery do renderowania tego, co chcesz, żeby gra wyglądała. Umożliwi to ładne przejścia z kamery podczas poruszania się po obiektach bez zrywania elementów sterujących.
źródło
Myślę, że ten pomysł zadziała:
Zachowaj kopię siatki planety po stronie procesora. Posiadanie wierzchołków siatki oznacza również, że masz normalne wektory dla każdego punktu na planecie. Następnie całkowicie wyłącz grawitację dla wszystkich bytów, zamiast tego przykładając siłę dokładnie w przeciwnym kierunku niż normalny wektor.
Teraz, w oparciu o który punkt należy obliczyć ten normalny wektor planety?
Najłatwiejszą odpowiedzią (która, jestem pewien, że zadziała dobrze), jest zbliżenie w przybliżeniu do metody Newtona : kiedy obiekty pojawiają się po raz pierwszy, znasz wszystkie ich początkowe pozycje na planecie. Użyj tej pozycji początkowej, aby określić
up
wektor każdego obiektu . Oczywiście grawitacja będzie w przeciwnym kierunku (w kierunkudown
). W następnej klatce, przed zastosowaniem grawitacji, rzuć promień z nowej pozycji obiektu w kierunku jego staregodown
wektora. Użyj przecięcia tego promienia z planetą jako nowego odniesienia do określeniaup
wektora. Rzadki przypadek, gdy promień nie uderza w nic, oznacza, że coś poszło strasznie nie tak i powinieneś przenieść swój obiekt z powrotem do miejsca, w którym był w poprzedniej klatce.Należy również pamiętać, że przy użyciu tej metody im dalsze pochodzenie gracza pochodzi z planety, tym gorsze staje się przybliżenie. Dlatego lepiej jest użyć gdzieś wokół stóp każdego gracza jako źródła. Zgaduję, ale myślę, że użycie stóp jako źródła również spowoduje łatwiejszą obsługę i nawigację gracza.
Ostatnia uwaga: Aby uzyskać lepsze wyniki, możesz nawet wykonać następujące czynności: śledzić ruch gracza w każdej klatce (np. Używając
current_position - last_position
). Następnie zaciśnij tomovement_vector
, aby jego długość w kierunku obiektuup
wynosiła zero. Nazwijmy ten nowy wektorreference_movement
. Przenieś poprzednireference_point
oreference_movement
i użyj tego nowego punktu jako początku śledzenia promieni. Po tym, jak promień uderzy w planetę, przejdźreference_point
do tego punktu wytrzymałości. Na koniec obliczyć nowyup
wektor na podstawie tego nowegoreference_point
.Niektóre pseudo-kod podsumowujący:
źródło
Ten post może być pomocny. Jego istotą jest to, że nie używasz kontrolerów postaci, ale stwórz własny, używając silnika fizyki. Następnie użyj normalnych wykrytych pod odtwarzaczem, aby ustawić je na powierzchni siatki.
Oto ładny przegląd techniki. Istnieje wiele innych zasobów z wyszukiwanymi hasłami, takimi jak „jedność po obiektach mario galaxy”.
Jest też projekt demonstracyjny z Unity 3.x, który miał chodzący silnik, z żołnierzem i psem oraz w jednej ze scen. Pokazał chodzenie po obiektach 3D w stylu Galaxy . Nazywa się to systemem ruchu przez runevision.
źródło
Obrót
Sprawdź odpowiedź na to pytanie na stronie answer.unity3d.com (faktycznie zadane przeze mnie). Zacytować:
Oto kod, który mi zasugerował:
Nazwij to każdą aktualizacją, a powinieneś ją uruchomić. (zauważ, że kod jest w języku UnityScript ).
Ten sam kod w C # :
Powaga
Do grawitacji możesz użyć mojej „techniki fizyki planet”, którą opisałem w moim pytaniu, ale tak naprawdę nie jest zoptymalizowana. To było coś, co przyszło mi do głowy.
Sugeruję stworzenie własnego systemu grawitacji.
Oto samouczek YouTube'a autorstwa Sebastiana Lague'a . To bardzo dobrze działające rozwiązanie.
EDYCJA: W jedności, przejdź do Edycja > Ustawienia projektu > Fizyka i ustaw wszystkie wartości Grawitacji na 0 (lub usuń Sztywne ciało ze wszystkich obiektów), aby zapobiec wbudowanej grawitacji (która po prostu pociąga gracza w dół) do konfliktu z niestandardowe rozwiązanie. (Wyłącz to)
źródło