Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Multiple build targets on the same platform

Discussion in 'Editor & General Support' started by tomas_unity836, Apr 22, 2022.

  1. tomas_unity836

    tomas_unity836

    Joined:
    Nov 25, 2020
    Posts:
    5
    We're developing a game that runs on different platforms (Android/Windows), in different stores (Oculus/Steam) and in different setups (VR/non-VR). Things that differ between versions are assets, project settings, some scenes (due to performance and size) and Unity packages. Some settings can be set per platform inside project settings, but not all, and since most of our build targets are for Windows it wouldn't help us either way.

    Right now we use Perforce and virtual streams that remaps the correct project settings, assets and packages to the root folder depending on which version you want to build/develop on. This is cumbersome and bloats the project.

    Preferably it would be possible to select a build target inside Unity, just like you can do with platforms, and that would work for changing all the things we need. I haven't found anything like this though.

    What is the recommended solution to this problem? We can't be alone with this problem and doing it our way doesn't feel correct.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,964
    Injecting different code scripting predefines at build time is one approach. Then your build scripts can observe the changed scripting #define and turn on / off whatever other assets, scenes, code whatever needs to change.

    Using git, I maintain a
    master
    and a
    tv
    branch for all my Android projects, which I need to build once for Android touch and once for Android TV.

    All development happens in
    master
    and when it is time to build, I merge
    master
    into
    tv
    , then make one build from each branch, with the BundleVersionCode incremented.

    This means that the diff between those two branches is ONLY the tiny few files I need changed to make the entire rest of the application behave differently. This is the file-level diff on my Jetpack Kurt game between those branch tips, for instance:

    Screen Shot 2022-04-22 at 8.17.51 AM.png
     
  3. tomas_unity836

    tomas_unity836

    Joined:
    Nov 25, 2020
    Posts:
    5
    That is essentially what we already do, but in Perforce. Having separate streams (branches) that contains the platform specific changes needed. There are many problems with this setup. Some of them are:
    * Testing different platforms require you to change stream/branch which, at least in Perforce gets annoying when you have pending changes.
    * Build systems gets more complicated due to the amount of streams/branches. It would be much simpler if a single branch could be used for all build types.
    * Getting an overview of what streams/branches we have gets harder due to it being a factor 9 bigger than it should be.
    * Making small streams/branches for small tasks gets less usable because you can't switch platform inside such a stream/branch.

    It sure is possible, but it's a lot of headache.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,964
    Doesn't p4 have a "Shelf" of some kind where you can instantly stick unfinished changes just locally? On git it is called stashing.

    Would it be? To me it is just as easy to do:

    - checkout TV
    - build TV
    - checkout master
    - build master
    - checkout potato
    - build potato

    etc.

    Yeah, last p4 branch I made / merged was circa 2005... I do recall p4 being brittle and / or difficult this way. I don't know what to suggest except "have you tried
    git
    ?" I know that's not super-useful though, but right tool for the job and all. :)
     
  5. tomas_unity836

    tomas_unity836

    Joined:
    Nov 25, 2020
    Posts:
    5
    Yes it has. So switching stream involves 1) shelf, 2) switch stream, 3) unshelf. Not impossible, but the annoyance piles on.

    How does that workflow work if you have a long/big feature branch? Release branch based on old master? Small short lived task/feature branch? In this case you would need one TV and one potato branch for each other branch you have.

    We've solved that with some backend script that creates all the virtual streams we need whenever a stream is created. Having all branches in git get multiplied by 9 just because you want to be able to test different platforms doesn't feel great. I don't think any of the visual git clients I've used would handle that gracefully. In P4 streams has a parent/child hierarchy as well so cleaning it up gets slightly easier. Cleaning up all platform branches that gets generated could become very brittle.

    I agree with P4 being brittle and I rather use something else, like git. In this specific scenario though I don't see how git would be better.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,964
    Yeah, fair enough... I didn't think about the matrix of N feature branches vs X target build platforms.

    Another approach would be to create (and maintain) a make-for-platform patch for each target platform.

    This means the build steps would be:

    - checkout master
    - build master
    - apply patch TV
    - build TV
    - revert to master
    - apply patch potato
    - build potato
    - revert to master

    etc.

    At the end of the day, ideally you want ALL the platform specific changes to be observable off a single bit (or integer) of different source data.

    This reduces the chance of getting that input wrong, and lets that one single input mushroom outwards into ALL the different changes necessary, and to do so in a way that is repeatable and source-controlled.

    For me the easiest is individual branches, and if I do have a feature branch needing multi-target testing, I usually just create a discardable build by hand, which doesn't really scale to enterprise... :) At least it's pretty fast...
     
  7. tomas_unity836

    tomas_unity836

    Joined:
    Nov 25, 2020
    Posts:
    5
    I... think we have done something similar to that in the past. Instead of having virtual streams/branches that contained the changes you had to run a script that applied those changes to your workspace directly. Apparently it caused problems because people had trouble saving/copying the files back to the proper place before submitting. It was before my time though.

    The issues that was experienced could maybe be solved with better tools around it. I think I have to do another pass on it... Thanks!
     
    Kurt-Dekker likes this.
  8. FiveFingerStudios

    FiveFingerStudios

    Joined:
    Apr 22, 2016
    Posts:
    509
    I'm currently porting a game from PC to Android and having an issue with how I should setup Git and build each version.

    I'm currently using one branch and I have a PC folder and an Android folder within the project that I stick platform specific assets. These folders are in the gitIgnore file and I maintain a separate repository for each folder.

    This works file for those files, but there are some files that I need to handle better. Specifically they are the Unity settings files such as the EditorBuildSettings. We use different scenes due to performance reasons.

    I would like to use branches to handle this, but I'm not sure how you would merge back and forth without having the changed files interfere with merges.
     
  9. tomas_unity836

    tomas_unity836

    Joined:
    Nov 25, 2020
    Posts:
    5
    What we're aiming for now internally is something similar to what I wrote we did long ago. It's also one of the simpler approaches (not counting the multiple branches).

    You right now have this file in git.

    /ProjectSettings/EditorBuildSettings.asset


    Instead of that, our approach is to add that file to git ignore and instead have these two files:

    /Overlays/PC/ProjectSettings/EditorBuildSettings.asset
    /Overlays/Android/ProjectSettings/EditorBuildSettings.asset


    Then, make a script/program that copies everything from "/Overlays/PC" or "/Overlays/Android" to the root. This is how you would switch platform.

    The biggest problem with this approach (in my opinion) is how you would modify the "overlayed" files. If it's not that many files then it could be as easy as to manually copy the files back when you know you have modified them. A more sophisticated approach would be to have a script/program that copies them back.

    Depending on which files you want to switch between platforms your script could be part of the Unity project itself. Otherwise you can make a simple bat file that achieves this.