Skip to content

Custom Actions

CyanLaser edited this page Jun 25, 2022 · 6 revisions

Note that the following documentation is for CyanTrigger Version 0.4. If you are on version 0.3 or below, jump to that section.

Custom Actions are CyanTrigger’s implementation of “Sub Programs”. With the Custom Actions framework, you can define your own Actions, Events, and even custom variable types. Custom Actions can be as simple as a shortcut to writing a few actions you use often, to as complex as full custom programs that are automatically added to a CyanTrigger that references it. See the examples section for simple usages of Custom Actions.

Custom Action Indicators

While working with CyanTrigger, you may use multiple Custom Actions in your logic without even realizing it. You can see if something is a Custom Action in multiple ways. If you ever see a yellow CyanTrigger icon, this usually means it is a Custom Action

CustomActionLogo

Events

To know if an Event is a Custom Action, the Event Variant selector will show a name that differs from “VRC_Direct”. You will also see the “Custom Action Info” section under the Event Header, providing the program asset and the Custom Action Definition. Clicking on either of these will select the file in the Assets folder.

EventVRCDirect EventLocalPlayer

Actions

All Custom Actions display with an asterisk after its name to help distinguish itself from built in Udon Actions. Another indicator that an action is a Custom Action is that the name of the action will have a different color compared to built in Udon actions.

ActionLabelAsterisk

This color is configurable in the CyanTrigger Settings UI Settings section if you would like to make it more apparent than the default value. “Udon Type Name” is for built-in types and “Custom Action Name” is for Custom Actions.

ColorTheme

When a Custom Action is expanded to show its inputs, you will see the “Custom Action Info” section under the Action Variant selector, providing the program asset and the Custom Action Definition. Clicking on either of these will select the file in the Assets folder.

ActionInfo

When adding actions to an event, there will be either a # icon or a yellow CyanTrigger icon. The # icon indicates the action is a built in Udon action or defined in code, where as the yellow CyanTrigger icon indicates the action is a Custom Action.

ActionSearch

Custom Action Instances (Variable Types)

All Custom Action Instances will have an asterisk after its name in the Variables section. If the variable name is cut off, you can move your mouse to the name to bring up a tooltip with the full type name. Hovering the mouse over the variable will show a button that can be clicked to view the program asset that defined this type.

CustomVariableAsterisk

When adding a global variable, there is a section at the top listed as “Custom Type”. Clicking on this will show all the Custom Action Instances defined in the project. Each will have “(Custom)” at the end of its name to make it obvious it is not a built in Udon type.

CustomVariableSelect

Creating Custom Actions

When creating new Custom Actions, it is best to have an Udon Program already created and finalized. You can use any compiler to define the Udon Program (CyanTrigger, UdonGraph, UdonSharp), as long as you have access to the program’s asset file. When creating Custom Actions, it is recommended to not change the program much, otherwise you will need to update the Custom Actions that use it.

To start creating Custom Actions, right click in the Assets folder and select “Create/CyanTrigger/CyanTrigger Custom Action”. This will create the Custom Action Definition file. The definition file will have a Yellow CyanTrigger icon.

RightClickCreate

Drag your program asset into the “Udon Program Asset” property to begin defining Custom Actions.

DragProgram

Definition Options

EmptyAction

After creating a Custom Action and adding a program, there are multiple options to set up the Custom Action.

Default Namespace

The “Default Namespace” option represents the name of the collection of Custom Actions. When a new action is added, the name space will automatically be applied. Actions are not required to have the same namespace, although it does help keep things organized. When changing the default namespace, any defined actions that have the same namespace will also be updated. When the Custom Action Definition is set to Multi-Instance, the Default Namespace will act as the name of the custom type shown in the variable section.

Auto Add Priority

When adding actions, there is an option to have it auto added to the CyanTrigger using the Custom Action. When multiple Custom Actions are set to auto add for the same event, the Auto Add Priority will be used to determine the order in which these actions will be added. Actions with a lower number will be added before an action with a higher number.

Instance Type

Custom Actions can be treated in one of two different ways: Single-Instance vs Multi-Instance. Picking between these depends on your Udon Program and if it is necessary for multiple uses of the action to use the same data or need its own separate instance per usage.

