For playing cutscenes, UDK requires using the Bink format and its native player. However, as students with no native code access, UDK’s Bink player has a major downside: the only play function is an exec command called MOVIETEST. The MOVIETEST function loads the movie and then stops the engine completely to play it. This means that the cutscenes are unskippable (input has been stopped) and can’t have subtitles (the message system is also stopped.) Our team believed that lacking those two features in our cutscene would make for a bad player experience, so we made a custom cutscene player in flash to fix this problem. Our flash file template for cutscenes is devised of four layers:Motivation
Design
Code
Cutscene Skip
//timer to prevent the cutscene from being skipped for the first two seconds (also hides the frame)
const ONE_SECOND_IN_MS = 1000;
var skip_allowed_timer:Timer = new Timer( ONE_SECOND_IN_MS, 2 );
skip_allowed_timer.addEventListener( TimerEvent.TIMER_COMPLETE, AllowSkipping );
var fade_in_skip_tween:Tween;
function AllowSkipping( timer_event:TimerEvent )
{
// fade in our skip prompt so that we're not distracting, and attach the event listener so they can skip
fade_in_skip_tween = new Tween( mc_skip_clip, "alpha", Regular.easeOut, 0.0, 1.0, FADE_LENGTH_SECONDS, true );
fade_in_skip_tween.start();
InputDelegate.getInstance().addEventListener(InputEvent.INPUT, HandleSkipInput );
}
function HandleSkipInput( input_event:InputEvent )
{
if( input_event.details.value != InputValue.KEY_UP )
return;
switch( input_event.details.navEquivalent )
{
case NavigationCode.GAMEPAD_A:
case NavigationCode.GAMEPAD_START:
InputDelegate.getInstance().removeEventListener(InputEvent.INPUT, HandleSkipInput );
ExternalInterface.call( "EndCutscene" );
break;
default:
return;
}
}
Subtitle Display
const FADE_LENGTH_SECONDS = 0.3;
const ONE_SECOND_IN_MILLIS = 1000;
var fade_in_tween:Tween;
var fade_out_tween:Tween;
var subtitle_timer:Timer = new Timer( ONE_SECOND_IN_MILLIS, 1 );
subtitle_timer.addEventListener( TimerEvent.TIMER_COMPLETE, HideSubtitle );
var subtitle_seconds_shown:Number = 1.0;
function ShowSubtitle()
{
//mc_subtitle.text_subtitle.text = subtitle_text;
fade_in_tween = new Tween( mc_subtitle, "alpha", Regular.easeOut, 0.0, 1.0, FADE_LENGTH_SECONDS, true );
subtitle_timer.start();
}
function HideSubtitle( timer_event:TimerEvent )
{
fade_out_tween = new Tween( mc_subtitle, "alpha", Regular.easeOut, 1.0, 0.0, FADE_LENGTH_SECONDS, true );
//fade_out_tween.addEventListener( TweenEvent.MOTION_FINISH, ClearSubtitle );
}
function ClearSubtitle()
{
mc_subtitle.text_subtitle.text = "";
}
function PlayMessage( message_number:uint, message_length:Number )
{
ExternalInterface.call( "PlayCutsceneMessage", message_number );
if( Extensions.isGFxPlayer )
{
mc_subtitle.Show( "Subtitle will show here.", message_length );
}
}
Unrealscript Backend
class SSG_Cutscene_Opening extends GfxMoviePlayer;
var class