Skip to content

Tool for Unity to create and run tests of Asset Regulations (texture size, number of vertices, etc.), and automate running.

License

Notifications You must be signed in to change notification settings

CyberAgentGameEntertainment/AssetRegulationManager

Repository files navigation

Asset Regulation Manager Asset Regulation Manager

ARM: Testing Unity assets automatically

license license license

Docs (English, 日本語)

Tool for Unity to create and run tests of Asset Regulations (texture size, number of vertices, etc.), and automate running.

Table of Contents

Details

Concepts & Features

It is important to strictly manage "Asset Regulations" in Unity game development. The following items are typical examples of Asset Regulations.

  • Texture Size
  • Number of Vertices of Mesh
  • File Name

If these asset regulations are not followed or not clearly defined, the problems like below can occur.

  • Asset size increases, resulting in longer download times.
  • Asset size increases, resulting in longer load times.
  • Memory usage increases, resulting in application crashes.
  • Shader processing increases with the number of vertices, resulting in a lower frame rate.
  • Fail to load due to wrong file name.

Asset Regulation Manager allows you to test such Asset Regulations. Everyone (even non-engineers) can easily test through the intuitive interface as shown below.

Asset Regulation Viewer
Asset Regulation Viewer

And the command line interface (CLI) is also available for periodic automated testing.

You can create the Asset Regulation Tests easily using the GUI tool as shown below.

Asset Regulation Editor
Asset Regulation Editor

Setup

Requirements

This library is compatible with the following environment.

  • Unity 2019.4 or higher.

Install

To install the software, follow the steps below.

  1. Open the Package Manager from Window > Package Manager
  2. "+" button > Add package from git URL
  3. Enter the following

Package Manager

Or, open Packages/manifest.json and add the following to the dependencies block.

{
    "dependencies": {
        "jp.co.cyberagent.assetregulationmanager": "https://github.com/CyberAgentGameEntertainment/AssetRegulationManager.git?path=/Assets/AssetRegulationManager"
    }
}

If you want to set the target version, write as follows.

To update the version, rewrite the version as described above. If you don't want to specify a version, you can also update the version by editing the hash of this library in the Packages/package-lock.json file.

{
  "dependencies": {
      "jp.co.cyberagent.assetregulationmanager": {
      "version": "https://github.com/CyberAgentGameEntertainment/AssetRegulationManager.git?path=/Assets/AssetRegulationManager",
      "depth": 0,
      "source": "git",
      "dependencies": {},
      "hash": "..."
    }
  }
}

Note
If you get a message like No 'git' executable was found. Please install Git on your system and restart Unity, you will need to set up Git on your machine.

Create Asset Regulation Tests

Create an asset to store data

To create Asset Regulation Test, first create a Regulation Data Asset from Assets > Create > Asset Regulation Data.

Create Regulation Data Asset
Create Regulation Data Asset

Data regarding Asset Regaultion Tests are stored in this asset.

You can create multiple assets in your project. And you can place it anywhere you like, but do not place it in special folders such as StreamingAssets.

Create Asset Regulations

Next, double-click on a regulation data asset or press the Open Editor button from the Inspector to open the Asset Regulation Editor. Then press the + button in the upper left corner of this window to create a new asset regulation.

Create Asset Regulation
Create Asset Regulation

One asset regulation consists of the following two elements.

Target

  • Assets to which this regulation applies.
  • Specify like "All Texture2D type assets in the Character folder".

Constraint

  • Constraint that the target assets must adhere to.
  • "Texture Size must be 1024x1024 or smaller", "Texture format must be ASTC4x4", etc.

The next step is to set these up.

Set up targets

To set up a target, first click the Add Asset Group button on the Targets tab in the right panel. You will see a new Asset Group named New Asset Group.

Create Asset Group
Create Asset Group

You can specify the target assets by adding Asset Filters to this asset group. For example, to target only the assets in the Characters folder, press the + button to the right of the asset group name and select Object Filter from the menu. And assign the Characters folder to the Object property of the added Object Filter.

Create Object Filter
Create Object Filter

Next, narrow down the targets to Texture2D type assets only. Press the + button as before and add Type Filter. And set Texture2D to the Type property of the added Type Filter.