Single-Instance Custom Actions mean that when used in a CyanTrigger, all actions from this Custom Action Definition will share the same variable data. It will act as if there is only one instance of the Udon Program inside the CyanTrigger using it. Single-Instance Custom Actions are useful for actions that do not need to save data between uses (GameObject.ToggleActive), or when the saved data should be used in all uses of the Custom Action (Transform.Respawn).

Multi-Instance Custom Actions, as the name implies, means you can have multiple instances of a Custom Action that each have their own data. Multi-Instance Custom Actions are treated like Custom Types. In order to use any actions defined in a CyanTrigger, you must also create a variable instance of this Custom Action and select that variable in the action. See the Counter example or GameObjectSyncedToggle example for more details.

Defining Actions

To add Actions to the Custom Action Definition, click on the plus icon in the actions list. This will bring up a menu where you can select from all the events on the program.

AddActionMenu

Along with the events on the program, there will always be the “Variable Setter” option. This option specifically is for when you only want to set or get variable values. It will not have any other logic. Note, if you are using CyanTrigger, some items may not show up automatically if it was generated. As an example, if the CyanTrigger itself does not use the Start or OnDeserialization event, but does use Event Replay, then these methods cannot be selected directly. To add these, you must click the “Auto Add Non-Custom Events” option. It will add the events, and enable Auto Add for these events.

After selecting an option, it will show up differently in the UI depending on the type of event. All Custom Events will show as “Action”, and all other event types will show as “Event”.

EventType

In the example, Start is the only non custom, and will show in the Events list.

ShowInEventList

MyEvent and SetMyVariable are both custom and will show up in the Action list.

ShowInActionList

When creating Custom Actions as Events, it must also define when it should call its actions. To define this, add the UdonBehaviour.SendCustomEvent action somewhere in the event. Make sure that the UdonBehaviour targets itself, This UdonBehaviour if using CyanTrigger, and the event is empty or null.

EventCallActionsDirect

This example will, on start, call the actions right away and not do anything else. You can also add logic around when or if the actions should fire.

EventCallActionsMaster

In this example, it checks if the local user is the master of the instance and only if they are the master will the actions be fired.

Action Options

After adding different actions, there are multiple options you can set on them.

ActionOptionsStart

Auto Add Action

Enabling Auto Add Action means that when this Custom Action Definition is referenced in a CyanTrigger, this specific action will be auto added into the CyanTrigger. The action will be hidden in the list so you cannot manually add it through the Event List or Action List. When Auto Add is enabled, all variables will be set to Hidden and the default value will be used. Make sure to set this value! If multiple Custom Action Definitions have Auto Add for the same events, use Auto Add Priority to determine the order in which these are added. See Transform.Respawn example for usage of Auto Add.

Action Namespace

Action Namespace is the name that will be displayed when searching for actions. You can set any name here, including built-in types like GameObject. It is recommended to keep this name the same as the default namespace on the Custom Action Definition.

Action Variant Name

Action Variant Name is the name for this specific action. Be careful when giving names. If something has the same namespace, action variant name, and variable input names, you will only be able to select one in the menu, and it will not be known which. There are no indicators at this time for name conflicts.

Description

The description field is a place for you to describe what this Custom Action does. At this time, it is not displayed anywhere.

Base Event Name

Base Event Name is used for internal purposes but shown in the inspector. It lists the type of event for this action. In the case the event type changes in the program itself, you can use the “Edit Base Action Data” option to update this event. Do this with caution as changing this can break the action itself.

Event Entry

Event Entry is used for internal purposes but shown in the inspector. It lists the compiled name of the event for this action. In the case the event name or type changes in the program itself, you can use the “Edit Base Action Data” option to update this event. Do this with caution as changing this can break the action itself.

Defining Action Inputs

InputOptionsAdding

After you have defined an Action, you can also define the inputs to this action. These inputs will affect what inputs display when using this action in the CyanTrigger. When adding an action to the Custom Action Definition, it will start with either no variables, or if the action had parameters, it will show all parameters for that action. In the example, MyCustomAction had a single parameter that will get auto added. When working with parameters, some options will be disabled, as the value is set by the parameter itself. If the parameter in the program is ever modified, you will need to manually update this custom action using the “Edit Base Action Data” checkbox at the top. See Updating Custom Actions for more details.

