浏览代码

implemented parameter behaviours

/parameter-bahaviours
Steven Leal 4 年前
当前提交
0c713aff
共有 83 个文件被更改,包括 1355 次插入769 次删除
  1. 49
      com.unity.perception/Editor/Randomization/StaticData.cs
  2. 2
      com.unity.perception/Editor/Randomization/Uxml/CategoricalOptionElement.uxml
  3. 2
      com.unity.perception/Editor/Randomization/Uxml/ParameterConfiguration.uxml
  4. 33
      com.unity.perception/Editor/Randomization/Uxml/ParameterElement.uxml
  5. 1
      com.unity.perception/Editor/Randomization/Uxml/SamplerElement.uxml
  6. 48
      com.unity.perception/Runtime/Randomization/Configuration/ParameterConfiguration.cs
  7. 14
      com.unity.perception/Runtime/Randomization/Parameters/CategoricalParameter.cs
  8. 13
      com.unity.perception/Runtime/Randomization/Parameters/NumericParameter.cs
  9. 44
      com.unity.perception/Runtime/Randomization/Parameters/Parameter.cs
  10. 14
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/BooleanParameter.cs
  11. 109
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorHsvaParameter.cs
  12. 2
      com.unity.perception/Runtime/Randomization/Samplers/SamplerUtility.cs
  13. 5
      com.unity.perception/Runtime/Randomization/Scenarios/FixedLengthScenario.cs
  14. 53
      com.unity.perception/Runtime/Randomization/Scenarios/ScenarioBase.cs
  15. 10
      com.unity.perception/Tests/Runtime/Randomization/ParameterConfigurationTests.cs
  16. 10
      com.unity.perception/Tests/Runtime/Randomization/ScenarioTests.cs
  17. 22
      com.unity.perception/Editor/Randomization/Editors/ParameterConfigurationEditor.cs
  18. 10
      com.unity.perception/Editor/Randomization/VisualElements/ParameterDragManipulator.cs
  19. 11
      com.unity.perception/Runtime/Randomization/Configuration/ParameterTarget.cs
  20. 3
      com.unity.perception/Editor/Randomization/Editors.meta
  21. 3
      com.unity.perception/Editor/Randomization/PropertyDrawers.meta
  22. 81
      com.unity.perception/Editor/Randomization/Uss/ParameterConfigurationStyles.uss
  23. 110
      com.unity.perception/Editor/Randomization/Uss/ParameterStyles.uss
  24. 3
      com.unity.perception/Editor/Randomization/Uss/ParameterStyles.uss.meta
  25. 17
      com.unity.perception/Editor/Randomization/Uss/SamplerStyles.uss
  26. 3
      com.unity.perception/Editor/Randomization/Uss/SamplerStyles.uss.meta
  27. 31
      com.unity.perception/Editor/Randomization/Uxml/ConfiguredParameterElement.uxml
  28. 3
      com.unity.perception/Editor/Randomization/Uxml/ConfiguredParameterElement.uxml.meta
  29. 10
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawer.uxml
  30. 3
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawer.uxml.meta
  31. 3
      com.unity.perception/Editor/Randomization/VisualElements.meta
  32. 22
      com.unity.perception/Runtime/Randomization/Configuration/ConfiguredParameter.cs
  33. 3
      com.unity.perception/Runtime/Randomization/Configuration/ConfiguredParameter.cs.meta
  34. 3
      com.unity.perception/Runtime/Randomization/ParameterBehaviours.meta
  35. 7
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorHsvaCategoricalParameter.cs
  36. 3
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorHsvaCategoricalParameter.cs.meta
  37. 7
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorRgbCategoricalParameter.cs
  38. 3
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorRgbCategoricalParameter.cs.meta
  39. 111
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorRgbParameter.cs
  40. 3
      com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorRgbParameter.cs.meta
  41. 30
      com.unity.perception/Editor/Randomization/Editors/ParameterBehaviourEditor.cs
  42. 3
      com.unity.perception/Editor/Randomization/Editors/ParameterBehaviourEditor.cs.meta
  43. 25
      com.unity.perception/Editor/Randomization/PropertyDrawers/ColorHsvaDrawer.cs
  44. 3
      com.unity.perception/Editor/Randomization/PropertyDrawers/ColorHsvaDrawer.cs.meta
  45. 26
      com.unity.perception/Editor/Randomization/PropertyDrawers/ParameterDrawer.cs
  46. 3
      com.unity.perception/Editor/Randomization/PropertyDrawers/ParameterDrawer.cs.meta
  47. 39
      com.unity.perception/Editor/Randomization/VisualElements/ColorHsvaField.cs
  48. 3
      com.unity.perception/Editor/Randomization/VisualElements/ColorHsvaField.cs.meta
  49. 212
      com.unity.perception/Editor/Randomization/VisualElements/ConfiguredParameterElement.cs
  50. 3
      com.unity.perception/Editor/Randomization/VisualElements/ConfiguredParameterElement.cs.meta
  51. 47
      com.unity.perception/Editor/Randomization/VisualElements/DrawerParameterElement.cs
  52. 3
      com.unity.perception/Editor/Randomization/VisualElements/DrawerParameterElement.cs.meta
  53. 193
      com.unity.perception/Editor/Randomization/VisualElements/ParameterElement.cs
  54. 51
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterBehaviour.cs
  55. 3
      com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterBehaviour.cs.meta
  56. 213
      com.unity.perception/Editor/Randomization/Uss/Styles.uss
  57. 6
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawerElement.uxml
  58. 3
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawerElement.uxml.meta
  59. 374
      com.unity.perception/Editor/Randomization/ParameterElement.cs
  60. 0
      /com.unity.perception/Editor/Randomization/Uss/ParameterConfigurationStyles.uss.meta
  61. 0
      /com.unity.perception/Editor/Randomization/VisualElements/CategoricalOptionElement.cs
  62. 0
      /com.unity.perception/Editor/Randomization/VisualElements/CategoricalOptionElement.cs.meta
  63. 0
      /com.unity.perception/Editor/Randomization/VisualElements/FloatRangeElement.cs
  64. 0
      /com.unity.perception/Editor/Randomization/VisualElements/FloatRangeElement.cs.meta
  65. 0
      /com.unity.perception/Editor/Randomization/Editors/ParameterConfigurationEditor.cs
  66. 0
      /com.unity.perception/Editor/Randomization/Editors/ParameterConfigurationEditor.cs.meta
  67. 0
      /com.unity.perception/Editor/Randomization/VisualElements/ParameterDragBar.cs
  68. 0
      /com.unity.perception/Editor/Randomization/VisualElements/ParameterDragBar.cs.meta
  69. 0
      /com.unity.perception/Editor/Randomization/VisualElements/ParameterDragManipulator.cs
  70. 0
      /com.unity.perception/Editor/Randomization/VisualElements/ParameterDragManipulator.cs.meta
  71. 0
      /com.unity.perception/Editor/Randomization/VisualElements/ParameterElement.cs.meta
  72. 0
      /com.unity.perception/Editor/Randomization/VisualElements/RandomSeedField.cs
  73. 0
      /com.unity.perception/Editor/Randomization/VisualElements/RandomSeedField.cs.meta
  74. 0
      /com.unity.perception/Editor/Randomization/VisualElements/SamplerElement.cs
  75. 0
      /com.unity.perception/Editor/Randomization/VisualElements/SamplerElement.cs.meta
  76. 0
      /com.unity.perception/Editor/Randomization/Editors/ScenarioBaseEditor.cs
  77. 0
      /com.unity.perception/Editor/Randomization/Editors/ScenarioBaseEditor.cs.meta
  78. 0
      /com.unity.perception/Runtime/Randomization/Configuration/ParameterTarget.cs
  79. 0
      /com.unity.perception/Runtime/Randomization/Configuration/ParameterTarget.cs.meta

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"/>

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


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement>
<Style src="../Uss/Styles.uss"/>
<Style src="../Uss/ParameterConfigurationStyles.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;"/>

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"/>

