Nicht eingeloggt
Registrieren

Eine Assault Map erstellen

Dieses Tutorial soll zeigen, wie die ganzen Assaultobjekte funktionieren und wie man sie einbaut und auf seine Ideen zuschneidet.
Ich selbst habe keine spielbare Assaultmap bis jetzt gemacht, ich kenne mich aber schon etwas mit den ganzen Objekten aus.
Schaut einfach mal, was ihr hieraus alles gebrauchen könnt.



I. Was muss ich für eine spielbare Assaultmap tun?

Zuerst nichts bahnbrechendes. Wenn man seine Assaultmap baut, will man sie auch testen. Damit sie aber auch als Assaultmap gestartet wird, braucht ihr den richtigen Default Game-type.
Ihr geht im Editor auf View->Level Properties und dort findet sich unter LevelInfo der DefaultGametype. Beim Neubeginn einer Map ist der leer, worauf das Spiel die Map beim Testspiel immer als Deathmatchmap interpretiert.
Um das nicht dem Zufall zu überlassen, geben wir dort "UT2k4Assault.ASGameInfo" ein. Beim Testspiel wird die Map nun als Assaultmap verstanden.
Nun bringt eine Assaultmap ohne Assaultobjekte ja rein gar nichts. Aber das ändern wir sofort.



II. Vorbereiten der Map

Für eine Assaultmap ist ein Konzept Pflicht. Dieses besteht grundsätzlich aus einem Floorplan wie jede Map und eben die ganzen Objekte und Stationen, die eine Assaultmap auch noch braucht.
Besser wäre es, erst die Map zu machen und hinterher alle Objekte einzufügen, das ist aber jedem selbst überlassen.
Auch ist es wichtig, sich zu notieren, wann und wo die einzelnen Teams starten sollen. Wie ihr schon gemerkt habt, ist es bei nahezu allen Assaultmaps so, dass man nach erfolgreicher Ausführung einer Aufgabe seinen Startpunkt verändert. Das ist der PlayerSpawnManager, dazu komme ich weiter unten. Diese ganzen Stationen sollten also mit auf das Konzept, dass man sich später beim einbauen nicht damit aufhalten muss.



III. Der normale Trigger

Das ziel dieses Objekts ist es lediglich, ihn zu betätigen, dass diese Aufgabe erfüllt ist. Logischerweise sollte man beachten, dass ihn nur das Attackerteam auslösen kann, man nimmt also keinen normalen Trigger, sondern einen TeamTrigger. Zu finden im ACB unter Triggers->Trigger->TeamTrigger.
Das besondere daran ist, dass man jetzt die Option der Teamnummer hat, welche unter dessen Einstellungen unter TeamTrigger->Team zu finden ist. 0 ist Defender und 1 ist Attacker. Also sollte man dafür 1 eintragen. Einen Trigger zu machen, den nur Defenders auslösen können gäbe keinen Sinn.
Damit auch Bots den Trigger benutzen, muss man noch einen bestimmten Actor verwenden. Das "TriggeredObjective"! Den wirst du wohl öfter brauchen, der sagt den Bots, dass er hier an dieser Stelle einen Trigger betätigen soll. Zu finden ist er unter "JumpDest->JumpSpot->GemaObjective->TriggeredObjective".
Addet ihn auf dem Trigger, etwa so wie auf dem Screenshot hier:

woolfxxximage22.jpg

Der Grund: Ein Trigger hat keine Möglichkeit, sich in ein Pfadnetzwerk einzubringen. Das TriggerObjective schon. Es wird so etwa hingesetzt, der Bot wird dann zu dieser Stelle gehen und somit den Trigger auslösen. Zusätzlich hat der Actor auch die Funktion, dem Bot zu vermitteln, dass es sehr wichtig ist, an diese Stelle zu gehen. Das unterscheidet ihn von einem gewöhnlichen PathNode.


Wichtige Eigenschaften Erklärung

