Skip to content

Create Platform Specific Game Objects – Unity

Being able to build for multiple different platforms is a powerful Unity feature. It enables you to build once and show off your game everywhere. That said, not all platforms are the same and you will have to do a bit of customization for each platform.

The art, text, and gameplay features may be different for each. It can be a hassle to make these changes back and forth with each build, so I’ve created a script to help save time.

Track Platform Changes

//#define PLATFORM_UPDATE_DEBUG

#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;

[ExecuteInEditMode]
public class PlatformUpdate : MonoBehaviour, IActiveBuildTargetChanged
{
	public static System.Action<BuildTarget> BuildTargetChangedListeners;

	BuildTarget currentTarget;
	public int callbackOrder { get { return 0; } }
	public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
	{
		currentTarget = newTarget;
		// Can't update immediately as scripts aren't ready
		EditorApplication.update += UpdateGameObjects;

#if PLATFORM_UPDATE_DEBUG
        Debug.Log("Switched build target to " + currentTarget);
#endif
	}

	void UpdateGameObjects()
	{
		if (BuildTargetChangedListeners != null)
			BuildTargetChangedListeners(currentTarget);
		EditorApplication.update -= UpdateGameObjects;

#if PLATFORM_UPDATE_DEBUG
        Debug.Log("Updated listeners with new target: " + currentTarget);
#endif
	}
}
#endif

Unity does have a callback to track platform changes. However, calling most functions directly from it can cause issues as the assets aren’t built yet. For example, disabling a GameObject will fail with a null reference exception.

To avoid that issue, once the platform changes, we wait until the next editor update to notify other objects.

Update GameObjects

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;

[ExecuteInEditMode]
public class PlatformSpecific : MonoBehaviour
{
    public BuildTarget activeTarget;

    public PlatformSpecific()
    {
        PlatformUpdate.BuildTargetChangedListeners += UpdateBuildTarget;
    }

    void OnDestroy()
    {
        PlatformUpdate.BuildTargetChangedListeners -= UpdateBuildTarget;
    }

    void UpdateBuildTarget(BuildTarget currentTarget)
    {
        gameObject.SetActive(currentTarget == activeTarget);
    }
}
#else
public class PlatformSpecific : MonoBehaviour { }
#endif

Most of the time, updates are easy to do. However, you will have some issues if you try to enable and disable objects. Disabled objects won’t call Awake, OnEnable, or Start, so you won’t be able to subscribe in the traditional places. To get around this, you can place your subscription in the constructor. This will work for even disabled objects.

Summary

That should do it. One weakness of the general case shown in the PlatformSpecific script is that you’ll sometimes want to be activated for multiple cases (like all standalone builds or mobile builds), so you may want to create extra scripts for those cases.

I’ve created a Unity asset package that you can pick up on the asset store for $1 that contains all the code shown here and additional scripts to handle each platform and platform group. Check it out if you appreciate the code or like the convenience of package management.

Published inCode ExamplesDevelopment Tips

Be First to Comment

    Leave a Reply

    Your email address will not be published. Required fields are marked *