48
com.unity.perception/Runtime/Randomization/Configuration/ParameterConfiguration.cs


public class ParameterConfiguration : MonoBehaviour
{
internal static HashSet<ParameterConfiguration> configurations = new HashSet<ParameterConfiguration>();
[SerializeReference] internal List<Parameter> parameters = new List<Parameter>();
[SerializeReference] internal List<ConfiguredParameter> parameters = new List<ConfiguredParameter>();
/// <summary>
/// Find a parameter in this configuration by name

/// <exception cref="ParameterConfigurationException"></exception>
public Parameter GetParameter(string parameterName, Type parameterType)
{
foreach (var parameter in parameters)
foreach (var configParameter in parameters)
if (parameter.name == parameterName && parameter.GetType() == parameterType)
return parameter;
if (configParameter.name == parameterName && configParameter.parameter.GetType() == parameterType)
return configParameter.parameter;
}
return null;
}

return null;
}
string PlaceholderParameterName() => $"Parameter{parameters.Count}";
internal T AddParameter<T>() where T : Parameter, new()
internal ConfiguredParameter AddParameter<T>(string parameterName) where T : Parameter, new()
parameter.name = PlaceholderParameterName();
parameters.Add(parameter);
return parameter;
var configParameter = new ConfiguredParameter { name = parameterName, parameter = parameter };
parameters.Add(configParameter);
return configParameter;
internal Parameter AddParameter(Type parameterType)
internal ConfiguredParameter AddParameter(string parameterName, Type parameterType)
parameter.name = PlaceholderParameterName();
parameters.Add(parameter);
return parameter;
var configParameter = new ConfiguredParameter { name = parameterName, parameter = parameter };
parameters.Add(configParameter);
return configParameter;
internal void ApplyParameters(int seedOffset, ParameterApplicationFrequency frequency)
internal void ApplyParameters(ParameterApplicationFrequency frequency)
foreach (var parameter in parameters)
if (parameter.target.applicationFrequency == frequency)
parameter.ApplyToTarget(seedOffset);
foreach (var configParameter in parameters)
if (configParameter.target.applicationFrequency == frequency)
configParameter.ApplyToTarget();
foreach (var parameter in parameters)
parameter.ResetState(scenarioIteration);
foreach (var configParameter in parameters)
configParameter.parameter.ResetState(scenarioIteration);
foreach (var parameter in parameters)
foreach (var configParameter in parameters)
if (parameterNames.Contains(parameter.name))
if (parameterNames.Contains(configParameter.name))
$"Two or more parameters cannot share the same name (\"{parameter.name}\")");
parameterNames.Add(parameter.name);
parameter.Validate();
$"Two or more parameters cannot share the same name (\"{configParameter.name}\")");
parameterNames.Add(configParameter.name);
configParameter.parameter.Validate();
}
}

