Nicht eingeloggt
Registrieren

MyLevel - Das map-interne Texture/Actors/Sound/Music-Package

(I) Vorwort

Um es gleich vorweg zu sagen: Dieses Tutorial baut auf über acht Jahren Mapping-Erfahrung meinerseits auf und ist dementsprechend geschrieben. Das heißt im Klartext, ich werde zwar auf die allgemein bekannten Eigenschaften des „MyLevel“-Packages eingehen, weil das einfach zum Kontext gehört. Allerdings gehen gerade die späteren Kapitel auch deutlich darüber hinaus, man sollte sich also schon mehr als nur durchschnittlich mit dem UEd 2 auskennen, sonst könnte das folgende recht harte Kost werden.


So... Wer durch diese Einleitung noch nicht vertrieben wurde, fragt sich jetzt möglicherweise, warum ich dieses Tutorial überhaupt schreibe. Ganz einfach aus dem Grund, aus dem so ziemlich alle Tutorials geschrieben werden: Um immer wiederkehrende Fragen mit einem einzigen Link beantworten zu können. :zwinker:
Ich denke dabei an Fragen wie „Muss ich MyLevel speichern?“; „Wie bekomme ich Actors in MyLevel?“; „Ist MyLevel besser als normale Packages?“; oder ganz grundsätzlich „Was ist MyLevel überhaupt?“
Soviel nur dazu, jetzt kommen wir mal zum praktischen Teil...


(II) Grundlegende Eigenschaften von „MyLevel“

Das wichtigste zuerst: „MyLevel“ ist, wie schon im Vorwort kurz angeschnitten, ein Package, also gewissermaßen ein Verzeichnis, in dem verschiedene Bestandteile einer Map gespeichert werden können. Allerdings ist „MyLevel“ nur sehr bedingt mit gewöhnlichen Packages wie z.B. „Ancient.utx“ oder „AmbOutside.uax“ vergleichbar.
Zum einen kann man nämlich in „MyLevel“ quasi alles speichern, seien es Texturen, Sounds, Music oder Actor Classes, während eine utx-Datei beispielsweise ausschließlich Texturen beinhalten kann.


Abb. 1: Sowohl Texture- als auch Sound-Browser enthalten „MyLevel“.


Der zweite, noch bedeutendere Unterschied, ist die Art, wie gespeichert wird, nämlich in die Map-Datei selbst, und nicht in ein externes Package, wie man es sonst kennt. Das bedeutet natürlich auch, dass jede Map ihr eigenes „MyLevel“ Package haben kann. Näheres dazu unter (III).


(III) Import von einzelnen Objekten und speichern des „MyLevel“-Packages

Etwas generelles zu diesem Kapitel: Unter „Objekten“ verstehe ich hier zu importierende Texturen (*.pcx), Sounds (*.wav) und Musikstücke (*.mod, *.it und ähnliche). Ich gehe nicht näher darauf ein, welche Kriterien die Dateien erfüllen müssen, dazu gibt es massig andere Tutorials. Wenn ich hier einen Import erkläre, dann anhand von Texturen, einfach weil selbige am häufigsten benötigt werden, Sounds und Musik funktionieren analog, zu Actors komme ich erst später (unter (VI)).

Also zum Import: Dieser funktioniert zunächst einmal genau so, wie man es kennt, man importiert z.B. eine Textur über den Texture-Browser, File -> Import. Wenn man seine pcx-Datei ausgewählt hat, gibt man im folgenden Popup-Fenster als Package „MyLevel“ an (Schreibweise beachten!!), die Group ist wie immer egal, der Name ebenso.


Abb. 2: Das muss im Import-Fenster stehen.


Soweit klar eigentlich, die Textur ist nun im „MyLevel“-Pack. Damit sie aber da drin bleibt, muss man komplett anders vorgehen als bei herkömmlichen Packages: Zunächst muss „MyLevel“ nicht gespeichert werden, oder genauer gesagt, man darf es auf keinen Fall speichern!! Das liegt daran, dass, wie der Name schon vermuten lässt, „MyLevel“ das Package „meines Levels“ bzw. „meiner Map“ ist, also automatisch zusammen mit der Map gespeichert wird, und zwar in die Map-Datei (*.unr) selber! ABER: Egal was man in „MyLevel“ importiert, es wird erst dann mit der Map gespeichert, wenn man es mindestens einmal verwendet hat!

Um das etwas anschaulicher zu machen, ein Beispiel: Du importierst eine Textur „Beispiel.pcx“ und gibst im Import-Fenster „Package: MyLevel“ an, die Textur erscheint nun wie gewünscht im Texture-Browser.


Abb. 3: Die Textur namens „Beispiel“ erscheint in „MyLevel“.


Damit sie jetzt im „MyLevel“-Package bleibt, musst du sie noch irgendwo in der Map platzieren, also z.B. einen Brush mit dieser Textur adden oder dergleichen. Danach speicherst du die Map (wie schon gesagt: Nicht das Package!!), und fertig. Wenn du jetzt den UEd schließt, wieder öffnest, und deine Map neu lädst, ist die Textur immer noch im „MyLevel“. Der Vorteil liegt auf der Hand: Im Gegensatz zur konvetionellen Methode (utx-Datei) hast du jetzt kein externes Package, das du beim Veröffentlichen der Map mitliefern musst, es bleibt also alles übersichtlicher.

