Unreal Engine 4.27.2, XCode 14, MacOS i LayerNames

Po pierwsze – kupiłem nowego MacBook Pro 14 (10/16 rdzeni, 16GB RAM, 1TB dysk). Do robienia muzyki, ale – apki pod iOS same się nie zrobią więc leciwy iMac 27 5K służy już wyłącznie do oglądania YT.

Pierwszy zonk to Unreal Engine. Poinstalowałem jak matka Apple kazała. Nowy XCode. Potem stwierdziłem, że przecież ostatnio na iMacu kompilowałem sobie zdalnie z Visual Studio Code na PCcie. Hardcore, ale działało. No to dawaj, instalujemy. Visual Studio Code, wersja dla silikonowych. Mono plus inne wynalazki.

No to testowo – pusty projekt – ale C++. Jest ZONK. Nie kompiluje się już przy tworzeniu projektu…

I tutaj muszę wspomnieć, że zrobiłem chwilę wcześniej dżejmsbłąda. Zrobiłem instalki na nowym sprzęcie, cośtam odpaliłem – niby działa. No i zrobiłem update systemu do Monterey na starym iMac’u tym samym tracąc stabilne rozwiązanie jakie działało. No – ale jak się spaliło mosty, to trzeba zbudować lotnię, o lotnisko będziemy się martwić później. A potem zachciało mi się odpalić stary projekt w C++.

Oczywiście jak zwykle internet jest pełen gównoteorii, od downgradowaniu XCode po teorie spiskowe pt. na MacOS z procesorami Sillicon to nie będzie działać. W pierwszej chwili pomyślałem – nowy XCode 14, bez poprawek, pewnie Apple coś zwalił. No cóż… Wychodzi na to, że po drugiej stronie tej monety jest Epic 🙂

Ale po kolei.

Od czego zaczynamy – mamy zainstalowane XCode, VisualStudioCode, pluginy do C++, Intellisense, mamy w systemie Mono, zainstalowaliśmy ostatnią wersję Unreal Engine 4 – czyli z numerkiem 4.27.2 i zrobiliśmy pusty projekt C++ bez startowych assetów o unikalnej nazwie MyProject. Tzn. usiłowaliśmy zrobić, gdybyśmy nie zaznaczyli, że chcemy nie blueprinty tylko C++ to projekt by się prawidłowo utworzył i otworzył w edytorze, ale w momencie dodania dowolnej klasy C++ wrócilibyśmy do tego samego punktu czyli przy otwieraniu projektu mamy takie okienko z pozornym wyborem.

Pozornym, bo jak klikniemy NO to nie otworzymy projektu. Jak klikniemy YES to też go nie otworzymy 😀

Co tak naprawdę się dzieje? Mój MacbookPro 14 jest na tyle szybki, że wyłapanie tego błędu w logu potrzebowało ode mnie sporej dozy refleksu (a logu mi się nie chciało szukać).

W zasadzie na tym screenie mamy odpowiedź. Za nim ją wskażę to tylko z kronikarskiego obowiązku – nie zbudował się katalog /binaries i /intermediate, więc nic nie odpalimy. To jest ta sama sytuacja, gdy otwieramy projekt bez tych katalogów i Unreal musi sobie je od nowa zbudować, nota bene jeżeli generujemy builda z edytora to de facto jeżeli zaznaczyliśmy opcję full rebuild to te katalogi i pliki w nich też są od nowa tworzone. Jeżeli potrzebujecie doczytać o tym, to kieruję do źródła czyli tutaj.

Unreal zachęca do przejścia w tryb prac ręcznych – posłuchajmy go – do dzieła. Tak naprawdę chodzi o uporządkowanie przy kompilacji, wyrzucanie nieużywanych zmiennych. W naszym przypadku -nie wiem dlaczego – dotyczy to tablicy LayerNames. Unreal w tym przypadku jest tak fajny, że podaje nam co powinniśmy dodać – chodzi o ciąg, który jest tak naprawdę poleceniem dla kompilatora – “-Wno-unused-but-set-variable”. Tych “unused” jest w sumie więcej

-Wno-comment 
-Wno-unused-function
-Wno-unused-parameter
-Wno-unused-variable
-Wno-unused-result
-Wno-extra
-Wno-multichar
-Wno-unused-label
-Wno-unused-local-typedefs
-Wno-unused-value

Parametry te są na tyle opisowe w swoich nazwach, że pozwolę sobie ich nie tłumaczyć – nas natomiast interesuje teraz nasz:

-Wno-unused-but-set-variable

Skoro Unreal Engine wymaga, aby z tym zrobić porządek – to zróbmy. Potrzebujemy dodać dwie linijki do plik MyProjectEditor.Target.cs w katalogu Source naszego projektu.

Musimy na ich końcu, przed nawiasem klamrowym zamykającym ciąg Public dodać takie dwie linijki:

bOverrideBuildEnvironment = true;
AdditionalCompilerArguments = "-Wno-unused-but-set-variable";

Dla czytelności zrobiłem odstęp pomiędzy oryginalną treścią a nowododaną. Istotne – musimy wstawić ten kod do obu plików, w to samo miejsce, na końcu kodu.

No dobrze, otwieramy ponownie projekt – w liście projektów może być niewidoczny, klikamy na more i wtedy dopiero możemy go wskazać. Znowu pytanie o przebudowanie projektu, ale my już odrobiliśmy lekcję. Jeżeli dysponujecie wersją źródłową/kompilowaną Unreal Engine to możecie równie dobrze wyedytować plik Material.h (w katalogu /Engine/Source/Runtime/Engine/Classes/Materials/) i zmienić pod w okolicach linii 1278 najpierw wyszukując poniższy kod:

#if WITH_EDITOR
const TArray<FText>* LayerNames = &LayersExpression->GetLayerNames();
#endif

dodać definicję jakiejkolwiek stałej, która skorzysta z tej definicji np.

const TArray* thisIsAnything = LayerNames;

takie rozwiązanie spowoduje, że każdy kolejny projekt nie będzie musiał być tak “naprawiany” na start 🙂

Tymczasem – dopłyńmy do brzegu z naszym pustym projektem:

tik tak tik tak i mamy to:

To jeszcze tylko dla pewności – zrobimy sobie nową klasę, otworzymy projekt w VisualStudioCode, cośtam sobie dodamy testowo (np. jedną zmienną) i skompilujemy. Stare przysłowie pszczół mówi – nie ma nic lepszego niż subsystem.

U mnie działa 🙂 Życzę w logu komunikatu:

ExitCode=0
UATHelper: Packaging (Mac): ARCHIVE COMMAND COMPLETED
UATHelper: Packaging (Mac): BUILD SUCCESSFUL
UATHelper: Packaging (Mac): AutomationTool exiting with ExitCode=0 (Success)

PS. nie nazywajcie projektu ‘test’, bo… to jest projekt, który się nie skopiluje 😀