14
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>();

/// 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();
}
}
}

13
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()
public override void Validate()
{
base.Validate();
foreach (var sampler in samplers)

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


[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>
/// 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() { }
}
}

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


[HideInInspector, SerializeReference] public ISampler value = new UniformSampler(0f, 1f);
/// <summary>
/// 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.
/// </summary>
[Range(0, 1)] public float threshold = 0.5f;
/// <summary>
/// Returns an IEnumerable that iterates over each sampler field in this parameter
/// </summary>
public override IEnumerable<ISampler> samplers

static bool Sample(float t) => t >= 0.5f;
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;
}
}
}

109
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorHsvaParameter.cs


using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine.Perception.Randomization.Samplers;
namespace UnityEngine.Perception.Randomization.Parameters

}
/// <summary>
/// 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]);
}
}
}
[Serializable]
public struct ColorHsva
{
public float h;
public float s;
public float v;
public float a;
public ColorHsva(float h, float s, float v, float a)
{
this.h = h;
this.s = s;
this.v = v;
this.a = a;
}
public static implicit operator float4(ColorHsva c) => new float4(c.h, c.s, c.v, c.a);
public static implicit operator ColorHsva(float4 f) => new ColorHsva(f.x, f.y, f.z, f.w);
public static implicit operator Vector4(ColorHsva c) => new float4(c.h, c.s, c.v, c.a);
public static implicit operator ColorHsva(Vector4 f) => new ColorHsva(f.x, f.y, f.z, f.w);
public static explicit operator Color(ColorHsva c)
{
var color = Color.HSVToRGB(c.h, c.s, c.v);
color.a = c.a;
return color;
}
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);
}
public override string ToString()
{
return $"ColorHsva({h}, {s}, {v}, {a})";
}
}
}

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()

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


