比较提交

...
此合并请求有变更与目标分支冲突。
/com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/ConstantSampler.cs
/com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/NormalSampler.cs
/com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/UniformSampler.cs
/com.unity.perception/Runtime/Randomization/Samplers/SamplerUtility.cs
/com.unity.perception/Runtime/Randomization/Parameters/NumericParameter.cs
/com.unity.perception/Runtime/Randomization/Parameters/Parameter.cs
/com.unity.perception/Runtime/Randomization/Parameters/CategoricalParameter.cs
/com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs
/com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/BooleanParameter.cs
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/FloatParameter.cs
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/IntegerParameter.cs
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector2Parameter.cs
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector3Parameter.cs
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector4Parameter.cs
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaParameter.cs.meta
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsva.cs.meta
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaCategoricalParameter.cs.meta
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbCategoricalParameter.cs.meta
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbParameter.cs.meta
/com.unity.perception/Editor/Randomization/Editors.meta
/com.unity.perception/Editor/Randomization/PropertyDrawers.meta
/com.unity.perception/Editor/Randomization/PropertyDrawers
/com.unity.perception/Editor/Randomization/VisualElements.meta
/com.unity.perception/Editor/Randomization/Editors
/com.unity.perception/Editor/Randomization/VisualElements
/com.unity.perception/Editor/Randomization/StaticData.cs
/com.unity.perception/Editor/Randomization/Uxml/CategoricalOptionElement.uxml
/com.unity.perception/Editor/Randomization/Uxml/ParameterElement.uxml
/com.unity.perception/Editor/Randomization/Uxml/SamplerElement.uxml
/com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs
/com.unity.perception/Tests/Runtime/Randomization/ParameterConfigurationTests.cs
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaParameter.cs
/com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterTarget.cs
/com.unity.perception/Editor/Randomization/Uxml/ParameterAssetEditor.uxml.meta
/com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaParameter.cs
/com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterTarget.cs.meta
/com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterTarget.cs
/com.unity.perception/Editor/Randomization/Uss/Styles.uss
/com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterList.cs.meta
/com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterListException.cs.meta

10 次代码提交

共有 107 个文件被更改,包括 1656 次插入1118 次删除
  1. 49
      com.unity.perception/Editor/Randomization/StaticData.cs
  2. 2
      com.unity.perception/Editor/Randomization/Uxml/CategoricalOptionElement.uxml
  3. 33
      com.unity.perception/Editor/Randomization/Uxml/ParameterElement.uxml
  4. 1
      com.unity.perception/Editor/Randomization/Uxml/SamplerElement.uxml
  5. 21
      com.unity.perception/Runtime/Randomization/Parameters/CategoricalParameter.cs
  6. 67
      com.unity.perception/Runtime/Randomization/Parameters/Parameter.cs
  7. 15
      com.unity.perception/Runtime/Randomization/Parameters/NumericParameter.cs
  8. 22
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/BooleanParameter.cs
  9. 8
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/FloatParameter.cs
  10. 8
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/IntegerParameter.cs
  11. 12
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector2Parameter.cs
  12. 13
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector3Parameter.cs
  13. 14
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector4Parameter.cs
  14. 2
      com.unity.perception/Runtime/Randomization/Samplers/SamplerUtility.cs
  15. 16
      com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/ConstantSampler.cs
  16. 21
      com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/NormalSampler.cs
  17. 21
      com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/UniformSampler.cs
  18. 12
      com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs.meta
  19. 4
      com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs
  20. 158
      com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs
  21. 20
      com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs
  22. 30
      com.unity.perception/Tests/Runtime/Randomization/ParameterConfigurationTests.cs
  23. 83
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaParameter.cs
  24. 24
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterTarget.cs
  25. 3
      com.unity.perception/Editor/Randomization/Editors.meta
  26. 3
      com.unity.perception/Editor/Randomization/PropertyDrawers.meta
  27. 3
      com.unity.perception/Editor/Randomization/VisualElements.meta
  28. 3
      com.unity.perception/Editor/Randomization/Uss/ParameterStyles.uss.meta
  29. 17
      com.unity.perception/Editor/Randomization/Uss/SamplerStyles.uss
  30. 3
      com.unity.perception/Editor/Randomization/Uss/SamplerStyles.uss.meta
  31. 46
      com.unity.perception/Editor/Randomization/Uss/ParameterAssetStyles.uss
  32. 110
      com.unity.perception/Editor/Randomization/Uss/ParameterStyles.uss
  33. 10
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawer.uxml
  34. 3
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawer.uxml.meta
  35. 3
      com.unity.perception/Editor/Randomization/Uxml/ParameterListItemElement.uxml.meta
  36. 21
      com.unity.perception/Editor/Randomization/Uxml/ParameterAssetEditor.uxml
  37. 20
      com.unity.perception/Editor/Randomization/Uxml/ParameterListItemElement.uxml
  38. 3
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters.meta
  39. 3
      com.unity.perception/Runtime/Randomization/ParameterBehaviours.meta
  40. 3
      com.unity.perception/Editor/Randomization/PropertyDrawers/ColorHsvaDrawer.cs.meta
  41. 3
      com.unity.perception/Editor/Randomization/PropertyDrawers/ParameterDrawer.cs.meta
  42. 25
      com.unity.perception/Editor/Randomization/PropertyDrawers/ColorHsvaDrawer.cs
  43. 26
      com.unity.perception/Editor/Randomization/PropertyDrawers/ParameterDrawer.cs
  44. 73
      com.unity.perception/Editor/Randomization/Editors/ParametersAssetEditor.cs
  45. 3
      com.unity.perception/Editor/Randomization/Editors/ParametersAssetEditor.cs.meta
  46. 39
      com.unity.perception/Editor/Randomization/VisualElements/ColorHsvaField.cs
  47. 3
      com.unity.perception/Editor/Randomization/VisualElements/ColorHsvaField.cs.meta
  48. 47
      com.unity.perception/Editor/Randomization/VisualElements/DrawerParameterElement.cs
  49. 3
      com.unity.perception/Editor/Randomization/VisualElements/DrawerParameterElement.cs.meta
  50. 193
      com.unity.perception/Editor/Randomization/VisualElements/ParameterElement.cs
  51. 3
      com.unity.perception/Editor/Randomization/VisualElements/ParameterListItemElement.cs.meta
  52. 67
      com.unity.perception/Editor/Randomization/VisualElements/ParameterListItemElement.cs
  53. 107
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsva.cs
  54. 3
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsva.cs.meta
  55. 10
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaCategoricalParameter.cs
  56. 10
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbCategoricalParameter.cs
  57. 3
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaCategoricalParameter.cs.meta
  58. 3
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbCategoricalParameter.cs.meta
  59. 3
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbParameter.cs.meta
  60. 111
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbParameter.cs
  61. 3
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterBehaviour.cs.meta
  62. 3
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration.meta
  63. 3
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterAsset.cs.meta
  64. 11
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterListException.cs
  65. 28
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterListItem.cs
  66. 3
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterListItem.cs.meta
  67. 118
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterList.cs
  68. 41
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterAsset.cs
  69. 44
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterBehaviour.cs
  70. 213
      com.unity.perception/Editor/Randomization/Uss/Styles.uss
  71. 21
      com.unity.perception/Editor/Randomization/Uxml/ParameterConfiguration.uxml
  72. 6
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawerElement.uxml
  73. 3
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawerElement.uxml.meta
  74. 125
      com.unity.perception/Editor/Randomization/ParameterConfigurationEditor.cs
  75. 11
      com.unity.perception/Editor/Randomization/ParameterConfigurationEditor.cs.meta
  76. 12
      com.unity.perception/Editor/Randomization/ParameterDragBar.cs
  77. 3
      com.unity.perception/Editor/Randomization/ParameterDragBar.cs.meta
  78. 101
      com.unity.perception/Editor/Randomization/ParameterDragManipulator.cs
  79. 3
      com.unity.perception/Editor/Randomization/ParameterDragManipulator.cs.meta
  80. 374
      com.unity.perception/Editor/Randomization/ParameterElement.cs
  81. 3
      com.unity.perception/Runtime/Randomization/Configuration.meta
  82. 0
      /com.unity.perception/Editor/Randomization/Uss/ParameterAssetStyles.uss.meta
  83. 0
      /com.unity.perception/Editor/Randomization/Uxml/ParameterAssetEditor.uxml.meta
  84. 0
      /com.unity.perception/Editor/Randomization/VisualElements/CategoricalOptionElement.cs
  85. 0
      /com.unity.perception/Editor/Randomization/VisualElements/CategoricalOptionElement.cs.meta
  86. 0
      /com.unity.perception/Editor/Randomization/VisualElements/FloatRangeElement.cs
  87. 0
      /com.unity.perception/Editor/Randomization/VisualElements/FloatRangeElement.cs.meta
  88. 0
      /com.unity.perception/Editor/Randomization/VisualElements/ParameterElement.cs.meta
  89. 0
      /com.unity.perception/Editor/Randomization/VisualElements/RandomSeedField.cs
  90. 0
      /com.unity.perception/Editor/Randomization/VisualElements/RandomSeedField.cs.meta
  91. 0
      /com.unity.perception/Editor/Randomization/VisualElements/SamplerElement.cs
  92. 0
      /com.unity.perception/Editor/Randomization/VisualElements/SamplerElement.cs.meta
  93. 0
      /com.unity.perception/Editor/Randomization/Editors/ScenarioBaseEditor.cs

49
com.unity.perception/Editor/Randomization/StaticData.cs


using System;
using System.Collections;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.Perception.Randomization.Samplers;

types.Add(type);
}
return types.ToArray();
}
internal static object GetManagedReferenceValue(SerializedProperty prop, bool parent=false)
{
var path = prop.propertyPath.Replace(".Array.data[", "[");
object obj = prop.serializedObject.targetObject;
var elements = path.Split('.');
if (parent)
elements = elements.Take(elements.Count() - 1).ToArray();
foreach (var element in elements)
{
if (element.Contains("["))
{
var elementName = element.Substring(0, element.IndexOf("["));
var index = Convert.ToInt32(element.Substring(element.IndexOf("[")).Replace("[","").Replace("]",""));
obj = GetArrayValue(obj, elementName, index);
}
else
obj = GetValue(obj, element);
}
return obj;
}
static object GetValue(object source, string name)
{
if (source == null)
return null;
var type = source.GetType();
var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (f == null)
{
var p = type.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
return p == null ? null : p.GetValue(source, null);
}
return f.GetValue(source);
}
static object GetArrayValue(object source, string name, int index)
{
if (!(GetValue(source, name) is IEnumerable enumerable))
return null;
var enumerator = enumerable.GetEnumerator();
while (index-- >= 0)
enumerator.MoveNext();
return enumerator.Current;
}
}
}

2
com.unity.perception/Editor/Randomization/Uxml/CategoricalOptionElement.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement class="categorical-option ">
<VisualElement class="categorical-option">
<Button name="remove" class="remove-option-button"/>
<Label name="index-label" text="[0]" style="min-width: 50px;"/>
<editor:PropertyField name="option" class="option-property-field"/>

33
com.unity.perception/Editor/Randomization/Uxml/ParameterElement.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<Box name="parameter-container" class="parameter-container">
<VisualElement name="drag-handle" class="move-buttons-container">
<VisualElement class="drag-handle"/>
</VisualElement>
<VisualElement style="flex-grow: 1; justify-content: center; margin-right: 6px;">
<VisualElement class="parameter-type-label-container">
<Box class="parameter-type-label-box">
<VisualElement name="collapse" class="collapse-parameter-toggle foldout-open"/>
<Label name="parameter-type-label" text="Type:" class="parameter-type-label"/>
<TextField name="name" text="Parameter Name"/>
</Box>
<Button name="remove-parameter" class="remove-parameter-button"/>
</VisualElement>
<VisualElement name="properties" class="parameter-properties-container" style="margin-bottom: 2px;">
<Box>
<editor:ObjectField label="Target GameObject" name="target"/>
<VisualElement name="target-container">
<VisualElement class="unity-base-field">
<Label text="Target Property" class="unity-base-field__label"/>
<editor:ToolbarMenu text="Select A Property" name="property-select-menu" class="property-select-menu"/>
</VisualElement>
<editor:EnumField label="Application Frequency" name="application-frequency"/>
</VisualElement>
</Box>
<Box name="extra-properties" style="padding-left: 4px; border-top-width: 0px;"/>
</VisualElement>
</VisualElement>
</Box>
<VisualElement>
<Style src="../Uss/ParameterStyles.uss"/>
<VisualElement name="properties"/>
</VisualElement>
</UXML>

1
com.unity.perception/Editor/Randomization/Uxml/SamplerElement.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement name="sampler-template" style="margin-bottom: 4px;">
<Style src="../Uss/SamplerStyles.uss"/>
<VisualElement style="flex-direction: row; align-items: center;">
<Label name="sampler-name" text="Sampler Name" class="unity-base-field__label sampler-name"/>
<editor:ToolbarMenu name="sampler-type-dropdown" text="Placeholder Sampler Type" class="sampler-type-menu"/>

