Editor Scripting: How To Detect a Change in Player Settings

I want to detect when a change is made to player settings. Specifically, when the Unity user makes a change to the Android “Bundle Identifier”, I want to call some Editor scripting code.

OnValidate() works with MonoBehaviours and ScriptableObjects:

But PlayerSettings is a Unity Object:

public sealed class PlayerSettings : UnityEngine.Object {

I can make a Custom Inspector for PlayerSettings:

[CustomEditor(typeof(PlayerSettings))]
public class PlayerSettingsValidate : Editor {
    public override void OnInspectorGUI() {
        DrawDefaultInspector();
    }
    public void OnValidate() {
        Debug.Log("You changed something");
    }
}

But DrawDefaultInspector() does not work, nor does OnValidate().

How can I detect when a change is made to a Player Settings value?

If you want to detect changes in the inspector, you can use :

if(DrawDefaultInspector()){
//Code here
}

Is this what you are looking for ?

You’ll need a wrapper class since your PlayerSettings does not derive from Monobehaviour and therefore is not part of the regular update cycle.

Create a wrapper class, which holds your PlayerSettings class as a field. Then create a customer editor which exposes properties of player settings to the inspector.

For example:

public class PlayerSettingsWrapper : Monobehaviour
{
    private PlayerSettings _settings;
    public int ASetting;

    public void UpateSettings()
    {
        _settings.ASetting = ASetting;
    }
}

Modify your editor to read PlayerSettingsWrapper instead and it should communicate the change.

Too late for the party but found a solution (kind of).
I try to achieve that with checks inside the OnInspectorGUI() method. This method is called when displaying and hovering over the PlayerSettings tab. Call it a lot of times but you can attach your logic there with simple if statements. I check the ScriptingBackend for the example purpose

public override void OnInspectorGUI()
{
	DrawDefaultInspector();
	if (PlayerSettings.GetScriptingBackend(BuildTargetGroup.Standalone) == ScriptingImplementation.Mono2x)
	{
		Debug.Log("Mono");
	}
	else
	{
		Debug.Log("IL2CPP");
	}
}

Still searching more elegant solution though.