TeamTrigger -> Team Teamnummer für das Team, welches den Trigger nur auslösen darf. 1=attacker, 0=defender

events -> Tag/event einen einzigartigen Begriff, um die beiden actors (siehe screenahot) miteinander zu verbinden



IV. Der UseObjective

Der UseTrigger wird hierfür nicht verwendet wie vielleicht gewohnt, sondern es gibt dazu einen Assault-optimierten Actor namens "UseObjective" zu finden im ACB->JumpDest->JumpSpot->ProximityObjective->UseObjective.
Dieses wird in die Map gesetzt, wo der Schalter sein soll. Achte darauf, dass er auch an der korrekten Stelle sitzt, nicht nur auf dem Boden, da das Ziel markiert wird. Die Einstellungen könnt ihr euch hier abgleichen:

woolfxxximage23.jpg




V. Der HoldObjective-Actor


Dieser hat die Funktion, dass der Attacker diesen Trigger für eine gewisse Zeit halten muss und dabei ein Mover ausgelöst wird. Also zum Beispiel muss ein Attacker ein Rad bis zum Anschlag aufdrehen, damit die Aufgabe erfüllt ist.
Den Actor findet ihr im ACB->JumpDest->Jumpspot->ProximityObjective->HoldObjective.Diesen addet ihr dort hin, wo der Spieler stehen muss, damit das Rad sich dreht. (alternativ kann es natürlich auch ein Hebel, eine Tür oder alles andre sein!) Jetzt müsst ihr den Mover einstellen. Erstmal, wenn es ein Rad ist, mit den Keys definieren, wohin es sich drehen soll. In einer anderen Assaultmap habe ich so einen mit einer 90° Drehung gemacht. (Hier setze ich einfach mal voraus, dass ihr wisst, wie ihr einen Mover mit den Keys richtig einstellt.) Entscheidend ist beim Mover die MoveTime. Diese bestimmt, wie lange der Spieler an dieser Station verweilen muss, bis der Mover ausgelöst wurde und das nächste Ziel in Angriff genommen werden kann. Ich habe MoveTime 5 genommen. Es dauert also 5 Sekunden, bis das Ziel erreicht ist.
Auch wichtig ist es, die Art des Movers einzustellen.
Das geschieht unter Object->InitialState. Dort muss anstatt PlayerBump "TriggerAdvance" eingestellt werden. Genau herleiten kann ich es mir jetzt nicht was das bedeutet, man muss sich einfach darauf verlassen.
Damit wir auch den HoldObjective Actor und den Mover in Verbindung bringen, machen wir folgendes: Das HoldObjective soll den Mover auslösen, der sich dreht. Natürlich nur solange, wie man vor ihm steht. Nachdem der Mover seine Endposition erreicht hat, soll er dem HoldObjective sagen, dass er fertig ist, der dann das Ziel als erfüllt einstellt.
Dazu bekommt der Mover einen einzigartigen Tag. Ich habe den Tag des Movers "drehrad" genannt.
Jetzt in die Einstellungen des HoldObjective Actors.



Rot eingerahmt ist jetzt der Tag des Movers, der ja bei Berührung des HoldObjectiv Actors ausgelöst werden soll.

An dieser Stelle ein tipp von mir: Es können auch mehrere Mover den Tag haben. In diesem Falle würden sich alle dann drehen. Ihr müsst nur aufpassen, wer von den Movern dann den HoldObjective Actor auslöst. Alle sollten die gleiche Movetime haben, aber nur einer darf den HoldObjectiveActor auslösen! Sonst könnte es zu unvorhergesehenen Ergebnissen kommen.

Wieder in die Einstellungen des Movers, um dem Mover unter dessen Einstellungen->Events->event den Tag des HoldObjective-actors zu geben. (Oben blau eingerahmt.) Dies verbindet jetzt beide Objekte.
Um zu verhindern, dass der Mover blockieren könnte, jetzt noch in dessen Einstellungen unter mover->MoverEncroachType auf "ME_IgnoreWhenEncroach" stellen. Den sonst könnte sich jemand sehr schlaues unter den Mover stellen, um ihn zu blockieren. Das will ja niemand.