21
com.unity.perception/Runtime/Randomization/Parameters/CategoricalParameter.cs


[Serializable]
public abstract class CategoricalParameter<T> : CategoricalParameterBase
{
[SerializeField] internal bool uniform;
[SerializeField] internal bool uniform = true;
[SerializeReference] ISampler m_Sampler = new UniformSampler(0f, 1f);
[SerializeField] List<T> m_Categories = new List<T>();

/// Returns a list containing the samplers attached to this parameter
/// Returns an IEnumerable that iterates over each sampler field in this parameter
public override ISampler[] samplers => new [] { m_Sampler };
public override IEnumerable<ISampler> samplers
{
get { yield return m_Sampler; }
}
/// <summary>
/// The sample type generated by this parameter

/// Validates the categorical probabilities assigned to this parameter
/// </summary>
/// <exception cref="ParameterValidationException"></exception>
internal override void Validate()
public override void Validate()
{
base.Validate();
if (!uniform)

: m_Categories[BinarySearch(randomValue)];
}
internal sealed override void ApplyToTarget(int seedOffset)
/// <summary>
/// Generates a generic sample
/// </summary>
/// <returns>The generated sample</returns>
public override object GenericSample()
if (!hasTarget)
return;
target.ApplyValueToTarget(Sample());
return Sample();
}
}
}

67
com.unity.perception/Runtime/Randomization/Parameters/Parameter.cs


using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Perception.Randomization.Samplers;

[HideInInspector, SerializeField] internal bool collapsed;
/// <summary>
/// The name of the parameter
/// </summary>
[HideInInspector] public string name = "Parameter";
/// <summary>
/// The target this parameter apply a sample to
/// </summary>
[HideInInspector, SerializeField] public ParameterTarget target = new ParameterTarget();
/// <summary>
/// Indicates whether this parameter has a target GameObject
/// </summary>
public bool hasTarget => target.gameObject != null;
// /// <summary>
// /// The name of the parameter
// /// </summary>
// [HideInInspector] public string name = "Parameter";
//
// /// <summary>
// /// The target this parameter apply a sample to
// /// </summary>
// [HideInInspector, SerializeField] public ParameterTarget target = new ParameterTarget();
//
// /// <summary>
// /// Indicates whether this parameter has a target GameObject
// /// </summary>
// public bool hasTarget => target.gameObject != null;
/// <summary>
/// The sample type generated by this parameter

/// <summary>
/// An array containing a reference to each sampler field in this parameter
/// Returns an IEnumerable that iterates over each sampler field in this parameter
public abstract ISampler[] samplers { get; }
public abstract IEnumerable<ISampler> samplers { get; }
/// <summary>
/// Constructs a new parameter

}
/// <summary>
/// Resets sampler states and then offsets those states using the current scenario iteration
/// Resets the state of each sampler employed by this parameter
/// <param name="scenarioIteration">The current scenario iteration</param>
public void ResetState(int scenarioIteration)
public void ResetState()
{
sampler.IterateState(scenarioIteration);
}
}
/// <summary>
/// Offsets the state of each sampler employed by this parameter
/// </summary>
/// <param name="offsetIndex">Often the current scenario iteration</param>
public void IterateState(int offsetIndex)
{
foreach (var sampler in samplers)
sampler.IterateState(offsetIndex);
/// Applies one sampled value to this parameters assigned target gameobject
/// Generates a generic sample
internal abstract void ApplyToTarget(int seedOffset);
/// <returns>The generated sample</returns>
public abstract object GenericSample();
internal virtual void Validate()
{
if (hasTarget)
{
if (target.component == null)
throw new ParameterValidationException($"Null component target on parameter \"{name}\"");
if (string.IsNullOrEmpty(target.propertyName))
throw new ParameterValidationException($"Invalid property target on parameter \"{name}\"");
}
}
public virtual void Validate() { }
}
}

15
com.unity.perception/Runtime/Randomization/Parameters/NumericParameter.cs


/// <returns>A NativeArray containing generated samples</returns>
public abstract NativeArray<T> Samples(int sampleCount, out JobHandle jobHandle);
internal sealed override void ApplyToTarget(int seedOffset)
/// <summary>
/// Generates a generic sample
/// </summary>
/// <returns>The generated sample</returns>
public override object GenericSample()
if (!hasTarget)
return;
target.ApplyValueToTarget(Sample());
return Sample();
internal override void Validate()
/// <summary>
/// Validate the settings of this parameter
/// </summary>
public override void Validate()
{
base.Validate();
foreach (var sampler in samplers)

22
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/BooleanParameter.cs


using System;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;

[HideInInspector, SerializeReference] public ISampler value = new UniformSampler(0f, 1f);
/// <summary>
/// Returns the sampler employed by this parameter
/// A threshold value that transforms random values within the range [0, 1] to boolean values.
/// Values greater than the threshold are true, and values less than the threshold are false.
public override ISampler[] samplers => new[] { value };
[Range(0, 1)] public float threshold = 0.5f;
static bool Sample(float t) => t >= 0.5f;
/// <summary>
/// Returns an IEnumerable that iterates over each sampler field in this parameter
/// </summary>
public override IEnumerable<ISampler> samplers
{
get { yield return value; }
}
bool Sample(float t) => t >= threshold;
/// <summary>
/// Generates a boolean sample

jobHandle = new SamplesJob
{
rngSamples = rngSamples,
samples = samples
samples = samples,
threshold = threshold
}.Schedule(jobHandle);
return samples;
}

{
[DeallocateOnJobCompletion] public NativeArray<float> rngSamples;
public NativeArray<bool> samples;
public float threshold;
samples[i] = Sample(rngSamples[i]);
samples[i] = rngSamples[i] >= threshold;
}
}
}

8
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/FloatParameter.cs


using System;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine.Perception.Randomization.Samplers;

[SerializeReference] public ISampler value = new UniformSampler(0f, 1f);
/// <summary>
/// Returns the sampler employed by this parameter
/// Returns an IEnumerable that iterates over each sampler field in this parameter
public override ISampler[] samplers => new []{ value };
public override IEnumerable<ISampler> samplers
{
get { yield return value; }
}
/// <summary>
/// Generates a float sample

8
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/IntegerParameter.cs


using System;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;

[SerializeReference] public ISampler value = new UniformSampler(0f, 1f);
/// <summary>
/// Returns the sampler employed by this parameter
/// Returns an IEnumerable that iterates over each sampler field in this parameter
public override ISampler[] samplers => new[] { value };
public override IEnumerable<ISampler> samplers
{
get { yield return value; }
}
/// <summary>
/// Generates an integer sample

12
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector2Parameter.cs


using System;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;

[SerializeReference] public ISampler y = new UniformSampler(0f, 1f);
/// <summary>
/// Returns the samplers employed by this parameter
/// Returns an IEnumerable that iterates over each sampler field in this parameter
public override ISampler[] samplers => new []{ x, y };
public override IEnumerable<ISampler> samplers
{
get
{
yield return x;
yield return y;
}
}
/// <summary>
/// Generates a Vector2 sample

13
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector3Parameter.cs


using System;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;

[SerializeReference] public ISampler z = new UniformSampler(0f, 1f);
/// <summary>
/// Returns the samplers employed by this parameter
/// Returns an IEnumerable that iterates over each sampler field in this parameter
public override ISampler[] samplers => new []{ x, y, z };
public override IEnumerable<ISampler> samplers
{
get
{
yield return x;
yield return y;
yield return z;
}
}
/// <summary>
/// Generates a Vector3 sample

14
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/Vector4Parameter.cs


using System;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;

[SerializeReference] public ISampler w = new UniformSampler(0f, 1f);
/// <summary>
/// The sampler used the samplers employed by this parameter
/// Returns an IEnumerable that iterates over each sampler field in this parameter
public override ISampler[] samplers => new []{ x, y, z, w };
public override IEnumerable<ISampler> samplers
{
get
{
yield return x;
yield return y;
yield return z;
yield return w;
}
}
/// <summary>
/// Generates a Vector4 sample

2
com.unity.perception/Runtime/Randomization/Samplers/SamplerUtility.cs


}
/// <summary>
/// Non-deterministically generates a random seed
/// Non-deterministically generates a non-zero random seed
/// </summary>
/// <returns>A non-deterministically generated random seed</returns>
public static uint GenerateRandomSeed()

16
com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/ConstantSampler.cs


public void ResetState() { }
/// <summary>
/// Resets a sampler's state to its base random seed and then offsets said seed using an index value.
/// Note that ConstantSamplers do not have random states.
/// </summary>
/// <param name="index">Often a the active scenario's currentIteration</param>
public void ResetState(int index) { }
/// <summary>
/// Set the base seed value of this sampler.
/// Note that ConstantSamplers do not have base seeds.
/// </summary>
/// <param name="seed">The seed that will replace the sampler's current seed</param>
public void Rebase(uint seed) { }
/// <summary>
/// Deterministically offsets a sampler's state when generating values within a batched job.
/// Deterministically offsets a sampler's state.
/// Note that ConstantSamplers do not have a state to iterate.
/// </summary>
/// <param name="offsetIndex">

21
com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/NormalSampler.cs


}
/// <summary>
/// Resets a sampler's state to its base random seed and then offsets said seed using an index value
/// </summary>
/// <param name="index">Often a the active scenario's currentIteration</param>
public void ResetState(int index)
{
ResetState();
IterateState(index);
}
/// <summary>
/// Set the base seed value of this sampler
/// </summary>
/// <param name="seed">The seed that will replace the sampler's current seed</param>
public void Rebase(uint seed)
{
baseSeed = seed;
}
/// <summary>
/// Deterministically offsets a sampler's state when generating values within a batched job
/// Deterministically offsets a sampler's state
/// </summary>
/// <param name="offsetIndex">
/// The index used to offset the sampler's state.

21
com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/UniformSampler.cs


}
/// <summary>
/// Resets a sampler's state to its base random seed and then offsets said seed using an index value
/// </summary>
/// <param name="index">Often a the active scenario's currentIteration</param>
public void ResetState(int index)
{
ResetState();
IterateState(index);
}
/// <summary>
/// Set the base seed value of this sampler
/// </summary>
/// <param name="seed">The seed that will replace the sampler's current seed</param>
public void Rebase(uint seed)
{
baseSeed = seed;
}
/// <summary>
/// Deterministically offsets a sampler's state when generating values within a batched job
/// Deterministically offsets a sampler's state
/// </summary>
/// <param name="offsetIndex">
/// The index used to offset the sampler's state.

12
com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs.meta


fileFormatVersion: 2
fileFormatVersion: 2
timeCreated: 1589772146
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

4
com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs


public override bool isScenarioComplete => currentIteration >= constants.totalIterations;
/// <summary>
/// Called before the scenario begins iterating
/// Fast forwards the current scenario iteration to the starting iteration indicated in this scenario's constants
public override void OnInitialize()
protected override void OnAwake()
{
currentIteration = constants.startingIteration;
}

158
com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Randomization.ParameterBehaviours;
using Unity.Simulation;
using UnityEngine.Perception.Randomization.Configuration;
using UnityEngine.Perception.Randomization.Parameters;
namespace UnityEngine.Perception.Randomization.Scenarios

/// </summary>
[DefaultExecutionOrder(-1)]
List<ParameterBehaviour> m_Behaviours = new List<ParameterBehaviour>();
List<Parameter> m_Parameters = new List<Parameter>();
bool m_WaitingForFinalUploads;
IEnumerable<ParameterBehaviour> m_ActiveBehaviours
{
get
{
foreach (var behaviour in m_Behaviours)
if (behaviour.enabled)
yield return behaviour;
}
}
[SerializeReference] public ParameterAsset[] parameterAssets;
/// <summary>
/// If true, this scenario will quit the Unity application when it's finished executing

/// <summary>
/// Returns the active parameter scenario in the scene
/// </summary>
public static ScenarioBase ActiveScenario
public static ScenarioBase activeScenario
if (s_ActiveScenario != null)
throw new ScenarioException("There cannot be more than one active ParameterConfiguration");
if (value != null && s_ActiveScenario != null && value != s_ActiveScenario)
throw new ScenarioException("There cannot be more than one active Scenario");
s_ActiveScenario = value;
}
}

