浏览代码

Merge pull request #50 from Unity-Technologies/dr-test3

Randomization interface update
/main
GitHub 4 年前
当前提交
0a4c4641
共有 178 个文件被更改,包括 3379 次插入22 次删除
  1. 4
      .yamato/environments.yml
  2. 4
      README.md
  3. 3
      com.unity.perception/Documentation~/TableOfContents.md
  4. 5
      com.unity.perception/Documentation~/index.md
  5. 3
      com.unity.perception/Editor/Unity.Perception.Editor.asmdef
  6. 3
      com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs
  7. 8
      com.unity.perception/Runtime/GroundTruth/SimulationState.cs
  8. 6
      com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureSensorSchedulingTests.cs.meta
  9. 37
      com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs
  10. 6
      com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs.meta
  11. 12
      com.unity.perception/package.json
  12. 8
      com.unity.perception/Editor/Randomization.meta
  13. 8
      com.unity.perception/Runtime/Randomization.meta
  14. 8
      com.unity.perception/Tests/Runtime/Randomization.meta
  15. 85
      com.unity.perception/Documentation~/Randomization/Images/ColorParameter.png
  16. 206
      com.unity.perception/Documentation~/Randomization/Images/ParameterConfiguration.png
  17. 101
      com.unity.perception/Documentation~/Randomization/Images/TestScenario.png
  18. 93
      com.unity.perception/Documentation~/Randomization/Images/TutorialBuild.png
  19. 67
      com.unity.perception/Documentation~/Randomization/Index.md
  20. 90
      com.unity.perception/Documentation~/Randomization/Parameters.md
  21. 87
      com.unity.perception/Documentation~/Randomization/Samplers.md
  22. 32
      com.unity.perception/Documentation~/Randomization/Scenarios.md
  23. 182
      com.unity.perception/Documentation~/Randomization/Tutorial.md
  24. 61
      com.unity.perception/Editor/Randomization/CategoricalOptionElement.cs
  25. 3
      com.unity.perception/Editor/Randomization/CategoricalOptionElement.cs.meta
  26. 24
      com.unity.perception/Editor/Randomization/FloatRangeElement.cs
  27. 3
      com.unity.perception/Editor/Randomization/FloatRangeElement.cs.meta
  28. 8
      com.unity.perception/Editor/Randomization/Icons.meta
  29. 3
      com.unity.perception/Editor/Randomization/Icons/DragHandle.png
  30. 140
      com.unity.perception/Editor/Randomization/Icons/DragHandle.png.meta
  31. 5
      com.unity.perception/Editor/Randomization/Icons/FoldoutClosed.png
  32. 140
      com.unity.perception/Editor/Randomization/Icons/FoldoutClosed.png.meta
  33. 3
      com.unity.perception/Editor/Randomization/Icons/FoldoutOpen.png
  34. 140
      com.unity.perception/Editor/Randomization/Icons/FoldoutOpen.png.meta
  35. 7
      com.unity.perception/Editor/Randomization/Icons/Search.png
  36. 140
      com.unity.perception/Editor/Randomization/Icons/Search.png.meta
  37. 8
      com.unity.perception/Editor/Randomization/Icons/X.png
  38. 140
      com.unity.perception/Editor/Randomization/Icons/X.png.meta
  39. 125
      com.unity.perception/Editor/Randomization/ParameterConfigurationEditor.cs
  40. 11
      com.unity.perception/Editor/Randomization/ParameterConfigurationEditor.cs.meta
  41. 12
      com.unity.perception/Editor/Randomization/ParameterDragBar.cs
  42. 3
      com.unity.perception/Editor/Randomization/ParameterDragBar.cs.meta
  43. 101
      com.unity.perception/Editor/Randomization/ParameterDragManipulator.cs
  44. 3
      com.unity.perception/Editor/Randomization/ParameterDragManipulator.cs.meta
  45. 3
      com.unity.perception/Editor/Randomization/ParameterElement.cs.meta
  46. 15
      com.unity.perception/Editor/Randomization/RandomSeedField.cs
  47. 3
      com.unity.perception/Editor/Randomization/RandomSeedField.cs.meta
  48. 119
      com.unity.perception/Editor/Randomization/SamplerElement.cs
  49. 3
      com.unity.perception/Editor/Randomization/SamplerElement.cs.meta
  50. 79
      com.unity.perception/Editor/Randomization/ScenarioBaseEditor.cs
  51. 3
      com.unity.perception/Editor/Randomization/ScenarioBaseEditor.cs.meta
  52. 39
      com.unity.perception/Editor/Randomization/StaticData.cs
  53. 3
      com.unity.perception/Editor/Randomization/StaticData.cs.meta
  54. 3
      com.unity.perception/Editor/Randomization/Uss.meta
  55. 213
      com.unity.perception/Editor/Randomization/Uss/Styles.uss
  56. 3
      com.unity.perception/Editor/Randomization/Uss/Styles.uss.meta
  57. 3
      com.unity.perception/Editor/Randomization/Uxml.meta
  58. 353
      com.unity.perception/Editor/Randomization/ParameterElement.cs
  59. 8
      com.unity.perception/Editor/Randomization/Uxml/CategoricalOptionElement.uxml
  60. 3
      com.unity.perception/Editor/Randomization/Uxml/CategoricalOptionElement.uxml.meta
  61. 12
      com.unity.perception/Editor/Randomization/Uxml/CategoricalParameterTemplate.uxml
  62. 3
      com.unity.perception/Editor/Randomization/Uxml/CategoricalParameterTemplate.uxml.meta
  63. 11
      com.unity.perception/Editor/Randomization/Uxml/FloatRangeElement.uxml
  64. 3
      com.unity.perception/Editor/Randomization/Uxml/FloatRangeElement.uxml.meta
  65. 21
      com.unity.perception/Editor/Randomization/Uxml/ParameterConfiguration.uxml
  66. 10
      com.unity.perception/Editor/Randomization/Uxml/ParameterConfiguration.uxml.meta
  67. 6
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawerElement.uxml
  68. 3
      com.unity.perception/Editor/Randomization/Uxml/ParameterDrawerElement.uxml.meta
  69. 3
      com.unity.perception/Editor/Randomization/Uxml/ParameterElement.uxml.meta
  70. 9
      com.unity.perception/Editor/Randomization/Uxml/SamplerElement.uxml
  71. 3
      com.unity.perception/Editor/Randomization/Uxml/SamplerElement.uxml.meta
  72. 20
      com.unity.perception/Editor/Randomization/Uxml/ScenarioBaseElement.uxml
  73. 3
      com.unity.perception/Editor/Randomization/Uxml/ScenarioBaseElement.uxml.meta
  74. 31
      com.unity.perception/Editor/Randomization/Uxml/ParameterElement.uxml
  75. 3
      com.unity.perception/Runtime/Randomization/Configuration.meta
  76. 11
      com.unity.perception/Runtime/Randomization/Configuration/ParameterConfiguration.cs.meta
  77. 11
      com.unity.perception/Runtime/Randomization/Configuration/ParameterConfigurationException.cs
  78. 3
      com.unity.perception/Runtime/Randomization/Configuration/ParameterConfigurationException.cs.meta
  79. 107
      com.unity.perception/Runtime/Randomization/Configuration/ParameterConfiguration.cs
  80. 8
      com.unity.perception/Runtime/Randomization/Parameters.meta
  81. 8
      com.unity.perception/Runtime/Randomization/Samplers.meta
  82. 42
      com.unity.perception/Runtime/Randomization/Samplers/FloatRange.cs
  83. 3
      com.unity.perception/Runtime/Randomization/Samplers/FloatRange.cs.meta
  84. 53
      com.unity.perception/Runtime/Randomization/Samplers/ISampler.cs
  85. 11
      com.unity.perception/Runtime/Randomization/Samplers/ISampler.cs.meta
  86. 3
      com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes.meta
  87. 3
      com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/ConstantSampler.cs.meta
  88. 3
      com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/NormalSampler.cs.meta
  89. 3
      com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/UniformSampler.cs.meta