InputOptions

Udon Name

The udon name for an input is the name of the variable in the program. This needs to match exactly or else the custom action will not set the value properly. If this is a CyanTrigger parameter, the name should follow the format "arg(VariableName)_(EventName)"

Display Name

Display Name is the name of the input that will be displayed in the action’s inspector.

Description

The description field is a place for you to describe what this input is for. The description will be shown when hovering over the variable in the inspector.

VariableDescription

Hidden in Inspector

This checkbox will determine if the input will be shown in the inspector or not. When checked, this input will always use the default value for the action. This is useful when reusing the same event for different constant inputs. “Repeat for Multiple Objects” and “Modifies Variable” options will both be disabled.

Repeat for Multiple Objects

Repeat for Multiple Objects is a shortcut to allow the inspector to give a list option to condense the interface when calling the action multiple times. Only the first input is allowed to have this option and it will be hidden for all other inputs in the list. As the name implies, for every input in the list, the Custom Action will be called with each value, combining multiple calls into one action.

VariableMulti

Modifies Variable

Modifies variable is the equivalent of Custom Event parameter’s Output option. When unchecked, the action inspector will allow inputs, either directly or from variables. When this is unchecked, then only variables are allowed to be set in the action inspector. It is expected that the Custom Action will set the value of this variable and that value will be copied to variable used in the inspector.

VariableOutput

Default Value

The default value is the value that will be initialized in the inspector. If “Hidden in Inspector” is checked, then this value will always be used for this input. This field will be disabled when “Modifies Variable” is checked.

Updating Custom Actions

After you have created your Custom Action, it is recommended to not change the events and variables used in the program. If these events and variables do change, you will need to go back and update the Custom Action to fix the expected names. You can edit these details by checking the “Edit Base Action Data” checkbox. This is unchecked normally as modifying these values without knowing will break the Custom Action. With this checked, you can edit the following items:

  • Action Base Event Name
  • Action Entry Event
  • Action Input Udon Name
  • Action Input Parameter Modifies Variable
  • Remove Action Input Parameter
EditBaseData

Example Custom Actions

GameObject.ToggleActive

ExampleGameObjectToggleActive

GameObject.ToggleActive is one of the default Custom Actions provided with CyanTrigger. It consists of a simple CyanTrigger Program that has a GameObject global variable and a single Custom Event that gets the active state of that global variable, flips it, and sets it back. Since this is a Custom Event and not any other event, it will be treated as an Action. Looking at the Custom Action Definition, there is only one action defined. This action is in the GameObject namespace, making it show up with all the other GameObject actions. The name is ToggleActive, which is different than the event name in the program. It has a single variable input, which is the GameObject global variable in the program. It is set to repeat for multiple objects, allowing this action to apply to multiple objects in one action. This is one of the simplest types of Custom Actions that you can create. It is basically a shortcut to condense a couple of actions into one.

ExampleGameObjectToggleActiveUse

OnPlayerTriggerEnter.LocalPlayer

ExamplePlayerTriggerEnterLocal

OnPlayerTriggerEnter.LocalPlayer is one of the default Custom Actions provided with CyanTrigger. It consists of a simple CyanTrigger Program that has a single event using OnPlayerTriggerEnter. Since this is not a Custom Event, it will be treated as an Event when used. Looking at the program itself, it checks if the player that entered the trigger is the local player. If it is the local player, it sends an empty event to itself, which for Custom Actions indicates that the CyanTrigger Event’s Actions should execute. In the case that the player is not local, the actions will not execute, preventing actions from firing for remote players. Looking at the Custom Action Definition, there is only one action defined. This action is in the OnPlayerTriggerEnter namespace, making it show up with VRChat’s OnPlayerTriggerEnter Event. The name is Local Player, which indicates the variant that can be selected in the Event Header. It has no variable inputs.

ExamplePlayerTriggerEnterLocalUse

Transform.Respawn

ExampleTransformRespawn

