Unzip multiple files (async)
Asynchronous Unzip Files Function
Overview
The Unzip Files (async) function extracts files from a ZIP archive in the background without blocking the main thread. This is the professional-grade solution for extracting large archives while maintaining responsive gameplay and UI.
Function Description
Node Name: Unzip Files (async)
Category: Archive Manager
Type: Asynchronous (non-blocking operation)
Extracts all files from a ZIP archive in a background thread with real-time progress tracking and completion callbacks. The main thread continues execution immediately while extraction happens in the background.
Blueprint Usage
Input Parameters
Parameter | Type | Description |
---|---|---|
Path to Zip | String | Full absolute path to the ZIP file you want to extract |
Delete After Extraction | Boolean | If true, deletes the ZIP file after successful extraction |
Get Progress | Zip Progress Delegate | Callback function that receives progress updates (0.0 to 1.0) |
Callback | Unzip Task Complete Delegate | Callback function executed when extraction completes |
Output Parameters
Parameter | Type | Description |
---|---|---|
Return Value | Zip Task | Reference to the background task (can be used for cancellation) |
Delegate Parameters
Unzipping_progress (Custom Event)
- Progress (Float): Extraction progress from 0.0 (0%) to 1.0 (100%)
Unzipping_complete (Custom Event)
- Success (Boolean):
true
if extraction succeeded,false
if failed - Path to Files (Array of Strings): Full paths to all extracted files (on success)
Blueprint Setup Steps
1. Create Custom Events for Callbacks
- Unzipping_progress Event: Right-click → Add Custom Event → Name: “Unzipping_progress”
- Add input parameter: Progress (Float)
- Unzipping_complete Event: Right-click → Add Custom Event → Name: “Unzipping_complete”
- Add input parameter: Success (Boolean)
- Add input parameter: Path to Files (Array of Strings)
2. Add the Unzip Files (async) Node
- Search for “Unzip Files (async)”
- Set Path to Zip: absolute path
- Set Delete After Extraction: ☐ (keep original ZIP file)
3. Connect Progress Tracking
- Connect Unzipping_progress custom event to Get Progress delegate
- Add Format Text node to display progress:
- Format:
"Unzipping: {Progress}%"
- Connect Progress × 100 to format parameter
- Format:
4. Connect Completion Callback
- Connect Unzipping_complete custom event to Callback delegate
- Add For Each Loop to iterate through extracted files:
- Connect Path to Files array to For Each Loop input
- Display each file path using Print String
5. Add Final Completion Message
- After the For Each Loop, add Print String: “Unzipping complete”
Example Blueprint Setup

