Beware this is a developer feature, the documentation is not complete but should give you an insight to develop your own applications.
You can access some of Predict Unity functionalities via script. The full documentation of the Predict Unity scripting API is not available yet but you can find bellow a quick view of the main functionalities.
The main classes that can be called within the Predict Unity plug-in are the following :
Managers :
Process Manager : start, reload and stop Predict Engine processes,
Input Manager : send user inputs to Predict Engine via the shared memory,
Output Manager : save the Predict Engine or Unity simulation,
Shortcut Manager : a component that gives access to all Predict Unity basic tools,
Batch Renderer : save a batch of Predict Engine simulations.
Components :
UVR Camera Component : the Predict Engine camera settings,
UVR Physical Sensor Component : the Predict Engine physical sensor settings,
UVR Light Component : the Predict Engine light settings,
UVR Skybox Component : the Predict Engine environment settings,
UVR Scene Component : the Predict Engine scene settings.
Pickers :
Transform Picker : move GameObjects in the scene,
Material Picker : change the materials of one or several geometries in the scene,
Rgb Environment Picker : change the environment of one of the cameras in the scene,
Setup Picker : enable and disable elements in the scene,
Geometry Picker : change the mesh on a geometry,
IES Picker : change the IES on a photometric area light,
Display EDF Picker : change the measure on a display area light.
The main functionalities in the Predict Unity plug-in are described bellow :
UVR.Tools.PluginEnvironment.StartCoroutine(string name, IEnumerator coroutine) enables you to start a coroutine from a non editor script. The name of the coroutine is for debug purpose only.
The Async function can also be called with a "yield return" to wait for the end of the process
void StartProcessForMainCamera(bool pReloadSceneStructure = true)
{
//This also works with a UVRPhysicalSensorComponent, in this case the resolution and CameraSettings are not required
UVR.Tools.PluginEnvironment.StartCoroutine("StartCameraProcessOverlay", UVR.Engine.ProcessManager.StartProcessForCameraAsync(Camera.main,
Camera.main.transform,
new Vector2Int(Camera.main.scaledPixelWidth, Camera.main.scaledPixelHeight),
UVR.Engine.CameraSettings.GetSettingsForCamera(Camera.main),
UVR.Engine.EngineProcess.ProcessTarget.Overlay,
null,
pReloadSceneStructure));
// OR
//The same can be done to start the process inside the Predict Engine view
UVR.Tools.PluginEnvironment.StartCoroutine("StartCameraProcess", UVR.Engine.ProcessManager.StartProcessForCameraAsync(Camera.main,
Camera.main.transform,
new Vector2Int(Camera.main.scaledPixelWidth, Camera.main.scaledPixelHeight),
UVR.Engine.CameraSettings.GetSettingsForCamera(Camera.main),
UVR.Engine.EngineProcess.ProcessTarget.Renderer,
null,
pReloadSceneStructure));
// OR
//If you are not sure the process is already running, you can use the following function
UVR.Tools.PluginEnvironment.StartCoroutine("StartOrReloadCameraProcessOverlay", UVR.Engine.ProcessManager.StartProcessForCameraAsync(Camera.main,
Camera.main.transform,
new Vector2Int(Camera.main.scaledPixelWidth, Camera.main.scaledPixelHeight),
UVR.Engine.CameraSettings.GetSettingsForCamera(Camera.main),
UVR.Engine.EngineProcess.ProcessTarget.Overlay,
null,
pReloadSceneStructure));
}
void StartProcessForOverlayCameras(bool pReloadSceneStructure = true)
{
UVR.Engine.ProcessManager.StartProcessForAllOverlayCameras(pReloadSceneStructure);
// OR
UVR.Tools.PluginEnvironment.StartCoroutine("StartOverlayProcesses", UVR.Engine.ProcessManager.StartProcessForAllOverlayCamerasAsync(pReloadSceneStructure));
}
void StartProcessForOutputs(bool pReloadSceneStructure = true)
{
UVR.Engine.ProcessManager.StartProcessForAllTextureCameras(pReloadSceneStructure);
// OR
UVR.Tools.PluginEnvironment.StartCoroutine("StartOutputProcesses", UVR.Engine.ProcessManager.StartProcessForAllTextureCamerasAsync(pReloadSceneStructure));
}
UVR.Engine.EngineProcess GetAProcess()
{
// ONE OF :
//First process using this sensor
return UVR.Engine.ProcessManager.GetProcessForCamera(Camera.main);
return UVR.Engine.ProcessManager.GetAllProcessesForCamera(Camera.main)[0];
//First process using this sensor and this target
return UVR.Engine.ProcessManager.GetProcessForCamera(Camera.main, UVR.Engine.EngineProcess.ProcessTarget.Overlay);
return UVR.Engine.ProcessManager.GetAllProcessesForCamera(Camera.main, UVR.Engine.EngineProcess.ProcessTarget.Overlay)[0];
//First process using this target
return UVR.Engine.ProcessManager.GetAllOverlayProcesses()[0];
return UVR.Engine.ProcessManager.GetAllTextureProcesses()[0];
return UVR.Engine.ProcessManager.GetRendererProcess();
return UVR.Engine.ProcessManager.GetProcessForTarget(UVR.Engine.EngineProcess.ProcessTarget.Overlay);
return UVR.Engine.ProcessManager.GetBatchProcess();
//First process
return UVR.Engine.ProcessManager.GetAllProcesses()[0];
}
string GetPredictEngineStatus()
{
UVR.Engine.EngineProcess lProcess = GetAProcess();
return lProcess.getState().ToString();
}
string GetPredictEnginePerfs()
{
UVR.Engine.EngineProcess lProcess = GetAProcess();
string lPerfs = "";
lPerfs += "Render time: " + lProcess.getRenderTime() + "\n";
lPerfs += "FPS: " + lProcess.getFPS() + "\n";
lPerfs += "SPP: " + lProcess.getSppMinMaxAvg().ToString() + "\n";
lPerfs += "Min Values: " + lProcess.getMinValues().ToString() + "\n";
lPerfs += "Max Values: " + lProcess.getMaxValues().ToString() + "\n";
lPerfs += "Avg Values: " + lProcess.getAvgValues().ToString() + "\n";
lPerfs += "Avg Post Processed Values: " + lProcess.getAvgPostProcessedValues().ToString() + "\n";
return lPerfs;
}
void PauseOverlayProcesses()
{
//Also possible for outputs using GetAllTextureProcesses()
List<UVR.Engine.EngineProcess> lProcesses = UVR.Engine.ProcessManager.GetAllOverlayProcesses();
foreach (UVR.Engine.EngineProcess process in lProcesses)
process.pause(true);
// OR
//Also possible for outputs using PauseProcessForAllTextureCameras(bool)
UVR.Engine.ProcessManager.PauseProcessForAllOverlayCameras(true);
}
void UnpauseOverlayProcesses()
{
//Also possible for outputs using GetAllTextureProcesses()
List<UVR.Engine.EngineProcess> lProcesses = UVR.Engine.ProcessManager.GetAllOverlayProcesses();
foreach (UVR.Engine.EngineProcess process in lProcesses)
process.pause(false);
// OR
//Also possible for outputs using PauseProcessForAllTextureCameras(bool)
UVR.Engine.ProcessManager.PauseProcessForAllOverlayCameras(false);
}
void TogglePauseForOverlayProcesses()
{
List<UVR.Engine.EngineProcess> lProcesses = UVR.Engine.ProcessManager.GetAllOverlayProcesses();
foreach (UVR.Engine.EngineProcess process in lProcesses)
process.togglePause();
}
void ReloadAllProcesses()
{
//Also possible using ReloadProcessForAllOverlayCameras(bool), ReloadProcessForAllTextureCameras(bool)
UVR.Engine.ProcessManager.ReloadAllProcesses(true);
// OR
//Also possible using ReloadProcessForAllOverlayCamerasAsync(bool), ReloadProcessForAllTextureCamerasAsync(bool)
UVR.Tools.PluginEnvironment.StartCoroutine("ReloadProcesses", UVR.Engine.ProcessManager.ReloadAllProcessesAsync(true));
//OR
List<UVR.Engine.EngineProcess> lProcesses = UVR.Engine.ProcessManager.GetAllProcesses();
foreach (UVR.Engine.EngineProcess process in lProcesses)
process.reload(process.getCameraSettings(), UVR.Engine.ProcessManager.GetGameSceneStructure(), UVR.Engine.ProcessManager.GetGameSceneData());
}
NB : It is possible to start or reload a process without reloading the content of the scene. This can be useful if you want to control and access precisely what is loaded in the Predict Engine simulation. In this case, you need to manually update the scene structure, then start the process with the ReloadSceneStructure argument set to false.
void UpdateSceneStructure()
{
//If you want to separate the loading of the scene and the start of the process, you can use the following function and start the process with pReloadSceneStructure = false
UVR.Tools.PluginEnvironment.StartCoroutine("UpdateStructure", UVR.Engine.ProcessManager.UpdateGameSceneStructure());
//You can then retrieve the structure if needed:
UVR.Engine.UVRSceneStructure lStructure = UVR.Engine.ProcessManager.GetGameSceneStructure();
UVR.Engine.UVRScene lData = UVR.Engine.ProcessManager.GetGameSceneData();
}
void StopProcesses()
{
//Also possible using StopProcessForAllTextureCameras(), StopAllRendererProcesses(), StopAllBatchProcesses()
UVR.Engine.ProcessManager.StopProcessForAllOverlayCameras();
//OR
List<UVR.Engine.EngineProcess> lProcesses = UVR.Engine.ProcessManager.GetAllProcesses();
foreach (UVR.Engine.EngineProcess process in lProcesses)
UVR.Engine.ProcessManager.StopProcess(process);
}
The engine overlay is displayed in the Unity game view. There are different display modes, see the Overlay Options section for more details on the overlay modes.
Reminder : The 4 overlay modes can be organized depending on whether or not they are interactive and automatic :
void SwitchOverlayDisplayMode()
{
UVR.Engine.InputManager.SetOverlayMode((int)UVR.Engine.ScreenOverlay.DisplayMode.AlwaysOn);
// OR
UVR.Engine.InputManager.SetOverlayInteractive(true);
UVR.Engine.InputManager.SetOverlayAutomatic(false);
// OR
UVR.Engine.InputManager.ToggleOverlayInteractive();
UVR.Engine.InputManager.ToggleOverlayAutomatic();
}
string GetOverlayDisplayMode()
{
return UVR.Engine.EngineInterfaceSettings.GetOverlayMode().ToString();
}
When the overlay mode is not automatic :
void HideShowOverlay()
{
UVR.Engine.InputManager.HideAndShowOverlay();
// OR
//Set a specific value
UVR.Engine.InputManager.HideAndShowOverlay(true);
}
void ExposureIncrease()
{
UVR.Engine.EngineProcess lProcess = GetAProcess();
//Set the exposure with a specific value
float lExposure = UVR.Engine.InputManager.GetExposure(lProcess);
lExposure += 1;
UVR.Engine.InputManager.SetExposure(lProcess, lExposure);
// OR
//Augment the exposure for the given process
UVR.Engine.InputManager.AugmentExposure(lProcess);
// OR
//Augment the exposure for all overlay process, also do it for the renderer process if includeRenderViewProcesses = true
UVR.Engine.InputManager.AugmentExposure(false);
}
void ExposureDecrease()
{
UVR.Engine.EngineProcess lProcess = GetAProcess();
//Set the exposure with a specific value
float lExposure = UVR.Engine.InputManager.GetExposure(lProcess);
lExposure -= 1;
UVR.Engine.InputManager.SetExposure(lProcess, lExposure);
// OR
//Augment the exposure for the given process
UVR.Engine.InputManager.ReduceExposure(lProcess);
// OR
//Augment the exposure for all overlay process, also do it for the renderer process if includeRenderViewProcesses = true
UVR.Engine.InputManager.ReduceExposure(false);
}
void EnableAutoExposure()
{
//Enable auto exposure for the given process
UVR.Engine.EngineProcess lProcess = GetAProcess();
UVR.Engine.InputManager.EnableAutoExposure(lProcess);
// OR
//Enable auto exposure for all overlay process, also do it for the renderer process if includeRenderViewProcesses = true
UVR.Engine.InputManager.EnableAutoExposure(true);
}
void ToggleDenoiser()
{
//Toggle the denoiser for the given process
UVR.Engine.EngineProcess lProcess = GetAProcess();
UVR.Engine.InputManager.ToggleDenoiserState(lProcess);
// OR
//Toggle the denoiser for all overlay process, also do it for the renderer process if includeRenderViewProcesses = true
UVR.Engine.InputManager.ToggleDenoiserState(true);
}
void SwitchVariant(UVR.Engine.GenericPicker pPicker, bool pReverse = false)
{
pPicker.SwitchOption(pReverse);
}
void SelectVariant(UVR.Engine.GenericPicker pPicker, int pOption)
{
pPicker.PickOption(pOption);
}
void ChangeMaterial(GameObject pGameObject, Material pMaterial)
{
UVR.Engine.MaterialPicker lMaterialPicker = pGameObject.GetComponent<UVR.Engine.MaterialPicker>();
//Use a picker : no need to reload the process if the material variant was already defined
if (lMaterialPicker != null)
{
//Switch to the next option
lMaterialPicker.SwitchOption();
// OR
//Select the given material
int lId = -1;
foreach (var lMaterial in lMaterialPicker.materials)
{
if (lMaterial == pMaterial)
{
lId = lMaterialPicker.materials.IndexOf(lMaterial);
break;
}
}
if (lId >= 0)
lMaterialPicker.PickOption(lId);
else
lMaterialPicker.PickUnlistedElement(pMaterial, pMaterial.name);
}
// OR
//Change the scene and reload the processes
else
{
MeshRenderer lRenderer = pGameObject.GetComponent<MeshRenderer>();
if (lRenderer != null)
{
//Change the material manually
lRenderer.sharedMaterial = pMaterial;
//Reload all the processes if pSendToAllProcesses = true, only the overlay processes otherwise
UVR.Engine.InputManager.ProcessInput(new UVR.Engine.InputManager.EngineInput(UVR.Engine.InputManager.EngineInputAction.ReloadRender), true);
}
}
}
void SaveTexture()
{
//Save the output of all processes
UVR.Engine.InputManager.OpenImageSaver(UVR.Engine.InputManager.ImageSaverMode.Processed, null, true, false);
// OR
//Save the output of a specific process
UVR.Engine.EngineProcess lProcess = GetAProcess();
UVR.Engine.InputManager.OpenImageSaver(UVR.Engine.InputManager.ImageSaverMode.Raw, lProcess, true, false);
// OR
//Save the output of the output processes
UVR.Engine.UVRPredictEngineOutput[] lOutputs = FindObjectsOfType<UVR.Engine.UVRPredictEngineOutput>();
foreach (var lOutput in lOutputs)
{
lOutput.SaveLDRSimulation();
lOutput.SaveHDRSimulation();
}
}
UVR.Engine.BatchRenderer.Settings ConfigureBatch(string pOutputFolder)
{
UVR.Engine.BatchRenderer.Settings lRenderingSettings = new UVR.Engine.BatchRenderer.Settings();
//REQUIRED
//Optical Instrument
///To find the correct ID for a camera, use the following function :
List<Camera> lCameras = UVR.Engine.ProcessManager.GetAllCamerasInTheScene(true);
List<UVR.Engine.UVRPhysicalSensorComponent> lSensors = UVR.Engine.ProcessManager.GetAllPhysicalSensorsInTheScene(true);
int lCameraId = lCameras.IndexOf(Camera.main); //For a camera
int lSensorId = lCameras.Count + lSensors.IndexOf(Camera.main.GetComponent<UVR.Engine.UVRPhysicalSensorComponent>()); //For a sensor
lRenderingSettings.selectedSensors = new Dictionary<int, bool>();
lRenderingSettings.selectedSensors[lCameraId] = true;
//File Name
lRenderingSettings.outputFileNameFormat = new List<UVR.Engine.BatchRenderer.Settings.FileFormatValue>() { new UVR.Engine.BatchRenderer.Settings.FileFormatValue(UVR.Engine.BatchRenderer.Settings.FileFormatElements.Scene) }; //Add here all the elements to include in the file name
lRenderingSettings.outputFileNameSeparator = "-";
lRenderingSettings.outputFileNameRemoveSpaces = false;
//Outputs
lRenderingSettings.resolution = new Vector2Int(1920, 1080);
lRenderingSettings.exportRawExr = true;
lRenderingSettings.exportProcessedPng = true;
lRenderingSettings.exportProcessedExr = true;
//Criterias
lRenderingSettings.saveCondition = UVR.Engine.BatchRenderer.SaveCondition.Time; //Time, Spp, Intervals
lRenderingSettings.saveTime = 10;
lRenderingSettings.saveSpp = 1000;
//
//OPTIONAL
//Enable the stereo mode
lRenderingSettings.stereoCamera = false; //if true, will generate an image for each eye
lRenderingSettings.interocularDistance = 0.0635f; //only required for stereo cameras
lRenderingSettings.stereoFocusedElement = null; //if not null, will focus the stereo camera on this element
//Variants
lRenderingSettings.variantsSelection = UVR.Engine.BatchRenderer.Settings.VariantsSelection.CustomSelection; //NoVariants, AllVariants, ActiveVariants, CustomSelection
lRenderingSettings.variants = new UVR.Engine.GenericPicker[] { }; //Add here the List of variants to use (you can create and configure them on the fly if necessary)
//Animations
UVR.Engine.BatchRenderer.Settings.AnimationSettings lAnim = new UVR.Engine.BatchRenderer.Settings.AnimationSettings();
lAnim.applyToCamera = false;
lAnim.clip = null; //Set here the AnimationClip to use
lAnim.transform = null; //Set here the Transform to animate
lRenderingSettings.animations = new UVR.Engine.BatchRenderer.Settings.AnimationSettings[] { lAnim }; //Add here the List of animations to use
lRenderingSettings.animTimeManagement = UVR.Engine.BatchRenderer.Settings.AnimationTimeManagement.Parallel; //Parallel, Sequential
lRenderingSettings.animLoopManagement = UVR.Engine.BatchRenderer.Settings.AnimationLoopManagement.Once; //Once, Loop, PingPong
//Predict Movie
lRenderingSettings.compileFramesToMovie = true; //To create a movie from the frames
lRenderingSettings.movieFrameRate = 25;
lRenderingSettings.movieName = "MyPredictMovie";
//
//Don't forget to compute the frames from all the given parameters when you are done
lRenderingSettings.computeSummary(true);
return lRenderingSettings;
}
void StartBatchProcess()
{
string lFolder = "Path/To/Output/Folder";
UVR.Engine.BatchRenderer.Settings lSettings = ConfigureBatch(lFolder);
UVR.Tools.PluginEnvironment.StartCoroutine("StartBatchProcess", UVR.Engine.BatchRenderer.StartRenderingAsync(lSettings, lFolder));
}