GUIInsert

A GUIInsert is a virtual LED on the playfield or backbox screen. The API is very similar to the LEDs API.

See the LEDs section of the SDK Guide for related information.

Overview

A GUIInsertScript contains the commands to determine what color a single GUIInsert should be over time. A Mode creates a separate GUIInsertScript for each GUIInsert it controls and adds these scripts to GUIInsertControllerMode. The controller orchestrates which scripts are running: for each GUIInsert, the GUIInsertScript with the highest priority is the one that runs. This way, a Mode with higher priority overrides a Mode with lower priority.

GUIInsert class

The GUIInsert class is never used and can be ignored. The real workhorse is the GUIInsertScript class.

GUIInsertScript

A GUIInsertScript is a collection of GUIInsertCommands for one GUIInsert and the code to run the commands. The class derives directly from object. Do not confuse it with a Unity Script. To create a GUIInsertScript, call the constructor with the GUIInsert name and the priority of the Mode:

GUIInsertScript script = new GUIInsertScript("insertName", priority);

You can assign a scriptName to the script. This is optional but it can be useful for debugging because the scriptName will appear in some log messages. This can help distinguish multiple scripts for the same insert, for example by including the mode name in the script name. P3SampleApp does not assign scriptNames and that’s acceptable too.

script.scriptName = "ModeName-InsertName";

A GUIInsertScript starts empty. You add new commands by calling AddCommand():

script.AddCommand("new text", textColors, colors, alpha, fadeTime, duration);

Internally, that creates a GUIInsertCommand which is a data object with no behavior. That’s an implementation detail because you never interact with the data type GUIInsertCommand (unless you implement your own receiver).

The only two commands available are: changing a text string and/or linearly interpolating the color of an object. Remember, the alpha is part of the color, so you can make objects appear and disappear.

You can add multiple commands to a script by calling AddCommand() multiple times. This can create blinking effects.

By default, the script is not removed when it finishes execution. This means the GUIInsert will remain in its final state after the last command. The script can be configured to automatically remove itself when execution finishes, like this:

script.autoRemove = true;

When the script is removed, the next-highest-priority script is executed, and it will likely change the GUIInsert.

To add the script to the GUIInsertControllerMode, post the event:

PostModeEventToModes("Evt_AddGUIInsertScript", script);

<appcode>BaseGameMode handles the event (in its base class BaseAppMode) and calls the GUIInsertControllerMode instance to add the script. The new script will start executing immediately if it has the highest priority for that GUIInsert (stopping the previous script if there was one).

Nothing prevents a mode from adding multiple scripts for the same insert at the same priority at the same time. The result is unpredictable and likely a bug in the application.

A GUIInsertScript is meant to be reused. The procedure is simple: clear the existing commands, add new ones, then add the script to the controller again. The script will reinitialize itself if it was currently executing.

script.Clear();

script.AddCommand("new text", textColors, colors, alpha, fadeTime, duration);

PostModeEventToModes("Evt_AddGUIInsertScript", script);

When the Mode no longer wants to control the GUIInsert, it must remove the script from GUIInsertControllerMode by posting an event:

PostModeEventToModes("Evt_RemoveGUIInsertScript", script);

<appcode>BaseGameMode handles the event (in its base class BaseAppMode) and calls the GUIInsertControllerMode instance to remove the script. The script will stop executing immediately if it had the highest priority for that GUIInsert (and the script with the next-highest-priority will execute instead). The script will no longer be considered for that GUIInsert.

Always remember to remove a script added to GUIInsertControllerMode when no longer needed. In particular, make sure to remove all remaining scripts in mode_stopped() when the Mode ends.

A script that was removed can be added later as is, or it can be reused with different commands.

RegisterGUIInserts