public abstract bool isScenarioComplete { get; }
/// <summary>
/// Called before the scenario begins iterating
/// Serializes the scenario's constants to a JSON file located at serializedConstantsFilePath
public virtual void OnInitialize() { }
public abstract void Serialize();
/// Called at the beginning of every scenario iteration
/// Deserializes constants saved in a JSON file located at serializedConstantsFilePath
public virtual void OnIterationSetup() { }
public abstract void Deserialize();
/// Called at the start of every frame
/// This method executed directly after this scenario has been registered and initialized
public virtual void OnFrameStart() { }
protected virtual void OnAwake() { }
/// <summary>
/// Called the frame after an iteration ends
/// </summary>
public virtual void OnIterationTeardown() { }
/// <summary>
/// Called when the scenario has finished iterating
/// </summary>
public virtual void OnComplete() { }
/// <summary>
/// Serializes the scenario's constants to a JSON file located at serializedConstantsFilePath
/// </summary>
public abstract void Serialize();
/// <summary>
/// Deserializes constants saved in a JSON file located at serializedConstantsFilePath
/// </summary>
public abstract void Deserialize();
void Awake()
{
activeScenario = this;
foreach (var asset in parameterAssets)
{
foreach (var parameter in asset.parameters)
{
parameter.Validate();
m_Parameters.Add(parameter);
}
}
OnAwake();
}
ActiveScenario = this;
activeScenario = this;
}
void OnDisable()

{
if (deserializeOnStart)
Deserialize();
foreach (var config in ParameterConfiguration.configurations)
config.ValidateParameters();
OnInitialize();
}
void Update()

return;
}
// Wait for any final uploads before exiting quitting
if (m_WaitingForFinalUploads)
{
if (!Manager.FinalUploadsDone)
return;
if (quitOnComplete)
#if UNITY_EDITOR
UnityEditor.EditorApplication.ExitPlaymode();
#else
Application.Quit();
#endif
return;
}
// Iterate Scenario
if (m_FirstScenarioFrame)
{

{
currentIteration++;
currentIterationFrame = 0;
OnIterationTeardown();
foreach (var behaviour in m_ActiveBehaviours)
behaviour.OnIterationEnd();
}
}

OnComplete();
foreach (var behaviour in m_ActiveBehaviours)
behaviour.OnScenarioComplete();
Manager.Instance.Shutdown();
if (quitOnComplete)
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
m_WaitingForFinalUploads = true;
return;
}
// Perform new iteration tasks

foreach (var config in ParameterConfiguration.configurations)
config.ResetParameterStates(currentIteration);
foreach (var config in ParameterConfiguration.configurations)
config.ApplyParameters(currentIteration, ParameterApplicationFrequency.OnIterationSetup);
OnIterationSetup();
foreach (var parameter in m_Parameters)
{
parameter.ResetState();
parameter.IterateState(currentIteration);
}
foreach (var behaviour in m_ActiveBehaviours)
behaviour.OnIterationStart();
foreach (var config in ParameterConfiguration.configurations)
config.ApplyParameters(framesSinceInitialization, ParameterApplicationFrequency.EveryFrame);
OnFrameStart();
foreach (var behaviour in m_ActiveBehaviours)
behaviour.OnFrameStart();
}
public T GetParameterAsset<T>() where T : ParameterAsset
{
foreach (var asset in parameterAssets)
if (asset is T typedAsset)
return typedAsset;
throw new ScenarioException($"A ParameterAsset of type {typeof(T).Name} was not added to this scenario");
}
public T GetParameterBehaviour<T>() where T : ParameterBehaviour
{
foreach (var behaviour in m_Behaviours)
if (behaviour is T typedBehaviour)
return typedBehaviour;
throw new ScenarioException($"A ParameterBehaviour of type {typeof(T).Name} was not added to this scenario");
}
internal void AddBehaviour<T>(T newBehaviour) where T : ParameterBehaviour
{
foreach (var behaviour in m_Behaviours)
if (behaviour.GetType() == newBehaviour.GetType())
throw new ScenarioException(
$"Two ParameterBehaviours of the same type {typeof(T).Name} cannot both be active simultaneously");
m_Behaviours.Add(newBehaviour);
m_Behaviours.Sort((b1, b2) => b1.executionPriority.CompareTo(b2.executionPriority));
}
internal void RemoveBehaviour(ParameterBehaviour behaviour)
{
var removed = m_Behaviours.Remove(behaviour);
if (!removed)
throw new ScenarioException(
$"No active ParameterBehaviour of type {behaviour.GetType().Name} could be removed");
}
}
}

20
com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs


using NUnit.Framework;
using UnityEngine;
using UnityEngine.Perception.GroundTruth;
using UnityEngine.Perception.Randomization.Configuration;
using UnityEngine.Perception.Randomization.ParameterBehaviours;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.Perception.Randomization.Samplers;
using UnityEngine.Perception.Randomization.Scenarios;

[UnityTest]
public IEnumerator AppliesParametersEveryFrame()
{
var config = m_TestObject.AddComponent<ParameterConfiguration>();
var parameter = config.AddParameter<Vector3Parameter>();
var config = m_TestObject.AddComponent<ParameterList>();
var configuredParameter = config.AddParameter<Vector3Parameter>("testParam");
var parameter = (Vector3Parameter)configuredParameter.parameter;
parameter.target.AssignNewTarget(
m_TestObject, m_TestObject.transform, "position", ParameterApplicationFrequency.EveryFrame);
configuredParameter.target.AssignNewTarget(
m_TestObject.transform, "position", ParameterApplicationFrequency.EveryFrame);
var initialPosition = Vector3.zero;
yield return CreateNewScenario(1, 5);

[UnityTest]
public IEnumerator AppliesParametersEveryIteration()
{
var config = m_TestObject.AddComponent<ParameterConfiguration>();
var parameter = config.AddParameter<Vector3Parameter>();
var config = m_TestObject.AddComponent<ParameterList>();
var configuredParameter = config.AddParameter<Vector3Parameter>("testParam");
var parameter = (Vector3Parameter)configuredParameter.parameter;
parameter.x = new UniformSampler(1, 2);
parameter.y = new UniformSampler(1, 2);
parameter.z = new UniformSampler(1, 2);

transform.position = prevPosition;
parameter.target.AssignNewTarget(
m_TestObject, transform, "position", ParameterApplicationFrequency.OnIterationSetup);
configuredParameter.target.AssignNewTarget(
transform, "position", ParameterApplicationFrequency.EveryIteration);
yield return CreateNewScenario(2, 2);

30
com.unity.perception/Tests/Runtime/Randomization/ParameterConfigurationTests.cs


using System.Collections;
using NUnit.Framework;
using NUnit.Framework;
using UnityEngine.Perception.Randomization.Configuration;
using UnityEngine.Perception.Randomization.ParameterBehaviours;
using UnityEngine.TestTools;
namespace RandomizationTests
{

Object.DestroyImmediate(m_TestObject);
}
[Test]
public void CheckForParametersWithSameNameTest()
{
var config = m_TestObject.AddComponent<ParameterConfiguration>();
var param1 = config.AddParameter<FloatParameter>();
var param2 = config.AddParameter<BooleanParameter>();
param1.name = "SameName";
param2.name = "SameName";
Assert.Throws<ParameterConfigurationException>(() => config.ValidateParameters());
}
// [Test]
// public void CheckForParametersWithSameNameTest()
// {
// var config = m_TestObject.AddComponent<ParameterList>();
// config.AddParameter<FloatParameter>("SameName");
// config.AddParameter<BooleanParameter>("SameName");
// Assert.Throws<ParameterListException>(() => config.Validate());
// }
var config = m_TestObject.AddComponent<ParameterConfiguration>();
Assert.DoesNotThrow(() => config.AddParameter(typeof(FloatParameter)));
Assert.Throws<ParameterConfigurationException>(() => config.AddParameter(typeof(Rigidbody)));
var config = m_TestObject.AddComponent<ParameterList>();
Assert.DoesNotThrow(() => config.AddParameter("TestParam1", typeof(FloatParameter)));
Assert.Throws<ParameterListException>(() => config.AddParameter("TestParam2", typeof(Rigidbody)));
}
}
}

83
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaParameter.cs


using System;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;

{
/// <summary>
/// A numeric parameter for generating Color samples
/// A numeric parameter for generating color samples using HSVA samplers
/// </summary>
[Serializable]
public class ColorHsvaParameter : NumericParameter<Color>

[SerializeReference] public ISampler alpha = new ConstantSampler(1f);
/// <summary>
/// Returns the samplers employed by this parameter
/// Returns an IEnumerable that iterates over each sampler field in this parameter
public override ISampler[] samplers => new []{ hue, saturation, value, alpha };
public override IEnumerable<ISampler> samplers
{
get
{
yield return hue;
yield return saturation;
yield return value;
yield return alpha;
}
}
/// Generates a color sample
/// Generates an RGBA color sample
/// <returns>The generated sample</returns>
/// <returns>The generated RGBA sample</returns>
public override Color Sample()
{
var color = Color.HSVToRGB(hue.Sample(), saturation.Sample(), value.Sample());

/// <summary>
/// Schedules a job to generate an array of samples
/// Generates an HSVA color sample
/// </summary>
/// <returns>The generated HSVA sample</returns>
public ColorHsva SampleHsva()
{
return new ColorHsva(hue.Sample(), saturation.Sample(), value.Sample(), alpha.Sample());
}
/// <summary>
/// Schedules a job to generate an array of RGBA color samples
/// </summary>
/// <param name="sampleCount">The number of samples to generate</param>
/// <param name="jobHandle">The handle of the scheduled job</param>

{
for (var i = 0; i < samples.Length; i++)
samples[i] = CreateColorHsva(hueRng[i], satRng[i], valRng[i], alphaRng[i]);
}
}
/// <summary>
/// Schedules a job to generate an array of HSVA color samples
/// </summary>
/// <param name="sampleCount">The number of samples to generate</param>
/// <param name="jobHandle">The handle of the scheduled job</param>
/// <returns>A NativeArray of samples</returns>
public NativeArray<ColorHsva> SamplesHsva(int sampleCount, out JobHandle jobHandle)
{
var samples = new NativeArray<ColorHsva>(sampleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
var hueRng = hue.Samples(sampleCount, out var hueHandle);
var satRng = saturation.Samples(sampleCount, out var satHandle);
var valRng = value.Samples(sampleCount, out var valHandle);
var alphaRng = alpha.Samples(sampleCount, out var alphaHandle);
var handles = new NativeArray<JobHandle>(4, Allocator.TempJob)
{
[0] = hueHandle,
[1] = satHandle,
[2] = valHandle,
[3] = alphaHandle
};
var combinedJobHandles = JobHandle.CombineDependencies(handles);
jobHandle = new SamplesHsvaJob
{
hueRng = hueRng,
satRng = satRng,
valRng = valRng,
alphaRng = alphaRng,
samples = samples
}.Schedule(combinedJobHandles);
handles.Dispose(jobHandle);
return samples;
}
[BurstCompile]
struct SamplesHsvaJob : IJob
{
[DeallocateOnJobCompletion] public NativeArray<float> hueRng;
[DeallocateOnJobCompletion] public NativeArray<float> satRng;
[DeallocateOnJobCompletion] public NativeArray<float> valRng;
[DeallocateOnJobCompletion] public NativeArray<float> alphaRng;
public NativeArray<ColorHsva> samples;
public void Execute()
{
for (var i = 0; i < samples.Length; i++)
samples[i] = new ColorHsva(hueRng[i], satRng[i], valRng[i], alphaRng[i]);
}
}
}

24
com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterTarget.cs


using System;
using UnityEngine.Perception.Randomization.Parameters;
namespace UnityEngine.Perception.Randomization.Parameters
namespace UnityEngine.Perception.Randomization.ParameterBehaviours
{
/// <summary>
/// Used to apply sampled parameter values to a particular GameObject, Component, and property.

public class ParameterTarget
{
[SerializeField] internal GameObject gameObject;
[SerializeField] internal ParameterApplicationFrequency applicationFrequency = ParameterApplicationFrequency.OnIterationSetup;
[SerializeField] internal ParameterApplicationFrequency applicationFrequency = ParameterApplicationFrequency.EveryIteration;
/// <param name="targetObject">The target GameObject</param>
GameObject targetObject,
gameObject = targetObject;
component = targetComponent;
propertyName = fieldOrPropertyName;
applicationFrequency = frequency;

internal void Clear()
{
gameObject = null;
component = null;
propertyName = string.Empty;
}

property.SetValue(component, value);
}
}
internal void Validate()
{
if (component == null)
throw new ParameterValidationException("Null target component");
if (string.IsNullOrEmpty(propertyName))
throw new ParameterValidationException("Invalid target property");
}
}
/// <summary>

{
/// <summary>
/// Applies a parameter once every iteration
/// Applies a parameter at the beginning of every iteration
OnIterationSetup,
EveryIteration,
/// Applies a parameter once every frame
/// Applies a parameter at the beginning of every frame
/// </summary>
EveryFrame
}

3
com.unity.perception/Editor/Randomization/Editors.meta


fileFormatVersion: 2
guid: 0b17046409af4c22bf74eec2a5965984
timeCreated: 1598135707

3
com.unity.perception/Editor/Randomization/PropertyDrawers.meta