Transform.Respawn is a Custom Action that shows off the Auto Add feature. Checking the program, there are two actions: Start and Respawn. The Start event will save the initial position and rotation of the transform. The Respawn event will then set the transform back to the original position and rotation. If there is a rigidbody it will also remove all velocity. Compared to the previous examples, this program is special in that it needs to be initialized and needs to save data between calls. This needs to be setup as two actions, one for the Start event to initialize the Custom Action, and another for Respawn to allow the user to respawn the transform. By setting the Start Custom Action to Auto Add, simply using the Transform.Respawn Custom Action will Auto Add the Start action, initializing it without the user needing to add it themselves. Auto Added actions will not show in the list for the user to add.

ExampleTransformRespawnUse

You only need to add this action anywhere in a CyanTrigger for everything to work.

Counter

Counter is a simple example showing off Multi-Instance support within Custom Actions. This Custom Action defines a counter that you can add one to the value and then check if the value “is large”.

ExampleCounter

Looking at the program, there is a single variable to hold the counter value, an event to add one to the value of that variable, and then an event to return if the value is considered “large”. In this case, large simply means greater than 10.

ExampleCounterUse

In this example using the Custom Action, two counters have been defined in the variables section: redCounter and blueCounter. Two events have been created to add to each counter, and then check if that counter is “Large”. If the value is large, print out that it is large. This example itself may not make sense, but it shows the building blocks for defining ways to handle data.

GameObjectSyncedToggle

GameObjectSyncedToggle is an example showing off Multi-Instance support within Custom Actions. This is a complicated example compared to the others. Multi-Instance is like creating your own Variable Types and is a form of subprogram that expects data to be saved for each “instance” of the Custom Action. For this example, the Custom Action will save a GameObject and a synced bool, and allow actions to toggle the bool, which will automatically set the enabled state of the saved GameObject.

SyncedToggleExampleProgram

Looking at the program, there two saved values are declared in the variables section with “isEnabled” being the synced bool, and “syncedGameObject” being the object that’s state will be toggled.

  • The “_SetGameObject” event takes in a gameobject parameter which will update the variable and update the value of the “isEnabled” variable (omitted from screenshot)
  • The “_Toggle” event will make sure the local player is the owner of the GameObject holding this action, flip the value of the synced “isEnabled” variable, and then request Udon to sync the variable to everyone in the room.
  • Finally the OnVariableChanged event checking the “isEnabled” bool will be called whenever the value updates, and it will set the enabled state for the saved GameObject.
SyncedToggleExampleDefinition

Looking at the Custom Action Definition, the main item here is that “Instance Type” is set to “Multi-Instance”. With this, you can create “instances” of the Custom Action in the Variables section of a CyanTrigger. There are 2 defined actions that link to the program with the same names.

SyncedToggleExampleUse

Here you can see a CyanTrigger using the GameObjectSyncedToggle Custom Actions. It has two Instances in the variables section: “syncedToggle1” and “syncedToggle2”. In the start method, it calls the SetGameObject for both instances, each with a different object. When using “Multi-Instance” Custom Actions, you must select which instance you want to use for each action.

SyncedToggleExampleUseInstance

After initializing the two instances, there are two methods for individually toggling each instance. “Toggle1” will toggle “syncedToggle1” instance, and “Toggle2” will toggle “syncedToggle2” instance.

SyncedToggleExampleUseHierarchy

V0.3 Custom Actions

This information only applies to CyanTrigger versions 0.3 and below. If you are on version 0.4 or above, see that section. CyanTriggers has a feature that allows for creating Custom Actions. At this time, this is still in development and some features that are missing. See the Limitations and Notes sections for more details. Currently Custom Actions can only be made from existing Udon programs. You can use UdonGraph or UdonSharp and not CyanTriggers. All Custom Actions that come with CyanTriggers were made in UdonGraph. If you would like to study how they were made, you can find them under the “Assets/CyanTrigger/Resources/DefaultCustomActions” folder.

Creating a Custom Action

You can create Custom Actions for both Events and Actions. If the Event is based on CustomEvent, then it will show up in the Actions list. If the Event is based on any other event, it will show up in the Events list. When creating Event Custom Actions, you must have at least one SendCustomEvent node with no inputs in your flow. This node will be replaced with CyanTrigger actions.

It is best to have the Udon program created and finalized before creating the CyanTrigger Custom Action definition. When you have it ready, you can create a new Custom Action Definition by right clicking in your assets folder and selecting “Create/VRChat/CyanTrigger/CyanTrigger Custom Udon Action”. This will create a new Udon based Custom Action. Drag your Udon Program into the property and it will allow you to edit the definition.

