Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Is there a "PreProcessBuildAttribute" like "PostProcessBuildAttribute"??

Discussion in 'Scripting' started by JohnSonLi, Dec 25, 2018.

  1. JohnSonLi

    JohnSonLi

    Joined:
    Apr 15, 2012
    Posts:
    586
    ...hm....
     
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,590
    No, it's not available at the time of writing.
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    Nope, but you can just programmatically build your project using the BuildPipeline:
    https://docs.unity3d.com/ScriptReference/BuildPipeline.BuildPlayer.html

    Then through whatever means you want, you can trigger this (menu entry, button in a gui window, whatever). And you're hook to before is just whatever lines you insert before calling BuildPlayer.

    I do it as a ScriptableObject asset, and generalized a lot of the build process so I can create configurations and save them as assets:
    https://github.com/lordofduct/space...nityFrameworkEditor/Settings/BuildSettings.cs

    I can even inherit from it to make project specific tweaks, like this one:
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEditor;
    6.  
    7. using com.spacepuppy;
    8. using com.spacepuppy.Collections;
    9. using com.spacepuppy.Project;
    10. using com.spacepuppyeditor;
    11.  
    12. using com.mansion;
    13.  
    14. namespace com.mansioneditor
    15. {
    16.  
    17.     [CreateAssetMenu(fileName = "EpisodeBuildSettings", menuName = "Spacepuppy Build Pipeline/Episode Build Settings")]
    18.     public class EpisodeBuildSettings : BuildSettings
    19.     {
    20.  
    21.         #region Fields
    22.  
    23.         [SerializeField]
    24.         private DistributionPlatform _distributionPlatform;
    25.         [SerializeField]
    26.         private EpisodeSettings _episodeSettings;
    27.         [SerializeField]
    28.         private string _resourcesFolderName;
    29.  
    30.         #endregion
    31.  
    32.         #region Properties
    33.  
    34.         public DistributionPlatform DistributionPlatform
    35.         {
    36.             get { return _distributionPlatform; }
    37.             set { _distributionPlatform = value; }
    38.         }
    39.  
    40.         public EpisodeSettings EpisodeSettings
    41.         {
    42.             get { return _episodeSettings; }
    43.             set { _episodeSettings = value; }
    44.         }
    45.  
    46.         public string ResourcesFolderName
    47.         {
    48.             get { return _resourcesFolderName; }
    49.             set { _resourcesFolderName = value; }
    50.         }
    51.  
    52.         #endregion
    53.  
    54.         #region Methods
    55.  
    56.         public override string[] GetScenePaths()
    57.         {
    58.             using (var lst = TempCollection.GetList<string>())
    59.             {
    60.                 if (this.BootScene != null) lst.Add(AssetDatabase.GetAssetPath(this.BootScene));
    61.  
    62.                 foreach (var scene in this.Scenes)
    63.                 {
    64.                     lst.Add(AssetDatabase.GetAssetPath(scene));
    65.                 }
    66.  
    67.                 if (this.EpisodeSettings != null && this.EpisodeSettings.TitleScreen.SceneAsset != null)
    68.                 {
    69.                     var path = AssetDatabase.GetAssetPath(this.EpisodeSettings.TitleScreen.SceneAsset);
    70.                     //if (lst.Contains(path)) lst.Remove(path);
    71.                     //lst.Insert(1, path);
    72.                     if (!lst.Contains(path))
    73.                         lst.Add(path);
    74.                 }
    75.  
    76.                 return lst.ToArray();
    77.             }
    78.         }
    79.  
    80.    
    81.  
    82.         #endregion
    83.  
    84.     }
    85.  
    86.     [CustomEditor(typeof(EpisodeBuildSettings))]
    87.     public class EpisodeBuildSettingsEditor : BuildSettingsEditor
    88.     {
    89.  
    90.         public const string PROP_DISTPLATFORM = "_distributionPlatform";
    91.         public const string PROP_EPISODESETTINGS = "_episodeSettings";
    92.         public const string PROP_RESOURCESFOLDERNAME = "_resourcesFolderName";
    93.  
    94.         public override void DrawBuildOptions()
    95.         {
    96.             base.DrawBuildOptions();
    97.  
    98.             this.DrawPropertyField(PROP_DISTPLATFORM);
    99.             this.DrawPropertyField(PROP_EPISODESETTINGS);
    100.             this.DrawPropertyField(PROP_RESOURCESFOLDERNAME);
    101.         }
    102.  
    103.  
    104.  
    105.         public override void SyncToGlobalBuild()
    106.         {
    107.             var settings = this.target as EpisodeBuildSettings;
    108.             var gameSettings = AssetDatabase.LoadAssetAtPath<Game>("Assets/Resources/GameSettings.asset");
    109.             if (gameSettings != null)
    110.             {
    111.                 Undo.RecordObject(gameSettings, "Sync Build Settings to GameSettings");
    112.                 gameSettings.SetEpisodeSettings(settings.EpisodeSettings);
    113.             }
    114.  
    115.             base.SyncToGlobalBuild();
    116.         }
    117.  
    118.  
    119.         protected override IEnumerator DoBuild(BuildSettings.PostBuildOption postBuildOption)
    120.         {
    121.             var settings = this.target as EpisodeBuildSettings;
    122.        
    123.             if(!string.IsNullOrEmpty(settings.ResourcesFolderName))
    124.             {
    125.                 var spath = @"Assets/Build/" + settings.ResourcesFolderName;
    126.                 AssetHelper.MoveFolder(spath, @"Assets/Build/Resources");
    127.                 AssetDatabase.Refresh();
    128.             }
    129.        
    130.             var gameSettings = AssetDatabase.LoadAssetAtPath<Game>(@"Assets/Resources/GameSettings.asset");
    131.             EpisodeSettings backupEpSettings = null;
    132.             DistributionPlatform backupPlatform = DistributionPlatform.Generic;
    133.             if (gameSettings != null)
    134.             {
    135.                 backupEpSettings = gameSettings.GetEpisodeSettings();
    136.                 backupPlatform = gameSettings.Platform;
    137.  
    138.                 gameSettings.SetEpisodeSettings(settings.EpisodeSettings);
    139.                 gameSettings.Platform = settings.DistributionPlatform;
    140.             }
    141.  
    142.             try
    143.             {
    144.                 settings.Build(postBuildOption);
    145.             }
    146.             finally
    147.             {
    148.                 if (gameSettings != null)
    149.                 {
    150.                     gameSettings.SetEpisodeSettings(backupEpSettings);
    151.                     gameSettings.Platform = backupPlatform;
    152.                 }
    153.  
    154.                 if (!string.IsNullOrEmpty(settings.ResourcesFolderName))
    155.                 {
    156.                     AssetHelper.MoveFolder("Assets/Build/Resources", "Assets/Build/" + settings.ResourcesFolderName);
    157.                     AssetDatabase.Refresh();
    158.                 }
    159.             }
    160.        
    161.             yield break;
    162.         }
    163.  
    164.  
    165.     }
    166.  
    167. }
    168.  
    It visually looks like this:
    BuildSettings.png

    I even have a 'build build' process to group builds together:
    https://github.com/lordofduct/space...FrameworkEditor/Settings/BulkBuildSettings.cs

    I use this to build multiple versions of the game and upload them in one click. Here is me building win/linux/macos and uploading for steam and itch.io:
    BuildSettings02.png

    ...

    As to your hook, if you wanted to use something similar to this.

    You could insert a static event that gets trigger.

    Or you could even use reflection, search through all the static methods out in the assembly, check for a custom attribute of your liking. And call that method. Completely emulating the PostProcessBuildAttribute.
     
    Last edited: Dec 25, 2018