C++ Usage
Basic Async Implementation
#include "ArchiveManagerBPLibrary.h"
// Async extraction with C++ delegates
FString ZipPath = TEXT("C:/Archives/GameAssets.zip");
bool DeleteAfterExtraction = false;
// Create progress delegate
FZipProgressDelegate ProgressDelegate;
ProgressDelegate.BindUFunction(this, FName("OnExtractionProgress"));
// Create completion delegate
FUnzipTaskCompleteDelegate CompleteDelegate;
CompleteDelegate.BindUFunction(this, FName("OnExtractionComplete"));
// Start async extraction
UZipTask* Task = UArchiveManagerBPLibrary::UnzipFilesAsync(
ZipPath,
DeleteAfterExtraction,
ProgressDelegate,
CompleteDelegate
);
// Store task reference for potential cancellation
CurrentUnzipTask = Task;
Advanced C++ Implementation with Lambda Callbacks
UCLASS()
class MYGAME_API UAsyncExtractManager : public UObject
{
GENERATED_BODY()
private:
UZipTask* CurrentTask;
TArray<FString> ExtractedFiles;
public:
// Start async extraction with C++ lambda callbacks
void ExtractArchiveAsync(const FString& ZipPath, const FString& DestinationDir = TEXT(""))
{
// Validate ZIP file exists
if (!FPaths::FileExists(ZipPath))
{
UE_LOG(LogTemp, Error, TEXT("ZIP file not found: %s"), *ZipPath);
OnExtractionFailed.Broadcast(TEXT("ZIP file not found"));
return;
}
// Progress callback using lambda
FZipProgressDelegate ProgressDelegate;
ProgressDelegate.BindLambda([this](float Progress) {
float Percentage = Progress * 100.0f;
UE_LOG(LogTemp, Log, TEXT("Extraction Progress: %.1f%%"), Percentage);
// Update UI progress bar
OnProgressUpdated.Broadcast(Progress);
});
// Completion callback with file processing
FUnzipTaskCompleteDelegate CompleteDelegate;
CompleteDelegate.BindLambda([this, DestinationDir](bool bSuccess, const TArray<FString>& ExtractedPaths) {
if (bSuccess)
{
ExtractedFiles = ExtractedPaths;
UE_LOG(LogTemp, Log, TEXT("Extraction completed. %d files extracted"), ExtractedPaths.Num());
// Process each extracted file
for (const FString& FilePath : ExtractedPaths)
{
UE_LOG(LogTemp, Log, TEXT("Extracted: %s"), *FilePath);
ProcessExtractedFile(FilePath);
}
OnExtractionSuccess.Broadcast(ExtractedPaths);
}
else
{
FString Error = UArchiveManagerBPLibrary::GetLastArchiveError();
UE_LOG(LogTemp, Error, TEXT("Extraction failed: %s"), *Error);
OnExtractionFailed.Broadcast(Error);
}
CurrentTask = nullptr;
});
// Start extraction
CurrentTask = UArchiveManagerBPLibrary::UnzipFilesAsync(
ZipPath, false, ProgressDelegate, CompleteDelegate
);
}
// Process individual extracted files
void ProcessExtractedFile(const FString& FilePath)
{
FString Extension = FPaths::GetExtension(FilePath).ToLower();
if (Extension == TEXT("txt") || Extension == TEXT("log"))
{
// Process text files
FString FileContent;
if (FFileHelper::LoadFileToString(FileContent, *FilePath))
{
UE_LOG(LogTemp, Log, TEXT("Loaded text file: %s (%d chars)"), *FilePath, FileContent.Len());
}
}
else if (Extension == TEXT("json"))
{
// Process JSON configuration files
LoadConfigurationFile(FilePath);
}
else if (Extension == TEXT("uasset") || Extension == TEXT("umap"))
{
// Handle Unreal asset files
QueueAssetForImport(FilePath);
}
}
// Cancel current operation
UFUNCTION(BlueprintCallable)
void CancelExtraction()
{
if (CurrentTask)
{
UArchiveManagerBPLibrary::Cancel();
CurrentTask = nullptr;
UE_LOG(LogTemp, Log, TEXT("Extraction cancelled"));
OnExtractionCancelled.Broadcast();
}
}
// Get list of extracted files
UFUNCTION(BlueprintCallable, BlueprintPure)
TArray<FString> GetExtractedFiles() const { return ExtractedFiles; }
// C++ delegates for UI integration
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnProgressUpdated, float, Progress);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnExtractionSuccess, const TArray<FString>&, ExtractedFiles);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnExtractionFailed, FString, ErrorMessage);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnExtractionCancelled);
UPROPERTY(BlueprintAssignable)
FOnProgressUpdated OnProgressUpdated;
UPROPERTY(BlueprintAssignable)
FOnExtractionSuccess OnExtractionSuccess;
UPROPERTY(BlueprintAssignable)
FOnExtractionFailed OnExtractionFailed;
UPROPERTY(BlueprintAssignable)
FOnExtractionCancelled OnExtractionCancelled;
private:
void LoadConfigurationFile(const FString& JsonPath) { /* Implementation */ }
void QueueAssetForImport(const FString& AssetPath) { /* Implementation */ }
};
Synchronous Wrapper for Simple Cases
// Simple synchronous extraction wrapper
TArray<FString> ExtractArchiveSync(const FString& ZipPath)
{
TArray<FString> ExtractedFiles;
bool bSuccess = UArchiveManagerBPLibrary::UnzipFiles(ZipPath, ExtractedFiles, false);
if (bSuccess)
{
UE_LOG(LogTemp, Log, TEXT("Successfully extracted %d files"), ExtractedFiles.Num());
}
else
{
FString Error = UArchiveManagerBPLibrary::GetLastArchiveError();
UE_LOG(LogTemp, Error, TEXT("Extraction failed: %s"), *Error);
ExtractedFiles.Empty();
}
return ExtractedFiles;
}
Advanced Features
File Processing During Extraction
The For Each Loop in the completion callback allows you to process each extracted file individually:
- Validate file integrity
- Load configuration files
- Import assets into the project
- Update UI with extracted content
Progress Monitoring
Real-time progress updates help create responsive user experiences:
- Update loading bars
- Show current extraction status
- Estimate remaining time
- Provide user feedback
Error Handling
You can use the Last archive error node in the completion callback:
Unzipping_complete Event
↓
Branch (Success)
├─ True: For Each Loop → Process Files
└─ False: Get Last Archive Error → Display Error Message
Common Use Cases
Game Development
- DLC Loading: Extract downloadable content packages
- Save Game Restoration: Extract backup save files
- Asset Streaming: Load compressed game assets
- User Content: Extract player-created content
Application Development
- Document Processing: Extract archived documents
- Data Import: Extract CSV/JSON data files
- Backup Restoration: Restore backed-up files
- Update Deployment: Extract application updates
Best Practices
User Experience
- Always show progress for large archives
- Provide meaningful status messages during extraction
- Allow cancellation for long operations
- Display extracted file list for user confirmation
Performance
- Use for archives >10MB or >20 files
- Process files incrementally in completion callback
- Monitor disk space before extraction
- Clean up temporary files after processing
Error Handling
- Validate ZIP file exists before extraction
- Check disk space for large archives
- Handle file permission issues gracefully
- Provide recovery options on failure
Threading and Memory Notes
- Background extraction: Files are extracted on worker thread
- Main thread callbacks: Progress and completion callbacks execute on main thread
- Memory efficiency: Files are extracted incrementally, not loaded into memory
- File system safety: All file operations are thread-safe