Create Type Filter
Create Type Filter

Now, you can target all Texture2D under the Characters folder.

Note that multiple asset groups can be set Up for a single asset regulation. If multiple asset groups are set up, all assets indicated by each asset group will be targets. The figure below shows an example of targeting of all Texture2D files in the Characters folder and all files with the exr extension in the CharacterHDR folder.

Multiple Asset Groups
Multiple Asset Groups

Set up constraints

Next, set up constraints. First, create a constraint regarding max texture size. Select Add Constraint > Texture > Max Texture Size from the Constraints tab in the right panel.

Max Texture Size
Max Texture Size

Enter the maximum size of the texture in the Max Size property of the added constraint and you are done.

Max Size
Max Size

In addition, add a constraint regarding texture format.
As before, select Add Constraint > Texture > Texture Format to add the constraint. This time, set Target to iOS and Format to ASTC_6x6.

Texture Format
Texture Format

You have now set the constraint.

Details on how to use the Asset Regulation Editor

The Asset Regulation Editor also supports the following operations.

  1. Select a column to search.
  2. Search regulations.
  3. Select the regulation data asset to edit.
  4. Rename the asset regulation.
  5. Right-click menu
    • Create a new asset regulation.
    • Remove the selected asset regulation.
    • Copy target information as string.
    • Copy constraint information as string.
  6. Drag to reorder asset regulations.

Editor Operations
Editor Operations

In the Targets tab, you can do the followings by right-click menu of asset groups.

  1. Rename the asset group name.
  2. Remove the asset group.
  3. Reorder the asset group (move up/down).
  4. Copy and paste.
  5. Paste the asset filter.

Targets Operations
Targets Operations

You can also do the followings by right-click menu of asset filters.

  1. Remove the asset filter.
  2. Reorder the asset filter (move up/down).
  3. Copy and paste.

Filters Operations
Filters Operations

From the right-click menu on the Constraints tab, you can do the followings.

  1. Remove the asset constraint.
  2. Reorder the asset constraint (move up/down).
  3. Copy and paste.

Constraints Operations
Constraints Operations

Note
All operations can be undo by pressing Ctrl (Command) + Z and redo by pressing Ctrl (Command) + Y.

Execute Asset Regulation Tests

Asset Regulation Viewer

You can open the Asset Regulation Viewer from Window > Asset Regulation Viewer to test the asset regulations using GUI tool.

First, enter the asset name in the search field at the top of the window to search the assets. Like the Project view, you can use type search, label search, and glob search (e.g. "t:Texture").

Search Assets
Search Assets

You can show the constraints for the asset by opening the toggle for each asset displayed after the search.

Show Constraints
Show Constraints

To test Asset Regulation, double-click on the target row.

Also you can test the all displayed Asset Regulations by pressing the Run All button.
If you want to test only asset regulations you selected, use the Run Selected button.

Run Tests
Run Tests

Details on how to use the Asset Regulation Viewer

The Asset Regulation Viewer also supports the following operations.

  1. Reload.
  2. Open the menu.
  3. Show/Hide assets with no asset regulations.
  4. Export test result.

Viewer Operations
Viewer Operations

Test with command line interface (CLI)

How to use

You can test Asset Regulations with the following method.

AssetRegulationManager.Editor.Core.Tool.Test.AssetRegulationTestCLI.AssetRegulationTestCLI.ExecuteTests

The following is an example of command line on Mac.

/Applications/Unity/Hub/Editor/2019.4.33f1/Unity.app/Contents/MacOS/Unity -projectPath [Your Project Path Here] -executeMethod AssetRegulationManager.Editor.Core.Tool.Test.AssetRegulationTestCLI.AssetRegulationTestCLI.ExecuteTests

Return value

The return value of the command line is as follows.

Return Value Description
0 All tests succeeded.
1 Failed test exists. But, with the -failWhenWarning option, this value is returned even when the warning is contained.
2 Execution failed.

How to receive results

The test results are saved to a file. You can specify the file path using the command line argument -resultFilePath.

The results will be written out like following.

