Zip multiple files (async)
Overview
The Zip Files (async) function compresses multiple files into a ZIP archive in the background without blocking the main thread. This is the solution for compressing large files or multiple files while maintaining responsive gameplay and UI.
Function Description
Node Name: Zip Files (async)
Category: Archive Manager
Type: Asynchronous (non-blocking operation)
Compresses multiple files in a background thread with real-time progress tracking and completion callbacks. The main thread continues execution immediately while compression happens in the background.
Input Parameters
Parameter | Type | Description |
---|---|---|
Path to Files | Array of Strings | Array containing full absolute paths to all files you want to compress |
Path to Zip | String | Full absolute path where the ZIP file should be created |
Delete After Compression | Boolean | If true, deletes all original files after successful compression |
Get Progress | Zip Progress Delegate | Callback function that receives progress updates (0.0 to 1.0) |
Callback | Zip Task Complete Delegate | Callback function executed when compression completes |
Output Parameters
Parameter | Type | Description |
---|---|---|
Return Value | Zip Task | Reference to the background task (can be used for cancellation) |
Delegate Parameters
ZipProgress (Custom Event)
- Progress (Float): Compression progress from 0.0 (0%) to 1.0 (100%)
OnZipComplete (Custom Event)
- Success (Boolean):
true
if compression succeeded,false
if failed - Path to Zip File (String): Full path to the created ZIP file (on success)
Setup Steps
1. Create Custom Events for Callbacks
- ZipProgress Event: Right-click → Add Custom Event → Name: “ZipProgress”
- Add input parameter: Progress (Float)
- OnZipComplete Event: Right-click → Add Custom Event → Name: “OnZipComplete”
- Add input parameter: Success (Boolean)
- Add input parameter: Path to Zip File (String)
2. Create the File Array
- Add Make Array node with file paths
- Example: Single large file
F:\Repos\tests\ArchiveManager\asset_file_200mb.psd
3. Add the Zip Files (async) Node
- Search for “Zip Files (async)”
- Connect the array to Path to Files
- Set absolute Path to Zip
4. Connect Progress Tracking
- Connect ZipProgress custom event to Get Progress delegate
- Add Format Text node to display progress:
- Format:
"Progress: {Progress}%"
- Connect Progress × 100 to format parameter
- Format:
5. Connect Completion Callback
- Connect OnZipComplete custom event to Callback delegate
- Add Format Text node to display result:
- Format:
"File zipped and saved at: {Path}"
- Connect Path to Zip File to format parameter
- Format:
6. Add Progress Display (Optional)
- Connect formatted progress text to Print String
- This provides real-time feedback during compression
Example Blueprint Setup

