|
| 1 | +--- |
| 2 | +title: Media Controller |
| 3 | +description: Manual for the included media controller |
| 4 | +--- |
| 5 | + |
| 6 | +> [!NOTE] |
| 7 | +> |
| 8 | +> The VPE media controller is very basic compared to the fully featured Kivvy |
| 9 | +> and Godot based media controllers by the MPF developers. |
| 10 | +
|
| 11 | +# Media Controller |
| 12 | + |
| 13 | +MPF is designed with real pinball machines in mind and those typically have a |
| 14 | +specialized circuit board for controlling the playfield hardware. To allow MPF |
| 15 | +to control your virtual playfield, VPE connects to MPF as if it was a stupid |
| 16 | +little circuit board that can do nothing but turn coils and lights on and off. |
| 17 | +As a result, MPF only gives simple orders to VPE without providing any |
| 18 | +information about the larger context within the current game, like what modes |
| 19 | +are active, how many players there are, or even what the score is. To get this |
| 20 | +information, VPE connects to MPF through a separate channel designed for |
| 21 | +controlling the displays and speakers in the backbox. |
| 22 | + |
| 23 | +## Text |
| 24 | + |
| 25 | +<img src="mpf-current-player-text.png" alt="Current player text component" width="367" class="img-fluid float-end" style="margin-left: 15px; margin-bottom: 10px"> |
| 26 | + |
| 27 | +To display variables from MPF (such as the current player's score) in a text |
| 28 | +field, you can use one of the following components: |
| 29 | + |
| 30 | +- **MPF Current Player Text** shows the number of the player whose turn it is. |
| 31 | +- **MPF Player Count Text** shows the number of players in the current game. |
| 32 | +- **MPF Machine Variable Text** and **MPF Player Variable Text** show machine |
| 33 | + and player variables, respectively. For technical reasons, they each have |
| 34 | + three variants: |
| 35 | + - **String** for text variables including symbols other than numeric digits |
| 36 | + - **Int** for whole numbers |
| 37 | + - **Float** for decimal numbers |
| 38 | + |
| 39 | +You can find these components under _Pinball -> MPF Media Controller_ in the |
| 40 | +_Add Component_ menu. Each component needs a text field to show the text. To |
| 41 | +create one, right-click in your hierarchy and select _UI -> Text - Text Mesh |
| 42 | +Pro_. If prompted, import the TMP Essential Resources, then drag the game object |
| 43 | +of the newly created text field into the _Text Field_ box on the MPF text |
| 44 | +component. To learn about positioning and styling text fields and other UI |
| 45 | +elements, refer to the |
| 46 | +[Unity documentation](https://docs.unity3d.com/Packages/com.unity.ugui@latest). |
| 47 | + |
| 48 | +### Formatting |
| 49 | + |
| 50 | +By default, the text field will display the variable as it was received from |
| 51 | +MPF, but you can optionally specify a format string to customize how the value |
| 52 | +from MPF is converted to text. The most basic way to use this feature is to add |
| 53 | +additional text before or after the variable. For example, enter `P{0}` into the |
| 54 | +_Format_ field of an _MPF Current Player Text_ component to prefix the player |
| 55 | +number with the letter 'P.' Using more advanced format string features, it is |
| 56 | +possible to separate every third digit of the score number with a comma or round |
| 57 | +to a certan number of decimal places. You could learn how to do that and much |
| 58 | +more in |
| 59 | +[Microsoft's introduction to string formatting in .NET](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-string-format#get-started-with-the-stringformat-method). |
| 60 | +Or you could take the easy route and just ask some LLM to write your format |
| 61 | +strings for you. |
| 62 | + |
| 63 | +## Sound |
| 64 | + |
| 65 | +<div style="overflow: auto;"> |
| 66 | +<!-- |
| 67 | +The text is shorter than the image on big screens. Make sure the next section |
| 68 | +doesn't start next to the image to avoid layout conflicts with the second image. |
| 69 | +--> |
| 70 | + |
| 71 | +<img src="event-and-mode-sounds.png" alt="Event and mode sound components" width="367" class="img-fluid float-end" style="margin-left: 15px; margin-bottom: 10px"> |
| 72 | + |
| 73 | +To play a sound effect when the player unlocks an achievement or to add a |
| 74 | +soundtrack for a specific mode, use the _MPF Event Sound_ and _MPF Mode Sound_ |
| 75 | +components. Each one allows you to specify the name of an event or mode from MPF |
| 76 | +and a sound it should trigger. _MPF Mode Sound_ has additional options for |
| 77 | +stopping the sound that are useful for music. |
| 78 | + |
| 79 | +</div> |
| 80 | + |
| 81 | +## Toggling Objects |
| 82 | + |
| 83 | +<img src="mpf-toggle-object-components.png" alt="Componenets for toggling objects" width="367" class="img-fluid float-end" style="margin-left: 15px; margin-bottom: 10px"> |
| 84 | + |
| 85 | +VPE's media controller can enable and disable game objects in the Unity scene |
| 86 | +whenever events occur or modes are triggered in MPF. While it is a far cry from |
| 87 | +what is possible with MPF's new Godot based media controller, this feature |
| 88 | +allows you to at least show and hide some graphics or videos when things happen |
| 89 | +in MPF without having to split your table across two game engines. |
| 90 | + |
| 91 | +The _Enable During MPF Mode_ component enables its parent object during the |
| 92 | +specified MPF mode and disables it otherwise. The _Toggle On MPF Event_ |
| 93 | +component enables its parent object when the _Enable Event_ occurs and disables |
| 94 | +it when the _Disable Event_ occurs. You do not have to specify both. If both are |
| 95 | +set to the same event, that event will enable the object if it is disabled and |
| 96 | +enable it when it is disabled. The MPF documentation contains a |
| 97 | +[list of all events built into MPF](https://missionpinball.org/latest/events/). |
| 98 | +In addition, you can define your own. |
| 99 | + |
| 100 | +Lastly, make sure the objects you add these components to are intially enabled. |
| 101 | +They cannot begin receiving events until their parent object is enabled. If the |
| 102 | +object should be disabled initially, do not just disable it in the scene. For |
| 103 | +objects controlled by a _Toggle On MPF Event_ component, use its _Enabled On |
| 104 | +Start_ checkbox. Objects with an _Enable During MPF Mode_ component will always |
| 105 | +be disabled on startup, at least until MPF starts the first mode. |
0 commit comments