Assets/Development/DevelopmentAssets/tex_dev_red_128.png
[Success] Texture Format: RGBA32 (iPhone) | Actual Value: RGBA32
[Success] Max Texture Size: 200 x 200 | Actual Value: 128 x 128

Assets/Development/DevelopmentAssets/tex_dev_red_256.png
[Failed] Texture Format: RGBA32 (iPhone) | Actual Value: ASTC_6x6
[Failed] Max Texture Size: 200 x 200 | Actual Value: 256 x 256

Note that you can output the results as json like follows by specifing Json as the command line argument -resultFormat.

{"results":[{"assetPath":"Assets/Development/DevelopmentAssets/tex_dev_red_128.png","entries":[{"status":"Success","description":"Texture Format: RGBA32 (iPhone)","message":"Actual Value: ASTC_6x6"},{"status":"Success","description":"Max Texture Size: 200 x 200","message":"Actual Value: 256 x 256"}]},{"assetPath":"Assets/Development/DevelopmentAssets/tex_dev_red_256.png","entries":[{"status":"Failed","description":"Texture Format: RGBA32 (iPhone)","message":"Actual Value: ASTC_6x6"},{"status":"Failed","description":"Max Texture Size: 200 x 200","message":"Actual Value: 256 x 256"}]}]}

Command line arguments

The command line arguments are described below.

Name Description
-resultFilePath <filePath> Specifies the output file path for test results. Default value is AssetRegulationManager/test_result.txt (or .json).
-resultFormat <formatName> Specifies the output format of the results.

* List (default)
* Json
-resultFilter <filterName> Filters test results by status.

* All: Output all results. (default)
* Success: Output only successful results.
* Warning: Output only results with warnings.
* Failed: Output only failed results.

You can specify multiple options by enclosing them with "" and separating with semicolons. For example, to output warnings and failures, specify as following.

-resultFilter "Warning;Failed"
-assetFilter <assetPath> Filters test target assets. Specify the asset paths. You can specify multiple paths by enclosing them with "" and separating with semicolons. And you can also use regular expressions.

For example, to target the files that have "mesh_" or "tex_" in their path, specify as following.

-assetFilter "mesh_;tex_"
-regulationFilter <regulationName> Filters asset regulations for testing. Specify the asset regulation names. You can specify multiple regulations by enclosing them with "" and separating with semicolons. And you can also use regular expressions.

For example, to target the regulations named "Character Prefabs" and "Character Textures", specify as following.

-regulationFilter "^Character Prefabs$;^Character Textures$"

Descriptions of Asset Filters

Name Overview and Property Description
Object Filter Filters by specifying the asset directly.
Use case: Target only assets under the Characters folder.

Folder Targeting Mode
Specify how folders are handled.
* Included Assets (Exclude Folders): Targets only assets in the folders.
* Self: Targets only the folders themselves.
* Both: Targets the folders and the included assets.

Object
Target asset. If you specify a folder, target all assets in the folder. Multiple items can be specified by using the right toggle.
Type Filter Filters by asset type.
Use case: Targets only Texture2d type assets.

Match With Derived Type
If checked, derived types are also covered.

Type
Target type. Multiple items can be specified by using the right toggle.
Asset Path Filter Filters by asset path.
Use case 1: Target assets contained in the folder named "Assets/Sample[Any 3 characters]/".
Use case 2: Exclude assets that contain "Dummy" in the file name.

Match With Folders
Targets the folders or not.

Asset Path (Regex)
Target asset path. Assets whose paths partially match these will be targeted. You can also use regular expressions. Multiple items can be specified by using the right toggle.

Condition
Specify how to handle multiple Asset Paths.
* Contains Matched: Target if any asset path matches.
* Match All: Target if all asset paths match.
* Contains Unmatched: Target if any one asset path does not match.
* Not Match All: Target if all asset paths do not match.
Extension Filter Filters by extension.
Use case: Target assets that have png or jpg extension.

Extension
Target extension. Multiple items can be specified by using the right toggle.
Dependent Object Filter Filters the assets that are referenced by the specified asset.
Use case: Targets the textures that are referenced by the prefab.

