BeamEmitter
Le BeamEmitter est un système de particules permettant de réaliser des arcs électriques et des coups de foudre. Il s'agit d'un type d'Emitter assez courant, utilisé par exemple pour les rayons lumineux au-dessus des relais du mode ONS, mais aussi pour les éclairs qui parcourent les mines flottantes dans le ciel cauchemardesque de CTF-Citadel.
Un BeamEmitter étire une feuille 2D entre son point de départ et son point d'arrivée. Chaque éclair entier, quelle que soit sa forme, est une seule particule. Par défaut, il s'agit d'une ligne parfaitement droite, mais il est possible d'ajouter des déviations aléatoires, pour courber et déformer l'éclair, et de créer des embranchements pour créer des décharges de foudre complexes.
Le BeamEmitter partage la quasi totalité des paramètres des autres systèmes de particules utilisables dans l'actor Emitter. Ce tutorial se concentrera donc sur les paramètres propres du BeamEmitter et sur ses spécificités.
Longueur et choix des cibles
Le BeamEmitter s'ajoute dans un Emitter de façon classique.
Il possède trois onglets de paramètres spécifiques, Beam, BeamNoise et BeamBranching. Ils permettent définir respectivement les points d'arrivée des particules, leur déformation et les embranchements.
Chaque éclair, lorsqu'il est généré, est étiré entre un point de départ (presque toujours l'actor Emitter lui-même, mais l'onglet Location permet de définir une autre origine, qui peut être une zone au lieu d'un point) et un point d'arrivée, qui peut être unique ou choisi dans une liste. Dans l'onglet Beam, le paramètre DetermineEndPointBy permet de choisir comment le point d'impact est déterminé :
- PTEP_Velocity : Permet de définir la direction de l'éclair en fonction de sa "vitesse", déterminée par son accélération et son paramètre StartVelocityRange, et sa longueur, en fonction de sa durée de vie (Time → LifeTimeRange). En d'autre termes, l'éclair (qui est fixe) est étiré entre son point de départ et un point calculé comme ayant réalisé le mouvement que ces paramètres décrivent.
- PTEP_Distance : L'éclair est toujours orienté suivant sa vitesse théorique, mais sa longueur est déterminée par le paramètre BeamDistanceRange. Il s'agit d'un simple Min/Max permettant de varier la longueur.
PTEP_Offset, PTEP_Actor, PTEP_TraceOffset et PTEP_OffsetAsAbsolute utilisent tous les entrées du paramètre BeamEndPoints, qui peut recevoir plusieurs éléments, chacun correspondant à un point d'impact potentiel.
Chaque BeamEndPoint numéroté possède un ActorTag, un offset permettant d'entrer des coordonnées et un paramètre Weight.
- PTEP_Offset : Les points d'arrivée sont déterminés par les coordonnées ajoutées manuellement dans l'offset du BeamEndPoint. Il s'agit de coordonnées relatives à la position de l'actor Emitter.
- PTEP_OffsetAsAbsolute Identique, mais les coordonnées sont alors absolues (calculées par rapport au centre de la map, où que se trouve l'Emitter).
- PTEP_TraceOffset : Fonctionne comme PTEP_Offset, à ceci près que si l'éclair rencontre un obstacle sur son chemin, le point de contact est utilisé comme point d'arrivée (la particule ne traverse pas les objets).
- PTEP_Actor : La foudre s'étire jusqu'à frapper l'actor dont le tag est paramétré dans ActorTag.
Si aucun BeamEndPoint n'est créé alors que le mode utilisé dans DetermineEndPointBy en demande, le BeamEmitter génère malgré tout des particules. Elles sont alors étirées vers le centre de la map (les coordonnées 0, 0, 0).
Le paramètre Weight permet de modifier les chances que chaque BeamEndPoint soit choisi comme point d'arrivée lors de la génération de l'éclair. Le valeur doit donc toujours être supérieure à 0, sinon le point n'est jamais choisi. Il suffit ensuite de donner des valeurs différentes aux différents points pour varier la fréquence de leur utilisation : si trois points sont utilisés avec des Weights de 1, 1 et 2, le troisième point sera ainsi frappé deux fois plus que les autres.
PTEP_DynamicDistance est un mode dynamique qui fonctionne comme PTEP_Distance mais permet de modifier la taille de l'éclair en temps réel à travers le code. Il s'agit d'un mode utile lorsque l'Emitter est créé et modifié en temps réel dans le jeu (par exemple lors du tir d'une arme) afin d'ajuster la longueur en cours de partie, mais sans intérêt pour un Emitter fixe ajouté dans un niveau (il ne fonctionne pas).
L'onglet Beam contient encore 4 paramètres :
- BeamTextureUScale et BeamTextureVScale : Définissent le nombre de répétitions de la texture sur l'axe horizontal et l'axe vertical (respectivement) pour éviter qu'elle ne soit trop étirée ou, au contraire, trop compressée. Les valeurs décimales sont acceptées.
- RotatingSheets : Par défaut, l'éclair est formé d'une seule feuille 2D faisant toujours face à la caméra. Il est possible d'en utiliser plusieurs entrecroisée pour créer un effet volumétrique plus prononcé. Les valeurs 0 et 1 ont un effet identique. Choisir 2 n'a pas d'effet visuel car la seconde feuille est créée perpendiculairement à la caméra et n'est donc jamais visible. À partir de 3, l'effet volumétrique devient évident.
- TriggerEndpoint : Très utile, ce paramètre permet, si DetermineEndPointBy = PTEP_Actor, de déclencher l'actor frappé par l'éclair comme s'il avait été activé par un Trigger. Un des usages courants est de déclencher un second Emitter qui émet des étincelles ou des particules, comme dans CTF-Citadel, ou pour activer un ScriptedTrigger pour déclencher un bruit, un mover, un téléporteur, etc. N'importe quel actor peut ainsi être déclenché, à condition qu'il soit spécifiquement visé avec son tag et non frappé au hasard.
En définissant la texture et la taille des particules ainsi que les points d'arrivée voulus pour les éclairs générés par le BeamEmitter, il est déjà possible de créer des coups de foudre frappant les endroits souhaités. En revanche, les éclairs sont parfaitement droits.
Dans cet exemple, la durée de vie des éclairs a été ramenée à 1 seconde, le StarSizeRange est abaissé à 20 et la texture est tirée du groupe Beams du package EpicParticles. Les points d'impact sont au nombre de 4 et utilisent PTEP_Offset.
Déformation
Le système de déformation des arcs électriques passe par deux étapes : d'abord, l'arc est divisé en un certain nombre de segments et chaque fin de segment peut recevoir une déviation aléatoire par rapport à la ligne droite que la foudre tente par défaut d'exécuter. Cela permet de donner une courbure aléatoire à l'arc dans son ensemble.
Après cela, l'arc entier est redivisé en un certain nombres de sous-segments qui peuvent eux-même recevoir des déviations pour ajouter des déformations sur la courbe principale de la foudre.
Ces paramètres se trouvent dans l'onglet BeamNoise, un onglet fourni en propriétés aux noms indéchiffrables au premier abord.
Courbure globale
Les principales déformations, qui donnent à l'arc sa forme globale, sont déterminées par deux paramètres : LowFrequencyPoints et LowFrequencyNoise. Le premier détermine combien de segments forment un éclair en donnant le nombre de points entre lesquels ils sont dessinés. Le nombre de points minimum est 2 (l'origine et le point d'impact), mais il faut au moins 3 LowFrequencyPoints pour que les arcs électriques puissent se déformer, le troisième point étant alors placé à mi-longueur de l'éclair. Ainsi, le nombre de segments sera égal au nombre de LowFrequencyPoints moins 1.
LowFrequencyNoise permet de spécifier un maximum et un minimum sur les trois axes. Pour chaque LowFrequencyPoint sur la longueur de la foudre, une déviation aléatoire de sa position est calculée entre ces bornes.
En variant la déviation minimale et maximale ainsi que le nombre de points, on peut donner une forme plus ou moins chaotique à chaque particule.
Le paramètre NoiseDetermineEndPoint est intéressant car il permet d'appliquer cette variation au point d'impact lui-même afin d'éviter que des éclairs très différents frappent exactement le même point de façon artificiellement mécanique. Il s'agit d'un paramètre intéressant lorsque le point d'impact est un actor visé avec son tag, car cela évite de frapper toujours précisément le pivot. En revanche, si le BeamEmitter doit déclencher l'actor en le frappant, il est préférable de garder ce paramètre sur faux pour éviter, par exemple, que la foudre n'enflamme un arbre alors qu'elle frappe à côté.
Courbures de détail
Tout au long de la courbure principale gérée par les LowFrequencyPoints, il est possible d'ajouter de la variation de détail qui donne une forme plus organique et anarchique à la foudre. Il faut pour cela utiliser HighFrequencyPoints et HighFrequencyNoiseRange, qui fonctionnent de la même façon mais à plus petite échelle.
Le nombre de HighFrequencyPoints est divisé sur toute la longueur de la foudre et non pas sur chaque segment. L'origine, le point d'impact et tous les LowFrequencyPoints sont compris dans le nombre total de HighFrequencyPoints. Leur nombre doit donc être au moins égal à LowFrequencyPoints, sous peine d'influer sur le comportement de ces deniers. Si l'on veut diviser chaque segment principal en 3, il font donc prendre le nombre total de segments (LowFrequencyPoints - 1, comme vu plus haut), le multiplier par 3 et y ajouter 1 :
FrequencyScale
Les deux modes de déformation peuvent être soumis à un FrequencyScale. Comme toutes les propriétés de type Scale (ColorScale, SizeScale, etc.), il permet de modifier la façon dont les paramètres concernés agissent au cours de la "vie" de la particule. Dans le cas du BeamEmitter, le Scale s'applique non pas au cours du temps mais sur la longueur de l'arc électrique.
Pour les déformations de détail (sur lesquelles l'effet du FrequencyScale est le plus visible), UseHighFrequencyScale doit être vrai et la liste HFScaleFactors doit contenir au moins un élément pour que le système fonctionne. Chaque élément est composé d'un FrequencyScale, qui permet de donner un coefficient multiplicateur appliqué sur le HighFrequencyNoiseRange, et un RelativeLength, qui détermine jusqu'à quel pourcentage de la longueur de l'arc ce coefficient est appliqué (0 est l'origine et 1 le point d'impact). Entre chaque élément, un "fondu" est appliqué, une transition douce entre deux états.
Par défaut, le FrequencyScale est calculé sur la longueur totale de la particule, mais il est possible de le répéter avec HFScaleRepeats. En utilisant une valeur de 1, une répétition est exécutée, ce qui signifie que dans le FrequencyScale utilisé, RelativeLength = 1 désigne non pas le point d'impact mais la moitié de la longueur de l'effet. Avec HFScaleRepeats = 2, le FrequencyScale est joué trois fois le long de l'éclair. La valeur par défaut, 0, indique une absence de répétition, donc un seul cycle étalé sur la longueur entière de la foudre.
Le même principe peut être appliqué aux LowFrequencyPoints en utilise UseLowFrequencyScale = vrai et en ajoutant des éléments à LFScaleFactors. La répétition peut également être activée avec LFScaleRepeats.
Déformation en temps réel
Il est enfin possible d'animer la foudre en temps réel. À intervalle régulier (et paramétrable), une partie des HighFrequencyPoints peut recevoir une nouvelle position. Trois paramètres permettent de définir quels points sont concernés, la force de l'effet et la fréquence de mise à jour.
- DynamicHFNoisePointsRange : Permet de sélectionner une plage de HighFrequencyPoints concernée par l'animation. Pour appliquer l'effet à tout l'éclair, Min doit être 0 et Max doit être supérieur ou égal à HighFrequencyPoints. Une portion seulement peut être choisie en indiquant les premier et dernier points de la partie que l'on souhaite faire bouger. Pour animer uniquement le tiers central d'un éclair composé de 30 HighFrequencyPoints, il faut ainsi choisir Min = 10 et Max = 20.
- DynamicNoiseRange : Définit, sur chaque axe, les bornes entre lesquelles chaque HighFrequencyPoint concerné reçoit une nouvelle position aléatoire, par rapport à sa dernière position connue.
- DynamicTimeBetweenNoiseRange : Le temps (en secondes) entre chaque rafraîchissement de la position des points dynamiques. Si la valeur est 0, le recalcul est constant, ce qui donne une sorte de tremblement fluide. Autrement, l'effet est saccadé.
Embranchements
L'onglet BeamBranching permet de transformer un éclair linéaire, étiré plus ou moins directement entre son origine et son arrivée, en un véritable coup de foudre qui se divise en plusieurs branches, chacune pouvant avoir son propre point d'impact et ses propres sous-embranchements.
Les embranchements sont créés à l'aide d'un autre BeamEmitter ajouté dans le même Emitter et dont les particules sont spawnées aléatoirement aux HighFrequencyPoints du BeamEmitter principal. Avant toute chose, il est donc nécessaire de réaliser un second BeamEmitter, générant des éclairs plus nombreux et de plus petite taille.
Ce BeamEmitter ne doit pas être activé par défaut car il sera "appelé" par le premier si nécessaire. Il faut donc régler, dans ses propriétés, Spawning → AutomaticInitialSpawning et Local → RespawnDeadParticles à faux. En conséquence, cet BeamEmitter secondaire semble inactif.
Les points d'impacts sont réglés de la même façon que pour le système principal et peuvent aussi déclencher des actors en les visant. C'est le principe utilisé dans CTF-Citadel : chaque éclair qui frappe une pointe sur une boule flottante active l'Emitter qui s'y trouve tout en générant des branches qui vont elles-même frapper d'autres pointes et y activer des Emitters.
Dans les paramètres du BeamEmitter principal, il faut indiquer le numéro du BeamEmitter secondaire dans BeamBranching → BranchEmitter afin d'indiquer quel système de particules est appelé.
L'effet n'est pas immédiatement visible. Il faut d'abord activer UseBranching pour indiquer au système principal que les embranchements sont activés, puis indiquer les chances de spawner des embranchements et leur emplacement.
- BranchHFPointsRange : Ce paramètre indique sur quels HighFrequencyPoints de BeamEmitter principal il est possible de spawner des branches du système secondaire. Si 20 HFPoints sont présent sur l'éclair principal, indiquer Min = 10 et Max = 20 ne fera spawner des branches que sur la dernière moitié de sa longueur, par exemple. Par défaut, les valeurs sont Min = à et Max = 1000, ce qui fait apparaître des branches sur la totalité de l'éclair (à moins que plus de 1000 HFPoints ne soient utilisés, ce qui est très improbable).
- BranchProbability : Détermine, pour chaque HighFrequencyPoint, le pourcentage de chances qu'une branche soit créée. Il s'agit d'une valeur comprise entre 0 (aucune chance) et 1 (spawne toujours).
- BranchSpawnAmountRange : Nombre de branches susceptibles de spawner à chaque embranchement. Par exemple, avec Min = 1 et Max = 3, chaque embranchement spawnera forcément au moins 1 branche et possiblement 2 ou 3, mais jamais plus.
Pour générer de manière uniforme des embranchements, il suffit d'indiquer Min = 1 et Max = 1 dans BranchProbability et BranchSpawnAmountRange.
Il est important de noter que l'éclair peut générer au maximum, sur toute sa longueur, autant de particules qu'indiqué dans les propriétés du BeamEmitter secondaire (General → MaxParticles). Si ce dernier gère ainsi au maximum 15 particules, un éclair du système principal ne pourra pas avoir plus de 15 branches, quels que soient le nombre de HighFrequencyPoints et la longueur de la foudre.
Le processus de décision du spawn des embranchements est complexe : lors du spawn de l'éclair principal, pour chaque HFPoint compris dans la plage délimitée dans BranchHFPointsRange en partant du premier et en descendant la liste dans l'ordre, une valeur aléatoire de BranchProbability est choisie entre les valeurs Max et Min indiquées, puis, un test est réalisé par rapport à cette valeur pour voir si, oui ou non, un spawn a lieu. Un nombre aléatoire de branches est alors choisi entre les valeurs Min et Max de BranchSpawnAmountRange et généré au point considéré.
Si BranchSpawnAmountRange est élevé et que BranchProbability est haut (Min et Max = 1, par exemple), il est possible que MaxParticles soit atteint dès le début de l'éclair et que plus aucune branche ne soit "disponible" pour la suite de la particule du système principal. Il faut dont soit augmenter le nombre de branches disponibles dans le BeamEmitter secondaire, soit diminuer les chances de spawn ou le nombre de branches par point.
La durée de vie des branches du BeamEmitter secondaire peut être supérieure à celle de l'éclair principal, ce qui cause un problème : les branches restent visibles après la disparition de l'éclair principal.
Le dernier paramètre restant de l'onglet BeamBranching, LinkupLifetime, permet d'éviter ce problème en supprimant les branches du système secondaire en même temps que l'éclair du système principal expire.
Notez enfin que le nombre maximum de particules du système secondaire est le nombre maximum de branches que le système principal peut avoir à un instant T, quel que soit le nombre d'éclairs qu'il affiche simultanément. Si le système principal génère 4 coups de foudre pouvant chacun accepter 10 branches mais que le système secondaire a MaxParticles = 10, il est possible que le premier éclair utilise d'un seul coup les 10 particules potentielles et que les trois autres soient en conséquence totalement dépourvus d'embranchements.
Le système d'embranchement peut être utilisé en cascade : un troisième BeamEmitter peut être utilisé pour créer des branches sur les particules du système secondaire et ainsi de suite.
Dans un tel cas, LinkupLifetime présente un problème : il peut être utilisé normalement pour que les particules rouges soient supprimées quand l'éclair principal disparaît, mais dans le cas du troisième système, les particules vertes restent en jeu jusqu'à l'expiration de la durée de vie des branches rouges au lieu de disparaître quand ces particules-mères sont supprimées. Il faut alors s'assurer que la durée de vie des particules soit identique dans les deux systèmes (voire les trois).
RSS Feed