/// </summary>
public override bool isScenarioComplete => currentIteration >= constants.totalIterations;
/// <summary>
/// Called before the scenario begins iterating
/// </summary>
public override void OnInitialize()
void Awake()
{
currentIteration = constants.startingIteration;
}

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


using System;
using Randomization.ParameterBehaviours;
using UnityEngine.Perception.Randomization.Configuration;
using UnityEngine.Perception.Randomization.Parameters;
namespace UnityEngine.Perception.Randomization.Scenarios
{

public abstract bool isScenarioComplete { get; }
/// <summary>
/// Called before the scenario begins iterating
/// </summary>
public virtual void OnInitialize() { }
/// <summary>
/// Called at the beginning of every scenario iteration
/// </summary>
public virtual void OnIterationSetup() { }
/// <summary>
/// Called at the start of every frame
/// </summary>
public virtual void OnFrameStart() { }
/// <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();

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

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

OnComplete();
foreach (var behaviour in ParameterBehaviour.activeBehaviours)
behaviour.OnScenarioComplete();
DatasetCapture.ResetSimulation();
if (quitOnComplete)
#if UNITY_EDITOR

if (currentIterationFrame == 0)
{
DatasetCapture.StartNewSequence();
foreach (var config in ParameterConfiguration.configurations)
config.ResetParameterStates(currentIteration);
foreach (var config in ParameterConfiguration.configurations)
config.ApplyParameters(currentIteration, ParameterApplicationFrequency.OnIterationSetup);
OnIterationSetup();
foreach (var behaviour in ParameterBehaviour.activeBehaviours)
behaviour.ResetState(currentIteration);
foreach (var behaviour in ParameterBehaviour.activeBehaviours)
behaviour.OnIterationStart();
foreach (var config in ParameterConfiguration.configurations)
config.ApplyParameters(framesSinceInitialization, ParameterApplicationFrequency.EveryFrame);
OnFrameStart();
foreach (var behaviour in ParameterBehaviour.activeBehaviours)
behaviour.OnFrameStart();
}
}
}

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


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";
config.AddParameter<FloatParameter>("SameName");
config.AddParameter<BooleanParameter>("SameName");
Assert.Throws<ParameterConfigurationException>(() => config.ValidateParameters());
}

var config = m_TestObject.AddComponent<ParameterConfiguration>();
Assert.DoesNotThrow(() => config.AddParameter(typeof(FloatParameter)));
Assert.Throws<ParameterConfigurationException>(() => config.AddParameter(typeof(Rigidbody)));
Assert.DoesNotThrow(() => config.AddParameter("TestParam1", typeof(FloatParameter)));
Assert.Throws<ParameterConfigurationException>(() => config.AddParameter("TestParam2", typeof(Rigidbody)));
}
}
}

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


public IEnumerator AppliesParametersEveryFrame()
{
var config = m_TestObject.AddComponent<ParameterConfiguration>();
var parameter = config.AddParameter<Vector3Parameter>();
var configuredParameter = config.AddParameter<Vector3Parameter>("testParam");
var parameter = (Vector3Parameter)configuredParameter.parameter;
parameter.target.AssignNewTarget(
configuredParameter.target.AssignNewTarget(
m_TestObject, m_TestObject.transform, "position", ParameterApplicationFrequency.EveryFrame);
var initialPosition = Vector3.zero;

public IEnumerator AppliesParametersEveryIteration()
{
var config = m_TestObject.AddComponent<ParameterConfiguration>();
var parameter = config.AddParameter<Vector3Parameter>();
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(
configuredParameter.target.AssignNewTarget(
m_TestObject, transform, "position", ParameterApplicationFrequency.OnIterationSetup);

22
com.unity.perception/Editor/Randomization/Editors/ParameterConfigurationEditor.cs


{
VisualElement m_Root;
VisualElement m_ParameterContainer;
SerializedProperty m_Parameters;
public ParameterConfiguration config;

{
var paramIndex = m_ParameterContainer.IndexOf(child);
var param = config.parameters[paramIndex];
((ParameterElement)child).Filtered = param.name.ToLower().Contains(lowerFilter);
((ConfiguredParameterElement)child).filtered = param.name.ToLower().Contains(lowerFilter);
}
}
}

config = (ParameterConfiguration)target;
m_Parameters = serializedObject.FindProperty("parameters");
m_Root = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ParameterConfiguration.uxml").CloneTree();

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);
for (var i = 0; i < m_Parameters.arraySize; i++)
m_ParameterContainer.Add(new ConfiguredParameterElement(m_Parameters.GetArrayElementAtIndex(i), this));
var parameter = config.AddParameter(parameterType);
parameter.RandomizeSamplers();
var configuredParameter = config.AddParameter($"Parameter{m_Parameters.arraySize}", parameterType);
configuredParameter.parameter.RandomizeSamplers();
m_ParameterContainer.Add(CreateParameterElement(config.parameters.Count - 1));
RefreshParameterElements();
}
public void RemoveParameter(VisualElement template)

void CollapseParameters(bool collapsed)
{
foreach (var child in m_ParameterContainer.Children())
((ParameterElement)child).Collapsed = collapsed;
((ConfiguredParameterElement)child).collapsed = collapsed;
}
}
}