Only Direct Dependencies
Targets the assets that are referenced directly.

Object
Referer Assets.

Descriptions of Asset Constraints

Name Overview and Property Description
File/Asset Path Constrains asset paths.

Asset Path (Regex)
Target asset path. You can also use regular expressions. Multiple items can be specified by using the right toggle.

Condition
You can specify how to handle multiple Asset Paths.
* Or: Target if any asset path matches.
* And: Target if all asset paths match.
File/File Size Constrains file size.

Max Size
Maximum asset size.

Unit
Size unit.
* B: Byte
* KB: Kilobyte (Kibibyte)
* MB: Megabyte (Mebibyte)
File/Folder Constrains belonging folder.

Folder
Target folder. Multiple items can be specified by using the right toggle.

Check Mode
You can specify how to handle multiple folders.
* Contains: Check that it is included in the folder.
* Not Contains: Check that it is NOT included in the folder.

Top Folder Only
If checked, targets only directly under the folder.
File/Asset Type Constrains asset types.

Match With Derived Types
If checked, targets the derived types.

Type
type.
Texture/Max Texture Size Constrains texture size.

Count Mode
Specify the size calculation method.
* Width And Height: Specify the width and height of the texture.
* Texel Count: Specify the number of texels in the texture.

Max Size / Max Texel Count
Texture size.
Texture/Texture Format Constrains texture format.

Target
Specify target platform. Multiple items can be specified by using the right toggle.

Format
Specify texture format. Multiple items can be specified by using the right toggle.
Texture/Max Texel Count in Asset Constrains the total number of texels referenced by the asset.

Max Count
Max texel count.
Texture/Max Texel Count in GameObject Constrains the total number of texels referenced by the GameObject's Renderer.

Max Count
Max texel count.

Exclude Children
If checked, child GameObjects are excluded from the check.

Exclude Inactive
If checked, inactive GameObjects are excluded from the check.

Allow Duplicate Count
If checked, counts twice if another renderer is referencing the same texture.
Texture/Max Texel Count in Scene Constrains the total number of texture texels referenced by the Renderer of GameObjects in the scene.

Max Count
Maximum texel count.

Exclude Inactive
If checked, inactive GameObjects are excluded from the check.

Allow Duplicate Count
If checked, counts twice if another renderer is referencing the same texture.
Texture/Max Texel Count in Folder Constrains the total number of texels of textures in the folder.

Max Count
Max texel count.

Top Folders Only
If checked, targets only the textures located directly under the folder.
Mesh/Max Vertex Count Constrains the total number of mesh vertices.
It can be used as a constraint for Mesh and GameObjects (Prefab, FBX, etc.).

Max Count
Maximum vertex count.

Exclude Children
If checked, child GameObjects are excluded from the check.
Note: Only available if the target asset is GameObject.

Exclude Inactive
If checked, inactive GameObjects are excluded from the check.
Note: Only available if the target asset is GameObject.

Allow Duplicate Count
If checked, counts twice if another renderer is referencing the same texture.
Note: Only available if the target asset is GameObject.
Mesh/Max Vertex Count in Scene Constrains the maximum total number of vertices for all meshes in the scene.

Max Count
Maximum vetex count.

Exclude Inactive
If checked, inactive GameObjects are excluded from the check.

Allow Duplicate Count
If checked, counts twice if another renderer is referencing the same texture.
GameObject/Max GameObject Count in GameObject Constrains GameObject count in a Prefab.

Max Count
Maximum GameObject count.

Exclude Inactive
If checked, inactive GameObjects are excluded from the check.
GameObject/Max GameObject Count in Scene Constrains GameObject count in a Scene.

Max Count
Maximum GameObject count.

Exclude Inactive
If checked, inactive GameObjects are excluded from the check.
Particle System/Max ParticleSystem Count in GameObject Constrains particle system count in a prefab.

Max Count
Maximum particle system count.

Exclude Inactive
If checked, inactive GameObjects are excluded from the check.
Particle System/Max ParticleSystem Count in Scene Constrains particle system count in a scene.

Max Count
Maximum particle system count.

Exclude Inactive
If checked, inactive GameObjects are excluded from the check.
Material/Shader Keyword Constrains the shader keywords enabled in a material.