Noch ein Beispiel: Wie oben schon angesprochen, kann man in „MyLevel“ alles importieren. Nehmen wir jetzt an, du willst in deiner Map genau eine eigene Textur, einen Sound und ein Musikstück verwenden. Nach herkömmlicher Methode bräuchtest du jetzt vier Dateien: *.unr (die Map selber), *.utx, *.uax, *.umx. „MyLevel“ dagegen speichert nun alles in deine Map, also bleibt’s bei einer einzigen unr-Datei.

Was hier noch zu erwähnen wäre: Nur bei den Texturen sieht man das „MyLevel“-Package direkt nach dem Importieren, bei Sounds und Music muss man nach dem Import erst noch irgendeine beliebige uax- bzw. umx-Datei im entsprechenden Browser öffnen, damit dieser aktualisiert wird, erst dann ist „MyLevel“ sichtbar. Warum? Keine Ahnung, ist halt so.


(IV) Löschen des „MyLevel“-Packages


Diesen Punkt erwähne ich nur am Rande, weil er sich eigentlich aus der vorherigen Eigenschaft, dass „MyLevel“ nicht gespeichert wird, von selbst ergibt: Es kann dementsprechend auch nicht „von Hand“ gelöscht werden. Da man wohl kaum willentlich ein Package löscht, das für die Map benötigt wird, ist diese Tatsache hauptsächlich deshalb interessant, weil man „MyLevel“ eben im Gegensatz zu exterenen Packs auch nicht „aus Versehen“ löschen kann. Wie schon vorher gesagt, jede verwendete Textur ist automatisch in „MyLevel“ verankert, und zwar genau so lange, wie sie verwendet wird. Umgekehrt heißt das natürlich auch, wenn man eine Textur nicht mehr verwendet (also etwa jeder Surface in der Map, die einmal mit dieser Textur belegt war, eine andere zuweist), dann wird die (nicht mehr benötigte) Textur automatisch aus dem Pack gelöscht. Der Vorteil ist klar, man spart Speicherplatz.
Um nun das gesamte „MyLevel“-Package wieder los zu werden, müsste man also seinen gesamten Inhalt aus der Map verbannen. Warum man das tun sollte weiß ich nicht, aber wie gesagt, ich wollte es eben erwähnen.


(V) Import von kompletten Paketen – Der Befehl „obj load“

Wer konsequent bis hier hin gelesen hat, wird möglicherweise schon langsam anfangen, sich zu langweilen, weil bisher ja wirklich das meiste allgemein bekannt war. Aber keine Sorge, jetzt wird’s etwas interessanter, wir kommen zum Import von kompletten Packages nach „MyLevel“.

Ich fange hier mal mit einem Beispiel an, damit gleich klar ist, was dieses Vorgehen bringen soll: Nehmen wir an, du willst eine Map mit Costum-Textures erstellen, beispielsweise, wie könnte es anders sein, mit „richrig.utx“. Dieses Pack müsstest du jetzt beim Veröffentlichen der Map mitliefern, eben weil es Costum (also nicht UT-Standart) ist. Allerdings hättest du dadurch schon wieder ein Pack mehr in deinem Zip-Archiv, selbiges wäre also nicht mehr so schön aufgeräumt wie ein Zip, das nur die Map enthält. Außerdem müsstest du das vollständige utx-Paket mitliefern, auch wenn du garnicht alle Texturen verwendest, also wäre das Archiv auch noch größer als nötig.
Klar, „MyLevel“ bietet sich hier mal wieder an. Man könnte nun ganz altertümlich jede Textur aus „richrig.utx“ einzeln ex- und in „MyLevel“ wieder importieren, aber das wäre extrem umständlich, und hätte auch noch andere Nachteile:
Erstens würden dabei alle Spezial-Flags (Masked etc.) verloren gehen, zweitens wären alle Detail-Textures weg, und drittens würde man so mit jeder Art von dynamischen Texturen (Water-Paint etc.) eh nicht weit kommen: Beim Export-Versuch einer Water-Texture oder dergleichen stürzt der Ed ab.


Abb. 4: Das kommt dabei raus, wenn man eine dynamische Textur exportieren will.


Also, insgesamt eine schlechte Idee. Und hier kommt nun „obj load“ ins Spiel:
Der Befehl, um den es sich hier dreht, lautet vollständig

Code:
obj load file=*.* package=MyLevel

und ist, wie alle UEd-Befehle, in die Command-Console einzugeben.
*.* steht dabei fĂĽr das zu importierende Package, im genannten Beispiel sieht der Befehl also so aus:

Code:
obj load file=richrig.utx package=MyLevel

Abb. 5: Hier nochmal im Bild: Der „obj load“ Befehl.


Was der Befehl macht, ist ja eigentlich selbsterklärend: Er kopiert den gesamten Inhalt von „richrig.utx“, also alle Texturen inklusive der Special-Flags, Details etc. nach „MyLevel“. Wenn man also nach dem Ausführen des Befehls in den Textures-Browser schaut, sieht man dort das „MyLevel“-Pack, und darin alle aus „richrig“ bekannten Texturen! Man kann nun also mit „MyLevel“ mappen, als wäre es „richrig“, nur dass man eben beim Veröffentlichen der Map kein externes Pack mitliefern muss.


Abb. 6: Alle „richrig“ Texturen befinden sich jetzt in „MyLevel“.


Soviel zum Texturen-Beispiel, und wer aufgepasst hat, weiĂź schon, was jetzt kommt: Ich habe bewusst *.* geschrieben, und nicht *.utx, weil auch die Dateiendung von Fall zu Fall variieren kann, sprich, wenn man z.B. den Befehl

Code:
obj load file=AmbAlien.uax package=MyLevel