10
com.unity.perception/Editor/Randomization/VisualElements/ParameterDragManipulator.cs


{
bool m_Active;
float m_Offset;
ParameterElement m_ParameterElement;
ConfiguredParameterElement m_ParameterElement;
VisualElement m_DragHandle;
VisualElement m_DragBar;
VisualElement m_ParameterContainer;

m_DragHandle = target.Q<VisualElement>("drag-handle");
m_ParameterElement = (ParameterElement)target;
m_ParameterElement = (ConfiguredParameterElement)target;
m_DragHandle = m_ParameterElement.Q<VisualElement>("drag-handle");
m_DragHandle.RegisterCallback<MouseDownEvent>(OnMouseDown);
m_DragHandle.RegisterCallback<MouseMoveEvent>(OnMouseMove);
m_DragHandle.RegisterCallback<MouseUpEvent>(OnMouseUp);

return;
}
if (m_ParameterElement.ConfigEditor.FilterString != string.Empty)
if (m_ParameterElement.configEditor.FilterString != string.Empty)
return;
m_ParameterContainer = target.parent;

void ReorderParameter(int currentIndex, int nextIndex)
{
m_ParameterElement.ConfigEditor.ReorderParameter(currentIndex, nextIndex);
m_ParameterElement.configEditor.ReorderParameter(currentIndex, nextIndex);
}
}
}

11
com.unity.perception/Runtime/Randomization/Configuration/ParameterTarget.cs


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

$"Component type {componentType.Name} does not have a property named {propertyName}");
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");
}
}

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

81
com.unity.perception/Editor/Randomization/Uss/ParameterConfigurationStyles.uss


.dark-viewport {
border-radius: 5px;
background-color: #191919;
padding: 2px;
}
.unity-toggle {
margin-left: 0;
}
.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");
}
.parameter-drag-bar {
width: 100px;
height: 6px;
background-color: rgba(100,149,237,0.4);
position: absolute;
}
.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;
}

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;
/*min-width: 120px;*/
-unity-text-align: middle-left;
}
.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");
}

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

31
com.unity.perception/Editor/Randomization/Uxml/ConfiguredParameterElement.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"/>
<TextField name="name" text="Parameter Name"/>
</Box>
<Button name="remove-parameter" class="remove-parameter-button"/>
</VisualElement>
<VisualElement name="properties" class="parameter-properties-container">
<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>
</VisualElement>
</VisualElement>
</Box>
</UXML>

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


fileFormatVersion: 2
guid: bb5d8b14dfb1488388860c0437274b7c
timeCreated: 1598232124

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/VisualElements.meta


fileFormatVersion: 2
guid: 7f8f95a1bb144a96b9310164f5560387
timeCreated: 1598135666

22
com.unity.perception/Runtime/Randomization/Configuration/ConfiguredParameter.cs


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

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


fileFormatVersion: 2
guid: b922e785add647cd876af9a755bbddf5
timeCreated: 1598227279

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


fileFormatVersion: 2
guid: 2dd2a5a912ed49ab8356572e5ca6d950
timeCreated: 1598132657

7
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorHsvaCategoricalParameter.cs


using System;
namespace UnityEngine.Perception.Randomization.Parameters
{
[Serializable]
public class ColorHsvaCategoricalParameter : CategoricalParameter<ColorHsva> { }
}

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