Check Condition
How to handle specified keywords.
* Enabled All: Check that all keywords are enabled.
* Enabled Any: Check that any of the keywords are enabled.
* Disabled All: Check that all keywords are disabled.
* Disabled Any: Check that any of the keywords are disabled.

Shader Keyword
Shader keyword.

Scripting

Edit regulation data assets via scripts

To edit regulation data assets via script, do like following.

using AssetRegulationManager.Editor.Core.Data;
using AssetRegulationManager.Editor.Core.Model.AssetRegulations;
using AssetRegulationManager.Editor.Core.Model.AssetRegulations.AssetConstraintImpl;
using AssetRegulationManager.Editor.Core.Model.AssetRegulations.AssetFilterImpl;
using UnityEditor;
using UnityEngine;

public static class AssetRegulationManagerScripting
{
    [MenuItem("Asset Regulation Manager/Samples/Create Data Asset")]
    private static void CreateDataAsset()
    {
        // Create data asset.
        var store = ScriptableObject.CreateInstance<AssetRegulationSetStore>();
        AssetDatabase.CreateAsset(store, "Assets/sample.asset");

        // Create and add a regulation.
        var regulation = new AssetRegulation();
        store.Set.Add(regulation);

        // Create targets.
        var assetGroup = regulation.AddAssetGroup();
        var extensionFilter = assetGroup.AddFilter<ExtensionBasedAssetFilter>();
        extensionFilter.Extension.IsListMode = true;
        extensionFilter.Extension.AddValue("png");
        extensionFilter.Extension.AddValue("jpg");

        // Create constraints.
        var fileSizeConstraint = regulation.AddConstraint<FileSizeConstraint>();
        fileSizeConstraint.Unit = FileSizeConstraint.SizeUnit.KB;
        fileSizeConstraint.MaxSize = 50;

        EditorUtility.SetDirty(store);
        AssetDatabase.SaveAssets();
    }
}

Run tests via scripts

To run regulation tests via script, do like following.

using System.Collections.Generic;
using AssetRegulationManager.Editor.Core.Data;
using AssetRegulationManager.Editor.Core.Model;
using AssetRegulationManager.Editor.Core.Model.Adapters;
using AssetRegulationManager.Editor.Core.Model.AssetRegulationTests;
using UnityEditor;

public static class AssetRegulationManagerScripting
{
    [MenuItem("Asset Regulation Manager/Samples/Execute Tests")]
    private static void ExecuteTests()
    {
        var repository = new AssetRegulationRepository();
        var testStore = new AssetRegulationTestStore();
        var assetDatabaseAdapter = new AssetDatabaseAdapter();
        var testGenerateService =
            new AssetRegulationTestGenerateService(repository, testStore, assetDatabaseAdapter);
        var testExecuteService = new AssetRegulationTestExecuteService(testStore);

        // Create tests.
        // Enter a filter as you would when searching in the project view.
        testGenerateService.Run("t:Object");

        // Filter tests.
        testStore.FilterTests(AssetRegulationTestStoreFilter.ExcludeEmptyTests);

        // Execute tests.
        testExecuteService.RunAll();

        // Export test results (optional).
        var testResultExportService = new AssetRegulationTestResultExportService(testStore);
        var exportTargetStatuses = new List<AssetRegulationTestStatus>
        {
            AssetRegulationTestStatus.Warning,
            AssetRegulationTestStatus.Failed
        };
        testResultExportService.Run("filepath.txt", exportTargetStatuses);

        // If you want to analyze the test results yourself, do as follows.
        foreach (var test in testStore.FilteredTests)
        {
            var targetAssetPath = test.AssetPath;
            // This will be Success if the status of the all entries is Success.
            var testStatus = test.LatestStatus.Value;

            foreach (var entry in test.Entries.Values)
            {
                // e.g. Success
                var testEntryStatus = entry.Status.Value;
                // e.g. Max Texture Size: 200 x 200
                var testEntryDescription = entry.Description;
                // e.g. Actual Value: 128 x 128
                var message = entry.Message.Value;
            }
        }
    }
}