Wunderbar. Damit habt ihr einen Mover gemacht, den man drehen muss, um das Ziel zu erreichen.


Wichtige Eigenschaften Erklärung

HoldObjective-Actor -> HoldObjective -> mover tag Der Tag des Movers oder der Mover, zu finden bei denen unter events -> Tag.

Mover -> mover -> MoveTime die Zeit, die benötigt wird, damit der Mover sich ans ende bewegt hat und das Ziel erfüllt ist.




VI. Der DestroyableObjective_SM-actor


Die der Name schon vermuten lässt, hat es hier was mit einem StaticMesh zu tun, den man zerstören muss. Das Prinzip ist eigentlich so einfach, das der Name schon alles sagt. Zu finden ist er im ACB->JumpDest->JumpSpot->GameObjective->DestroyableObjective->DestroyableObjective_SM.Wenn man ihn in die Map addet, erscheint ein riesiger Cube mit der Default-Textur drauf. Das ist natürlich untragbar! Man markiert einen StaticMesh aus dem StaticMesh Browser und geht dann in die Einstellungen des DestroyableObjective_SM-Actors.
Unter Display->StaticMesh kann man nun per "Use"-Button seinen StaticMesh benützen.

Optional bietet sich die Möglichkeit an, einen zusätlichen StaticMesh zu verwenden, inden sich der erste verwandelt, sobald er zerstört ist.
Diese Option ist unter DestroyableObjective_SM->DestroyedStaticMesh zu finden.
So kann man das netterweise so einrichten, dass man beispielsweise auf ein Auto ballern muss, welches dann explodiert und zurück bleibt ein zerstörtes Wrack.


Unter der Einstellung "DestroyableObjective" kann man nun unter Anderem die DamageCapacity einstellen. Soviel schaden wird mindestens benötigt, bis der Mesh explodiert. Standartmäßig 100, muss an das Level angepasst werden.
Die restlichen Einstellungen erklären sich eigentlich von selbst. Bei "bCanDefenderDamage" bin ich mir sicher. sinneshalber glaube ich, dass die Einstellung bewirkt, dass auch die Verteidiger bei Beschuss dem Objekt Schaden entziehen können.


Wichtige Eigenschaften Erklärung

DestroyableObjective -> DestroyableObjective -> bCanDeferDamage Bei true können auch die Verteidiger dem Objekt schaden zufügen durch Beschuss, mit der Linkgun aber auch reparieren.

DestroyableObjective_SM -> DestroyedStaticMesh optional, mesh, der bei zerstörung das Objekt ersetzt

Display -> StaticMesh Der StaticMesh, der als Objekt angezeigt werden soll.




VII. Der Energy Core


Aus AS-Junkyard bekannt, ist die Aufgabe, den Energiekern des Hellbenders sich zu holen und zur Garage zu liefern. Das erreicht man durch den Actor "ASOBJ_EnergyCore_Spawn" und dem Actor "ASOBJ_EnergyCore_Delivery".
Der "ASOBJ_EnergyCore_Spawn"-actor stellt den Energiekern dar. Wie man den Mesh ändert habe ich noch nicht herausgefunden, ich bin mir ziemlich sicher, dass es unter Display->StaticMesh funktioniert, es hat aber nicht geklappt. Sollte ich es herausfinden, werde ich das selbstverständlich noch nachtragen.


Wichtig ist natürlich auch ein Actor, zu dem du deinen EnergyCore bringst. Dieser heißt "ASORBJ_EnergyCore_Delivery" und ist zu finden im ACB->JumpDest->Jumpspot->GameObjective (hier ist übrigens der ASOBJ_EnergyCore_Spawn)->ProximityObjective->"ASORBJ_EnergyCore_Delivery".Nachdem ihr diesen in die Map geaddet habt, wird das nächste um was ihr euch kümmern müsst der Radius dieses Actors sein. Also den Actor des Delivery anklicken, in dessen Einstellungen auf Collision gehen.
Vorher allerdings wäre es von Vorteil, wenn du in der Ansicht die Radi der Actoren anzeigen lässt. Das geschieht da.