fileFormatVersion: 2
guid: e7985c4ea0bf49578e9cabd2c1a63cb6
timeCreated: 1598217458

7
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/ColorRgbCategoricalParameter.cs


using System;
namespace UnityEngine.Perception.Randomization.Parameters
{
[Serializable]
public class ColorRgbCategoricalParameter : CategoricalParameter<Color> { }
}

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


fileFormatVersion: 2
guid: f4bd575c48a145ec9b63eb48ce636ed7
timeCreated: 1598251957

111
com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/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 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/Parameters/ParameterTypes/ColorRgbParameter.cs.meta


fileFormatVersion: 2
guid: a4fdf61227254683a9950f586d6e8f57
timeCreated: 1598252064

30
com.unity.perception/Editor/Randomization/Editors/ParameterBehaviourEditor.cs


using System;
using Randomization.ParameterBehaviours;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
[CustomEditor(typeof(ParameterBehaviour), true)]
public class ParameterBehaviourEditor : UnityEditor.Editor
{
public override VisualElement CreateInspectorGUI()
{
var root = new VisualElement();
var iterator = serializedObject.GetIterator();
// Start iterating over properties
iterator.NextVisible(true);
// Skip m_Script property
iterator.NextVisible(false);
// Create property fields
do { root.Add(new PropertyField(iterator.Copy())); }
while (iterator.NextVisible(false));
return root;
}
}
}

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


fileFormatVersion: 2
guid: 305a421aca744ce49ced7056c1733f48
timeCreated: 1598220645

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)]
public 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);
}
}
}

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


fileFormatVersion: 2
guid: 5e8094c28dd142a09fbbd38ca560164b
timeCreated: 1598250942

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)]
public 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);
}
}
}

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


fileFormatVersion: 2
guid: d389620d3aa3471ca1877eb59cdfb465
timeCreated: 1598135745

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

212
com.unity.perception/Editor/Randomization/VisualElements/ConfiguredParameterElement.cs


using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.Configuration;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class ConfiguredParameterElement : VisualElement
{
bool m_Filtered;
Type m_ParameterSampleType;
VisualElement m_Properties;
VisualElement m_TargetContainer;
ToolbarMenu m_TargetPropertyMenu;
SerializedProperty m_SerializedProperty;
SerializedProperty m_Collapsed;
SerializedProperty m_Target;
SerializedProperty m_TargetGameObject;
SerializedProperty m_TargetComponent;
SerializedProperty m_TargetProperty;
const string k_CollapsedParameterClass = "collapsed-parameter";
public ParameterConfigurationEditor configEditor { get; private set; }
public int ParameterIndex => parent.IndexOf(this);
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 bool filtered
{
get => m_Filtered;
set
{
m_Filtered = value;
style.display = value
? new StyleEnum<DisplayStyle>(DisplayStyle.Flex)
: new StyleEnum<DisplayStyle>(DisplayStyle.None);
}
}
public ConfiguredParameterElement(SerializedProperty property, ParameterConfigurationEditor config)
{
configEditor = config;
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ConfiguredParameterElement.uxml");
template.CloneTree(this);
m_SerializedProperty = property;
var parameterProperty = m_SerializedProperty.FindPropertyRelative("parameter");
var parameter = (Parameter)StaticData.GetManagedReferenceValue(parameterProperty);
m_ParameterSampleType = parameter.sampleType;
m_Collapsed = parameterProperty.FindPropertyRelative("collapsed");
m_Target = m_SerializedProperty.FindPropertyRelative("target");
m_TargetGameObject = m_Target.FindPropertyRelative("gameObject");
m_TargetComponent = m_Target.FindPropertyRelative("component");
m_TargetProperty = m_Target.FindPropertyRelative("property");
this.AddManipulator(new ParameterDragManipulator());
var removeButton = this.Q<Button>("remove-parameter");
removeButton.RegisterCallback<MouseUpEvent>(evt => configEditor.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");
ToggleTargetContainer();
var frequencyField = this.Q<EnumField>("application-frequency");
frequencyField.Init(ParameterApplicationFrequency.OnIterationSetup);
var applicationFrequency = m_Target.FindPropertyRelative("applicationFrequency");
frequencyField.BindProperty(applicationFrequency);
var targetField = this.Q<ObjectField>("target");
targetField.objectType = typeof(GameObject);
targetField.value = m_TargetGameObject.objectReferenceValue;
targetField.RegisterCallback<ChangeEvent<Object>>(evt =>
{
ClearTarget();
var appFreqEnumIndex = applicationFrequency.intValue;
m_TargetGameObject.objectReferenceValue = (GameObject)evt.newValue;
applicationFrequency.intValue = appFreqEnumIndex;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
ToggleTargetContainer();
FillPropertySelectMenu();
});
FillPropertySelectMenu();
var collapseToggle = this.Q<VisualElement>("collapse");
collapseToggle.RegisterCallback<MouseUpEvent>(evt => collapsed = !collapsed);
var parameterProperties = this.Q<VisualElement>("properties");
parameterProperties.Add(new ParameterElement(m_SerializedProperty.FindPropertyRelative("parameter")));
}
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(newTarget.component, newTarget.propertyName);
}
static string TargetPropertyDisplayText(Component component, string propertyName)
{
return $"{component.GetType().Name}.{propertyName}";
}
void FillPropertySelectMenu()
{
if (m_TargetGameObject.objectReferenceValue == null)
return;
m_TargetPropertyMenu.menu.MenuItems().Clear();
var options = GatherPropertyOptions((GameObject)m_TargetGameObject.objectReferenceValue, m_ParameterSampleType);
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.component, option.propertyName),
a => { SetTarget(option); });
}
m_TargetPropertyMenu.text = m_TargetProperty.stringValue == string.Empty
? "Select a property"
: TargetPropertyDisplayText((Component)m_TargetComponent.objectReferenceValue, m_TargetProperty.stringValue);
}
}
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;
}
}
}

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