Create custom asset filters

You can create your own asset filter by creating a class derived from AssetFilterBase in the Editor folder.

using System;
using AssetRegulationManager.Editor.Core.Model.AssetRegulations;
using AssetRegulationManager.Editor.Core.Model.AssetRegulations.AssetFilterImpl;

[Serializable]
[AssetFilter("Custom Filter", "Custom Filter")] // Required for GUI.
public class CustomAssetFilter : AssetFilterBase
{
    public string AssetPathToMatch { get; set; }

    /// This will be called before and less often than IsMatch.
    /// And will be executed in the main thread, in contrast to IsMatch.
    /// So you should write heavy processes or processes that use Unity's API here.
    public override void SetupForMatching()
    {
    }

    // Return true if the asset passes this filter.
    // This may be executed outside the main thread.
    public override bool IsMatch(string assetPath, Type assetType)
    {
        return AssetPathToMatch == assetPath;
    }

    // A description of this asset filter.
    public override string GetDescription()
    {
        return string.IsNullOrEmpty(AssetPathToMatch) ? string.Empty : $"Asset Path: {AssetPathToMatch}";
    }
}

A class derived from GUIDrawer is also required for GUI.

using AssetRegulationManager.Editor.Foundation.CustomDrawers;
using UnityEditor;

[CustomGUIDrawer(typeof(CustomAssetFilter))]
public sealed class CustomAssetFilterDrawer : GUIDrawer<CustomAssetFilter>
{
    public override void Setup(object target)
    {
        base.Setup(target);

        // If you want to setup this drawer, write here.
    }

    protected override void GUILayout(CustomAssetFilter target)
    {
        target.AssetPathToMatch = EditorGUILayout.TextField("Asset Path", target.AssetPathToMatch);
    }
}

Now you have created the custom asset filter.

Custom Filter
Custom Filter

Create custom asset constraints

You can create your own asset constraint by creating a class derived from AssetConstraint in the Editor folder.

using System;
using System.IO;
using AssetRegulationManager.Editor.Core.Model.AssetRegulations;
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;
using Object = UnityEngine.Object;

[Serializable]
[AssetConstraint("Custom/Custom Constraint", "Custom Constraint")] // Required for GUI.
public sealed class CustomAssetConstraint : AssetConstraint<Object>
{
    [SerializeField] private string _assetName;

    private string _latestValue;

    public string AssetName
    {
        get => _assetName;
        set => _assetName = value;
    }

    // Get a description of this constraint.
    public override string GetDescription()
    {
        return $"Asset Name: {_assetName}";
    }

    // Returns the most recently used value for the test as a string.
    public override string GetLatestValueAsText()
    {
        return string.IsNullOrEmpty(_latestValue) ? "None" : _latestValue;
    }

    // Returns true if the asset is within constraints.
    protected override bool CheckInternal(Object asset)
    {
        Assert.IsNotNull(asset);

        var assetPath = AssetDatabase.GetAssetPath(asset);
        var assetName = Path.GetFileNameWithoutExtension(assetPath);
        _latestValue = assetName;

        return _assetName == assetName;
    }
}

A class derived from GUIDrawer is also required for GUI.

using AssetRegulationManager.Editor.Foundation.CustomDrawers;
using UnityEditor;

[CustomGUIDrawer(typeof(CustomAssetConstraint))]
public sealed class CustomAssetConstraintDrawer : GUIDrawer<CustomAssetConstraint>
{
    public override void Setup(object target)
    {
        base.Setup(target);

        // If you want to setup this drawer, write here.
    }

    protected override void GUILayout(CustomAssetConstraint target)
    {
        target.AssetName = EditorGUILayout.TextField("Asset Name", target.AssetName);
    }
}

Now you have created the custom asset constraint.

Custom Constraint
Custom Constraint

License

This software is released under the MIT license. You are free to use it within the scope of the license, but the following copyright and license notices are required.

In addition, the table of contents for this document has been created using the following software.

See Third Party Notices.md for more information about the license of toc-generator.

About

Tool for Unity to create and run tests of Asset Regulations (texture size, number of vertices, etc.), and automate running.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages