Controllable Plugins #

Controllable plugins are custom controllables that can be added to a scene at runtime with the API. Before running the simulator (running the executable or pressing Play in the Editor) controllable plugins must be built by the simulator using Simulator -> Build... menu and the built asset placed in the AssetBundles/Controllables folder.

Open-source example:

Table of Contents

Building Controllable Plugins top#

  1. Open Simulator -> Build... menu item
  2. Select controllable plugins in "Controllables" section of build window
  3. Build plugins with "Build" button

The bundle named controllable_XXX will be placed in the AssetBundles/Controllables folder. If building the binary, this folder is included in the target destination.

See build instructions for more details.

Creating Controllable Plugins top#

Create a folder in Assets/External/Controllables , e.g. Assets/External/Controllables/TrafficCone.

Inside this folder you must place the controllable prefab with same name (TrafficCone.prefab) that will be used by simulator to instantiate at runtime, the controllable logic script and Models folder with materials and textures.

This prefab must have a logic script that inherits interface IControllable and added to the root of the prefab. The controllable tag and layer for traffic cone is set to Obstacle. If collisions are desired, then add a collider components. A Rigidbody component can be added if velocity changes are desired, if not, velocity change commands will be ignored.

To create a prefab:

  1. Right-click in the scene hierarchy and select Create Empty
  2. Change the name to the name of the controllable (e.g. TrafficCone)
  3. In the Inspector for this object, select Add Component
  4. Search for the controllable script
  5. Add Rigidbody if needed
  6. Add Collider if needed
  7. Drag this object from the scene hierarchy into the project folder to create a new prefab, delete prefab in Hierarchy panel

Controllable Logic top#

Additionally place a C# script which will be compiled & bundled with prefab, as well as any additional Unity resources (shaders, materials, textures, etc...). This is required even for simple objects such as a Traffic Cone.

Controllable scripts must inherit interface IControllable which allows controllables to receive API commands. In addition, it must implement all interface variables and methods. See the below code block from TrafficCone.cs:

namespace Simulator.Controllable
{
    public class TrafficCone : MonoBehaviour, IControllable
    {
        public bool Spawned { get; set; }
        public string UID { get; set; }
        public string GUID => UID;
        public string ControlType { get; set; } = "cone";
        public string CurrentState { get; set; }
        public string[] ValidStates { get; set; } = new string[] { };
        public string[] ValidActions { get; set; } = new string[] { };
        public List<ControlAction> DefaultControlPolicy { get; set; } =
            new List<ControlAction>
            {
                new ControlAction { Action = "state", Value = "" }
            };

        public List<ControlAction> CurrentControlPolicy { get; set; }

        private void Awake()
        {
            CurrentControlPolicy = DefaultControlPolicy;
            Control(CurrentControlPolicy);
        }

        protected void OnDestroy()
        {
            Resources.UnloadUnusedAssets();
        }

        public void Control(List<ControlAction> controlActions)
        {
            foreach (var action in controlActions)
            {
                switch (action.Action)
                {
                    case "state":
                        CurrentState = action.Value;
                        break;
                    default:
                        Debug.LogError($"'{action.Action}' is an invalid action for '{ControlType}'");
                        break;
                }
            }
        }
    }
}