Jak převést projekt z Unity 4 do Unity 6
Jak dostat projekt z Unity 4 do Unity 6 bez ztráty scén: převod na text přes Unity 2019.4, port UnityScriptu do C# se zachováním GUID a obnova starého HUD.

Projekt z Unity 4 neotevírejte přímo v Unity 6 a hlavně v něm nic neukládejte. Unity 6 staré binární scény načte jen částečně a uložením ztrátu potvrdí; bezpečná cesta vede přes Unity 2019.4, které starý formát umí přečíst i zapsat jako text, a teprve potom do Unity 6.
Týká se to projektů, které mají scény a prefaby uložené v binárním formátu a skripty v UnityScriptu, jazyce podobném JavaScriptu, který Unity kdysi podporovalo vedle C#. Postup ukážeme na hře Onager, fyzikální hře s katapultem napsané v Unity 4.1.2 a v UnityScriptu. Projekt měl 126 skriptů, 75 scén a 78 prefabů, po převodu běží na Unity 6000.5 s URP (Universal Render Pipeline) a je zdarma na App Store i Google Play.
Co se stane, když projekt otevřete v Unity 6
Nejjednodušší přístup je otevřít projekt v Unity 6 a přepnout serializaci na Force Text, tedy na ukládání assetů jako čitelný YAML. To ale není překlad souborů. Unity každý asset načte přes svůj importér a zapíše zpět jako YAML, takže všechno projde loaderem Unity 6. Ten u každé scény hlásí, že našel Transform bez GameObjectu, a „visící“ komponentu smaže. Uložení to udělá natrvalo.
Rozsah ztráty se dá změřit nástrojem binary2text, který je přiložený k editoru a čte serializovaný soubor bez importéru. V Onageru jsme jeho výpis porovnali s výsledným YAML a počítali jen komponenty, které zmizely z GameObjectů, jež přežily:
| Komponenta | Ztraceno |
|---|---|
| Camera | 130 |
| ParticleSystem | 132 |
| Transform | 167 |
| BoxCollider | 104 |
| Rigidbody | 100 |
| GUITexture / GUIText | 303 / 179 |
Bez ztráty nebyla ani jedna ze 75 scén. Zmizely celé kamery pro HUD a hlavní kamera dostala novou, výchozí. Důležité je, že škoda vzniká už při načtení, ne při uložení. Dokud projekt není převedený, nesmí ho Unity 6 uložit, ani jednu scénu, ani jeden prefab.
Krok 1: Zaznamenejte původní stav
Než na cokoli sáhnete, vyfoťte si každou scénu a pro každou scénu si nástrojem binary2text uložte výpis původního souboru. Podle výpisu budete v kroku 3 kontrolovat kamery a v kroku 5 obnovovat HUD. Původní binární soubory nechte v historii gitu, nemažte je.

