Lightning Arc

Overview

This entity can be placed in the levels and Track View cinematics to create electric like effects. It creates electrical arcs between two or more points.

You can find it in the RollupBar create tab under Entity. In the Browser expand 'Environment' where you find 'LightningArc'.

After being placed, it will need to have a lightning preset, a material assigned and at least one Target entity in order to work.

While active, it will spark a new electric arc to one of the assigned entity targets randomly.

The entity will be able to trigger new sparks either in game mode or AI/Physics mode. In editor mode, the entity will always be disabled.

Making it work - Checklist

Here is a list of steps you need to take in order to make sure it works:

  • Your LightingArc entity is Active.
  • Your LightingArc entity is Entity-linked to at least one TagPoint.
  • Rename the Link name to Target (Is NewLink by default).
  • AI/Physics is on.
  • Your LightingArc has a lightning material assigned (Materials/Effects/Lightning).
  • The ArcPreset on your LightingArc object has a valid entry assigned (Default is assigned by default).
    • To make changes checkout \Libs\LightningArc\LightningArcEffects.xml.
    • After changes reload via CVar: g_reloadGameFx.
    • Refer to the Lightning Preset Setup section below.

Parameters

Parameter

Description

Active

If set to true, it will automatically start sparking after jumping into game.

ArcPreset

A valid preset must be given. This will tell how the lightning arc will look like.

Delay

Delay in seconds between sparks.

Delay Variation

Time randomization in seconds.

Material

Any material with Illum shader can be used but a specific setup will be needed to have good looking spark effects. To apply the material to the LightningArc, just normally apply the material to the entity like you normally do with any other entity type.

All the selected electric arcs will start using that material.

It is recommended to use a diffuse texture that slightly looks like a beam of electricity (or you can be creative!) in 99 transparency in additive mode and a bit of glow. As you can see from the picture above, the texture has 4 beams.

The lightning will warp around the U coordinate and use the V coordinate as a multi-frame animation.

Flow Graph

Port

Description

Enable / Disable

Allows to dynamically enable or disable the internal timer.

Strike

Allows to manually trigger a spark even when the entity is disabled.
This will allow to synchronize the spark effect with other level events.

EntityId

The entity that was last struck.

StrikeTime

The time the last spark will spend to fade out.

Lightning Preset Setup

To setup the lightning visuals, open the following file: Libs\LightningArc\LightningArcEffects.xml

Parameter

Description

lightningDeviation

The smooth snaky effect given to the lightning in meters.

lightningFuzzyness

The noisy effect given to the lighting in meters.

lightningVelocity

After a spark is triggered, it will start to shift from its original position upwards.

branchMaxLevel

Should be kept at either 0 or 1 but either values can be used. It will allow child branches to strike out of the main beam and child sparks to branch out of other child beams if this value is 2 or higher.

branchProbability

How probable a child is going to spark from another beam segment. If set to 0, no branch is generated, 0.5 there will be a 50% probability of sparking a branch, 2.0 will have a probability of sparking 2 per beam, etc.

maxNumStrikes

Hard limit on the number of beam segments that can be generated regardless of previous parameters.

strikeTimeMin

Minimum time a spark is kept alive.

strikeTimeMax

Maximum time a spark is kept alive.

strikeFadeOut

When the spark dies, it will take this time to fade out into oblivion. Actually it will decrease its beamSize to 0 instead of actually fading via transparency.

strikeNumSegments

Number of snaky segments generated.

strikeNumPoints

Number of points per segment generated to create the noisy effect.

The number of actual segments generated will be defined by strikeNumSegments * strikeNumPoint.

When the code generates the geometry, it will create a camera/beam aligned quad with exactly 2 triangles. This means the number of triangles per strike is going to be strikeNumSegments*strikeNumPoint*2. Since maxNumStrikes is the hard limit of potential number of sparks active at any time, the potential number poly count of a given lightning effect is going to be strikeNumSegments*strikeNumPoint*2*maxNumStrike.

However, please keep in mind that while using the LightningArc entity, every time it strikes, a new lightning effect is going to be triggered and therefore the total poly count of a given effect can go way higher. The game has a internal hard limits for the total amount of lightning effects, lightning strikes and poly count that cannot be surpassed or geometry will start to disappear.

beamSize

Width of the beam being generated. Child beams while have half of the width.

beamTexTiling

Texture tilling depends on the world size of the actual beam being mapped. A value of 2.0 means the texture will wrap around twice every meter.
A value of 0.25 means the texture will warp around every 4 meters. Only the U coordinate of the texture map is affected by this parameter.

beamTexShift

The U coordinate will move in a given direction at this value's rate. While beamTexTiling will only affect the U coordinate, the V coordinate will be automatically calculated to select one of the texture's frames.

beamTexFrames

Number of frames in the animation.

beamTexFPS

Frames per second of the multi-frame animation.

Parameter reload

Since the lightning effect is implemented within the more general Game Effects, it will be possible to reload during run-time all the parameters for fast edit.

All you have to do is put g_gameFXSystemDebug to 1 and then every time you press 'numpad .', all the game effects parameters will be reloaded and will take effect right away. You can also run the console command g_reloadGameFx for the same effect.

Code Interface

To trigger a lightning effect through code (check LightningBolt.cpp for live examples), all you need to do is:

CLightningGameEffect::TIndex m_lightningId = \-1;

m_lightningId = g_pGame->GetLightningGameEffect()->TriggerSpark(
      boltParams.lightning.c_str(),
      gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(boltParams.material.c_str()),
      CLightningGameEffect::STarget(emitterEntityId),
      CLightningGameEffect::STarget(receiverEntityId));

The lightning game effect will manage automatically the update positions. STarget supports any given position given by code, an entity id to keep track of the position automatically or a character attachment to align the spark to a specific point of your entity.

Please check CLightningGameEffect for the full code interface.

LightningArcs in Cinematics

In Crysis 3 and its cinematics we made extensive use of this cool entity!

While of course you can animate the position of that LightingArc and Target-TagPoint and Enable/Disable its state or use 'Strike' via Track View:

You can also add some nice functionality via Flow Graph magic like light emitting on Strike or particles appearing on the arcs ends (which could also get you some sound).

You actually won't need much more stuff in Track View so I'll keep manageable:

But there is a little something in the background to make this happen. Here are the ingredients:

  • 2 of your electric sparkle particle objects.
    • Link each to the LightningArc object and the target TagPoint.
    • Remove any position offset so that when selecting one of the particle objects move tool will show 0 0 0.
    • If you move the acrs while striking a glow covering the arc ends using Move Rel Emitter could help.
  • One light with a fitting color and average range (approximately, depending on how big your arcs will be).
  • A Track Event in your sequence.
    • Create it with the Edit Events option from Track View list context menu.
    • In the TrackView Events window click Add and give it a decent name.
    • To use it you need an arbitrary Track Event track.
    • Create one with the Add Event option from Track View list context menu.
    • The name of this track doesn't matter - its like a folder.
    • Double click on Track Event track creates a key.
    • Double click on key pops up the key popup in which you can select your event under Track Event.
  • A Flow Graph which utilizes your Track Events.
    • Create a new one via right click on LightningArc or use an existing one.
    • Right click in empty space and Add Track Event Node.
    • In Track Event Node select your sequence and the actual Track Event appears.
    • This output you can use to trigger everything. An example can be found below.

To explain this one: We have 2 GetPos nodes for TagPoint and LightningArc to aim the particle objects (you could of course skip that if you have an even emission all around) and to create the mean position for the light. The particles and light are turned on and off again with delays.

Copy/Paste this right away if you like (Paste with connections via Ctrl+Shift+V):

<Graph Description="" Group="Lightning">
 <Nodes>
  <Node Id="2" Class="entity:LightningArc" pos="-40,-410,0" flags="1" GraphEntity="0">
   <Inputs entityId="0" Disable="0" Enable="0" Strike="0"/>
  </Node>
  <Node Id="7" Class="TrackEvent" pos="-340,-340,0" flags="1">
   <Inputs seq_Sequence="" seqid_SequenceId="1"/>
   <Outputs>
    <Output Name="lightningStrike"/>
   </Outputs>
  </Node>
  <Node Id="271" Class="Weapon:AutoSightWeapon" pos="210,-400,0" flags="1" InHideMask="3" EntityGUID="{4D24A451-4BFE-4664-97FF-FEBD9D2ED99C}" EntityGUID_64="46644BFE4D24A451">
   <Inputs entityId="0" enemy="0,0,0"/>
  </Node>
  <Node Id="272" Class="Entity:GetPos" pos="-40,-260,0" flags="1" EntityGUID="{EA94523C-5517-485C-BA05-DB50098F3A37}" EntityGUID_64="485C5517EA94523C">
   <Inputs entityId="0" CoordSys="1"/>
  </Node>
  <Node Id="274" Class="entity:ParticleEffect" pos="790,20,0" flags="1" EntityGUID="{4D24A451-4BFE-4664-97FF-FEBD9D2ED99C}" EntityGUID_64="46644BFE4D24A451">
   <Inputs entityId="0" Disable="0" Enable="0" Kill="0" Restart="0" Spawn="0"/>
  </Node>
  <Node Id="863" Class="Weapon:AutoSightWeapon" pos="210,-340,0" flags="1" EntityGUID="{1B3B0ADC-D22A-4377-BE7B-CB7D03C12B5B}" EntityGUID_64="4377D22A1B3B0ADC">
   <Inputs entityId="0" enemy="0,0,0"/>
  </Node>
  <Node Id="864" Class="Entity:GetPos" pos="-40,-130,0" flags="1" EntityGUID="{4D24A451-4BFE-4664-97FF-FEBD9D2ED99C}" EntityGUID_64="46644BFE4D24A451">
   <Inputs entityId="0" CoordSys="1"/>
  </Node>
  <Node Id="866" Class="entity:ParticleEffect" pos="790,130,0" flags="1" EntityGUID="{1B3B0ADC-D22A-4377-BE7B-CB7D03C12B5B}" EntityGUID_64="4377D22A1B3B0ADC">
   <Inputs entityId="0" Disable="0" Enable="0" Kill="0" Restart="0" Spawn="0"/>
  </Node>
  <Node Id="868" Class="entity:Light" pos="790,-70,0" flags="1" EntityGUID="{7424B2C9-AAC8-4137-A372-B0A7732B8720}" EntityGUID_64="4137AAC87424B2C9">
   <Inputs entityId="0" Active="0" Disable="0" Enable="0"/>
  </Node>
  <Node Id="872" Class="Time:Delay" pos="510,0,0" flags="1">
   <Inputs delay="0.1" resetOnInput="0"/>
  </Node>
  <Node Id="876" Class="Vec3:AddVec3" pos="190,-190,0" flags="1">
   <Inputs A="0,0,0" B="0,0,0"/>
  </Node>
  <Node Id="878" Class="Vec3:MulVec3" pos="300,-190,0" flags="1">
   <Inputs A="0,0,0" B="0.5,0.5,0.5"/>
  </Node>
  <Node Id="882" Class="Entity:BeamEntity" pos="460,-230,0" flags="1" EntityGUID="{7424B2C9-AAC8-4137-A372-B0A7732B8720}" EntityGUID_64="4137AAC87424B2C9">
   <Inputs entityId="0" Position="0,0,0" Rotation="0,0,0" UseZeroRot="0" Scale="0,0,0" Memo=""/>
  </Node>
  <Node Id="883" Class="Time:Delay" pos="510,90,0" flags="1">
   <Inputs delay="0.5" resetOnInput="0"/>
  </Node>
  <Node Id="884" Name="aim_the_particle_fx" Class="_commentbox" pos="200,-437.39063,0" flags="1">
   <Inputs TextSize="1" Color="0.27451,0.352941,0.705882" DisplayFilled="1" DisplayBox="1" SortPriority="16"/>
   <ResizeBorder X="0" Y="0" Width="170" Height="133"/>
   <NodeSize Width="171.79163" Height="160.39063"/>
  </Node>
  <Node Id="885" Name="move_light_to_middle_of_lightningArc" Class="_commentbox" pos="180,-267.39063,0" flags="1">
   <Inputs TextSize="1" Color="0.27451,0.352941,0.705882" DisplayFilled="1" DisplayBox="1" SortPriority="16"/>
   <ResizeBorder X="0" Y="0" Width="432" Height="134"/>
   <NodeSize Width="432" Height="161.39063"/>
  </Node>
  <Node Id="886" Name="turn_particles_and_light_on_and_off" Class="_commentbox" pos="500,-107.39003,0" flags="1">
   <Inputs TextSize="1" Color="0.27451,0.352941,0.705882" DisplayFilled="1" DisplayBox="1" SortPriority="16"/>
   <ResizeBorder X="0" Y="0" Width="427" Height="320"/>
   <NodeSize Width="427" Height="347.39063"/>
  </Node>
 </Nodes>
 <Edges>
  <Edge nodeIn="2" nodeOut="7" portIn="Strike" portOut="lightningStrike" enabled="1"/>
  <Edge nodeIn="272" nodeOut="7" portIn="Get" portOut="lightningStrike" enabled="1"/>
  <Edge nodeIn="864" nodeOut="7" portIn="Get" portOut="lightningStrike" enabled="1"/>
  <Edge nodeIn="882" nodeOut="7" portIn="Beam" portOut="lightningStrike" enabled="1"/>
  <Edge nodeIn="271" nodeOut="272" portIn="enemy" portOut="Pos" enabled="1"/>
  <Edge nodeIn="876" nodeOut="272" portIn="A" portOut="Pos" enabled="1"/>
  <Edge nodeIn="863" nodeOut="864" portIn="enemy" portOut="Pos" enabled="1"/>
  <Edge nodeIn="876" nodeOut="864" portIn="B" portOut="Pos" enabled="1"/>
  <Edge nodeIn="872" nodeOut="868" portIn="in" portOut="Active" enabled="1"/>
  <Edge nodeIn="883" nodeOut="868" portIn="in" portOut="Active" enabled="1"/>
  <Edge nodeIn="868" nodeOut="872" portIn="Disable" portOut="out" enabled="1"/>
  <Edge nodeIn="878" nodeOut="876" portIn="A" portOut="out" enabled="1"/>
  <Edge nodeIn="882" nodeOut="878" portIn="Position" portOut="out" enabled="1"/>
  <Edge nodeIn="274" nodeOut="882" portIn="Enable" portOut="Done" enabled="1"/>
  <Edge nodeIn="866" nodeOut="882" portIn="Enable" portOut="Done" enabled="1"/>
  <Edge nodeIn="868" nodeOut="882" portIn="Enable" portOut="Done" enabled="1"/>
  <Edge nodeIn="274" nodeOut="883" portIn="Disable" portOut="out" enabled="1"/>
  <Edge nodeIn="866" nodeOut="883" portIn="Disable" portOut="out" enabled="1"/>
 </Edges>
</Graph>