GUIInsertHelpers keeps a list of all GUIInsert names. The list is populated in the RegisterGUIInserts method of <appcode>BaseGameMode. These are the GUIInserts in P3SampleApp:

        protected override void RegisterGUIInserts()

        {

            base.RegisterGUIInserts();

            GUIInsertHelpers.AddGUIInsert("InfoPopup");

            GUIInsertHelpers.AddGUIInsert("SideTargetHighlight0");

            GUIInsertHelpers.AddGUIInsert("SideTargetHighlight1");

            GUIInsertHelpers.AddGUIInsert("SideTargetHighlight2");

            GUIInsertHelpers.AddGUIInsert("SideTargetHighlight3");

            GUIInsertHelpers.AddGUIInsert("SideTargetHighlight4");

            GUIInsertHelpers.AddGUIInsert("SideTargetHighlight5");

            GUIInsertHelpers.AddGUIInsert("SideTargetHighlight6");

            GUIInsertHelpers.AddGUIInsert("SideTargetHighlight7");

        } 

In P3SampleApp, the InfoPopup GUIInsert is used in PopupMode. The SideTargetHighlightN GUIInserts are used in SideTargetMode.

GUIInserts are registered in the Start() method of BaseGameMode. This occurs during the call to base.Start() in the Start() method of <appcode>BaseGameMode.

Modes that use GUIInserts should be created only after GUIInserts have been registered. For example, in P3SABaseGameMode, HUDMode and PopupMode are created in Start(). In contrast, BumpersMode can be created in mode_started() because it does not use GUIInserts.

Whenever a Mode is created, the P3Mode base class creates a new GUIInsertScript for each registered GUIInsert. These scripts are for the exclusive use of this mode. All the scripts are empty and at the same priority as the Mode. The list of scripts is stored in the field GUIInsertScripts. The same scripts are also stored in the field GUIInsertScriptsDict which is a Dictionary mapping the GUIInsert name to the corresponding script.

        protected List<GUIInsertScript> GUIInsertScripts;

        protected Dictionary<string, GUIInsertScript> GUIInsertScriptsDict;

This is not mandatory, but it’s simpler to reuse the scripts that are already created by the base class. For the GUIInsert named insertName, the mode can access the corresponding script with

GUIInsertScriptsDict["insertName"]

The scripts are not automatically added to GUIInsertControllerMode. The Mode must configure the scripts for the GUIInserts it controls. After the Mode is started, it can add these scripts to GUIInsertControllerMode explicitly.

When the Mode ends, the SDK automatically removes the scripts from GUIInsertControllerMode. It can do this because it maintains the list of all scripts in the GUIInsertScripts field. This might try to remove some scripts that were never added, but that’s not a problem.

Helper Methods

GUIInsertHelpers got its name because it contains many helper functions. A typical helper function takes an existing GUIInsertScript, clears it, adds some commands to achieve a specific effect and finally adds the newly configured script to GUIInsertControllerMode.

static GUIInsertScript OnInsert(P3Controller controller, GUIInsertScript script, ushort[] color)

static GUIInsertScript OnInsert(P3Controller controller, GUIInsertScript script, string text, ushort[] textColor, ushort[] color)

static GUIInsertScript PulseInsert(P3Controller controller, GUIInsertScript script, ushort[] pulseColor, ushort[] endColor)

static GUIInsertScript FadeOutInsert(P3Controller controller, GUIInsertScript script, ushort[] color, double fadeTime)

static GUIInsertScript FadeOutInsert(P3Controller controller, GUIInsertScript script, string text, ushort[] textColor, ushort[] color, double fadeTime)

static GUIInsertScript BlinkInsert(P3Controller controller, GUIInsertScript script, ushort[] color)

static GUIInsertScript BlinkInsert(P3Controller controller, GUIInsertScript script, ushort[] color, double fadeOnTime, double onTime, double fadeOffTime, double offTime)

static GUIInsertScript BlinkInsert(P3Controller controller, GUIInsertScript script, string text, ushort[] textColor, ushort[] color)