Krok 2: Převod na text přes Unity 2019.4
Unity 2019.4 je poslední editor, který formát z Unity 4.1 umí přečíst i zapsat. Převod dělejte se zavřeným editorem v samostatné kopii repozitáře:
- Verze projektu. V souboru s verzí projektu nastavte původní verzi (u Onageru 4.1.2), aby editor zvolil cestu pro starý projekt. Unity ji při otevření přepíše, stačí, že platí při prvním importu.
- Prázdné balíčky. Vyprázdněte seznam závislostí balíčků. Jedna chyba kompilace znamená, že nebude fungovat žádná položka menu z editorových skriptů, a to vypadá, jako by se menu vůbec neobjevilo.
- Import od nuly. Smažte složku Library a nechte projekt naimportovat.
- Force Text a vynucené přepsání. Unity 2019.4 po změně na Force Text existující soubory samo nepřepíše. Je potřeba to vyvolat funkcí pro reserializaci assetů, a to jen assetů, ne i jejich meta souborů. Přepsání všech meta souborů způsobí, že Unity 6 potom importuje stále dokola.
Jedna past je v gitu. Pokud v nastavení atributů gitu označíte scény jako text s koncem řádku LF, git z binárních scén při ukládání do repozitáře vyhodí bajty, které vypadají jako konec řádku. V Onageru to poškodilo osm scén. Na assety Unity atribut pro konce řádků nedávejte, Unity stejně zapisuje LF.
Krok 3: Výsledek ověřte v editoru, ne čtením YAML
Čtení převedených souborů vede k sebejistým a nesprávným závěrům. Zkrácené záznamy instancí prefabů vypadají jako ztráta, stejně jako kamera, která se jen přesunula do prefabu. Rozhoduje to, co Unity postaví v paměti. Každou převedenou scénu otevřete a její kamery porovnejte s výpisem originálu z kroku 1.
V Onageru mělo po převodu všech 75 scén stejné kamery i jejich pořadí. Ztratilo se jen to, co žádný dnešní editor nezná: 569 GUITexture, 179 GUIText a staré částicové systémy, které Unity odstranilo v roce 2018.
Krok 4: UnityScript do C# se stejným GUID
Unity ukončovalo UnityScript postupně od verze 2017.2, takže ruční port do C# je jediná cesta. Scény odkazují na skripty přes GUID, jedinečný identifikátor, který Unity ukládá do meta souboru každého assetu, a hodnoty polí ukládají podle jména pole. Když to při portu dodržíte, všechny odkazy se připojí samy:
pro každý skript X v UnityScriptu:
vytvoř C# skript s třídou přesně jménem X
zkopíruj GUID z meta souboru starého skriptu do meta souboru nového
veřejná pole: stejné jméno, stejný typ, i s překlepy
nic nepřejmenovávej, dokud projekt neběží
V Onageru se takto po portu všech 126 skriptů připojilo 12 935 komponent v 73 scénách a v Inspectoru zůstaly všechny nastavené hodnoty.
Textovým hledáním v projektu se nedá zjistit, které skripty se používají. Binární prefab má GUID uložený jako bajty, ne jako text. V Onageru tak vypadalo nepoužívaných jednadvacet skriptů a všechny byly živé. Dejte si pozor i na pozůstatky starších pokusů o port: jeden prefab dřevěné kostky ukazoval na dva skripty z takového pokusu a jen kvůli němu chybělo 1 140 komponent. Pokud je potřeba v binárním souboru změnit GUID, vyměňte ho přímo v bajtech, šestnáct za šestnáct, aby se soubor neposunul.
Krok 5: Obnovte HUD z původních binárních scén
GUITexture a GUIText v Unity 6 nejsou a s nimi zmizí celý HUD, který na nich stál. Kreslit ho znovu není potřeba. Původní binární scény z historie gitu binary2text přečte bez ohledu na to, jestli třídy ještě existují. Vytáhněte z nich každý obrázek a text HUD s texturou, barvou, pozicí a zarovnáním a skriptem je vraťte na stejné objekty ve scénách. V Onageru to bylo 577 obrázků a 180 textů.
Takto se zachrání i texty, které nikde jinde nejsou. V Onageru to bylo 111 textů: všechny titulky tutoriálů a celá tabule s kredity. Při psaní HUD od nuly byste si je museli vymyslet. Při přenosu barvy počítejte s jednou věcí, kterou dokumentace neříká: staré GUITexture barvu při vykreslení zdvojnásobovalo. Všech 577 obrázků mělo barvu přesně 0,5, takže šedá znamenala bílou.
Po převodu: staré triky nahraďte
Staré projekty často obcházely omezení tehdejšího Unity a tyto obezličky se po převodu vyplatí předělat:
- Odraz v podlaze. Onager měl lesklou podlahu bez skutečného odrazu. Pod podlahou stál druhý, zrcadlově otočený svět: kopie každého objektu, jejíž pozici skript každý třetí snímek zkopíroval z originálu, v jednom levelu 50 až 70 klonů. Nahradit se to dá jednou kamerou navíc, která odraz kreslí v polovičním rozlišení. Odrážejí se pak i částice a trosky, což klonovaný svět neuměl.
- Míření. Pokud náhled dráhy předpovídá, kam střelu pošle síla přidaná v prvním fyzikálním kroku, střela dopadne jinam než značka. Spolehlivější je vypočítat rychlost jednou, náhled nakreslit přesně z ní a střele ji přiřadit přímo.
- Výkon. Měřte na slabém telefonu. Na Motorole G52 klesl Onager z 20 na 6 fps jen kvůli shaderu stěn, víc než rozlišení, stíny a odraz dohromady. Na nízkých a středních detailech proto mají stěny jednodušší materiál.
Pokud řešíte fyziku tisíců objektů v současném Unity, podívejte se i na falešný ragdoll pro tisíce nepřátel v Unity DOTS. Jak po převodu přidat staré 2D hře glow a 2D světla v URP, popisuje samostatný návod.
Co postup nevyřeší
Komponenty, které dnešní Unity nezná, se nepřipojí. GUITexture a GUIText je třeba obnovit jako v kroku 5, staré částicové systémy se ztratí. Jména tříd a polí zůstanou přesně jako v původním projektu, i s překlepy a v jazyce, ve kterém je někdo kdysi napsal. Scény se na ně vážou jménem, takže přejmenování má smysl dělat jen přes editor, který odkazy přepíše sám.
Pokud máte starý projekt v Unity a potřebujete ho dostat do současné verze, napište nám.