fileFormatVersion: 2
guid: a26a70e27aed4ced88ef9ac7e17c2793
timeCreated: 1598228666

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;
}
}
}

51
com.unity.perception/Runtime/Randomization/ParameterBehaviours/ParameterBehaviour.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 ParameterBehaviour : MonoBehaviour
{
internal static HashSet<ParameterBehaviour> activeBehaviours = new HashSet<ParameterBehaviour>();
public abstract IEnumerable<Parameter> parameters { get; }
void Awake()
{
activeBehaviours.Add(this);
OnInitialize();
}
void OnDestroy()
{
activeBehaviours.Remove(this);
}
protected virtual void OnInitialize() { }
public virtual void OnFrameStart() { }
public virtual void OnIterationStart() { }
public virtual void OnIterationEnd() { }
public virtual void OnScenarioComplete() {}
public virtual void Validate() { }
internal void ResetState(int scenarioIteration)
{
foreach (var parameter in parameters)
parameter.ResetState(scenarioIteration);
}
public virtual void Reset()
{
foreach (var parameter in parameters)
foreach (var sampler in parameter.samplers)
sampler.baseSeed = SamplerUtility.GenerateRandomSeed();
}
}
}

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


fileFormatVersion: 2
guid: bb8689894f7f41d180c308dbe85f3ced
timeCreated: 1598132668

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;
}

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

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;
}
}
}

/com.unity.perception/Editor/Randomization/Uss/Styles.uss.meta → /com.unity.perception/Editor/Randomization/Uss/ParameterConfigurationStyles.uss.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/ParameterConfigurationEditor.cs → /com.unity.perception/Editor/Randomization/Editors/ParameterConfigurationEditor.cs

/com.unity.perception/Editor/Randomization/ParameterConfigurationEditor.cs.meta → /com.unity.perception/Editor/Randomization/Editors/ParameterConfigurationEditor.cs.meta

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

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

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

/com.unity.perception/Editor/Randomization/ParameterDragManipulator.cs.meta → /com.unity.perception/Editor/Randomization/VisualElements/ParameterDragManipulator.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

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

/com.unity.perception/Runtime/Randomization/Parameters/ParameterTarget.cs → /com.unity.perception/Runtime/Randomization/Configuration/ParameterTarget.cs

/com.unity.perception/Runtime/Randomization/Parameters/ParameterTarget.cs.meta → /com.unity.perception/Runtime/Randomization/Configuration/ParameterTarget.cs.meta

正在加载...
取消
保存