fileFormatVersion: 2
guid: d3107e026b2943c1868c9b3f8c6480d3
timeCreated: 1598135730

3
com.unity.perception/Editor/Randomization/VisualElements.meta


fileFormatVersion: 2
guid: 7f8f95a1bb144a96b9310164f5560387
timeCreated: 1598135666

3
com.unity.perception/Editor/Randomization/Uss/ParameterStyles.uss.meta


fileFormatVersion: 2
guid: def81fa16f8b41aca393a30c3b1fac72
timeCreated: 1598222679

17
com.unity.perception/Editor/Randomization/Uss/SamplerStyles.uss


.sampler-type-menu {
flex-grow: 1.5;
border-radius: 3px;
border-width: 1px;
margin-top: 2px;
margin-right: 3px;
}
.sampler-name {
/*color: lightgreen;*/
-unity-font-style: bold;
}
.float-range .unity-base-field__label {
min-width: auto;
margin-right: 4px;
}

3
com.unity.perception/Editor/Randomization/Uss/SamplerStyles.uss.meta


fileFormatVersion: 2
guid: 85ff041b142f41798a7703bda9bb1ba7
timeCreated: 1598222791

46
com.unity.perception/Editor/Randomization/Uss/ParameterAssetStyles.uss


.dark-viewport {
border-radius: 5px;
background-color: #191919;
padding: 2px;
}
.unity-toggle {
margin-left: 0;
}
.remove-parameter-button {
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/X.png");
width: 16px;
height: 16px;
}
.move-buttons-container {
width: auto;
margin-right: 6px;
border-color: black;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
background-color: #2A2A2A;
padding: 3px 2px;
justify-content: center;
}
.drag-handle {
width: 16px;
height: 70%;
min-height: 20px;
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/DragHandle.png");
}
.unity-imgui-container {
margin-left: 1px;
margin-right: 3px;
}
.search-icon {
width: 16px;
height: 16px;
margin-top: 2px;
flex-shrink: 0;
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/Search.png");
}

110
com.unity.perception/Editor/Randomization/Uss/ParameterStyles.uss


.parameter-container {
border-width: 2px;
border-radius: 5px;
flex-direction: row;
margin: 2px 1px;
}
.parameter-type-label-container {
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 1px;
}
.parameter-type-label-box {
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-grow: 0;
-unity-text-align: middle-center;
border-width: 0;
padding: 1px;
font-size: 13px;
-unity-font-style: bold;
}
.parameter-type-label {
color: cornflowerblue;
-unity-text-align: middle-left;
margin-right: 4px;
}
.parameter-type-label-box .unity-base-text-field__input {
padding-left: 6px;
padding-right: 6px;
}
.collapse-parameter-toggle {
flex-shrink: 0;
margin-right: 3px;
margin-left: 3px;
width: 12px;
height: 12px;
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/FoldoutOpen.png");
}
.collapsed-parameter .collapse-parameter-toggle {
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/FoldoutClosed.png");
}
.collapsed-parameter .parameter-properties-container {
display: none;
}
.collapsed-parameter .move-buttons-container {
flex-direction: row;
}
.collapsed-parameter .move-button {
width: 16px;
}
.categorical-option {
flex-direction: row;
background-color: #3F3F3F;
margin: 1px;
border-radius: 4px;
}
.options-list-view {
background-color: #191919;
border-radius: 4px;
margin-right: 2px;
padding: 3px;
border-bottom-right-radius: 0;
}
.option-property-field {
width: 0;
flex-grow: 1;
flex-shrink: 0;
}
.uniform-probability .hide-when-uniform {
display: none;
}
.add-option-button {
align-self: flex-end;
border-width: 0;
border-top-right-radius: 0;
border-top-left-radius: 0;
background-color: #191919;
margin-top: 0;
margin-right: 2px;
}
.add-option-button:hover {
background-color: #2A2A2A;
}
.add-option-button:active {
color: cornflowerblue;
}
.remove-option-button {
width: 12px;
height: 14px;
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/X.png");
}

10
com.unity.perception/Editor/Randomization/Uxml/ParameterDrawer.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement>
<Style src="../Uss/ParameterStyles.uss"/>
<VisualElement style="flex-direction: row; align-items: center;">
<VisualElement name="collapse" class="collapse-parameter-toggle foldout-open"/>
<Label name="field-name" style="-unity-font-style: bold; font-size: 12px;"/>
</VisualElement>
<VisualElement name="drawer" class="parameter-properties-container" style="padding-left: 18px;"/>
</VisualElement>
</UXML>

3
com.unity.perception/Editor/Randomization/Uxml/ParameterDrawer.uxml.meta


fileFormatVersion: 2
guid: 6a4bb3efae29429292ccdfa63e661872
timeCreated: 1598240583

3
com.unity.perception/Editor/Randomization/Uxml/ParameterListItemElement.uxml.meta


fileFormatVersion: 2
guid: bb5d8b14dfb1488388860c0437274b7c
timeCreated: 1598232124

21
com.unity.perception/Editor/Randomization/Uxml/ParameterAssetEditor.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement style="height: 100%;">
<Style src="../Uss/ParameterAssetStyles.uss"/>
<VisualElement style="flex-direction: row; align-items: center; margin-bottom: 2px; margin-top: 2px;">
<VisualElement class="search-icon" style="margin-left: 3px; margin-right: 2px;"/>
<TextField name="filter-parameters" style="flex-grow: 1; flex-shrink: 1;"/>
</VisualElement>
<VisualElement class="dark-viewport" style="min-height: 100px;">
<VisualElement name="parameters-container" style="flex-shrink: 0;"/>
</VisualElement>
<VisualElement style="flex-direction: row; justify-content: center;">
<VisualElement style="flex-grow: 1"/>
<Button name="collapse-all" text="Collapse All" style="font-size: 13px; padding: 4px;"/>
<Button name="expand-all" text="Expand All" style="font-size: 13px; padding: 4px;"/>
<VisualElement style="flex-grow: 1"/>
</VisualElement>
</VisualElement>
</UXML>

20
com.unity.perception/Editor/Randomization/Uxml/ParameterListItemElement.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<Box name="parameter-container" class="parameter-container">
<Style src="../Uss/ParameterStyles.uss"/>
<VisualElement name="drag-handle" class="move-buttons-container">
<VisualElement class="drag-handle"/>
</VisualElement>
<VisualElement style="flex-grow: 1; justify-content: center;">
<VisualElement class="parameter-type-label-container">
<Box class="parameter-type-label-box">
<VisualElement name="collapse" class="collapse-parameter-toggle foldout-open"/>
<Label name="parameter-type-label" text="Type:" class="parameter-type-label"/>
<TextElement name="name" text="Field Name"/>
</Box>
</VisualElement>
<VisualElement name="properties" class="parameter-properties-container">
</VisualElement>
</VisualElement>
</Box>
</UXML>

3
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters.meta


fileFormatVersion: 2
guid: ce91e289cdaa4ccc849a0c287aefd34d
timeCreated: 1598326361

3
com.unity.perception/Runtime/Randomization/ParameterBehaviours.meta


fileFormatVersion: 2
guid: 2dd2a5a912ed49ab8356572e5ca6d950
timeCreated: 1598132657

3
com.unity.perception/Editor/Randomization/PropertyDrawers/ColorHsvaDrawer.cs.meta


fileFormatVersion: 2
guid: 5e8094c28dd142a09fbbd38ca560164b
timeCreated: 1598250942

3
com.unity.perception/Editor/Randomization/PropertyDrawers/ParameterDrawer.cs.meta


fileFormatVersion: 2
guid: d389620d3aa3471ca1877eb59cdfb465
timeCreated: 1598135745

25
com.unity.perception/Editor/Randomization/PropertyDrawers/ColorHsvaDrawer.cs


using UnityEditor;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor.PropertyDrawers
{
[CustomPropertyDrawer(typeof(ColorHsva), true)]
class ColorHsvaDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
return new ColorHsvaField(property);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.PropertyField(position, property, label, true);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property);
}
}
}

26
com.unity.perception/Editor/Randomization/PropertyDrawers/ParameterDrawer.cs


using System;
using UnityEditor;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor.PropertyDrawers
{
[CustomPropertyDrawer(typeof(Parameter), true)]
class ParameterDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
return new DrawerParameterElement(property);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.PropertyField(position, property, label, true);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property);
}
}
}

73
com.unity.perception/Editor/Randomization/Editors/ParametersAssetEditor.cs


using System;
using Randomization.ParameterBehaviours;
using UnityEditor;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
[CustomEditor(typeof(ParameterAsset), true)]
public class ParametersAssetEditor : UnityEditor.Editor
{
VisualElement m_Root;
VisualElement m_ParameterContainer;
SerializedProperty m_Parameters;
string m_FilterString = string.Empty;
string FilterString
{
set
{
m_FilterString = value;
var lowerFilter = m_FilterString.ToLower();
foreach (var child in m_ParameterContainer.Children())
{
var param = (ParameterListItemElement)child;
param.filtered = param.displayName.ToLower().Contains(lowerFilter);
}
}
}
public override VisualElement CreateInspectorGUI()
{
m_Root = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ParameterAssetEditor.uxml").CloneTree();
m_ParameterContainer = m_Root.Q<VisualElement>("parameters-container");
var filter = m_Root.Q<TextField>("filter-parameters");
filter.RegisterValueChangedCallback((e) => { FilterString = e.newValue; });
var collapseAllButton = m_Root.Q<Button>("collapse-all");
collapseAllButton.clicked += () => CollapseParameters(true);
var expandAllButton = m_Root.Q<Button>("expand-all");
expandAllButton.clicked += () => CollapseParameters(false);
RefreshParameterElements();
return m_Root;
}
void RefreshParameterElements()
{
m_ParameterContainer.Clear();
var properties = serializedObject.GetIterator();
if (properties.NextVisible(true))
{
do
{
var propertyValue = StaticData.GetManagedReferenceValue(properties);
if (propertyValue != null && propertyValue.GetType().IsSubclassOf(typeof(Parameter)))
m_ParameterContainer.Add(new ParameterListItemElement(properties.Copy()));
} while (properties.NextVisible(false));
}
}
void CollapseParameters(bool collapsed)
{
foreach (var child in m_ParameterContainer.Children())
((ParameterListItemElement)child).collapsed = collapsed;
}
}
}

3
com.unity.perception/Editor/Randomization/Editors/ParametersAssetEditor.cs.meta


fileFormatVersion: 2
guid: 012ed5df9c884c2dbf47886b520af29a
timeCreated: 1598378710

39
com.unity.perception/Editor/Randomization/VisualElements/ColorHsvaField.cs


using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class ColorHsvaField : ColorField
{
SerializedProperty m_Property;
SerializedProperty m_H;
SerializedProperty m_S;
SerializedProperty m_V;
SerializedProperty m_A;
public ColorHsvaField(SerializedProperty property)
{
m_Property = property;
label = m_Property.displayName;
m_H = m_Property.FindPropertyRelative("h");
m_S = m_Property.FindPropertyRelative("s");
m_V = m_Property.FindPropertyRelative("v");
m_A = m_Property.FindPropertyRelative("a");
rawValue = (Color)new ColorHsva(m_H.floatValue, m_S.floatValue, m_V.floatValue, m_A.floatValue);
this.RegisterValueChangedCallback(evt =>
{
var color = (ColorHsva)evt.newValue;
m_H.floatValue = color.h;
m_S.floatValue = color.s;
m_V.floatValue = color.v;
m_A.floatValue = color.a;
m_Property.serializedObject.ApplyModifiedProperties();
});
}
}
}

3
com.unity.perception/Editor/Randomization/VisualElements/ColorHsvaField.cs.meta


fileFormatVersion: 2
guid: 103b163a2467415ab86b0df8175b12a6
timeCreated: 1598254290

47
com.unity.perception/Editor/Randomization/VisualElements/DrawerParameterElement.cs


using UnityEditor;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class DrawerParameterElement : VisualElement
{
Parameter m_Parameter;
SerializedProperty m_Collapsed;
SerializedProperty m_Property;
const string k_CollapsedParameterClass = "collapsed-parameter";
bool collapsed
{
get => m_Collapsed.boolValue;
set
{
m_Collapsed.boolValue = value;
m_Property.serializedObject.ApplyModifiedPropertiesWithoutUndo();
if (value)
AddToClassList(k_CollapsedParameterClass);
else
RemoveFromClassList(k_CollapsedParameterClass);
}
}
public DrawerParameterElement(SerializedProperty property)
{
m_Property = property;
m_Collapsed = property.FindPropertyRelative("collapsed");
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ParameterDrawer.uxml").CloneTree(this);
var collapseToggle = this.Q<VisualElement>("collapse");
collapseToggle.RegisterCallback<MouseUpEvent>(evt => collapsed = !collapsed);
collapsed = m_Collapsed.boolValue;
var fieldNameField = this.Q<Label>("field-name");
fieldNameField.text = property.displayName;
var drawer = this.Q<VisualElement>("drawer");
drawer.Add(new ParameterElement(property));
}
}
}