woolfxxximage25.jpg

und bewirkt, dass alle markierten Actors mit deren Kollisionszonen angezeigt werden.
Wenn du nun in den Einstellungen unter Collision die CollisionHeight (kollisionshöhe) und den CollisionRadius (Kollisionsradius) anpasst, kannst du in der 3D Ansicht gleich sehen, ob es in deine Map so passt oder nicht. Geil, oder?
Jetzt hat man den EnergyCore, den man in die im Screenshot rot dargestellte Zone bringen muss um das Ziel zu erfüllen.

Wichtige Eigenschaften Erklärung

ASOBJ_EnergyCore_Delivery -> Collision -> Collision height/radius Große für die Kollisionszone festlegen




IIX. Die Playerstarts und der PlayerSpawnManager


Damit nicht attacker und defender-teams wild durcheinander spawnen, kann man das Team einstellen, welches durch diesen Playerstart spawnen soll. Das macht man nicht durch den Playerstart, sondern durch den PlayerSpawnManager.
Dies ist das wohl komplizierteste am Assault gametyp, und äußerst ätzend. Ich musste mir zwanzigmal das Tut dazu auf angelmapper.com durchlesen, um das zu verstehen. Daran werde ich mich auch orientieren. Das Problem ist, umso mehr Stationen du hast, desto komplizierter wird das ganze.

woolfxxximage26.jpg

Bei 1 fängt man an, 2 ist der EnergyCore den man aufheben muss, das zu Punkt 3 bringen, bei 4 erst die Tür zerstören, im Raum bei 4 den Trigger betätigen und bei 5 den Hebel ziehen, danach ist die Runde zu Ende.

Die Map ist komplett aus dem Tutorial von angelmapper.com nachgebaut, ich kann das leider mit dem PSM nicht anders erklären, ich werde einiges übersetzen und ausführen so gut ich kann.

Bei jeder Nummer befinden sich 6 Startplätze. Alle sind gleich eingestellt.


Das Prinzip:


Zuerst sind Nummer 1 und 2 aktiviert, wo bei Nr.1 die attacker starten und bei 2 die defenders. So stößt das Attackerteam auf Widerstand während es versucht zu Punkt 2 zu gelangen.. Sobald Team 1 (attacker) das Objekt an sich genommen hat, werden die Startpunkte geändert. Nr. 1 wird inaktiv, bei nr. 2 starten die Attacker und bei nr.3 starten die Defender. Nachdem der EnergyCore an Punkt 3 abgegeben wurde, ändern sich die Startpunkte so, dass die Attacker bei nr.3 starten und die Defender bei nr. 5. Sie sollen jetzt die Attacker davon abhalten, die Tür vor 4 zu zerstören. Ist die Tür dann doch zerstört und der Trigger bei 4tens ausgelöst, starten die Attacker bei nr.4 und die Defender bei Nr. 5. Jetzt müssen nur noch die Attacker den Hebel bei nr. 5 umlegen und schon ist die Runde vorbei.

Der PlayerSpawnManager hat jetzt die Funktion, einzelne Playerstarts zu aktivieren, bzw. zu deaktivieren. Die Playerstarts haben in den Optionen einen Eintrag, den wir brauchen werden. Gemeint ist das "TeamNumber" oben auf dem Screenshot der PlayerStart-Einstellungen. Dabei werden jetzt alle PlayerStarts in Bereich 1 auch die Teamnummer 1 bekommen. Genauso alle Playerstarts in Bereich 2 und so weiter bis 5. Dabei ist Teamnumber nicht nur auf 0 und 1, also Attacker und Defender begrenzt, in diesem Falle bedeuten die Nummern etwas anderes, nämlich die Verbindung der Playerstarts mit den für die Bereiche zuständigen PlayerStartManagern.

