How to set a Scripting Define symbol from code, for every platform

Hello, I’m trying to set the scripting define symbols from code using PlayerSettings.SetScriptingDefineSymbols, but that code seems to do something undocumented:

If a Build Profile is active, rather than the Player Settings being updated, the active Build Profile is updated instead.

Here’s my use case: I have a system that supports two audio implementations: FMOD and Unity. Users choose which system they use in a wizard, and then FMOD_AUDIO_SYNTAX / UNITY_AUDIO_SYNTAX symbols are defined based on which systems they picked. This way if you do not use FMOD, the FMOD-specific code is excluded from the project.

These symbols must be defined for every Build Target. This was working as expected:

But now a user has tested this system on a project that uses Build Profiles, and after running the setup wizard, only the active Build Profile’s “Player Settings” were updated, leaving the actual base Player Settings unchanged.

So other people in their team had compile errors because they were not on the same Build Profile.

What is now the suggested way to update the scripting define symbols from code for all Build Targets, like it normally does when there isn’t a Build Profile active? As far as I can tell there is no official way to do this any more. The only thing I can think of is to update the Project Settings.asset file / any Build Profile .asset file in the project as a text file, which sounds very hacky and error-prone :disappointed_face:

Any advice is appreciated, and I also wanted to just let other people know that if they are trying to set scripting define symbols from code, they will probably run into this issue too. In fact, I’m a bit surprised that I couldn’t find anyone else talking about this. Is this change not going to break a bunch of people’s custom packages :thinking: ?

Its a really strange behaviour indeed. I would expect that the SetScriptingDefineSymbols would set for everything. But primarly for the Player Settings

I can’t recall exactly but I do the sensible thing: I don’t trust that applying a setting once will suffice. The user may simply remove it, forget about it, then complain that it’s “not working”.

So that script that enables or disables build symbols simply runs when the setting changes and also applies the symbol (if necessary) every domain reload in a InitializeOnLoadMethod.

Whether it’s sufficient to do it only once as part of a Setup Wizard or to do it every domain reload is off-topic though

We’re talking about how to add a scripting define symbol from code for every platform, even if a specific Build Profile is active (in which case PlayerSettings.SetScriptingDefineSymbols currently has the undocumented behaviour of only updating the active Build Profile’s Player Setting Overrides and not the Player Settings itself)

Oh I’m also interested in this problem. I’ve yet found any solution.

Can this method behaviour be dependent on script location?

I have noticed the method
PlayerSettings.SetScriptingDefineSymbols

  • works properly when used inside Package Manager package, inside Packages folder - for instance the Post Processing V2 - for both Player Settings and Build Profile’s Player Settings Overrides
  • and works for Build Profile’s Player Settings Overrides only, when used in a script inside Assets folder

How to get it to work the same from inside the Asset folder?