Advanced Features
Progress Monitoring
The progress callback fires regularly during compression:
- 0.0: Compression starting
- 0.5: 50% complete
- 1.0: Compression finished
Task Reference
The returned Zip Task can be used with:
- Cancel Current Operation: Stop compression mid-process
- Task status monitoring
- Multiple simultaneous operations
Error Handling in Completion Callback
Use Last Archive Error node to access and print errors.
Common Use Cases
Large File Compression
- Video files, assets, or databases
- Background compression while user continues working
- Progress feedback for user experience
Batch Processing
- Multiple document compression
- Asset pipeline automation
- Backup operations
Game Development
- Save game compression with progress bar
- Asset bundling for downloadable content
- User-generated content packaging
Best Practices
User Experience
- Always show progress for operations > 2 seconds
- Provide cancel option for long operations
- Display meaningful status messages
- Handle completion gracefully (success/failure feedback)
Performance
- Use for files > 10MB or > 50 files
- Limit concurrent operations (max 2-3 simultaneous)
- Monitor memory usage during compression
- Consider file size limits (test with your largest expected files)
Error Handling
- Always implement completion callback
- Check Success parameter before proceeding
- Use Get Last Archive Error for failure details
- Validate file paths before starting operation
Threading Notes
- Main thread continues: UI remains responsive
- Background processing: Compression runs on worker thread
- Callback execution: Delegates fire on main thread (safe for UI updates)
- Memory sharing: Arrays are safely copied to background thread
Cancellation Support
Use Cancel current operation node in level blueprint or pawn controller blueprint to cancel the operation.
Performance Characteristics
- Startup overhead: ~50ms to initialize background task
- Memory usage: Peak usage = largest file size + ZIP overhead
- Progress frequency: Updates every ~100KB processed
- Completion delay: Callback fires within 1 frame of completion
C++ Usage
Basic Async Implementation
#include "ArchiveManagerBPLibrary.h"
UCLASS()
class MYGAME_API UAsyncCompressionManager : public UObject
{
GENERATED_BODY()
private:
UZipTask* CurrentTask;
public:
// Start async compression with proper UFunction delegates
UFUNCTION(BlueprintCallable)
void CompressLargeFilesAsync()
{
// Prepare file list (SAME as original article)
TArray<FString> LargeFiles;
LargeFiles.Add(TEXT("C:/LargeAssets/Video.mp4"));
LargeFiles.Add(TEXT("C:/LargeAssets/Texture.psd"));
FString OutputZip = TEXT("C:/Archives/LargeAssets.zip");
// bind to UFunction instead of lambda
FZipProgressDelegate ProgressDelegate;
ProgressDelegate.BindUFunction(this, FName("OnCompressionProgress"));
FZipTaskCompleteDelegate CompleteDelegate;
CompleteDelegate.BindUFunction(this, FName("OnCompressionComplete"));
// Start async compression (SAME function call as original)
CurrentTask = UArchiveManagerBPLibrary::ZipFilesAsync(
LargeFiles,
OutputZip,
false,
ProgressDelegate,
CompleteDelegate
);
}
// Progress callback function (required for UFunction binding)
UFUNCTION()
void OnCompressionProgress(float Progress)
{
float Percentage = Progress * 100.0f;
UE_LOG(LogTemp, Log, TEXT("Compression Progress: %.1f%%"), Percentage);
// Update UI progress bar here
OnProgressUpdated.Broadcast(Progress);
}
// Completion callback function (required for UFunction binding)
UFUNCTION()
void OnCompressionComplete(bool bSuccess, const FString& ZipPath)
{
if (bSuccess)
{
UE_LOG(LogTemp, Log, TEXT("Compression completed: %s"), *ZipPath);
OnCompressionSuccess.Broadcast(ZipPath);
}
else
{
FString Error = UArchiveManagerBPLibrary::GetLastArchiveError();
UE_LOG(LogTemp, Error, TEXT("Compression failed: %s"), *Error);
OnCompressionFailed.Broadcast(Error);
}
CurrentTask = nullptr;
}
// Cancel current operation
UFUNCTION(BlueprintCallable)
void CancelCompression()
{
if (CurrentTask)
{
UArchiveManagerBPLibrary::Cancel();
CurrentTask = nullptr;
UE_LOG(LogTemp, Log, TEXT("Compression cancelled"));
}
}
// C++ delegates for UI integration
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnProgressUpdated, float, Progress);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCompressionSuccess, FString, ZipPath);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCompressionFailed, FString, ErrorMessage);
UPROPERTY(BlueprintAssignable)
FOnProgressUpdated OnProgressUpdated;
UPROPERTY(BlueprintAssignable)
FOnCompressionSuccess OnCompressionSuccess;
UPROPERTY(BlueprintAssignable)
FOnCompressionFailed OnCompressionFailed;
};
Simple one-shot usage
// For simple cases where you don't need progress tracking
void CompressFilesSimple()
{
TArray<FString> FilesToCompress = {
TEXT("C:/Data/File1.txt"),
TEXT("C:/Data/File2.txt")
};
FString OutputZip = TEXT("C:/Output/Compressed.zip");
// Create empty delegates for simple usage
FZipProgressDelegate EmptyProgress;
FZipTaskCompleteDelegate EmptyComplete;
// Start compression (fire and forget)
UZipTask* Task = UArchiveManagerBPLibrary::ZipFilesAsync(
FilesToCompress,
OutputZip,
false,
EmptyProgress,
EmptyComplete
);
// Optional: Store task reference for cancellation
// UArchiveManagerBPLibrary::Cancel(); // Cancel if needed
}
Integration with Game Save System
UCLASS()
class MYGAME_API USaveGameCompressor : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
// Async save game compression
UFUNCTION(BlueprintCallable)
void CompressSaveGamesAsync()
{
// Collect all save files (SAME as original article)
TArray<FString> SaveFiles;
FString SaveDir = FPaths::ProjectSavedDir() / TEXT("SaveGames");
IFileManager::Get().FindFiles(SaveFiles, *SaveDir, TEXT("*.sav"), true, false);
// Convert to full paths (SAME as original)
TArray<FString> FullPaths;
for (const FString& SaveFile : SaveFiles)
{
FullPaths.Add(SaveDir / SaveFile);
}
if (FullPaths.Num() == 0)
{
UE_LOG(LogTemp, Warning, TEXT("No save files found"));
return;
}
// Create timestamped backup (SAME as original)
FString BackupName = FString::Printf(TEXT("SaveBackup_%s.zip"),
*FDateTime::Now().ToString(TEXT("%Y%m%d_%H%M%S")));
FString BackupPath = FPaths::ProjectSavedDir() / TEXT("Backups") / BackupName;
// Ensure backup directory exists
IFileManager::Get().MakeDirectory(*FPaths::GetPath(BackupPath), true);
// Setup progress tracking with UFunction binding
FZipProgressDelegate ProgressDelegate;
ProgressDelegate.BindUFunction(this, FName("OnBackupProgress"));
// Setup completion callback with UFunction binding
FZipTaskCompleteDelegate CompleteDelegate;
CompleteDelegate.BindUFunction(this, FName("OnBackupComplete"));
// Start async compression (SAME function call as original)
UArchiveManagerBPLibrary::ZipFilesAsync(FullPaths, BackupPath, false, ProgressDelegate, CompleteDelegate);
}
// Progress callback (required for UFunction binding)
UFUNCTION()
void OnBackupProgress(float Progress)
{
// Update loading screen or progress bar
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Green,
FString::Printf(TEXT("Backup Progress: %.0f%%"), Progress * 100.0f));
}
}
// Completion callback (SAME logic as original)
UFUNCTION()
void OnBackupComplete(bool bSuccess, const FString& BackupPath)
{
if (bSuccess)
{
UE_LOG(LogTemp, Log, TEXT("Save game backup completed: %s"), *BackupPath);
// Notify UI or save system
}
else
{
UE_LOG(LogTemp, Error, TEXT("Save game backup failed"));
}
}
};