Diese kommen jetzt. Im ACB->Info->Playerstartmanager. Aus Gründen der übersicht kommen die PSM am Besten immer über ihre zu kontrollierenden Playerstarts.

Den ersten PSM addest du in Bereich Nr.1 über den Playerstarts mit der Teamnummer 1. In den Einstellungen des PSM kommt auch Teamnummer 1 rein.


Als Tag bekommt er "attacker0", das ist der tag, mit dem er dann angesprochen wird.
AssaultTeam ist einfach das Team. Anstatt den Nummern 0 und 1 trägt man hier Attackers oder Defenders ein. Bei Bereich 1 starten die Attacker. Also kommen die auch in die Einstellungen rein.
bAllowTeleporting heißt, dass die Spieler des Teams, wenn sie noch leben, zu diesem PlayerSpawnManager teleportiert werden können, sobald der nächste PSM aktiviert wird.
bEnabled kommt nur bei Bereich 1 und 2 auf true, da diese beiden ja am Anfang aktiviert sein sollen.
Wenn ein PlayerSpawnManager durch seinen Tag angesprochen wird, durch einen Trigger oder ähnlichem, wird der Zustand von bEnabled hin und her geschaltet. Der bei Nr.1 wird dann deaktiviert, der bei 2 aktiviert.


In Bereich 2 kommen zwei PlayerStartManager hin. Beide kontrollieren die Selbe PlayerStart-Teamnummer, mit der Besonderheit, dass der eine von den Attackern ist und der andere von den Defenders. Der von den Attackern ist deaktiviert, also bei dem das bEnabled auf false. Der PSM der Defenders bei Pos.2 ist ja bei bEnabled auf true. Dieser wird hinterher ausgeschaltet. Das geht immer so weiter. In den Bereichen 2,3 und 4 sind auch zwei PSM, jeweils von Attackers und Defenders. Bei Bereich 5 ist nur der der Defenders, der dann in den letzten beiden Stationen Aktivert sein wird.

Der PSM hat also nicht direkt was mit den Teams zu tun, sondern weist einer Teamnummer, welche die PlayerStarts auch benutzen einen PSM zu, welcher dann die Teamnummer der Playerstarts den Attacker/Defendern zuweist.

Um die PlayerStartManager nun zu kontrollieren, ist ein ScriptedTrigger vorausgesetzt. Diesen findet man im ACB->Keypoint->AIScript->ScriptedSequence->ScriptedTrigger.

Wichtige Eigenschaften Erklärung

PlayerSpawnManager -> AssaultTeam Das Team, welches der PSM kontrolliert
PlayerSpawnManager -> bAllowTeleporting Ob das jeweilige Team sich mit der q-taste zum nächsten spawnpoint teleportieren darf
PlayerSpawnManager -> bEnabled ob der PSM bei Rundenstart schon aktiv sein soll.
PlayerSpawnManager -> PlayerStartTeam Die Teamnummer der Playerstarts, die von diesem PSM kontrolliert werden sollen.




IX. Die Reihenfolge der Objekte


Auch etwas wichtiges ohne das eine Assaultmap unspielbar wäre ist es, die ganzen Objekte in die richtige Reihenfolge zu bringen. Angefangen vom ersten Objekt, mit einigen weiteren, mal auch zwei auf einmal bis zum letzten. Das alles ist ja auch aufgelistet im Spiel.


Das Prinzip ist einfach. Man kann in jedem Assaultobjekt die DefensePriority festlegen. Also die Priorität, wobei hier die Reihenfolge gemeint ist.


