Mit diesen Einstellungen steuern Sie, wie Character Studio einen Übergang von einem Zustand zu einem anderen bewerkstelligen soll, wenn ein kognitiver Controller eingesetzt wird. Detailliertere Informationen finden Sie unter So richten Sie einen kognitiven Controller ein und verwenden ihn.
Die wichtigste Komponente des Übergangs ist das MAXScript-Bedingungsskript. Dies ist ein mit dem Controller verknüpftes Skript, das einmal pro Frame ausgeführt wird; es prüft einen beliebigen Aspekt oder mehrere Aspekte der Szene und entscheidet anhand des erfolgreichen (wahr oder 1) oder nicht erfolgreichen (falsch oder 0) Testergebnisses, ob der Übergang ausgeführt wird.
Character Studio führt Skripts pro zugewiesenem Vertreter einmal pro Frame aus, deshalb können Vertreter auch auf animierte Objekte und Effekte präzise reagieren.
Alle in Übergängen verwendeten Skripts haben die folgende Struktur:
fn [FunctionName] del t = ( [MAXScript code] if [MAXScript conditional] then 1 else 0 )
Der Eröffnungsabschnitt enthält "fn" (Funktion) gefolgt vom Funktionsnamen, der auch im Dialogfeld "Zustandsübergang" vorhanden sein muss, dann den Eingabeparametern "del t", und zuletzt "= (". Darauf kann kein oder ein beliebiger MAXScript-Code folgen.
Der Abschlussabschnitt enthält eine erforderliche MAXScript-Bedingung und dann "then 1 else 0". Wenn das Ergebnis der Bedingung wahr ist, wird 1 zurückgegeben (d. h. der Übergang soll stattfinden); wenn das Ergebnis der Bedingung falsch ist, wird 0 zurückgegeben (d. h. der Übergang soll nicht stattfinden). Sie können die Reihenfolge der Zahlen 1 und 0 umkehren ("then 0 else 1"), damit der Übergang nicht stattfindet, wenn die Bedingung wahr ist und umgekehrt. Schließlich muss die Funktion mit einer schließenden Klammer enden: ")".
Im Folgenden sind einige Beispiele für Skripts in kognitiven Controllern mit einer kurzen Erklärung aufgeführt. Diese Beispiele können Sie anpassen und in Ihren eigenen Szenen verwenden.
Dieses Beispiel-Skript testet die Anzahl der Partikel, die vom Partikelsystem "Spray01" ausgesendet wurden, und gibt ein positives Ergebnis zurück, wenn sie gleich 100 ist.
fn TestParticles del t = ( if (particleCount $Spray01) == 100 then 1 else 0 )
Dieses Beispiel-Skript testet die Position eines Objekts namens "Sphere03" und gibt ein positives Ergebnis zurück, wenn seine Position X>=150, Y>=0 und Z>=70 ist.
fn PositionCheck del t = ( if ($sphere03.pos.x >= 150 and $sphere03.pos.y >=0 and $sphere03.pos.z >=70) then 1 else 0 )
Dieses Beispiel-Skript testet den Parameter "Dichte" (Density) eines Nebeleffekts (fog) und gibt ein positives Ergebnis zurück, wenn er gleich 50 ist.
fn TestAtmos del t = ( atmos_fog = getAtmospheric 1 print atmos_fog.density -- to:debug if (atmos_fog.density == 50) then 1 else 0 )
Beachten Sie die zweite Zeile, in der die Nebelatmosphäre einer Variablen namens "atmos_fog" zugewiesen wird. Dies ist nur für Atmosphäreneffekte notwendig; bei den meisten Standardobjekten können Sie einfach ein Dollarzeichen "$" vor den Objektnamen stellen, wie in den beiden vorherigen Beispielen. Die "1" hinter dem Befehl "getAtmospheric" bezieht sich auf die Position der Atmosphäre im Dialogfeld "Rendereffekte" Liste "Effekte".
Wenn diese Zuweisung ausgeführt ist, können Sie eine Liste der Atmosphären-Eigenschaften abrufen, indem Sie in der MAXScript-Aufzeichnung folgenden Befehl eingeben:
ShowProperties atmos_fog
Auch die dritte Zeile im Beispiel-Skript ist für den kognitiven Controller nicht erforderlich; sie druckt lediglich das Ergebnis des Tests im Aufzeichnungsfenster, falls dies für die Fehlerbehebung benötigt wird.
Dieses Beispiel-Skript verwendet die MAXScript-Funktion "Distance", um die Entfernung zwischen einem Vertreter (delegate02) und einem Szenenobjekt (sphere01) abzurufen, und gibt ein positives Ergebnis zurück, wenn sie geringer als 30 ist.
fn TestDist del t = ( get_dist=distance $sphere01.pos $delegate02.simpos print (get_dist) if get_dist < 30 then 1 else 0 )
Wie im vorherigen Beispiel wird eine Variable verwendet; in diesem Fall dient sie zur Vereinfachung des Skripts. In der zweiten Zeile wird mit der Funktion "Distance" die Entfernung zwischen einer Kugel (sphere) und einem Vertreter (delegate) abgerufen und das Ergebnis der Variablen "get_dist" zugewiesen. Wenn Sie nicht nur einen bestimmten, sondern alle Vertreter testen möchten, die den kognitiven Controller verwenden, ersetzen Sie "$delegate02.simpos" durch "del.simpos".
In der dritten Zeile des Skripts wird die berechnete Entfernung an das Aufzeichnungsfenster gesendet, wo sie zur Fehlerbehebung verwendet werden kann. Diese Zeile wird für die Simulation nicht benötigt und kann gelöscht werden. Zuletzt wird der Wert mit der Konstanten 30 verglichen; wenn er niedriger ist, gibt das Skript 1 zurück, damit der Übergang durchgeführt wird.
Sie können auf der Grundlage dieses Skripts einen kognitiven Controller erstellen, der mehrere Suchverhaltensweisen/-zustände verwendet, um Vertreter zwischen beliebig vielen Objekten auf einem Pfad entlang zu bewegen. Sobald sich ein Vertreter in der gegebenen Entfernung von einem angegebenen Objekt befindet, findet der Übergang statt, und der Vertreter beginnt den nächsten Suchzustand, um sich zum nächsten Objekt zu begeben. Da der Übergang an jedem Frame getestet wird, können sich die Zielobjekte beliebig bewegen, wodurch sich eine anscheinend dynamische Animation ergibt.
Dieses Beispiel-Skript prüft den Parameter "Winkel" (Angle) des Modifikators "Biegen" (Bend), der auf einen Zylinder angewendet wurde, und gibt "Wahr" zurück, wenn er zwischen 70 und -70 einschließlich liegt.
fn TestBend del t = ( if ($cylinder01.bend.angle <= 70 and $cylinder01.bend.angle >= -70) then 1 else 0 )
Beachten Sie, dass in der If-Anweisung in der zweiten Zeile Klammern um den Text gesetzt sind, weil Skripttest zwei Bedingungen abfragt: ob der Winkel kleiner oder gleich 70 und ob der Winkel größer oder gleich -70 ist. Wegen des booleschen "and" zwischen den beiden Tests, gibt das Skript nur "True" zurück, wenn beide Bedingungen erfüllt werden.
Manchmal müssen Sie in einem Übergangsskript feststellen, welches Verhalten derzeit einen bestimmten Vertreter beeinflusst. Crowd stellt hierfür eine MAXScript-gestützte Methode zur Verfügung. Sie können sogar prüfen, ob ein bestimmter Vertreter als Ziel innerhalb des betreffenden Verhaltens angegeben ist. Ein Beispiel wäre eine Cocktail-Party, in der Betty Harry ausweicht, wenn Harry Sally sucht. Wenn Harry Sally jedoch ausweicht, dann sucht Betty Harry.
Das folgende Beispiel verwendet ein komplexeres Szenario, als es oben beschrieben wurde. Es folgt eine Übersicht.
Sechs Vertreter werden mit dem Wandabstoß-Verhalten in einem "Raum" festgehalten, der durch vier Raster definiert ist. Vertreter 1, 2, 3 und 5 wandern willkürlich durch die Simulation. Vertreter 4 verwendet jedoch einen kognitiven Controller (cc1), der ihn anweist, zunächst zu wandern und dann zu einem von drei Ausweichverhalten zu wechseln, wenn die Mitglieder eines von drei willkürlichen Paaren von Vertretern sich einander bis auf 50 Einheiten nähern. Jedes Ausweichverhalten zielt auf eine andere Gruppe von drei Vertretern ab. Zwei enthalten dabei Vertreter 2. Vertreter 6 wurde ein zweiter kognitiver Controller (cc2) zugewiesen, der das folgende Skript verwendet, um die Anweisung zum Wechsel auf ein Ausweichverhalten zu geben, wenn Vertreter 4 Vertreter 2 ausweicht. Das Herz des Skripts ist die folgende Zeile in der Funktion transfunc4:
(isDelAvoid = isDelegateAvoiding the_current_behavior.name "$Delegate04" "$Delegate02"
Laden Sie die Datei, drücken Sie F11, um das Aufzeichnungsfenster zu öffnen, und lösen Sie dann die Simulation. Im Aufzeichnungsfenster wird immer, wenn Vertreter 4 Vertreter 2 ausweicht, eine Meldung angezeigt.
Sie können dieses Skript in Ihren eigenen Simulationen verwenden, um zu prüfen, ob ein Vertreter einem zweiten ausweicht, indem Sie die Namen der Vertreter in der Zeile oben ersetzen und außerdem die Namen Ihrer Ausweichverhalten in der Liste in transfunc4 einsetzen, wobei Sie nach Bedarf Zeilen hinzufügen oder löschen.
Das Beispielskript illustriert einen zweiten wichtigen Punkt: Übergangsskripts mit kognitiven Controllern können mehrere Funktionen enthalten. Crowd führt zunächst die Funktion aus, die im Dialogfeld "Zustandsübergang" Feld "Übergangsbedingung" angegeben ist, und diese Funktion ruft eine oder mehrere weitere Funktionen im Skript auf, die natürlich ihrerseits Funktionen aufrufen können. In diesem Fall ruft transfunc4 die erste Funktion, isDelegateAvoiding, auf, und gibt ihre drei Parameter weiter.
Schließlich enthält das Skript eine Spezialfunktion, getBehaviorType, die ein Eingabeverhalten mit einer Liste bekannter Verhalten vergleicht und, wenn sie eine Entsprechung findet, das bekannte Verhalten zurückgibt. In diesem Fall geht transfunc4 die Liste der Verhalten durch, die derzeit "Delegate04" beeinflussen, wobei es alle mit getBehaviorType testet, und wenn ein Ausweichverhalten wirksam ist, überprüft es, ob "Delegate02" in diesem Ausweichverhalten ein Hindernis ist. Die Verwendung dieser Funktion ist effizienter und flexibler als der Test auf spezifische Verhalten, besonders, wenn Ihre Szene viele Verhaltensweisen des gleichen Typs enthält oder Sie die Einstellungen der Verhalten ständig bearbeiten. Sie können die zurückgegebenen Verhalten sehen, wenn Sie den Kommentar (doppelter Bindestrich) am Anfang der folgenden Zeile in transfunc4 entfernen:
-- format "Return Behavior: %\n" return_behavior fn isDelegateAvoiding theCurrentBehavior theCogDelegate theAvoidingDelegate = ( the_return = 0 counter = 1 for the_assignments in $Crowd01.assignments do ( if the_return == 1 then exit if the_assignments.delegate != undefined then ( if theCogDelegate == "$"+the_assignments.delegate.name then ( if the_assignments.cogcontrol != undefined then ( for the_cogcontrol_state in the_assignments.cogcontrol.states do ( if the_return == 1 then exit for the_cogcontrol_state_behavior in the_cogcontrol_state.behaviors do ( if the_return == 1 then exit if the_cogcontrol_state_behavior.name == theCurrentBehavior then ( for the_obstacle in the_cogcontrol_state_behavior.obstacles do ( if the_return == 1 then exit if "$"+the_obstacle.name == theAvoidingDelegate then ( --format "Set it true here !\n" the_return = 1 ) ) ) ) ) ) ) ) counter = counter + 1 ) the_return ) fn getBehaviorType val = ( if not iskindof val MAXRefTarg do return undefined theBehaviors = #( Speed_Vary_Behavior ,Orientation_Behavior ,Scripted_Behavior , Wander_Behavior ,Surface_Arrive_Behavior ,Path_Follow_Behavior , Seek_Behavior ,Avoid_Behavior ,Wall_Seek_Behavior , Space_Warp_Behavior,Wall_Repel_Behavior,Surface_Follow_Behavior , Repel_Behavior ) val_classID = val.classid for behav in theBehaviors do ( local behav_classid = behav.classid if val_classID[1] == behav_classid[1] and val_classID[2] == behav_classid[2] do ( return behav ) ) undefined ) fn transFunc4 del t = ( another_the_return = 0 counter = 1 for the_current_behavior in $Delegate04.behaviors do ( if another_the_return == 1 then exit return_behavior = getBehaviorType the_current_behavior --format "Return Behavior: %\n" return_behavior if return_behavior == Avoid_Behavior then ( isDelAvoid = isDelegateAvoiding the_current_behavior.name "$Delegate04" "$Delegate02" if isDelAvoid == 1 then ( format "$Delegate04 found to be Avoiding $Delegate02\n" format " Starting Transition in frame %:\n" t another_the_return = 1 ) ) counter = counter + 1 ) another_the_return )
Wenn mehrere Übergangstests ein positives Ergebnis zurückgeben, bestimmt Character Studio anhand der Prioritätseinstellung, welcher Übergang stattfinden soll. Sie führt den Übergang mit dem niedrigsten Prioritätswert aus. So wird beispielsweise ein Übergang mit dem Prioritätswert 0 vor einem mit dem Prioritätswert 1 ausgeführt usw.
Niedrigere Werte verursachen einen abrupteren Übergang, während höhere Werte einen allmählicheren Übergang ergeben.
Niedrigere Werte verursachen einen abrupteren Übergang, während höhere Werte einen allmählicheren Übergang ergeben.
Der Name der MAXScript-Funktion, die angibt, wann bzw. wie der Übergang durchgeführt werden soll.
Dieser Name muss auch am Anfang der Hauptfunktion im Skript nach "fn" erscheinen. Das Skript kann weitere Funktionen enthalten, die von der Hauptfunktion aufgerufen werden oder sich gegenseitig aufrufen.
Öffnet ein Editorfenster, mit dem das MAXScript-Skript des Übergangs bearbeitet, gespeichert und geladen werden kann.