Search Unity

Showcase Simple Self-Updater Implementation (Free script!)

Discussion in 'Scripting' started by JudahMantell, Jun 2, 2022.

  1. JudahMantell

    JudahMantell

    Joined:
    Feb 28, 2017
    Posts:
    476
    After going back and forth searching for an easy way to update my app, I wrote this simple self-updater implementation. It's nothing super innovative, but figured it might be useful nonetheless!

    All of the options on the asset store are for patching, which is great but in my case not needed as the application is relatively small. Previously I was checking for updates from a JSON file on my website, then opening the download page if the user wants to "Update Now". But I wanted to automate it even further, giving the illusion of a launcher without the need for an extra application.

    The script includes some UI code (progress bar) which can be easily altered to fit your needs.
    (Switching to a different scene is an idea, instead of showing a UI element). It also automatically resizes the game window to give the illusion of a separate application, but that can be removed easily if not needed.

    I'm open to any feedback or suggestions!
    Code (CSharp):
    1.  
    2. #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_WSA_10_0 || WINDOWS_UWP
    3. #define UNITY_WINDOWS
    4. #endif
    5.  
    6. using System;
    7. using System.Collections;
    8. using System.Collections.Generic;
    9. using System.IO;
    10. using UnityEngine;
    11. using UnityEngine.Networking;
    12.  
    13. public class AutoUpdater : MonoBehaviour
    14. {
    15.     // set the web urls to your installer downloads
    16.     public string macInstallerPath, windowsInstallerPath;
    17.    
    18.     // to change the window size during download, set it here
    19.     public Vector2Int downloaderWindowSize;
    20.    
    21.     private Vector2Int initialWindowSize;
    22.     private string downloadingFilePath;
    23.     private string downloadFolder;
    24.  
    25.     [Header("UI")]
    26.     // UI to show/hide when downloading
    27.     public GameObject downloadUI;
    28.     public UnityEngine.UI.Image progressBar;
    29.     public TMPro.TextMeshProUGUI progressText;
    30.     public UnityEngine.UI.Button cancelButton;
    31.    
    32.     UnityWebRequest uwr;
    33.     private bool cancelled = false;
    34.     private void Start()
    35.     {
    36.         initialWindowSize = new Vector2Int(Screen.currentResolution.width, Screen.currentResolution.height);
    37.         cancelButton.onClick.AddListener(CancelDownload);
    38.  
    39.         downloadFolder = Application.temporaryCachePath;
    40.        
    41.         // Setup your executable names here
    42. #if UNITY_WINDOWS
    43.         downloadingFilePath = Path.Combine(downloadFolder, "Installer.exe");
    44. #else
    45.         downloadingFilePath = Path.Combine(downloadFolder, "Installer.pkg");
    46. #endif
    47.  
    48.         // delete the old installer from the temp path if it exists
    49.         if (File.Exists(downloadingFilePath))
    50.             File.Delete(downloadingFilePath);
    51.  
    52.     }
    53.  
    54.     public void BeginUpdate()
    55.     {
    56.         Debug.Log("BEGINNING UPDATED VERSION DOWNLOAD");
    57.  
    58.         downloadUI.gameObject.SetActive(true);
    59.         Screen.SetResolution(downloaderWindowSize.x, downloaderWindowSize.y, FullScreenMode.Windowed);
    60.  
    61.         StartCoroutine(BeginWebRequest());
    62.     }
    63.  
    64.     public void CancelDownload()
    65.     {
    66.         Debug.Log("CANCELLING");
    67.         if (uwr == null || uwr.isDone) return;
    68.  
    69.         uwr.disposeDownloadHandlerOnDispose = true;
    70.         uwr.Abort();
    71.         cancelled = true;
    72.         Screen.SetResolution(initialWindowSize.x, initialWindowSize.y, FullScreenMode.Windowed);
    73.         downloadUI.gameObject.SetActive(false);
    74.     }
    75.  
    76.     private IEnumerator BeginWebRequest()
    77.     {
    78.         cancelled = false;
    79. #if UNITY_WINDOWS
    80.         string url =windowsInstallerPath;
    81. #else
    82.         string url = macInstallerPath;
    83. #endif
    84.         uwr = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
    85.         uwr.disposeDownloadHandlerOnDispose = true;
    86.         uwr.downloadHandler = new DownloadHandlerFile(downloadingFilePath);
    87.         uwr.SendWebRequest();
    88.         yield return null;
    89.          
    90.         // handle progress bar/text
    91.         while (!uwr.isDone)
    92.         {
    93.             progressBar.fillAmount = uwr.downloadProgress;
    94.             progressText.text = (Math.Round(uwr.downloadProgress, 2) * 100f).ToString() + " %";
    95.             yield return new WaitForSeconds(0.2f);
    96.         }
    97.         uwr.Dispose();
    98.  
    99.         if (!cancelled)
    100.         {
    101.             // open the new installer and close the current game.
    102.             System.Diagnostics.Process.Start(downloadingFilePath);
    103.             Application.Quit();
    104.         }
    105.     }
    106.  
    107.    
    108. }
    Also hosted here:
    https://gist.github.com/SceneForgeStudio/f10f1464683227e00f83c6dde54fb2fe