4
.yamato/environments.yml


upmci_registry: https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
test_editors:
- version: 2019.3.15f1
- version: 2019.4.6f1
- version: 2019.3.15f1
- version: 2019.4.6f1
publish_platforms:
- name: win

4
README.md


> com.unity.perception is in active development. Its features and API are subject to significant change as development progresses.
## Documenation
## Documentation
[Randomizing your simulation](com.unity.perception/Documentation~/Randomization/Index.md)
## Local development
The repository includes two projects for local development in `TestProjects` folder, one set up for HDRP and the other for URP.

3
com.unity.perception/Documentation~/TableOfContents.md


* [Getting Started](GettingStarted.md)
* [Labeling](GroundTruth-Labeling.md)
* [Perception Camera](PerceptionCamera.md)
* [Dataset Capture](DatasetCapture.md)
* [Dataset Capture](DatasetCapture.md)
* [Randomization](Randomization/Index.md)

5
com.unity.perception/Documentation~/index.md


[Setting up your first perception scene](GettingStarted.md)
[Randomizing your simulation](Randomization/Index.md)
## Example projects using Perception
### SynthDet

|[Labeling](GroundTruth-Labeling.md)|Component which marks a GameObject and its descendants with a set of labels|
|[LabelConfig](GroundTruth-Labeling.md#LabelConfig)|Asset which defines a taxonomy of labels for ground truth generation|
|[Perception Camera](PerceptionCamera.md)|Captures RGB images and ground truth from a [Camera](https://docs.unity3d.com/Manual/class-Camera.html)|
|[DatasetCapture](DatasetCapture.md)|Ensures sensors are triggered at proper rates and accepts data for the JSON dataset|
|[DatasetCapture](DatasetCapture.md)|Ensures sensors are triggered at proper rates and accepts data for the JSON dataset|
|[Randomization](Randomization/Index.md)|Integrate domain randomization principles into your simulation|

3
com.unity.perception/Editor/Unity.Perception.Editor.asmdef


"Unity.Collections",
"Unity.Perception.Runtime",
"PathCreatorEditor",
"PathCreator"
"PathCreator",
"UnityEngine.UI"
],
"includePlatforms": [
"Editor"

3
com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs


using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using Unity.Simulation;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Perception.Randomization.Scenarios;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.Serialization;

8
com.unity.perception/Runtime/GroundTruth/SimulationState.cs


throw new InvalidOperationException("AsyncAnnotation has already been reported and cannot be reported again.");
PendingCapture pendingCapture = null;
int annotationIndex = -1;
break;
annotationIndex = pendingCapture.Annotations.FindIndex(a => a.Item1.Equals(asyncAnnotation.Annotation));
if (annotationIndex != -1)
break;
Debug.Assert(pendingCapture != null);
Debug.Assert(pendingCapture != null && annotationIndex != -1);
var annotationIndex = pendingCapture.Annotations.FindIndex(a => a.Item1.Equals(asyncAnnotation.Annotation));
var annotationTuple = pendingCapture.Annotations[annotationIndex];
var annotationData = annotationTuple.Item2;

6
com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureSensorSchedulingTests.cs.meta


defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
userData:
assetBundleName:
assetBundleVariant:

37
com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs


using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;

FileAssert.Exists(capturesPath);
StringAssert.Contains(TestHelper.NormalizeJson(expectedAnnotation), EscapeGuids(File.ReadAllText(capturesPath)));
}
[UnityTest]
public IEnumerator AnnotationAsyncReportResult_FindsCorrectPendingCaptureAfterStartingNewSequence()
{
const string fileName = "my/file.png";
var value = new[]
{
new TestValues()
{
a = "a string",
b = 10
}
};
var ego = DatasetCapture.RegisterEgo("");
var annotationDefinition = DatasetCapture.RegisterAnnotationDefinition("");
var sensorHandle = DatasetCapture.RegisterSensor(ego, "", "", 1, 0);
// Record one capture for this frame
sensorHandle.ReportCapture(fileName, default);
// Wait one frame
yield return null;
// Reset the capture step
DatasetCapture.StartNewSequence();
// Record a new capture on different frame that has the same step (0) as the first capture
sensorHandle.ReportCapture(fileName, default);
// Confirm that the annotation correctly skips the first pending capture to write to the second
var asyncAnnotation = sensorHandle.ReportAnnotationAsync(annotationDefinition);
Assert.DoesNotThrow(() => asyncAnnotation.ReportValues(value));
DatasetCapture.ResetSimulation();
}
[Test]

6
com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs.meta


defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
userData:
assetBundleName:
assetBundleVariant:

12
com.unity.perception/package.json


"com.unity.entities": "0.8.0-preview.8",
"com.unity.simulation.capture": "0.0.10-preview.10",
"com.unity.simulation.core": "0.0.10-preview.17"
},
"description": "Tools for authoring and executing autonomous vehicle simulations.",
"displayName": "Perception",
"name": "com.unity.perception",
"unity": "2019.3",
"version": "0.3.0-preview.1"
},
"description": "Tools for generating large-scale data sets for perception-based machine learning training and validation",
"displayName": "Perception",
"name": "com.unity.perception",
"unity": "2019.4",
"version": "0.3.0-preview.1"
}

8
com.unity.perception/Editor/Randomization.meta


fileFormatVersion: 2
guid: bc1c8d85f0374514ab4d1af6b3bbe6cd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
com.unity.perception/Runtime/Randomization.meta


fileFormatVersion: 2
guid: 511b2251e3510cd48a26b8a61f6911f0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
com.unity.perception/Tests/Runtime/Randomization.meta


fileFormatVersion: 2
guid: 44d8bef3d43160b428851cccd5080624
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

85
com.unity.perception/Documentation~/Randomization/Images/ColorParameter.png

之前 之后
宽度: 455  |  高度: 307  |  大小: 30 KiB

206
com.unity.perception/Documentation~/Randomization/Images/ParameterConfiguration.png

之前 之后
宽度: 499  |  高度: 608  |  大小: 54 KiB

101
com.unity.perception/Documentation~/Randomization/Images/TestScenario.png

之前 之后
宽度: 499  |  高度: 285  |  大小: 24 KiB

93
com.unity.perception/Documentation~/Randomization/Images/TutorialBuild.png

之前 之后
宽度: 496  |  高度: 631  |  大小: 36 KiB

67
com.unity.perception/Documentation~/Randomization/Index.md


