Search Unity

  1. We would like to hear your feedback about Unity and our products. Click here for more information.
    Dismiss Notice

Help Wanted Force code recompiling after scripting define symbols changed

Discussion in 'Testing & Automation' started by aurelien-morel-ubiant, Apr 5, 2019.

  1. aurelien-morel-ubiant

    aurelien-morel-ubiant

    Joined:
    Sep 27, 2017
    Posts:
    181
    Hello,
    I would to know if there is a way to pre-compile scripts during a build process.
    Because in our custom builder we implemented something like this :

    Code (CSharp):
    1. private bool PreBuildCustomMethod()
    2.         {
    3.             if (IsBuilding() && m_bBuildAbort)
    4.                 return NextBuildMethod(PreBuildCustomMethod);
    5.  
    6.             DebugBuilderGlobalDefines( "PreBuildCustomMethod" );
    7.  
    8.             Type preBuildCustomType = null;
    9.             string[] allAsmDef = Directory.GetFiles(Application.dataPath + "/", "*.asmdef", SearchOption.AllDirectories);
    10.             int nBuildMethodsFound = 0;
    11.             int nAssemblyCount = allAsmDef.Length;
    12.             if (allAsmDef.Length == 0)
    13.             {
    14.                 preBuildCustomType = Type.GetType("BuildMethod,Assembly-CSharp-Editor");
    15.                 if (preBuildCustomType != null)
    16.                 {
    17.                     MethodInfo methodInfo = preBuildCustomType.GetMethod("PreBuild");
    18.                     if (methodInfo != null)
    19.                         methodInfo.Invoke(null, null);
    20.                     nBuildMethodsFound++;
    21.                     nAssemblyCount++;
    22.                 }
    23.             }
    24.             else
    25.             {
    26.                 foreach (string singleAsmDef in allAsmDef)
    27.                 {
    28.                     string sAssemblyName = Path.GetFileNameWithoutExtension(singleAsmDef);
    29.                     preBuildCustomType = Type.GetType("BuildMethod," + sAssemblyName);
    30.                     if (preBuildCustomType != null)
    31.                     {
    32.                         nBuildMethodsFound++;
    33.                         MethodInfo methodInfo = preBuildCustomType.GetMethod("PreBuild");
    34.                         if (methodInfo != null)
    35.                             methodInfo.Invoke(null, null);
    36.                     }
    37.                 }
    38.             }
    39.  
    40.             return NextBuildMethod(PreBuildCustomMethod, nBuildMethodsFound.ToString() + " build methods found in the " + nAssemblyCount.ToString() + " assemblies");
    41.         }
    This allow us to do special stuff that must be done before or after the real pipeline build. But in a recent project, we have something like this :

    Code (CSharp):
    1. public static class BuildMethod
    2. {
    3.     public static void PreBuild()
    4.     {
    5.         string pathUISkin = UISkinManager.GetTargetUISkinModelPath();
    6.         Debug.LogWarning("pathUISkin : " + pathUISkin);
    7.         if (!AssetDatabase.CopyAsset( pathUISkin, "Assets/Resources/UISkins/UISkin.asset" ))
    8.         {
    9.             Debug.LogWarning("Copy the asset but remvoe before : " + pathUISkin);
    10.             AssetDatabase.MoveAssetToTrash( "Assets/Resources/UISkins/UISkin.asset" );
    11.             AssetDatabase.CopyAsset( pathUISkin, "Assets/Resources/UISkins/UISkin.asset" );
    12.         }
    13.     }
    14.  
    15.     public static void PostBuild()
    16.     {
    17.         Debug.LogWarning("Remove the asset copied earlier ");
    18.         AssetDatabase.MoveAssetToTrash( "Assets/Resources/UISkins/UISkin.asset" );
    19.     }
    20. }
    21.  
    22. public static string GetTargetUISkinModelPath()
    23.     {
    24.         string path = string.Empty;
    25.  
    26. #if USE_VERTUOZ
    27.         path = "Assets/Assets_MyHemis/AppData/UISkins/UISkin_Vertuoz.asset";
    28.         Debug.LogWarning("USE VERTUOZ");
    29. #elif USE_FLEXOM
    30.         path = "Assets/Assets_MyHemis/AppData/UISkins/UISkin_Flexom.asset";
    31.         Debug.LogWarning("USE FLEXOM");
    32. #elif USE_UBIANT
    33.         path = "Assets/Assets_MyHemis/AppData/UISkins/UISkin_Ubiant.asset";
    34.         Debug.LogWarning( "USE UBIANT" );
    35. #endif
    36.  
    37.         if (path == string.Empty)
    38.             Debug.LogError("[UISkinManager] The path of the target UISkin is unknowed");
    39.  
    40.         return path;
    41.     }
    42.  
    Before the PreBuildCustomMethod process, we have a method to define the new global define based on your
    Code (CSharp):
    1. PlayerSettings.SetScriptingDefineSymbolsForGroup( targetGroup, sData );
    .

    But sadly due to the fact that we changed the global define here and before the BuildPlayer, they are ignored by all the methods between them.

    So currently in our gitlab-ci process, I have to do this :


    Code (CSharp):
    1. if [[ "$RECOMPILE_ONLY" = "false" ]]; then
    2.                     "${UNITY_EXECUATBLE}" -batchmode -nographics -buildTarget "$PLATFORM" -logFile "${UNITY_LOGS_PATH}" -projectpath "${CI_PROJECT_DIR}/UnityProject" -executeMethod Ubiant.Editor.Builder.BuilderModel.BatchBuild -RECOMPILE_ONLY="true" -BUILD_PROFILE="$PROFILE" -ANDROID_SDK_PATH="${ANDROID_SDK_PATH}" -ANDROID_NDK_PATH="${ANDROID_NDK_PATH}" -BUILD_PROJECT_VERSION="$VERSION_NUMBER" -BUILD_DESTINATION="${PATH_TO_PLATFORM_BUILD}" -HOCKEY_APP_TEAM="${TEAM_ID_BUILD}" -BUILD_HOCKEYAPP
    3.                 fi
    4.                 "${UNITY_EXECUATBLE}" -batchmode -nographics -buildTarget "$PLATFORM" -logFile "${UNITY_LOGS_PATH}" -projectpath "${CI_PROJECT_DIR}/UnityProject" -executeMethod Ubiant.Editor.Builder.BuilderModel.BatchBuild -RECOMPILE_ONLY="$RECOMPILE_ONLY" -BUILD_PROFILE="$PROFILE" -ANDROID_SDK_PATH="${ANDROID_SDK_PATH}" -ANDROID_NDK_PATH="${ANDROID_NDK_PATH}" -BUILD_PROJECT_VERSION="$VERSION_NUMBER" -BUILD_DESTINATION="${PATH_TO_PLATFORM_BUILD}" -HOCKEY_APP_TEAM="${TEAM_ID_BUILD}" -BUILD_HOCKEYAPP
    5.            
    In this way, the first batchmode allow us to only recompile our project to correctly setup the scripting symbols and only call after another batchmode that take the good defines set by the first batchmode.

    It's maybe something twisted but this could allow us to switch some resources based on a profile (each profile has its own scripting symbol)

    Thanks.