About VaM Plugins

Below are some fundamental concepts about Virt-A-Mate (VaM) plugins that will help you understand how they are structured and how they work.

Types of Plugins

There are three types of plugins in VaM:

  1. Scene Plugins

    • The plugin is loaded and active only within the current scene.
  2. Session Plugins

    • The plugin remains active for the entire VaM session (across all scenes) until VaM is closed.
  3. Atom Plugins

    • The plugin interacts with a specific atom (a scene object), such as a character or other scene element.
    • Example: Plugins that perform actions on ‘people’ or other individual objects.

What Are Plugins?

  • Plugins are Simply C# Script Files:
    Plugins are implemented as *.cs script files using Mono C# — Microsoft’s open source variation of the .NET framework. An alternative approach to managing multiple scripts within a single plugin is to use a .cslist file. This file acts as a manifest, listing multiple C# files that collectively function as one plugin instance. Each .cslist file can be loaded as a single Atom, Session, or Scene plugin instance. For example, your .cslist file might contain:
src/Lapiro_Routimator.cs
src/MacGruber_Utils.cs

Each line in the file represents a C# script that implements a plugin. When Virt-A-Mate initializes, it reads this file and loads every plugin specified, streamlining the process of adding or removing functionality.

  • Inheritance Hierarchy:

    • All VaM plugins derive from MVRScript.
    • MVRScript itself is a subclass of Unity’s MonoBehaviour.
    • This means your plugin can access all methods and properties available in MVRScript, which in turn gives you access to Unity’s rich functionality provided by MonoBehaviour.
  • Superclasses and Inheritance:

    • MVRScript is the superclass of your plugin, hiding a lot of functionality that you can use.
    • MonoBehaviour (from Unity) is the base class for MVRScript, so you also inherit features and methods from Unity’s API.
    • You can explore the official MonoBehaviour documentation to see its inherited hierarchy. At the top of that page, you can follow the inheritance chain all the way to the base class Object.

Access Modifiers

  • Public, Private, and Protected:
    These terms refer to access modifiers which control how objects, functions, and properties are exposed:

    • Public: Accessible from any other class.
    • Private: Accessible only within the class where they are declared.
    • Protected: Accessible within the class and its subclasses.

You can search online for detailed comparisons and explanations of these modifiers.

User Interface (UI) in Plugins

  • Plugins May Need Settings:
    Some plugins require user inputs (dials, knobs, sliders, etc.) to adjust settings or parameters.

  • Building the UI:

    • If your plugin needs user input, you must build the corresponding UI elements.
    • UI is often referred to as User Interface (UI) or User Experience (UX) when emphasizing design aspects.
    • These UI elements allow users to interact with your plugin and tweak its behavior.

Below is a SimpleButtonPlugin.cs VAM plugin that creates two UI button labeled “Direct Button” and “VAM JSON Action Button”. When the button is pressed, a message (“Button pressed!”) is logged.
This VaM plugin demonstrates two distinct methods of creating UI buttons:

  1. Direct button creation (UIDynamicButton)
  2. Button created via JSONStorableAction (VAM API)
// Import the UnityEngine namespace which provides access to the Unity engine's core classes.
using UnityEngine;

// Define a new class called SimpleButtonPlugin that extends MVRScript.
// MVRScript is a base class provided by Virt-A-Mate (VAM) for creating custom plugins.
// It gives you access to VAM's API, allowing you to create custom behavior and UI elements.
public class SimpleButtonPlugin : MVRScript
{
    // JSONStorableAction button
    private JSONStorableAction jsonActionButton;
  
    // The Init() method is called by VAM when the plugin is initialized.
    // This is where you set up your UI components and any initial logic.
    public override void Init()
    {
        // ----- Method 1: Direct UIDynamicButton -----
        // Create a new button using VAM's CreateButton method.
        // The method returns an instance of UIDynamicButton, a custom UI component provided by VAM.
        // UIDynamicButton is part of VAM's dynamic UI system, and it isn't found in standard Unity libraries.
        // The first argument "Direct Button" sets the button's label.
        // The second argument (false) determines whether the button appears on the right side (true) or left side (false) of the UI panel.
        UIDynamicButton myButton = CreateButton("Direct Button", false);
        
        // Register the OnButtonPressed method as a callback for when the button is clicked.
        // The 'onClick' event of the button (a UnityEvent) is used to trigger any assigned listener methods.
        // When the button is pressed, the OnButtonPressed method will be invoked.
        myButton.button.onClick.AddListener(OnButtonPressed);
      
        // ----- Method 2: JSONStorableAction (Externally accessible) -----
        // Define an action that can be triggered externally and persistently
        jsonActionButton = new JSONStorableAction("VAM JSON Action Button", OnJSONActionButtonPressed);
        RegisterAction(jsonActionButton);
      
        // Create a button and bind it directly to this JSONStorableAction
        CreateButton("VAM JSON Action Button", false).button.onClick.AddListener(() => jsonActionButton.actionCallback.Invoke());
    }

    // This is the callback method that gets called when the button is pressed.
    // It uses VAM's SuperController to log a message, which is helpful for debugging.
    // SuperController is part of VAM's internal framework for managing logging and overall control.
    private void OnButtonPressed()
    {
        // Log a message to the VAM console to indicate that the button has been pressed.
        SuperController.LogMessage("Direct button pressed!");
    }
  
        // Callback method for the JSON Action button
      private void OnJSONActionButtonPressed()
    {
        // Log a message to the VAM console to indicate that the  JSON button has been pressed.
        SuperController.LogMessage("JSON Action Button pressed!");
    }
}

🔍 Comparison Table:

Approach Advantages Disadvantages
Direct (UIDynamicButton) - Shorter and simpler- Easy direct manipulation of buttons - No automatic persistence- No external access from other plugins
VaM API (JSONStorableAction) - External plugin accessibility- Persistent and standardized- Core VaM design principle - Slightly more verbose

Recommendation (Important for Beginners):

Using JSONStorableAction and other JSONStorables is a core design principle of the Virt-A-Mate API. Prioritize their use whenever possible, as they provide standardized integration, persistence, and seamless interaction across plugins and the VaM environment.

VaM API (JSONStorableAction) External plugin accessibility