Website powered by

Lessons Learned: Scripting Randomized in Unreal 4 Bonus

General / 08 May 2019

Hello again! 

In the last post, I touched briefly on some of the lessons I learned from scripting the dialogue system for Boardwalk Gulch. In the summary, I went back to the old system to clean it up; it was a good experience, but nevertheless I really wanted to use what I'd learned about dialogue moving forward. Thankfully, I got to do just that during a new project. With the added benefit of this new project not being a solo task but rather a group effort, I got the added challenge of creating a much-more standalone system then one I'd previously created. In this post, I'll be going over this new system, the changes from the previously created dialogue interface, and some major improvements I was able to make! 


First Improvement: the Master Audio Handler


By far, one of the biggest changes from the Boardwalk dialogue system was the segmentation of the entire audio system into a single blueprint class rather than part of the larger game instance. This was by far one of the best changes made for this system. In addition to being a lot easier for the main coder on our team to implement and being nicely standalone, it was nicely convenient to have all audio-related variables and functions in one place rather than spread across multiple BPs. 


One of the best advantages to this method was that it allowed me to easily alter the levels of the ambient noise during dialogue playback. Being able to temporarily lower and raise the volume of the ambient radio while playing dialogue was a nice addition made possible with this change. 


Second Improvement: the BPI 

In addition to the main blueprint for the master audio handler, I created a secondary blueprint interface for calling the master's functions. This was a much, much more versatile choice than the previous "cast to game instance" required for the Boardwalk system as it allowed for a lot more freedom to message and trigger functions for the audio from other blueprints. 


Third Improvement: Randomization Handling


  One of the biggest drawbacks of the Boardwalk system was its clunky way of randomizing what line was being played. Instead of this, I broke the randomization into two functions that utilized a specified tag from the BPI message. The tag array built corresponded to the audio array (ie, index 1 of the audio array is a generic exclamatory phrase and index 1 of the tag array is "exclamation"). When messaged, the "GetPossible" function was called, which looped through the tag array to find all the entries matching the specified tag, then added their index numbers to a temporary "matching entries" array. This array was then used to get a random line from that group of selected indices. The results are functionally similar to the Boardwalk system, but allow for much greater iteration and expansion than the former. 


Conclusions:

Overall, this system was a great experiment in taking what I'd learned from a previous system to rebuild a better, newer version. This system is a heck of a lot cleaner, and as such, I was able to quickly and successfully integrate it into the main project file. 


Thank you for reading this post! Next time, I'll be getting back into more completed blueprints! 

Lessons Learned: Scripting Randomized Dialogue in UE4 Part 2

General / 30 March 2019

When I undertook the task of creating a short level based off of my previously made Boardwalk Gulch environment, there were two things I set out to accomplish: create a unique character that would inhabit the level, and give the player a sense that this character was interacting with them. 

In the last post, I covered the scripting process for the ambient lines in the dialogue system. This time, I'll be talking about the contextual dialogue scripts built for the game.  


Contextual Dialogue:

With the ambient dialogue system mostly completed, I turned my attention to the main method by which I wanted the NPC personality I had created to interact with the player: context-based voice lines. Since the majority of lines would play based on objects the player picked up in the game world, I decided (for better or worse) to fire the voice lines inside the interaction script for each object. 



Notably, this decision was a bit of a double-edged sword in several ways. 

Pros:

  • Since it used a method of playback fairly similar to the ambient system that came before it, I was able to get basic functionality up and running fairly painlessly. 
  • Having the script executed per-item allowed for easy troubleshooting (when a problem would emerge with a particular line, it was easy to find the associated item and therefore isolate the problem). 
  • The actual logic behind the system itself was fairly simple: cast to the game instance where the dialogue is stored, pick a random line from the relevant set, then display the notification and play the sound file in the same method the ambient lines used.


Cons: 

  • Headaches when it came to overlapping dialogue lines. Since each item's dialogue script ran similarly but entirely separately from both the ambient dialogue and from the script of other objects, a somewhat unwieldy global timer system had to be constructed to make sure that contextual lines would not overlap one another.  
  • This script needed to be inserted into every item with corresponding dialogue. For the scope of the game (only four objects with recorded voice lines) this was not a major issue, but nevertheless it limited the versatility of the system as a whole. 
  • The whole script was very node-heavy, resulting in a fairly messy-looking blueprint. 


Lessons Learned: 

In hindsight, the contextual dialogue script was a slightly clunky but functional system that suffered from poor legibility and limited versatility. That being said, creating the system was a great learning experience for me that taught me several important lessons: 

  • Building out a more versatile system should take priority over a "quick fix", as the latter can create unforeseen problems later in a project and limit expansion further down the line.  
  •  collapsing several of the messier portions into functions and reordering some of the inputs and outputs results in a much cleaner and elegant-looking script that still is functional when used (pictured below): 



Thanks for reading this post! Next post, I'll be covering some of my work with the scripting of endless hallways and impossible spaces! Until next time! 

Lessons Learned: Scripting Randomized Dialogue in UE4 Part 1

General / 28 March 2019

When I undertook the task of creating a short level based off of my previously made Boardwalk Gulch environment, there were two things I set out to accomplish: create a unique character that would inhabit the level, and give the player a sense that this character was interacting with them.

Creating a Character:

The first task was fairly easy to begin. I had already created a mascot of sorts for the doomed "desert beach resort" I had created: Helios Sam, the Sun Cowboy. Creating Sam's backstory of a moderately deranged boardwalk employee accidentally locked into the PA booth and left with a book of cheesy mascot dialogue was to say the least, enjoyable, and being able to recruit the ever-talented Alex Norton to record the voice lines was truly a pleasure. With the character made and the voice lines recorded though, the more technical part of the project would begin. 


The Beginning: 

I reached the decision early on that it would be best to have Sam interacting with the player through an intercom rather than in person, as it both fit in more with the created backstory and, quite frankly, saved a lot of time that would've otherwise been spent on animation and modeling of a character model. This decision, however, came with a natural problem: how to successfully create the illusion of interaction with a NPC without the NPC being having a physical presence in the game space. To combat this problem, I decided to sort the dialogue into two separate groups: ambient and contextual. This first post will cover how I scripted the former. 


Ambient Lines: 

Ambient lines would be by far the easiest type of dialogue to script. A new function (pictured above) was set up in the global game instance to handle both the randomization of the dialogue and the actual audio playback itself. A "master array" of the sound files was set up alongside a string array which contained the corresponding written text for each line (see the example at the bottom of this post). This meant that when a ranged random integer was set for a line, the audio played would match the displayed subtitle. After playing the sound, a separate function would set a new interval of between 15 and 30 seconds before a new line could be played (script below). 

 

Overall, this method proved to be an effective way of managing a dialogue system that felt fairly natural, albeit with some repetition of voice lines. While this method of scripting was by no means a flawless solution (more on that in a later post), it still proved suitable for the scope and stricter time limitation of the project it was a part of.  

Thanks for reading! The next post will cover the scripting of the project's contextual dialogue, as well as a brief post-mortem on the dialogue system as a whole! Until next time!