benutzt, importiert man alle Sounds aus „AmbAlien“, genauso funktioniert es auch mit umx-Paketen. Wichtig ist dabei nur, dass die zu importierenden Pakete da liegen, wo sie hingehören, also utx-Dateien im Textures-Ordner, uax im Sounds-Ordner, umx im Music-Ordner. Hierzu gilt selbiges wie oben, „MyLevel“ wird im Sounds- und Music-Browser erst sichtbar, wenn man danach noch ein beliebiges Pack öffnet.

Ein Punkt sollte hier noch erwähnt werden: Wenn man irgendetwas mit Hilfe dieses Befehls in „MyLevel“ bringt, dann sollte man das tun, bevor man die eigentliche Map öffnet! Da das frisch importierte „MyLevel“ beim Laden der Map erhalten bleibt, gibt es hier auch keine Konflikte, selbst wenn die Map, die man öffnet, schon andere Objekte in „MyLevel“ enthält. Jetzt fragen sich sicher alle, warum man das in dieser Reihenfolge machen soll. Ganz einfach, weil der Editor, wenn man den Befehl bei einer schon geöffneten Map anwendet, in seltenen Fällen abstürzt. Und um der nächsten Frage vorzubeugen: Nein, ich weiß nicht, wann das genau vorkommt, aber es ist mir schon passiert, deshalb die Warnung.



(VI) Spezielle Anwendung von „obj load“: Import von Actor-Classes

Wer nun mit seinen Überlegungen an dem Punkt angekommen ist, wo er sich fragt, warum ich bisher so konsequent dem Import von Actors (bzw. u-Dateien) aus dem Weg gegangen bin, obwohl das doch ganz genau so funktionieren müsste, dem kann ich sagen: Völlig richtig. Es funktioniert wirklich exakt wie oben beschrieben. Also, um z.B. eine u-Datei aus dem System-Ordner namens „Temp.u“ zu importieren (momentan muss man sich unter diesem Namen noch nichts vorstellen können, ich komme aber später nochmal darauf zu sprechen), lautet der Befehl natürlich wie folgt:

Code:
obj load file=Temp.u package=MyLevel

Der Grund, warum der Import von u-Dateien ein eigenes Kapitel bekommt, ist trotzdem naheliegend: Weil die Möglichkeiten, die sich so bieten, einfach sehr vielfältig sind, und ich deshalb einige Beispiele bringen werde, die den Rahmen von Kapitel (V) gesprengt hätten.

Schon allein der Aufbau einer u-Datei unterscheidet sich nämlich wesentlich von dem einer utx, uax oder umx. Während beispielsweise ein utx-Package nur Texturen enthalten kann, ist in einer u-Datei quasi alles möglich: Von Decos (Bäume etc.) über komplett animierte Pawns bis hin zu neuen Triggers oder neuen Mover-Typen. Wie ich kürzlich gelernt habe, kann ein u-Package sogar die Funktionen der anderen Packs übernehmen, also auch Texturen, Sounds und Musik enthalten (Beispiel: „Botpack.u“), aber das ist im Mapping-Alltag nicht von allzu großer Bedeutung, und wird deshalb hier nicht weiter ausgeführt. Außerdem, wie man Texturen u.ä. auf halbwegs „normalem“ Wege nach „MyLevel“ bringt, wurde ja weiter oben schon beschrieben.

Ich unterscheide deshalb bei den in u-Dateien vorkommenden Objekten primär zwischen zwei Gruppen:

So, das war jetzt eigentlich alles nur Vorbemerkung...
Kommen wir zum eigentlichen Import, zunächst einmal von Scripts:
Nehmen wir an, du willst eine Unterart des „Trigger“ in deiner Map verwenden, den irgendwann mal ein kluger Kopf für eine andere Map oder Mod gescripted hat.
Als Beispiel verwende ich den „DispatcherPlus“ aus dem Pack „NBSpecialsUT.u“. Was man mit diesem „DispatcherPlus“ anfangen kann, tut nichts zur Sache, ist ja auch nur ein Beispiel.
Man importiert also wie gewohnt „NBSpecialsUT“ über den „obj load“ Befehl, also:

Code:
obj load file=NBSpecialsUT.u package=MyLevel

Im Actor-Browser ist nun wie erwartet unter „Trigger“ der erwähnte „DispatcherPlus“ zu finden, zusammen mit vielen anderen neuen Scripts, eben allem, was in „NBSpecialsUT“ so drin ist.


Abb. 7: Der „DispatcherPlus“ ist in „MyLevel“, allerdings auch noch jede Menge andere Scripts.


Da du aber nur den „DispatcherPlus“ in „MyLevel“ haben (und behalten!) willst, gehst du genauso vor, wie schon bei den Texturen (Punkt (III)): Du platzierst mindestens einen „DispatcherPlus“ in der Map, damit ist er in „MyLevel“ verankert. Wenn du jetzt den Ed schließt, wieder öffnest, und die Map neu lädst, siehst du den Effekt: Im Actor-Browser ist unter „Trigger“ immer noch der „DispatcherPlus“ aufgelistet, alle anderen „neuen“ Scripts sind verschunden.


Abb. 8: Wie erwartet, ist nur der „DispatcherPlus“ geblieben.


Du kannst jetzt also ganz einfach den „DispatcherPlus“ verwenden, ohne gleich das ganze „NBSpecialsUT.u“ Pack mit der Map zusammen veröffentlichen zu müssen. Bei „NBSpecialsUT.u“ wäre das zwar noch annehmbar, aber es gibt auch u-Dateien mit mehreren MB, da ist man so schon besser beraten.

