Search Unity

Feedback Please avoid version control noise such as changing 'Always Included Shaders' after each build

Discussion in 'Editor & General Support' started by Xarbrough, Sep 25, 2019.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    When developing for multiple platforms my team is facing a lot of version control noise (unnecessary modifications to files in the project). One of the things constantly modified by Unity is the 'Always Included Shaders' list in the Graphics Projects Settings.

    Shaders_NewProject.PNG Shaders_AfterWindowsBuild.PNG Shaders_AfterAndroidBuild.PNG

    For example:
    1) Build for Windows -> Unity adds VideoComposite, VideoDecode and Compositing
    2) Build for Android -> Unity adds VideoDecodeAndroid
    3) Build for Windows -> Unity removes VideoDecodeAndroid

    This isn't a problem for solo developers working locally or simply pushing all their changes onto their own repository, but for teams this becomes annoying because we, for example, have one developer handling Android and another developer building for Windows. Now, everytime somebody does a build, they change the GraphicsSettings.asset file and either commit it to source control, causing a potential merge conflict or need to revert the file manually.

    This could be solved by Unity, I believe. My ideas would be:
    1) Do not constantly add and remove shaders automatically. Instead, ask the user if s/he wants to include this shaders the first time it is needed (e.g. "Android requires this shader, please include it") and then leave the list as it is until a user decides to manually modify it. Also, I'm not sure why I even need "VideoDecodeAndroid" when I'm not using a VideoPlayer, for example.
    2) Even better: split the list per platform, so that users can set the shaders per platform and have these settings persistent like many other settings already are.

    Thank you for listening and please let me know if anyone has other ideas or sees complications for what I'm proposing. :)
     
  2. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    I don't want to create a new thread for every issue, but since it's also difficult for me to create reproduction cases for QA, I at least want to remind Unity and the community that version control noise is still a big concern.

    The shader issue is still happening in the newest version of Unity using URP when switching between iOS and Android platforms. One platform removes some internal shader, the other adds it back in. There doesn't seem to be a way to either remove it completely or make it persist.

    Unity constantly sets files dirty without changing them (e.g. ProjectSettings or Addressables settings). It seems to be enough to open the inspector window for these settings for them to be marked dirty and therefore be picked up by version control. Especially Git suffers from this since it uses file metadata to detect changes.

    But even worse, we have a lot of files that change depending on the local machine or platform settings. For example, the QualitySettings anti-aliasing setting constantly changes because it seems to be forced to 0 on some machines and then set back to 4 on other computers. This has been an issue for over a year now (I've reported a bug case), but it's still happening in every new project.
     
    Peter77 likes this.
  3. not_a_valid_username

    not_a_valid_username

    Joined:
    Jul 28, 2018
    Posts:
    23
    This is by no means a "proper" solution that can only come from Unity, but I use the script below to listen to the PreprocessBuild event, and when that event occurs I manually remove the shaders that I don't want included.
    Code (CSharp):
    1.  
    2. public class PostBuildSettings : IPreprocessBuildWithReport
    3. {
    4.     public int callbackOrder { get { return 1; } }
    5.  
    6.     /// <summary>
    7.     /// Unity adds some shaders to the AlwaysIncludedShaders list
    8.     /// that are not really needed for this app. So, to remove it,
    9.     /// we listen to when Unity is preparing to build and manually remove them
    10.     /// </summary>
    11.     /// <param name="target"></param>
    12.     /// <param name="pathToBuiltProject"></param>
    13.     public void OnPreprocessBuild(BuildReport report)
    14.     {
    15.         var graphicsSettingsObj = AssetDatabase.LoadAssetAtPath<GraphicsSettings>("ProjectSettings/GraphicsSettings.asset");
    16.         var serializedObject = new SerializedObject(graphicsSettingsObj);
    17.         var arrayProp = serializedObject.FindProperty("m_AlwaysIncludedShaders");
    18.         Debug.Log("num included = " + arrayProp.arraySize);
    19.         bool didRem = false;
    20.         int newSize = -1;
    21.         for (int i = arrayProp.arraySize - 1; i >= 0; i--)
    22.         {
    23.             var arrayElem = arrayProp.GetArrayElementAtIndex(i);
    24.             var refVal = arrayElem.objectReferenceValue;
    25.             Shader shader = (Shader)refVal;
    26.             string shaderName = shader?.name;
    27.  
    28.             if (shaderName == "Hidden/VideoDecode"
    29.                 || shaderName == "Hidden/VideoComposite"
    30.                 || shaderName == "Hidden/Compositing")
    31.             {
    32.                 Debug.Log("Removing " + shaderName);
    33.                 arrayProp.DeleteArrayElementAtIndex(i);
    34.                 didRem = true;
    35.                 // update the size if applicable
    36.                 if (newSize == -1 || newSize == i + 1)
    37.                     newSize = i;
    38.             }
    39.         }
    40.  
    41.         if (didRem)
    42.         {
    43.             if (newSize != -1)
    44.                 arrayProp.arraySize = newSize;
    45.             Debug.Log("Saving changes");
    46.             serializedObject.ApplyModifiedProperties();
    47.             AssetDatabase.SaveAssets();
    48.         }
    49.     }
    50. }
     
    DerrickBarra likes this.
  4. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    Thanks for the code snippet @not_a_valid_username . I assume after removing shaders we could also add whatever shaders we want using the same basic logic.

    @Xarbrough You're 100% right that this should be handled by Unity, with each platform receiving its own list of always included shaders to avoid us having to work around it. The current workflow doesn't work properly with multi-platform builds where we need to keep sizes down (like WebGL and mobile)
     
  5. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Serialized files are still such a mess... why is the serializer randomly switching between putting properties on one or multiple lines?

    upload_2020-11-25_16-29-53.png

    I believe it should always stick to a single line in this case.

    Only a little related, but in Unity 2020.1 there's a setting called "Force Serialize References On One Line". Why only serialize reference? In any case, Unity should stick to one behaviour and not randomly change.

    In Unity 2020.2, the above screenshot still describes our daily version control struggle. Developer A commits, developer B opens Unity, lines are changed from two lines to a single line or vice versa.

    It sucks and I'm trying to create a repro case, but it won't happen if we intentionally try to repeat it. At least not with simple cases like just opening/saving certain files or trying to make small changed to one of the prefabs. There's probably something more complex going on.
     
    Last edited: Feb 4, 2021
    SupremacyLasse, cdr9042 and Peter77 like this.