Skrypt c jedność metody fizyki 2d. Portal informacji o zabezpieczeniach. Istnieją trzy poziomy kontroli nad ciałem sztywnym

* Unity * to bardzo potężny, progresywny silnik z dużym potencjałem. Posiada wiele wbudowanych funkcji (w tym silnik fizyki * NvidiaPhysX *), których my, użytkownicy, nie będziemy musieli ręcznie rejestrować. :)
W tym krótkim artykule chciałbym omówić fizyczne możliwości silnika. Zacznijmy więc:

Sztywny korpus
=
= Co to jest? =
Funkcja * Rigidbody * ukrywa Absolute Rigid Body (* ATT *). Jeśli wyjaśnimy to z grubsza i jasno, to *ATT* w fizyce i mechanice jest idealnym ciałem sztywnym, które pod wpływem siły nie może zmienić swoich właściwości, ale może (pod jej wpływem) poruszać się w 3 wymiarach (w dół, w górę, do przodu itp.) tj. w naszych osiach XYZ), a także obracać się w 3 wymiarach (ponownie wzdłuż osi XYZ).

W * Unity *, a także w innych silnikach gier (znowu nazywam je z grubsza silnikami "gry"), * Rigidbody * służy do różnych obiektów, z którymi możemy wchodzić w interakcje, pchać, kopać itp. Takie obiekty pod naszym wpływem będą się dalej toczyć, poruszać i zderzać z innymi obiektami pod wpływem grawitacji.

Jakie zastosowanie możemy znaleźć dla tej funkcji? =
Na przykład, aby stworzyć samochód, oprócz * Rigidbody * potrzebujemy Zderzacz na 4 koła"a i * kod * (* skrypt *) przykładający siłę do kół, w zależności od wciskanych klawiszy.

  • * Masa * - Masa naszego obiektu w kilogramach... Zaleca się nie ustawiać wartości mas 100 razy większych lub mniejszych niż masy innych *ATT*.
  • * Drag* - Jak bardzo ciało podlega oporowi powietrza, gdy porusza się pod wpływem sił. Przy wartości * 0 * nie ma oporu, a nieskończona wartość natychmiast zatrzyma nasz obiekt.
  • Opór kątowy- Na ile ciało podlega oporowi powietrza, gdy obraca się pod wpływem sił. Przy wartości * 0 * nie ma oporu, a nieskończona wartość natychmiast zatrzyma obrót naszego obiektu.
  • Użyj grawitacji- Po włączeniu na obiekt oddziałuje grawitacja.
  • jest kinematyczny- Po włączeniu obiekt nie ma wpływu na silnik fizyki i można go zmienić tylko za pomocą funkcji * Transform *. Może to być przydatne na przykład przy tworzeniu ruchomych platform.
  • * Interpolacja * - Jest używana tylko wtedy, gdy ruchy twojego ATT wydają ci się dziwne lub niezręczne, itp.:
  1. Nic: Interpolacja nie jest stosowana
  2. Interpolować: W porównaniu z przekształceniem poprzedniej klatki (*klatka*), następna zostanie wygładzona.
  3. Ekstrapolować: Transformacja bieżącej klatki jest wygładzana w porównaniu z szacowaną (przybliżoną) transformacją następnej.
  • Zamrożenie rotacji- Zabrania jakiejkolwiek rotacji, zarówno skryptowej, jak i kolizyjnej. Jednak rotację można wykonać za pomocą funkcji // przekształć.Obróć ()
  • Wykrywanie kolizji- Służy do zapobiegania przechodzeniu szybko poruszających się obiektów przez inne obiekty bez znajdowania Kolizja„s” (specjalna „siatka” na obiektach, z którymi zderzają się ze sobą iz graczem).
  1. Oddzielny: Domyślnie nasz obiekt „zauważa” wszystkie inne obiekty, z którymi może się zderzyć.
  2. Ciągły: Posługiwać się Dyskretna kolizja z dynamicznymi obiektami kolizyjnymi (które mają * ATT *) i Ciągła kolizja dla statycznej Zderzacz siatki"s (bez * ATT *). Tryb Ciągła dynamika używa Ciągła kolizja dla jednego konkretnego * ATT *. Reszta * ATTs * użyje trybu _Discrete_. (To znacznie wpłynie na obciążenie silnika fizyki, po prostu pozostaw _Discrete_, jeśli nie ma problemów ze zderzeniami szybkich obiektów)
  3. Ciągła dynamika: Używane dla obiektów w trybie _Ciągły_ lub Ciągła dynamiczna kolizja. Ciągła kolizja będzie również używany do statycznego Zderzacz siatki"s (bez * ATT *). W przypadku wszystkich innych używany jest tryb _Discrete_. Używany do szybko poruszających się obiektów.

Jak możemy wykorzystać tę funkcję? =
= Podstawowa wiedza.
Aby użyć * ATT *, potrzebujemy już utworzonego obiektu gry (* GameObject *), klikając go, przechodzimy do menu zgodnie z następującą ścieżką: Komponenty - Fizyka - Rigidbody ... Wszystko, * ATT * dodane! :)
Obiekt podlega teraz grawitacji, można do niego przyłożyć siły za pomocą skryptów, ale aby obiekt zachowywał się dokładnie tak, jak chcesz, musisz dodać * Collider * lub * Joint *.