Kommen wir zum zweiten Punkt, dem Import von Meshes:
Hier zeigt sich eigentlich erst die wahre Genialität des „obj load“ Befehls. Denn während man alles bisher beschriebene auch irgendwie anders nach „MyLevel“ bekommen hätte (sogar Scripts, selbige könnte man theoretisch mittels Copy&Paste in den Script-Editor einfügen), ist beim „MyLevel“-Import von Meshes „obj load“ wirklich die einzige Möglichkeit!
Die Vorgehensweise ist natürlich immer noch die gleiche wie bisher: „obj load“ mit dem Package, in dem sich der zu importierende Mesh befindet, ausführen, fertig. Naja, fast.
Der Mesh ist jetzt zwar in „MyLevel“, aber wie benutzt man ihn? Dazu muss man sich vorstellen, dass ein Mesh nur die „Erscheinungsform“ einer Class ist, so besteht etwa ein Baum nicht nur aus dem Tree-Mesh, er enthält noch jede Menge weiter Informationen, z.B. Drawscale, Skins, Collision, Event... Also alles, was man auch in den Properties einer Deco-Class sehen kann.


Abb. 9: Der Mesh selbst ist nur eine von vielen Einstellungen der Deco-Class.


Dementsprechend ist es logisch, wie man den importierten Mesh verwendet: Man sucht im Actor-Browser unter „Decorations“ nach der entsprechenden Class, und platziert diese in der Map. Da der Mesh fester Bestandteil der Class ist (er definiert immerhin ihr Aussehen!), wird er so in „MyLevel“ verankert.