static GUIInsertScript BlinkInsert(P3Controller controller, GUIInsertScript script, string text, ushort[] textColor, ushort[] color, double fadeOnTime, double onTime, double fadeOffTime, double offTime)

The return value is the GUIInsertScript passed as argument.

Since these helper methods add the script to GUIInsertControllerMode, make sure you call them only when the mode is already started. In particular, do not initialize the scripts in the mode constructor with these methods.

You will often see this pattern, where the return value is assigned back to the Dictionary:

GUIInsertScriptsDict["insertName"] = GUIInsertHelpers.OnInsert(p3,

GUIInsertScriptsDict["insertName"], color);

Unfortunately, this code forgets to update the list in the field GUIInsertScripts. If the return value were a different script, that would break the automatic removal of the scripts when the mode ends. Fortunately, the returned script is always the same script that was passed in. We can simplify the statement by removing the assignment:

GUIInsertHelpers.OnInsert(p3, GUIInsertScriptsDict["insertName"], color);

GUIInsertHelpers also has this helper method to add or remove a script:

static void AddorRemoveScript(GUIInsertScript script, bool run)

Call GUIInsertHelpers.AddOrRemoveScript(script, true) to post the Evt_AddGUIInsertScript event and thus add the script to GUIInsertControllerMode.

Call GUIInsertHelpers.AddOrRemoveScript(script, false) to post the Evt_RemoveGUIInsertScript event and thus remove the script from GUIInsertControllerMode.

The AdjustColor() method in GUIInsertHelpers reduces the color values to 1/4 of the original values if the name contains the keyword "flasher". This method is a carry-over from LEDHelpers, where it makes more sense.  

static ushort[] AdjustColor(string name, ushort[] startingColor)

Synchronizers

A synchronizer is an object that can ensure multiple GUIInsertScripts start at the same time. GUIInsertHelpers has two methods to create a synchronizer:

static void AddSynchronizerGroup(int index, Double interval)

static void AddSynchronizerGroup(int index, Double interval, int dependentIndex)

The index is the id of the synchronizer. The scripts reference the synchronizers by their index. The interval is the period between synchronizer firings. The dependentIndex is the index of another synchronizer that must fire for this synchronizer to fire.

The synchronizer index value is arbitrary. The application can choose any integer as long as it does not collide with an existing synchronizer. It is common to use very small integers.

Synchronizers cannot be removed once they are created. Make sure you do not continuously create new synchronizers because that will cause a leak.

GUIInsertHelpers.AddSynchronizerGroup() is implemented by posting the Evt_AddGUIInsertSynchronizerGroup event with an array of 3 doubles corresponding to the 3 arguments of AddSynchronizerGroup(). BaseAppMode handles this event and calls AddSynchronizer(index, interval, dependentIndex) directly on the GUIInsertControllerMode instance.

To enroll the GUIInsertScript in a synchronizer group, assign the synchronizer index to the script:

        script.synchronizerIndex = index;

The GUIInsertScript documentation says the default value of synchronizerIndex is 0, but the real default value is -1. This means the script is not controlled by any synchronizer unless its synchronizerIndex is assigned.

Think of it this way for the case without a dependentIndex. The synchronizer defines a set of GUIInsertScripts. The synchronizer fires at regular intervals. When the synchronizer fires, it adds all its GUIInsertScripts to GUIInsertControllerMode. If the scripts were currently executing (because they took longer than the interval), they get reinitialized to the beginning. The controller sorts all the scripts by GUIInsert and priority. For each GUIInsert, the script with the highest priority is the one that runs (not necessarily what was just added by the synchronizer).

delayedGUIInsertScript is an internal data object used by GUIInsertControllerMode to manage the execution delay caused by a synchronizer interval. This is an implementation detail because you never interact with that class.

Evt_RunGUIInsertCommand<insertName>

When a GUIInsertScript is selected for execution, it runs its commands one after the other.

