Wednesday, March 7, 2007

Making a Cinematic

Okay, I know that in my last post I said that I'd talk about my riddle door, but it seems that there are a lot of questions on the boards about cinematics and cutscenes, and given that's actually the next step that the PCs in my campaign come upon, I thought I'd take that on instead. Plus, the riddle door is ULTRA cool, so I'm hoping I can bait you all into coming back again tomorrow to read that article. :-)

So you want to make a cinematic, eh? Well, the one great thing about NWN2 is that it has a built-in cinematic/cutscene engine - conversations!! And it's actually pretty darn easy to put one together, once you get the basics down.

To put this part of the project into perspective, once the PCs have either (1) helped the ogre chef out and received his secret key or (2) killed the goblin shaman and obtained the other key, they go to the throne room, where the chief of the goblins is located (actually a Bugbear, so there's a little bit of license taken there, but he's still a badass barbarian). When the PC's enter the doorway, they trigger a cutscene where a Goblin lackey comes to the Chief to report a missing patrol. The chief, of course, wants nothing to do with this, and strikes down the goblin.

So, knowing that a cutscene/cinematic is really just a conversation, the first step (obviously) is to generate the conversation. The trick here is that there are no PC lines in the conversation. One-sided, you say? I say thee nay!! You can specify the speaker and listener for NPC conversation nodes in the Nodes properties view (see below, click to make biggerer):



So we've got the conversation set up (you'll see some actions, but we'll get to those in a little bit - they're tricksy, they are). Now we need to set the stage for the scene itself:


There are six key components to this scene: three static cameras (mod_cam_bugbear_chief, mod_cam_goblin_tattler, and mod_cam_goblin_death), two creatures (mod_c_goblin_tattler and mod_c_bugbear_chief), and one waypoint (mod_wp_tattler). For the cameras, every node in the conversation is set to use one of those static cameras in its Node properties. For most of them, I used Pan, Medium, and Static Camera to get the effects that I needed.

If you don't want to use static cameras, though, you can use some of the preset camera functionality. The different types of shots are pretty straightforward, if you know anything about cinematics, that is. But, if you don't, here's a rundown:
  • Behind The Head: Similar to a standard 3rd-person perspective.
  • Close-Up: "I'm ready for my close-up, Mr. DeMille..."
  • Establishing: A wide shot that shows much of the environment around the target.
  • Long: Wide shot, but more narrowly focused than an Establishing shot.
  • Medium: Between a Long and Close-Up shot.
  • Side: View of the target's side.
  • Three-Fourths: Just like it says, tries for 3/4 of the target in the shot (from head down).
  • Top-Down: Pretty straightforward.
  • Torso: Focuses in on the speaker's torso.
  • Two-Shot: Attempts to get both speaker and listener in the view.
  • Walk-By: The only moving camera setting - camera tracks past the speaker as they talk.
  • Worm's Eye: What a worm would see, up from the floor toward the speaker.
So the characters themselves are probably also pretty self-explanatory, right? At least I hope they are!! But what's the waypoint for? Simple - I didn't want this to be an entirely static scene, so I made sure that three actions were assigned: 1) The goblin walks up to the chief and speaks, 2) the chief strikes down the gobline, and 3) the goblin dies.

Now which of these three do you think was the easiest to do? Yep - walking to the waypoint. There's a simple action script called ga_cutscene_move() that takes the waypoint tag, a delay value in milliseconds, and a boolean value for running. Just set it and forget it (but make sure that your speaker for that node is the one you want moving!!).

Second easiest? Believe it or not, that was the death of the goblin. Making the bugbear attack took me far too long to figure it out. Now, I don't claim that either of these are the most elegant solutions, but they're what worked for me...

For the goblin death, I created a custom script that grabs the goblin's current hit points and inflicts damage on that goblin for his current HP+1.

void main (string sTargetTag) {
object oTarget = GetObjectByTag(sTargetTag);
int iHP = GetCurrentHitPoints(oTarget) + 1;
effect eDamage = EffectDamage(iHP);
DelayCommand(0.5,ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oTarget));
}

As for the attack, it took me forever to figure it out. I knew that it had to be some form of animation, but couldn't figure out what that animation was or how to trigger it. After several hours of research and LOTS of trial and error, I found a post that mentioned the ability to wildcard animation names. So, I created this script for the attack animation, and lo and behold, it worked!!

void main (string sAttackerTag) {
object oAttacker = GetObjectByTag(sAttackerTag);
string sCustomAnimation = "*1attack01";
object oSound = GetObjectByTag("mod_snd_bugbear_atk3");
SoundObjectPlay(oSound);
PlayCustomAnimation(oAttacker,sCustomAnimation,0,1.0);
}

For the actual module, I combined both of the above into a single script that runs the attack animation and causes the death of the goblin, in one fell swoop.

Whew! So we've got the conversation set up, and the actions ready to go. Now...how in the heck do we trigger the conversation? I wanted it to happen immediately after the characters entered a door, so I placed triggers at both of the possible entry points (screenshot):


Again, it took a lot of research and trial and error to set up the triggers to work properly. I finally managed to track down the scene in the original campaign where Qara is found, about to be attacked by the other wizards outside the Flagon. It was there that the secret was uncovered: gtr_speak_node()!!!

This grand and glorious script reads variables off of the trigger to which it is assigned, and runs the conversation that is associated with that trigger according to the parameters that it finds. To set the variables, you click the option in the trigger's Properties window that's above all the scripts (appropriately titled "Variables"). This pops up a new window where you create the necessary variables:
  • NPC_Tag (string) = the tag of the NPC that's starting the conversation.
  • Conversation (string) = the refname for the conversation (the name in the conversation editor).
  • TalkNow (boolean) = Whether to initiate the conversation immediately, or cause the NPC to walk to the PC.
  • Multiuse (boolean) = Whether this is a one-time conversation/cutscene, or can it be triggered more than once by the PC?
  • Run (integer) = Should the NPC run(0) or walk(1) to the PC, or (-1) not move at all.
  • CutsceneBars (boolean) = Should the top and bottom black bars appear during the conversation.
  • OnceOnly (boolean) = Should this conversation ever be triggered by another PC (probably specific to MP modules).
Once those variables were set on the trigger, and the gtr_speak_node script was assigned to the OnEnter event, everything was good to go.

I hope this helps someone out, if for no other reason than it took me almost an hour to just type all this up! :-) Just kidding - if you are working on cinematics of your own, this should be a good stepping-off point for you. Happy modding!!

1 comment:

Anonymous said...

This is an very useful post. Thanks for taking the time to write it.

Good luck building!