3
com.unity.perception/Editor/Randomization/VisualElements/DrawerParameterElement.cs.meta


fileFormatVersion: 2
guid: e2eb905ca8c14b5cbe43e48418948be0
timeCreated: 1598255728

193
com.unity.perception/Editor/Randomization/VisualElements/ParameterElement.cs


using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class ParameterElement : VisualElement
{
VisualElement m_PropertiesContainer;
SerializedProperty m_SerializedProperty;
Parameter parameter => (Parameter)StaticData.GetManagedReferenceValue(m_SerializedProperty);
CategoricalParameterBase categoricalParameter => (CategoricalParameterBase)parameter;
public ParameterElement(SerializedProperty property)
{
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ParameterElement.uxml");
template.CloneTree(this);
m_SerializedProperty = property;
m_PropertiesContainer = this.Q<VisualElement>("properties");
CreatePropertyFields();
}
void CreatePropertyFields()
{
m_PropertiesContainer.Clear();
if (parameter is CategoricalParameterBase)
{
CreateCategoricalParameterFields();
return;
}
var currentProperty = m_SerializedProperty.Copy();
var nextSiblingProperty = m_SerializedProperty.Copy();
nextSiblingProperty.NextVisible(false);
currentProperty.NextVisible(true);
do
{
if (SerializedProperty.EqualContents(currentProperty, nextSiblingProperty))
break;
if (currentProperty.type.Contains("managedReference") &&
currentProperty.managedReferenceFieldTypename == StaticData.samplerSerializedFieldType)
m_PropertiesContainer.Add(new SamplerElement(currentProperty.Copy(), parameter));
else
{
var propertyField = new PropertyField(currentProperty.Copy());
propertyField.Bind(currentProperty.serializedObject);
m_PropertiesContainer.Add(propertyField);
}
} while (currentProperty.NextVisible(false));
}
void CreateCategoricalParameterFields()
{
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/CategoricalParameterTemplate.uxml").CloneTree();
var optionsProperty = m_SerializedProperty.FindPropertyRelative("m_Categories");
var probabilitiesProperty = m_SerializedProperty.FindPropertyRelative("probabilities");
var probabilities = categoricalParameter.probabilities;
var listView = template.Q<ListView>("options");
listView.itemsSource = probabilities;
listView.itemHeight = 22;
listView.selectionType = SelectionType.None;
listView.style.flexGrow = 1.0f;
listView.style.height = new StyleLength(listView.itemHeight * 4);
VisualElement MakeItem() => new CategoricalOptionElement(
optionsProperty, probabilitiesProperty);
listView.makeItem = MakeItem;
void BindItem(VisualElement e, int i)
{
var optionElement = (CategoricalOptionElement)e;
optionElement.BindProperties(i);
var removeButton = optionElement.Q<Button>("remove");
removeButton.clicked += () =>
{
probabilitiesProperty.DeleteArrayElementAtIndex(i);
// First delete sets option to null, second delete removes option
var numOptions = optionsProperty.arraySize;
optionsProperty.DeleteArrayElementAtIndex(i);
if (numOptions == optionsProperty.arraySize)
optionsProperty.DeleteArrayElementAtIndex(i);
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
listView.itemsSource = categoricalParameter.probabilities;
listView.Refresh();
};
}
listView.bindItem = BindItem;
var addOptionButton = template.Q<Button>("add-option");
addOptionButton.clicked += () =>
{
probabilitiesProperty.arraySize++;
optionsProperty.arraySize++;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
listView.itemsSource = categoricalParameter.probabilities;
listView.Refresh();
listView.ScrollToItem(probabilitiesProperty.arraySize);
};
var addFolderButton = template.Q<Button>("add-folder");
if (categoricalParameter.sampleType.IsSubclassOf(typeof(Object)))
{
addFolderButton.clicked += () =>
{
var folderPath = EditorUtility.OpenFolderPanel(
"Add Options From Folder", Application.dataPath, string.Empty);
if (folderPath == string.Empty)
return;
var categories = LoadAssetsFromFolder(folderPath, categoricalParameter.sampleType);
probabilitiesProperty.arraySize += categories.Count;
optionsProperty.arraySize += categories.Count;
var uniformProbability = 1f / categories.Count;
for (var i = 0; i < categories.Count; i++)
{
var optionProperty = optionsProperty.GetArrayElementAtIndex(i);
var probabilityProperty = probabilitiesProperty.GetArrayElementAtIndex(i);
optionProperty.objectReferenceValue = categories[i];
probabilityProperty.floatValue = uniformProbability;
}
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
listView.itemsSource = categoricalParameter.probabilities;
listView.Refresh();
};
}
else
addFolderButton.style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
var clearOptionsButton = template.Q<Button>("clear-options");
clearOptionsButton.clicked += () =>
{
probabilitiesProperty.arraySize = 0;
optionsProperty.arraySize = 0;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
listView.itemsSource = categoricalParameter.probabilities;
listView.Refresh();
};
var scrollView = listView.Q<ScrollView>();
listView.RegisterCallback<WheelEvent>(evt =>
{
if (Mathf.Approximately(scrollView.verticalScroller.highValue, 0f))
return;
if ((scrollView.scrollOffset.y <= 0f && evt.delta.y < 0f) ||
scrollView.scrollOffset.y >= scrollView.verticalScroller.highValue && evt.delta.y > 0f)
evt.StopImmediatePropagation();
});
var uniformToggle = template.Q<Toggle>("uniform");
var uniformProperty = m_SerializedProperty.FindPropertyRelative("uniform");
uniformToggle.BindProperty(uniformProperty);
void ToggleProbabilityFields(bool toggle)
{
if (toggle)
listView.AddToClassList("uniform-probability");
else
listView.RemoveFromClassList("uniform-probability");
}
ToggleProbabilityFields(uniformToggle.value);
if (Application.isPlaying)
uniformToggle.SetEnabled(false);
else
uniformToggle.RegisterCallback<ChangeEvent<bool>>(evt => ToggleProbabilityFields(evt.newValue));
var seedField = template.Q<IntegerField>("seed");
seedField.BindProperty(m_SerializedProperty.FindPropertyRelative("m_Sampler.<baseSeed>k__BackingField"));
m_PropertiesContainer.Add(template);
}
static List<Object> LoadAssetsFromFolder(string folderPath, Type assetType)
{
if (!folderPath.StartsWith(Application.dataPath))
throw new ApplicationException("Selected folder is not an asset folder in this project");
var assetsPath = "Assets" + folderPath.Remove(0, Application.dataPath.Length);
var assetIds = AssetDatabase.FindAssets($"t:{assetType.Name}", new []{assetsPath});
var assets = new List<Object>();
foreach (var guid in assetIds)
assets.Add(AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid), assetType));
return assets;
}
}
}

3
com.unity.perception/Editor/Randomization/VisualElements/ParameterListItemElement.cs.meta


fileFormatVersion: 2
guid: a26a70e27aed4ced88ef9ac7e17c2793
timeCreated: 1598228666

67
com.unity.perception/Editor/Randomization/VisualElements/ParameterListItemElement.cs


using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.ParameterBehaviours;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class ParameterListItemElement : VisualElement
{
VisualElement m_Properties;
VisualElement m_TargetContainer;
ToolbarMenu m_TargetPropertyMenu;
SerializedProperty m_SerializedProperty;
SerializedProperty m_Collapsed;
const string k_CollapsedParameterClass = "collapsed-parameter";
public bool collapsed
{
get => m_Collapsed.boolValue;
set
{
m_Collapsed.boolValue = value;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
if (value)
AddToClassList(k_CollapsedParameterClass);
else
RemoveFromClassList(k_CollapsedParameterClass);
}
}
public string displayName => m_SerializedProperty.displayName;
public bool filtered
{
set => style.display = value
? new StyleEnum<DisplayStyle>(DisplayStyle.Flex)
: new StyleEnum<DisplayStyle>(DisplayStyle.None);
}
public ParameterListItemElement(SerializedProperty property)
{
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ParameterListItemElement.uxml");
template.CloneTree(this);
m_SerializedProperty = property;
var parameter = (Parameter)StaticData.GetManagedReferenceValue(property);
m_Collapsed = property.FindPropertyRelative("collapsed");
var parameterTypeLabel = this.Query<Label>("parameter-type-label").First();
parameterTypeLabel.text = Parameter.GetDisplayName(parameter.GetType());
var parameterNameField = this.Q<TextElement>("name");
parameterNameField.text = property.displayName;
var collapseToggle = this.Q<VisualElement>("collapse");
collapseToggle.RegisterCallback<MouseUpEvent>(evt => collapsed = !collapsed);
var parameterProperties = this.Q<VisualElement>("properties");
parameterProperties.Add(new ParameterElement(property));
}
}
}

107
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsva.cs


using System;
using Unity.Mathematics;
namespace UnityEngine.Perception.Randomization.Parameters
{
/// <summary>
/// A struct representing the hue, saturation, value, and alpha components of a particular color
/// </summary>
[Serializable]
public struct ColorHsva
{
/// <summary>
/// A float value representing the hue component of a color
/// </summary>
public float h;
/// <summary>
/// A float value representing the saturation component of a color
/// </summary>
public float s;
/// <summary>
/// A float value representing the value component of a color
/// </summary>
public float v;
/// <summary>
/// A float value representing the alpha component of a color
/// </summary>
public float a;
/// <summary>
/// Constructs an ColorHsva struct
/// </summary>
/// <param name="h">Hue</param>
/// <param name="s">Saturation</param>
/// <param name="v">Value</param>
/// <param name="a">Alpha</param>
public ColorHsva(float h, float s, float v, float a)
{
this.h = h;
this.s = s;
this.v = v;
this.a = a;
}
/// <summary>
/// Implicitly converts an HSVA Color to a float4
/// </summary>
/// <param name="c">The HSVA color to convert to a float4</param>
/// <returns>A new float4</returns>
public static implicit operator float4(ColorHsva c) => new float4(c.h, c.s, c.v, c.a);
/// <summary>
/// Implicitly converts an float4 to an HSVA color
/// </summary>
/// <param name="f">The float4 to convert to an HSVA color</param>
/// <returns>A new HSVA color</returns>
public static implicit operator ColorHsva(float4 f) => new ColorHsva(f.x, f.y, f.z, f.w);
/// <summary>
/// Implicitly converts an HSVA Color to a Vector4
/// </summary>
/// <param name="c">The HSVA color to convert to a Vector4</param>
/// <returns>A new Vector4</returns>
public static implicit operator Vector4(ColorHsva c) => new float4(c.h, c.s, c.v, c.a);
/// <summary>
/// Implicitly converts an Vector4 to an HSVA color
/// </summary>
/// <param name="v">The Vector4 color to convert to an HSVA color</param>
/// <returns>A new HSVA color</returns>
public static implicit operator ColorHsva(Vector4 v) => new ColorHsva(v.x, v.y, v.z, v.w);
/// <summary>
/// Converts an HSVA Color to an RGBA Color
/// </summary>
/// <param name="c">The HSVA color to convert to RGBA</param>
/// <returns>A new RGBA color</returns>
public static explicit operator Color(ColorHsva c)
{
var color = Color.HSVToRGB(c.h, c.s, c.v);
color.a = c.a;
return color;
}
/// <summary>
/// Converts an RGBA Color to an HSVA Color
/// </summary>
/// <param name="c">The RGBA color to convert to HSVA</param>
/// <returns>A new HSVA color</returns>
public static explicit operator ColorHsva(Color c)
{
Color.RGBToHSV(c, out var h, out var s, out var v);
return new ColorHsva(h, s, v, c.a);
}
/// <summary>
/// Generates a string representation of a ColorHsva
/// </summary>
/// <returns>A string representing the components of this ColorHsva</returns>
public override string ToString()
{
return $"ColorHsva({h}, {s}, {v}, {a})";
}
}
}

3
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsva.cs.meta


fileFormatVersion: 2
guid: ccdce8798ec146649d4714046529de2c
timeCreated: 1598326388

10
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaCategoricalParameter.cs


using System;
namespace UnityEngine.Perception.Randomization.Parameters
{
/// <summary>
/// A categorical parameter for generating ColorHsva samples
/// </summary>
[Serializable]
public class ColorHsvaCategoricalParameter : CategoricalParameter<ColorHsva> { }
}

10
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbCategoricalParameter.cs


using System;
namespace UnityEngine.Perception.Randomization.Parameters
{
/// <summary>
/// A categorical parameter for generating RGBA color samples
/// </summary>
[Serializable]
public class ColorRgbCategoricalParameter : CategoricalParameter<Color> { }
}

3
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorHsvaCategoricalParameter.cs.meta


fileFormatVersion: 2
guid: e7985c4ea0bf49578e9cabd2c1a63cb6
timeCreated: 1598217458

