Expose Parameters to the Remote App with LiveProperty
Many features are still experimental and breaking changes may occur.
Attaching attributes such as [LiveClass] / [LiveField] / [LiveProperty] to a Studio-app-side script in VirgoMotionStudioTemplate turns that member into a LiveProperty. LiveProperties are used consistently for the following purposes:
- Editing values and calling functions from the Remote App
- Saving to and restoring from a live scene (
*.live.json) - Recording to and playback from live data (
*.live.bin)
Exposed* attributesIn RemoteControl 0.26.0, the Exposed* attributes such as [ExposedClass] were renamed to Live*. See Migrating from the Old Names for the mapping.
Minimal Example
1. Write a Script
Attach [LiveClass] and [LiveField] to a MonoBehaviour.
using UnityEngine;
using Lilium.RemoteControl;
[LiveClass]
public class MyEffect : MonoBehaviour
{
[LiveField]
public int hoge;
}
2. Add a GameObject and Attach the Script
Create an empty GameObject in the Studio scene of VirgoMotionStudioTemplate and attach the script above.

3. Register It with the Remote Control Container
Select the Remote Control Container GameObject already placed in the scene, and add an entry to the Objects list of the Remote Control Container component.
- Press the
+button onObjects, then selectLiveGameObjectfrom the type dropdown - Drag the GameObject created in step 2 into the
Referencefield of that entry
The Id is assigned automatically when you add the entry. Values restored from a live scene are matched to this Id, so avoid changing it later.
Simply attaching [LiveClass] will not make it appear on the Remote App's "Live Scene" page. The [LiveClass] components attached to the GameObjects registered in Objects are exposed together.
If you also want to control position, rotation, and scale from the Remote App, choose LiveGameObjectWithTransform instead of LiveGameObject.
4. Verify the Behavior
Press Play in the Unity Editor, or launch the built app and connect from the Remote App. MyEffect will appear on the Remote App's "Live Scene" page, and the hoge field will be shown as an integer input. Changing the value is reflected immediately, and saving the live scene writes it to *.live.json.

You don't need to press Play — starting the server via the toggle in the editor toolbar (the devices icon) lets you connect from the Remote App while staying in Edit mode.
The [LiveField] and other attributes you add may not be recognized correctly on the Remote App side. In that case, stop Play mode, then press the Reset button in Window > Lilium Remote Control > UI Designer and re-enter Play mode.

Choosing Between Attributes
| Attribute | Target | Purpose |
|---|---|---|
[LiveClass] | class / struct | Registers this type as one that holds LiveProperties |
[LiveField] | field | Exposes a field and makes it editable |
[LiveProperty] | property | Exposes a property. Editable if it has a setter; read-only display if it only has a getter |
[LiveFunction] | method | Exposes a method as a button |
[LiveEnum] | enum | Required to display enum values as a dropdown |
[Help("...")] | any of the above | Shows help text in the Remote App |
[Hide] | field / property / method | Hides an already-exposed member from the Remote App UI |
[LiveField] is sufficient in most cases. Use [LiveProperty] when you want to run logic when the value changes.
Running Logic on Value Change with LiveProperty
When you write to a property with [LiveProperty] from the Remote App, its setter is called. Write logic in the setter to reflect the change in the scene immediately.
using UnityEngine;
using Lilium.RemoteControl;
[LiveClass]
public class MyLight : MonoBehaviour, ILiveDeserializeCallback
{
[SerializeField]
private Light targetLight;
// The value that actually gets saved (shadow field)
[LiveField, Hide, FormerlyNamedAs("intensity")]
private float _intensity = 1f;
// The member shown to the Remote App
[LiveProperty, Slider(0f, 8f)]
public float intensity
{
get => _intensity;
set
{
_intensity = value;
targetLight.intensity = value; // logic run on change
}
}
// Called after the live scene finishes loading
public void OnAfterLiveDeserialize()
{
targetLight.intensity = _intensity;
}
}
[LiveProperty]alone is not saved to the live scene. To save it, pair it with a field marked[LiveField, Hide, FormerlyNamedAs("propertyName")]. This field is called a shadow field, and only the property side is shown in the Remote App.- Saving and restoring a live scene reads and writes the shadow field directly; the setter is not called. Put any logic that needs to run after loading in
ILiveDeserializeCallback.OnAfterLiveDeserialize. - If the actual value lives on another component and the shadow field can go stale, update the shadow field right before saving in
ILiveSerializeCallback.OnBeforeLiveSerialize.
Customize How Values Are Displayed
Numeric sliders, labels, display order, and so on can be controlled via attributes.
using UnityEngine;
using Lilium.RemoteControl;
[LiveClass(Category = "Effect", Icon = "auto_fix_high")]
public class MyEffect : MonoBehaviour
{
[LiveField, Slider(0f, 1f, 0.01f)]
public float intensity = 0.5f;
[LiveField, Slider(1, 10)]
public int repeat = 3;
[LiveField]
public Color tint = Color.white;
[LiveFunction(label = "Reset")]
public void ResetParams()
{
intensity = 0.5f;
repeat = 3;
tint = Color.white;
}
}
| Setting | Effect |
|---|---|
[Slider(min, max, step)] | Displays a numeric value as a slider (omitting step defaults to 1/20 of the range) |
[LiveClass(Category = "...")] | The category heading on the "Live Scene" page |
[LiveClass(Icon = "...")] | Specifies a Material Icons icon name |
label | Display name (e.g. [LiveField(label = "Strength")]) |
order | Display order (negative comes earlier, positive comes later) |
[LiveFunction(icon = "...")] | Icon shown on the button (Material Icons) |

