< All Topics

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

ParameterTypeDescription
Path to ZipStringFull absolute path to the ZIP file you want to extract
Delete After ExtractionBooleanIf true, deletes the ZIP file after successful extraction
Get ProgressZip Progress DelegateCallback function that receives progress updates (0.0 to 1.0)
CallbackUnzip Task Complete DelegateCallback function executed when extraction completes

Output Parameters

ParameterTypeDescription
Return ValueZip TaskReference 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

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

  1. Always show progress for large archives
  2. Provide meaningful status messages during extraction
  3. Allow cancellation for long operations
  4. Display extracted file list for user confirmation

Performance

  1. Use for archives >10MB or >20 files
  2. Process files incrementally in completion callback
  3. Monitor disk space before extraction
  4. Clean up temporary files after processing

Error Handling

  1. Validate ZIP file exists before extraction
  2. Check disk space for large archives
  3. Handle file permission issues gracefully
  4. 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
Table of Contents