3
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbCategoricalParameter.cs.meta


fileFormatVersion: 2
guid: f4bd575c48a145ec9b63eb48ce636ed7
timeCreated: 1598251957

3
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbParameter.cs.meta


fileFormatVersion: 2
guid: a4fdf61227254683a9950f586d6e8f57
timeCreated: 1598252064

111
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorParameters/ColorRgbParameter.cs


using System;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine.Perception.Randomization.Samplers;
namespace UnityEngine.Perception.Randomization.Parameters
{
/// <summary>
/// A numeric parameter for generating RGBA color samples
/// </summary>
[Serializable]
public class ColorRgbParameter : NumericParameter<Color>
{
/// <summary>
/// The sampler used for randomizing the red component of generated samples
/// </summary>
[SerializeReference] public ISampler red = new UniformSampler(0f, 1f);
/// <summary>
/// The sampler used for randomizing the green component of generated samples
/// </summary>
[SerializeReference] public ISampler green = new UniformSampler(0f, 1f);
/// <summary>
/// The sampler used for randomizing the blue component of generated samples
/// </summary>
[SerializeReference] public ISampler blue = new UniformSampler(0f, 1f);
/// <summary>
/// The sampler used for randomizing the alpha component of generated samples
/// </summary>
[SerializeReference] public ISampler alpha = new ConstantSampler(1f);
/// <summary>
/// Returns an IEnumerable that iterates over each sampler field in this parameter
/// </summary>
public override IEnumerable<ISampler> samplers
{
get
{
yield return red;
yield return green;
yield return blue;
yield return alpha;
}
}
/// <summary>
/// Generates an RGBA color sample
/// </summary>
/// <returns>The generated RGBA sample</returns>
public override Color Sample()
{
return new Color(red.Sample(), green.Sample(), blue.Sample(), alpha.Sample());
}
/// <summary>
/// Schedules a job to generate an array of samples
/// </summary>
/// <param name="sampleCount">The number of samples to generate</param>
/// <param name="jobHandle">The handle of the scheduled job</param>
/// <returns>A NativeArray of samples</returns>
public override NativeArray<Color> Samples(int sampleCount, out JobHandle jobHandle)
{
var samples = new NativeArray<Color>(sampleCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
var redRng = red.Samples(sampleCount, out var redHandle);
var greenRng = green.Samples(sampleCount, out var greenHandle);
var blueRng = blue.Samples(sampleCount, out var blueHandle);
var alphaRng = alpha.Samples(sampleCount, out var alphaHandle);
var handles = new NativeArray<JobHandle>(4, Allocator.TempJob)
{
[0] = redHandle,
[1] = greenHandle,
[2] = blueHandle,
[3] = alphaHandle
};
var combinedJobHandles = JobHandle.CombineDependencies(handles);
jobHandle = new SamplesJob
{
redRng = redRng,
greenRng = greenRng,
blueRng = blueRng,
alphaRng = alphaRng,
samples = samples
}.Schedule(combinedJobHandles);
handles.Dispose(jobHandle);
return samples;
}
[BurstCompile]
struct SamplesJob : IJob
{
[DeallocateOnJobCompletion] public NativeArray<float> redRng;
[DeallocateOnJobCompletion] public NativeArray<float> greenRng;
[DeallocateOnJobCompletion] public NativeArray<float> blueRng;
[DeallocateOnJobCompletion] public NativeArray<float> alphaRng;
public NativeArray<Color> samples;
public void Execute()
{
for (var i = 0; i < samples.Length; i++)
samples[i] = new Color(redRng[i], greenRng[i], blueRng[i], alphaRng[i]);
}
}
}
}

3
com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterBehaviour.cs.meta


fileFormatVersion: 2
guid: bb8689894f7f41d180c308dbe85f3ced
timeCreated: 1598132668

3
com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration.meta


fileFormatVersion: 2
guid: e71c37bf9c4144728de471f853a09a19
timeCreated: 1598290624

3
com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterAsset.cs.meta


fileFormatVersion: 2
guid: 396df67bc35a43dbabb608af04012599
timeCreated: 1598378733

11
com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterListException.cs


using System;
namespace UnityEngine.Perception.Randomization.ParameterBehaviours
{
[Serializable]
class ParameterListException : Exception
{
public ParameterListException(string message) : base(message) { }
public ParameterListException(string message, Exception innerException) : base(message, innerException) { }
}
}

28
com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterListItem.cs


using System;
using UnityEngine.Perception.Randomization.Parameters;
namespace UnityEngine.Perception.Randomization.ParameterBehaviours
{
[Serializable]
class ParameterListItem
{
public string name = "Parameter";
[SerializeReference] public Parameter parameter;
[HideInInspector, SerializeField] public ParameterTarget target = new ParameterTarget();
public bool hasTarget => target.component != null;
public void ApplyToTarget()
{
if (!hasTarget)
return;
target.ApplyValueToTarget(parameter.GenericSample());
}
public void Validate()
{
target.Validate();
parameter.Validate();
}
}
}

3
com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterListItem.cs.meta


fileFormatVersion: 2
guid: b922e785add647cd876af9a755bbddf5
timeCreated: 1598227279

118
com.unity.perception/Runtime/Randomization/ParameterBehaviours/Configuration/ParameterList.cs


using System;
using System.Collections.Generic;
using Randomization.ParameterBehaviours;
using UnityEngine;
using UnityEngine.Perception.Randomization.Parameters;
namespace UnityEngine.Perception.Randomization.ParameterBehaviours
{
/// <summary>
/// Defines a list of parameters for randomizing simulations
/// </summary>
[ExecuteInEditMode]
[AddComponentMenu("Perception/Randomization/Parameter List")]
public class ParameterList : ParameterBehaviour
{
[SerializeReference] internal List<ParameterListItem> configuredParameters = new List<ParameterListItem>();
// /// <summary>
// /// The parameters contained within this ParameterList
// /// </summary>
// public override IEnumerable<Parameter> parameters
// {
// get
// {
// foreach (var configParameter in configuredParameters)
// yield return configParameter.parameter;
// }
// }
internal ParameterListItem AddParameter<T>(string parameterName) where T : Parameter, new()
{
var parameter = new T();
var configParameter = new ParameterListItem { name = parameterName, parameter = parameter };
configuredParameters.Add(configParameter);
return configParameter;
}
internal ParameterListItem AddParameter(string parameterName, Type parameterType)
{
if (!parameterType.IsSubclassOf(typeof(Parameter)))
throw new ParameterListException($"Cannot add non-parameter types ({parameterType})");
var parameter = (Parameter)Activator.CreateInstance(parameterType);
var configParameter = new ParameterListItem { name = parameterName, parameter = parameter };
configuredParameters.Add(configParameter);
return configParameter;
}
/// <summary>
/// Find a parameter in this configuration by name
/// </summary>
/// <param name="parameterName">The name of the parameter to lookup</param>
/// <param name="parameterType">The type of parameter to lookup</param>
/// <returns>The parameter if found, null otherwise</returns>
/// <exception cref="ParameterListException"></exception>
public Parameter GetParameter(string parameterName, Type parameterType)
{
foreach (var configParameter in configuredParameters)
{
if (configParameter.name == parameterName && configParameter.parameter.GetType() == parameterType)
return configParameter.parameter;
}
return null;
}
/// <summary>
/// Find a parameter in this configuration by name and type
/// </summary>
/// <param name="parameterName"></param>
/// <typeparam name="T">The type of parameter to look for</typeparam>
/// <returns>The parameter if found, null otherwise</returns>
public T GetParameter<T>(string parameterName) where T : Parameter
{
foreach (var configuredParameter in configuredParameters)
{
if (configuredParameter.name == parameterName && configuredParameter.parameter is T typedParameter)
return typedParameter;
}
return null;
}
/// <summary>
/// Applies parameter samples to their targets at the start of each scenario iteration
/// </summary>
public override void OnIterationStart()
{
foreach (var configParameter in configuredParameters)
if (configParameter.target.applicationFrequency == ParameterApplicationFrequency.EveryIteration)
configParameter.ApplyToTarget();
}
/// <summary>
/// Applies parameter samples to their targets at the start of every frame
/// </summary>
public override void OnFrameStart()
{
foreach (var configParameter in configuredParameters)
if (configParameter.target.applicationFrequency == ParameterApplicationFrequency.EveryFrame)
configParameter.ApplyToTarget();
}
// /// <summary>
// /// Validates the settings of each parameter within this ParameterList
// /// </summary>
// /// <exception cref="ParameterListException"></exception>
// public override void Validate()
// {
// var parameterNames = new HashSet<string>();
// foreach (var configParameter in configuredParameters)
// {
// if (parameterNames.Contains(configParameter.name))
// throw new ParameterListException(
// $"Two or more parameters cannot share the same name (\"{configParameter.name}\")");
// parameterNames.Add(configParameter.name);
// configParameter.Validate();
// }
// }
}
}

41
com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterAsset.cs


using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.Perception.Randomization.Samplers;
namespace Randomization.ParameterBehaviours
{
public abstract class ParameterAsset : ScriptableObject
{
internal IEnumerable<Parameter> parameters
{
get
{
var fields = GetType().GetFields();
foreach (var field in fields)
{
if (!field.IsPublic || !field.FieldType.IsSubclassOf(typeof(Parameter)))
continue;
var parameter = (Parameter)field.GetValue(this);
if (parameter == null)
{
parameter = (Parameter)Activator.CreateInstance(field.FieldType);
field.SetValue(this, parameter);
}
yield return parameter;
}
}
}
/// <summary>
/// Reset to default values in the Editor
/// </summary>
public virtual void Reset()
{
foreach (var parameter in parameters)
foreach (var sampler in parameter.samplers)
sampler.baseSeed = SamplerUtility.GenerateRandomSeed();
}
}
}

44
com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterBehaviour.cs


using System;
using UnityEngine;
using UnityEngine.Perception.Randomization.Scenarios;
namespace Randomization.ParameterBehaviours
{
/// <summary>
/// The base class for all randomization scripts
/// </summary>
public abstract class ParameterBehaviour : MonoBehaviour
{
public virtual int executionPriority => 1;
public void Awake()
{
ScenarioBase.activeScenario.AddBehaviour(this);
}
/// <summary>
/// Included in the base ParameterBehaviour class to activate the enabled toggle in the inspector UI
/// </summary>
protected virtual void OnEnable() {}
/// <summary>
/// OnFrameStart is called at the start of every frame if the ParameterBehaviour is enabled
/// </summary>
public virtual void OnFrameStart() { }
/// <summary>
/// OnIterationStart is called at the start of every iteration if the ParameterBehaviour is enabled
/// </summary>
public virtual void OnIterationStart() { }
/// <summary>
/// OnIterationEnd is called at the end of every iteration if the ParameterBehaviour is enabled
/// </summary>
public virtual void OnIterationEnd() { }
/// <summary>
/// Run when the scenario completes
/// </summary>
public virtual void OnScenarioComplete() {}
}
}

213
com.unity.perception/Editor/Randomization/Uss/Styles.uss


.dark-viewport {
border-radius: 5px;
background-color: #191919;
padding: 2px;
}
.parameter-container {
border-width: 2px;
border-radius: 5px;
flex-direction: row;
margin: 2px 1px;
}
.parameter-type-menu {
margin: 1px 3px;
border-width: 1px;
border-radius: 3px;
background-color: #585858;
}
#parameter-type-menu .unity-toolbar-menu__text {
font-size: 13px;
padding: 3px;
}
.sampler-type-menu {
flex-grow: 1.5;
border-radius: 3px;
border-width: 1px;
margin-top: 2px;
margin-right: 3px;
}
.sampler-name {
/*color: lightgreen;*/
-unity-font-style: bold;
}
.parameter-type-label-container {
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 1px;
}
.parameter-type-label-box {
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-grow: 0;
-unity-text-align: middle-center;
border-width: 0;
padding: 1px;
font-size: 13px;
-unity-font-style: bold;
}
.parameter-type-label {
color: cornflowerblue;
/*min-width: 120px;*/
-unity-text-align: middle-left;
}
.parameter-type-label-box .unity-base-text-field__input {
padding-left: 6px;
padding-right: 6px;
}
.unity-toggle {
margin-left: 0;
}
.property-selection-container {
flex-direction: row;
}
.property-select-menu {
flex-grow: 1;
border-width: 1px;
padding-bottom: 1px;
border-radius: 3px;
margin-right: 1px;
}
.remove-parameter-button {
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/X.png");
width: 16px;
height: 16px;
}
.move-buttons-container {
width: auto;
margin-right: 6px;
border-color: black;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
background-color: #2A2A2A;
padding: 3px 2px;
justify-content: center;
}
.drag-handle {
width: 16px;
height: 70%;
min-height: 20px;
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/DragHandle.png");
}
.move-button {
border-width: 0;
width: 42px;
height: 16px;
padding: 9px;
-unity-background-scale-mode: scale-to-fit;
}
.unity-imgui-container {
margin-left: 1px;
margin-right: 3px;
}
.search-icon {
width: 16px;
height: 16px;
margin-top: 2px;
flex-shrink: 0;
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/Search.png");
}
.collapse-parameter-toggle {
flex-shrink: 0;
margin-right: 2px;
width: 12px;
height: 12px;
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/FoldoutOpen.png");
}
.collapsed-parameter .collapse-parameter-toggle {
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/FoldoutClosed.png");
}
.collapsed-parameter .parameter-properties-container {
display: none;
}
.collapsed-parameter .move-buttons-container {
flex-direction: row;
}
.collapsed-parameter .move-button {
width: 16px;
}
.categorical-option {
flex-direction: row;
background-color: #3F3F3F;
margin: 1px;
border-radius: 4px;
}
.options-list-view {
background-color: #191919;
border-radius: 4px;
margin-right: 2px;
padding: 3px;
border-bottom-right-radius: 0;
}
.option-property-field {
width: 0;
flex-grow: 1;
flex-shrink: 0;
}
.uniform-probability .hide-when-uniform {
display: none;
}
.add-option-button {
align-self: flex-end;
border-width: 0;
border-top-right-radius: 0;
border-top-left-radius: 0;
background-color: #191919;
margin-top: 0;
margin-right: 2px;
}
.add-option-button:hover {
background-color: #2A2A2A;
}
.add-option-button:active {
color: cornflowerblue;
}
.remove-option-button {
width: 12px;
height: 14px;
background-image: resource("Packages/com.unity.perception/Editor/Randomization/Icons/X.png");
}
.parameter-drag-bar {
width: 100px;
height: 6px;
background-color: rgba(100,149,237,0.4);
position: absolute;
}
.float-range .unity-base-field__label {
min-width: auto;
margin-right: 4px;
}

