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): trueif extraction succeeded,falseif 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::CancelCurrentOperation();
            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