Expose enum Values as Choices
For a field of an enum type, the enum itself must have [LiveEnum] attached.
using UnityEngine;
using Lilium.RemoteControl;
[LiveEnum]
public enum EffectMode
{
Off,
Soft,
Strong,
}
[LiveClass]
public class MyEffect : MonoBehaviour
{
[LiveField]
public EffectMode mode = EffectMode.Soft;
}

For enums you can't attach an attribute to, such as HumanBodyBones, register them with the assembly attribute [LiveExternalEnum].
[assembly: Lilium.RemoteControl.LiveExternalEnum(typeof(UnityEngine.HumanBodyBones), excludeNames = new[] { "LastBone" })]
Conditional Display
ShowIf / HideIf let you control visibility based on the value of another field. When you attach more than one, the member is shown only when all conditions are met. They can also be attached to [LiveFunction] buttons.
[LiveField]
public bool useColor;
[LiveField, ShowIf(nameof(useColor), true)]
public Color color = Color.white;
Choosing Where a Value Is Saved
By default, LiveProperty values are saved to the live scene (*.live.json).
| Setting | Where it's saved |
|---|---|
| (none) | The live scene (*.live.json) |
[LiveField(persistable = false)] | Not saved (still exposed to the Remote App) |
[LiveField(persistScope = PersistScope.Project)] | A project-wide settings file ({ClassName}.settings.json) |
Use persistable = false for temporary, experimental values or values you want reset on every launch. Use PersistScope.Project for settings that don't change when you switch scenes, such as a port number.
Members saved to the live scene are also eligible for recording in live data. Members that aren't saved, or that are saved to project settings, are not recorded.
Adding, type-changing, or renaming exposed members can break compatibility with previously saved *.live.json files. When renaming, attach [FormerlyNamedAs("oldName")] so values saved under the old name can still be restored. It can also be used when renaming a class.
Exposing Values Without Changing a Script (LiveClassAsset)
Classes you can't attach attributes to — Unity's built-in components, third-party components, and the like — can be exposed with a Live Class Asset.
- Open
Window > Lilium Remote Control > Live Class Asset - Assign a Live Class Asset to
Preset(useNewto create one) - In the class list, use
+(search across all classes) orFrom Selected(choose from the components on the currently selected GameObject) to add a class - In the detail pane on the right, use
+to check the properties, fields, and methods you want to expose. Labels and controls (such as sliders) are also configured here - Apply the asset. To apply it project-wide, add it to the list in
Project Settings > Lilium Remote Control; to carry it around with a scene or set, add it to theAssetslist of aRemote Control Container
Register the GameObject that holds the component you want to expose in the Remote Control Container's Objects, the same as in step 3. For detailed steps, see Expose Any Property with a LiveClassAsset.
Migrating from the Old Names
In RemoteControl 0.26.0, every "Exposed" name was renamed to "Live".
| Old | New |
|---|---|
[ExposedClass] | [LiveClass] |
[ExposedField] | [LiveField] |
[ExposedProperty] | [LiveProperty] |
[ExposedFunction] | [LiveFunction] |
[ExposedEnum] | [LiveEnum] |
[ExposedExternalEnum] | [LiveExternalEnum] |
[ExposedKey] | [LiveKey] |
[ExposedDefault] | [LiveDefault] |
[ExposedHelp("...")] | [Help("...")] |
[FormerlyExposedAs("...")] | [FormerlyNamedAs("...")] |
ExposedGameObject / ExposedGameObjectWithTransform | LiveGameObject / LiveGameObjectWithTransform |
OnExposedChanged / OnExposedReset | OnLiveChanged / OnLiveReset |
- Entries already registered in a
Remote Control Containerand elsewhere are loaded automatically under the new type names.
Related Links
- SDK Components — The structure of the SDK, including the
RemoteControlpackage - Remote Control Release Notes — Details of the 0.26.0 changes