Als Beispiel nehme ich hier eine sehr spezielle Situation, die aber (zumindest bei mir) recht häufig vorkommt: Den Import eines mit dem Programm „MeshMaker“ selbst-erstellten Meshes. Die Funktionsweise des „MeshMakers“ ist eigentlich selbsterklärend, aber eine kurze Erklärung schadet nicht, vor allem, weil ein Schritt dabei von großer Bedeutung ist.
Man öffnet zunächst mit dem „MeshMaker“ eine selbstgebaute t3d-Datei (wie das geht, sollte klar sein, ansonsten verweise ich mal wieder auf andere Tutorials :zwinker, die man zum Mesh machen möchte, und folgt grob gesagt den Anweisungen, bis „Step Two“. Dort setzt man den Haken bei „Create a ready-to-use decoration“, gibt als Package „Temp“ an (man kann es auch anders nennen, aber so erklärt sich der Name im oben verwendeten Beispiel!), und schließt den Vorgang mittels Klick auf „Next“ ab.


Abb. 10: So muss „Step Two“ im „MeshMaker“ aussehen.


Damit hat man seinen eigenen Mesh erstellt, dieser ist jedoch vorerst im Pack „Temp.u“, und noch nicht in „MyLevel“. Aber wie es weitergeht, sollte klar sein: UEd öffnen, „obj load“ Befehl für „Temp.u“ ausführen, der Mesh (bzw. die dazugehörige Actor-Class) ist nun im Actor-Browser unter „Decorations“ verfügbar, und befindet sich im „MyLevel“ Package!
Alles weitere dürfte auch klar sein: Map öffnen, Deco-Class setzen, Map speichern. Da nun die Class in der Map verwendet wird, ist sie fester Bestandteil von „MyLevel“, und der Mesh, der ihr Aussehen beschreibt, dementsprechend ebenso. So, nun wird auch die „Temp.u“ nicht mehr benötigt, und kann dementsprechend gelöscht werden (daher der Name „Temp“: „temporary“ :zwinker

Das selbe funktioniert natürlich auch, wenn man den Mesh nicht selber erstellt, sondern aus einem existierenden Pack importiert. Damit fällt logischerweise der „MeshMaker“ Schritt weg, aber ab dem Import der u-Datei läuft alles gleich.

An dieser Stelle nochmal eine Warnung, die sehr ernst zu nehmen ist: Ein Mesh hat in aller Regel einen oder mehrere Skin(s). (Wenn man einen Mesh mit „MeshMaker“ erstellt, sieht man sogar gleich, welche(n).) Diese Skins sind an den Mesh gebunden, die Information, welche Skins verwendet werden, wird also auch beim „MyLevel“-Import mit übernommen. Solange die Skins in einem UT-Standart-utx-Paket liegen, ist das kein Problem, unangenehm wir es aber, wenn sie das eben nicht tun, also Costum-Textures sind. Dann passiert nämlich folgendes:
Der Mesh ist zwar in „MyLevel“, trägt aber weiterhin die Information, dass, um ihn korrekt darzustellen, Texturen aus einem anderen (externen!) Pack benötigt werden, und sobald man den Mesh in seiner Map platziert, ist das entsprechende Pack nötig, damit man die Map noch öffnen kann. Somit hat man in diesem Moment quasi nichts gewonnen, man muss zwar die u-Datei, aus der der Mesh ursprünglich kam, nicht mehr mitliefern, die utx-Datei, aus der die Mesh-Skins kommen, aber sehr wohl!
Aber natĂĽrlich kann man auch das umgehen, indem man dem Mesh andere Skins gibt. Das geht so: Man sucht im Actor-Browser nach der Deco-Class, die den Mesh beinhaltet (und zwar bevor man die erste Deco in die Map setzt!), Rechtsklick -> Default Properties -> Display -> Skin (oder MultiSkins). Dort sieht man, welche Texturen als Skins dienen, und kann sie eben auch ersetzen.
Dabei müssen die „neuen“ Skins nichtmal wirklich anders aussehen, sondern nur wo anders zu finden sein. Und, was liegt da nahe?! Richtig: „MyLevel“!
Also bingt man die ursprünglichen Skins aus der ensprechenden utx-Datei nach „MyLevel“ (unter anderem Namen, sonst treten Konflikte auf!), und ersetzt mit diesen „neuen“ Skins die „alten“. Jetzt kann man die Deco-Class in die Map setzen, speichern, und damit wäre dieses Problem auch aus der Welt geschafft.


Abb. 11: Hier werden die „alten“ Skins durch die „neuen“ (nur „MyLevel“ oder UT-Standart!) ersetzt.


Was noch zu sagen ist: Diese „Verknüpfung“ mit externen Packages kann nicht nur bei Meshes auftreten, auch Scripts (siehe oben) können theoretisch Befehle enthalten, die sich auf andere Packs beziehen. Man muss also beim „obj load“-Import von Actors generell höllisch aufpassen, ob man nicht vielleicht aus Versehen ein Package „mitnimmt“, das man garnicht haben will!
Um sich zu vergewissern, ob die Map auch wirklich keine „Blindgänger“ benötigt, kann man wie folgt vorgehen: Man öffnet den Ed, dann die Map, und schaut in allen Browsern (Textures, Sounds, Music, Actors) nach, ob auch wirklich ausschließlich „gewünschte“ Packs geladen wurden. Wenn dem so ist, kann man aufatmen, wenn nicht, dann kostet es meist etwas Zeit und Nerven, bis man den Übeltäter gefunden hat... Also: Lieber gleich aufpassen!



(VII) Speichern von „MyLevel“-Objekten erzwingen

Ich gebe zu, das vorige Kapitel war heftig. (Wenn’s euch beruhigt, das Schreiben war auch kein Spaß. ) Ab hier wird es etwas weniger theoretisch, denn jetzt folgen ein paar nützliche Tips, wie man das „MyLevel“ Package in besonderen Situationen verwenden kann.

Der erste Trick, nämlich das „erzwungene Speichern“, ist gleich mal gar kein wirklicher Trick, sondern sollte, wenn man Kapitel (III) aufmerksam gelsen hat, fast selbstverständlich sein.
Wie ich schon mehrfach erwähnte, bleibt jedes Objekt genau dann in „MyLevel“ gespeichert, wenn es in der Map verwendet wird. Außerdem war schon die Rede vom Import ganzer Pakete, exemplarisch seien es hier mal wieder Texturen. So, und wer vorher schon mitgedacht hat, dem ist sicher der „Logikfehler“ aufgefallen: Was bringt es denn, ein ganzes Pack zu importieren, wenn nur diejenigen Texturen gespeichert werden, die man auch verwendet? Das hieße ja, beim nächsten Neustart des Editors sind alle anderen wieder weg, und man muss nochmal das ganze Pack importieren?!
Tja, ganz genau so ist es. Wenn man mit einem Costum-Package mappt, dann gibt es zwei Möglichkeiten:
Entweder, man macht es so, wie gerade beschrieben, man importiert das ganze Pack mittels „obj load“ bei jedem Editor-Start neu, so hat man dann immer alle Texturen zur Verfügung. Das geht zwar, aber ich halte es nicht für besonders elegant.
Oder, Möglichkeit zwei, man „zwingt“ das „MyLevel“ Package gleich beim ersten mal (also direkt nach dem Import) dazu, sich alle Texturen zu „merken“. Und wie das geht, sollte auch klar sein: Indem man eben alle Texturen verwendet. Ich habe mir dazu angewöhnt, irgendwo ganz am Rand des im Editor verfügbaren Platzes eine Reihe von Cubes zu subtracten, jeden mit einer Textur aus „MyLevel“.

rev-ml-tut-12a.jpg
Abb. 12: So kann eine (ziemlich lange) Reihe aus Cubes mit Costum-Textures aussehen.


Danach kann man die Map beruhigt speichern, und bei jedem neuen Ă–ffnen sind die Texturen wieder da, sie werden ja verwendet!
Das hat im Gegensatz zur ersten Möglichkeit den großen Vorteil, dass man ab diesem Moment nicht mehr auf das entsprechende externe Pack angewiesen ist. Und was noch schöner ist, man muss nicht jedes mal, wenn man seine Map lädt, auch noch die Texturen öffnen, die Texturen werden einfach gleich mit geladen!

Gut, jetzt kommen bestimmt wieder ein paar Leute an, von wegen es sei doch verdammt umständlich, bei großen Costum-Packs von 100 oder mehr Texturen für jede einen Cube zu subtracten... Ich würde sagen, das kann man sehen, wie man will, natürlich bedeutet es ein paar Minuten Arbeit, aber es ist eben einmalige Arbeit, danach hat man nie wieder Probleme.

Ach, und was sich natürlich von selbst versteht: Wenn die Map fertig ist, sollte man die Cube-Reihe wieder löschen, so verschwinden dann auch die Texturen aus „MyLevel“, die man in der Map nirgends aktiv benutzt hat.



(VIII) Verwendete externe Packages durch „MyLevel“ ersetzen

Dieser Trick hat eigentlich ein sehr ähnliches Ziel wie der vorherige: Eine Map mit Costum-Textures zu bauen, wobei alle verwendeten Texturen in „MyLevel“ sind. Der Unterschied zu Punkt (VII) ist nun der, dass jetzt die Texturen nicht von vorne herein in „MyLevel“ gepackt werden, sondern dass während des Mappens noch ein externes Pack verwendet wird, und das Ersetzen erst zum Schluss stattfindet. Das ist zwar eigentlich eine etwas umständliche Vorgehensweise, aber auch die einzig mögliche, wenn man eben schon gemappt hat, und nur noch „aufräumen“ will.

„Texturen ersetzen? Das geht doch mit dem ‚Replace Textures’ Tool“, werden jetzt einige denken. Stimmt, das geht. Und wer zu viel Zeit hat, kann’s ja auch gerne so machen.
Es gibt aber eine wesentlich schönere Möglichkeit.
Ich habe vorher schon mal in einer unbedeutenden Bemerkung erwähnt, dass der UEd Probleme mit Texturen hat, die den gleichen Namen tragen. Konkret heißt das, wenn du z.B. zwei Texturen namens „Light_1“ geöffnet hast, die aber in verschiedenen Packages liegen, dann erkennt der Editor nur diejenige von beiden an, die zuerst geöffnet war. Darin sehe ich einen der zahlreichen kleinen Bugs des UEd, und in den meisten Fällen ist dieser Bug auch extrem nervig, aber genau in diesem Fall, den wir hier haben, können wir den Bug ausnutzen! (Übrigens ist das der einzige mir überhaupt bekannte Ed-Bug, den man zu seinem Vorteil nutzen kann!)

Was macht man also genau? Zuerst mal müssen wir zusehen, dass wir die Costum-Textures aus dem Pack, das in der Map verwendet wird, nach „MyLevel“ bringen, und wie das geht, ist ja langsam klar: „obj load“... Als nächstes wird die entsprechende Map geöffnet, und jetzt haben wir genau den angesprochenen Effekt: Jede der Costum-Textures ist zweimal im Texture-Browser vorhanden, einmal in „MyLevel“ und einmal im Costum-Pack selbst, das gerade mit der Map zusammen geöffnet wurde. Und vor allem: Die „MyLevel“-Texturen waren zuerst offen! Beste Voraussetzungen also, um den gewünschten Bug herbeizuführen.
Noch tragen die Surfaces in der Map natürlich die „alten“ Texturen aus dem externen Pack, logisch, diese wurden ja auch ursprünglich verwendet.

Was jetzt kommt, ist eigentlich ein ziemlich billiger, aber sehr wirksamer Trick: Markiere deine gesamte Map (Rechtsklick auf irgendeinen Brush oder sonstwas -> Select All), kopiere sie (STRG+C oder Edit -> Copy), erstelle eine neue Map (Edit -> New) und füge das eben kopierte ein (STRG+V oder Edit -> Paste). Du must natürlich rebuilden, damit die Architektur sichtbar wird, aber danach siehst du den gewünschten Effekt: Alle Costum-Textures sind nun die aus „MyLevel“! Warum das so ist? Nun ja, wegen des Bugs natürlich. Der Editor weist beim Rebuilden jeder Surface wieder eine Textur zu, und wenn er nun irgendwo eine Surface findet, die die „Light_1“ Textur trägt, dann legt er diese auch wieder darauf. Nur ist für den Ed eben die einzig relevante „Light_1“ Textur diejenige, die zuerst geöffnet war: Die aus „MyLevel“!


Abb. 13: Die gleiche Surface vor und nach dem Tausch: Zuerst „richrig“, dann „MyLevel“.


Was nun folgt, ist nur noch Kosmetik. Die alte Map (in der die Texturen noch extern waren) braucht keiner mehr, du kannst also die neue sofort unter dem gleichen Namen speichern. Das einzige, was du noch tun musst, da es sich ja eine neue Map handelt, ist, die Level-Properties neu einzutragen, da diese nicht mit übernommen werden. Aber mal kurz Author, Name, etc. anzugeben, geht wohl deutlich schneller, als Massen von Texturen via „Replace Textures“ zu ersetzen, oder? :zwinker:


Abb. 14: Die Level-Properties mĂĽssen in der neuen Map nachgetragen werden.


Nur ein kleiner Wermutstropfen diesbezüglich: Dieser Trick funktioniert nur mit Texturen! Sounds, Musik und Actors muss man leider doch auf die „altmodische Art“ behandeln.



(IX) MyLevel von einer Map auf eine andere ĂĽbertragen

Bisher ging es ja eigentlich immer um das gleiche: Externe Objekte bzw. Packages irgendwie nach „MyLevel“ zu bringen. Jetzt kommt mal etwas anderes, nämlich das Übertragen eines (kompletten) „MyLevel“ Packages von „Map A“ nach „Map B“.
Hier muss man gleich von vorne herein zwei Fälle unterscheiden:

Im ersten Fall ist das Vorgehen einfach, und auch nicht wirklich neu. Man öffnet zuerst „Map A“, das „MyLevel“ Package wird logischerweise mit geladen. Jetzt öffnet man „Map B“, wobei natürlich alle Objekte, die in den Browsern aufgelistet sind (also auch die „MyLevel“-Objekte von „Map A“), erhalten bleiben. Das war’s eigentlich schon. Man kann jetzt nach Herzenslust alles aus „MyLevel“ verwenden, und wie schon immer gilt: Sobald ein Objekt einmal (in „Map B“) verwendet wird, ist es verankert. Dementsprechend bietet es sich an, gleich im Anschluss an das Übertragen Trick (VII) auszuführen („erzwungenes Speichern“), damit man den Zwischenschritt über „Map A“ nicht bei jedem Editor-Neustart wieder gehen muss, sondern gleich alle Objekte im „MyLevel“ von „Map B“ zur Verfügung hat.

So, das war jetzt natürlich sehr einfach, schwieriger wird es aber, wenn „Map B“ eben schon vor dem Übertragen eigene „MyLevel“-Objekte beinhaltet. Denn wenn man in diesem Fall so vorgeht, wie oben beschrieben, dann passiert folgendes: Sobald man „Map B“ geöffnet hat, und versucht, einen Blick ins „MyLevel“ zu werfen (in dem jetzt sowohl Objekte aus „Map A“ als auch aus „Map B“ sind), stürzt der Editor mal wieder ab. Kurz gesagt, wenn zwei (oder mehr) „MyLevel“ Packages verschiedener Maps gleichzeitig geöffnet sind, führt das zu Konflikten. Oder noch anders ausgedrückt, man kann zwar theoretisch auch hier das „MyLevel“ übertragen, es hilft einem nur nichts, weil man dann nicht mehr darauf zugreifen kann, ohne den Ed zum Absturz zu bringen.


Abb. 15: Mal wieder ein Absturz, hervorgerufen durch zwei verschiedene „MyLevel“ Packages.


Nicht gerade eine zufriedenstellende Lösung, da muss wohl was anderes her...

In Kapitel (III) habe ich die vielleicht wichtigste Eigenschaft des „MyLevel“ Packs genannt: Es darf nicht gspeichert werden, niemals, unter keinen Umständen! Ähäm... Unter fast keinen Umständen, bis auf diesen hier.
Ja, ganz recht, in diesem Fall muss man mal die goldenen Regel brechen und das „MyLevel“ Package (das von „Map A“ natürlich) abspeichern, allerdings nicht unter dem Namen „MyLevel“, sondern unter irgendeinem anderen, ich nenne es mal wieder (exemplarisch für Texturen) „Temp.utx“.
Hier ist zu beachten, dass das nicht mit einem Schritt getan ist, sondern jeweils fĂĽr Texturen, Sounds, Musik und Actor-Classes ein eigenes Pack gespeichert werden muss.
Dazu gleich eine Randbemerkung: Wie speichert man eigentlich Actor-Packages extern, also in eine u-Datei? Das ist, im Vergleich zu Texture-Packs etc., recht schwierig: Wenn man seine „Map A“ geladen hat, geht man in den Actor-Browser und dort auf View -> Show Packages. Am unteren Ende des Browsers erscheint nun eine Liste mit allen aktuell geöffneten Packs, aber „MyLevel“ ist nicht aufgelistet! Das liegt mal wieder daran, dass der Browser erst aktualisiert werden muss, sprich, man öffnet irgendeine beliebige u-Datei, danach ist in der Liste „MyLevel“ sichtbar. Jetzt setzt man nur noch den Haken vor „MyLevel“ und klickt auf den „Save“ Button.


Abb. 16: Diese Haken müssen gesetzt sein, um „MyLevel“ als externe u-Datei zu speichern.


Blöderweise kann man hier keinen Namen angeben, statt dessen wird das Pack automatisch unter „MyLevel.u“ im System-Ordner abgelegt. Aber auch das sollte kein allzu großes Problem darstellen, man öffnet einfach selbigen Ordner, sucht die Datei und benennt sie um, z.B. wieder in „Temp.u“.

So, jetzt aber zurück zum „Temp.utx“ Beispiel: Man hat jetzt also alle „MyLevel“ Packages gespeichert, sie liegen demnach als ganz normale, externe Packages in den entsprechenden UT-Unterordnern.
Als nächstes wird der UEd neu gestartet (wichtig!!), danach verfährt man nach bekanntem Muster: „obj load“ mit allen exportierten Packs, z.B.

Code:
obj load file=Temp.utx package=MyLevel

Danach öffnet man „Map B“, und hat nun problemlos alle Objekte zur Verfügung, die vorher noch zum „MyLevel“ von „Map A“ gehörten! Trick (VII) anwenden, fertig!
Ach ja, die „Temp“-Dateien kann man dann natürlich auch weider löschen.



(X) Wann ist „MyLevel“-Import sinnvoll und wann nicht?

Wenn man regelmäßig diese und ähnliche Fragen im UEd2-Board liest, möchte man denken, dass die Antwort lautet: „Es ist immer sinnvoll!“
Dem kann ich fast zustimmen, allerdings gibt es ein paar Situationen, wo der „MyLevel“-Import nur bedingt etwas bringt, und außerdem sogar einen Fall, wo es totaler Schwachsinn wäre, „MyLevel“ zu verwenden.

Ich habe die Vorteile von „MyLevel“ zwar schon mehrfach erwähnt, aber die wichtigsten beiden hier nochmal kompakt:
Erstens ist das Zip-Archiv, in dem die Map veröffentlicht wird, und damit auch der UT-Ordner von demjenigen, der die Map herunterlädt, ordentlicher, weil einfach weniger Dateien zu verwalten sind. Es soll mittlerweile sogar Leute geben, die Maps, die mit übermäßig vielen zusätzlichen Dateien daherkommen, garnicht mehr entpacken, also auch nicht spielen! Das finde ich persönlich zwar übertrieben, aber es ist nunmal so.
Naja, und zweitens spart „MyLevel“ Speicherplatz im Zip-Archiv, weil eben, im Gegensatz zu externen Packs, nicht benötigte Texturen etc. automatisch weggelassen werden.

So, wir kommen dann mal zu möglichen Nachteilen, und gleich der erste kann sich aus dem zweiten Vorteil (Speicherplatz) entwickeln. Das klingt paradox, ist aber so. Denn auch, wenn die Zip-Datei kleiner ist, kann es sein, dass derjenige, der die Map herunterlädt, am Ende mehr Speicherplatz verbraucht.
Ein Beispiel: Nehmen wir wieder an, du baust eine Map mit den „richrig“ Texturen, die eigentlich fast jeder UT-Spieler ohnehin schon hat. Du musst sie trotzdem mitliefern, eben für diejenigen, die sie nicht haben.
Packst du einfach die utx-Datei extern mit ins Zip, so wird selbiges größer, als es wäre, wenn du die Texturen in „MyLevel“ hättest (weil es sicher nicht alle wären). Aber wenn jemand deine Map runterlädt, und „richrig“ schon hat, dann muss er die Texturen nicht ersetzen, sondern es reicht ihm, die Map in seinen UT-Ordner zu kopieren. Er verbraucht also nur den Speicherplatz für deine Map (ohne Texturen) und „richrig“.
Wenn du dagegen alle „richrig“-Texturen in „MyLevel“ packst, wird das Zip-Archiv kleiner. ABER: Der Spieler, der sich deine Map holt, verbraucht jetzt trotzdem mehr Speicherplatz: Für deine Map (mit Texturen!!), und für die „richrig.utx“, die er schon vorher hatte!
Jetzt ist natürlich die Frage: Was ist besser, ein kleiner Download oder mehr freier Speicherplatz? Ich persönlich würde sagen, in Zeiten von 500+ GB Festplatten ist die Download-Größe wichtiger, also doch wieder eher „MyLevel“.
Allerdings kann man hier auch wieder so denken, wenn man mit „richrig“ mappt, und wirklich so gut wie alle Texturen daraus verwendet, dann ist der Unterscheid zwischen „MyLevel“ und „extern“ im Zip kaum noch vorhanden, beim Spieler, der die Map lädt, aber besonders groß. Also wäre es in diesem Falle vielleicht wirklich eine Überlegung wert, mal auf „MyLevel“ zu verzichten. Aber wirklich nur in diesem einen Fall, denn mir fällt spontan kein anderes Texture-Package ein, das nur annährend so weit verbreitet wäre wie „richrig“, also kann man bei allen anderen ruhig bei „MyLevel“ bleiben.

Ein weiterer Punkt, wo „MyLevel“ nur bedingt Sinn macht, ist, wenn man selbst erstellte Texturen o.ä. verwendet, selbige aber zur freien Verfügung stellen will. Denn dann müsste jeder, der die Texturen in Zukunft verwenden will, sie erst mal aus der ensprechenden Map herausholen, was für alle Betroffenen ziemlich umständlich wäre. Also, wer etwas „Open Source“ anbieten will, der sollte das auch in Form eines klassischen utx-Packs tun.

Was ich hier auch mal vorsichtshalber erwähne, damit niemand auf dumme Gedanken kommt: Selbstverständlich darf man nie etwas in "MyLevel" importieren, was außerhalb der Map gebraucht wird! Ich denke dabei vor allem an Game-Menus und dergleichen, da diese ja im Grunde auch nur gewöhnliche Actor-Classes sind. Da allerdings auf das "MyLevel" Package nur die entsprechende Map zugreifen kann, und nicht das Spiel selbst, kann so etwas garnicht funktionieren. Genau gesagt, der Import funktioniert schon, aber alles weitere nicht. Also, Finger weg!

Und zu guter Letzt noch eine Situation, wo die Verwendung von „MyLevel“ einfach nur dämlich wäre: Mods oder Mappacks! Denn wenn hier mehrere Maps zusammen veröffentlicht werden, von denen jede Texturen aus dem gleichen Pack verwendet (z.B. ein „Industrial“-Mappack, in dem jede Map „HourIndusX.utx“ nutzt), dann wäre es völlig absurd, das Package in jeder Map zu „MyLevel“ zu machen, denn dadurch würde jede Map-Datei wachsen, und zusammen wären sie um einiges größer, als die Maps ohne „MyLevel“ plus das externe Pack. Sprich, man würde so den „Speicherplatz sparen“ Effekt genau umkehren!



(XI) Schlusswort

Erstmal GlĂĽckwunsch an alle, die bis hierher durchgehalten haben!
Ich versuche jetzt, mich wenigstens hier kurz zu fassen, nachdem sich das Tutorial ohnehin schon irrsinnig in die Länge gezogen hat. (Auf einer Website fällt es vielleicht garnicht so sehr auf, aber in Word sind das zehn DIN A4 Seiten, Schriftgröße 12, normaler Zeilenabstand, keine großen Absätze, keine Bilder!!)

Viel bleibt sowieso nicht zu sagen, ich hoffe einfach, es ist mir gelungen, euch die Verwendung von „MyLevel“ ein bisschen näher zu bringen, euch ein paar Tricks zu zeigen, die ihr noch nicht kanntet, und euch vor den typischen Problemen zu warnen, bevor ihr sie selbst bekommt.
Wie in Kapitel (X) beschrieben, gibt es schon ein paar Situationen, in denen „MyLevel“ mit Vorsicht zu genießen ist, aber ich kann wohl mit Recht behaupten, dass das Einzelfälle sind. In den übrigen 99% aller Fälle ist „MyLevel“ uneingeschränkt zu empfehlen, vorausgesetzt natürlich, man weiß, wie man damit umgeht. Aber das wisst ihr jetzt ja hoffentlich. :zwinker:


Abschließend gilt wie immer: Die Antwort auf alle Fragen, die evtl. durch dieses Tutorial entstanden sind, lautet „42“, und wer Rechtschreibfehler findet, darf sie behalten.



greetings,

Revelation