For the resource inspection requirements in the project, it needs to be simple and convenient to configure, automate execution, and be able to promptly locate related personnel. Based on this requirement, I have open-sourced a resource compliance scanning tool ResScannerUE, with configuration documentation: UE Resource Compliance Inspection Tool ResScannerUE.
This article will introduce how to achieve automated resource scanning through this tool, provide support for incremental detection combined with Git, use Commandlet to automatically trigger and execute detection rules for Content content changes on CI platforms, and be able to locate the most recent committers of problematic resources, achieving precise positioning and real-time scanning report sending to corporate WeChat, reminding relevant personnel to take action.
Additionally, I also provide a Git-based Pre-Commit Hook implementation, allowing detection of non-compliant resources before submitting and prohibiting the submission, thus avoiding the contamination of remote repositories with problematic resources. The overall solution has been meticulously designed and extensively optimized for experience and enhanced automation support, making it very convenient to configure and integrate, capable of meeting various resource scanning needs.
In the plugin, it is possible to configure paths and resource lists for each rule, and it also provides global resource paths and resource lists used for all rules, supporting the suppression of configurations in each rule.
By controlling global resources and suppressing resource configurations in single rules, it can precisely control which resources undergo all rules checks, which is the basis for achieving automated resource scanning.
To implement automated resource scanning, it can be divided into two parts based on different needs:
- Full scan
- Incremental scan
The full scan goes without saying; you simply need to specify the global resource /Game
and other Root directories in the plugin, suppress the resources configured in the rules, and export a configuration. For incremental scans, I provide two solutions in the plugin: detection based on a file list and detection based on Git version comparison.
File List Detection
If you want to dynamically specify which resources to check rather than pre-specifying them in the configuration, I have provided functionality in the ResScanner
commandlet to specify a file list. You can add -filecheck
and -filelist
to the execution parameters to specify the file list, separating files with a comma.
1 | UE4Editor.exe Project.uproject -run="ResScanner" -config="ScannerConfig.json" -filecheck -filelist="Asset/A.uasset,Asset/B.uasset" |
This method requires passing all files to be checked externally.
Git Version Comparison Detection
Typically, project repositories are divided into two parts:
- Code repository: basic project structure, code, configurations, etc.
- Resource repository: Content
This is used to isolate the working environments of art and programming from each other. For most resource management situations, version control tools like Git are used for management. Therefore, it is necessary to extract the file list from each commit in the resource repository managed by Git and pass it to ResScanner for specific resource checks.
The original Git comparison between two commits can be done using the following command:
1 | git diff --name-only HEAD~ HEAD |
This can be used to get the file changes between the last two commits, thus obtaining the original list of changed files.
Usually, this part of the logic would be implemented through scripts such as Python, but since this demand is relatively general, I provide support directly in ResScannerUE. When we want to perform rule checks using Git versions, we can enable the provided GitChecker
through the plugin.
Git’s version comparison and committer retrieval are based on a tool I previously open-sourced: GitControllerUE, which is a plugin for UE capable of obtaining Git repository version information.
Based on it, ResScannerUE can automatically scan the most recent commit record changes in files and check for non-compliance in submissions. By default, it checks the most recent commit, but if you want to specify more commits, you only need to modify the hash value of the starting commit in the configuration.
The following configuration example scans the files of the latest Git commit for texture naming checks:
1 | { |
You just need to specify this config when executing the Commandlet:
1 | UE4Editor.exe Project.uproject -run="ResScanner" -config="Full_Scan_Config.json" |
Additionally, in the GitChecker
configuration, there is an option to record the submitter of the files. Here, I made a trick: in the storage structure of the scanning results, there are two arrays:
1 | USTRUCT(BlueprintType) |
The scanning result will be serialized into JSON. By default, both arrays will be serialized, but this is not our requirement. When bRecordCommiter
is off, only the AssetPackageNames
of the scanned resources will be serialized; conversely, AssetsCommiter
will be serialized. We can control the serialization based on whether FProperty
has the CPF_Transient
FLAG. If this FLAG is included, the Property will not be serialized.
Thus, before each serialization of the scanning result, I will perform a marking action, deciding which property to add CPF_Transient
based on the configuration:
1 | // set CPF_Transient to AssetPackageNames or AssetsCommiter |
Call these two functions before each serialization:
1 | FRuleMatchedInfo::ResetTransient(); |
Thus achieving on-demand serialization effect:
Detection of Uncommitted Files
The previous section introduced detection of resource changes between two committed versions. If the resources are not committed, another mechanism needs to be employed.
Uncommitted files refer to those files with local modifications that have not been committed:
1 | $ git status |
Based on the detection of uncommitted files, it is possible to perform resource scanning before submitting and prohibit non-compliant submissions. This will be detailed in the following implementation of the pre-commit hook.
In the plugin, there are options in the GitChecker
configuration:
1 | "gitChecker": |
There are two modes for Git detection:
- bDiffCommit: comparison of resource scans based on the two Commit HASH versions
- bUncommitFiles: scanning uncommitted resources
Both modes can be enabled as needed; typically, scheduled scans will enable bDiffCommit
, while pre-submission checks will use bUncommitFiles
.
Commandlet Parameter Replacement
To further facilitate executing scan tasks through Commandlet, I have also added parameter replacement functionality to the commandlet of ResScannerUE. You can dynamically replace options in the configuration file while specifying it through command line parameters, achieving more powerful automation capabilities.
For example, you can disable global resource configurations or choose whether to store scan results via the command line:
1 | UE4Editor.exe Project.uproject -run="ResScanner" -config="Full_Scan_Config.json" -bByGlobalScanFilters=false -savePath.path="D:\" |
And you can specify the starting commit HASH for Git version scans:
1 | UE4Editor.exe Project.uproject -run="ResScanner" -config="Full_Scan_Config.json" -gitChecker.bGitCheck=true -gitchecker.beginCommitHash=HEAD~ -gitchecker.endCommitHash=HEAD |
Properties in the plugin can be specified in the manner of -ProjectName=Value
. This way, it achieves the requirement of providing a basic configuration, while dynamically controlling the behavior of parameters in the configuration via the command line, exposing more optional parameters when integrated into CI systems.
Corporate WeChat Reminder
Based on the commandlet mechanism of ResScannerUE, it is very convenient to integrate corporate WeChat reminders. After submitting resources, the system automatically checks the submitted resources and sends group notifications:
The entire process only requires:
- Python to launch the commandlet of ResScannerUE
- Check the return value of the commandlet for any hit resources (returns
-1
) - Read the
Saved/ResScanner/*_result.json
file - Use Python to send corporate WeChat messages
Here, I provide an example:
1 | import os |
Usage method:
1 | python3 resscanner_notice.py |
By passing these parameters, you can launch ResScanner for scanning and notify the results to corporate WeChat.
Pre-Commit Hook
The previous automation process primarily triggered detection and report sending after submission. Essentially it’s a process of problem occurs first, problem solved later.
So, can we eliminate the contamination of erroneous resources to the trunk at an early stage, detecting whether resources are compliant before everyone submits? If non-compliant, submission should be prohibited.
The answer is yes. We can combine the GitChecker.bUncommitFiles
provided by ResScannerUE (see Detection of Uncommitted Files) with Git’s Pre-Commit Hook mechanism to achieve:
- Execute the Hook script during Commit
- The Hook script launches the commandlet of ResScannerUE to conduct compliance scanning of uncommitted resources (
GitChecker.bUncommitFiles = true
) - Obtain the exit code of the commandlet. If there are non-compliant resources, stop the commit and prompt about the non-compliance.
The script to be executed by the Git Pre-Commit Hook is as follows:
1 | #coding=utf-8 |
Place it in the root directory of Content
, create a pre-commit
file under Content/.git/hooks
, and fill it with the following sh script:
1 |
|
Execution effect:
Combining with some Git GUI clients can achieve a friendly prompt effect:
Conclusion
This article introduces the engineering practice of automating resource scanning based on ResScannerUE, which can easily integrate resource scanning into various processes of the development pipeline.