[004] All Our NPCs


A lot of little coding things I forgot about needing this week. Let's start with the main ones.


NPC Scripting

Well, the name is not very descriptive. Basically, there is a little complexity to some NPC sequences (that is, talking to NPCs in a certain order to get through an area, etc.) The game is simple enough that the most complicated NPC only has three or four *linear* states. Say A, B, and C. You can only hear B's dialogue after hearing A (or some other flag being set), only hear C after B's flag (or some other flag RELYING on A being set... etc.)

AOA (and Even the Ocean) use a similar easy flag system: each chunk of dialogue has a descriptive key ("morningConversation2"), that key is used to access the dialogue, and can be used to store a flag value (0, 1, 2, etc). Most of the time I set a flag to 1 to denote having heard that conversation, but you can do other stuff as well.

 An NPC has a few parts to it:

  • Condition for dialogue trigger being active ("if some flag is 1, then you can talk to this NPC.")
  • Is there a box collider associated with this NPC? (Sometimes you need to block passageways with dialogue).
  • Default dialogue key, i.e. what conversation plays by default.
  • Optional: dialogue keys for alternative dialogues, and the dialogue keys whose corresponding flags must be 1 before that alternative must be played. 
  • A few other things... NPCs are really just triggers that play dialogue, but you can also trigger cutscenes with their triggers. This is useful because I plan to have the camera cut to a closeup shot of some NPCs while talking, but return to normal right after.

Anyways, this is probably a little harder if you have some level of branching to the dialogue. But a simplification I made for this game was no dialogue choices or branching. My story doesn't need it, and it would be weird for my main character to be making choices. Plus when doing a game alone you should really take every simplification you can get... !

Audio Manager

So I had finally finished some songs... and realized I hadn't really worked on the audio manager for this game. Nothing complicated, but I needed the ability to loop a song in a peculiar way, do crossfades. Unity doesn't support any of that out of the box and it's easy enough for me to merit doing myself.  

The 'peculiar looping' isn't that strange, and is probably common in games. Just, many engines don't support it out of the box. In a lot of music it's important to have loop points. So take a song structure that goes ABC. But A is an intro - so it would be really awkward or hard to write a "D" section that neatly transitions to A. What might make more sense is for the song to just indefinitely repeat ABCBCBCBC... which you need your engine to do. It's not too bad to do this with a single Unity AudioSource, set a loop start point and use the end of the song as the endpoint - when the song is done playing immediately jump to the loop start point. 

But the problem with that is that it's not always easily to cleanly loop. What if you have a few bars of reverb or some grain delay etc at the end of your song? Then that gets cut off in the loop. If you let those few bars play in the song and then loop, there's some weird silence.

The solution is having two Audio Sources, and define a loop start AND end. The first audio source plays, when it passes the loop end point, the second source starts *from the loop start point*. The first source continues to the end of the file, so the reverb/whatever overlays onto the repeating track. Problem solved! (Then the two tracks switch off doing this behavior).

AudioData

So a thing to note is I maintain a single AudioManager instance for the whole game, so songs can play between scene changes if need be. But I run into a problem when I want to store data per scene, like what song plays by default. I could define song metadata in a file, but that always feels like working against Unity unless it really makes sense like storing dialogue. So what I did was make a second AudioManager in each scene, that isn't a prefab instance. When a new scene starts, I can then have that second AudioManager (I call it AudioData) give its values to the global instance AudioManager. 

Overall it kind of feels hacky, but it's a lot nicer to get things working through Unity, and to have any new stuff I add to my AudioManager to be able to be set custom per scene.

Right now, though, I set the loop start/end inside of the AudioData inspector. But if I want to repeat a song throughout the game then I'm copy pasting, potentially bad. So I would probably use an XML file in that case. But songs won't repeat enough throughout the game to warrant that effort.

Seeing through walls

I finally mostly fixed this, my 3rd person camera would partially see through walls when you walk near them. It's possible to fix most issues with a raycast and stopping your camera from moving through a wall when it's being offset and focusing on the player. But you still need to deal with the near clipping plane intersecting with meshes. What I did was raycast left and right from the center of the near clipping plane (using viewport to world function for the values), and if I hit the wall, nudge the camera, after all of its other positioning has been done. Seems to work okay!

General Level Design Progress

I finished hooking up all the cutscenes/levels for the intro of the game, which is nice to see the game flowing along. Also with the NPC progress I mentioned above I was able to finish the most complex NPC sequence (which is pretty simple relative to other event sequences I've worked on. Unity also makes it really easy.)

Also started blocking out some levels, finishing some texturing/effects work in some areas. General "game progress" stuff.

Here's one area being blocked out...


Debug tool

I need to test certain events in the game without replaying the game, so I added two properties to one of my prefabs that appear in every scene, for dialogue keys whose flags I want set to '1' at the start of the game. Since most events check if a previous event is done, this lets me basically play the game from anywhere I want, which is useful when testing certain short sequences.

Leave a comment

Log in with your itch.io account to leave a comment.