‫Witamy spowrotem.
‫Teraz w tym filmie porozmawiamy o hitowych wydarzeniach.
‫Chcielibyśmy wykryć, kiedy pocisk w coś trafi i w ten sposób możemy coś zrobić w
‫odpowiedzi, np. zniszczyć pocisk.
‫A później zajmiemy się zadawaniem obrażeń i powodowaniem efektów eksplozji i tym podobnych.
‫Porozmawiajmy teraz trochę o hitowych wydarzeniach.
‫Nasz pocisk ma element siatkowy.
‫Jego typ to ty statyczny komponent siatkowy, a ty statyczny komponent siatkowy to jedna klasa w długiej hierarchii
‫klas, a nierzeczywisty system silnika jednym z jego rodziców to ty prymitywny komponent.
‫Oto strona z dokumentacją dla twojego prymitywnego komponentu.
‫Mówi, że prymitywne komponenty są postrzegane jako komponenty, które zawierają lub generują pewien rodzaj geometrii, która jest
‫ogólnie renderowana lub używana jako dane o kolizji.
‫Są więc w zasadzie komponentami sceny z kilkoma dodatkowymi funkcjami.
‫A jeśli przewiniesz w dół i spojrzysz na hierarchię, zobaczysz, że widzieliśmy komponent i
‫pochodzę od tego pierwotnego komponentu, i możesz przewijać w dół i zobaczyć wszystkie inne klasy, które
‫pochodzą od ciebie.
‫Składnik pierwotny.
‫Powodem, dla którego to podkreślamy, jest to, że statyczny komponent siatki dziedziczy
‫te cechy z twojego podstawowego komponentu, a ty prymitywny komponent ma możliwość generowania zdarzeń trafień.
‫Co rozumiemy przez generowanie zdarzeń trafień?
‫Cóż, powiedzmy, że mamy w naszym świecie pewną geometrię reprezentowaną przez prostokąt po
‫prawej stronie i mamy obiekt ze statyczną siatką reprezentowaną przez okrąg po lewej stronie.
‫Teraz, jeśli ten obiekt, który ma statyczny komponent siatki, porusza się w kierunku bloku, to jeśli ten komponent jest
‫skonfigurowany do obsługi zdarzeń trafień, to jak tylko trafi w ten blok, zdarzenie trafienia zostanie wygenerowane
‫po kolizji.
‫Teraz zdarzenie trafienia wygeneruje pewne dane dotyczące tej kolizji, w tym komponent, który został
‫trafiony.
‫Więc ten blok tutaj może mieć statyczny komponent siatki.
‫Możemy uzyskać dostęp do tego komponentu po kolizji.
‫Możemy również uzyskać dostęp do aktora, który został trafiony, a zdarzenie głowy również generuje wynik trafienia EF.
‫Dowiedzieliśmy się trochę o wyniku trafienia F i wiemy, że zawiera on wiele zmiennych dotyczących
‫zdarzenia trafienia, takich jak lokalizacja trafienia, która jest wektorem F reprezentującym lokalizację na świecie.
‫Więc mamy naszą siatkę pocisków.
‫Jest to zmienna typu statycznego wskaźnika komponentu siatki.
‫Teraz, gdy ten statyczny komponent siatki uderza w coś na świecie, chcemy mieć jakiś kod, który
‫na to zareaguje.
‫Teraz będąc statycznym komponentem siatki, dziedziczy rzeczy z twojej pierwotnej klasy komponentów.
‫Jedną z rzeczy, które dziedziczy, jest zmienna wywoływana po trafieniu komponentu.
‫Oto dokumentacja dotycząca trafienia komponentu.
‫Jest to opisane jako zdarzenie o nazwie Kiedy komponent uderza lub zostaje uderzony przez coś stałego.
‫Teraz przewijając w dół, widzimy, że po trafieniu komponentu ma sygnaturę trafienia komponentu typu F.
‫A jeśli to klikniemy, zobaczymy, że sygnatura trafienia komponentu F jest strukturą.
‫Wracając, widzimy, że dokumentacja mówi o zdarzeniu wywoływanym, gdy komponent uderza lub zostaje uderzony
‫przez coś stałego.
‫Może się to zdarzyć z powodu takich rzeczy, jak ruch postaci przy użyciu ustawionej lokalizacji z włączonym przemiataniem
‫lub symulacja fizyki dla zdarzeń, w których obiekty nakładają się, takie jak wejście w wyzwalacz, zobacz zdarzenie nakładania się.
‫Są więc zdarzenia hitowe i zdarzenia nakładające się.
‫Interesują nas hity.
‫Wiemy więc, że trafienie w komponencie jest opisane w dokumentacji jako zdarzenie trafienia i wiemy, że
‫trafienie w komponencie jest strukturą typu F sygnatury trafienia komponentu.
‫Na razie w porządku.
‫Teraz to zdarzenie trafienia po trafieniu komponentu jest również czymś, co nazywamy delegatem multiemisji.
‫Delegat multiemisji może mieć powiązanych z nim wiele funkcji.
‫Mogą istnieć funkcje, które istnieją w wielu klasach.
‫A jeśli te funkcje zostaną powiązane z delegatem multiemisji, zostaną dodane do czegoś, co nazywa
‫się listą wywołań.
‫To jest lista funkcji, które mają zostać wywołane, gdy zdarzenie trafienia mówi im, że mają zostać wywołane.
‫Mówimy, że to zdarzenie trafienia lub delegat multiemisji jest emitowane, gdy coś się dzieje.
‫Tak więc w przypadku, gdy nasza siatka pocisków w coś trafi, delegat będzie rozgłaszał do wszystkich klas,
‫które mają funkcję powiązaną z tym delegatem.
‫Natychmiast po wysłaniu tej emisji wszystkie te powiązane funkcje są wywoływane w odpowiedzi na tę
‫emisję.
‫To bardzo potężna funkcja Unreal Engine.
‫Pozwala nam to mieć to coś, co nazywa się delegatem, który czeka na zdarzenie, takie jak kolizja.
‫I wtedy.
‫A delegat zostanie rozgłoszony, w wyniku czego wszystkie powiązane funkcje będą wywoływane w odpowiedzi na rozgłoszenie.
‫Ponieważ wiele funkcji może być powiązanych z tym delikatnym, nazywamy to multiemisją.
‫Emituje do wielu klas, które mają przypisane do niego swoje funkcje.
‫Jak powiązać funkcję z tym delegatem?
‫Cóż, przy trafieniu komponentu jest kilka funkcji, które pozwalają nam to zrobić, z których jedna nazywa
‫się dodawanie dynamiczne.
‫Więc kiedy wywołujemy dynamiczną funkcję ADD, wszystko, co musimy zrobić, to przekazać w dwóch parametrach obiekt użytkownika, do
‫którego możemy to wykorzystać, oraz funkcję wywołania zwrotnego, która jest adresem jakiejś funkcji w naszej
‫klasie.
‫Kiedy więc uzyskamy dostęp do tego w delegatze trafienia komponentu i wywołamy funkcję dynamiczną add, możemy przekazać obiekt
‫użytkownika i wywołanie zwrotne.
‫A to spowoduje dodanie tego wywołania zwrotnego do listy wywołań zdarzeń trafień.
‫Teraz po trafieniu komponentu rozgłosimy ten delegat, w wyniku czego zostaną wywołane wszystkie powiązane z nim funkcje.
‫Aby więc powiązać się z tym delegatem, musimy utworzyć funkcję zwrotną.
‫Oto pocisk i chcielibyśmy funkcji zwrotnej dla zdarzenia trafienia.
‫Więc stwórzmy tutaj prywatną funkcję, która będzie nieważna.
‫I zamierzam po prostu nazwać to na hit.
‫Moglibyśmy to nazwać jak tylko chcemy, ale wydaje się to wystarczająco opisowe.
‫Teraz ta funkcja zwrotna musi mieć poprawną sygnaturę dla zdarzeń trafień, co oznacza, że
‫jej lista parametrów wejściowych musi być bardzo szczegółowa.
‫Pierwszy parametr wejściowy musi być typu „wskaźnik podstawowego komponentu” i nazywa się hit comp.
‫To jest składnik, który uderza.
‫W naszym przypadku nasza siatka pocisków będzie uderzać w różne rzeczy.
‫Następnym parametrem jest wskaźnik aktora o nazwie Inny aktor.
‫To będzie aktor, który został trafiony.
‫Następnym parametrem wejściowym jest kolejny wskaźnik do podstawowego komponentu o nazwie other comp.
‫To kolejny składnik, który został trafiony.
‫Więc jeśli trafimy na składnik siatki statycznej innego aktora, to będzie to składnik siatki statycznej.
‫Następny jest wektor F zwany impulsem normalnym.
‫Jeśli symulujemy fizykę, silnik fizyki zastosuje impuls w odpowiedzi na zderzenie.
‫A ten wektor f reprezentuje kierunek i wielkość tego impulsu.
‫I na koniec mamy parametr wejściowy typu const F hit result i jest to stała referencja i nazywa
‫się hit.
‫Tak więc, gdy zostanie wywołane przy trafieniu, będziemy mieć dostęp do wyniku trafienia, który zawiera jeszcze więcej informacji o
‫trafieniu.
‫Teraz, ponieważ wiążemy to z delegatem, musi to być funkcja U.
‫Więc oznaczymy to Twoją funkcją.
‫Teraz powinieneś znać swoją funkcję.
‫To tak jak ty, tylko dla funkcji, a nie zmiennych.
‫Tak bardzo ważne.
‫Aby to zadziałało, nasze wywołanie zwrotne musi być funkcją u.
‫Teraz zadeklarowaliśmy funkcję.
‫Przejdźmy dalej i zdefiniujmy funkcję.
‫Więc z powrotem w pociskach.
‫CP Tuż pod naszą funkcją tick, zdefiniujmy tę funkcję.
‫Damy jej treść funkcji i umieścimy nazwę klasy tuż przed nazwą funkcji, a teraz mamy
‫funkcję zwrotną.
‫Jesteśmy więc gotowi, aby powiązać tę funkcję przy trafieniu z naszym delegatem i musimy to zrobić na początku gry.
‫Robienie tego w konstruktorze jest zbyt wcześnie i czasami możesz napotkać problemy, takie jak brak
‫powiązania delegata.
‫Więc zrobimy to tutaj i zaczniemy grać.
‫Mamy więc naszą siatkę pocisków i użyjemy operatora strzałki, aby uzyskać dostęp do zmiennej odziedziczonej po tobie.
‫Komponent prymitywny wywoływany przy trafieniu komponentu i przy trafieniu komponentu ma funkcję add dynamic.
‫Co dziwne, autouzupełnianie nie zadziała w przypadku dodawania dynamiki, więc będziesz musiał wpisać
‫całą nazwę funkcji.
‫Jest to funkcja, której użyjemy, aby powiązać nasze wywołanie zwrotne po trafieniu komponentu i dodać tę funkcję
‫do listy wywołań.
‫Teraz najpierw potrzebujemy obiektu użytkownika, który będzie tym, ponieważ jest to klasa, w
‫której przywiązujemy funkcję do, a następnie potrzebujemy adresu do funkcji, która będzie adresem przy trafieniu.
‫Użyjemy więc adresu operatora i funkcji pocisk przy trafieniu.
‫Dzięki temu mamy powiązaną naszą funkcję i jesteśmy gotowi do generowania zdarzeń trafień.
‫Teraz możemy to przetestować za pomocą dziennika UEE i możemy użyć ostrzeżenia dziennika temp.
‫A za tekst możemy po prostu powiedzieć na trafienie.
‫A jeśli widzimy to w dzienniku wyjściowym, wiemy, że nasza funkcja przy trafieniu została wywołana, skompilujmy
‫to.
‫Więc mam otwarty dziennik wyjściowy.
‫Zamierzam nacisnąć play i wystrzelić pocisk, a przy trafieniu pojawi się moja wiadomość w dzienniku.
‫Więc to działa.
‫Teraz tylko na marginesie, jeśli przejdziemy do pocisku BP i wybierzemy siatkę pocisku w panelu szczegółów, możemy
‫przewinąć w dół do sekcji kolizji.
‫I tutaj widzimy, że ustawienia kolizji są ustawione tak, aby blokować całą dynamikę, a włączona kolizja jest
‫ustawiona na to ustawienie, w którym włączone są kolizje i fizyka.
‫Jest to konieczne w przypadku hitów.
‫Musimy mieć możliwość zapytania o zdarzenie trafienia.
‫I oczywiście fizyka pozwala silnikowi fizyki działać na siatkę pocisku.
‫Więc teraz, gdy powiązaliśmy się z delegatem on składnik hit z naszą funkcją on hit i umieściliśmy ogromny
‫dziennik, aby upewnić się, że działa, chciałbym, abyś zbadał tę funkcję trochę bardziej, abyśmy mogli zrozumieć
‫niektóre z tych parametrów wejściowych w naszej funkcji przy trafieniu.
‫Tak więc w funkcji przy trafieniu dodaj więcej dzienników YOUI.
‫Chciałbym, abyś wydrukował nazwy niektórych z tych parametrów wejściowych za pomocą funkcji git name.
‫Chciałbym, abyś użył dziennika YUI do wydrukowania nazwy hitu kompozycji, innego aktora i innej kompozycji, abyśmy mogli
‫zobaczyć nazwy obiektów, które uderzamy.
‫Będziesz używać formatu procent se, określ w makrze tekstowym dziennika E.
‫I tak dla przypomnienia, za każdym razem, gdy wywołujemy get name, musimy użyć gwiazdki podczas przekazywania tego ciągu do
‫makra dziennika YUI, na przykład, aby uzyskać nazwę innego aktora, którego nazwiemy innego aktora, pobierzemy nazwę i
‫wstawimy tę gwiazdkę na początku tylko po to, aby zwrócić ciąg w stylu C, którego oczekuje
‫log, gdy sformatujesz go za pomocą ciągu.
‫Zatrzymaj więc wideo i użyj Yui zaloguj się w naszej funkcji przy trafieniu, aby wydrukować teraz nazwy hitowej kompozycji, innego
‫aktora i innej kompozycji.
‫Dobra.
‫Więc tutaj, w pocisku CP, użyję tutaj twojego dziennika.
‫Skopiuję więc ten wiersz, w którym używam dziennika Yui, a dla ciągu napiszę hit comp procent s
‫i zaraz po tekście nazwę hit comp get name i potrzebuję tej gwiazdki do konwersji z ciągu F
‫na ciąg w stylu C.
‫Teraz użyję tej samej linijki, tylko zmienię tekst na inny aktor i tym
‫razem nazwiemy go imieniem innego aktora.
‫I na koniec, wydrukuję inne połączenie komputerowe, zdobędę nazwę na innym komputerze.
‫Więc skompilujmy i wróćmy tutaj w edytorze, zamierzam iść dalej, wcisnąć Odtwórz, wystrzelić pocisk
‫i to sprawdzę.
‫Widzimy, że trafienie to siatka pocisków.
‫Pamiętaj, że powiedzieliśmy, że to jest komponent wykonujący uderzenie, czyli nasz pocisk
‫pociskowy, a zobaczysz, że używa nazwy, którą przypisaliśmy temu komponentowi podczas tworzenia domyślnego podobiektu.
‫Jest to więc jedna z tych sytuacji, w których używa się tej nazwy.
‫Teraz zobaczysz, że jest napisane, że inna wada aktora podkreśla zero.
‫A to dlatego, że ten statyczny aktor siatki, który jest wadą, ma nazwę wada podkreślona przez zero.
‫Czasami silnik umieszcza liczbę na końcu swojej wewnętrznej nazwy dla aktorów i komponentów, i
‫zobaczysz, że to samo dzieje się, gdy wypisujemy inną kompozycję.
‫Aktor siatki statycznej z wadami ma składnik siatki statycznej, a jego nazwa to zero składnika siatki statycznej.
‫To daje nam trochę więcej informacji o tych parametrach wejściowych w naszej funkcji zwrotnej przy trafieniu.
‫Jest to przydatne, ponieważ mamy dostęp do tych obiektów w C++, jeśli chcielibyśmy coś zrobić w odpowiedzi na
‫zdarzenie trafienia.
‫Podsumowując, dowiedzieliśmy się o zdarzeniach trafień i ich implementacji jako delegatów multiemisji, a także dowiedzieliśmy się,
‫jak one działają.
‫Stworzyliśmy funkcję o nazwie On Hit and Bound, która jest funkcją delegata po trafieniu komponentu, który
‫nasza siatka pocisków odziedziczyła po Twojej klasie podstawowego komponentu.
‫Teraz nie zniszczyliśmy pocisku przy trafieniu, ale teraz wiemy, że możemy to łatwo zrobić, ponieważ mamy
‫tę funkcję zwrotną i możemy umieścić w tej funkcji logikę, taką jak zniszczenie pocisku.
‫Zajmiemy się tym w przyszłym filmie.
‫Na razie poklep się po plecach, ponieważ jest to jeden z bardziej złożonych obszarów Unreal Engine C++, których do
‫tej pory się nauczyłeś.
‫Do zobaczenia w następnym filmie.