Dabei hält man sich an folgendes System:
Am besten man fängt hinten an und geht zum ersten. Das letzte Objekt hat die DefensePriority 0, dann das vorletzte hat die DefensePriority 1 und so weiter bis zum ersten Objekt.
Ich empfehle, diesen Schritt als letztes zu machen, wenn man hinterher noch ein Objekt hinten dran setzt, muss man auch die ganzen Priority-Nummern neu anpassen.

Aus AS-Mothership bekannt, dass man auch mehrere Objekte auf einen Schlag auslösen muss. In dem Falle können es z.B zwei Schalter sein. Dann bekommen beide die selbe Nummer. erst wenn beide ausgelöst wurden, geht es weiter.




X. Der Scripted Trigger


Auch ein komplizierter Teil, der einiges an Konzentrationsfähigkeit, Intelligenz, Geduld und Verständnis fordert. ;-)

Und eigentlich brauchst du nur zwei verschiedene Aktionen des Scripted Triggers: Waitforevent und Triggerevent.
Mit waitforevent sagst du dem ScriptedTrigger, dass er solange nichts machen soll, bis ein bestimmtes Event ausgelöst wird. Das wird dann auch dort in den Einstellungen eingegeben. Da kommen die ganzen Events der bestimmten Assaultobjekte rein. Auch wichtig: Der Einsatz von ScriptedTriggern kann sehr unterschiedlich gestaltet werden. Man wird sich die Beispielmap anschauen müssen um das zu verstehen.

Der ScriptedTrigger Beim ersten Objekt:


Waitforevent -> Event des ersten Objekts, z.B MoverTrigger, Teamtrigger, Objekt, DeliveryZone usw.
Wenn dieses Event ausgelöst wurde, geht der ScriptedTigger zur nächsten Aktion.
Triggerevent -> Hier muss der Tag des ersten PSM der Attacker rein.
Triggerevent -> Hier des zuvor inaktiven PSM der Attacker an Position2, der aktiviert wird.
Triggerevent -> Gleich daneben ist der zuvor aktive PSM der Defender bei Pos.2, der jetzt deaktiviert wird.
Triggerevent -> An Pos.3 wird jetzt der PSM der Defender aktiviert, damit diese die Attacker daran hindern können, von 2 zu 3 zu kommen.

Der zweite ScriptedTrigger kommt zum zweiten Objekt. Wenn dieses von den Attackern erreicht und ausgelöst wird, müssen sich die Startpunkte ja wieder umstellen. Also:


Waitforevent -> Event des zweiten Assaultobjekts
Triggerevent -> Der PSM der Attacker bei Position2 wird deaktiviert
Triggerevent -> Der PSM der Attacker wird bei Position3 aktiviert
Triggerevent -> Der PSM der Defender an Pos.3 wird deaktiviert
Triggerevent -> Der PSM der Defender wird an Pos.5 aktiviert.

! An Pos.5 starten die defender in meinem speziellen Beispiel, da Pos.4 ein Raum, abgetrennt durch eine Tür ist. Es wäre sinnlos, die Defender in diesem abgeschlossenen Raum spawnen zu lassen, da sie ja die Attacker nicht von der Zerstörung der Tür abhalten könnten.

Die nächsten würden immer so weiter gehen, das kommt auf die unterschiedlichen Objekte in der AS-Map an. In meiner Beispielmap würde ich nur noch einen ScriptedTrigger benötigen:

Waitforevent -> Tag des Schalters im Raum wo die Tür vorher gesprengt wurde
Triggerevent -> Der PSM der Attacker bei Pos. 3 wird deaktiviert
Triggerevent -> Der PSM der Attacker wird bei Pos. 4 aktiviert.




XI. Der Trigger_ASRoundEnd



Damit das Spiel auch aufhört, nachdem das letzte Objekt ausgelöst wurde, nimmt man einen solchen Trigger. Zu finden im ACB->Triggers->Trigger_ASRoundEnd.
Interessant ist auch nur der Tag, der halt irgendwie "Spielende" heißt und das letzte Objekt, welches ausgelöst wird, ihn in den Einstellung als event trägt.