21
com.unity.perception/Editor/Randomization/Uxml/ParameterConfiguration.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement>
<Style src="../Uss/Styles.uss"/>
<VisualElement style="flex-direction: row; align-items: center; margin-bottom: 2px; margin-top: 2px;">
<VisualElement class="search-icon" style="margin-left: 3px; margin-right: 2px;"/>
<TextField name="filter-parameters" style="flex-grow: 1; flex-shrink: 1;"/>
</VisualElement>
<ScrollView name="parameter-scroll-view" class="dark-viewport" style="min-height: 100px; max-height: 600px;">
<VisualElement name="parameters-container" style="flex-shrink: 0;"/>
</ScrollView>
<VisualElement style="flex-direction: row; justify-content: space-between;">
<VisualElement style="flex-grow: 1"/>
<editor:ToolbarMenu text="Add New Parameter" name="parameter-type-menu" class="parameter-type-menu"/>
<Button name="collapse-all" text="Collapse All" style="font-size: 13px; padding: 4px;"/>
<Button name="expand-all" text="Expand All" style="font-size: 13px; padding: 4px;"/>
<VisualElement style="flex-grow: 1"/>
</VisualElement>
</VisualElement>
</UXML>

6
com.unity.perception/Editor/Randomization/Uxml/ParameterDrawerElement.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement style="flex-direction: row;">
<Label style="width: 150px;"/>
<editor:ToolbarMenu style="flex-grow: 1; margin-left: 3px; margin-right: 2px; border-top-width: 1px; border-bottom-width: 1px; border-radius: 3px;"/>
</VisualElement>
</UXML>

3
com.unity.perception/Editor/Randomization/Uxml/ParameterDrawerElement.uxml.meta


fileFormatVersion: 2
guid: 18765b47a76c4adcb639d0d247b8bd34
timeCreated: 1596419194

125
com.unity.perception/Editor/Randomization/ParameterConfigurationEditor.cs


using System;
using UnityEngine;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.Configuration;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
[CustomEditor(typeof(ParameterConfiguration))]
class ParameterConfigurationEditor : UnityEditor.Editor
{
VisualElement m_Root;
VisualElement m_ParameterContainer;
public ParameterConfiguration config;
string m_FilterString = string.Empty;
public string FilterString
{
get => m_FilterString;
private set
{
m_FilterString = value;
var lowerFilter = m_FilterString.ToLower();
foreach (var child in m_ParameterContainer.Children())
{
var paramIndex = m_ParameterContainer.IndexOf(child);
var param = config.parameters[paramIndex];
((ParameterElement)child).Filtered = param.name.ToLower().Contains(lowerFilter);
}
}
}
public override VisualElement CreateInspectorGUI()
{
config = (ParameterConfiguration)target;
m_Root = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ParameterConfiguration.uxml").CloneTree();
m_ParameterContainer = m_Root.Q<VisualElement>("parameters-container");
var filter = m_Root.Q<TextField>("filter-parameters");
filter.RegisterValueChangedCallback((e) => { FilterString = e.newValue; });
var collapseAllButton = m_Root.Q<Button>("collapse-all");
collapseAllButton.clicked += () => CollapseParameters(true);
var expandAllButton = m_Root.Q<Button>("expand-all");
expandAllButton.clicked += () => CollapseParameters(false);
var parameterTypeMenu = m_Root.Q<ToolbarMenu>("parameter-type-menu");
foreach (var parameterType in StaticData.parameterTypes)
{
parameterTypeMenu.menu.AppendAction(
Parameter.GetDisplayName(parameterType),
a => { AddParameter(parameterType); },
a => DropdownMenuAction.Status.Normal);
}
RefreshParameterElements();
return m_Root;
}
void RefreshParameterElements()
{
m_ParameterContainer.Clear();
for (var i = 0; i < config.parameters.Count; i++)
m_ParameterContainer.Add(CreateParameterElement(i));
}
ParameterElement CreateParameterElement(int index)
{
return new ParameterElement(index, this);
}
void AddParameter(Type parameterType)
{
var parameter = config.AddParameter(parameterType);
parameter.RandomizeSamplers();
serializedObject.Update();
m_ParameterContainer.Add(CreateParameterElement(config.parameters.Count - 1));
}
public void RemoveParameter(VisualElement template)
{
var paramIndex = m_ParameterContainer.IndexOf(template);
m_ParameterContainer.RemoveAt(paramIndex);
config.parameters.RemoveAt(paramIndex);
serializedObject.Update();
RefreshParameterElements();
}
public void ReorderParameter(int currentIndex, int nextIndex)
{
if (currentIndex == nextIndex)
return;
if (nextIndex > currentIndex)
nextIndex--;
var parameterElement = m_ParameterContainer[currentIndex];
var parameter = config.parameters[currentIndex];
parameterElement.RemoveFromHierarchy();
config.parameters.RemoveAt(currentIndex);
m_ParameterContainer.Insert(nextIndex, parameterElement);
config.parameters.Insert(nextIndex, parameter);
serializedObject.Update();
RefreshParameterElements();
}
void CollapseParameters(bool collapsed)
{
foreach (var child in m_ParameterContainer.Children())
((ParameterElement)child).Collapsed = collapsed;
}
}
}

11
com.unity.perception/Editor/Randomization/ParameterConfigurationEditor.cs.meta


fileFormatVersion: 2
guid: dd62abede5784c84f90495b367408ced
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
com.unity.perception/Editor/Randomization/ParameterDragBar.cs


using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class ParameterDragBar : VisualElement
{
public ParameterDragBar()
{
AddToClassList("parameter-drag-bar");
}
}
}

3
com.unity.perception/Editor/Randomization/ParameterDragBar.cs.meta


fileFormatVersion: 2
guid: 7c1e08b02e5a4c55875f34baf32f8e76
timeCreated: 1596143672

101
com.unity.perception/Editor/Randomization/ParameterDragManipulator.cs


using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class ParameterDragManipulator : MouseManipulator
{
bool m_Active;
float m_Offset;
ParameterElement m_ParameterElement;
VisualElement m_DragHandle;
VisualElement m_DragBar;
VisualElement m_ParameterContainer;
protected override void RegisterCallbacksOnTarget()
{
m_DragHandle = target.Q<VisualElement>("drag-handle");
m_ParameterElement = (ParameterElement)target;
m_DragHandle.RegisterCallback<MouseDownEvent>(OnMouseDown);
m_DragHandle.RegisterCallback<MouseMoveEvent>(OnMouseMove);
m_DragHandle.RegisterCallback<MouseUpEvent>(OnMouseUp);
}
protected override void UnregisterCallbacksFromTarget()
{
m_DragHandle.UnregisterCallback<MouseDownEvent>(OnMouseDown);
m_DragHandle.UnregisterCallback<MouseMoveEvent>(OnMouseMove);
m_DragHandle.UnregisterCallback<MouseUpEvent>(OnMouseUp);
}
void OnMouseDown(MouseDownEvent evt)
{
if (m_Active)
{
evt.StopImmediatePropagation();
return;
}
if (m_ParameterElement.ConfigEditor.FilterString != string.Empty)
return;
m_ParameterContainer = target.parent;
m_DragBar = new ParameterDragBar();
m_DragBar.style.width = new StyleLength(m_ParameterContainer.resolvedStyle.width);
target.parent.Add(m_DragBar);
m_Offset = m_DragHandle.worldBound.position.y - m_ParameterContainer.worldBound.position.y;
m_DragBar.style.top = evt.localMousePosition.y + m_Offset;
m_Active = true;
m_DragHandle.CaptureMouse();
evt.StopPropagation();
}
void OnMouseMove(MouseMoveEvent evt)
{
if (!m_Active || !m_DragHandle.HasMouseCapture())
return;
m_DragBar.style.top = evt.localMousePosition.y + m_Offset;
evt.StopPropagation();
}
void OnMouseUp(MouseUpEvent evt)
{
if (!m_Active || !m_DragHandle.HasMouseCapture() || !CanStopManipulation(evt))
return;
var dragBarY = evt.localMousePosition.y + m_Offset;
m_DragBar.RemoveFromHierarchy();
m_Active = false;
m_DragHandle.ReleaseMouse();
evt.StopPropagation();
var p = 0;
var middlePoints = new float[m_ParameterContainer.childCount];
foreach (var parameterElement in m_ParameterContainer.Children())
{
var middleHeight = parameterElement.worldBound.height / 2;
var localY = parameterElement.worldBound.y - m_ParameterContainer.worldBound.position.y;
middlePoints[p++] = middleHeight + localY;
}
for (var i = 0; i < middlePoints.Length; i++)
{
if (dragBarY < middlePoints[i])
{
ReorderParameter(m_ParameterElement.ParameterIndex, i);
return;
}
}
ReorderParameter(m_ParameterElement.ParameterIndex, middlePoints.Length);
}
void ReorderParameter(int currentIndex, int nextIndex)
{
m_ParameterElement.ConfigEditor.ReorderParameter(currentIndex, nextIndex);
}
}
}

3
com.unity.perception/Editor/Randomization/ParameterDragManipulator.cs.meta


fileFormatVersion: 2
guid: f2b59fa8baf440f597257d8eb8219afa
timeCreated: 1596140810

374
com.unity.perception/Editor/Randomization/ParameterElement.cs


