This guide will help you set up a basic UI Canvas for you VRChat world. Though this guide is targeted for Udon, most of it will still apply for SDK2 world.
The first thing you will want to do is generate your Canvas. Right click your hierarchy and choose Canvas.
A Canvas GameObject will be generated. In the canvas component of this object, you will see it by default is set to “Screen Space - overlay”. Go ahead and change that setting to be World Space. A slot for an event camera will now appear. Take your scene camera and put it into that slot.
If you want this Canvas to be interactable (or register in cameras). Change its layer from the UI layer (its default) to an interactable layer like the Default Layer. Specify for intractability, add a UI shape component. Now you can interact with every component under this canvas. Worth noting, not only can the UI layer not be interacted with by the player, it will also not appear in cameras.
Now set up the size and shape of your canvas. Begin by reducing the canvas scale, I usually recommend .01 on all transforms. Your canvas should be at a more manageable size, as well as its children transforms. Place it where you would like it.
This will be added on runtime, so I don’t think this step is always necessary, but is mentioned for debugging purposes. Add a box collider, change its scale to match the Canvas scale, the Z axis should be 1. You should have a thin box collider that covers the Canvas without it being too deep, if not match box colliders bounds to the Canvas scale. It’s important the collider is not too thick. The raycast from the player will end at the start of the collider.
You can right click the canvas and add UI objects to them, any that you generate should be on the correct layer.
If you find the text is too blurry, the canvas has a component called the UI scaler. Change the dynamic pixels per unit to about 2 or 3. Larger numbers will have a hit on performance without looking that much better.
At this point you can generate a button and it should be interactable. The button will need to be inside the Canvas. With CyanEmu (or in game, but please use CyanEmu), you should be able to click the button and see it react. The button currently does nothing as it has not been set up yet.
If you have followed setting up a Canvas, you should already have a button. If not, in your set up canvas, generate a UI Button.
The button will already have most things set up. It will include a text field as a child, a 9 sliced UI Graphic (google this if you want to make your own) and various coloring options regarding interaction.
The most important thing is choosing what the button will invoke. At the button component will be an (possibly) empty list of things it will do when the button is pressed. Click the + button. It will give you a slot for a game object. The options of what you want to invoke are dependent on the game object you put in that slot. For example, if you put in an audio source you can invoke Play(), Stop(), or Pause(). In most cases you will want to invoke custom methods from your udon code.
In this situation we will use a custom public method from the udon behavior. Similarly in SDK2, a custom trigger can be used.
Drag the Game Object with the Udon Behaviour into the empty slot on the button. You have a list of option to choose from, but for custom methods choose “UdonBehaviour.ChooseCustomEvent (string)”. This should not be under another drop down. Input the name of the method of the behavior verbatim in the field that appears. Do not include the methods parenthesis.
If the code works, the name is copied correctly, and the method is public. The method should run when the button is clicked.
You can get by with most things with just buttons and text. Sliders are a bit more complicated.
You will need three things. A UI slider (in your canvas), a public variable of type Slider in your Udon Script (this requires using UnityEngline.UI), and a custom Method that runs when you interact with the slider.
Generate a slider like you did the other UI objects. After generating the slider, set its navigation to none. This will prevent movement from affecting the slider. The Udon behavior will be assigned just like it was on the button. Use “UdonBehaviour.ChooseCustomEvent (string)” like before, and use the custom method name verbatim as well.
The Udon Behavior will have the UI slider assigned to it.
The custom method will apply the sliders value (.value) on what you wish to be affected by it. For example PointLightName.intensity = sliderName.value; If you slide it all the way down, the Point Lights intensity will be the minimum value on the slider, and vice versa. For those using Udon sharp, include using UnityEngline.UI.
With those all finished and assigned your slider should work.