浏览代码
Merge pull request #89 from Unity-Technologies/tutorial_sample_project
Merge pull request #89 from Unity-Technologies/tutorial_sample_project
Added new perception tutorial/main
GitHub
4 年前
当前提交
dd6792f9
共有 524 个文件被更改,包括 35426 次插入 和 23 次删除
-
1.gitignore
-
9README.md
-
2com.unity.perception/Documentation~/Randomization/Index.md
-
2com.unity.perception/Documentation~/Randomization/RandomizerTags.md
-
21com.unity.perception/Documentation~/SetupSteps.md
-
6com.unity.perception/Documentation~/index.md
-
2com.unity.perception/Editor/GroundTruth/PerceptionCameraEditor.cs
-
9com.unity.perception/package.json
-
409com.unity.perception/Documentation~/Tutorial/Phase1.md
-
34com.unity.perception/Documentation~/Tutorial/TUTORIAL.md
-
773com.unity.perception/Documentation~/Tutorial/Images/create_new_project.png
-
980com.unity.perception/Documentation~/Tutorial/Images/package_manager.png
-
500com.unity.perception/Documentation~/Tutorial/Images/project_folders_samples.png
-
1001com.unity.perception/Documentation~/Tutorial/Images/hierarchy.png
-
139com.unity.perception/Documentation~/Tutorial/Images/hierarchy_1.png
-
282com.unity.perception/Documentation~/Tutorial/Images/forward_renderer.png
-
323com.unity.perception/Documentation~/Tutorial/Images/forward_renderer_inspector.png
-
1001com.unity.perception/Documentation~/Tutorial/Images/exampleprefab.png
-
181com.unity.perception/Documentation~/Tutorial/Images/idlabelconfig.png
-
162com.unity.perception/Documentation~/Tutorial/Images/scenario_hierarchy.png
-
545com.unity.perception/Documentation~/Tutorial/Images/dataset_written.png
-
70com.unity.perception/Documentation~/Tutorial/Images/play.png
-
720com.unity.perception/Documentation~/Tutorial/Images/all_back_rands.png
-
618com.unity.perception/Documentation~/Tutorial/Images/back_prefab.png
-
1001com.unity.perception/Documentation~/Tutorial/Images/background_good.png
-
264com.unity.perception/Documentation~/Tutorial/Images/background_randomizer.png
-
1001com.unity.perception/Documentation~/Tutorial/Images/before_light.png
-
1001com.unity.perception/Documentation~/Tutorial/Images/camera_prep.png
-
1001com.unity.perception/Documentation~/Tutorial/Images/first_rand.png
-
772com.unity.perception/Documentation~/Tutorial/Images/jupyter1.png
-
643com.unity.perception/Documentation~/Tutorial/Images/jupyter2.png
-
328com.unity.perception/Documentation~/Tutorial/Images/object_count_plot.png
-
85com.unity.perception/Documentation~/Tutorial/Images/cloud_icon.png
-
291com.unity.perception/Documentation~/Tutorial/Images/create_proj.png
-
165com.unity.perception/Documentation~/Tutorial/Images/light_2.png
-
129com.unity.perception/Documentation~/Tutorial/Images/light_rand_1.png
-
589com.unity.perception/Documentation~/Tutorial/Images/light_rand_2.png
-
840com.unity.perception/Documentation~/Tutorial/Images/mono.png
-
426com.unity.perception/Documentation~/Tutorial/Images/runinusim.png
-
336com.unity.perception/Documentation~/Tutorial/Images/build_uploaded.png
-
112com.unity.perception/Documentation~/Tutorial/Images/usim_login.png
-
183com.unity.perception/Documentation~/Tutorial/Images/di_usim_1.png
-
1001com.unity.perception/Documentation~/Tutorial/Images/di_usim_2.png
-
191com.unity.perception/Documentation~/Tutorial/Images/di_usim_3.png
-
961com.unity.perception/Documentation~/Tutorial/Images/di_usim_4.png
-
246com.unity.perception/Documentation~/Tutorial/Images/add_comp_perc.png
-
196com.unity.perception/Documentation~/Tutorial/Images/perc_comp.png
-
1001com.unity.perception/Documentation~/Tutorial/Images/first_run.png
-
222com.unity.perception/Documentation~/Tutorial/Images/fixedscenarioempty.png
-
509com.unity.perception/Documentation~/Tutorial/Images/pc_labelers_added.png
-
487com.unity.perception/Documentation~/Tutorial/Images/pclabelconfigsadded.png
-
374com.unity.perception/Documentation~/Tutorial/Images/semseglabelconfig.png
-
281com.unity.perception/Documentation~/Tutorial/Images/signin.png
-
214com.unity.perception/Documentation~/Tutorial/Images/windowed.png
-
327com.unity.perception/Documentation~/Tutorial/Phase3.md
-
214com.unity.perception/Documentation~/Tutorial/Phase2.md
-
8com.unity.perception/Samples~/Tutorial Files.meta
-
4com.unity.perception/Samples~/Tutorial Files/.sample.json
-
8com.unity.perception/Samples~/Tutorial Files/Foreground Objects.meta
-
8com.unity.perception/Samples~/Tutorial Files/Shaders.meta
-
164com.unity.perception/Samples~/Tutorial Files/Shaders/HueShiftOpaque.shadergraph
-
10com.unity.perception/Samples~/Tutorial Files/Shaders/HueShiftOpaque.shadergraph.meta
-
8com.unity.perception/Samples~/Tutorial Files/Background Objects.meta
-
8com.unity.perception/Samples~/Tutorial Files/Background Textures.meta
-
8com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado.meta
-
674com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_001.png
-
738com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_002.png
-
973com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_003.png
-
384com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_004.png
-
675com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_005.png
-
508com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_006.png
-
935com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_007.png
-
916com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_008.png
-
428com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_009.png
-
784com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_010.png
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_001.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_002.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_003.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_004.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_005.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_006.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_007.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_008.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_009.png.meta
-
142com.unity.perception/Samples~/Tutorial Files/Background Textures/Avocado/Avocado_010.png.meta
-
8com.unity.perception/Samples~/Tutorial Files/Background Textures/Kiwi.meta
-
659com.unity.perception/Samples~/Tutorial Files/Background Textures/Kiwi/Kiwi_001.png
-
731com.unity.perception/Samples~/Tutorial Files/Background Textures/Kiwi/Kiwi_002.png
-
635com.unity.perception/Samples~/Tutorial Files/Background Textures/Kiwi/Kiwi_003.png
-
801com.unity.perception/Samples~/Tutorial Files/Background Textures/Kiwi/Kiwi_004.png
-
773com.unity.perception/Samples~/Tutorial Files/Background Textures/Kiwi/Kiwi_005.png
|
|||
|
|||
# Perception Tutorial |
|||
## Phase 1: Setup and Basic Randomizations |
|||
|
|||
In this phase of the Perception tutorial, you will start from downloading and installing Unity Editor and the Perception package. You will then use our sample assets and provided components to easily generate a synthetic dataset for training an object-detection model. |
|||
|
|||
Through-out the tutorial, lines starting with bullet points followed by **"Action:"** denote the individual actions you will need to perform in order to progress through the tutorial. This is while non-bulleted lines will provide additional context and explanation around the actions. If in a hurry, you can just follow the actions! |
|||
|
|||
Steps included this phase of the tutorial: |
|||
- [Step 1: Download Unity Editor and Create a New Project](#step-1) |
|||
- [Step 2: Download the Perception Package and Import Samples](#step-2) |
|||
- [Step 3: Setup a Scene for Your Perception Simulation](#step-3) |
|||
- [Step 4: Specify Ground-Truth and Setup Object Labels](#step-4) |
|||
- [Step 5: Add and Set-up Randomizers](#step-5) |
|||
- [Step 6: Generate and Verify Synthetic Data](#step-6) |
|||
|
|||
|
|||
### <a name="step-1">Step 1: Download Unity Editor and Create a New Project</a> |
|||
* **Action**: Navigate to [this](https://unity3d.com/get-unity/download/archive) page to download and install the latest version of Unity Editor 2020.1.x. (The tutorial has not yet been tested on newer versions.) |
|||
|
|||
An alternative approach is to first install [_**Unity Hub**_](https://unity3d.com/get-unity/download), which will allow you to have multiple versions of Unity on your computer, and make it easier to manage your Unity projects and the versions of Unity they will use. |
|||
|
|||
During the installation of Unity, you will be asked to choose which modules you would like to include. This will depend on the types of applications you eventually intend to build with your Unity installation; however, for the purposes of this tutorial, we need to make make sure _**Linux Build Support**_ is checked. In addition, if you do not already have _**Visual Studio**_ on your computer, the wizard will give you an option to install it. Go ahead and check this option, as we will need _**Visual Studio**_ for writing some simple scripts in Phase 2 of the tutorial. |
|||
|
|||
* **Action**: Make sure the _**Linux Build Support**_ and _**Visual Studio**_ installation options are checked when selecting modules during installation. |
|||
|
|||
When you first run Unity, you will be asked to open an existing project, or create a new one. |
|||
|
|||
* **Action**: Open Unity and create a new project using the Universal Render Pipeline. Name your new project _**Perception Tutorial**_, and specify a desired location as shown below. |
|||
|
|||
<p align="center"> |
|||
<img src="Images/create_new_project.png" align="center" width="800"/> |
|||
</p> |
|||
|
|||
### <a name="step-2">Step 2: Download the Perception Package and Import Samples</a> |
|||
|
|||
Once your new project is created and loaded, you will be presented with the Unity Editor interface. From this point on, whenever we refer to _**the editor**_, we mean Unity Editor. |
|||
* **Action**: From the top menu bar, open _**Window**_ -> _**Package Manager**_. |
|||
|
|||
As the name suggests, the _**Package Manager**_ is where you can download new packages, update or remove existing ones, and access a variety of information and additional actions for each package. |
|||
|
|||
* **Action**: Click on the _**+**_ sign at the top-left corner of the _**Package Manager**_ window and then choose the option _**Add package frim git URL...**_. |
|||
* **Action**: Enter the address `com.unity.perception` and click _**Add**_. |
|||
|
|||
**Note:** If you would like a specific version of the package, you can append the version to the end of the url. For example `com.unity.perception@0.1.0-preview.5`. For this tutorial, **we do not need to add a version**. You can also install the package from a local clone of the Perception repository. More inofrmation on installing local pacakges is available [here](https://docs.unity3d.com/Manual/upm-ui-local.html). |
|||
|
|||
It will take some time for the manager to download and import the package. Once the operation finishes, you will see the newly download Perception package automatically selected in the _**Package Manager**_, as depicted below: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/package_manager.png" width="600"/> |
|||
</p> |
|||
|
|||
|
|||
Each package can come with a set of samples. As seen in the righthand panel, the Perception package includes a sample named _**Tutorial Files**_, which will be required for completing this tutorial. The sample files consist of example foreground and background objects, randomizers, shaders, and other useful elements to work with during this tutorial. **Foreground** objects are those thatthe eventual machine learning model will try to detect, and **background** objects will be placed in the background as distractors for the model. |
|||
|
|||
* **Action**: In the _**Package Manager**_ window, from the list of _**Samples**_ for the Perception package, click on the _**Import into Project**_ button for the sample named _**Tutorial Files**_. |
|||
|
|||
Once the sample files are imported, they will be placed inside the `Assets/Samples/Perception` folder in your Unity project. You can view your project's folder structure and access your files from the _**Project**_ tab of the editor, as seen in the image below: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/project_folders_samples.png" width="600"/> |
|||
</p> |
|||
|
|||
* **Action**: The _**Project**_ tab contains a search bar; use it to find the file named `ForwardRenderer.asset`, as shown below: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/forward_renderer.png"/> |
|||
</p> |
|||
|
|||
* **Action**: Click on the found file to select it. Then, from the _**Inspector**_ tab of the editor, click on the _**Add Renderer Feature**_ button, and select _**Ground Truth Renderer Feature**_ from the dropdown menu: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/forward_renderer_inspector.png" width="400"/> |
|||
</p> |
|||
|
|||
This step prepares your project to render tailor-made images that will be later used for labeling the generated synthetic data. |
|||
|
|||
### <a name="step-3">Step 3: Setup a Scene for Your Perception Simulation</a> |
|||
Simply put, in Unity, Scenes contain any object that exists in the world. This world can be a game, or in this case, a perception-oriented simulation. Every new project contains a Scene named `SampleScene`, which is automatically openned when the project is created. This Scenes comes with several objects and settings that we do not need, so let's create a new one. |
|||
|
|||
* **Action**: In the _**Project**_ tab, right-click on the `Assets/Scenes` folder and click _**Create -> Scene**_. Name this new Scene `TutorialScene` and double-click on it to open it. |
|||
|
|||
The _**Hierarchy**_ tab of the editor displays all the Scenes currently loaded, and all the objects currently present in each loaded Scene, as shown below: |
|||
<p align="center"> |
|||
<img src="Images/hierarchy.png" width="700"/> |
|||
</p> |
|||
|
|||
As seen above, the new Scene already contains a camera (`Main Camera`) and a light (`Directional Light`). We will now modify the camera's field of view and position to prepare it for the tutorial. |
|||
|
|||
* **Action**: Click on `Main Camera` and in the _**Inspector**_ tab, modify the camera's `Position`, `Rotation`, `Projection` and `Size` to match the screenshot below. (Note that `Size` only becomes available once you set `Projection` to `Orthographic`) |
|||
|
|||
<p align="center"> |
|||
<img src="Images/camera_prep.png"/> |
|||
</p> |
|||
|
|||
|
|||
For this tutorial, we prefer our light to not cast any shadows, therefore: |
|||
|
|||
* **Action**: Click on `Directional Light` and in the _**Inspector**_ tab, set `Shadow Type` to `No Shadows`. |
|||
|
|||
We will now add the necessary components to the camera in order to equip it for the perception workflow. To do this, we need to add a `PerceptionCamera` component to it, and then define which types of ground-truth we wish to generate using this camera. |
|||
|
|||
* **Action**: Select `Main Camera` again and in the _**Inspector**_ tab, click on the _**Add Component**_ button. |
|||
* **Action**: Start typing `Perception Camera` in the search bar that appears, until the `Perception Camera` script is found, with a **#** icon to the left: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/add_comp_perc.png" width="400"/> |
|||
</p> |
|||
|
|||
* **Action**: Click on this script to add it as a component. Your camera is now a `Perception` camera. |
|||
|
|||
Adding components is the standard way in which objects can have various kinds of logic and data attached to them in Unity. This includes objects placed within the Scene (called GameObjects), such as the camera above, or objects outside of a Scene, in your project folders (called Prefabs). |
|||
|
|||
The `Perception Camera` component comes with its own UI to modify various aspects of synthetic frame generation and annotation, as well as add or remove ground-truth |
|||
labelers and labelling configurations: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/perc_comp.png" width="400"/> |
|||
</p> |
|||
|
|||
If you hover your mouse pointer over each of the fields shown (e.g. `Capture Interval`), you will see a tooltip popup with an explanation on what the item controls. You may see a warning at the bottom of this UI regarding asynchronous shader compilation. If so, follow the instructions in the warning message to disable this functionality and remove the warning. |
|||
|
|||
As seen in the UI for `Perception Camera`, the list of `Camera Lebelers` is currently empty. For each type of ground-truth you wish to generate along-side your captured frames (e.g. 2D bounding boxes around objects), you will need to add a corresponding `Camera Labeler` to this list. |
|||
|
|||
To speed-up your perception workflow, the Perception package comes with four common labelers for object-detection tasks; however, if you are comfortable with code, you can also add your own custom labelers. The labelers that come with the Perception package cover **2D bounding boxes, object counts, object information (pixel counts and ids), and semantic segmentation images (each object rendered in a unique colour)**. |
|||
|
|||
* **Action**: Click on the _**+**_ button to the bottom right corner of the empty labeler list, and select `BoundingBox2DLabeler`. |
|||
* **Action**: Repeat the above step to add `ObjectCountLabeler`, `RenderedObjectInfoLabeler`, `SemanticSegmentationLabeler`. |
|||
|
|||
Once you add the labelers, the _**Inspector**_ view of the `Perception Camera` component will look like this: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/pc_labelers_added.png" width="400"/> |
|||
</p> |
|||
|
|||
|
|||
One of the useful features that comes with the `Perception Camera` component is the ability to display real-time visualizations of the labelers when your simulation is running. For instance, `BoundingBox2DLabeler` can display bounding boxes around the foreground objects that it tracks in real-time and `SemanticSegmentationLabeler` displays the semantic segmentation image overlaid on top of the camera's view . To enable this feature, make sure the `Show Labeler Visualizations` checkmark is enabled. |
|||
|
|||
### <a name="step-4">Step 4: Specify Ground-Truth and Setup Object Labels</a> |
|||
|
|||
It is now time to tell each labeler added to the `Perception Camera` which objects it should label in the generated dataset. For instance, if your workflow is intended for generating frames and ground-truth for detecting chairs, your labelers would need to know that they should look for objects labeled "chair" within the scene. The chairs should in turn also be labeled "chair" in order to make them visible to the labelers. We will now learn how to set-up these configuartions. |
|||
|
|||
You will notice each added labeler has a field named `Id Label Config`. By adding a label configuration here you can instruct the labeler to look for certain labels within the scene and ignore the rest. To do that, we should first create label configurations. |
|||
|
|||
* **Action**: In the _**Project**_ tab, right-click the `Assets` folder, then click _**Create -> Perception -> Id Label Config**_. |
|||
|
|||
This will create a new asset file named `IdLabelConfig` inside the `Assets` folder. |
|||
|
|||
* **Action**: Rename the newly created `IdLabelConfig` asset to `TutorialIdLabelConfig`. |
|||
|
|||
Then, click on this asset to bring up its _**Inspector**_ view. In there, you can specify the labels that this config will keep track of. A new label config like this one contains an empty list of labels. |
|||
|
|||
In this tutorial, we will generate synthetic data intended for detecting 10 everyday grocery items. Thus, in this step, you will add labels for each of these 10 items to the list of labels for `TutorialIdLabelConfig`. |
|||
|
|||
* **Action**: Select `TutorialIdLabelConfig` and in the _**Inspector**_ tab, click on the _**+**_ button to add 10 new label entries. Use the following exact names for these entries: |
|||
|
|||
1 `candy_minipralines_lindt` |
|||
|
|||
2 `cereal_cheerios_honeynut` |
|||
|
|||
3 `cleaning_snuggle_henkel` |
|||
|
|||
4 `craft_yarn_caron` |
|||
|
|||
5 `drink_greentea_itoen` |
|||
|
|||
6 `drink_whippingcream_lucerne` |
|||
|
|||
7 `lotion_essentially_nivea` |
|||
|
|||
8 `pasta_lasagne_barilla` |
|||
|
|||
9 `snack_biscotti_ghiott` |
|||
|
|||
10 `snack_granolabar_naturevalley` |
|||
|
|||
|
|||
Once done, the _**Inspector**_ window for `TutorialIdLabelConfig` will look like this: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/idlabelconfig.png" width="400"/> |
|||
</p> |
|||
|
|||
These are the names of the 10 grocery items that we will work with in this tutorial. Wonder were the actual objects are? They were imported into your project when you imported the tutorial files from the _**Package Manager**_, and are located in the folder `Assets/Samples/Perception/0.5.0-preview.1/Tutorial Files/Foreground Objects/Phase 1/Prefabs` . |
|||
|
|||
Notice that each of the labels you entered automatically has a numerical ID assigned. These ids are required in order to use the generated data in machine learning models, which typically require numerical ids for classification of objects. |
|||
|
|||
The label configuration we have created is compatible with three of the four labelers we plan to attach to our `Perception Camera`. However, `SemanticSegmentationLabeler` requires a different kind of label configuration which includes unique colors for each label instead of numerical IDs. This is because the output of this labeler are images in which each visibile foreground object is painted in a unique color. |
|||
|
|||
* **Action**: In the _**Project**_ tab, right-click the `Assets` folder, then click _**Create -> Perception -> Semantic Segmentation Label Config**_. Name this asset `TutorialSemanticSegmentationLabelConfig`. |
|||
* **Action**: Add the same 10 labels from the above list to this new label configuration. Note how this time they each get a new unique color instead of a number: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/semseglabelconfig.png" width="400"/> |
|||
</p> |
|||
|
|||
Now that you have created your label configurations, we need to assign them to labelers that you previously added to your `Perception Camera` component. |
|||
|
|||
* **Action**: Select the `Main Camera` object from the Scene _**Hierarchy**_, and in the _**Inspector**_ tab, assign the newly created `TutorialIdLabelConfig` to the first three labelers. To do so, you can either drag and drop the former into the corresponding fields for each labeler, or click on the small circular button in front of the `Id Label Config` field, which brings up an asset selection window filtered to only show compatible assets. Assign `TutorialSemanticSegmentationLabelConfig` to the fourth labeler. The `Perception Camera` component will now look like the image below: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/pclabelconfigsadded.png" width="400"/> |
|||
</p> |
|||
|
|||
The final piece of the label set-up workflow is to assign the same 10 labels to the objects that are supposed to be detected by an eventual object-detection model. As mentioned above, these are located at `Assets/Samples/Perception/0.5.0-preview.1/Tutorial Files/ Foreground Objects/Phase 1/Prefabs`. |
|||
|
|||
In Unity, Prefabs are essentially reusable GameObjects that are stored to disk, along with all their child GameObjects, components, and property values. Let's see what our sample prefabs include. |
|||
|
|||
* **Action**: In the _**Project**_ tab, navigate to `Assets/Samples/Perception/0.5.0-preview.1/Tutorial Files/ Foreground Objects/Phase 1/Prefbas` |
|||
* **Action**: Double click the file named `drink_whippingcream_lucerne.prefab` to open the Prefab asset. |
|||
|
|||
When you open the Prefab asset, you will see the object shown in the Scene tab and its components shown on the right side of the editor, in the _**Inspector**_ tab: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/exampleprefab.png"/> |
|||
</p> |
|||
|
|||
The Prefab contains a number of components, including a `Transform`, a `Mesh Filter`, a `Mesh Renderer` and a `Labeling` component (highlighted in the image above). While the first three of these are common Unity components, the fourth one is specific to the Perception package, and is used for assigning labels to objects. You can see here that the cream carton is already labeled `drink_whippingcream_lucerner`. This is true for all the foreground objects supplied in the sample tutorial files in order to save time, which means you do not need to perform any additonal steps to label your foreground objects. However, adding a label to a prefab would be as simple as clicking _**Add Component**_ and adding the `Labeling` script, then typing the label in. |
|||
|
|||
Note that each object can have multiple labels assigned, and thus appear as different objects to labelers with different label configurations. For instance, you may want your semantic segmentation labeler to detect all cream cartons as `dairy_product`, while your bounding box labeler still distinguishes between different types of dairy product. To achieve this, you can add a `dairy_product` label to all your dairy products, and then in your label configuration for semantic segmentation, only add the `dairy_product` label, and not any specific products or brand names. To add an additional label to the cream carton, you can click on the _**+**_ button to the bottom right corner of the label list, in the `Labeling` component. |
|||
|
|||
### <a name="step-5">Step 5: Add and Set-up Randomizers</a> |
|||
|
|||
As mentioned earlier, one of the core ingredients of the perception workflow is the randomization of various aspects of the simulation, in order to introduce sufficient variation into the generated data. |
|||
|
|||
To start randomizing your simulation you will first need to add a `Scenario` to your scene. Scenarios control the execution flow of your simulation by coordinating all `Randomizer` components added to them. The Perception package comes with a useful set of Randomizers that let you quickly place your foreground objects in the Scene, generate varied backgrounds, as well as randomize various parameters of the simulation over time, including things such as positon, scale, and rotation of objects, number of objects within the camera's view, and so on. Randomizers achieve this through coordinating a number of `Parameter`s, which essentially define the most granular randomization behaviors. For instance, for continuous variable types such as floats, vectors, and colors, Parameters can define the range, sampling distribution, and seed for randomization. This is while another class of Paramters let you randomly select one out of a number of categorical options. |
|||
|
|||
To summarize, a sample `Scenario` could look like this: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/scenario_hierarchy.png" width = "300"/> |
|||
</p> |
|||
|
|||
|
|||
In this tutorial, you will learn how to use the provided Randomizers, as well as how to create new ones that are custom-fitted to your randomization needs. |
|||
|
|||
* **Action**: Create a new GameObject in your Scene by right-clicking in the _**Hierarchy**_ tab and clicking `Create Empty`. |
|||
* **Action**: Rename your new GameObject to `Simulation Scenario`. |
|||
* **Action**: In the _**Inspector**_ view of this new object, add a new `Fixed Length Scenario` component. |
|||
|
|||
Each `Scenario` executes a number of `Iteration`s, and each Iteration carries on for a number of frames. These are timing elements you can leverage in order to customize your Scenarios and the timing of your randomizations. You will learn how to use Iteartions and frames in Phase 2 of this tutorial. For now, we will use the `Fixed Length Scenario`, which is a special kind of Scenario that runs for a fixed number of frames during each Iteration, and is sufficient for many common use-cases. Note that at any given time, you can have only one Scenario active in your Scene. |
|||
|
|||
The _**Inspector**_ view of `Fixed Length Scenario` looks like below: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/fixedscenarioempty.png" width = "400"/> |
|||
</p> |
|||
|
|||
There are a number settings and properties you can modify here. `Quit On Complete` instructs the simulation to quit once this Scenario has completed executing. We can see here that the Scenario has been set to run for 100 Iterations, and that each Iteration will run for one frame. But this is currently an empty `Scneario`, so let's add some Randomizers. |
|||
|
|||
* **Action**: Click _**Add Randomizer**_, and from the list choose `BackgroundObjectPlacementRandomizer`. |
|||
|
|||
This Randomizer uses Poisson-Disk sampling to select random positions from a given area, and spawn copies of randomly selected Prefabs (from a given list) at the chosen positions. We will use this component to generate a background that will act as a distraction for our eventual object-detection machine learning model. |
|||
|
|||
* **Action**: Click _**Add Folder**_, and from the file explorer window that opnes, choose the folder `Assets/Samples/Perception/0.5.0-preview.1/Tutorial Files/Background Objects/Prefabs`. |
|||
|
|||
The beckground Prefabs are primitve shapes devoid of color or texture. Later Randomizers will take care of those aspects. |
|||
|
|||
* **Action**: Set the rest of the properties (except for `Seed`) according to the image below. The `Seed` attribute is the seed used for the underlying random sampler, and does not need to match the image shown. |
|||
|
|||
<p align="center"> |
|||
<img src="Images/background_randomizer.png" width = "400"/> |
|||
</p> |
|||
|
|||
* **Action**: Click on the **▷** (play) button located at top middle section of the editor to run your simulation. |
|||
|
|||
<p align="center"> |
|||
<img src="Images/play.png" width = "500"/> |
|||
</p> |
|||
|
|||
When the simulation starts running, Unity Editor will switch to the _**Game**_ tab to show you the output of the active camera, which carries the `Perception Camera` component: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/first_run.png" width = "700"/> |
|||
</p> |
|||
|
|||
In this view, you will also see the real-time visualizations we discussed before shown on top of the camera's view. In the top right corner of the window, you can see a visualization control panel, through which you can enable or disable visualizations for individual labelers. That said, we currently have no foreground objects in the Scene yet, so no bounding boxes or semantic segmentations will be displayed. |
|||
|
|||
Note that disabling visualizations for a labeler does not affect your generated data. The annotations from all labelers that are active before running the simulation will continue to be recorded and will appear in the output data. |
|||
|
|||
To generate data as fast as possible, the simulation utilizes asynchronous processing to churn through frames quickly, rearranging and randomizing the objects in each frame. To be able to check out individual frames and inspect the real-time visualizations, click on the pause button (next to play). You can also switch back to the Scene view to be able to inspect each object individually. For performance reasons, it is recommended to disable visualizations altogether (from the _**Inspector**_ view of `Perception Camera`) once you are ready to generate a large dataset. |
|||
|
|||
As seen in the image above, what we have now is just a beige-colored wall of shapes. This is because so far we are only spawning them, and the beige color of our light is what gives them their current look. To make this background more useful, let's add a couple more `Randomizers`. |
|||
|
|||
* **Action**: Repeat the previous steps to add `TextureRandomizer`, `HueOffsetRandomizer`, and `RotationRandomizer`. |
|||
|
|||
`TextureRandomizer` will have the task of attaching random textures to our colorless background objects at each Iteration of the Scenario. Simlarly, `HueOffsetRandomizer` will alter the color of the objects, and `RotationRandomizer` will give the objects a new random rotation each Iteration. |
|||
|
|||
* **Action**: In the UI snippet for `TextureRandomizer`, click _**Add Folder**_ and choose `Assets/Samples/Perception/0.5.0-preview.1/Tutorial Files/Background Textures`. |
|||
|
|||
* **Action**: In the UI snippet for `RotationRandomizer`, change all the maximum values for the three ranges to `360` and leave the minimums at `0`. |
|||
|
|||
Your list of Randomizers should now look like the screenshot below: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/all_back_rands.png" width = "400"/> |
|||
</p> |
|||
|
|||
Note that the `Seed` values do not need to match the image above. |
|||
|
|||
There is one more important thing left to do, in order to make sure all the above Randomizers operate as expected. Since `BackgroundObjectPlacementRandomizer` spawns objects, it already knows which objects in the Scene it is dealing with; however, the rest of the Randomizers we added are not yet aware of what objects they should target because they don't spawn their own objects. |
|||
|
|||
To make sure each Randomizer knows which objects it should work with, we will use an object tagging and querying workflow that the bundled Randomizers already use. Each Randomizer can query the Scene for objects that carry certain types of `RandomizerTag` components. For instance, the `TextureRandomizer` queries the Scene for objects that have a `TextureRandomizerTag` component (you can change this in code!). Therefore, in order to make sure our background Prefabs are affected by the `TextureRandomizer` we need to make sure they have `TextureRandomizerTag` attached to them. |
|||
|
|||
* **Action**: In the _**Project**_ tab, navigate to `Assets/Samples/Perception/0.5.0-preview.1/Tutorial Files/Background Objects/Prefabs`. |
|||
* **Action**: Select all the files inside and from the _**Inspector**_ tab add a `TextureRandomizerTag` to them. This will add the component to all the selected files. |
|||
* **Action**: Repeat the above step to add `HueOffsetRandomizerTag` and `RotationRandomizerTag` to all selected Prefabs. |
|||
|
|||
Once the above step is done, the _**Inspector**_ tab for a background Prefab should look like this: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/back_prefab.png" width = "400"/> |
|||
</p> |
|||
|
|||
If you run the simulation now you will see the generated backgrounds look much more colourful and distracting! |
|||
|
|||
<p align="center"> |
|||
<img src="Images/background_good.png" width = "700"/> |
|||
</p> |
|||
|
|||
It is now time to spawn and randomize our foregournd objects. We are getting close to generating our first set of synthetic data! |
|||
|
|||
* **Action**: Add `ForegroundObjectPlacementRandomizer` to your list of Randomizers. Click _**Add Folder**_ and select `Assets/Samples/Perception/0.5.0-preview.1/Tutorial Files/Foreground Objects/Phase 1/Prefabs`. |
|||
* **Action**: Set these values for the above Randomizer: `Depth = 3, Separation Distance = 1.5, Placement Area = (5,5)`. |
|||
|
|||
This Randomizer uses the same algorithm as the one we used for backgrounds; however, it is defined in a separate C# class because you can only have **one of each type of Randomizer added to your Scenario**. Therefore, this is our way of differentating between how background and foreground objects are treated. |
|||
|
|||
While the texture and color of the foreground objects will be constant during the simulation, we would like their rotation to be randomized similar to the background Prefabs. To achieve this: |
|||
|
|||
* **Action**: From the _**Project**_ tab select all the foreground Prefabs located in `Assets/Samples/Perception/0.5.0-preview.1/Tutorial Files/Foreground Objects/Phase 1/Prefabs`, and add a `RotationRandomizerTag` component to them. |
|||
|
|||
The last step here is to make sure the order of randomizations is correct. Randomizers execute according to their order within the list of Randomizers added to your Scenario. If you look at the list now, you will notice that `ForegroundObjectPlacementRandomizer` is coming after `RotationRandomizer`, therefore, foreground objects will NOT be included in the rotation randomizations, even though they are carrying the proper tag. To fix that: |
|||
|
|||
* **Action**: Drag `ForegroundObjectPlacementRandomizer` and drop it above `RotationRandomizer`. |
|||
|
|||
### <a name="step-6">Step 6: Generate and Verify Synthetic Data</a> |
|||
|
|||
You are now ready to generate your first dataset. Our current set-up will produce 100 frames of annotated captures. |
|||
|
|||
* **Action** Click **▷** (play) again and this time let the simulation finish. This should take only a few seconds. |
|||
|
|||
While the simulation is running, your _**Game**_ view will quickly generate frames similar to the gif below (visualization for `SemanticSegmentationLabeler` is disabled here): |
|||
|
|||
<p align="center"> |
|||
<img src="Images/generation1.gif" width = "700"/> |
|||
</p> |
|||
|
|||
|
|||
Once the run is complete, you will see a message in the _**Console**_ tab of the editor, with information on where the generated data has been saved. An example is shown below (Mac OS): |
|||
|
|||
<p align="center"> |
|||
<img src="Images/dataset_written.png"/> |
|||
</p> |
|||
|
|||
* **Action**: Navigate to the dataset path addressed in the _**Console**_. |
|||
|
|||
In this folder, you will find a few types of data, depending on your `Perception Camera` settings. These can include: |
|||
- Logs |
|||
- JSON data |
|||
- RGB images (raw camera output) (if the `Save Camera Output to Disk` checkmark is enabled on `Perception Camera`) |
|||
- Semantic segmentation images (if the `SemanticSegmentationLabeler` is added and active on `Perception Camera`) |
|||
|
|||
The output dataset includes a variety of information about different aspects of the active sensors in the Scene (currently only one), as well as the ground-truth generated by all active labelers. [This page](https://github.com/Unity-Technologies/com.unity.perception/blob/master/com.unity.perception/Documentation%7E/Schema/Synthetic_Dataset_Schema.md) provides a comprehensive explanation on the schema of this dataset. We strongly recommend having a look at the page once you have completed this tutorial. |
|||
|
|||
* **Action**: To get a quick feel of how the data is stored, open the folder whose name starts with `Dataset`, then open the file named `captures_000.json`. This file contains the output from `BoundingBox2DLabeler`. The `captures` array contains the position and rotation of the sensor (camera), the position and rotation of the ego (sensor group, currently only one), and the annotations made by `BoundingBox2DLabeler` for all visible objects defined in its label configuration. For each visibile object, the annotations include: |
|||
* `label_id`: The numerical id assigned to this object's label in the labeler's label configuration |
|||
* `label_name`: The object's label, e.g. `candy_minipralines_lindt` |
|||
* `instance_id`: Unique instance id of the object |
|||
* `x` and `y`: Pixel coordinates of the top-left corner of the object's bounding box (measured from the top-left corner of the image) |
|||
* `width` and `height` of the object's bounding box |
|||
|
|||
|
|||
To verify and analyze a variety of metrics for the generated data, such as number of foreground objects in each frame and degree of representation for each foreground object (label), we will now use Unity's Dataset Insights framework. This will involve running a Jupyter notebook which is conveniently packaged within a Docker file that you can download from Unity. |
|||
|
|||
* **Action**: Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop) |
|||
* **Action**: Open a command line interface (Command Prompt on Windows, Terminal on Mac OS, etc.) and type the following command to run the Dataset Insights Docker image: |
|||
`docker run -p 8888:8888 -v <path to synthetic data>:/data -t unitytechnologies/datasetinsights:latest`, where the path to data is what we earlier found in Unity's console messages. |
|||
|
|||
This will download a Docker image from Unity. If you get an error regarding the path to your dataset, make sure you have not included the enclosing `<` and `>` in the path and that the spaces are properly escaped. |
|||
|
|||
* **Action**: The image is now running on your computer. Open a web browser and navigate to `http://localhost:8888` to open the Jupyter notebook: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/jupyter1.png"/> |
|||
</p> |
|||
|
|||
* **Action**: To make sure your data is properly mounted, navigate to the `data` folder. If you see the dataset's folders there, we are good to go. |
|||
* **Action**: Navigate to the `datasetinsights/notebooks` folder and open `Perception_Statistics.ipynb`. |
|||
* **Action**: Once in the notebook, replace the `<GUID>` in the `data_root = /data/<GUID>` line with the name of the dataset folder inside your generated data. For example `data_root = /data/Dataseta26351bc-1b72-46c5-9e0c-d7afd6df2974`. |
|||
|
|||
<p align="center"> |
|||
<img src="Images/jupyter2.png"/> |
|||
</p> |
|||
|
|||
This notebook contains a variety of functions for generating plots, tables, and bounding box images that help you analyze your generated dataset. Certain parts of this notebook are currently not of use to us, such as the code meant for downloading data generated through Unity Simulation (coming later in this tutorial). |
|||
|
|||
Each of the code blocks in this notebook can be executed by clicking on them to select them, and the clicking the _**Run**_ button at the top of the notebook. When you run a code block, an **asterisk (\*)** will be shown next to it on the left side, until the code finishes executing. |
|||
|
|||
Below, you can see a sample plot generated by the Dataset Insights notebook, depicting the number of times each of the 10 foreground objects appeared in the dataset. As shown in the histogram, there is a high level of uniformity between the labels, which is a desirable outcome. |
|||
|
|||
|
|||
<p align="center"> |
|||
<img src="Images/object_count_plot.png" width="600"/> |
|||
</p> |
|||
|
|||
|
|||
* **Action**: Follow the instructions laid out in the notebook and run each code block to view its outputs. |
|||
|
|||
This concludes Phase 1 of the Perception tutoial. In the next phase, you will dive a little bit into randomization code and learn how to build your own custom Randomizer. [Click here to continue to Phase 2: Custom Randomizations](Phase2.md) |
|
|||
<img src="../images/unity-wide.png" align="middle" width="3000"/> |
|||
|
|||
# Perception Tutorial |
|||
|
|||
The Perception package offers a variety of tools for generating synthetic datasets intended for use in perception-based machine learning tasks, such as object detection, semantic segmentation, and so on. These datasets are in the form of **frames** captured using simulated sensors. These frames are **annotated** with **ground-truth**, and are thus ready to be used for training and validating machine learning models. While the type of ground-truth bundled with this data will depend on your intended machine learning task, the Perception package already comes with a number of common ground-truth labelers which will make it easier for you to generate synthetic data. This tutorial will guide you all the way from setting up Unity on your computer to generating a large-scale synthetic dataset for training an object-detection model. |
|||
|
|||
While this process may sound complicated, **you do not need to have any prior experience with Unity or C# coding** in order to follow the first phase of this tutorial and generate a dataset using our provided samples and components. The tutorial will be divided into three high-level phases based on the complexity of the tasks involved. During these phases, you will be gradually introduced to more advanced tools and workflows that the Perception package enables you to perform. |
|||
|
|||
## [Phase 1: Setup and Basic Randomizations](Phase1.md) |
|||
|
|||
This phase will cover essential tasks and skills such as: |
|||
* Downloading Unity Editor and the Perception package |
|||
* Fundamental interactions with Unity Editor (importing sample assets into your Unity project, working with prefabs and scenes, adding components to objects and prefabs, etc.) |
|||
* Learning about essential components of the Perception package and creating a basic simulation with these essential elements. |
|||
* Running your simulations on your computer and observing real-time visualizations of the ground-truth labelers. |
|||
* Finding the synthetic data generated from your simulation and understanding its various pieces. |
|||
* Using _**Dataset Insights**_ to generate statistics and visualizations for your synthetic data (e.g. number of objects in each frame, presence of each object in the whole data, etc.) |
|||
|
|||
## [Phase 2: Custom Randomizations](Phase2.md) |
|||
|
|||
In order to get the best out of comptuer vision models, the training data needs to contain a large-degree of variation. This is achieved through randomizing various aspects of your simulation between captured frames. While you will use basic randomizations in Phase 1, Phase 2 of the tutorial will help you learn how to randomize your simulations in more complex ways by guiding you through writing your first customized randomizer in C# code. Once you complete this phase, you will know how to: |
|||
* Create custom randomizers by extending our provided samples. |
|||
* Coordinate the operation of several randomizers by specifying their order of execution and the objects they affect. |
|||
* Have objects specify criteria (e.g. ranges, means, etc.) and logic (e.g. unique behaviors) for their randomizable attributes. |
|||
|
|||
## [Phase 3: Cloud](Phase3.md) |
|||
|
|||
You will generally require a large amount of data to train your computer vision model. Generating data in these practical sizes will take incredible amounts of time to finish if performed on typical workstation computers. This is where the cloud comes in. In this phase, you will learn how to: |
|||
* Generate large-scale synthetic datasets containing hundreds of thousands of frames by leveraging the power of **Unity Simulation** (USim). |
|||
* Keep track of your USim runs using the USim command-line interface (USim-CLI). |
|||
* Use Dataset Insights to download and analyze your cloud-generated data. |
|||
|
|||
|
|||
[Continue to Phase 1: Setup and Basic Randomizations](Phase1.md) |
773
com.unity.perception/Documentation~/Tutorial/Images/create_new_project.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.perception/Documentation~/Tutorial/Images/hierarchy.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.perception/Documentation~/Tutorial/Images/exampleprefab.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.perception/Documentation~/Tutorial/Images/background_good.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.perception/Documentation~/Tutorial/Images/before_light.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.perception/Documentation~/Tutorial/Images/camera_prep.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.perception/Documentation~/Tutorial/Images/first_rand.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
328
com.unity.perception/Documentation~/Tutorial/Images/object_count_plot.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.perception/Documentation~/Tutorial/Images/di_usim_2.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
961
com.unity.perception/Documentation~/Tutorial/Images/di_usim_4.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
1001
com.unity.perception/Documentation~/Tutorial/Images/first_run.png
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
# Perception Tutorial |
|||
## Phase 3: Cloud |
|||
|
|||
In this phase of the tutorial, we will learn how to run our Scene on _**Unity Simulation (USim)**_ and analyze the generated dataset using _**Dataset Insights**_. USim will allow us to generate a much larger dataset than what is typically plausible on a workstation computer. |
|||
|
|||
Steps included this phase of the tutorial: |
|||
- [Step 1: Setup Unity Account, USim, and Cloud Project](#step-1) |
|||
- [Step 2: Run Project on USim](#step-2) |
|||
- [Step 3: Keep Track of USim Runs Using USim-CLI](#step-3) |
|||
- [Step 4: Analyze the Dataset using Dataset Insights](#step-4) |
|||
|
|||
### <a name="step-1">Step 1: Setup Unity Account, USim, and Cloud Project</a> |
|||
|
|||
In order to use Unity Simulation you need to first create a Unity account or login with your existing one. Once logged in, you will also need to sign-up for Unity Simulation. |
|||
|
|||
* **Action** Click on the _**Cloud**_ button at the top-right corner of Unity Editor to open the _**Services**_ tab. |
|||
|
|||
<p align="center"> |
|||
<img src="Images/cloud_icon.png" width="400"/> |
|||
</p> |
|||
|
|||
If you have not logged in yet, the _**Services**_ tab will display a message noting that you are offline: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/signin.png" width="400"/> |
|||
</p> |
|||
|
|||
* **Action**: Click _**Sign in...**_ and follow the steps in the window that opens to sign in or create an account. |
|||
* **Action**: Sign up for a free trial of Unity Simulation [here](https://unity.com/products/unity-simulation). |
|||
|
|||
Unity Simulation is a cloud-based service that makes it possible for you run thousands of instances of Unity builds in order to generate massive amounts of data. The USim service is billed on a per-usage basis, and the free trial offers up to $100 of free credit per month. In order to access the free trial, you will need to provide credit card information. **This information will be used to charge your account if you exceed the $100 monthly credit.** A list of hourly and daily rates for various computational resources is available in the page where you first register for USim. |
|||
|
|||
Once you have registered for a free trial, you will be taken to your USim dashboard, where you will be able to observe your usage and billing invoices. |
|||
|
|||
It is now time to connect your local Unity project to a cloud project. |
|||
|
|||
* **Action**: Return to Unity Editor. In the _**Services**_ tab click _**Select Organization**_ and choose the only available option (which typically has the same name as your Unity username). |
|||
|
|||
If you have used Unity before, you might have set-up multiple organizations for your account. In that case, choose whichever you would like to associate with this project. |
|||
|
|||
<p align="center"> |
|||
<img src="Images/create_proj.png" width="400"/> |
|||
</p> |
|||
|
|||
* **Action**: Click _**Create**_ to create a new cloud project and connect your local project to it. |
|||
|
|||
### <a name="step-2">Step 2: Run Project on USim</a> |
|||
|
|||
The process of running a project on Unity Simulation involves building it for Linux and then uploading this build, along with a set of parameters, to Unity Simulation. The Perception package simplifies this process by including a dedicated _**Run in USim**_ window that accepts a small number of required parameters and handles everything else automatically. |
|||
|
|||
For performance reasons, it is best to disable real-time visualizations before carrying on with the USim run. |
|||
|
|||
* **Action**: From the _**Inspector**_ view of `Perception Camera`, disable real-time visualizations. |
|||
|
|||
In order to make sure our builds are compatible with USim, we need to set our project's scripting backend to _**Mono**_ rather than _**IL2CPP**_. The latter is the default option for projects created with newer versions of Unity, so we need to change it. We will also need to switch to _**Windowed**_ mode. |
|||
|
|||
* **Action**: From the top menu bar, open _**Edit -> Project Settings**_. |
|||
* **Action**: In the window that opens, navigate to the _**Player**_ tab, find the _**Scripting Backend**_ setting (under _**Other Settings**_), and change it to _**Mono**_: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/mono.png"/> |
|||
</p> |
|||
|
|||
* **Action**: Change _**Fullscreen Mode**_ to _**Windowed**_ and set a width and height of 800 by 600. |
|||
|
|||
<p align="center"> |
|||
<img src="Images/windowed.png" width="600"/> |
|||
</p> |
|||
|
|||
* **Action**: Close _**Project Settings**_. |
|||
* **Action**: From the top menu bar, open _**Window -> Run in USim**_. |
|||
|
|||
<p align="center"> |
|||
<img src="Images/runinusim.png" width="600"/> |
|||
</p> |
|||
|
|||
* **Action**: Choose `TutorialScene` (which is the Scene we have been working in) as your _**Main Scene**_ and the `SimulationScenario` object as your _**Scenario**_. |
|||
|
|||
Here, you can also specify a name for the run, the number of iterations the Scenario will execute for, and the number of concurrent _**Instances**_ for the run. |
|||
|
|||
* **Action**: Name your run `FirstRun`, set the number of iterations to `1000`, and instances to `1`. |
|||
* **Action**: Click _**Build and Run**_. |
|||
|
|||
Your project will now be built and then uploaded to USim. Depending on the upload speed of your internet connection, this might take anywhere from a few seconds to a couple of minutes. |
|||
|
|||
* **Action**: Once the operation is complete, you can find the **Build ID**, **Run Definition ID**, and **Execution ID** of this USim run in the _**Console**_ tab: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/build_uploaded.png"/> |
|||
</p> |
|||
|
|||
|
|||
### <a name="step-3">Step 3: Keep Track of USim Runs Using USim-CLI</a> |
|||
|
|||
To keep track of the progress of your USim run, you will need to use USim's command-line interface (USim-CLI). Detailed instructions for USim-CLI are provided [here](https://github.com/Unity-Technologies/Unity-Simulation-Docs/blob/master/doc/quickstart.md#download-unity-simulation-quickstart-materials). For the purposes of this tutorial, we will only go through the most essential commands, which will help us know when our USim run is complete and where to find the produced dataset. |
|||
|
|||
* **Action**: Download the latest version of `unity_simulation_bundle.zip` from [here](https://github.com/Unity-Technologies/Unity-Simulation-Docs/releases). |
|||
|
|||
**Note**: If you are using a MacOS computer, we recommend using the _**curl**_ command from the Terminal to download the file, in order to avoid issues caused by the MacOS Gatekeeper when using the CLI. You can use these commands: |
|||
``` |
|||
curl -Lo ~/Downloads/unity_simulation_bundle.zip <URL-unity_simulation_bundle.zip> |
|||
unzip ~/Downloads/unity_simulation_bundle.zip -d ~/Downloads/unity_simulation_bundle |
|||
``` |
|||
The `<URL-unity_simulation_bundle.zip>` address can be found at the same page linked above. |
|||
|
|||
* **Action**: Extract the zip archive you downloaded. |
|||
* **Action**: Open a command-line interface (Terminal on MacOS, cmd on Windows, etc.) and navigate to the extracted folder. |
|||
|
|||
If you downloaded the zip archive in the default location in your downloads folder, you can use these commands to navigate to it from the command-line: |
|||
|
|||
MacOS: |
|||
`cd ~/Downloads/unity_simulation_bundle` |
|||
|
|||
Windows: |
|||
`cd C:\Users\UserName\Downloads\unity_simulation_bundle` |
|||
|
|||
You will now be using the _**usim**_ executable to interact with Unity Simluation through commands. |
|||
|
|||
* **Action** To see a list of available commands, simply run `usim` once: |
|||
|
|||
MacOS: |
|||
`USimCLI/mac/usim` |
|||
|
|||
Windows: |
|||
`USimCLI\windows\usim` |
|||
|
|||
The first step is to login. |
|||
|
|||
* **Action**: Login to USim using the `usim login auth` command. |
|||
|
|||
MacOS: |
|||
`USimCLI/mac/usim login auth` |
|||
|
|||
Windows: |
|||
`USimCLI\windows\usim login auth` |
|||
|
|||
This command will ask you to press Enter to open a browser for you to login to your Unity account: |
|||
|
|||
`Press [ENTER] to open your browser to ...` |
|||
|
|||
* **Action**: Press Enter to open a browser window for logging in. |
|||
|
|||
Once you have logged you will see this page: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/usim_login.png" width="400"/> |
|||
</p> |
|||
|
|||
**Note**: On MacOS, you might get errors related to permissions. In these cases, try running your commands with the `sudo` qualifier. For example: |
|||
`sudo USimCLI/mac/usim login auth`. This will ask for your MacOS account's password, and should help overcome the persmission issues. |
|||
|
|||
**Note : From this point on we will only include MacOS formatted commands in the tutorial, but all the USim commands we use will work in all supported operating systems.** |
|||
|
|||
* **Action**: Return to your command-line interface. Get a list of cloud projects associated with your Unity account using the `usim get projects` command: |
|||
|
|||
MacOS: |
|||
`USimCLI/mac/usim get projects` |
|||
<!--Windows: |
|||
`USimCLI\windows\usim get projects`--> |
|||
|
|||
Example output: |
|||
|
|||
``` |
|||
name id creation time |
|||
--------------------- ---------------------------------------- --------------------------- |
|||
Perception Tutorial acd31956-582b-4138-bec8-6670be150f09 * 2020-09-30T00:33:41+00:00 |
|||
SynthDet 9ec23417-73cd-becd-9dd6-556183946153 2020-08-12T19:46:20+00:00 |
|||
``` |
|||
|
|||
In case you have more than one cloud project, you will need to "activate" the one corresponding with your perception tutorial project. If there is only one project, it is already activated and you will not need to execute the command below (note: replace `<project-id>` with the id of your desired project). |
|||
|
|||
* **Action**: Activate the relevant project: |
|||
|
|||
MacOS: |
|||
`USimCLI/mac/usim activate project <project-id>` |
|||
<!--Windows: |
|||
`USimCLI\windows\usim get projects <project-id>` --> |
|||
|
|||
When asked if you are sure you want to change the active project, enter "**y**" and press **Enter**. |
|||
|
|||
Now that we have made sure the correct project is active, we can get a list of all the current and past runs for the project. |
|||
|
|||
* **Action**: Use the `usim get runs` command to obtain a list of current and past runs: |
|||
|
|||
MacOS: |
|||
`USimCLI/mac/usim get runs` |
|||
|
|||
<!--Windows: |
|||
`USimCLI\windows\usim get runs`--> |
|||
|
|||
An example output with 3 runs would look like this: |
|||
|
|||
``` |
|||
Active Project ID: acd31956-582b-4138-bec8-6670be150f09 |
|||
name id creation time executions |
|||
----------- --------- --------------------- ----------------------------------------------- |
|||
FirstRun 1tLbZxL 2020-10-01 23:17:50 id status created_at |
|||
--------- ------------- --------------------- |
|||
yegz4WN In_Progress 2020-10-01 23:17:54 |
|||
Run2 klvfxgT 2020-10-01 21:46:39 id status created_at |
|||
--------- ------------- --------------------- |
|||
kML3i50 In_Progress 2020-10-01 21:46:42 |
|||
Test 4g9xmW7 2020-10-01 02:27:06 id status created_at |
|||
--------- ----------- --------------------- |
|||
xBv3arj Completed 2020-10-01 02:27:11 |
|||
``` |
|||
|
|||
As seen above, each run has a name, an ID, a creation time, and a list of executions. Note that each "run" can have more than one "execution", as you can manually execute runs again using USim-CLI. |
|||
|
|||
You can also obtain a list of all the builds you have uploaded to USim using the `usim get builds` command. |
|||
|
|||
You may notice that the IDs seen above for the run named `FirstRun` match those we saw earlier in Unity Editor's _**Console**_. You can see here that the single execution for our recently uploaded build is `In_Progress` and that the execution ID is `yegz4WN`. |
|||
|
|||
USim runs executions on simulation nodes. If you enter a number larger than 1 for the number of instances in the _**Run in USim**_ window, your run will execute simultaneously on more than one node. You can view the status of each execution node using the `usim summarize run-execution <execution-id>` command. This command will tell you how many nodes have succeeded, failed, have not run yet, or are in progress. Make sure to replace `<execution-id>` with the execution ID seen in your run list. In the above example, this ID would be `yegz4WN`. |
|||
|
|||
* **Action**: Use the `usim summarize run-execution <execution-id>` command to observe the status of your execution nodes: |
|||
|
|||
MacOS: |
|||
`USimCLI/mac/usim summarize run-execution <execution-id>` |
|||
<!--Windows: |
|||
`USimCLI\windows\usim summarize run-execution <execution-id>`--> |
|||
|
|||
Here is an example output of this command, indiciating that there is only one node, and that the node is still in progress: |
|||
|
|||
``` |
|||
state count |
|||
------------- ------- |
|||
Successes 0 |
|||
In Progress 1 |
|||
Failures 0 |
|||
Not Run 0 |
|||
``` |
|||
|
|||
At this point, we will need to wait until the execution is complete. Check your run with the above command periodically until you see a 1 for `Successes` and 0 for `In Progress`. |
|||
Given the relatively small size of our Scenario (1,000 Iterations), this should take less than 5 minutes. |
|||
|
|||
* **Action**: Use the `usim summarize run-execution <execution-id>` command periodically to check the progress of your run. |
|||
* **Action**: When execution is complete, use the `usim download manifest <execution-id>` command to download the execution's manifest: |
|||
|
|||
MacOS: |
|||
`USimCLI/mac/usim download manifest <execution-id>` |
|||
|
|||
The manifest is a `.csv` formatted file and will be downloaded to the same location from which you execute the above command, which is the `unity_simulation_bundle` folder. |
|||
This file does **not**** include actual data, rather, it includes links to the generated data, including the JSON files, the logs, the images, and so on. |
|||
|
|||
* **Action**: Open the manifest file to check it. Make sure there are links to various types of output and check a few of the links to see if they work. |
|||
|
|||
|
|||
### <a name="step-4">Step 4: Analyze the Dataset using Dataset Insights</a> |
|||
|
|||
In order to to download the actual data from your run, we will now use Dataset Insights again. This time though, we will utilize some of the lines that were commented in our previous use with locally generated data. |
|||
|
|||
* **Action**: Open the Dataset Insights Jupyter notebook again, using the command below: |
|||
|
|||
`docker run -p 8888:8888 -v <download path>/data:/data -t unitytechnologies/datasetinsights:latest` |
|||
|
|||
In the above command, replace `<download path>` with the location on your computer in which you wish to download your data. |
|||
|
|||
Once the Docker image is running, the rest of the workflow is quite similar to what we did in Phase 1, with certain differences caused by the need to download the data from USim. |
|||
|
|||
* **Action**: Open a web browser and navigate to `http://localhost:8888` to open the Jupyter notebook. |
|||
* **Action**: Navigate to the `datasetinsights/notebooks` folder and open `Perception_Statistics.ipynb`. |
|||
* **Action**: In the `data_root = /data/<GUID>` line, the `<GUID>` part will be the location inside your `<download path>` where the data will be downloaded. Therefore, you can just remove it so as to have data downloaded directly to the path you previously specified: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/di_usim_1.png"/> |
|||
</p> |
|||
|
|||
The next few lines of code pertain to setting up your notebook for downloading data from USim. |
|||
|
|||
* **Action**: In the block of code titled "Unity Simulation [Optional]", uncomment the lines that assign values to variables, and insert the correct values, based on information from your USim run. |
|||
|
|||
We have previoulsy learned how to obtain the `run_execution_id` and `project_id`. You can remove the value already present for `annotation_definition_id` and leave it blank. What's left is the `access_token`. |
|||
|
|||
* **Action**: Return to your command-line interface and run the `usim inspect auth` command. |
|||
|
|||
MacOS: |
|||
`USimCLI/mac/usim inspect auth` |
|||
|
|||
If you receive errors regarding authentication, your token might have timed out. Repeat the login step (`usim login auth`) to login again and fix this issue. |
|||
|
|||
A sample output from `usim inspect auth` will like like below: |
|||
|
|||
``` |
|||
Protect your credentials. They may be used to impersonate your requests. |
|||
access token: Bearer 0CfQbhJ6gjYIHjC6BaP5gkYn1x5xtAp7ZA9I003fTNT1sFp |
|||
expires in: 2:00:05.236227 |
|||
expired: False |
|||
refresh token: FW4c3YRD4IXi6qQHv3Y9W-rwg59K7k0Te9myKe7Zo6M003f.k4Dqo0tuoBdf-ncm003fX2RAHQ |
|||
updated: 2020-10-02 14:50:11.412979 |
|||
``` |
|||
|
|||
The `access_token` you need for your Dataset Insights notebook is the access token shown by the above command, minus the `'Bearer '` part. So in this case, we should input `0CfQbhJ6gjYIHjC6BaP5gkYn1x5xtAp7ZA9I003fTNT1sFp` in the notebook. |
|||
|
|||
* **Action**: Copy the access token excluding the `'Bearer '` part to the corresponding field in the Dataset Inisghts notebook. |
|||
|
|||
Once you have entered all the information, the block of code should look like the screenshot below (the actual values you input will be different): |
|||
|
|||
<p align="center"> |
|||
<img src="Images/di_usim_2.png"/> |
|||
</p> |
|||
|
|||
|
|||
* **Action**: Continue to the next code block and run it to download all the meta-data files from the generated dataset. This includes JSON files and logs, but does not include images (which will be downloaded later). |
|||
|
|||
You will see a progress bar while the data downloads: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/di_usim_3.png"/> |
|||
</p> |
|||
|
|||
|
|||
The next couple of code blocks (under "Load dataset metadata") analyze the downloaded meta-data and display a table containing annotation-id's for the various metrics defined in the dataset. |
|||
|
|||
* **Action**: Once you reach the code block titled "Built-in Statistics", make sure the value assigned to the field `rendered_object_info_definition_id` matches the id displayed for this metric in the table output by the code block immediately before it. The screenshot below demonstrates this (note that your ids might differ from the ones here): |
|||
|
|||
<p align="center"> |
|||
<img src="Images/di_usim_4.png"/> |
|||
</p> |
|||
|
|||
Follow the rest of the steps inside the notebook to generate a variety of plots and stats. Keep in mind that this notebook is provided just as an example, and you can modify and extend it according to your own needs using the tools provided by the [Dataset Insights framework](https://datasetinsights.readthedocs.io/en/latest/). |
|||
|
|||
This concludes the Perception tutorial. The next step in this workflow would be to train an object-detection model using a USim-generated dataset. It is important to note that the 1000 large dataset we generated here is probably not sufficiently large for training most models. We chose this number here so that the run would complete in a fairly short period of time, allowing us to move on to learning how to analyze the dataset's statistics. In order to generate data for training, we recommend a dataset of about 400,000 captures. |
|||
|
|||
The grocery objects we used in the foreground are a subset of objects from the [SynthDet](https://github.com/Unity-Technologies/SynthDet) project, which is a custom project based on the Perception package. Instructions for training a [Faster-RCNN](https://arxiv.org/abs/1506.01497) object-detection model based on data generated with the SynthDet project are provided [here](https://github.com/Unity-Technologies/datasetinsights/blob/master/docs/source/Evaluation_Tutorial.md). Although the instructions are tailored to SynthDet, the principles will be the same for training a model. |
|||
|
|||
In the near future, we will expand this tutorial to Phase 4, which will inclde model training instructions which are tailor-made for the project we built together here. |
|
|||
# Perception Tutorial |
|||
## Phase 2: Custom Randomizations |
|||
|
|||
In Phase 1 of the tutorial, we learned how to use the Randomizers that are bundled with the Perception package to spawn background and foreground objects, and randomize their position, rotation, texture, and hue offset (color). In this phase, we will build a custom light Randomizer for the `Directional Light` object, affecting the light's intensity and color on each Iteration of the Scenario. We will also learn how to include certain data or logic inside a randomized object (such as the light) in order to more explicitly define and restrict its randomization behaviors. |
|||
|
|||
Steps included this phase of the tutorial: |
|||
- [Step 1: Build a Lighting Randomizer](#step-1) |
|||
- [Step 2: Bundle Data and Logic Inside Randomization Tags](#step-2) |
|||
|
|||
### <a name="step-1">Step 1: Build a Lighting Randomizer</a> |
|||
|
|||
We need to create two C# classes for our light randomization, `MyLightRandomizer` and `MyLightRandomizerTag`. The first of these will sample random values and assign them to the intensity and color of the light, and the second class will be the component that will be added to `Directional Light`, making it a target of `MyLightRandomizer`. |
|||
|
|||
* **Action**: In the _**Project**_ tab, right-click on the `Scripts` folder and select _**Create -> C# Script**_. Name your new script file `MyLightRandomizer.cs`. |
|||
* **Action**: Create another script and name it `MyLightRandomizerTag.cs`. |
|||
* **Action**: Double-click `MyLightRandomizer.cs` to open it in _**Visual Studio**_. |
|||
|
|||
Note that while _**Visual Studio**_ is the default option, you can choose any text editor of your choice. You can change the this setting in _**Preferences -> External Tools -> External Script Editor**_. |
|||
|
|||
* **Action**: Remove the contents of the class and copy/paste the code below: |
|||
|
|||
``` |
|||
using System; |
|||
using UnityEngine; |
|||
using UnityEngine.Experimental.Perception.Randomization.Parameters; |
|||
using UnityEngine.Experimental.Perception.Randomization.Randomizers; |
|||
|
|||
[Serializable] |
|||
[AddRandomizerMenu("Perception/My Light Randomizer")] |
|||
public class MyLightRandomizer : Randomizer |
|||
{ |
|||
public FloatParameter lightIntensityParameter; |
|||
|
|||
protected override void OnIterationStart() |
|||
{ |
|||
var taggedObjects = tagManager.Query<MyLightRandomizerTag>(); |
|||
|
|||
foreach (var taggedObject in taggedObjects) |
|||
{ |
|||
var light = taggedObject.GetComponent<Light>(); |
|||
light.intensity = lightIntensityParameter.Sample(); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
The purpose of this piece of code is to obtain a random float parameter and assign it to the light's `Intensity` field on the start of every Iteration. Let's go through the code above and understand each part. The `FloatParameter` field makes it possible for us to define a randomized float parameter and modify its properties from the editor UI, similar to how we already modified the properties for the previous Randomizers we used. |
|||
|
|||
If you return to your list of Randomizers in the _**Inspector**_ view of `SimulationScenario`, you can now add this new Randomizer. |
|||
|
|||
* **Action**: Add `MyLightRandomizer` to the list of Randomizers in `SimulationScenario`. |
|||
|
|||
You will notice the the Randomizer's UI snippet contains one Parameter named `Light Intensity Parameter`. This is the same Parameter we added in the code block above. Here, you can set the sampling distribution (`Value`), `Seed`, and `Range` for this float Parameter: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/light_rand_1.png" width="420"/> |
|||
</p> |
|||
|
|||
|
|||
* **Action**: In the UI snippet for `MyLightRandomzier`, set the minimum and maximum for range to 0.5 and 3. |
|||
|
|||
This range of intensities is arbitrary but will give us a typically nice lighting without excessive darkness or burnt-out highlights. |
|||
|
|||
The `MyLightRandomizer` class extends `Randomizer`, which is the base class for all Randomizers that can be added to a Scenario. This base class provides a plethora of useful functions and properties that can help catalyze the process of creating new Randomziers. |
|||
|
|||
The `OnIterationStart()` function is used for telling the Randomizer what actions to perform at the start of each Iteration of the Scenario. As seen in the code block, at the start of each Iteration, this class queries the `tagManager` object for all objects that carry the `MyLightRandomizerTag` component. Then, for each object inside the queried list, it first retrieves the `Light` component, and then sets its intensity to a new random float sampled from `lightIntensityParamter`. |
|||
|
|||
* **Action**: Open `MyLightRandomizerTag.cs` and replace its contents with the code below: |
|||
|
|||
``` |
|||
using UnityEngine; |
|||
using UnityEngine.Experimental.Perception.Randomization.Randomizers; |
|||
|
|||
[AddComponentMenu("Perception/RandomizerTags/MyLightRandomizerTag")] |
|||
[RequireComponent(typeof(Light))] |
|||
public class MyLightRandomizerTag : RandomizerTag |
|||
{ |
|||
} |
|||
|
|||
``` |
|||
|
|||
Yes, a RandomizerTag can be this simple if you just need it for helping Randomizers query for target objects. Later, you will learn how to add code here to encapsulate more data and logic within the randomized objects. |
|||
|
|||
Notice there is a `RequireComponent(typeof(Light))` line at the top. This line makes it so that you can only add the `MyLightRandomizerTag` component to an object that already has a `Light` component attached. This way, the Randomizers that query for this tag can be confident that the found objects have a `Light` component, and can thus be Randomized. |
|||
|
|||
* **Action**: Select `Directional Light` in the Scene's _**Hierarchy**_, and in the _**Inspector**_ tab, add a `Light Randomizer Tag` component. |
|||
* **Action**: Run the simulation again and inspect how `Directional Light` now switches between different intensities. You can pause the simulation and then use the step button (to the right of the pause button) to move the simulation one frame forward and clearly see the varying light intensity |
|||
|
|||
Let's now add more variation to our light by randomizing its color as well. |
|||
|
|||
* **Action**: Back inside `MyLightRandomizer.cs`, define a new `ColorRgbParameter`: |
|||
|
|||
`public ColorRgbParameter lightColorParameter;` |
|||
|
|||
* **Action**: Inside the code block that intensity was previously applied, add code for sampling color from the above Parameter and applying it: |
|||
|
|||
``` |
|||
foreach (var taggedObject in taggedObjects) |
|||
{ |
|||
var light = taggedObject.GetComponent<Light>(); |
|||
light.intensity = lightIntensityParameter.Sample(); |
|||
light.color = lightColorParameter.Sample(); |
|||
} |
|||
``` |
|||
|
|||
If you now check the UI snippet for `MyLightRandomizer`, you will notice that `Color Parameter` is added. This Parameter includes four separate randomized values for `Red`, `Green`, `Blue` and `Alpha`. Note that the meaningful range for all of these values is 0-1 (and not 0-255). You can see that the sampling range for red, green, and blue is currently also set to 0-1, which means the parameter covers a full range of colors. A color with (0,0,0) RGB components essentially emits no light. So let's increase the minimum a bit to avoid such a scenario.. |
|||
|
|||
* **Action**: Increase the minimum value for red, green, and blue components to 0.4 (this is an arbitrary number that typically produces good-looking results). |
|||
|
|||
Each value should also already have a unique `Seed` specified. This is the seed which the sampler will use to produce a random value from the specifed distribution. If two random parameters have the same seed, range, and distribution, they will always have the same value. In the case of this color, this would lead to the red, green, and blue components having equal values, and thus the produced color always being a shade of grey. As such, in order to get varied colors and not just grey, we need to make sure the seed values are different for our red, green, and blue components. |
|||
|
|||
* **Action**: In the UI snippet for `MyLightRandomizer`, make sure the red, green, and blue components have different `Seed` values. Set the distribution and value for Alpha to `Constant` and 1, as we do not want to randomize the alpha component of the color. |
|||
|
|||
The UI for `My Light Randomizer` should now look like this: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/light_rand_2.png" width="420"/> |
|||
</p> |
|||
|
|||
|
|||
* **Action**: Run the simulation for a few frames to observe the lighting color changing on each iteration. |
|||
|
|||
|
|||
### <a name="step-2">Step 2: Bundle Data and Logic Inside Randomization Tags</a> |
|||
|
|||
|
|||
You may sometimes need to bundle certain randomization-related data or logic within an object that are inherent to the object itself. For instance, you may have multiple lights in the Scene but would like each of them to have their own unique range of intensities. It would be quite tedious to add a new Parameter to your light Randomizer for each of your lights. Furthermore, this would make your light Randomizer excessively tailored to one use-case, limiting the Randomizer's reusability. |
|||
|
|||
There are also cases were you may need to include certain logic within your object in order to make the Randomizer code more reusable and easy to maintain. For instance, you may want to build an office chair Prefab to use in various simulations. This chair is likely to support a range of customizations for its various parts (back angle, seat angle, seat height, etc.). Instead of directly mapping a Rotation Parameter from a Randomizer to the rotation of the back angle object within the chair, it might be more convenient to have the chair expose the range of possible angles in the form of a simple float between 0 and 1. With this approach, the Randomizer would only need to sample a float Parameter and assign it to the chair. The chair would in turn have a script attached that knows how to map this single float to a certain plausible back angle. You could even map this float to a more complex state of the chair. Your Randomizer would still only need one float Parameter. |
|||
|
|||
Let's try this approach with our `Directional Light` object. We will create a duplicate of this light and then have the two lights use different ranges of intensity while both using the exact same float Parameter from `MyLightRandomizer.cs`. |
|||
|
|||
* **Action**: Right-click on `Directional Light` in the Scene _**Hierarchy**_, and select _**Duplicate**_. The new light will automatically be named `Directional Light (1)`. |
|||
* **Action**: Change the Y rotation of `Directional Light (1)` to 60, as shown below: |
|||
|
|||
<p align="center"> |
|||
<img src="Images/light_rand_2.png" width="420"/> |
|||
</p> |
|||
|
|||
* **Action**: Change the Y rotation of `Directional Light` to -60. |
|||
|
|||
This makes the two lights illuminate the scene from opposing sides, each having a 30 degree angle with the background and foreground planes. |
|||
|
|||
* **Action**: Open `MyLightRandomizerTag.cs` and modify it to match the code below: |
|||
``` |
|||
using UnityEngine; |
|||
using UnityEngine.Experimental.Perception.Randomization.Randomizers; |
|||
|
|||
[AddComponentMenu("Perception/RandomizerTags/MyLightRandomizerTag")] |
|||
[RequireComponent(typeof(Light))] |
|||
public class MyLightRandomizerTag : RandomizerTag |
|||
{ |
|||
public float minIntensity; |
|||
public float maxIntensity; |
|||
|
|||
public void SetIntensity(float rawIntensity) |
|||
{ |
|||
var light = gameObject.GetComponent<Light>(); |
|||
var scaledIntensity = rawIntensity * (maxIntensity - minIntensity) + minIntensity; |
|||
light.intensity = scaledIntensity; |
|||
} |
|||
} |
|||
|
|||
``` |
|||
In the above code, we have created a new `SetIntensity` function that first scales the incoming intensity (assumed to be between 0 and 1) to our desired range and then assigns it to the light's intensity. The `Light` component is now fetched from the GameObject that this Randomizer tag is attached to. This works because both this tag component and the `Light` component are attached to the same object in the Scene (which is one of the lights). |
|||
|
|||
This component is already added to both our lights. We now need to set our desired minimum and maximum intensities, and this can be done through the _**Inspector**_ view. |
|||
|
|||
* **Action**: Select `Directional Light` and from the _**Inspector** UI for the `MyLightRandomizerTag` component, set `Min Intensity` to 0.5 and `Max Intensity` to 3. |
|||
* **Action**: Repeat the above step for `Directional Light (1)` and set `Min Intensity` to 0 and `Max Intensity` to 0.4. |
|||
|
|||
Note that with this change, we fully transfer the responsibility for the light's intensity range to `MyLightRandomizerTag.cs` and assume the intensity value coming from `My Light Randomizer` is always between 0 and 1. Therefore, we now need to change the range for the corresponding Parameter in `My Light Randomizer` to (0,1). |
|||
|
|||
* **Action**: Select `SimulationScenario` and from the UI snippet for `My Light Randomizer`, change the range for `Light Intensity Parameter` from (0.5,3.5) to (0,1). |
|||
|
|||
We also need to make a minor change to `MyLightRandomizer.cs` in order to make it compatible with this new approach. |
|||
|
|||
* **Action**: Open `MyLightRandomizer.cs` and modify it as seen below: |
|||
|
|||
``` |
|||
using System; |
|||
using UnityEngine; |
|||
using UnityEngine.Experimental.Perception.Randomization.Parameters; |
|||
using UnityEngine.Experimental.Perception.Randomization.Randomizers; |
|||
|
|||
[Serializable] |
|||
[AddRandomizerMenu("Perception/My Light Randomizer")] |
|||
public class MyLightRandomizer : Randomizer |
|||
{ |
|||
public FloatParameter lightIntensityParameter; |
|||
public ColorRgbParameter lightColorParameter; |
|||
|
|||
protected override void OnIterationStart() |
|||
{ |
|||
var taggedObjects = tagManager.Query<MyLightRandomizerTag>(); |
|||
foreach (var taggedObject in taggedObjects) |
|||
{ |
|||
var light = taggedObject.GetComponent<Light>(); |
|||
light.color = lightColorParameter.Sample(); |
|||
|
|||
var tag = taggedObject.GetComponent<MyLightRandomizerTag>(); |
|||
tag.SetIntensity(lightIntensityParameter.Sample()); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
Notice how we now fetch the `MyLightRandomizerTag` component from the tagged object and use its `SetIntensity` function instead of directly setting the intensity of the `Light` component. |
|||
|
|||
* **Action**: Run your simulation, then pause it. Go to the _**Scene**_ view and inspect the color and intensity of each of the lights. Try turning each on and off to see how they affect the current frame. |
|||
|
|||
By this point in the tutorial, we have learned how to set-up a Perception Scene, randomize our simulation, and verify our generated datasets using Dataset Insights. That said, the size of the dataset we created was only 100 captures, which is not sufficient for model-training purposes. It is now time to generate a large-scale synthetic dataset with tens of thousands of frames using Unity Simulation. |
|||
|
|||
[Click here to continue to Phase 3: Cloud](Phase3.md) |
|
|||
fileFormatVersion: 2 |
|||
guid: 70702619b50434c58aae4e17122e2fc1 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
{ |
|||
"displayName":"Tutorial Files", |
|||
"createSeparatePackage": false |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 13b964c72863a4de183a0c3ae86e0629 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 53626f3a0945543409146c27e1275a9c |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
164
com.unity.perception/Samples~/Tutorial Files/Shaders/HueShiftOpaque.shadergraph
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: 90ad3a47f8ccd406eab0fbf0c7a64d88 |
|||
ScriptedImporter: |
|||
internalIDToNameTable: [] |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} |
|
|||
fileFormatVersion: 2 |
|||
guid: f2a6a55b23a504333a6dfd74eecf75d9 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 73725c0c50cbe46bd87caa5677948d34 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 322cc7411e6ed4ed798fa656bd7da7d8 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: a4315e23f1cb54c7a9998e07e5872403 |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: 3be265349956646cf91bcc3a41573e76 |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: 58482064046cc4a299c6eefa51882ba4 |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: f902c1464bba14760b6b21e7213aa7f4 |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: 51a0d6a0d9f214dc19327ba840d4e6d5 |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: 8727d525080ed4c5dac23408fc6d04a9 |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: 53b765e12f18c4eac99a57ced3cb7471 |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: 4abfbd1b0c68d4be2a8b7d10212c3ebd |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: 7713ea4da14544ec2a3684a8bd9d84ce |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: e0dcb5042fcf346f19474d15c4aae281 |
|||
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 |
|||
vTOnly: 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 |
|||
ignorePngGamma: 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: |
|
|||
fileFormatVersion: 2 |
|||
guid: 58c162d9fc16e4184b6f0eaaaf5e3e6d |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
部分文件因为文件数量过多而无法显示
撰写
预览
正在加载...
取消
保存
Reference in new issue