Diese Scene-Graph-Funktion befindet sich in einem experimentellen Zustand. Markiere in den Projekt-Einstellungen das Kontrollkästchen, um die Einstellung „Experimentelle Scene-Graph-Funktionen“ zu aktivieren, um auf diese experimentellen Funktionen in Scene Graph zuzugreifen.
Sollte dein Projekt experimentelle Scene Graph Funktionen enthalten, werden sie während des Validierungsprozesses im Creator-Portal abgefangen. Du erhältst eine Benachrichtigung über Assets, die deine Fähigkeit einschränken, deine Insel zu veröffentlichen. Deaktiviere die experimentellen Funktionen in den Projekt-Einstellungen, um deine Insel zu veröffentlichen.
Szenendiagramm hat eine Funktion, die in alle Entitäten und Komponenten eingebaut ist und einzelne Events oder eine Kette von Events in deinem Szenendiagramm erstellt, genannt Szene-Events. Szenen-Events sind Kommunikationsprotokolle, die eine Möglichkeit für verschiedene Teile eines Szenendiagramms bieten, miteinander zu kommunizieren, indem sie neues Verhalten für Entitäten und Komponenten überschreiben und definieren.
Szenen-Events können projektübergreifend wiederverwendet werden. Du kannst Szenen-Events erweitern, indem du zusätzliche Events hinzufügst oder das Verhalten von Entitäten und Komponenten in einer Ereigniskette veränderst, um etwas anderes zu tun.
Mehrere Komponenten können auf ein Szenen-Event reagieren und die Events können in der Scene-Diagramm-Hierarchie nach oben oder nach unten gesendet werden. Es ist vielleicht hilfreich, sie sich als Nachrichten vorzustellen, die über das Szenendiagramm weitergeleitet werden, sodass jede Komponente die Möglichkeit erhält, auf die Nachricht zu reagieren.
Zum Beispiel, wenn du ein Grab mit Szenendiagramm einrichtest, kannst du Szene-Events nutzen, um eine Kette von Events zu definieren, die beginnen, wenn die statischen Mesh-Tore aufschwingen. Das Öffnen der Tore könnte als Ausgangspunkt für eine Kette von Events dienen, die dazu führen, dass ein Partikeleffekt von Geistern hinter Grabsteinen hervorfliegt und unheimliche Musik zu spielen beginnt.
Das kann ein Szene-Event sein, das du mehrfach auf dem Friedhof verwendest, oder du könntest das Event so optimieren, dass du die Grundfunktionen des Szene-Events nutzen kannst – eine Art von statischer Mesh-Tür, die geöffnet wird und eine Reihe von Events auslöst.
Bei Szenen-Events geht es darum, Teile des Szenediagramms voneinander zu entkoppeln, damit sie über Nachrichten kommunizieren können, anstatt sich direkt aneinander zu binden.
Wie Szene-Events funktionieren
Verse wird verwendet, um Events über das Szenendiagramm an bestimmte Entitäten und Komponenten zu senden. Um ein Szenen-Event in einer component zu behandeln, setzt du die vorhandene OnReceive(scene_event):logic Funktion in der component außer Kraft. Jedes Szenen-Event, das deine Komponente durchläuft, ruft dann diese Funktion auf und bietet dir eine Möglichkeit, auf das Event zu reagieren.
Ein Szenen-Event ist eine beliebige Klasse, die das scene_event Interface implementiert. Szene-Events können auf drei Arten gesendet werden: SendUp, SendDown, oder SendDirect.
SendUp
SendUp sendet das Event an die betroffene Entität und deren Parents. Die Parent-Entität übergibt dann dieses Event an ihren Parent und so weiter, bis sie die Simulation Entität erreicht, der die Entitäten in ihrer Welt übergeordnet sind.
Der Sender weiß nicht genau, welcher Empfänger das Event behandeln wird, oder ob überhaupt etwas auf das Event reagieren wird. Diese Art des Sendens eignet sich hervorragend für das Versenden von Telemetrie, Signalisierung an übergeordnete Level-Systeme oder verschiedene Arten von Anfragen, die bearbeitet werden können oder nicht.
Stell dir zum Beispiel vor, du schlägst mit einem Schwert auf die Füße eines Charakter ein, wobei der Fuß tief in der Hierarchie steht. Da das Bein möglicherweise nicht mit Schaden umgehen kann, pflanzt sich das Ereignis bis zur Basis des Charakters fort, wo du eine damage_receiever_component platziert hast, die das Schadensereignis empfangen und den Treffer verarbeiten kann.
In dem folgenden Diagramm ist die Parent-Entität das Event mit der Bezeichnung 1, das in der ersten grünen Entität ausgelöst wird. Der SendUp-Aufruf beginnt bei der Parent-Entität in der Hierarchie und sendet das Ereignis nach oben an die Simulationsentität.
SendDown
Alternativ könntest du die Simulation-Entität als Katalysator verwenden und eine Reihe von Änderungen an den Baum der Entitäten zu senden. SendDown sendet das Event an die betroffene Entität und alle Children. Jedes Child gibt dieses Event dann an seine Children weiter.
Dies könnte in einer Situation verwendet werden, in der ein globales Event eingetreten ist und alles in der Szene eine Möglichkeit haben sollte, darauf zu reagieren.
Direkt senden
SendDirect sendet ein Event direkt an die betroffene Entität, gibt das Event aber nicht an Parents oder Children weiter. Dies wird verwendet, um eine bestimmte Entität oder Komponente als Ziel zu verwenden, wie in dem folgenden Diagramm dargestellt.
Verbrauchen von Events
Wenn ein Event in einer Entitätshierarchie nach oben oder unten gesendet wird, können einzelne Komponenten sich entscheiden, nicht auf das Event zu reagieren. Die Komponente markiert das Event als abgeschlossen und sendet das Event nicht an seine Children oder Parents – es fungiert im Grunde als Aus-Schalter.
Durch das Verbrauchen von Ereignissen kannst du den Umfang der Wirkung eines Ereignisses kontrollieren. Es funktioniert auf zwei Arten:
Das Event ist nur für eine Entität relevant, nicht für die Children der Entität noch deren Parents.
Es wird vermieden, das relevante Event direkt an die Children oder Parents einer Entität zu senden.
Indem du es vermeidest, ein Event an ein Child oder Parent zu senden, kannst du entscheiden, was dieses Event für die Parents und Children der Entität bedeutet, und es so einrichten, dass du ihnen manuell ein anderes Event als Antwort senden kannst, um mehr Kontrolle darüber zu haben, wie diese Entitäten auf das ursprüngliche Event reagieren.
Zum Beispiel erhält eine Entität über SendDown ein Schadens-Event. Eine Komponente einer Entität könnte sich entscheiden, darauf zu reagieren, indem sie Kondition wegnimmt, und würde dieses Event nicht weiter durch die Entität-Hierarchie senden, da es nicht notwendig ist, dass die Child-Entitäten Schaden nehmen.
Wenn jedoch ein Punktesystem über der empfangenden Entität platziert ist, müsste die Parent-Kette der Entität die Schadensinformationen senden, um dem Spieler eine Medaille für das Beschädigen von Feinden zu verleihen. In dieser Situation könnte ein SendUp-Aufruf an der empfangenden Entität mit einem speziellen Event verwendet werden, das die Schadenspunktzahl an eine Parent-Komponente sendet, die auf die Punkteinformationen lauscht.
Verbrauchen von Events während SendUp und SendDown
Events können während der Ereignispropagation, die entweder durch SendUp oder SendDown ausgelöst wird, verbraucht werden,indem True von der OnReceive(SceneEvent:scene_event):logic Implementierung einer Komponente zurückgegeben wird.
Wenn eine Komponente einer Entität sich dafür entscheidet, ein Event während eines SendUp zu verbrauchen, rufen alle Komponenten der Entität weiterhin ihre jeweiligen OnRecieve Callbacks auf. Die Verteilung wird dann gestoppt und nicht an den Parent der Entität weitergegeben.
Wenn eine Komponente einer Entität sich dafür entscheidet, ein Event während eines SendDown zu verbrauchen, rufen alle Komponenten der Entität weiterhin ihre jeweiligen OnRecieve Callbacks auf. Das Event wird nicht an die Children der Entität weitergegeben. Das Event wird jedoch weiterhin an die übrigen Entitäten auf demselben Level übergeben.
In dem Diagramm unten siehst du, dass während Szene Event 4 in der Kette von Events fortgesetzt wird, Szene Event 3 jedoch nicht.
Ein Szenen-Event erstellen
Vor dem Erstellen von Szenen-Events sind einige anfängliche Einrichtungs- und Sequenzarbeiten erforderlich. Erstelle die unten aufgeführten Assets, um Mesh-Komponenten mit Bäumen und die Partikeleffekte mit dem entsprechenden Effekt zu bevölkern. Wenn du die Partikeleffekt-Assets speicherst, werden sie automatisch in einer Verse-Datei namens Assets.digest.verse als Verse-Objekte gespeichert, auf die du in deinem Code referenzieren kannst.
Damit der Blitzschlag an einem zufälligen Punkt am Himmel über einer Entität beginnt und an einer Szenendiagramm-Entität auf dem Boden endet, modifiziere den Blitzschlag-Blitzschlag-VFX wie folgt:
Stelle die Strahl-Emitter-Einrichtung > Strahlstart als Vektor zur Position hinzufügen, setze Position auf SimulationPosition, setze Vektor auf Zufallsbereichsvektor mit Minimum als (-200,0, -200,0, 1000) und Maximum als (200,0, 200,0, 2000,0).
Stelle die Strahl-Emitter-Einrichtung > Strahlende als SimulationPosition.
Jetzt beginnt der Blitzschlag irgendwo im Himmel über der Entität und endet an der Entität, an die
particle_system_componentangehängt ist.Statisches Mesh Bäume und Gras
Modelliere deine eigenen Bäume mit dem Modellierungsmodus.
Füge diese Assets zu Entitäten hinzu und platziere dann mehrere Lightning-Ziel-Entitäten im gesamten Scene Graph, wo der Blitz einschlagen könnte. Jede dieser Blitzschlag-Entitäten hat eine Blitzschlag particle_system_component, die bereit ist, die Befehle zu empfangen, die du in deinem Szenen-Event definierst. Es ist keine zusätzliche Einrichtung erforderlich.
Entitäten können in einem Prefab verschachtelt oder völlig separat und in der Szene verteilt sein.
Migriere Assets aus dem UE Starter-Inhaltspaket, um das Feuer-VFX zu erstellen, oder du kannst die Blitzschlag- und Feuer-VFX in UE erstellen und diese Assets in dein UEFN-Projekt migrieren.
Erstelle alle deine Assets, bevor du Entitäten zu der Szene hinzufügst. Auf diese Weise werden alle von dir erstellten Statisches-Mesh-Assets im Mesh-Komponentenmenü angezeigt.
Wenn die Entitäten an Ort und Stelle sind, denke über die Sequenz der Events nach, die den Waldbrand verursachen, und überlege dann Namen für die Events, die beschreiben, was das Event tut. Folge anschließend dem Verse-Tutorial im Abschnitt Kodieren des Verhaltens.
Benennungskonventionen für Szenen-Events
Du kannst bei der Benennung eines Szene-Events so viele Zeichen verwenden, wie du brauchst. Die Nomenklatur sollte deinen Event beschreiben und die Absicht des Events deutlich machen, zum Beispiel damage_taken_event, health_power_up_event, usw.
In der Sequenz der Waldbrände gibt es zwei wichtige Events:
Blitzeinschlag
Feuer breitet sich aus
Um zu beschreiben, was diese Events bewirken, bennenne den Blitzeinschlag-Event struck_by_lightning_event und das Feuerausbreitungs-Event fire_propagation_event.
Sequenz von Events
Wenn du ein Szenen-Event erstellst, betrachte es als ein Interface, das Effekte in der Hierarchie von Entitäten und Komponenten hat, die Effekte nach oben und unten haben. Da Szenen-Events außerdem von anderen Personen verwendet werden können, solltest du überlegen, wie ein anderer Entwickler auf deinem Event aufbauen oder dein Event in seinem eigenen Szenendiagramm verwenden könnte.
Das Szenen-Event, das du erstellst, erstellt einen Bericht über die wichtigsten Events, die ablaufen, bevor ein anderer Event ausgelöst wird, das sich auf das Parent-Event bezieht. Die Sequenz der Events ist also wie folgt:
In der Welt tritt ein Szenen-Event mit dem Namen
struck_by_lightning_eventauf.Entitäten melden, ob sie vom
Strike_by_lightning_eventgetroffen wurden oder nicht. Vom Blitz getroffene Entitäten lösen dasfire_propagation_eventaus.Das
fire_propagation_eventlässt andere Entitäten entscheiden, ob sie nahe genug amfire_propagation_eventsind, um ebenfalls Feuer zu fangen.Das
fire_propagation_eventbreitet sich auf die anderen Mesh-Komponenten aus
Das fire_propagation_event wird so lange ausgeführt, bis jede Mesh-Komponente, die festlegt, dass sie nahe genug am fire_propagation_event war, Feuer gefangen hat. Es sollte einem echten Waldfeuer ähneln, wenn es in der Szene läuft.
Erweitern einer Sequenz
Während der struck_by_lightning_event den fire_propagation_event verursacht, kannst du das Spiel erweitern, indem du neue Dinge hinzufügst, die das Feuer propagieren. Zum Beispiel fügst du ein explosives_event hinzu, das ein fire_propagation_event sendet, wenn es explodiert.
Eine andere interessante Sache an Szenen-Events ist, dass die Entitäten, die das fire_propagation_event verarbeiten, nicht wissen müssen, was das Feuer verursacht hat, nur, dass etwas sie dazu bringt, zu überlegen, ob sie brennen sollen oder nicht. Dies erleichtert die Wartung des Codes aus zwei Gründen:
In der Welt tritt ein Szenen-Event mit dem Namen
struck_by_lightning_eventauf.Es ist einfacher zu ändern, wie sich das
struck_by_lightning_eventverhält, ohne Entitäten zu beschädigen, die sich nur um dasfire_propagation_eventkümmern.Es ist einfacher, ein
explosive_eventzu schreiben, weil brennbare Dinge sich nur um dasfire_propagation_eventkümmern.
Kodierung des Verhaltens
Wenn das Scene Graph mit allen notwendigen Entitäten abgeschlossen ist, verwende den folgenden Code, um ein Szene-Event zu erstellen, das mit einem Blitzeinschlag beginnt und dazu führt, dass ein Feuer in den Bäumen ausbricht und Feuerschaden verursacht.
Das Assets.digest.verse sucht automatisch nach den Verse-Objekten, um sie in der Szene zu referenzieren. Die von Ihnen erstellten Partikeleffekte werden unter einem VFX-Modul referenziert.
VFX := module:
Fire_NS<scoped {/InvalidDomain/Scene_Events_Test}> := class<final><public>(particle_system_component):
Lightning_NS<scoped {/InvalidDomain/Scene_Events_Test}> := class<final><public>(particle_system_component):
Schritt 1: Erstelle eine Scene Graph Komponente
Um ein Szenen-Event in UEFN zu erstellen, öffne das Verse-Menü in der Menüleiste und wähle Verse-Explorer aus der Dropdown-Liste aus. Das Verse-Explorer-Panel öffnet sich im Editor. Dieses enthält die Liste der Verse-Dateien, die mit deinem Projekt assoziiert sind.
Erstelle eine neue Verse-Datei, indem du wie folgt vorgehst:
Klicke mit der rechten Maustaste auf den Projektnamen oben in der Liste.
Wähle Neue Verse-Datei zum Projekt hinzufügen aus der Dropdown-Liste aus. Das Fenster Verse-Script erstellen wird geöffnet.
Wähle die Szenendiagramm Komponente aus der Liste der Verse-Dateien aus und nenne die Datei fire_event_component.
Klicke auf Erstellen. Die Datei öffnet sich automatisch in Visual Studio Code (VS Code) und enthält Boilerplate-APIs, die zum Erstellen eines neuen Komponentenverhaltens erforderlich sind.
Wenn du bereit bist, dein Script zu testen, öffne das Verse Menü und wähle Verse-Code aus der Dropdown-Liste aus. Wähle anschließend die Verse-Schaltfläche aus, um deinen Code auszuführen.
Schritt 2: Füge Verse-Bibliotheken hinzu
Beginne dein Szene-Event, indem du zunächst die Sequenz der Events und Bedingungen aufbaust, die dazu führen, dass der Blitz einschlägt. Nachdem der Blitzeinschlag-Event definiert wurde, erstelle den Waldbrand-Event, indem du die Eigenschaften des Brandschadens, die Feuerausbreitungsprotokolle und die Feuerlöschprotokolle definierst.
Füge die folgenden Bibliotheken deinen Komponente hinzu, um sicherzustellen, dass du räumliche Mathematik für den Ort deines Blitzeinsschlag und Feuers verwenden, Gleichzeitigkeit und andere Verse-Funktionen erstellen kannst.
Verseusing { /Verse.org/SpatialMath } using { /Verse.org/Random } using { /Verse.org/Concurrency } using { /Verse.org/Simulation } using { /Verse.org/SceneGraph }
Schritt 3: Definiere die Blitzschlag-Event-Klasse
Diese Event-Klasse bestimmt die Quellposition für den Blitz, den Blitzeinschlagpunkt und den DamageRadius des Trefferpunktes.
Erstelle eine Event-Klasse mit dem Namen
stroke_by_lightning_event := class(scene_event):. Die Klasse definiert die Eigenschaften des Szenen-Events in konstanten Ausdrücken, die beschreiben, wo das Blitzschlag-Event in der Szene eintritt, mit einem Vektor für Positionsinformationen und den Schadensradius des Blitzeinschlags mit einemfloat-Wert.Verse# Event to indicate an entity is struck by lightning struck_by_lightning_event<public> := class(scene_event): # Lightning hit location HitLocation:vector3 = vector3{} # Lightning damage radius DamageRadiusCentimeters:float = 100.0
Schritt 4: Erstelle eine Wetterkomponente und füge bearbeitbare Eigenschaften mit Variablen hinzu
Verwende bearbeitbare Eigenschaften und Variablen, um festzulegen, ob der Blitz in der Szene erscheint, zufällige Blitze einschlagen, die Zeit zwischen den Einschlägen und den Schadensradius des Blitzeinschlags.
Definiere, wie sich die Beleuchtung verhält, indem du
bearbeitbareEigenschaften zu einer Komponentenklasse mit dem Namenlightning_weather_component := component ():hinzufügst. Umriss der bearbeitbaren Eigenschaften die minimale und maximale Anzahl für die Zeit zwischen Blitzeinschlägen und den Schadensradius dieser Einschläge in Zentimeter.Verse# Component that lives on an entity, and randomly creates lightning strikes lightning_weather_component<public> := class<final_super>(component): # Minimum random time between lightning strikes @editable MinRandomLightningDelaySeconds:float = 10.0 # Maximum random time between lightning strikes @editable MaxRandomLightningDelaySeconds:float = 60.0
Schritt 5: Definiere die Blitzschlag-Events
Verwende eine Methode, um Blitzschlag-VFX zu prüfen und verwende deren Start- und End-Strahl Eigenschaften, um zu bestimmen, wie nah die Mesh-Komponenten an den VFX sind, und sende diese Informationen im Event nach oben und unten.
Erstelle eine
OnSimulateBedingungsMethode.VerseOnSimulate<override>()<suspends>:void=Erstelle und füge eine
Schleifehinzu, die die Beleuchtungskomponente zufällig spielt und aussetzt, indem du eine Konstante verwendest, die minimale und maximale Delay-Werte für die Spielzeit verwendet.Verseloop: # Sleep for a random delay before next lightning strike RandomDelay := GetRandomFloat(MinRandomLightningDelaySeconds, MaxRandomLightningDelaySeconds) Sleep(MaxRandomLightningDelaySecondsFüge einen
if-Ausdruck hinzu, der die Simulations-Entität verwendet, um andere Entitäten in der Simulation zu suchen, da alle anderen Entitäten Children der Simulation-Entität sind. Auf diese Weise kann eine zufällige Entität ausgewählt werden, die vom Blitz getroffen wird, anstatt Kollisionen zu verwenden, um Entitäten in der Szene zu finden.Verse# Randomly hit an entity in the world with lightning if (SimEntity := Entity.GetSimulationEntity[]):Als nächstes muss der Code ein Ziel vorgeben, in das der Blitz einschlagen soll.
Füge einen
thenAusdruck hinzu, der eine Anforderung sendet, das Beleuchtungsziel von der SimEntity zu sein. Füge dann einen bedingtenif-Ausdruck hinzu, der auf diese Übertragung reagiert und bewirkt, dass alle Entitäten, die reagieren können, ein Event zurück an die SimEntity senden. Als Nächstes musst du die Quelle des Blitzes finden, da ein Strahl-Emitter zwei Punkte für den Beginn und das Ende des Strahls verwendet.VerseLightningTargets := for (EntityWithLightning : SimEntity.FindDescendantEntitiesWithComponent(particle_system_component)): EntityWithLightning if: LightningTargets.Length > 0 RandomIndex := GetRandomInt(0, LightningTargets.Length - 1) RandomEntity := LightningTargets[RandomIndex]Rufe die
LightningVFXComponentan der zufälligen Position mit einer if-Anweisung auf. Füge dann einen then-Ausdruck hinzu, der den Strahl-Partikeleffekt an der für die Quelle und Ziel-Position festgelegten Position abspielt.Die
lightning_entityverwendet Strahl-Emitter-Einrichtung > Strahlstart, um das Beleuchtungsevent an zufälligen Punkten am Himmel abzuspielen.LightningVFXComponentverwendet dann die Strahlpartikel-Option Strahl-Emitter-Einrichtung > Strahlende, um zu bestimmen, wo das Ende des Strahlpartikels in der Szene erscheint. Die Einstellung ist auf Simulation Position festgelegt, die Endkoordinaten des Partikeleffekts für dielightning_entityverwendet.Erstelle und definiere anschließend den Schaden, der vom
struck_by_lightning_eventverursacht wird, mithilfe der Quell- und Zieldaten, um zu lokalisieren, wo der Schaden auf dem Mesh-Komponentenziel auftritt, und verwendeDamageRadius, um den vom Blitzschaden betroffenen Gebiet zu beschreiben. Dieses Event wird an die Simualtions-Entität gesendet, um eine zufällige Dauer hinzuzufügen, also beende die Kette der Events mitSimulationEntity.SendDown(Event).Verseif (VFX := RandomEntity.GetComponent[particle_system_component]): RandomDurationOfStrike := GetRandomFloat(MinRandomLightningDurationSeconds, MaxRandomLightningDurationSeconds) VFX.Play() Sleep(RandomDurationOfStrike) VFX.Stop() else: Print("Could not find particle_system_component on this entity") Event := struck_by_lightning_event: HitLocation := Entity.GetGlobalTransform().Translation
Schritt 6: Definieren die Feuer-Events
Erstelle Event-Klassen, die den Schadenmenge definieren, den das Feuer verursacht, und ob sich das Feuer basierend auf dem Schaden in der Szene propagieren soll.
Erstelle zwei Klassen. Eine
fire_damage_eventKlasse und einefire_propagation_eventKlasse, die prüfen, obDamageAmountausgeführt wird, und das Feuerpartikel abspielen, wennDamageAmountden Float-Schwellenwert erreicht.Verse# Event indicating an entity was damaged by fire fire_damage_event<public> := class(scene_event): BurningEntity:entity = entity{} DamageAmount:float = 100.0 # Event indicating an entity propagates fire fire_propagation_event<public> := class(fire_damage_event): FireRadiusCentimeters:float = 100.0Erstelle eine
flammable_component-Klasse, die bestimmt, dass ein Mesh brennbar ist, und die bearbeitbaren Eigenschaften, die festgelegt werden können, damit Meshs in der Szene Feuer fangen.Verse# Component that makes something flammable flammable_component<public> := class<final_super>(component): # Fire damage amount applied every second @editable FireDamageAmount:float = 10.0 # Fire tries to propagate on this interval @editable FirePropagationIntervalSeconds:float = 10.0Eine Bedingungsvariable wird zum
flammable_eventhinzugefügt, die entscheidet, ob die Feuer-VFX abgespielt werden oder abgespielt werden sollten.Verse# Is it on fire? var IsOnFire:logic = falseEine
IsCloseEnoughToBurningEntityToIgnite-Funktion bestimmt, ob das Feuer nahe genug ist, um weitere Feuer-VFX-Events auszulösen.Verse# Is this component close enough to the source of a fire propagation event to burst into flames? IsCloseEnoughToBurningEntityToIgnite(FirePropogationEvent:fire_propagation_event)<decides><transacts>:void = EntityLocation := Entity.GetGlobalTransform().Translation FirePropogationLocation := FirePropogationEvent.BurningEntity.GetGlobalTransform().Translation DistanceToFire := Distance(EntityLocation, FirePropogationLocation) DistanceToFire <= FirePropagationEvent.FireRadiusCentimetersEine
IsCloseEnoughToLightningToIgniteFunktion bestimmt, ob der Blitzeineinschlag nahe genug am Mesh war, so dass es in Flammen aufgeht.Verse# Is this component close enough to a lightning strike to burst into flames? IsCloseEnoughToLightningToIgnite(LightningEvent:struck_by_lightning_event)<decides><transacts>:void = EntityLocation := Entity.GetGlobalTransform().Translation LightningStrikeLocation := LightningEvent.HitLocation DistanceToFire := Distance(EntityLocation, LightningStrikeLocation) DistanceToFire <= LightningEvent.DamageRadiusCentimetersDie Funktion OnRecieve bestimmt, welche Meshes Feuer fangen, sobald die Funktion IsCloseEnoughToBurningEntityToIgnite die Nähe der Feuerausbreitung bestimmt, und die Variable IsCloseEnoughToLightningToIgnite die Nähe des Blitzeinschlags zum Mesh bestimmt.
Verse# Receive scene events OnReceive<override>(SceneEvent:scene_event):logic = # Burst into flames if lightning hit close enough if (LightningEvent := struck_by_lightning_event[SceneEvent], IsCloseEnoughToLightningToIgnite[LightningEvent]): Ignite() # Burst into flames if something close enough is burning if (FireEvent := fire_propagation_event[SceneEvent], IsCloseEnoughToBurningEntityToIgnite[FireEvent]): Ignite() falseEine
Ignite methodwird verwendet, um den Effekt automatisch durch eine bedingte if-Anweisung abzuspielen, die nach dem Feuerpartikel-System sucht. EinethenAnweisung definiert, ob es True ist, dass die Komponente die Feuer-VFX abspielt.Füge der Methode asynchrone Aufgaben hinzu, um das Feuerpartikel-System Fire_NS zu prüfen, damit das Feuer spawnt und sich ausbreitet, wenn es aufgerufen wird.
Verse# Burst into flames Ignite():void = if (not IsOnFire?): set IsOnFire = true # Add a new fire VFX component FireVFX := VFX.Fire_NS{Entity := Entity} Entity.AddComponents(array{FireVFX}) # Spawn async tasks to implement the state of being on fire
Schritt 7: Definiere das Endes des Feuer-Event
Als Nächstes erstellst du eine Reihe von Methoden, die bestimmen, wann Mesh-Komponenten in Flammen aufgehen, wann die Flammen erlöschen, welchen Schaden ein Feuer verursacht und wann sich das Feuer ausbreiten soll.
Erstelle nun eine
Extinguish-Methode,die den Feuereffekt stoppt, indem sie mit Bedingungsanweisungen nach Komponenten sucht, die den Feuereffekt spielen, um das Feuerpartikelsystem zu finden und den Effekt zu entfernen.Verse# Put out the flames Extinguish():void= if (IsOnFire?): set IsOnFire = false # Remove the fire VFX component if (FireVFX := Entity.GetComponent[particle_system_component]): FireVFX.RemoveFromEntity()Erstelle eine
OnFire-Methode, die eine Schleife verwendet, die denFireDamageüberwacht und das Event die Entitätenkette gegen Ende des Events sendet und bewirkt, dass die Wiedergabe des Events gestoppt wird.Verse# Suspends function called when we're on fire OnFire()<suspends>:void= # Damage self every second loop: # Fill out a fire damage event - replace this with whatever properties should go here FireDamage := fire_damage_event: DamageAmount := FireDamageAmount Entity.SendDown(FireDamage) Sleep(1.0)Abschließend erstellst du eine
FirePropagation Methode, die eineSchleifeverwendet, um das Feuer über die Kette der Entitäten zu verteilen, sodass diese gelöscht werden, wenn sie die Simulations-Entität erreichen.Verse# Propagate fire to other entities FirePropagation()<suspends>:void= loop: Sleep(FirePropagationIntervalSeconds) if: SimulationEntity := Entity.GetSimulationEntity[] FirePropagationEvent := fire_propagation_event{ BurningEntity := Entity } then: # Broadcast fire propagation event down from simulation entity SimulationEntity.SendDown(FirePropagationEvent)
Wenn der Code abgeschlossen ist, kompiliere den Code und füge die entsprechenden Entitäten zum Szenendiagramm hinzu, um die Blitzeinschläge und Waldfeuereffekte zu unterstützen. Füge danach flammable_component zu den Entitäten in der Szene hinzu, die Feuer fangen sollen. Es muss eine Entität der obersten Ebene unter der simulation entity geben, wobei die lightning_weather_component das Wetter steuert.
Sobald alle Entitäten mit den entsprechenden Szenenevents aktualisiert wurden, startest du eine Live-Bearbeitung Sitzung, um zu sehen, wie dein Code in der Szene funktioniert.
Ergebnis
Kopiere den Code und füge ihn in dein Projekt ein, um zu sehen, wie das Szene-Event funktioniert.
lightning.verse
using { /Verse.org }
using { /Verse.org/Native }
using { /Verse.org/Random }
using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
using { /Verse.org/SpatialMath }
# Event to indicate an entity is struck by lightning
struck_by_lightning_event<public> := class(scene_event):
fire.verse
using { /Verse.org }
using { /Verse.org/Native }
using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
using { /Verse.org/SpatialMath }
# Event indicating an entity was damage by fire
fire_damage_event<public> := class(scene_event):
BurningEntity:entity = entity{}
DamageAmount:float = 100.0