This set of Blueprint scripts were created as part of my work at Crowbar Collective, to handle project-wide asset validations for Unreal asset types which are most often imported or authored by artists, such as StaticMesh
, Texture2D
, MaterialInstance
, and so on.
While it's possible to inspect many assets in bulk using the asset audit tool (Alt-Shift-A), the built-in Data Validation plugin offers a framework for creating custom validator scripts which execute from a contextual action in the content browser (Asset Actions > Validate) or automatically at the time of save.
It would even be possible to extend these scripts to modify the asset(s) and correct any issues discovered during validation. However, it was left up to the user to make the corrections for two reasons:
- Other scripts could be created to modify the asset, as a separation of behaviours. This would possibly be even more useful since a different context menu action could be created to apply a preset 'profile' of settings to an asset with a single click.
- Maintaining the separation of 'validation' and 'asset setup/modification' also seems very important. At some point, we will probably want to audit and validate all of the project's assets (or some subset of them) in a batch. Any error in this process could potentially damage valid assets or cause a cascading series of other problems.
I created a base class validator (deriving from UEditorValidatorBase
) as there were some common behaviours to share across every custom validator script. Primarily, there is an option for "project-specific" validation, checking only the assets under Content/GameName/ directory rather than under the entire Content/ root. In some cases we wanted to import plugin or external assets in folders outside of our content structure, and only cared about validations when the assets became folded into our project structure (if at all). There is also a common behaviour to handle ignored assets, when the asset was assigned an 'ignore validation' metadata tag.
The baseclass provides a stub for the ValidateLoadedAsset
function inherited from UEditorValidatorBase
. The derived validator classes are expected to override this and provide behaviour to determine a given asset's validity here. Another stub is provided for the inherited CanValidateAsset
function but the expectation is for derived classes to extend the function and incorporate it into the class-specific validation.
For example, the StaticMeshValidator incorporates the parent class CanValidateAsset
stub into the check which determines if the asset is of the StaticMesh
type. Its ValidateLoadedAsset
function provides the unique validation behaviour to apply to static meshes. In this case, the only condition is trivial - checking that the mesh asset names are formatted in (lowercase) camelCase, a project-specific rule. The asset is determined to pass or fail validation based on that condition.
Other scripts were implemented for different asset types - Blueprints, Animations, Materials, Meshes, Textures, and different data tables. The texture validator is one of the most complex since it has to account for the many types of textures and their various settings. The ValidateLoadedAsset
function handles some special cases and exclusions, checks the texture name for an appropriate suffix, and then checks certain properties based on the texture type (color, normal, packed masks, etc). That meant creating an additional function (ValidateTexture2D
) to evaluate an arbitrary Texture2D
object against reference values specified for compression, texture groups, and sRGB setting.
The (small) amount of time invested to create these scripts seemed worthwhile, as they immediately began to solve long-embedded issues relating to asset naming and property conventions. When validation issues are detected during save, a notification provides specific contextual information, so artists and designers were increasingly empowered (and encouraged) to solve issues in the moment, rather than waiting for reviews, asset audits, or technical support.
Finally, the following image (click for large, or new tab for full) shows an overview of the ValidateLoadedAsset
function for another class responsible for checking the project's DataTable
of weapon properties. Any weapons (table rows) which are configured incorrectly can be identified when the asset is saved, which provides an additional layer of sanity checking.