# Overview
The randomization toolset simplifies randomizing aspects of generating synthetic data. It facilitates exposing parameters for randomization, offers samplers to pick random values from parameters, and provides scenarios to define a full randomization process. Each of these also allows for custom implementations to fit particular randomization needs.
**What is Domain Randomization?**
Domain randomization is used to create variability in synthetic datasets to help ML models trained in a synthetic domain (Unity) work well in real world applications. The intuition is that the real world is complex and varies widely, while synthetic datasets have limited variation. By randomizing parts of the synthetic domain the ML model will be exposed to enough variability to perform well when deployed. Domain randomization techniques vary widely in what they randomize and how they choose the randomization to apply. The randomization toolset is intended to facilitate a broad variety of implementations and applications.
Our use of domain randomization draws from Tobin et al. (2017) work training robotic pick and place using purely synthetic data.
**How can a Unity project be randomized using the Perception Randomization toolset?**
Randomizing a project involves the following steps:
1. Create a parameter configuration
2. Add parameters to the parameter configuration
3. Customize parameter properties and samplers
4. Create a scenario to control simulation execution
As the first step mentions, randomization begins with creating a new ParameterConfiguration component. From here, users can configure and organize new random parameters to control various aspects of their simulation directly from the inspector in the Unity editor.
![Example Parameters](./Images/ParameterConfiguration.png)
Next, create a few parameters and modify their properties. Parameters often customize their random variables through the parameter configuration using samplers. Samplers enable users to specify a type of probabilty distribution to use when generating random values.
Finally, add a Scenario component to the scene. Scenarios are used to coordinate the application of randomizations during the execution of a simulation.
Continue reading for more details concerning the three primary components driving randomizations in the perception package: parameters, samplers, and scenarios.
## Parameters
Parameters are used to map common types of simulation properties to random variables. For example, a Vector3 size parameter can be used to randomize the x, y, and z dimensions of an obstacle. Or a material parameter can be used to swap between different terrain surface materials. Additionally, parameter sub-properties can be modified from the parameter configuration in playmode better visualize the impact of different randomization settings.
To read more about how to create custom parameter types, navigate over to the [parameters doc](Parameters.md).
## Samplers
Samplers generate random float values by sampling from probability distributions. They are considered bounded since each random sampler generates float values within a range defined by a minumum and maximum value. The values generated from samplers are often used to randomize the sub components of parameters.
![Example Parameters](./Images/ColorParameter.png)
For example, a color parameter has four independently randomizable components: hue, saturation, value, and alpha. Each of the four samplers attached to a color parameter can employ a unique probability distribution to customize how new colors are sampled within a simulation. Out of the box, the perception package supports uniform and normal distribution sampling. So in our color example, a user may choose a normal distribution for their hue, a uniform distribution for saturation, and a constant value sampler for the value and alpha color components.
Take a look at the [samplers doc](Samplers.md) to learn more about implementing custom probability distributions and samplers that can integrate with the perception package.
## Scenarios
Scenarios have three responsibilities:
1. Controlling the execution flow of your simulation
2. Customizing the application of random parameters in your project
3. Defining constants that can be configured externally from a built Unity player
The fundamental principle of domain randomization is to simulate environments under a variety of randomized conditions. Each **iteration** of a scenario is intended to encapsulate one complete run of a simulated environment under uniquely randomized conditions. Scenarios determine how to setup a new iteration, what conditions determine the end of an iteration, how to clean up a completed iteration, and finally how many iterations to perform. Each of these behaviors can be customized for a new scenario by deriving from the Scenario class in the perception package.
It is possible to configure parameters to affect simulation properties directly from the parameter configuration. While useful, this feature is constrained to a particular set of use cases. Instead, a user can reference existing parameters in their scenario to implement more intricate randomizations. For example, a user can reference a `SpawnCount` parameter and a `ObjectPosition` parameter to randomize the positions of a dynamic number of objects during the setup step of a scenario.
![Example Parameters](./Images/TestScenario.png)
Finally, scenarios define constants from which to expose global simulation behaviors automatically. By modifying serialized constants externally, users can customize their simulation runtime even after their project has been built.
## Getting Started
Visit our [randomization tutorial doc](Tutorial.md) to get started using the perception package's randomization tools in an example project.

90
com.unity.perception/Documentation~/Randomization/Parameters.md


# Parameters
## Lookup Parameters
To obtain a parameter from a paramter configuration, use the GetParameter() method:
```
// Get a reference to the parameter configuration attached to this GameObject
var parameterConfiguration = GetComponent<ParameterConfiguration>();
// Lookup the parameter "ObjectWidth" by name
var parameter = GetComponent<FloatParameter>("ObjectWidth");
```
## Creating and Sampling Parameters
Parameters are typically managed by `ParameterConfigurations` in the Unity Editor. However, parameters can be instanced independently like a regular class too:
```
// Create a color parameter
var colorParameter = new HsvaColorParameter();
// Generate one color sample
var color = colorParameter.Sample();
```
Note that parameters, like samplers, generate new random values for each call to the Sample() method:
```
var color1 = colorParameter.Sample();
var color2 = colorParameter.Sample();
Assert.AreNotEqual(color1, color2);
```
## Defining Custom Parameters
All parameters derive from the `Parameter` abstract class, but all included perception package parameter types derive from two specialized Parameter base classes:
1. `CategoricalParameter`
2. `NumericParameter`
### Categorical Parameters
Categorical parameters choose a value from a list of options that have no intrinsic ordering. For example, a material paramater randomly chooses from a list of material options, but the list of material options itself can be rearranged into any particular order without affecting the distribution of materials selected.
If your custom parameter is a categorical in nature, take a look at the [StringParameter]() class included in the perception package as a reference for how to derive the `CategoricalParameter` class.
```
using UnityEngine.Perception.Randomization.Parameters.Attributes;
namespace UnityEngine.Perception.Randomization.Parameters
{
[AddComponentMenu("")]
[ParameterMetaData("String")]
public class StringParameter : CategoricalParameter<string> {}
}
```
**Note:** the AddComponentMenu attribute with an empty string prevents parameters from appearing in the Add Component GameObject menu. Randomization parameters should only be created with by a `ParameterConfiguration`
### Numeric Parameters
Numeric parameters use samplers to generate randomized structs. Take a look at the [ColorHsvaParameter]() class included in the perception package for an example on how to implement a numeric parameter.
## Improving Sampling Performance
For numeric parameters, it is recommended to use the JobHandle overload of the Samples() method when generating a large number of samples. The JobHandle overload will utilize the Unity Burst Compiler and Job System to automatically optimize and multithread parameter sampling jobs. The code block below is an example of how to use this overload to sample two parameters in parallel:
```
// Get a reference to the parameter configuration attached to this GameObject
var parameterConfiguration = GetComponent<ParameterConfiguration>();
// Lookup parameters
var cubeColorParameter = parameterConfiguration.GetParameter<HsvaColorParameter>("CubeColor");
var cubePositionParameter = parameterConfiguration.GetParameter<Vector3Parameter>("CubePosition");
// Schedule sampling jobs
var cubeColors = cubeColorParameter.Samples(constants.cubeCount, out var colorHandle);
var cubePositions = cubePositionParameter.Samples(constants.cubeCount, out var positionHandle);
// Combine job handles
var handles = JobHandle.CombineDependencies(colorHandle, positionHandle);
// Wait for the jobs to complete
handles.Complete();
// Use the created samples
for (var i = 0; i < constants.cubeCount; i++)
{
m_ObjectMaterials[i].SetColor(k_BaseColorProperty, cubeColors[i]);
m_Objects[i].transform.position = cubePositions[i];
}
// Dispose of the generated samples
cubeColors.Dispose();
cubePositions.Dispose();
```

87
com.unity.perception/Documentation~/Randomization/Samplers.md


# Samplers
Samplers in the perception package are classes that deterministically generate random float values from bounded probability distributions. Although samplers are often used in conjunction with parameters to generate arrays of typed random values, samplers can be instantiated and used from any ordinary script:
```
var sampler = new NormalSampler();
sampler.seed = 123456789u;
sampler.mean = 3;
sampler.stdDev = 2;
sampler.range = new FloatRange(-10, 10);
// Generate a sample
var sample = sampler.NextSample();
```
Four Samplers are included with the perception package:
1. Constant Sampler
2. Uniform Sampler
3. Normal Sampler
4. Placeholder Range Sampler
#### Constant Sampler
Generates constant valued samples
#### Uniform Sampler
Samples uniformly from a specified range
#### Normal Sampler
Generates random samples from a truncated normal distribution bounded by a specified range
#### Placeholder Range Sampler
Used to define a float range [minimum, maximum] for a particular component of a parameter (example: the hue component of a color parameter). This sampler is useful for configuring sample ranges for non-perception related scripts, particularly when these scripts have a public interface for manipulating a minimum and maximum bounds for their sample range but perform the actual sampling logic internally.
## Performance
Samplers are designed to be Unity Burst Compiler and Job System compatible to increase simulation performance when generating large numbers of samples. Below is an example of a simple job that uses a NormalSampler directly to create 100 normally distributed samples:
```
[BurstCompile]
public struct SampleJob : IJob
{
NormalSampler sampler;
public NativeArray<float> samples;
public void Execute()
{
for (var i = 0; i < samples.Length; i++)
samples[i] = sampler.NextSample();
}
}
```
Additionally, samplers have a NativeSamples() method that can schedule a ready-made multi-threaded job intended for generating a large array of samples. Below is an example of how to combine two job handles returned by NativeSamples() to generate two arrays of samples simultaneously:
```
// Create samplers
var uniformSampler = new UniformSampler
{
range = new FloatRange(0, 1),
seed = 123456789u
};
var normalSampler = new NormalSampler
{
range = new FloatRange(0, 1),
mean = 0,
stdDev = 1,
seed = 987654321u
};
// Create sample jobs
var uniformSamples = uniformSampler.NativeSamples(1000, out var uniformHandle);
var normalSamples = normalSampler.NativeSamples(1000, out var normalHandle);
// Combine job handles
var combinedJobHandles = JobHandle.CombineDependencies(uniformHandle, normalHandle);
// Wait for jobs to complete
combinedJobHandles.Complete();
//...
// Use samples
//...
// Dispose of sample arrays
uniformSamples.Dispose();
normalSamples.Dispose();
```
## Custom Samplers
Take a look at the [UniformSampler](../../Runtime/Randomization/Samplers/SamplerTypes/UniformSampler) and [NormalSampler](../../Runtime/Randomization/Samplers/SamplerTypes/NormalSampler) structs as references for implementing your own [ISampler](../../Runtime/Randomization/Samplers/ISampler). Note that the NativeSamples() method in the ISampler interface requires the usage of the Unity Job System. Take a look [here](https://docs.unity3d.com/Manual/JobSystem.html) to learn more about how to create jobs using the Unity Job System.

32
com.unity.perception/Documentation~/Randomization/Scenarios.md


# Scenarios
Scenarios have three responsibilities:
1. Controlling the execution flow of your simulation
2. Customizing the application of random parameters in your project
3. Defining constants that can be configured externally from a built Unity player
By default, the perception package includes one ready-made scenario, the `FixedFrameLengthScenario` class. This scenario is useful for when all created parameters have target GameObjects configured directly in the `ParameterConfiguration` and the scenario execution requires little modification.
More commonly, users will find the need to create their own Scenario class. Below is an overview of the more common scenario properties and methods a user can override:
1. **isIterationComplete** - determines the conditions that cause the end of a scenario iteration
2. **isScenarioComplete** - determines the conditions that cause the end of a scenario
3. **Initialize** - actions to complete before the scenario has begun iterating
4. **Setup** - actions to complete at the beginning of each iteration
5. **Teardown** - actions to complete at the end of each iteration
6. **OnComplete** - actions to complete after the scenario as completed
## Constants
Scenarios define constants from which to expose global simulation behaviors like a starting iteration value or a total iteration count. Users can serialize these scenario constants to JSON, modify them in an external program, and finally reimport the JSON constants at runtime to configure their simulation even after their project has been built. Below is an example of the constants used in the `FixedFrameLengthScenario` class:
```
[Serializable]
public class Constants
{
public int iterationFrameLength = 1;
public int startingIteration;
public int totalIterations = 1000;
}
```
A few key things to note here:
1. Make sure to include the [Serializable] attribute on a constant class. This will ensure that the constants can be manipulated from the Unity inspector.
2. By default, UnityEngine.Object class references cannot be serialized to JSON in a meaningful way. This includes Monobehaviors and SerializedObjects. For more information on what can and can't be serialized, take a look at the [Unity JsonUtility manual](https://docs.unity3d.com/ScriptReference/JsonUtility.html).
3. A scenario class's Serialize() and Deserialized() methods can be overriden to implement custom serialization strategies.

182
com.unity.perception/Documentation~/Randomization/Tutorial.md


# Randomization Tutorial
This goal of this tutorial is to walk users through an example randomized perception project that explores the following activities:
1. Creating a parameter configuration
2. Customizing parameters and samplers
4. Configuring a scenario to run the simulation
5. Configure the perception camera
6. Building a simulation runtime
7. Modifying scenario constants
By the end of this guide, the user should have a new project that generates the perception data necessary to train a model to identify a cube from a solid colored background.
Note: Before beginning the tutorial, follow [this guide](../SetupSteps.md) to install the perception package into a new Unity project.
## Step 1: Create Scene and GameObjects
1. Create a new scene using `File -> New Scene`
2. Use the key combo `Ctrl+S` to save and name the new scene
3. Create a new cube GameObject
1. Create a new cube GameObject by navigating to `GameObject -> 3D Object -> Cube` in the menubar
2. Rename the new cube GameObject "Cube" by double clicking on the new GameObject that appeared in the hierarchy
3. Reset the cube's transform component by right clicking on transform component in the cube's inpector and clicking `Reset`
4. Create a new background GameObject
1. Create a new quad GameObject and rename it "Background"
2. Set the background quad's position to (0, 0, 2) to set it behind the cube and make the quad large enough to fill the camera by change the quad's scale to (30, 30, 1)
5. In the *MeshRenderer* component of the *Cube* and *Background* GameObjects, set `Lighting -> Cast shadows -> Off` to prevent the two objects from casting shadows on each other
## Step 2: Create Parameter Configuration
1. Create a new empty GameObject by using `GameObject -> Create Empty` from the menubar
2. Rename the new empty GameObject "Config" by double clicking on the new GameObject that appeared in the hierarchy
3. To add a new Parameter Configuration component to the Config GameObject, click on the GameObject in the hierarchy and then click the `Add Component` button in the inspector window. Select `Randomization -> Parameter Configuration` to add the new component.
## Step 3: Create and Customize Parameters
In this step, we will configure 6 parameters to randomize the scene: *CubePosition*, *CubeRotation*, *CubeScale*, *CubeColor*, *BackgroundColor*, and *CameraRotation*
#### Parameter 1: Cube Position
1. Create a new Vector3 parameter by clicking *Add New Parameter -> Vector3* on the parameter configuration inspector
2. Rename the parameter "CubePosition" by typing the text box next to the blue text indicating the parameter's type
3. Click the *Target GameObject* checkbox and select the *Cube* GameObject in the target object selector. Select the property *position* from the property dropdown.
4. Consider using the following sampler values:
* X : Uniform [-5, 5]
* Y : Uniform [-5, 5]
* Z : Constant [Value = 0]
#### Parameter 2: Cube Rotation
1. Create a new Vector3 parameter named "CubeRotation"
2. Select the *Cube* GameObject as the target GameObject and select the property *Transform.eulerAngles* from the property dropdown
3. Consider using the following component values:
* X : Uniform [0, 360]
* Y : Uniform [0, 360]
* Z : Uniform [0, 360]
#### Parameter 3: Cube Scale
1. Create a new Vector3 parameter named "CubeScale"
2. Select the *Cube* GameObject as the target GameObject and select the property *Transform.localScale* from the property dropdown
3. Consider using the following component values:
* X : Uniform [0.5, 2]
* Y : Uniform [0.5, 2]
* Z : Uniform [0.5, 2]
4. To ensure that the X, Y, and Z samplers all sample equal scale values, copy the X sampler's random seed to all three samplers
#### Parameter 4: Cube Color
1. Create a new ColorHSVA parameter named "CubeColor"
2. Skip setting the target GameObject. We will be using this parameter from within the scenario instead.
3. Consider using the following component values:
* Hue : Uniform [0, 1]
* Saturation : Uniform [0, 1]
* Value : Uniform [0.25, 1]
* Alpha : Constant [Value = 0]
#### Parameter 5: Background Color
1. Create a new ColorHSVA parameter named "BackgroundColor"
2. Skip setting the target GameObject. We will be using this parameter from within the scenario instead.
3. Consider using the following component values:
* Hue : Uniform [0, 1]
* Saturation : Uniform [0, 1]
* Value : Uniform [0.25, 1]
* Alpha : Constant [Value = 0]
#### Parameter 6: Camera Rotation
1. Create a new Vector3 parameter named "CameraRotation"
2. Select the *Main Camera* GameObject as the target GameObject and select the property *Transform.eulerAngles* from the property dropdown
3. Consider using the following component values:
* X : Constant [Value = 0]
* Y : Constant [Value = 0]
* Z : Uniform [0, 360]
## Step 4: Configure Scenario
1. Right click on the *Scripts* folder in the project hierarchy and select `Create -> C# Script`. Name the script "CubeScenario" and press enter.
2. Double click on the new "CubeScenario" script to open it for edit
3. In your code editor, paste the following C# code into the CubeScenario script:
```
using System;
using UnityEngine;
using UnityEngine.Perception.Randomization.Configuration;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.Perception.Randomization.Scenarios;
public class CubeScenario : Scenario<CubeScenario.Constants>
{
[Serializable]
public class Constants
{
public int totalIterations = 1000;
}
public override bool isIterationComplete => currentIterationFrame >= 1;
public override bool isScenarioComplete => currentIteration >= constants.totalIterations;
public ParameterConfiguration config;
public GameObject background;
public GameObject cube;
ColorHsvaParameter m_BackgroundColorParameter;
ColorHsvaParameter m_CubeColorParameter;
Material m_BackgroundMaterial;
Material m_CubeMaterial;
static readonly int k_BaseColor = Shader.PropertyToID("_BaseColor");
public override void OnInitialize()
{
m_BackgroundColorParameter = config.GetParameter<ColorHsvaParameter>("BackgroundColor");
m_CubeColorParameter = config.GetParameter<ColorHsvaParameter>("CubeColor");
m_BackgroundMaterial = background.GetComponent<MeshRenderer>().material;
m_CubeMaterial = cube.GetComponent<MeshRenderer>().material;
}
public override void OnIterationSetup()
{
m_BackgroundMaterial.SetColor(k_BaseColor, m_BackgroundColorParameter.Sample());
m_CubeMaterial.SetColor(k_BaseColor, m_CubeColorParameter.Sample());
}
}
```
So what is this CubeScenario script accomplishing?
1. The *Constants* nested class in this scenario script determines what scenario parameters can be JSON serialized. Only these parameters can be changed externally from a built player. In this example, we expose the number of total iterations the scenario will complete.
2. The overrided properties *isIterationComplete* and *isScenarioComplete* are checked before every frame to control the scenario's execution flow. In this case, the scenario will execute for only one frame for each iteration and continue executing until reaching the total iteration limit set by the *totalIterations* field in the constants class.
3. In Unity, manipulating the color of a material is a shader specific task that cannot be accomplished directly from a color parameter's target GameObject setting. Instead we:
1. Expose a reference to the parameter configuration this scenario's inspector as the public script variable
2. Cache the ID of the *_BaseColor* shader property
3. Override the OnInitialize() method to cache a few references. First, we lookup the parameters *BackgroundColor* and *CubeColor* by name from the the parameter configuration. Second, we grab the references to the materials attached to the cube and background GameObjects when the simulation starts.
4. Override the OnIterationSetup() method to apply randomly sampled color values to the shaders of the cached materials at the beginning of each scenario iteration
4. Back in the Unity editor, navigate to the inspector of the *Config* GameObject and use `Add Component -> CubeScenario` to add the new CubeScenario component to your parameter configuration.
5. Open the constants dropdown and confirm how many iterations the scenario should run (the default is 1000)
6. Use the *backgroundColorParameter* and *cubeColorParameter* dropdowns to inform the script of which parameters in the configuration to use for the BackgroundColor and CubeColor respectively.
7. Select the *Background* and *Cube* GameObjects from their respective GameObject field selectors
8. Confirm that the scenario and parameter configuration are composed properly by clicking the play button in the editor. In the Game window, a cube of different sizes, rotations, scales, and colors should be appearing against a color changing background.
9. To serialize the constants used in the scenario to JSON for external modification after this project has been built into a runtime, click the *Serialize Config* button on the parameter configuration
## Step 5: Configure Perception Camera
Read through the [general perception getting started guide](../GettingStarted.md) before completing the following steps:
1. (For URP projects) Add GroundTruthRendererFeature
2. Add a *PerceptionCamera* component to the MainCamera
3. Label the cube
1. Add a *Labeling* component to the cube GameObject
2. Create a *LabelingConfiguration* asset
3. Add the cube label to the new configuration
4. Select the new configuration asset from the perception camera
4. Enter play mode to confirm that labeled data is being generated
## Step 6: Build Simulation Runtime
1. Create a new sub-folder under "Assets" in the Project Hierarchy named "BuildConfigurations"
2. Right click on the BuildConfigurations folder and use `Create -> Build -> Empty Build Configuration` to create a new build configuration asset
3. Rename the build configuration asset "TutorialBuild"
4. Copy the settings from the example build configuration screenshot below:
![TutorialBuild](Images/TutorialBuild.png)
5. Click the "Build" button in the upper righthand corner of the build configuration inspector to create an executable of the tutorial scene.
## Step 7: Modify Scenario Constants
**Note**: Make sure that the "Deserialize On Start" field is checked in the scenario's inspector. A player built without this field checked will cause the player to not load serialized constants.
1. Navigate to the folder created during the build from the previous step of this tutorial (example: C:\projects\RandomizationTutorial\Builds\Tutorial)
2. Open the "_Data" folder (example: Tutorial_Data) and then open the "StreamingAssets" folder
3. Inside the folder should be the JSON scenario constants serialized from the parameter configuration in Step 4
4. Edit this JSON file to update the scenario constants used in the player
5. Confirm the new constants are deserialized at runtime by executing the simulation

61
com.unity.perception/Editor/Randomization/CategoricalOptionElement.cs


using System;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class CategoricalOptionElement : VisualElement
{
int m_Index;
SerializedProperty m_CategoryProperty;
SerializedProperty m_ProbabilitiesProperty;
internal CategoricalOptionElement(
SerializedProperty categoryProperty,
SerializedProperty probabilitiesProperty)
{
m_CategoryProperty = categoryProperty;
m_ProbabilitiesProperty = probabilitiesProperty;
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/CategoricalOptionElement.uxml");
template.CloneTree(this);
}
// Called from categorical parameter
public void BindProperties(int i)
{
m_Index = i;
var indexLabel = this.Q<Label>("index-label");
indexLabel.text = $"[{m_Index}]";
var optionProperty = m_CategoryProperty.GetArrayElementAtIndex(i);
var option = this.Q<PropertyField>("option");
option.BindProperty(optionProperty);
var label = option.Q<Label>();
label.parent.Remove(label);
var probabilityProperty = m_ProbabilitiesProperty.GetArrayElementAtIndex(i);
var probability = this.Q<FloatField>("probability");
probability.isDelayed = true;
probability.labelElement.style.minWidth = 0;
probability.labelElement.style.marginRight = 4;
if (Application.isPlaying)
{
probability.value = probabilityProperty.floatValue;
probability.SetEnabled(false);
}
else
{
probability.SetEnabled(true);
probability.RegisterValueChangedCallback((evt) =>
{
if (evt.newValue < 0f)
probability.value = 0f;
});
probability.BindProperty(probabilityProperty);
}
}
}
}

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


fileFormatVersion: 2
guid: 3066f77d411047baafb6cc454adc6e37
timeCreated: 1595535184

24
com.unity.perception/Editor/Randomization/FloatRangeElement.cs


using UnityEngine;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class FloatRangeElement : VisualElement
{
public FloatRangeElement(SerializedProperty property)
{
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>($"{StaticData.uxmlDir}/FloatRangeElement.uxml");
template.CloneTree(this);
var minimumField = this.Q<FloatField>("minimum");
minimumField.bindingPath = property.propertyPath + ".minimum";
var maximumField = this.Q<FloatField>("maximum");
maximumField.bindingPath = property.propertyPath + ".maximum";
this.Bind(property.serializedObject);
}
}
}

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


fileFormatVersion: 2
guid: e37f169c618d471d8ed9614a41096437
timeCreated: 1595281335

8
com.unity.perception/Editor/Randomization/Icons.meta


fileFormatVersion: 2
guid: 7d1007e5e43ddb348826f6466e129f6f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
com.unity.perception/Editor/Randomization/Icons/DragHandle.png

之前 之后
宽度: 32  |  高度: 32  |  大小: 1.6 KiB

140
com.unity.perception/Editor/Randomization/Icons/DragHandle.png.meta


fileFormatVersion: 2
guid: d555aa5357abff5438d7aa10822c77f5
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 2
mipBias: -100
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Windows Store Apps
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

