using System; using UnityEngine; using UnityEngine.Perception.GroundTruth; using UnityEngine.Experimental.Perception.Randomization.Configuration; using UnityEngine.Experimental.Perception.Randomization.Parameters; namespace UnityEngine.Experimental.Perception.Randomization.Scenarios { /// /// The base class of all scenario classes /// public abstract class ScenarioBase : MonoBehaviour { static ScenarioBase s_ActiveScenario; bool m_SkipFrame = true; bool m_FirstScenarioFrame = true; /// /// If true, this scenario will quit the Unity application when it's finished executing /// [HideInInspector] public bool quitOnComplete = true; /// /// When true, this scenario will deserializes constants from a Json file before it begins executing /// [HideInInspector] public bool deserializeOnStart; /// /// The name of the Json file this scenario's constants are serialized to/from. /// [HideInInspector] public string serializedConstantsFileName = "constants"; /// /// Returns the active parameter scenario in the scene /// public static ScenarioBase ActiveScenario { get => s_ActiveScenario; private set { if (s_ActiveScenario != null) throw new ScenarioException("There cannot be more than one active ParameterConfiguration"); s_ActiveScenario = value; } } /// /// Returns the file location of the JSON serialized constants /// public string serializedConstantsFilePath => Application.dataPath + "/StreamingAssets/" + serializedConstantsFileName + ".json"; /// /// The number of frames that have elapsed since the current scenario iteration was Setup /// public int currentIterationFrame { get; private set; } /// /// The number of frames that have elapsed since the scenario was initialized /// public int framesSinceInitialization { get; private set; } /// /// The current iteration index of the scenario /// public int currentIteration { get; protected set; } /// /// Returns whether the current scenario iteration has completed /// public abstract bool isIterationComplete { get; } /// /// Returns whether the entire scenario has completed /// public abstract bool isScenarioComplete { get; } /// /// Called before the scenario begins iterating /// public virtual void OnInitialize() { } /// /// Called at the beginning of every scenario iteration /// public virtual void OnIterationSetup() { } /// /// Called at the start of every frame /// public virtual void OnFrameStart() { } /// /// Called the frame after an iteration ends /// public virtual void OnIterationTeardown() { } /// /// Called when the scenario has finished iterating /// public virtual void OnComplete() { } /// /// Serializes the scenario's constants to a JSON file located at serializedConstantsFilePath /// public abstract void Serialize(); /// /// Deserializes constants saved in a JSON file located at serializedConstantsFilePath /// public abstract void Deserialize(); void OnEnable() { ActiveScenario = this; } void OnDisable() { s_ActiveScenario = null; } void Start() { if (deserializeOnStart) Deserialize(); foreach (var config in ParameterConfiguration.configurations) config.ValidateParameters(); OnInitialize(); } void Update() { // TODO: remove this check when the perception camera can capture the first frame of output if (m_SkipFrame) { m_SkipFrame = false; return; } // Iterate Scenario if (m_FirstScenarioFrame) { m_FirstScenarioFrame = false; } else { currentIterationFrame++; framesSinceInitialization++; if (isIterationComplete) { currentIteration++; currentIterationFrame = 0; OnIterationTeardown(); } } // Quit if scenario is complete if (isScenarioComplete) { OnComplete(); DatasetCapture.ResetSimulation(); if (quitOnComplete) #if UNITY_EDITOR UnityEditor.EditorApplication.isPlaying = false; #else Application.Quit(); #endif } // Perform new iteration tasks if (currentIterationFrame == 0) { DatasetCapture.StartNewSequence(); foreach (var config in ParameterConfiguration.configurations) config.ResetParameterStates(currentIteration); foreach (var config in ParameterConfiguration.configurations) config.ApplyParameters(currentIteration, ParameterApplicationFrequency.OnIterationSetup); OnIterationSetup(); } // Perform new frame tasks foreach (var config in ParameterConfiguration.configurations) config.ApplyParameters(framesSinceInitialization, ParameterApplicationFrequency.EveryFrame); OnFrameStart(); } } }