Skip to content

Custom Updater Tutorial

The Updater class forms the cornerstone of the client-side updating mechanism for your game or application. This tutorial provides a step-by-step guide on customizing and creating your own Updater using various components tailored to your requirements.

Understanding the Updater Class

The Updater class orchestrates the update process, interfacing with various components like VersionManager, Downloader, Installer, and Launcher. For detailed insights into each component's role and functionality, please refer to the Classes section in this documentation.

The Updater class manages everything from checking versions to downloading and installing updates, as well as launching the updated application.

Key Components of the Updater Class

  • Platform: Identifies the platform (e.g., Windows, Linux, etc.) for which the Updater supports (abstract property).
  • VersionManager: Handles the local and remote version checking.
  • Downloader: Responsible for downloading the necessary update files.
  • Installer: Manages the installation of downloaded updates.
  • Launcher: Responsible for launching the application.

Creating a Custom Updater

To create a custom updater, you need to extend the Updater abstract class. Here's an outline to get started:

using ByteCobra.Logging;
using ByteCobra.Updater.Models;
using System.Threading;
using System.Threading.Tasks;

namespace ByteCobra.Updater
{
    public class MyCustomUpdater : Updater
    {
        // Constructor and additional method implementations
    }
}

Implementing the UpdateAsync Method

One of the crucial methods to implement in your custom updater is UpdateAsync. This method orchestrates the entire update process, including version checks, downloading, and installation. Here's a simplified overview of its typical workflow:

  • Check Local Version: Determine if the application is installed and identify the installed version.
  • Fetch Remote Version: Get the latest version available on the server.
  • Compare Versions: Decide whether an update is needed based on the local and remote version comparison.
  • Download and Install Updates: If an update is required, download the necessary files and install them.
  • Launch Application: The application can be configured to launch automatically after an update completes. Alternatively, you have the flexibility to trigger the launcher externally, such as through a button in the user interface, allowing for more user control over when the application starts post-update.

Customizing your updater allows you to tailor the update process to fit your specific needs. You might want to add extra steps, such as pre-update checks, custom logging, or post-update cleanup tasks.

Updater Behaviour

The UpdaterBehaviour class in Unity serves as an interface between Unity's game engine and the core updater logic. This MonoBehaviour-derived class wraps around the Updater C# class, facilitating the execution of the update process within the Unity environment.

The UpdaterBehaviour class allows Unity developers to incorporate the custom updater logic into their game with ease. It manages the update process by leveraging Unity's event-driven architecture and provides customizable properties through the Unity Inspector.

Workflow

  • Initialization: On start, the UpdaterBehaviour kicks off the update process.
  • Update Process: It calls the UpdateAsync method, which should contain the logic to manage the update sequence (version check, downloading & installing a new version if needed).
  • Launch Control: Based on the AutoLaunch property, the application either launches automatically or waits for an external trigger, such as a button.

Implementing UpdaterBehaviour

Here's an example for implementing a custom UpdaterBehaviour that uses a custom Updater in your Unity project:

CustomUpdaterBehaviour

using ByteCobra.Updater;
using ByteCobra.Updater.Unity;
using UnityEngine;

public class CustomWebUpdaterBehaviour : WebUpdaterBehaviour
{
    protected override Updater Updater => CustomUpdater;
    protected CustomUpdater CustomUpdater { get; private set; }

    protected override void Awake()
    {
        base.Awake();
        CustomUpdater = new CustomUpdater(
            ApplicationName, 
            WebVersionBehaviour.VersionManager, 
            DownloaderBehaviour.Downloader, 
            DirectoryInstaller.DirectoryInstaller, 
            WindowsLauncher.WindowsLauncher);
    }

    protected override async void Start()
    {
        // Check internet
        if (Application.internetReachability != NetworkReachability.NotReachable)
        {
            await UpdateAsync();
        }
        else
        {
            // Launch the application if no internet
            await WindowsLauncher.Launcher.LaunchAsync();
        }
    }
}

CustomUpdater

using ByteCobra.Updater;
using ByteCobra.Updater.Client.Launchers;
using ByteCobra.Updater.Installers;
using ByteCobra.Updater.Updaters;
using System;
using System.Threading;
using System.Threading.Tasks;

public class CustomUpdater : WindowsUpdater
{
    public CustomUpdater(
        string applicationName, 
        VersionManager versionManager, 
        Downloader downloader, 
        DirectoryInstaller installer, 
        WindowsLauncher launcher)
        : base(
            applicationName, 
            versionManager, 
            downloader, 
            installer, 
            launcher)
    {
    }

    public override async Task UpdateAsync(
        bool autoLaunch, 
        CancellationToken cancellationToken)
    {
        try
        {
            // Check if autoLaunch is true and try to launch the app
            if (autoLaunch)
            {
                bool launched = 
                    await Launcher.LaunchAsync();

                if (!launched)
                {
                    // Implement your logic here 
                    // in case the launch fails
                }
            }
        }
        // Logic to handle exceptions, possibly including 
        // launching the app without update
        catch (Exception ex)
        {
            if (autoLaunch)
            {
                bool launched = await Launcher.LaunchAsync();
                if (!launched)
                {
                    // Implement your logic here in case the launch fails
                }
            }
        }
    }
}

Swap out the default UpdaterBehaviour in your scene with the custom one (in this case CustomWebUpdaterBehaviour).

Customization Tips

  • Adding UI Elements: You can extend UpdaterBehaviour to interact with Unity UI elements, such as showing update progress or triggering updates through buttons. The example scene demonstrates how you can add a text that shows the update progress.
  • Handling User Input: Integrate user input to control when and how updates are applied, offering a more interactive experience.
  • Logging and Feedback: Implement custom logging and feedback mechanisms within Unity to provide real-time update status to users.