Kod rządzi światem.
W skrypcie będziemy teraz manipulować naszym obiektem za pomocą funkcji Dodaj Siłę () oraz Dodaj moment obrotowy () .
Ponieważ używam * JavaScript * w * Unity *, moje przykłady będą z nim, linki do innych przykładów skryptów (on C # lub * Boo *) znajdziesz poniżej, w akapicie Dodatkowe informacje na temat ATT.

Rigidbody.AddForce

// Rigidbody.AddForce wykorzystuje 2 rodzaje formuł, a także wiele innych funkcji związanych z ruchem w przestrzeni. // 1 typ: funkcja AddForce (siła: Vector3, tryb: ForceMode = ForceMode.Force): void // Siła, która wyrzuca obiekt w górę, względem globalnego układu współrzędnych. function FixedUpdate () (rigidbody.AddForce (Vector3.up * 10);) // Używając Vector3, wbudowanej funkcji Unity, która jest zasadniczo taka sama jak standardowy układ współrzędnych. // Typ 2: funkcja AddForce (x: float, y: float, z: float, mode: ForceMode = ForceMode.Force): void // To samo, ale tutaj używany jest układ współrzędnych X-Y-Z. funkcja FixedUpdate() (rigidbody.AddForce (0, 10, 0);)

Rigidbody.AddTorque

// Funkcja rozwija obiekt wokół podanej osi. // 1 typ: function AddTorque (moment obrotowy: Vector3, tryb: ForceMode = ForceMode.Force): void // Obraca klawisz ATT wokół globalnej funkcji osi Y FixedUpdate () (rigidbody.AddTorque (Vector3.up * 10);) / / Typ 2: funkcja AddTorque (x: float, y: float, z: float, mode: ForceMode = ForceMode.Force): void // Robi to samo, ale znowu w innym systemie pomiarowym. funkcja FixedUpdate() (rigidbody.AddTorque (0, 10, 0);)

ATT wchodzi w interakcję z obiektami.
Do prawidłowego działania naszych *ATT* należy je dostarczyć zderzak„ami (lub Kolizja"my jak ci się podoba ^. ^).
Przeczytaj więcej o zderzaczach poniżej.


Rozmiar ma znaczenie!
Obserwuj wymiary swojego obiektu, ponieważ są one znacznie bardziej znaczące, nawet masy * ATT *. Jeśli obiekt nie porusza się prawidłowo, wisi w powietrzu lub nie koliduje, spróbuj dostosować jego wielkość (nie * ATT *, ale sam obiekt). Podczas importowania modelu z edytora 3D jego wymiary są zachowywane, dlatego należy zachować ostrożność na etapie modelowania i przestrzegać wymiarów wszystkich modeli.

Dodatkowe informacje o ATT =
Na tym prawdopodobnie zakończę opisywanie * ATT * lub * Rigidbody *. Jest jednak kilka wskazówek, szczególnie dla tych, którzy zaglądali tu wcześniej :)

  1. Standardowy rozmiar kostki w * Unity * to 1 metr, dlatego bardzo wygodnie jest sprawdzić za jego pomocą rozmiar swoich modeli. Aby stworzyć kostkę, wybierz z menu GameObject - Utwórz inny - Cube
  2. Względny wykładnik * Masa * określa, w jaki sposób dwa obiekty będą ze sobą oddziaływać.
  3. * Masa * nie wpływa na prędkość spadania z wysokości, użyj w tym celu * Drag *.
  4. Im wyższe wartości * Drag *, tym większy ciężar elementu. standardowe wartości są różne od 0,001(solidny kawałek metalu) do 10(pióro).
  5. Jeśli potrzebujesz zmodyfikować obiekt za pomocą zarówno skryptów, jak i fizyki, dodaj do niego * ATT * z parametrem * Kinematyka *.

Możesz zobaczyć przykłady skryptów wpływu sił zewnętrznych na obiekt za pomocą funkcji * ATT * pod następującymi linkami:
* Dodaj Siłę *
* Dodaj moment obrotowy *

Aby zmienić przykładowy skrypt, kliknij na tekst z nazwą języka programowania!

Zderzacze
=
= Co to jest? =
W poprzedniej sekcji zbadaliśmy, jak działa * Rigidbody * i wspomnieliśmy o tak zwanych * colliderach *. * Zderzacz * dla nas jest obiektem pomocniczym w postaci siatki prostego prymitywu lub odwrotnie złożonego kształtu, który znajduje się wokół naszego modelu lub części modelu i współdziała z innymi obiektami, jeśli są również otoczone przez zderzacze .
Aby wizualnie wyjaśnić koneserom edytora świata * Warcraft 3 *, wyobraźmy sobie model, który zaimportowaliśmy, do którego nie przypisaliśmy tekstur ścieżki w edytorze dudad - to będzie nasz obiekt; a rolę zderzaczy będą pełnić blokery ścieżki wokół modelu. Oczywiście jest to dość prymitywne porównanie, ponieważ w * Unity * są one znacznie bardziej funkcjonalne. Cóż, przyjrzyjmy się bliżej.

Rodzaje zderzaczy. =
Zderzaki są dodawane za pomocą menu Komponent - Fizyka ... Istnieje kilka rodzajów:

  • Zderzacz pudełek- w formie sześcianu.
  • Zderzacz kuli- w formie kuli.
  • Zderzacz kapsułek- w formie kapsułki.
  • Zderzacz siatki- automatycznie tworzy zderzacz zgodnie z kształtem siatki obiektu, nie może zderzać się z innymi zderzaczami tego samego typu. Używany głównie do obiektów statycznych, takich jak środowisko toru wyścigowego.
  • Zderzacz kół- używany do kół, bardzo przydatna rzecz.
  • Zderzacz złożony- kombinacje prymitywów, które razem działają jak jeden. Aby stworzyć tak złożony zderzacz, musisz dodać obiekty podrzędne do naszego podstawowego zderzacza i powiązać z nimi prymitywem. Na przykład bardzo wygodne jest wykonanie prostych zderzaczy do maszyn.


Konfigurowalne cechy =
W zasadzie wszystkie zderzacze są do siebie podobne, służą po prostu do obiektów o różnych kształtach, ale mają kilka różnych parametrów.

  • * Kostka *

* * Materiał * - Pokazuje, jak zderzacz oddziałuje z innymi obiektami, przypisując fizyczny materiał, na przykład metal, lód itp.
* Czy wyzwalacz- Jeśli parametr jest włączony, to skrypt ma wpływ na obiekt, a nie na fizykę.
* * Rozmiar * - Rozmiar zderzacza wzdłuż osi X-Y-Z.
* * Środek * - Pozycja zderzacza względem lokalnych współrzędnych obiektu.

  • *Kula*

* * Promień * - Promień kuli, zastępuje parametr * Rozmiar *.
* Pozostałe parametry pozostają bez zmian.

  • * Kapsułka * (parametry zastępują rozmiar)

* * Promień * - Grubość kapsułki.
* * Wysokość * - Wysokość cylindrycznej części zderzacza (bez zaokrąglonych podstaw).
* * Direction * - Kierunek zderzacza względem lokalnych współrzędnych obiektu.


  • Zderzacz siatki(parametry zastępują rozmiar)

* * Siatka * - Wybierz żądaną siatkę, aby utworzyć zderzacz.
* Gładkie zderzenia sferyczne - Włączenie tej funkcji wygładza powierzchnię zderzacza. Powinien być stosowany na gładkich powierzchniach, np. pochyłym terenie bez nadmiernej kanciastości, po którym powinny się toczyć kule.
* * Wypukły * - Po włączeniu pozwala naszemu zderzaczowi zderzać się z innymi tego samego. Zderzacz wypukłych siatek„s są ograniczone do 255 trójkątów.

  • Zderzacz kół(parametry zastępują rozmiar)

* * Promień * - Promień koła.
* Odległość zawieszenia- Maksymalna odległość, aby zwiększyć zawieszenie koła. Zawieszenie zawsze zwiększa się wzdłuż lokalnej osi *Y*.
* Sprężyna zawieszenia- Zawieszenie próbuje dotrzeć do określonego punktu przy użyciu różnych sił.

  1. Wiosna: Próby osiągnięcia określonego punktu (pozycji). Im wyższy parametr, tym szybciej jest osiągany.
  2. Amortyzator: zmiękcza, spowalnia prędkość ruchu zawieszenia. Im wyższa wartość, tym wolniej porusza się wstrząs.
  3. Pozycja docelowa: Całkowita „ścieżka”, którą może „przebyć” uprząż. * 0 * oznacza w pełni rozciągnięty wstrząs, a * 1 * oznacza w pełni skompresowany. Domyślna wartość to 0, co odpowiada normalnemu zawieszeniu samochodu.

* * Masa * - Masa koła.
* Tarcie do przodu / na boki - Parametry tarcia dla prostego toczenia koła i toczenia się na boki (dzieje się to w poślizgach lub podczas driftu).

Pisanie Arkanoida w Unity. Mechanika kul i platform

Kontynuujemy więc serię artykułów na temat pisania prostej gry w Unity - klasycznego arkanoida. Będziemy używać tylko narzędzi 2D dostarczonych przez silnik. W każdym z artykułów poruszymy jeden aspekt pisania gier, a w tym wprawimy w ruch piłkę i platformę kontrolowaną przez gracza.

Oto lista wszystkich artykułów:

  1. Mechanika kul i platform.

Gdzie się zatrzymamy?

W poprzedniej lekcji założyliśmy projekt, przenieśliśmy do niego zasoby i stworzyliśmy pierwszą prostą scenę. Jeśli jej nie przeczytałeś, zdecydowanie zalecamy naprawienie tej wady.

Podgląd wyników

Ruch platformy

Platformę już mamy - stworzyliśmy ją w ostatniej lekcji. Pozostaje nauczyć ją poruszania się i tylko w lewo lub w prawo, tj. na osi X. W tym celu musimy napisać skrypt ( Scenariusz).

Skrypty to fragmenty kodu odpowiedzialne za określone zadanie. Unity może pracować ze skryptami napisanymi w trzech językach programowania: Boo, JavaScript i C#. Użyjemy tego ostatniego, ale możesz spróbować swoich sił również w innych językach.

Aby stworzyć skrypt, przejdź do zakładki Projekt, znajdziemy tam folder o tej samej nazwie Skrypty i kliknij go prawym przyciskiem myszy. Wybierzmy Utwórz -> Skrypt C#... Pojawi się nowy plik o nazwie NewBehaviourScript. Dla wygody zmień jego nazwę na PlayerScript. W zakładce Inspektor możesz zobaczyć zawartość skryptu.

Otwórz skrypt, klikając dwukrotnie. Uruchomi się środowisko programistyczne MonoDevelop, które możesz następnie zmienić na dowolny dogodny dla siebie edytor. Oto, co zobaczysz:

Korzystanie z UnityEngine; za pomocą System.Collections; public class NewBehaviourScript: MonoBehaviour (// użyj tej metody, aby zainicjować void Start () () // Aktualizacja jest wywoływana, gdy każda klatka gry jest renderowana void Update () ())

Wszystkie skrypty w Unity mają domyślnie dwie metody:

  • Start (): Służy do inicjowania zmiennych lub parametrów, których potrzebujemy w kodzie.
  • Aktualizacja (): wywoływana każda klatka gry, potrzebna do aktualizacji stanu gry.

Aby przesunąć platformę, potrzebujemy dwóch rodzajów informacji: pozycji i prędkości.

Dlatego musisz utworzyć dwie zmienne do przechowywania tych informacji:

public float playerVelocity;
prywatny Vector3 playerPozycja;

Zauważ, że jedna zmienna jest zadeklarowana publicznie, a druga jest prywatna. Dlaczego to się robi? Faktem jest, że Unity pozwala na edycję wartości zmiennych publicznych bez wchodzenia do edytora MonoDevelop, bez konieczności zmiany kodu. Ta funkcja jest bardzo przydatna w takich przypadkach. gdy konieczne jest skorygowanie wartości w locie. Jedną z takich wartości jest szybkość platformy, dlatego ogłosiliśmy ją publicznie.

Zapisz skrypt w edytorze MonoDevelop i przejdź do edytora Unity. Teraz mamy skrypt i musimy go przypisać do jakiegoś obiektu, w naszym przypadku platformy. Wybierz naszą platformę w zakładce Hierarchia i w oknie Inspektor dodaj komponent, klikając przycisk Dodaj komponent.

Dodanie naszego skryptu do komponentu można wykonać w inny sposób. Przeciągnij nasz skrypt do obszaru przycisków Dodaj komponent... W zakładce Inspektor powinieneś zobaczyć coś takiego:

Zauważ, że komponent skryptu ma teraz pole Prędkość gracza które można natychmiast zmienić. Jest to możliwe poprzez publiczne zadeklarowanie zmiennej. Ustaw parametr na 0.3 i przejdź do edytora MonoDevelop.

Teraz musimy znać pozycję platformy: playerPosition. Aby zainicjować zmienną, odnieś się do obiektu skryptu w metodzie Start():

// użyj tej metody, aby zainicjować void Start() (// pobierz pozycję początkową platformy playerPosition = gameObject.transform.position;)

Świetnie, ustaliliśmy pozycję startową platformy i teraz możesz ją przesunąć. Ponieważ potrzebujemy, aby platforma poruszała się tylko wzdłuż osi X, możemy użyć metody GetAxis klasy Input. Do tej funkcji przekażemy napis Poziomy, który zwróci 1, jeśli naciśnięto klawisz "w prawo", a -1 - "w lewo". Mnożąc uzyskaną liczbę przez prędkość i dodając tę ​​wartość do aktualnej pozycji gracza, otrzymujemy ruch.

Dodamy również czek na wyjście z aplikacji, naciskając klawisz Esc.

Oto, na czym powinniśmy skończyć:

Korzystanie z UnityEngine; za pomocą System.Collections; public class PlayerScript: MonoBehaviour (public float playerVelocity; private Vector3 playerPosition; // użyj tej metody do zainicjowania void Start() (// pobierz pozycję początkową platformy playerPosition = gameObject.transform.position;) // Aktualizacja jest wywoływana, gdy każda klatka gry jest rysowana void Update() (// ruch poziomy playerPosition.x + = Input.GetAxis ("Horizontal") * playerVelocity; // wyjście z gry if (Input.GetKeyDown (KeyCode.Escape)) ( Application.Quit ();) // aktualizacja pozycji platformy transform.position = playerPosition;))

Zapisz skrypt i wróć do edytora Unity. Naciśnij przycisk Bawić się i spróbuj przesunąć platformę za pomocą lewego i prawego przycisku.

Definiowanie obszaru gry

Najprawdopodobniej zauważyłeś, że platforma może wychodzić poza pole gry. Faktem jest, że nie mamy żadnych kontroli przed przekroczeniem jakichkolwiek granic.

Dodajmy kolejną zmienną publiczną do naszego istniejącego skryptu i nazwijmy ją granicą.

Ta zmienna będzie przechowywać maksymalną współrzędną platformy wzdłuż osi X. Ponieważ zamierzamy budować poziomy w formie symetrycznej wokół punktu o współrzędnych (0, 0, 0), bezwzględną wartością zmiennej brzegowej będzie to samo dla dodatniej części osi X i dla ujemnej.

Dodajmy teraz kilka warunków. Zróbmy to po prostu: jeśli obliczona pozycja jest większa niż granica lub mniejsza niż granica, to po prostu ustawiamy nową pozycję wzdłuż osi X równą wartości zmiennej granicznej. Tym samym gwarantujemy, że platforma nie opuszcza naszych granic i nigdy nie opuszcza obszaru gry. Oto kod:

Korzystanie z UnityEngine; za pomocą System.Collections; public class PlayerScript: MonoBehaviour (public float playerVelocity; private Vector3 playerPosition; // użyj tej metody do zainicjowania void Start() (// pobierz pozycję początkową platformy playerPosition = gameObject.transform.position;) // Aktualizacja jest wywoływana, gdy każda klatka gry jest rysowana void Update() (// ruch poziomy playerPosition.x + = Input.GetAxis ("Horizontal") * playerVelocity; // wyjście z gry if (Input.GetKeyDown (KeyCode.Escape)) ( Application.Quit ();) // zaktualizuj pozycję platformy transform.position = playerPosition; // sprawdź, czy jest poza granicami if (playerPosition.x< -boundary) { transform.position = new Vector3 (-boundary, playerPosition.y, playerPosition.z); } if (playerPosition.x >granica) (transform.position = new Vector3 (boundary, playerPosition.y, playerPosition.z);)))

Teraz wróć do edytora i przełączając się do gry, znajdź optymalną wartość zmiennej brzegowej. W naszym przypadku pojawiła się liczba 5.46. Otworzyć Inspektor i zresetuj pozycję platformy X do 0, a parametr Granica ustaw go zgodnie ze znalezioną wartością.

Naciśnij przycisk Bawić się i upewnij się, że zrobiłeś wszystko dobrze. Platforma powinna poruszać się tylko w obrębie pola gry.

Włączam fizykę

Aby zderzenia były bardziej realistyczne, wykorzystamy symulację fizyki. W tym artykule dodamy właściwości fizyczne do granic piłki, platformy i pola. Ponieważ piszemy grę 2D, będziemy używać colliderów 2D. Zderzacz to oddzielny typ komponentu, który umożliwia obiektowi reagowanie na zderzacze innych obiektów.

W oknie Hierarchia wybierz naszą platformę, przejdź do Inspektor i kliknij przycisk Dodaj komponent... W wyświetlonym oknie wpisz collider. Jak widać, opcji jest bardzo dużo. Każdy zderzacz ma określone właściwości odpowiadające powiązanym obiektom - prostokąty, koła itp.

Ponieważ nasza platforma jest prostokątna, użyjemy Zderzacz pudełek 2D... Wybierz go, a komponent automatycznie określi wymiary platformy: nie będziesz musiał ich ustawiać ręcznie, Unity zrobi to za Ciebie.

Zrób to samo dla 3 obramowań ( Hierarchia -> Inspektor -> Dodaj komponent -> Box Collider 2D).

Z piłką trochę inaczej: ma okrągły kształt. Wybierzmy piłkę i dodajmy do niej komponent Zderzacz kołowy 2D.

W rzeczywistości zderzacz okręgu i prostokąta jest bardzo podobny, z wyjątkiem tego, że zamiast parametru Rozmiar, który określa szerokość i długość, w okręgu jest używany Promień... Uważamy, że wyjaśnienia tutaj są zbyteczne.

Elastyczna Kolizja

Aby nasza piłka odbijała się od bloków, ścian i platform, musimy ustawić powierzchnię (materiał) dla składnika fizycznego dodanego wcześniej. Wszystko jest już w Unity, wystarczy tylko dodać niezbędny materiał.

Otwórz okno Projekt i wewnątrz folderu Zaleta utwórz nowy folder o nazwie Fizyka. Kliknij nowo utworzony folder prawym przyciskiem myszy i wybierz Utwórz -> Materiał Physics2D... Nazwij go BallPhysicsMaterial.

Każda powierzchnia w Unity ma dwa parametry: tarcie (tarcie) i elastyczność (odskok)... Możesz przeczytać więcej o silniku fizyki i szeregu parametrów fizycznych. Jeśli potrzebujesz absolutnie elastycznego ciała, powinieneś ustawić tarcie na 0, a elastyczność na 1.

Teraz mamy gotowy materiał, ale nie ma to jeszcze nic wspólnego z piłką. Wybierz obiekt z piłką w zakładce Hierarchia i w oknie Inspektor zobaczysz pole Materiał składnik Zderzacz kołowy 2D... Przeciągnij tutaj nowo utworzony materiał.

Dodawanie komponentu Sztywny korpus

Aby nasza piłka poruszała się pod kontrolą fizyki, musimy dodać do niej jeszcze jeden składnik: Korpus sztywny 2D... Wybierz obiekt kuli w oknie Hierarchia i dodaj powyższy składnik - choć ma kilka parametrów, nas interesuje tylko jeden: Skala grawitacyjna... Ponieważ nasza piłka będzie się poruszać tylko dzięki odbiciu, ustawimy ten parametr na 0 - w ten sposób zagwarantujemy, że grawitacja nie zareaguje na obiekt. Wszystko inne można pozostawić bez zmian.

Zachowanie koralików

Stwórzmy osobny skrypt dla piłki (znowu używając C# jako języka programowania) i nazwijmy go BallScript. Połącz wygenerowany skrypt z obiektem ( Hierarchia -> Inspektor -> Dodaj komponent).

Zanim zaczniemy pisać skrypt, zdefiniujmy zachowanie balonika:

  1. Piłka ma dwa stany: nieaktywną (kiedy znajduje się na platformie na początku gry) i aktywną (kiedy jest w ruchu).
  2. Piłka stanie się aktywna tylko raz.
  3. Kiedy piłka staje się aktywna, przykładamy do niej siłę, aby zaczęła się poruszać.
  4. Jeśli piłka opuści pole gry, zostaje dezaktywowana i umieszczona na platformie.

Na podstawie tych informacji utwórzmy zmienne globalne ballIsActive, ballPosition i ballInitialForce:

prywatna kula boolIsActive;
prywatne Vector3 ballPosition;
prywatne Vector2 ballInitialForce;

Teraz, gdy mamy już zestaw zmiennych, musimy przygotować obiekt. W metodzie Start() musimy:

  • stworzyć siłę, która zostanie przyłożona do piłki;
  • umieścić piłkę w stanie nieaktywnym;
  • zapamiętaj pozycję piłki.

Oto jak możesz to zrobić:

Void Start () (// utwórz siłę ballInitialForce = new Vector2 (100.0f, 300.0f); // wyłącz ballIsActive = false; // zapamiętaj pozycję ballPosition = transform.position;)

Jak być może zauważyłeś, przyłożona siła nie jest ściśle pionowa, ale nachylona w prawo – piłka będzie się poruszać po przekątnej.

Unieważnij aktualizację (// sprawdź, czy wciśnięto spację, jeśli (Input.GetButtonDown ("Skok") == true) ())

Następnym krokiem jest sprawdzenie stanu kuli, ponieważ wystarczy ustawić siłę, gdy kula jest w stanie nieaktywnym:

Void Update() (// sprawdź, czy spacja jest naciśnięta if (Input.GetButtonDown ("Skok") == true) (// sprawdź stan, jeśli (! BallIsActive) ()))

Jeżeli założymy, że jesteśmy na początku gry, to musimy przyłożyć siłę do piłki i ustawić ją w stan aktywny:

Void Update() (// sprawdź, czy naciśnięto spację if (Input.GetButtonDown ("Skok") == true) (// sprawdź stan, jeśli (! BallIsActive) (// zastosuj siłę fixedbody2D.AddForce (ballInitialForce) ; // ustaw stan aktywny ballIsActive =! ballIsActive;)))

Jeśli teraz włączysz grę, to naciskając spację, piłka faktycznie zacznie się poruszać. Możesz jednak zauważyć, że kulka w stanie nieaktywnym nie zachowuje się całkiem poprawnie: jeśli poruszamy platformą, to kulka powinna się z nią poruszać, ale w rzeczywistości pozostaje w tej samej pozycji. Przestań grać, naprawmy to.

W metodzie Update musimy sprawdzić stan kuli, a jeśli jest nieaktywna, ustawić pozycję kuli w osi X taką samą jak platforma.

Rozwiązanie jest dość proste, ale jak uzyskać współrzędną zupełnie innego obiektu? Elementary - utworzymy zmienną typu GameObject i zapiszemy referencję do obiektu platformy:

publiczny GameObject playerObject;

Wróćmy do metody Update():

Void Update() (// sprawdź, czy naciśnięto spację if (Input.GetButtonDown ("Skok") == true) (// sprawdź stan, jeśli (! BallIsActive) (// zastosuj siłę fixedbody2D.AddForce (ballInitialForce) ; // ustaw stan aktywny ballIsActive =! ballIsActive;) if (! ballIsActive && playerObject! = null) (// ustaw nową pozycję piłki ballPosition.x = playerObject.transform.position.x; // ustaw pozycję piłki piłka transform.position = ballPosition;)) )

Zapisz skrypt i wróć do edytora Unity. Być może zauważyłeś, że zmienna playerObject jest zadeklarowana, używana, ale nigdzie nie została zainicjowana. Tak to prawda. Aby go zainicjować, przejdź do zakładki Hierarchia, znajdź piłkę i w oknie Inspektor znajdź komponent Piłkowy skrypt... Ten składnik ma parametr Obiekt gracza, obecnie pusta:

Znajdź w zakładce Hierarchia naszą platformę i przeciągnij ją na pole Obiekt gracza... Rozpocznij grę, naciskając przycisk Bawić się i upewnij się, że wszystko działa.

Resetowanie gry

Jeśli na tym etapie rozpoczniesz grę i przegrasz (tak, że piłka wypadnie z pola), to nic nie wróci do normy. Ale w rzeczywistości stan gry powinien zostać zresetowany. Naprawmy to.

Bardzo łatwo jest złapać ten stan: kulka będzie aktywna, a jej pozycja wzdłuż osi Y jest ujemna. Jeśli tak, to przenosimy piłkę do stanu nieaktywnego i kładziemy ją na platformie:

If (ballIsActive && transform.position.y< -6) { ballIsActive = !ballIsActive; ballPosition.x = playerObject.transform.position.x; ballPosition.y = -4.2f; transform.position = ballPosition; }

Ale to nie koniec. Po zapisaniu skryptu i uruchomieniu gry zauważysz, że przy każdym ponownym uruchomieniu poziomu kulka nabiera coraz większej siły. Dlaczego tak się dzieje? Chodzi o to, że nie usuwamy sił działających na piłkę. Aby to naprawić, możemy użyć parametru IsKinematic, wyłączając go przed dodaniem siły i włączając po upadku.

Oto ostateczna metoda Update():

Klasa publiczna BallScript: MonoBehaviour (private bool ballIsActive; private Vector3 ballPosition; private Vector2 ballInitialForce; // GameObject public GameObject playerObject; // użyj tej metody, aby zainicjować void Start () (// utwórz wymuszenie ballInitialForce = new Vector2 (100.0f, 300.0 f); // dezaktywuj ballIsActive = false; // zapamiętaj pozycję ballPosition = transform.position;) void Update() (// sprawdź, czy naciśnięto spację if (Input.GetButtonDown ("Jump") == true) ( // sprawdź stan if (! ballIsActive) (// zresetuj wszystkie siły fixedbody2D.isKinematic = false; // zastosuj siłę fixedbody2D.AddForce (ballInitialForce); // ustaw stan aktywny ballIsActive =! ballIsActive;) if (! ballIsActive && playerObject! = null) (// ustaw nową pozycję piłki ballPosition.x = playerObject.transform.position.x; // ustaw pozycję piłki transform.position = ballPosition;) // sprawdź, czy piłka spada if (ballIsActive && tra nsform.pozycja.y< -6) { ballIsActive = !ballIsActive; ballPosition.x = playerObject.transform.position.x; ballPosition.y = -4.2f; transform.position = ballPosition; rigidbody2D.isKinematic = true; } } }

I teraz to jest dokładnie to. Uruchom grę i sprawdź, czy wszystko działa zgodnie z oczekiwaniami.

W następnej części

Tak więc drugi artykuł dobiegł końca. Nauczyłeś się teraz, jak pracować ze skryptami, colliderami i klawiaturą. Następnym razem porozmawiamy o mechanice bloków gry.

Wyświetlenia: 734


Moja dziwna ścieżka twórcza zaprowadziła mnie do tworzenia gier. Dzięki doskonałemu programowi studenckiemu firmy informatycznej, której nazwa składa się z jednej greckiej małej litery, współpracującej z naszą uczelnią, udało się zebrać zespół, wygenerować dokumentację i stworzyć grę Agile pod okiem wysokiej jakości QA inżynier (witaj Anno!)

Bez większego namysłu Unity został wybrany jako silnik. To wspaniały silnik, który może naprawdę szybko i łatwo stworzyć bardzo złą grę, w którą przy zdrowych zmysłach nikt nigdy nie zagra. Aby stworzyć dobrą grę, nadal musisz przejrzeć dokumentację, zagłębić się w niektóre funkcje i zdobyć doświadczenie programistyczne.

Nasza gra wykorzystywała silnik fizyczny w sposób, którego nie oczekiwała, co powodowało wiele problemów z wydajnością na platformach mobilnych. Ten artykuł, na przykładzie naszej gry, opisuje moje zmagania z silnikiem fizyki i wszystkimi cechami jego działania, które zostały zauważone na drodze do opłacalnej wersji beta.

Gra

Kilka słów o tym, jak to zostało zrobione.
Stworzony za pomocą Blendera i kilku skryptów Pythona. W momencie kręcenia w rogu ekranu znajdowało się 16 kwadratów, których kolor zakodował 32 bity liczby zmiennoprzecinkowej - obrót telefonu w danym momencie. R, G - dane, B - parzystość. 0 - 0, 255 - 1. Film nagrany na komputerze został podzielony na klatki za pomocą ffmpeg, każdej klatce renderowania przypisano odszyfrowany róg. Ten format pozwolił nam przetrwać każdą kompresję w procesie fotografowania i przezwyciężyć fakt, że wszystkie programy mają nieco inne wyobrażenie o upływającym czasie. W rzeczywistości gra przebiega w taki sam sposób, jak na renderze.


Samolot przelatuje przez niekończącą się i nieprzewidywalną jaskinię, w której znajdują się bonusy, różnego rodzaju monety oraz wrogowie, w których można strzelać samonaprowadzającymi pociskami. Uderzył w ścianę - natychmiast zgubiony.
Cechą charakterystyczną gry jest to, że poziom jest przybity do horyzontu, a sterowanie w nim jest żyroskopowe, a ponadto absolutne. Przechyliłem telefon o 45 stopni - samolot leciał pod kątem 45 stopni. Musisz zrobić martwą pętlę - musisz przekręcić tablet. Bez wrażliwości, po prostu hardcore.
Podkreślmy dwa główne i oczywiste problemy dla programisty:
Problem 1: Nieskończoność
Unity przechowuje i przetwarza współrzędne obiektów w postaci zwykłych 32-bitowych elementów pływających z dokładnością do 6 miejsc po przecinku. Problem w tym, że gra nie ma końca, a jeśli polecimy wystarczająco długo, zaczną się różne szalone błędy, aż po teleportację przez ściany. Istnieje kilka podejść do rozwiązania tego problemu:
  • Ignorowanie. Na przykład w Minecrafcie błędy zaokrąglania sprawiły, że gra stała się ciekawsza tylko dzięki spawnowaniu.

  • Teleportacja do (0; 0; 0), gdy samolot jest zbyt daleko od początku.

  • Zmiana punktu początkowego. To nie samolot się porusza, ale poziom wokół niego.
  • W naszym przypadku jedyną poprawną opcją jest trzecia, która została zaimplementowana. O wdrożeniu - trochę później.
    Pierwszy, ignorowanie, jest absolutnie nie do przyjęcia. Stworzenie robota, który może grać w naszą grę bez końca, to ciekawe (i bardzo proste) zadanie, które ktoś rozwiąże. A zwykłych koreańskich graczy nie należy lekceważyć – samolot jest szybki, poziom generowany jest nieprzewidywalnie. A jeśli latasz i latasz przed przejściem przez ściany, to znacznie dokładniejsze strzelanie oczywiście zacznie zawodzić po 5 minutach lotu.
    Drugi – teleportacja gracza i całego świata – rzuca urządzenia mobilne na kolana, w niektórych przypadkach – na około pół sekundy. Jest to bardzo zauważalne, a zatem niedopuszczalne. Ale jest to całkowicie akceptowalna opcja dla bezpretensjonalnych, niekończących się gier na PC.

    Problem 2: generowanie poziomów

    Istnieje kilka podstawowych podejść do budowania niekończących się biegaczy:
  • Korzystanie z gotowych segmentów poziomów, które losowo dokują. Odbywa się to na przykład w Subway Surfers. Jest łatwy do wdrożenia, ale gracz szybko się do tego przyzwyczaja i wie, na co się przygotować, co jest nudne.

  • Poziom to prosta linia, na której losowo umieszczane są przeszkody. Odbywa się to w Joypack Joyride i Temple Run. W naszym przypadku znacznie ograniczyłoby to liczbę manewrów.

  • Wszystko jest generowane losowo. Najtrudniejsza, nieprzewidywalna i interesująca opcja dla gracza.
  • Oczywiście wybraliśmy najtrudniejszą opcję. W jego sercu znajduje się bardzo złożona maszyna stanów, która wykonuje nad nimi losowe przejścia. Ale w ramach tego artykułu interesujący jest nie mechanizm, ale proces generowania poziomu i jego organizacji z uwzględnieniem wybranego punktu wyjścia.

    Struktura poziomu

    Lecimy w jaskini, ma podłogę i sufit - kilka bloków, elementarne jednostki budowlane. Bloki są połączone w segmenty, które płynnie do siebie pasują. Segmenty jako całość obracają się wokół samolotu i poruszają się wzdłuż jego wektora prędkości, tworząc iluzję lotu. Jeśli segment opuści pole widzenia kamery, jest usuwany z bloków, dokowany do ostatniego segmentu poziomu i wypełniany nowymi blokami, zgodnie z instrukcjami generatora. Suma takich segmentów to poziom.
    Doświadczeni programiści Unity mogli słusznie skrzywić się na zakres prac i wszystkie możliwe pułapki. Ale słowami wszystko jest proste, a ja nie miałem doświadczenia w rozwoju...

    Podstawowe prawa fizyki w jedności

    W ciągu miesiąca rozwoju, eksperymentowania i czytania dokumentacji, zidentyfikowałem trzy podstawowe prawa fizyki w Unity. Można je naruszać, ale ceną za naruszenie jest wydajność. Silnik w żaden sposób nie ostrzeże Cię o błędzie, a bez profilera możesz nigdy się o nich nie dowiedzieć. Nieprzestrzeganie tych przepisów może spowolnić grę. w dziesiątkach pewnego razu. Jak rozumiem, pogwałcenie jakiegokolwiek prawa prowadzi do tego, że silnik fizyki oznacza wadliwy zderzacz jako niepoprawny i odtwarza go na obiekcie, po czym następuje ponowne obliczenie fizyki:
    1. Zderzacze nie mogą się poruszać, obracać, włączać/wyłączać i zmieniać rozmiaru.
    Po dodaniu zderzacza do obiektu zapomnij o jego wpływie na niego lub o obiektach, które go zawierają. Normalny zderzacz jest obiektem czysto statycznym. Na przykład drzewo może mieć jeden zderzacz. Jeśli drzewo może spaść na gracza, drzewo upadnie wraz z występem. Jeśli to drzewo wyrośnie z magicznej chmury składników odżywczych, która nie ma zderzacza, ale może się poruszać, towarzyszyć temu będzie spadek produktywności.
    2. Jeśli obiekt się porusza lub obraca - musi to być bryła sztywna, tj. mają składnik Rigidbody.
    Tak jest napisane w dokumentacji. Nie musisz uważnie czytać, aby rozpocząć tworzenie gry, ponieważ Unity jest bardzo prosty i intuicyjny.
    Rigidbody zmienia relację silnika fizycznego z obiektem. Zaczynają na niego działać siły zewnętrzne, może mieć prędkości liniowe i kątowe, a co najważniejsze, ciało sztywne może poruszać się i obracać za pomocą silnika fizycznego, nie powodując całkowitego przeliczenia fizyki.
    Istnieją dwa rodzaje brył - zwykłe i kinematyczne. Zwykłe ciała oddziałują ze sobą i ze zwykłymi zderzaczami - jedno ciało nie może przejść przez drugie. Ciała kinematyczne podlegają uproszczonym regułom symulacji — nie mają na nie wpływu żadne siły zewnętrzne, w tym grawitacja. Mogą swobodnie przejść przez wszystko.
    Jeśli nie masz nic przeciwko oddaniu obiektów pod kontrolę silnika fizycznego, użyj zwykłych sztywnych ciał. Na przykład, jeśli chcesz pięknie toczyć kamienie z klifu. Jeśli twoje skrypty lub animatorzy bezpośrednio kontrolują obiekt, użyj ciał kinematycznych, abyś nie musiał nieustannie zmagać się z silnikiem i przypadkowymi kolizjami obiektów. Na przykład, jeśli masz animowaną postać lub kierowany pocisk, który wybucha w kontakcie z czymś.
    3. Jeśli obiekt jest ciałem sztywnym, musi poruszać się i obracać metodami bryły sztywnej.
    Zapomnij o wywoływaniu Transform "na obiekcie natychmiast po dodaniu do niego collidera. Od teraz Transform jest twoim wrogiem i zabójcą wydajności. Zanim napiszesz transform.position = ... lub transform.eulerAngles = ... powiedz" Teraz doskonale rozumiem, co robię, jestem zadowolony z hamulców, które wywoła ta linia.” Nie zapominaj o połączeniach hierarchicznych: jeśli nagle przesuniesz obiekt zawierający ciała stałe, fizyka zostanie przeliczona.
    Istnieją trzy poziomy sterowania ciałem sztywnym:
    - Najwyższy, a więc naturalny poziom - poprzez siły. Są to metody AddForce i AddTorque. Silnik fizyczny uwzględni masę ciała i poprawnie obliczy wynikową prędkość. Wszystkie interakcje ciał zachodzą na tym poziomie.
    - Średnia - zmiana prędkości. Są to właściwości prędkości i prędkości kątowej. Na ich podstawie obliczane są siły działające na ciała podczas ich interakcji, a także oczywiście ich położenie w następnym momencie. Jeśli sztywny korpus ma bardzo małą prędkość, „zasypia”, aby oszczędzać zasoby.
    - Najniższy poziom to bezpośrednio współrzędne obiektu i jego orientacja w przestrzeni. Są to metody MovePosition i MoveRotation. Przy kolejnej iteracji obliczeń fizycznych (jest to ważne, ponieważ każde kolejne wywołanie metody w ramach jednej klatki zastępuje wywołanie poprzedniego), teleportują obiekt do nowej pozycji, po czym żyje on jak poprzednio. Ten poziom jest używany w naszej grze i tylko na nim, ponieważ zapewnia pełną kontrolę nad obiektem.

    Co pozostało? Obiekt wł./wył. i skalowanie. Nie wiem, czy istnieje sposób na zmianę rozmiaru obiektu bez mylenia silnika. Całkiem możliwe, że nie. Wyłączenie obiektu jest bezbolesne, a włączenie go… tak, powoduje przeliczenie fizyki w okolicach włączonego obiektu. Dlatego staraj się nie włączać zbyt wielu obiektów jednocześnie, rozciągnij ten proces w czasie, aby użytkownik tego nie zauważył.

    Istnieje prawo, które nie wpływa na wydajność, ale wpływa na wydajność: ciało stałe nie może być częścią ciała stałego. Obiekt rodzica będzie dominował, więc dziecko albo będzie stać w stosunku do rodzica, albo zachowywać się w nieprzewidywalny i niepoprawny sposób.

    Jest jeszcze jedna niefizyczna cecha Unity, o której warto wspomnieć: dynamiczne tworzenie i niszczenie obiektów za pomocą metod Instantiate / Destroy jest NIESAMOWITE wolne. Boję się nawet wyobrazić sobie, co dzieje się pod maską podczas tworzenia obiektu. Jeśli potrzebujesz tworzyć i usuwać coś dynamicznie - korzystaj z fabryk i wypełniaj je niezbędnymi obiektami podczas ładowania gry. Instantiate powinno się nazywać w ostateczności - jeśli w fabryce nagle zabraknie wolnych obiektów, a na zawsze zapomnisz o Destroy - wszystko, co powstało, powinno zostać ponownie użyte.

    Stosowanie prawa w praktyce

    (ta sekcja zawiera tok rozumowania podczas tworzenia gry i jej funkcje)

    Poziom powinien oczywiście się obracać i poruszać.
    Ułatwmy sobie na zawsze nasze życie, umieszczając oś obrotu niwelatora – samolot – w punkcie początkowym. Teraz możemy obliczyć odległość od punktu do niego, obliczając długość wektora współrzędnych punktu. Drobiazg, ale fajnie.
    Przenoszenie obiektów razem jest łatwe dzięki hierarchii obiektów w Unity, ponieważ dzieci są częścią rodzica. Na przykład opisana struktura poziomów jest logicznie zaimplementowana w następujący sposób:
    - Oś obrotu
    - - Poziom
    - - - Segment 1
    - - - - Blok 1 (Zderzacz)
    - - - - ...
    - - - - Blok N
    - - - Segment 2 ...
    - - - Segment 3 ...
    - - - Segment 4 ...
    (Możesz nawet obejść się bez obiektu poziomu)

    Skrypt na osi odbiera dane z żyroskopu i ustawia pod nim odpowiedni kąt... I łamie wiele zasad na raz, bo obrót będzie przekazywany przez hierarchię do zderzaczy, co doprowadzi silnik fizyki do szału. Będziesz musiał uczynić oś sztywną bryłą i obrócić ją odpowiednią metodą. Ale co z ruchem poziomym? Oczywiście oś obrotu i przedmiot poziomu nie poruszą się, każdy segment trzeba przesunąć indywidualnie, w przeciwnym razie mamy do czynienia z problemem nieskończoności. Oznacza to, że segmenty muszą być bryłami sztywnymi. Ale już wyżej w hierarchii mamy ciało sztywne, a ciało sztywne nie może być częścią ciała sztywnego. Logiczna i elegancka hierarchia nie jest odpowiednia, wszystko trzeba robić ręcznie - zarówno obrót, jak i ruch, bez użycia obiektu jako osi obrotu. Przygotuj się na to, jeśli masz unikalne cechy rozgrywki.

    Gdybyś musiał przenieść segmenty bezpośrednio i tak, to musiałyby zostać obrócone. Główną trudnością jest to, że silnik fizyki Unity nie ma metody „obracania obiektu wokół dowolnego punktu” (Transform ma, ale nie daj się skusić). Pozostaje tylko „obracać się wokół jego środka”. Jest to logiczne, ponieważ obrót wokół dowolnej osi jest zarówno obrotem, jak i ruchem, a są to dwie różne operacje. Ale można go naśladować. Najpierw obracamy odcinek wokół jego osi, następnie obracamy współrzędne jego „własnej osi” wokół płaszczyzny. Z racji tego, że samolot jest na początku, nie musimy nawet pamiętać szkolnej geometrii i wchodzić na Wikipedię, Unity ma już wszystko. Wystarczy przeliczyć kąt obrotu na kwaternion i pomnożyć go przez współrzędne punktu. Swoją drogą dowiedziałem się o tym już w momencie pisania artykułu, zanim użyto macierzy rotacji.

    Mamy wrogów, którzy pchają samolot pod ścianę w nadziei, że zabiją. Jest tarcza, która odpycha samolot od ścian, pomagając przetrwać. Jest to zaimplementowane w banalny sposób - istnieje wektor przesunięcia, który jest dodawany do współrzędnych każdego segmentu w każdej klatce, a następnie resetowany. Każdy, kto chce kopnąć samolot, specjalną metodą, może zostawić wektor swojego kopnięcia, który zostanie dodany do tego wektora przemieszczenia.

    Ostatecznie rzeczywiste współrzędne segmentu, każdej klatki, są obliczane przez centrum sterowania ruchem poziomu mniej więcej tak:
    Pozycja wektora3 = segment.CachedRigidbody.pozycja; Vector3 deltaPos = Czas.deltaTime * Vector3.left * ustawienia.Prędkość; segment.truePosition = Quaternion.Euler (0, 0, deltaAngle) * (pozycja + deltaPos + przesunięcie przesunięcia);
    Po wszystkich obliczeniach i kulach niezbędnych do precyzyjnego wyrównania segmentów, aby działały podczas regeneracji, segment.truePosition jest wysyłany do metody MovePosition sztywnego korpusu segmentu.

    wnioski

    Jak szybko to wszystko działa? Na starych flagowcach - Nexusie 5 i LG G2 - gra leci z prędkością 60 FPS, z ledwo zauważalnym spadkiem przy włączaniu nowych zderzaczy podczas generowania segmentu (jest to nieuniknione i nie działa) i robakami wypychającymi się z ziemi (ty może stworzyć jakieś piekło, aby to obejść, ale teraz dochodzi do celowego naruszenia trzeciego prawa). 40 stabilnych FPS daje każde urządzenie z żyroskopem, na które się natkniemy. Bez znajomości i rozważenia wszystkich przepisów wydajność była co najmniej niezadowalająca, a telefony przegrzane. Tak bardzo, że pomyślałem o napisaniu własnego, prostego, wyspecjalizowanego silnika dla fizyki 2D. Na szczęście fizyka w Unity okazała się na tyle elastyczna, że ​​wszystkie problemy można było ominąć i stworzyć unikalną grę, wystarczyło zaledwie kilka tygodni eksperymentów.

    Teraz, gdy znasz już wszystkie główne pułapki silnika fizyki Unity, możesz szybko sklonować naszą grę, niszcząc marzenia, życie i wiarę trzech biednych uczniów w ludzkość. Mam nadzieję, że ten artykuł zaoszczędzi Ci wiele czasu w przyszłości i pomoże znaleźć nie do końca oczywiste naruszenia praw fizyki produktywnej w Twoich projektach.

    Przeczytaj dokumentację i poeksperymentuj, nawet jeśli używasz prostych i intuicyjnych narzędzi.

    Powiązane artykuły: