script_intro

From Valve Developer Community
Jump to: navigation, search

script_intro is a point entity available in all Source games.


Entity description

The script_intro entity is a singleplayer only entity that is used extensively in the intro sequence for Half-Life 2. It makes use of DirectX's render-to-texture capabilities to overlay a second camera onto the main camera, i.e., the player's view, and to blend between the two views using various effects. This is also useful for doing traditional A-B camera exposition sequences.

Some of the possible uses for this entity include hallucination effects and dream sequences, traditional A-B camera work for machinima, and so on.

The main issue with understanding this entity is the workflow isn't the same as other entities, in that it's highly time based. You don't just set keys and it works, but rather you'll have to trigger it at intervals using inputs, so a good working knowledge of Source's entity I/O system is required.

Using script_intro

There's only one key that you have to deal with on this entity, and that's it's targetname. Once you have a name to refer to the entity by, all the work is done by sending it inputs. The blended view (with the currently configured parameters) is enabled by firing the Activate input. Before you trigger Activate, there are several inputs you should send to initialize the entity, so that the transition from the normal player view to the blended view is seamless. They are SetCameraViewEntity, SetFOV, FadeTo, SetFadeColor, and SetBlendMode.

Start by sending the SetCameraViewEntity input, with the name of the point_camera entity that you'll be using as the second view as a parameter. The camera will be automatically activated once the Activate input is fired on script_intro. Remember, the player's viewpoint is the first camera, so in traditional film terms, the player is the A camera, and the point_camera that script_intro is using is the B camera. A subsequent optional SetFOV input will set the desired field of view for the B camera. If you want to control the FOV of the A camera as well, you can use the env_zoom entity. Note that you don't have to ever trigger SetCameraViewEntity; in that case, the input for the B camera will be totally black, and you can still use the entity for its post-processing effects applied to the player's view.

Next, you can use the SetFadeColor and FadeTo inputs to optionally apply an additional blend of solid color to the two cameras once the entity is activated. SetFadeColor (default is 0 0 0) defines the color that is added to the mix, and FadeTo defines how opaque this color will be when blended. You use the input by sending a parameter with it with two values separated by a space. The first value is an integer with a range of 0-255, where 255 is completely opaque, and 0 (default) is completely transparent (resulting in no solid color being mixed into the view). The second value is a number in seconds that the fade will occur over; when initially configuring the entity, use the value of 0 for the second parameter to apply the change instantly.

Finally, you may want to change the default blend mode by firing SetBlendMode. A good choice for a starting value is 8 (see the list below), as it displays only the player (A) camera and ignores the B camera, allowing for a seamless transition. If you are not using the B camera, you are fine with the default 0.

At this point, you can fire the Activate input to enable the blended view on the fully configured entity. Next you'll want to use the SetNextBlendMode, SetNextBlendTime, SetNextFOV, SetFOVBlendTime, and FadeTo to accompish transition effects.

SetNextBlendMode with a parameter of 6 is the most natural of blend modes. It will produce a straight additive blend between the two cameras when complete. The other blend modes will produce special effects, such as the black and white and inversion effects seen in HL2's intro. Send a SetNextBlendMode input with a integer parameter of 0 through 9, each produces a different effect. This sets up the blend; you next send an input of SetNextBlendTime to execute the blend, with a parameter that equals the time value that you want the blend effect to occur over, in seconds. The blend mode will cause the camera to change effects when executed; so it will blend from one effect to the next.

SetNextFOV and SetFOVBlendTime work to smoothly transition camera B FOV from one value (the default, or the last executed SetFOV) to the next; otherwise, they work analogously to SetNextBlendMode and SetNextBlendTime.

Finally, the SetFadeColor and FadeTo inputs can be used to smoothly blend a solid color into the view (similarly to env_fade). In order to avoid sharp changes in color, make sure to only fire SetFadeColor while the FadeTo alpha is set to 0. Once you've set the desired fade color, execute a FadeTo input with the desired fade amount and the number of seconds to accomplish the fade. For example, setting the fade color to "255 255 255" and then executing FadeTo with values of "127 5" will fade the player's view to a milky white over 5 seconds. Of note, the FadeTo input is used hackishly in the intro sequence to fadeout the player's view. This is because the env_fade entity can't be iterated, i.e. you can't have two env_fades, and fade from one to the other.

Once you are done toying with the player's view, you can fire the Deactivate input to return it to normal, followed by SetOff inputs to any cameras you've been using.

Blend modes

This is a list of the apparent function of the blend modes. These can be set in the entity by sending it a SetNextBlendMode and SetNextBlendTime, or just SetBlendMode.

  • 0: Camera A is normal color, camera B is inverted grayscale, multiplicatively blended (each pixel value in the resulting view is determined by multiplying the values of the corresponding pixels in A and B views). Note that if no camera B is used, this just renders the player view normally. This is the default value.
  • 1: Camera A is inverted color, camera B is normal grayscale, additively blended (each pixel value in the resulting view is determined by adding up the values of the corresponding pixels in A and B views).
  • 2: Camera A is normal grayscale, camera B is normal color, multiplicatively blended.
  • 3: Camera A is normal grayscale, camera B is normal color. Camera B is masked with the inverse of camera A's luminosity, which becomes the latter's alpha channel. That is, darker pixels in A do not allow much light from B, whereas brighter pixels in A render almost completely as B.
  • 4: Both A and B are normal color, otherwise the same as 3.
  • 5: Camera A is posterized color, camera B is normal color, but B's low values (absolute black) serve as an alpha mask for A (are transparent to A). B camera is drawn everywhere except where its pixels would have been black; A camera is drawn for those pixels instead.
  • 6: Both A and B are normal color, additively blended. This appears to be the most straightforward mix between the two screenbuffers, applying a straight blend.
  • 7: Camera A is blank, camera B is normal. This can be used to take control of the player's view, similar to the point_viewcontrol entity. However, the player can still move around and act, they just won't see what's going on around them.
  • 8: Camera A is normal, camera B is blank. This is the opposite of 7 and equivalent to the player's regular view.
  • 9: Both A and B are normal color. Camera A is masked with camera B's luminosity, which becomes the latter's alpha channel. That is, brighter pixels in B do not allow much light from A, whereas darker pixels in B render almost completely as A. (New with Half-Life 2: Episode Two / Source 2007)
Note:The above descriptions are valid only for the DX9 rendering mode. Earlier DirectX versions may not have the features to implement all of these modes, and consequently will either use simplified modes (0, 1, 3, and 5) or forgo blending altogether, displaying only one of the inputs (2 and 4). If you make extensive use of these modes, you should test your scripts with all applicable rendering modes (by supplying the appropriate value of mat_dxlevel to the engine command line).

Examples of use

See the following Half-Life 2 (and Episodic) maps for various uses of this entity:

Straight fade from player's view to the camera view and back over 10 seconds (assuming you have a script_intro entity with the name "fxintro" on the map and a camera named "b_camera", fired from (repeatable) OnTrigger outputs):

"OnTrigger" "fxintro,SetCameraViewEntity,b_camera,0,-1"
"OnTrigger" "fxintro,SetBlendMode,8,0.01,-1"
"OnTrigger" "fxintro,Activate,,0.02,-1"
"OnTrigger" "fxintro,SetNextBlendMode,7,0.03,-1"
"OnTrigger" "fxintro,SetNextBlendTime,5,0.04,-1"
"OnTrigger" "fxintro,SetNextBlendMode,8,5.05,-1"
"OnTrigger" "fxintro,SetNextBlendTime,5,5.06,-1"
"OnTrigger" "fxintro,Deactivate,,10.06,-1"
"OnTrigger" "b_camera,SetOff,,10.07,-1"

Bugs

  • script_intro does not work properly on the maps that contain 3D skyboxes. Depending on the engine version, they either won't be rendered at all (even in the player view), or worse, result in clipping of the 2D skyboxes, leaving the sky totally or partially black. To work around this problem, either don't use 3D skyboxes on the affected maps, or make sure the sky is not visible from the places where you intend to use this entity.
  • Viewmodels, if present in the player view, are not rendered properly while script_intro is active (only the 2D parts are visible). One should make sure the player either does not possess any weapons, or is forced to hide them for the duration of the blend sequence.

Both issues are caused by when the skybox and viewmodels are rendered in the scene composition.

Code Fix: The skybox bug can be fixed by moving CSkyboxView's setup in CViewRender::RenderView() to occur after the secondary camera would be drawn in the intro scene, meaning it would be separated into one instance directly before CViewRender::ViewDrawScene() and another instance of the setup in CViewRender::ViewDrawScene_Intro() shortly after the m_bDrawPrimary block. Putting it right before g_pClientShadowMgr->PreRender() works. The clear color background should be removed as well, at least while the skybox is calculated to be visible.
Confirm:Does removing VIEW_CLEAR_COLOR cause VortWarp to stop working correctly?
Code Fix: The viewmodel bug can be fixed by disabling the regular call to CViewRender::DrawViewModels() in CViewRender::RenderView() when the intro code is active and adding a separate call to CViewRender::ViewDrawScene_Intro() before intro_screenspaceeffect is composed. Putting it right after the main DrawWorldAndEntities works.

Keyvalues

Match env_zoom's FOV transition <boolean>
Whether the script should match env_zoom's FOV transition.

Targetname:

Name <string>
The targetname that other entities refer to this entity by.
Entity Scripts <scriptlist> (New with Left 4 Dead 2)
Space delimited list of VScript files (without file extension) that are executed after all entities have spawned. The scripts are all executed in the same script scope, later ones overwriting any identical variables and functions.
Script think function <string> (New with Left 4 Dead 2)
Name of a function in this entity's script which will be called automatically every 100 milliseconds (ten times a second) for the duration of the script. It can be used to create timers or to simulate autonomous behavior. The return value (if present) will set the time until the next call.
Note:Try to avoid expensive operations in this function, as it may cause performance problems.

Inputs

Activate
Take control of the player's view and start blending the two scenes.
Deactivate
Stop controlling the view.
SetCameraViewEntity  <string>
Set the viewpoint to blend with the player's viewpoint.
SetBlendMode  <integer>
Set the blending mode to use.
SetFOV  <integer>
Set the fov for the second camera.
SetNextFOV  <integer>
Set the FOV to blend to over time. Follow this with a SetFOVBlendTime input to start the fov blend.
SetFOVBlendTime  <float>
Set the amount of time it should take to blend to the next fov target, and start blending.
SetNextBlendMode  <integer>
Set the blending mode to blend to over time. Follow this with a SetNextBlendTime input to start the mode blend.
SetNextBlendTime  <float>
Set the amount of time it should take to blend to the next mode, and start blending.
FadeTo  <string>
Fade to a specific alpha amount of an amount of time. Parameters: <alpha> <duration>
SetFadeColor  <string>
Set the fade color. Parameters: <Red> <Green> <Blue>

Targetname:

Kill
Removes this entity and any entities parented to it from the world.
KillHierarchy
Functions the same as Kill, although this entity and any entities parented to it are killed on the same frame, being marginally faster than Kill.
AddOutput  <string>
Evaluates a keyvalue/output on this entity. It can be potentially very dangerous, use with care.
Format: <key> <value>
Format: <output name> <targetname>:<inputname>:<parameter>:<delay>:<max times to fire, -1 means infinite>
FireUser1 to FireUser4
Fire the OnUser outputs; see User Inputs and Outputs.
Use  !FGD
Same as a player invoking +use; may not do anything. Can also be invoked by creating an output that does not specify an input.
This input is not included in Valve's FGDs.
RunScriptFile  <script> (New with Left 4 Dead 2)
Execute a VScript file from disk, without file extension. The script contents are merged with the script scope of the receiving entity.
RunScriptCode  <string> (New with Left 4 Dead 2)
Execute a string of VScript source code in the scope of the entity receiving the input. String quotation may be needed when fired via console.
Bug: In <Left 4 Dead 2>, the code is executed in the script scope of the entity that fires the output, not the one receiving the input.
Warning: Never try to pass string parameters to a script function with this input. It will corrupt the VMF structure because of the nested quotation marks, which then must be removed manually with a text editor.
CallScriptFunction  <string> (New with Left 4 Dead 2) !FGD
Execute a VScript function in the scope of the receiving entity.
SetLocalOrigin  <coordinates> (New with Alien Swarm) !FGD
Send this entity to a spot in the map. If the entity is parented to something, it will be offset from the parent by this amount.
SetLocalAngles  <angles> (New with Alien Swarm) !FGD
Set this entity's angles.

Outputs

Targetname:

OnUser1 to OnUser4
These Outputs each fire in response to the firing of the like-numbered FireUser1 to FireUser4 Input; see User Inputs and Outputs.
OnKilled  (Only in the Left 4 Dead series)
This Output fires when the entity is killed and removed from the game.