Defining Actions

To begin defining Custom Actions from your Udon program, hit the plus sign in the “Actions” list. This will pop up a list of all Events in the Udon Program. You may create multiple Custom Actions from the same event. This is useful when you want to use default variable options that are hidden in the CyanTrigger interface.

Once you have added an Action, choose a Namespace for your action. The Namespace will be used to determine where this action shows up in the Action and Event lists. If multiple use the same namespace, they will show up together. Similarly, also choose an action Variant name. This is equivalent to a method name and should describe what this Custom Action does.

Defining Action Inputs

With an Action defined, you can also edit the Inputs into this Custom Action. The Variables list will show the inputs into this action. You can only use a variable once. The choices for variables are the Public variables in the Udon Program. Each variable has a few settings:

  • Udon Name - This is the name of the variable in the Udon Program. Do not change the variable in the udon program as it will break this link.
  • Display Name - This is the name that will show in the CyanTrigger interface. It can be whatever you want, but pick something descriptive.
  • Description - Description of this variable. This will show as a tooltip over the displayname for the input in the CyanTrigger interface
  • Repeat for Multiple Objects - This option is only available to the first input in the list. If enabled, the CyanTrigger inspector will create a list for the input. This action will then be executed for each input in this list.
  • Hidden in Inspector - This option is only available for constant values with a default value set. Using this you can create different preset variants of your action.
  • Allows Constants - This option will allow constant values in the CyanTrigger interface. Not every type has an editor for constants though.
  • Allow Variable Inputs - This option will allow variables to be used as inputs into this Custom Action.
  • Modifies Variable - If checked, this means that the Udon Program will modify the variable. If this is checked, then any changes to the variable in the Udon Program will be copied over to the input variable provided in the interface. If the user provides a variable with an OnValueChanged callback, that will be checked after the Custom Action has fully completed. If this value is not checked and the Udon Program modifies the variable, this does nothing to the variable provided in the CyanTrigger interface.
  • Default Value - This is the value that will be defaulted the input allows for constant values.

Limitations

The Custom Action system is still early in development. There are limitations to what kinds of programs you can create. These may change in the future.

  • Only one state - All instances of a Custom Action on a CyanTrigger will use the same variables. If it is not set in the inspector, it will be whatever was used last. This means that if you have a Custom Action that increments a variable, that variable will be the same for all uses of the Custom Action on that CyanTrigger. There is no way to have a unique variable for each use of the Custom Action, yet.
  • One Event - As of right now, there is only one entry into a Custom Action. If you need something as a dependency, then it needs to be defined as another Custom Action and added in the CyanTrigger manually.

Notes

  • While you can have multiple Actions defined in the same Udon Program and Custom Action Definition, it is best to keep it one action per Udon Program. This is because the entire Udon assembly for the Udon Program will be copied into the CyanTrigger and unused items will bloat the CyanTrigger program.
  • Do not duplicate CyanTrigger Custom Action Definition files. Each defined action within them has a unique GUID to represent them. Duplicating the definition file does not properly generate new GUIDS yet.
  • Once you have defined a custom action, do not change names within your program source. Changing the name of the Custom Event, changing to another event, changing the name of a public variable will not properly update the definition and will cause things to break. You may however update the nodes within the program.

Examples

ActionExample

This is the Custom Action for GameObject.ToggleActive. The UdonGraph on the left uses Custom Event and has two public variables. On the right, you can see the CyanTrigger Custom Action Definition. There is only one defined action. This action only uses one of the public variables as input. This variable is allowed to be repeated for multiple instances of the action and it can be a constant or variable type. The variable will not be modified.

EventExample

This is the Custom Action for OnTriggerEnter.GameObject. The UdonGraph on the left uses the OnTriggerEnter Event and has one public variable. Note that the last node in the flow chain is SendCustomEvent with no inputs. This is important for Event Custom Actions as that is when CyanTrigger actions will be executed. You can have additional nodes following this node if you would like to perform more logic after all Actions have executed. On the right, you can see the CyanTrigger Custom Action Definition. There is only one defined action. This action uses the one public variable as input. This variable is allowed to be repeated for multiple instances of the action and it can be a constant or variable type. The variable will not be modified.