Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020.2 has been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

How to run a setup method when a package is imported/updated?

Discussion in 'Package Manager' started by caioteixeira5, Apr 5, 2019.

  1. caioteixeira5

    caioteixeira5

    Joined:
    Apr 5, 2019
    Posts:
    3
    Hello :)
    We are trying to run a setup method when a package is imported, we found out that methods with InitializeOnLoadMethod are called when a package is imported for the first time but not when it is updated :/ Just to clarify our use case, we are using a private scoped registry, we want to create/update a custom gradle template on the Assets/Plugins folder every time a package is imported/updated.
    Is there a proper way to call a method when a package is imported and/or updated?
     
  2. manu73

    manu73

    Unity Technologies

    Joined:
    Aug 22, 2014
    Posts:
    68
    Hi @caioteixeira5!

    There are no existing callbacks to know when a package is installed/updated or removed :(

    But you can effectively used a InitializeOnLoadMethod fct to know which packages are installed.
    Btw, this fct will be called at each domain reload (install/update/remove of a package but also entering play-mode)

    Here's a code snippet (works with Unity 2019.1.0b9) you may starts with:

    Code (CSharp):
    1.  
    2. using System.Text;
    3. using System.Threading;
    4. using UnityEngine;
    5. using UnityEditor;
    6. using UnityEditor.PackageManager;
    7.  
    8. public static class InstalledPackages
    9. {
    10.     [InitializeOnLoadMethod]
    11.     private static void InitializeOnLoad()
    12.     {
    13.         var listRequest = Client.List(true);
    14.         while (!listRequest.IsCompleted)
    15.             Thread.Sleep(100);
    16.  
    17.         if (listRequest.Error != null)
    18.         {
    19.             Debug.Log("Error: " + listRequest.Error.message);
    20.             return;
    21.         }
    22.  
    23.         var packages = listRequest.Result;
    24.         var text = new StringBuilder("Packages:\n");
    25.         foreach (var package in packages)
    26.         {
    27.             if (package.source == PackageSource.Registry)
    28.                 text.AppendLine($"{package.name}: {package.version} [{package.resolvedPath}]");
    29.         }
    30.        
    31.         Debug.Log(text.ToString());
    32.     }
    33. }
    34.  
    Regards,

    Manu73
     
  3. caioteixeira5

    caioteixeira5

    Joined:
    Apr 5, 2019
    Posts:
    3
    Thank you for the quick answer! :)

    I tested it in both Unity 2018.3 and 2019.1, but it seems to have the same behavior that I had before. This method is not called when a package is updated.
    I actually have a piece of new information, this issue only happens when using a private registry. When I update an official package the method is called.
     
  4. manu73

    manu73

    Unity Technologies

    Joined:
    Aug 22, 2014
    Posts:
    68
    Hi @caioteixeira5!

    Sorry for this inconvenience.

    I locally use Verdaccio and scoped registry in Packman and I was able to update my package published in my local registry.

    The only difference I think, it's that my package contains scripts that I have updated.

    Domain reload (which will call InitializeOnLoadMethod) will only occur if there are changes in scripts.

    Does your package only contains assets (aka non scripts)?
    Also, in Unity General preferences, do you have Auto-Refresh checked?

    Manu73
     
  5. manu73

    manu73

    Unity Technologies

    Joined:
    Aug 22, 2014
    Posts:
    68
    Hi @caioteixeira5!

    I've updated the code snippet to take care of assets only change:

    Code (CSharp):
    1.  
    2. using System.Linq;
    3. using System.Text;
    4. using System.Threading;
    5. using UnityEngine;
    6. using UnityEditor;
    7. using UnityEditor.PackageManager;
    8.  
    9. public class InstalledPackages : AssetPostprocessor
    10. {
    11.     private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    12.     {
    13.         var inPackages = importedAssets.Any(path => path.StartsWith("Packages/")) ||
    14.             deletedAssets.Any(path => path.StartsWith("Packages/")) ||
    15.             movedAssets.Any(path => path.StartsWith("Packages/")) ||
    16.             movedFromAssetPaths.Any(path => path.StartsWith("Packages/"));
    17.  
    18.         if (inPackages)
    19.         {
    20.             InitializeOnLoad();
    21.         }
    22.     }
    23.    
    24.     [InitializeOnLoadMethod]
    25.     private static void InitializeOnLoad()
    26.     {
    27.         var listRequest = Client.List(true);
    28.         while (!listRequest.IsCompleted)
    29.             Thread.Sleep(100);
    30.  
    31.         if (listRequest.Error != null)
    32.         {
    33.             Debug.Log("Error: " + listRequest.Error.message);
    34.             return;
    35.         }
    36.  
    37.         var packages = listRequest.Result;
    38.         var text = new StringBuilder("Packages:\n");
    39.         foreach (var package in packages)
    40.         {
    41.             if (package.source == PackageSource.Registry)
    42.                 text.AppendLine($"{package.name}: {package.version} [{package.resolvedPath}]");
    43.         }
    44.        
    45.         Debug.Log(text.ToString());
    46.     }
    47. }
    You can adapt this code to only look in specific Packages.
     
    GarthSmith likes this.
  6. caioteixeira5

    caioteixeira5

    Joined:
    Apr 5, 2019
    Posts:
    3
    Thank you!
    It is working now :)
    I am also using Verdaccio, my package has both assets and scripts. I am not sure why exactly this was not working, but modifying a hardcoded string on a script was not triggering a recompile for some reason.
     
  7. manu73

    manu73

    Unity Technologies

    Joined:
    Aug 22, 2014
    Posts:
    68
    You're welcome.
     
  8. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,805
    neilsarkar likes this.
  9. finger-k4

    finger-k4

    Joined:
    Jun 19, 2015
    Posts:
    2
    Hey @QFSW did you make any progress on this topic? I am looking to do the same but if there are compiler errors Unity grinds to a halt, even if there are scripts which can execute.

    Thanks!
     
  10. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,805
    Unfortunately not
     
unityunity