5
com.unity.perception/Editor/Randomization/Icons/FoldoutClosed.png

之前 之后
宽度: 32  |  高度: 32  |  大小: 1.8 KiB

140
com.unity.perception/Editor/Randomization/Icons/FoldoutClosed.png.meta


fileFormatVersion: 2
guid: 7818c5e4d2413b34482d07005d447bfc
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 2
mipBias: -100
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Windows Store Apps
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

3
com.unity.perception/Editor/Randomization/Icons/FoldoutOpen.png

之前 之后
宽度: 32  |  高度: 32  |  大小: 1.8 KiB

140
com.unity.perception/Editor/Randomization/Icons/FoldoutOpen.png.meta


fileFormatVersion: 2
guid: 0960d5f2a553d8f4fbb79f2a4c362c45
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 2
mipBias: -100
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Windows Store Apps
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

7
com.unity.perception/Editor/Randomization/Icons/Search.png

之前 之后
宽度: 32  |  高度: 32  |  大小: 2.0 KiB

140
com.unity.perception/Editor/Randomization/Icons/Search.png.meta


fileFormatVersion: 2
guid: 0ae23578b45dce7478d3364d8b237294
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 2
mipBias: -100
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Windows Store Apps
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

8
com.unity.perception/Editor/Randomization/Icons/X.png

之前 之后
宽度: 32  |  高度: 32  |  大小: 3.3 KiB

140
com.unity.perception/Editor/Randomization/Icons/X.png.meta


fileFormatVersion: 2
guid: 26335dfb433170348ad78bfe72dc07ff
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 2
mipBias: -100
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Windows Store Apps
maxTextureSize: 8192
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

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

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


fileFormatVersion: 2
guid: ea72d77c64d1447aa195e2068f02cf74
timeCreated: 1595279847

15
com.unity.perception/Editor/Randomization/RandomSeedField.cs


using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class RandomSeedField : IntegerField
{
public RandomSeedField(SerializedProperty property)
{
label = "Seed";
this.BindProperty(property);
}
}
}

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


fileFormatVersion: 2
guid: b4fa54f5ed5d4d67a278fa8b42dc55cb
timeCreated: 1596171029

119
com.unity.perception/Editor/Randomization/SamplerElement.cs


using System;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.Perception.Randomization.Samplers;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
class SamplerElement : VisualElement
{
Parameter m_Parameter;
ISampler m_Sampler;
SerializedProperty m_Property;
SerializedProperty m_RangeProperty;
VisualElement m_Properties;
ToolbarMenu m_SamplerTypeDropdown;
public SamplerElement(SerializedProperty property, Parameter parameter)
{
m_Property = property;
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>($"{StaticData.uxmlDir}/SamplerElement.uxml");
template.CloneTree(this);
m_Parameter = parameter;
m_Sampler = GetSamplerFromSerializedObject();
if (m_Sampler == null)
CreateSampler(typeof(UniformSampler));
var samplerName = this.Q<Label>("sampler-name");
samplerName.text = UppercaseFirstLetter(m_Property.name);
m_Properties = this.Q<VisualElement>("fields-container");
m_SamplerTypeDropdown = this.Q<ToolbarMenu>("sampler-type-dropdown");
m_SamplerTypeDropdown.text = SamplerUtility.GetSamplerDisplayName(m_Sampler.GetType());;
foreach (var samplerType in StaticData.samplerTypes)
{
var displayName = SamplerUtility.GetSamplerDisplayName(samplerType);;
m_SamplerTypeDropdown.menu.AppendAction(
displayName,
a => { ReplaceSampler(samplerType); },
a => DropdownMenuAction.Status.Normal);
}
CreatePropertyFields();
}
void ReplaceSampler(Type samplerType)
{
CreateSampler(samplerType);
m_SamplerTypeDropdown.text = SamplerUtility.GetSamplerDisplayName(samplerType);
CreatePropertyFields();
}
void CreateSampler(Type samplerType)
{
var newSampler = (ISampler)Activator.CreateInstance(samplerType);
if (newSampler is IRandomRangedSampler rangedSampler)
{
rangedSampler.baseSeed = SamplerUtility.GenerateRandomSeed();
if (m_RangeProperty != null)
rangedSampler.range = new FloatRange(
m_RangeProperty.FindPropertyRelative("minimum").floatValue,
m_RangeProperty.FindPropertyRelative("maximum").floatValue);
}
m_Sampler = newSampler;
m_Property.managedReferenceValue = newSampler;
m_Property.serializedObject.ApplyModifiedProperties();
}
void CreatePropertyFields()
{
m_RangeProperty = null;
m_Properties.Clear();
var currentProperty = m_Property.Copy();
var nextSiblingProperty = m_Property.Copy();
nextSiblingProperty.Next(false);
if (currentProperty.NextVisible(true))
{
do
{
if (SerializedProperty.EqualContents(currentProperty, nextSiblingProperty))
break;
if (currentProperty.name == "<baseSeed>k__BackingField")
{
m_Properties.Add(new RandomSeedField(currentProperty.Copy()));
}
else if (currentProperty.type == "FloatRange")
{
m_RangeProperty = currentProperty.Copy();
m_Properties.Add(new FloatRangeElement(m_RangeProperty));
}
else
{
var propertyField = new PropertyField(currentProperty.Copy());
propertyField.Bind(m_Property.serializedObject);
m_Properties.Add(propertyField);
}
}
while (currentProperty.NextVisible(false));
}
}
static string UppercaseFirstLetter(string s)
{
return string.IsNullOrEmpty(s) ? string.Empty : char.ToUpper(s[0]) + s.Substring(1);
}
ISampler GetSamplerFromSerializedObject()
{
var configType = m_Parameter.GetType();
var field = configType.GetField(m_Property.name);
return (ISampler)field.GetValue(m_Parameter);
}
}
}

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


fileFormatVersion: 2
guid: b367f8f2cb8e465ca2d60ccbd5414a14
timeCreated: 1595277943

79
com.unity.perception/Editor/Randomization/ScenarioBaseEditor.cs


using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.Perception.Randomization.Scenarios;
using UnityEngine.UIElements;
namespace UnityEngine.Perception.Randomization.Editor
{
[CustomEditor(typeof(ScenarioBase), true)]
class ScenarioBaseEditor : UnityEditor.Editor
{
ScenarioBase m_Scenario;
SerializedObject m_SerializedObject;
VisualElement m_Root;
VisualElement m_InspectorPropertiesContainer;
VisualElement m_ConstantsContainer;
SerializedProperty m_ConstantsProperty;
public override VisualElement CreateInspectorGUI()
{
m_Scenario = (ScenarioBase)target;
m_SerializedObject = new SerializedObject(m_Scenario);
m_Root = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
$"{StaticData.uxmlDir}/ScenarioBaseElement.uxml").CloneTree();
CreatePropertyFields();
CheckIfConstantsExist();
var serializeConstantsButton = m_Root.Query<Button>("serialize-constants").First();
serializeConstantsButton.clicked += () => m_Scenario.Serialize();
var deserializeConstantsButton = m_Root.Query<Button>("deserialize-constants").First();
deserializeConstantsButton.clicked += () => m_Scenario.Deserialize();
return m_Root;
}
void CreatePropertyFields()
{
m_InspectorPropertiesContainer = m_Root.Q<VisualElement>("inspector-properties");
m_InspectorPropertiesContainer.Clear();
var iterator = m_SerializedObject.GetIterator();
var foundProperties = false;
if (iterator.NextVisible(true))
{
do
{
if (iterator.name == "m_Script")
{
// Skip this property
}
else if (iterator.name == "constants")
{
m_ConstantsProperty = iterator.Copy();
}
else
{
foundProperties = true;
var propertyField = new PropertyField(iterator.Copy());
propertyField.Bind(m_SerializedObject);
m_InspectorPropertiesContainer.Add(propertyField);
}
} while (iterator.NextVisible(false));
}
if (!foundProperties)
m_InspectorPropertiesContainer.style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
}
void CheckIfConstantsExist()
{
m_ConstantsContainer = m_Root.Q<VisualElement>("constants-container");
if (m_ConstantsProperty == null)
{
m_InspectorPropertiesContainer.style.marginBottom = 0;
m_ConstantsContainer.style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
}
}
}
}

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


fileFormatVersion: 2
guid: face5e97e23d402cbf6fafadb39fa0c3
timeCreated: 1596213301

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


using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine.Perception.Randomization.Parameters;
using UnityEngine.Perception.Randomization.Samplers;
namespace UnityEngine.Perception.Randomization.Editor
{
static class StaticData
{
const string k_RandomizationDir = "Packages/com.unity.perception/Editor/Randomization";
internal const string uxmlDir = k_RandomizationDir + "/Uxml";
internal static readonly string samplerSerializedFieldType;
internal static Type[] parameterTypes;
internal static Type[] samplerTypes;
static StaticData()
{
parameterTypes = GetConstructableDerivedTypes<Parameter>();
samplerTypes = GetConstructableDerivedTypes<ISampler>();
var samplerType = typeof(ISampler);
samplerSerializedFieldType = $"{samplerType.Assembly.GetName().Name} {samplerType.FullName}";
}
static Type[] GetConstructableDerivedTypes<T>()
{
var collection = TypeCache.GetTypesDerivedFrom<T>();
var types = new List<Type>();
foreach (var type in collection)
{
if (!type.IsAbstract && !type.IsInterface)
types.Add(type);
}
return types.ToArray();
}
}
}

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


fileFormatVersion: 2
guid: 63e6a339ad0c4a2e8d110f120397a17b
timeCreated: 1595278931

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


fileFormatVersion: 2
guid: fcf9d543882d491e9b2c1e9a32f18763
timeCreated: 1590479034

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

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


fileFormatVersion: 2
guid: 5e1a10e7ee7a46898d0138a9d08615ee
timeCreated: 1589577216

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


fileFormatVersion: 2
guid: 36c3e81fb3034cce8b3f05ceac6bae70
timeCreated: 1590479019

353
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_TargetGameObjectProperty;
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_TargetGameObjectProperty = m_SerializedProperty.FindPropertyRelative("target.gameObject");
ToggleTargetContainer();
var frequencyField = this.Q<EnumField>("application-frequency");
frequencyField.BindProperty(m_SerializedProperty.FindPropertyRelative("target.applicationFrequency"));
var targetField = this.Q<ObjectField>("target");
targetField.objectType = typeof(GameObject);
targetField.value = m_TargetGameObjectProperty.objectReferenceValue;
targetField.RegisterCallback<ChangeEvent<Object>>(evt =>
{
ClearTarget();
m_TargetGameObjectProperty.objectReferenceValue = (GameObject)evt.newValue;
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_TargetGameObjectProperty.objectReferenceValue == null
? new StyleEnum<DisplayStyle>(DisplayStyle.None)
: new StyleEnum<DisplayStyle>(DisplayStyle.Flex);
}
void ClearTarget()
{
m_SerializedProperty.FindPropertyRelative("target.component").objectReferenceValue = null;
m_SerializedProperty.FindPropertyRelative("target.propertyName").stringValue = string.Empty;
m_SerializedProperty.serializedObject.ApplyModifiedProperties();
}
void SetTarget(ParameterTarget newTarget)
{
m_SerializedProperty.FindPropertyRelative("target.gameObject").objectReferenceValue = newTarget.gameObject;
m_SerializedProperty.FindPropertyRelative("target.component").objectReferenceValue = newTarget.component;
m_SerializedProperty.FindPropertyRelative("target.propertyName").stringValue = newTarget.propertyName;
m_SerializedProperty.FindPropertyRelative("target.fieldOrProperty").enumValueIndex = (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();
m_TargetPropertyMenu.text = parameter.target.propertyName == string.Empty
? "Select a property"
: TargetPropertyDisplayText(parameter.target);
var options = GatherPropertyOptions(parameter.target.gameObject, parameter.sampleType);
foreach (var option in options)
{
m_TargetPropertyMenu.menu.AppendAction(
TargetPropertyDisplayText(option),
a => { SetTarget(option); });
}
}
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)
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)
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);
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");
}
uniformToggle.RegisterCallback<ChangeEvent<bool>>(evt =>
{
ToggleProbabilityFields(evt.newValue);
});
ToggleProbabilityFields(uniformToggle.value);
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;
}
}
}

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


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<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"/>
<editor:FloatField label="p:" name="probability" tooltip="Probability" class="hide-when-uniform" style="min-width: 40px; flex-grow: 0.15;"/>
</VisualElement>
</UXML>

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


fileFormatVersion: 2
guid: 460abe2d28664087a03451ba6e6aded7
timeCreated: 1595535174

12
com.unity.perception/Editor/Randomization/Uxml/CategoricalParameterTemplate.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<Toggle label="Uniform" name="uniform"/>
<editor:IntegerField label="Seed" name="seed"/>
<VisualElement class="options-list-view">
<ListView name="options"/>
</VisualElement>
<VisualElement style="flex-direction: row; justify-content: flex-end;">
<Button name="add-option" text="Add Option" class="add-option-button"/>
<Button name="add-folder" text="Add Folder" class="add-option-button"/>
<Button name="clear-options" text="Clear Options" class="add-option-button"/>
</VisualElement>
</UXML>

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


fileFormatVersion: 2
guid: 9fa2b0cf20234dfb803b8cc006803416
timeCreated: 1595539730

11
com.unity.perception/Editor/Randomization/Uxml/FloatRangeElement.uxml


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement>
<VisualElement style="flex-direction: row; margin: 1px, 1px, 1px, 3px;">
<Label text="Range" class="unity-base-field__label" style="min-width: 147;"/>
<VisualElement class="float-range" style="flex-grow: 1; flex-direction: row;">
<editor:FloatField label="Min" tooltip="Minimum" name="minimum" style="flex-grow: 1; flex-shrink: 0; flex-basis: 0; margin-bottom: 0;"/>
<editor:FloatField label="Max" tooltip="Maximum" name="maximum" style="flex-grow: 1; flex-shrink: 0; flex-basis: 0; margin-right: 2px; margin-bottom: 0;"/>
</VisualElement>
</VisualElement>
</VisualElement>
</UXML>

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


fileFormatVersion: 2
guid: fa52ef1fb8f14ef388dbed7e2a67c570
timeCreated: 1594857611

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>

10
com.unity.perception/Editor/Randomization/Uxml/ParameterConfiguration.uxml.meta


fileFormatVersion: 2
guid: 6b8a21614fbae12468cb42ada0df200f
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

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

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


fileFormatVersion: 2
guid: be31f9fb5f9b43ad835fdcf99969b9df
timeCreated: 1589576576

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


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement name="sampler-template" style="margin-bottom: 4px;">
<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"/>
</VisualElement>
<VisualElement name="fields-container" style="margin-left: 18px;"/>
</VisualElement>
</UXML>

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


fileFormatVersion: 2
guid: e91be9c80e944358b231c125be80a749
timeCreated: 1594847524

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


<UXML xmlns="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements">
<VisualElement>
<Style src="../Uss/Styles.uss"/>
<VisualElement name="inspector-properties" style="margin-bottom: 20px;"/>
<VisualElement name="configuration-container" class="dark-viewport">
<Toggle label="Quit On Complete" tooltip="Quit the application when the scenario completes" binding-path="quitOnComplete" style="margin-left: 3px"/>
<VisualElement name="constants-container">
<editor:PropertyField binding-path="constants"/>
<editor:PropertyField name="configuration-file-name" label="Constants File Name" binding-path="serializedConstantsFileName"/>
<editor:PropertyField tooltip="Read constants from JSON when the application starts" name="deserialize-on-start" label="Deserialize On Start" binding-path="deserializeOnStart" style="padding-left: 4px;"/>
<VisualElement style="flex-direction: row;">
<Button name="serialize-constants" text="Serialize Constants" style="flex-grow: 1;"/>
<Button name="deserialize-constants" text="Deserialize Constants" style="flex-grow: 1;"/>
</VisualElement>
</VisualElement>
</VisualElement>
</VisualElement>
</UXML>

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


fileFormatVersion: 2
guid: edfeb68a9e894552845fba6fa1246b32
timeCreated: 1596213495

31
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>
</UXML>

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


fileFormatVersion: 2
guid: b5afd2495bca4fdca95b86d9113f27b2
timeCreated: 1594059945

11
com.unity.perception/Runtime/Randomization/Configuration/ParameterConfiguration.cs.meta


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

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


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

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


fileFormatVersion: 2
guid: 17957711f996479c98d1bdf7f153f791
timeCreated: 1594069464

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


using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Perception.Randomization.Parameters;
namespace UnityEngine.Perception.Randomization.Configuration
{
/// <summary>
/// Creates parameter interfaces for randomizing simulations
/// </summary>
[ExecuteInEditMode]
[AddComponentMenu("Perception/Randomization/ParameterConfiguration")]
public class ParameterConfiguration : MonoBehaviour
{
internal static HashSet<ParameterConfiguration> configurations = new HashSet<ParameterConfiguration>();
[SerializeReference] internal List<Parameter> parameters = new List<Parameter>();
/// <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="ParameterConfigurationException"></exception>
public Parameter GetParameter(string parameterName, Type parameterType)
{
foreach (var parameter in parameters)
{
if (parameter.name == parameterName && parameter.GetType() == parameterType)
return 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 parameter in parameters)
{
if (parameter.name == parameterName && parameter is T typedParameter)
return typedParameter;
}
return null;
}
string PlaceholderParameterName() => $"Parameter{parameters.Count}";
internal T AddParameter<T>() where T : Parameter, new()
{
var parameter = new T();
parameter.name = PlaceholderParameterName();
parameters.Add(parameter);
return parameter;
}
internal Parameter AddParameter(Type parameterType)
{
if (!parameterType.IsSubclassOf(typeof(Parameter)))
throw new ParameterConfigurationException($"Cannot add non-parameter types ({parameterType})");
var parameter = (Parameter)Activator.CreateInstance(parameterType);
parameter.name = PlaceholderParameterName();
parameters.Add(parameter);
return parameter;
}
internal void ApplyParameters(int seedOffset, ParameterApplicationFrequency frequency)
{
foreach (var parameter in parameters)
if (parameter.target.applicationFrequency == frequency)
parameter.ApplyToTarget(seedOffset);
}
internal void ResetParameterStates(int scenarioIteration)
{
foreach (var parameter in parameters)
parameter.ResetState(scenarioIteration);
}
internal void ValidateParameters()
{
var parameterNames = new HashSet<string>();
foreach (var parameter in parameters)
{
if (parameterNames.Contains(parameter.name))
throw new ParameterConfigurationException(
$"Two or more parameters cannot share the same name (\"{parameter.name}\")");
parameterNames.Add(parameter.name);
parameter.Validate();
}
}
void OnEnable()
{
configurations.Add(this);
}
void OnDisable()
{
configurations.Remove(this);
}
}
}

8
com.unity.perception/Runtime/Randomization/Parameters.meta


fileFormatVersion: 2
guid: 5a083fd64edd63b489c90e6e560b7b64
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
com.unity.perception/Runtime/Randomization/Samplers.meta


fileFormatVersion: 2
guid: 20888c77a2d3cdf4292a74014adb9217
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

42
com.unity.perception/Runtime/Randomization/Samplers/FloatRange.cs


using System;
using Unity.Assertions;
namespace UnityEngine.Perception.Randomization.Samplers
{
/// <summary>
/// A struct representing a continuous range of values
/// </summary>
[Serializable]
public struct FloatRange
{
/// <summary>
/// The smallest value contained within the range
/// </summary>
public float minimum;
/// <summary>
/// The largest value contained within the range
/// </summary>
public float maximum;
/// <summary>
/// Constructs a float range
/// </summary>
/// <param name="min">The smallest value contained within the range</param>
/// <param name="max">The largest value contained within the range</param>
public FloatRange(float min, float max)
{
minimum = min;
maximum = max;
}
/// <summary>
/// Assert whether this range is valid
/// </summary>
/// <exception cref="ArgumentException"></exception>
public void Validate()
{
Assert.IsTrue(minimum <= maximum);
}
}
}

3
com.unity.perception/Runtime/Randomization/Samplers/FloatRange.cs.meta


fileFormatVersion: 2
guid: 9b6ce91d860d43678056976471e0aee4
timeCreated: 1594664777

53
com.unity.perception/Runtime/Randomization/Samplers/ISampler.cs


using System;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
namespace UnityEngine.Perception.Randomization.Samplers
{
/// <summary>
/// Generates random values from probability distributions
/// </summary>
public interface ISampler
{
/// <summary>
/// Resets a sampler's state to its base random seed
/// </summary>
void ResetState();
/// <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>
void ResetState(int 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>
void Rebase(uint seed);
/// <summary>
/// Deterministically offsets a sampler's state when generating values within a batched job
/// </summary>
/// <param name="offsetIndex">
/// The index used to offset the sampler's state.
/// Typically set to either the current scenario iteration or a job's batch index.
/// </param>
void IterateState(int offsetIndex);
/// <summary>
/// Generates one sample
/// </summary>
/// <returns>The generated sample</returns>
float 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 generated samples</returns>
NativeArray<float> Samples(int sampleCount, out JobHandle jobHandle);
}
}

11
com.unity.perception/Runtime/Randomization/Samplers/ISampler.cs.meta


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

3
com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes.meta


fileFormatVersion: 2
guid: ca86ee11ed094732b0998725e06e3e4d
timeCreated: 1594925584

3
com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/ConstantSampler.cs.meta


fileFormatVersion: 2
guid: 3ce7b56509d648e8a770542d4b6daedb
timeCreated: 1594663720

3
com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/NormalSampler.cs.meta


fileFormatVersion: 2
guid: 37c6807b87e8428a844325daa345458f
timeCreated: 1594070043

3
com.unity.perception/Runtime/Randomization/Samplers/SamplerTypes/UniformSampler.cs.meta


fileFormatVersion: 2
guid: f275ac53608a4d178dd2372d3ac77632
timeCreated: 1593483623

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

正在加载...
取消
保存