using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class ParameterElement : VisualElement
{
int m_ParameterIndex;
bool m_Filtered;
VisualElement m_Properties;
VisualElement m_ExtraProperties;
VisualElement m_TargetContainer;
ToolbarMenu m_TargetPropertyMenu;
SerializedProperty m_SerializedProperty;
SerializedProperty m_Target;
SerializedProperty m_TargetGameObject;
SerializedProperty m_ApplicationFrequency;
const string k_CollapsedParameterClass = "collapsed-parameter";
public ParameterConfigurationEditor ConfigEditor { get; private set; }
Parameter parameter => ConfigEditor.config.parameters[m_ParameterIndex];
CategoricalParameterBase categoricalParameter => (CategoricalParameterBase)parameter;
public int ParameterIndex => parent.IndexOf(this);
public bool Collapsed
{
get => parameter.collapsed;
set
{
parameter.collapsed = value;
if (value)
AddToClassList(k_CollapsedParameterClass);
else
RemoveFromClassList(k_CollapsedParameterClass);
}
}
public bool Filtered
{
get => m_Filtered;
set
{
m_Filtered = value;
style.display = value
? new StyleEnum<DisplayStyle>(DisplayStyle.Flex)
: new StyleEnum<DisplayStyle>(DisplayStyle.None);
}
}
public ParameterElement(int index, ParameterConfigurationEditor paramConfigEditor)
{
ConfigEditor = paramConfigEditor;
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ParameterElement.uxml");
template.CloneTree(this);
m_ParameterIndex = index;
m_SerializedProperty =
ConfigEditor.serializedObject.FindProperty("parameters").GetArrayElementAtIndex(m_ParameterIndex);
this.AddManipulator(new ParameterDragManipulator());
Collapsed = parameter.collapsed;
var removeButton = this.Q<Button>("remove-parameter");
removeButton.RegisterCallback<MouseUpEvent>(evt => paramConfigEditor.RemoveParameter(this));
var parameterTypeLabel = this.Query<Label>("parameter-type-label").First();
parameterTypeLabel.text = Parameter.GetDisplayName(parameter.GetType());
var parameterNameField = this.Q<TextField>("name");
parameterNameField.isDelayed = true;
parameterNameField.BindProperty(m_SerializedProperty.FindPropertyRelative("name"));
m_TargetContainer = this.Q<VisualElement>("target-container");
m_TargetPropertyMenu = this.Q<ToolbarMenu>("property-select-menu");
m_Target = m_SerializedProperty.FindPropertyRelative("target");
m_TargetGameObject = m_Target.FindPropertyRelative("gameObject");
ToggleTargetContainer();
var frequencyField = this.Q<EnumField>("application-frequency");
frequencyField.Init(ParameterApplicationFrequency.OnIterationSetup);
m_ApplicationFrequency = m_Target.FindPropertyRelative("applicationFrequency");
frequencyField.BindProperty(m_ApplicationFrequency);
var targetField = this.Q<ObjectField>("target");
targetField.objectType = typeof(GameObject);
targetField.value = m_TargetGameObject.objectReferenceValue;
targetField.RegisterCallback<ChangeEvent<Object>>(evt =>
{
ClearTarget();
var appFreqEnumIndex = m_ApplicationFrequency.intValue;
m_TargetGameObject.objectReferenceValue = (GameObject)evt.newValue;
m_ApplicationFrequency.intValue = appFreqEnumIndex;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
ToggleTargetContainer();
FillPropertySelectMenu();
});
FillPropertySelectMenu();
var collapseToggle = this.Q<VisualElement>("collapse");
collapseToggle.RegisterCallback<MouseUpEvent>(evt => Collapsed = !Collapsed);
m_ExtraProperties = this.Q<VisualElement>("extra-properties");
CreatePropertyFields();
}
void ToggleTargetContainer()
{
m_TargetContainer.style.display = m_TargetGameObject.objectReferenceValue == null
? new StyleEnum<DisplayStyle>(DisplayStyle.None)
: new StyleEnum<DisplayStyle>(DisplayStyle.Flex);
}
void ClearTarget()
{
m_Target.FindPropertyRelative("component").objectReferenceValue = null;
m_Target.FindPropertyRelative("propertyName").stringValue = string.Empty;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
}
void SetTarget(ParameterTarget newTarget)
{
m_TargetGameObject.objectReferenceValue = newTarget.gameObject;
m_Target.FindPropertyRelative("component").objectReferenceValue = newTarget.component;
m_Target.FindPropertyRelative("propertyName").stringValue = newTarget.propertyName;
m_Target.FindPropertyRelative("fieldOrProperty").intValue = (int)newTarget.fieldOrProperty;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
m_TargetPropertyMenu.text = TargetPropertyDisplayText(parameter.target);
}
static string TargetPropertyDisplayText(ParameterTarget target)
{
return $"{target.component.GetType().Name}.{target.propertyName}";
}
void FillPropertySelectMenu()
{
if (!parameter.hasTarget)
return;
m_TargetPropertyMenu.menu.MenuItems().Clear();
var options = GatherPropertyOptions(parameter.target.gameObject, parameter.sampleType);
if (options.Count == 0)
{
m_TargetPropertyMenu.text = "No compatible properties";
m_TargetPropertyMenu.SetEnabled(false);
}
else
{
m_TargetPropertyMenu.SetEnabled(true);
foreach (var option in options)
{
m_TargetPropertyMenu.menu.AppendAction(
TargetPropertyDisplayText(option),
a => { SetTarget(option); });
}
m_TargetPropertyMenu.text = parameter.target.propertyName == string.Empty
? "Select a property"
: TargetPropertyDisplayText(parameter.target);
}
}
static List<ParameterTarget> GatherPropertyOptions(GameObject obj, Type propertyType)
{
var options = new List<ParameterTarget>();
foreach (var component in obj.GetComponents<Component>())
{
if (component == null)
continue;
var componentType = component.GetType();
var fieldInfos = componentType.GetFields();
foreach (var fieldInfo in fieldInfos)
{
if (fieldInfo.FieldType == propertyType && fieldInfo.IsPublic && !fieldInfo.IsInitOnly)
options.Add(new ParameterTarget()
{
gameObject = obj,
component = component,
propertyName = fieldInfo.Name,
fieldOrProperty = FieldOrProperty.Field
});
}
var propertyInfos = componentType.GetProperties();
foreach (var propertyInfo in propertyInfos)
{
if (propertyInfo.PropertyType == propertyType && propertyInfo.GetSetMethod() != null)
options.Add(new ParameterTarget()
{
gameObject = obj,
component = component,
propertyName = propertyInfo.Name,
fieldOrProperty = FieldOrProperty.Property
});
}
}
return options;
}
void CreatePropertyFields()
{
m_ExtraProperties.Clear();
if (parameter is CategoricalParameterBase)
{
CreateCategoricalParameterFields();
return;
}
var currentProperty = m_SerializedProperty.Copy();
var nextSiblingProperty = m_SerializedProperty.Copy();
nextSiblingProperty.Next(false);
if (currentProperty.NextVisible(true))
{
do
{
if (SerializedProperty.EqualContents(currentProperty, nextSiblingProperty))
break;
if (currentProperty.type.Contains("managedReference") &&
currentProperty.managedReferenceFieldTypename == StaticData.samplerSerializedFieldType)
m_ExtraProperties.Add(new SamplerElement(currentProperty.Copy(), parameter));
else
{
var propertyField = new PropertyField(currentProperty.Copy());
propertyField.Bind(currentProperty.serializedObject);
m_ExtraProperties.Add(propertyField);
}
} while (currentProperty.NextVisible(false));
}
}
void CreateCategoricalParameterFields()
{
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/CategoricalParameterTemplate.uxml").CloneTree();
var optionsProperty = m_SerializedProperty.FindPropertyRelative("m_Categories");
var probabilitiesProperty = m_SerializedProperty.FindPropertyRelative("probabilities");
var probabilities = categoricalParameter.probabilities;
var listView = template.Q<ListView>("options");
listView.itemsSource = probabilities;
listView.itemHeight = 22;
listView.selectionType = SelectionType.None;
listView.style.flexGrow = 1.0f;
listView.style.height = new StyleLength(listView.itemHeight * 4);
VisualElement MakeItem() => new CategoricalOptionElement(
optionsProperty, probabilitiesProperty);
listView.makeItem = MakeItem;
void BindItem(VisualElement e, int i)
{
var optionElement = (CategoricalOptionElement)e;
optionElement.BindProperties(i);
var removeButton = optionElement.Q<Button>("remove");
removeButton.clicked += () =>
{
probabilitiesProperty.DeleteArrayElementAtIndex(i);
// First delete sets option to null, second delete removes option
var numOptions = optionsProperty.arraySize;
optionsProperty.DeleteArrayElementAtIndex(i);
if (numOptions == optionsProperty.arraySize)
optionsProperty.DeleteArrayElementAtIndex(i);
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
listView.itemsSource = categoricalParameter.probabilities;
listView.Refresh();
};
}
listView.bindItem = BindItem;
var addOptionButton = template.Q<Button>("add-option");
addOptionButton.clicked += () =>
{
probabilitiesProperty.arraySize++;
optionsProperty.arraySize++;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
listView.itemsSource = categoricalParameter.probabilities;
listView.Refresh();
listView.ScrollToItem(probabilitiesProperty.arraySize);
};
var addFolderButton = template.Q<Button>("add-folder");
if (categoricalParameter.sampleType.IsSubclassOf(typeof(Object)))
{
addFolderButton.clicked += () =>
{
var folderPath = EditorUtility.OpenFolderPanel(
"Add Options From Folder", Application.dataPath, string.Empty);
if (folderPath == string.Empty)
return;
var categories = LoadAssetsFromFolder(folderPath, categoricalParameter.sampleType);
probabilitiesProperty.arraySize += categories.Count;
optionsProperty.arraySize += categories.Count;
var uniformProbability = 1f / categories.Count;
for (var i = 0; i < categories.Count; i++)
{
var optionProperty = optionsProperty.GetArrayElementAtIndex(i);
var probabilityProperty = probabilitiesProperty.GetArrayElementAtIndex(i);
optionProperty.objectReferenceValue = categories[i];
probabilityProperty.floatValue = uniformProbability;
}
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
listView.itemsSource = categoricalParameter.probabilities;
listView.Refresh();
};
}
else
addFolderButton.style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
var clearOptionsButton = template.Q<Button>("clear-options");
clearOptionsButton.clicked += () =>
{
probabilitiesProperty.arraySize = 0;
optionsProperty.arraySize = 0;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
listView.itemsSource = categoricalParameter.probabilities;
listView.Refresh();
};
var scrollView = listView.Q<ScrollView>();
listView.RegisterCallback<WheelEvent>(evt =>
{
if (Mathf.Approximately(scrollView.verticalScroller.highValue, 0f))
return;
if ((scrollView.scrollOffset.y <= 0f && evt.delta.y < 0f) ||
scrollView.scrollOffset.y >= scrollView.verticalScroller.highValue && evt.delta.y > 0f)
evt.StopImmediatePropagation();
});
var uniformToggle = template.Q<Toggle>("uniform");
var uniformProperty = m_SerializedProperty.FindPropertyRelative("uniform");
uniformToggle.BindProperty(uniformProperty);
void ToggleProbabilityFields(bool toggle)
{
if (toggle)
listView.AddToClassList("uniform-probability");
else
listView.RemoveFromClassList("uniform-probability");
}
ToggleProbabilityFields(uniformToggle.value);
if (Application.isPlaying)
uniformToggle.SetEnabled(false);
else
uniformToggle.RegisterCallback<ChangeEvent<bool>>(evt => ToggleProbabilityFields(evt.newValue));
var seedField = template.Q<IntegerField>("seed");
seedField.BindProperty(m_SerializedProperty.FindPropertyRelative("m_Sampler.<baseSeed>k__BackingField"));
m_ExtraProperties.Add(template);
}
static List<Object> LoadAssetsFromFolder(string folderPath, Type assetType)
{
if (!folderPath.StartsWith(Application.dataPath))
throw new ApplicationException("Selected folder is not an asset folder in this project");
var assetsPath = "Assets" + folderPath.Remove(0, Application.dataPath.Length);
var guids = AssetDatabase.FindAssets($"t:{assetType.Name}", new []{assetsPath});
var assets = new List<Object>();
foreach (var guid in guids)
assets.Add(AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid), assetType));
return assets;
}
}
}

3
com.unity.perception/Runtime/Randomization/Configuration.meta


fileFormatVersion: 2
guid: b5afd2495bca4fdca95b86d9113f27b2
timeCreated: 1594059945

/com.unity.perception/Editor/Randomization/Uss/Styles.uss.meta → /com.unity.perception/Editor/Randomization/Uss/ParameterAssetStyles.uss.meta

/com.unity.perception/Editor/Randomization/Uxml/ParameterConfiguration.uxml.meta → /com.unity.perception/Editor/Randomization/Uxml/ParameterAssetEditor.uxml.meta

/com.unity.perception/Editor/Randomization/CategoricalOptionElement.cs → /com.unity.perception/Editor/Randomization/VisualElements/CategoricalOptionElement.cs

/com.unity.perception/Editor/Randomization/CategoricalOptionElement.cs.meta → /com.unity.perception/Editor/Randomization/VisualElements/CategoricalOptionElement.cs.meta

/com.unity.perception/Editor/Randomization/FloatRangeElement.cs → /com.unity.perception/Editor/Randomization/VisualElements/FloatRangeElement.cs

/com.unity.perception/Editor/Randomization/FloatRangeElement.cs.meta → /com.unity.perception/Editor/Randomization/VisualElements/FloatRangeElement.cs.meta

/com.unity.perception/Editor/Randomization/ParameterElement.cs.meta → /com.unity.perception/Editor/Randomization/VisualElements/ParameterElement.cs.meta

/com.unity.perception/Editor/Randomization/RandomSeedField.cs → /com.unity.perception/Editor/Randomization/VisualElements/RandomSeedField.cs

/com.unity.perception/Editor/Randomization/RandomSeedField.cs.meta → /com.unity.perception/Editor/Randomization/VisualElements/RandomSeedField.cs.meta

/com.unity.perception/Editor/Randomization/SamplerElement.cs → /com.unity.perception/Editor/Randomization/VisualElements/SamplerElement.cs

/com.unity.perception/Editor/Randomization/SamplerElement.cs.meta → /com.unity.perception/Editor/Randomization/VisualElements/SamplerElement.cs.meta

/com.unity.perception/Editor/Randomization/ScenarioBaseEditor.cs → /com.unity.perception/Editor/Randomization/Editors/ScenarioBaseEditor.cs

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存