To execute a GUIInsertCommand, the script posts the ModeToGUI event Evt_RunGUIInsertCommand<insertName> with the GUIInsertCommand as the event data. Notice how the insertName is appended to the event name. This way, the event goes directly to the intended GUI Component without affecting other objects.

The GUI components that can handle the event are: ColorReceiver and TextReceiver.

GUIInsertColorChanger can also handle the event but it is obsolete. Use ColorReceiver and/or TextReceiver instead.

ColorReceiver

The ColorReceiver component can be added to a GameObject to handle the color changing requests coming from GUIInsertScripts. This component expects a Renderer, Image, RawImage, and/or Button on the same GameObject. It can also use an optional Material component directly on the game object to override the Renderer's Material.

In the Inspector, set the ColorReceiver id to the GUIInsert name.

ColorReceiver handles the Evt_RunGUIInsertCommand<id> event expecting a GUIInsertCommand in the event data. It executes the command by doing the linear interpolation of the color.

ColorReceiver handles the Evt_State<id> event expecting a bool as event data. Pass true to enable the Renderer, false to disable it. LanesMode and HUDMode are examples of modes posting the Evt_State<id> event.

TextReceiver

The TextReceiver component can be added to a GameObject to handle text string and color changing requests coming from GUIInsertScripts. This component expects a Text or TextMesh on the same GameObject.

In the Inspector, set the TextReceiver id to the GUIInsert name. Also specify whether to updateMaterialColor, the defaultFontSize, whether to adjustFontSizePerBounds, and the bounds.

TextReceiver handles the Evt_RunGUIInsertCommand<id> and Evt_State<id> events like ColorReceiver.

TextReceiver also handles the Evt_Text<id> event expecting a text string as event data. The TextReceiver reacts by changing the text on the Text or TextMesh component.

GUIInsert Prefab

There is no GUIInsert Prefab. You will have to create your own if you have multiple GUIInserts in your scenes. Use the two examples below for guidance.

You can see a ColorReceiver in the HomeScene at the path Home/SideTargets/Highlights/SideTargetHighlight0

You can see a TextReceiver in the HomeScene at the path Home/ApronDisplay/BallNumber

Modes Using GUIInserts

Here is a list of modes that use GUIInserts one way or another.

GUIInsertControllerMode orchestrates the execution of the scripts.

BaseAppMode creates the BaseGUIInserts mode and the GUIInsertControllerMode. It handles the Evt_AddGUIInsertScript, Evt_RemoveGUIInsertScript, Evt_AddGUIInsertSynchronizerGroup by making the corresponding call directly on the GUIInsertControllerMode instance.

BaseGUIInserts mode blackens all GUIInserts when it starts.

BonusMode blackens all GUIInserts when it starts.

PopupMode handles these events:

Many modes send these events to show a diagnostic or error message.

SideTargetMode controls the SideTargetHighlights, blinking when unhit, steady on when hit, off when all targets are complete.

RGBFadeLightShow in LEDShowControllerMode.cs turns a list of GUIInserts red, green, blue and black in sequence.

HomeMode, P3SAAttractMode and SceneMode blacken all GUIInserts when the scene goes live.

Appendix: Comparison of GUIInsertScript vs LEDScript APIs

GUIInsert

LEDs

Script Class

GUIInsertScript

LEDScript

Declaration

RegisterGUIInserts()

Base machine definition and module definition file

Dictionary

GUIInsertScriptsDict["name"]

p3.LEDs["name"]

default

autoRemove

false

true

Controller

Mode

GUIInsertControllerMode

LEDControllerMode

Add

GUIInsertHelpers.AddOrRemoveScript(script, true)

p3.LEDController.AddScript(script, -1, 0)

Remove

GUIInsertHelpers.AddOrRemoveScript(script, false)

p3.LEDController.RemoveScript(script)

Synchronizer

GUIInsertHelpers.AddSynchronizerGroup(

    index, interval, dependentIndex)

p3.LEDController.AddSynchronizer(

    index, interval, dependentIndex)