What is it?

An end-to-end multiplatform solution for Unity!

Battle-tested during the development of the quadruple-platform game Snuggle Truck, this tool allows for configuration of specific per-platform settings for all devices. Need to change button sizes for iPhone Retina and swap out textures for iPad? Not a problem. Need to replace text on a per-platform basis or swap fonts? Easy. Need to create a resolution-independent UI that works on all major aspect ratios? It's a breeze!

Tutorial Video / Demo!

Screenshots!

What do you get?

PlatformSpecifics

A component that stores all per-platform information and applies it with ease. All stock platforms are supported (iPhone, iPad, Android, Standalone, Webplayer) as well as custom platforms (Demo build, Press-only build) and major aspect ratios (4x3, 16x9, 16x10, and 3x2 for iOS). Also includes a helper tool called EasyPlatform that emulates different platforms within the Unity Editor.

AssetSettings

Your asset management command center. Create configurations of asset compressions and apply them whenever needed. Get the granularity that Unity doesn't provide by creating custom asset configurations for all situations. When you want to change texture compression or audio bitrate on hundreds of files at once, this tool makes it painless.

BuildProcess

An automated granular build process. Operates as a one-button menu item for building to different platforms. It scans scenes for platform-specific changes and assets and applies them at BUILD TIME to achieve optimal stripping! If you're trying to stay under 20mb for iPhone, you'll appreciate the flexibility of having PlatformSpecifics and BuildProcess working to your advantage.

Others

Also included are a couple of dependencies and usability extras that are needed for this pipeline's operation, such as AspectPerfect - A tool that automates the process of scaling quads to the proper aspect ratio of a texture, making working with sprites very simple... And RenderQueueSorter - A tool that helps avoid sorting issues in 2d games by adding the ability to hand specify render order.

Any requirements?

Unity Pro is required for BuildProcess support! We utilize a custom BuildPipeline, which is a Pro-only feature. If you're not using the BuildProcess but only want to use AssetSettings and PlatformSpecifics, Unity Pro is not required. We're looking into selling a reduced price package with 2 out of the 3 tools. Please contact us if you're interested.

*Fully tested with Unity version 3.3 and version 3.4

Documentation

Getting Started (General)

So you've got a sweet game, and now you need it to work on multiple devices or at multiple resolutions. You've purchased the MultiPlatform ToolKit and are wondering how to get started. Here's what you do:


  1. Import the MultiPlatform ToolKit into your project by installing via the Unity Asset Store.
  2. Find an object in your scene that needs to be positioned, scaled, or changed in some way depending on the platform.
  3. Select the item in the Heirarchy and go to the menu bar and choose "Component -> Scripts -> Platform Specifics". This will add the PlatformSpecifics component to your object. This is the container that stores all per-platform information.
  4. Fill in the details of the change you'd like to make and assign them to the platform of choice.
  5. Go to the menu bar and choose "Window -> MultiPlatform ToolKit -> Easy Platform"
  6. A small window will appear. This is the EasyPlatform platform emulator. It lets you emulate a certain platform from within the Unity Editor. Dock this window somewhere on-screen for handy access.
  7. Choose the platform you'd like to preview from the pulldown list in EasyPlatform and hit the Play Mode button in Unity to test out your game and preview the changes you've made.
  8. At this point, your changes are complete and will take effect in your build.

Setting up PlatformSpecifics

PlatformSpecifics does quite a few things and has lots of buttons. What do they all mean? Well, lets investigate:

  • Upon adding a PlatformSpecifics component to a GameObject, you'll see the options available. There's Restrict to Platforms, Materials, Local Scale per Platform, Local Scale per Aspect Ratio, Local Position per Platform, Local Position per Aspect Ratio, Fonts, and Text mesh text. Lots of options!
  • Opening up one of these options, you'll see an "Add Default Entries" button that will pre-populate one of these options with a standard set of platforms. You can set these default platforms on the line that defines 'defaultPlatforms', near the top of PlatformSpecificsEditor.cs
  • Hitting the blue (+) sign button will add a single entry to the list and further clicks on the blue (+) sign button will add additional platforms.
  • The gray up and down buttons will move an entry vertically up and down the list of platforms.
  • The red (-) sign is used to delete an entry from the list of platforms.
  • The 'Get' and 'Set' buttons allow for easy swapping of values in the options fields of a platform. For example, you can position an object in the scene view exactly as you'd like it for iPhone and then hit the 'Get' button to retrieve the value from the Transform component in the inspector and auto-load it into the field you've selected. 'Set' on the other hand will apply a value to the Transform so you can apply that data to the selected GameObject.

Tutorial 1 - Positioning a UI element on iPhone vs iPhone Retina vs iPad

Lets say you wanted to position a box in the upper left corner of your screen on your iOS game which runs on iPhone, iPhone Retina displays, and iPad. Here's how you'd do it:


  1. In Unity, switch your Game view resolution to 'iPad Wide (1024x768)' assuming we're working in a landscape orientation.
  2. Position your UI element into the upper left corner of screen space. Note that the exact world coordinates to position the element into the upper left corner depends on your camera settings.
  3. Add a PlatformSpecifics component to the UI element GameObject by going to the menu bar and choosing "Component -> Scripts -> Platform Specifics".
  4. In the Inspector, under PlatformSpecifics, open the Local Position per Platform section and hit the blue (+) button to add a new entry.
  5. Choose iPad from the platform pulldown.
  6. Hit the 'Get' button to store the position data for iPad.
  7. Hit the blue (+) button again to add an additional platform.
  8. Choose iPhoneRetina from the platform pulldown.
  9. Change your Game view resolution to 'iPhone 4G Wide (960x640)'.
  10. Re-position the UI element to be in the upper left now that we've changed the aspect ratio by showing the iPhone Retina screen size in the Game view.
  11. Hit the 'Get' button next to your iPhoneRetina entry to store the position data.
  12. Lastly repeat the steps above to add your third and final platform, which would be iPhone. Make sure to change your Game view resolution to 'iPhone Wide (480x320)' when positioning.
  13. Feel free to use EasyPlatform to test out your individual changes per platform, which saves testing iteration time by skipping the step of building to all 3 devices just to test if your positioning is correct. See #5 of Getting Started for more information on how to use EasyPlatform.
  14. Note: The default scene that ships with the MultiPlatform ToolKit shows this exact example in action, with the green square in the upper left of the screen.

Tutorial 2 - Scaling a background to the correct width on Android or Standalone

Let's say you wanted to have a background plane behind your non-iOS game (Android or Standalone for example) and it should stretch from the left edge to the right edge of the screen, but your game could be played at 320x240, or 640x480, or 800x600, or one of a million other resolutions. Well, most resolutions fall under 5 different aspect ratios:

16:9, 16:10, 3:2, 4:3, or 5:4 - (Check out this handy resolution chart!)

Thankfully we provide support for those 5 aspect ratios as well as some really wonky Android resolutions that Unity Android lists as common resolutions. We've also made it super easy to add additional custom aspect ratios in case you're working with offbeat hardware. So, lets walk through the process of setting up resolution-independent positioning, very similar to Tutorial 1 but outside of the iOS space.


  1. In Unity, switch your Game view resolution to the '16:9' resolution.
  2. Position your UI element into the upper left corner of the 16:9 screen space. Note that the exact world coordinates to position the element into the upper left corner depends on your camera settings.
  3. Add a PlatformSpecifics component to the UI element GameObject by going to the menu bar and choosing "Component -> Scripts -> Platform Specifics"
  4. In the Inspector, under PlatformSpecifics, open the Local Position per Aspect Ratio section and hit the blue (+) button to add a new entry.
  5. Choose Aspect16By9 from the pulldown.
  6. Hit the 'Get' button to store the position data.
  7. Hit the blue (+) button again to add an additional aspect ratio.
  8. Choose Aspect16By10 from the platform pulldown.
  9. Change your Game view resolution to the '16:10' resolution.
  10. Re-position the UI element to be in the upper left now that we've changed the aspect ratio to 16:10 in the Game view
  11. Hit the 'Get' button next to your Aspect16By10 entry to store the position data.
  12. Lastly repeat the steps above for any additional aspect ratios, including the 1024x600 and 800x480 custom sizes if you are trying to support those sizes specifically for Android.
  13. In order to emulate the visuals for each aspect ratio, just change the Game view resolution to an aspect ratio of your choice and hit Play mode in Unity, and the changes will take effect. Note that EasyPlatform should be set to Standalone or Android in order to emulate the different aspect ratios.

Preparing the Build Pipeline

You've set up your scene to use different PlatformSpecifics and are ready to do a real on-device build. You'd like to try out your Mac build, your PC build, your iPhone build, your Android build, etc. We first need to edit BuildProcess.cs so it can cater to your specific needs.


  1. Open up BuildProcess.cs
  2. Follow the comments within the document and look for areas noted with "CHANGE ME!" Lets outline some of the details below.
  3. The first mandatory change involves filling in the paths to the scene files used for each build. Near the top of the file is a static string array called standaloneScenes. This is the array of scenes that is passed through the build pipeline during a Standalone build. Normally the Build Settings dialog (under File -> Build Settings) holds this information, but since we want to automate the build process from end-to-end, we need to manually set up these lists of scenes in case we'd like certain scenes to be included on certain platforms and not on others. Note that the data stored in the Build Settings dialog will be disregarded.
  4. Next, fill in the bundle identifier if deploying to Android or iOS.
  5. Below the bundle identifier, set up the name of your game and how you'd like it displayed on that certain platform. For example, your game might be called "GameName" but on iPad, it's "GameName HD"
  6. You're all set! Save and close BuildProcess.cs
  7. In order to run a build, go to the menu bar and choose Window -> MultiPlatform ToolKit -> Build -> Build Android or whatever specific platform you're looking to build. You can also choose a Debug build from the Debug menu under the Build pulldown.
  8. Builds are placed by default in your project folder, along side the Assets folder, or inside a Builds folder if it exists in the project folder. Feel free to change this directory by modifying what is returned by GetBuildDirectory() in BuildProcess.cs.
  9. Note: During the build process, temporary scenes are created as the scenes get modified before sending through the build pipeline. If an error occurs mid-build, you may see some scenes that haven't been cleaned up since the process was halted in the middle. If you see any scenes named scenename_temp, these are your original, untouched scene files and should not be deleted. In case of an error during the BuildProcess, the safest thing to do is revert via AssetServer or any other versioning system you might be using (SVN, Perforce, etc). If you're not using any versioning on your project, remove the scenes that don't end with _temp and rename the scenes to their original names, removing the _temp suffix.

Tutorial 3 - Removing elements from your game and changing text based on platform

Lets say your Standalone PC/Mac game contained a level editor, but due to time or scope reasons, you wanted to leave the level editor out of your mobile versions. We'll need to make sure the button in the main menu is removed and that the scene itself is not included in the mobile versions of the build. In addition, there's some text in the game that talks about the level editor, but instead of removing it, we want to swap that text to say that the level editor is available *only* on the PC and Mac, to avoid any confusion. MultiPlatform ToolKit to the rescue! Here's how we do it:


  1. In Unity, select your GameObject that acts as a button to load up the Level Editor.
  2. Add a PlatformSpecifics component to the button GameObject by going to the menu bar and choosing "Component -> Scripts -> Platform Specifics".
  3. In the Inspector, under PlatformSpecifics, open Restrict to Platforms section and hit the blue (+) button to add a new entry.
  4. Choose Standalone. Now the item will remain only if the platform is Standalone, and will be destroyed if it's any other platform.
  5. Find the text that talks about the level editor functionality. Make sure that the text object being used is a TextMesh. If the text is being presented to the screen using a different type of text class, see the Custom Text Compatibility section for more information.
  6. Add a PlatformSpecifics component to the text GameObject and open the Text Mesh Text section.
  7. Add an entry for each of your supported mobile platforms and copy in your explanation text, such as: "Sorry, the Level Editor is only available on PC and Mac!"
  8. Lastly we'll want to ensure that the level editor scene is not included in the mobile builds. Assuming your level editor was built as a separate scene file, we're going to edit our BuildProcess.cs file to specify the exact scenes to be included per-platform
  9. Open up BuildProcess.cs and navigate to the static string arrays near the top of the file, under standaloneScenes. If you're doing an iPhone build, edit the iPhoneScenes array to be something like:
    static string[] iPhoneScenes = new string[] { @"Assets/Scenes/gameScene.unity" };

    In this case, we're assuming that the iPhone scenes array should not include the level editor scene, while the standaloneScenes array contains it.
  10. That's it! Now Standalone builds will contain the level editor scene, the level editor button, and text specific to the level editor, while the mobile versions will contain no level editor scene (and thus have a smaller build size), no level editor button, and text explaining that fact to the user gracefully!

Tutorial 4 - Preventing certain code from executing on one platform

Lets say you wanted to have a class that only ran on iOS, for example. Lets see how we'd do that:


  1. Unity actually supports this out of the box and part of the code within the MultiPlatform ToolKit actually depends on this functionality. See the Platform Dependent Compilation section of the documentation for details.
  2. Specifically for our example, any code wrapped in the following code will be stripped at compile time unless it's an iOS build or being run in the Unity Editor:
    #if UNITY_IPHONE
    //code goes here
    #endif
  3. Note that the UNITY_IPHONE and UNITY_ANDROID defines exist when in the Unity Editor. If you want to exclude the editor from running the code, use a define statement like the following:
    #if UNITY_IPHONE && !(UNITY_EDITOR)
    //code goes here
    #endif

Tutorial 5 - Material swaps per-platform with and without stripping

Lets say you wanted to use a high resolution texture on your iPad build but use a differently sized version for your iPhone build. After all, they are two different aspect ratios, so squashing the iPad texture down on the iPhone will end up stretching it, so why not make pixel perfect versions for both builds? Well depending on your goals, you might be trying to stay under 20mb on iPhone and are doing separate iPhone and iPad builds. Other times you don't care about file size. In both cases, we have a solution that fits the bill:


  1. In order to do a texture swap per-platform, add a PlatformSpecific component to your GameObject that contains the Renderer component.
  2. Open up the Materials option and click the blue (+) button to add a new platform. Choose iPad.
  3. Drag in your iPad material with the iPad texture linked into the material.
  4. Hit the blue (+) button and add a new platform. Choose iPhone.
  5. Drag in your iPhone material with the iPhone texture linked into the material.
  6. You can test the texture swap by using EasyPlatform to emulate the platform and entering Play mode in the Unity editor. See #5 of 'Getting Started' for more information on how to use EasyPlatform.
  7. The only thing left is to decide whether or not you would like to strip references of the other platforms when building. For those going for the smallest build possible (such as those trying to make an iPhone-only build that stays under 20mb), you'll want the materials not a part of your platform to be stripped. When doing a build, just make sure to choose the 'Build iPhone' option. For those who would like the ability to keep the materials intact on the target platform, such as those with Universal iOS games, choose the 'Build Universal iOS' option and no materials will be stripped from the scene. This way you'll keep the ability to swap materials depending on your platform!
  8. Known Issue: Unity doesn't currently support a way to ensure that a linked texture is *not* loaded into memory upon loading a scene. All textures/materials linked to an active resource in a scene will be loaded upon scene load or instantiation of a prefab. If you're using MultiPlatform ToolKit, for example, to swap from iPad textures to iPhone textures and you're using a universal build, both textures will be loaded into memory.

Handling Assets with AssetSettings

Unity's texture importer only exposes per-platform customization of the Max Size and Format properties and it only distinguishes between WebPlayer, Standalone, iOS, and Android platforms. We had two problems with this scheme: One, there are quite a few other texture import settings that we'd like to have control of on a per-platform basis and Two, in certain cases we'd like to be able to distinguish between iPhone and iPad as separate platforms. Unity's audio importer, on the other hand, does not expose any per-platform customization of its import settings and this is another area we felt needed improvement.

Asset Settings solves these problems by allowing you to create any asset configuration for any type of build; such as Demo builds, Press-only builds, or a Debug builds with special asset import settings. Let's get acquainted with the Asset Settings interface. Note that all buttons in the Asset Settings interface have tooltips that provide additional information, which you can view by hovering your cursor above the buttons.


  1. Open up Asset Settings window by going to the menu bar and choosing "Window -> MultiPlatform Toolkit -> Asset Settings".
  2. For convenience, you can dock the window in the same pane as the Scene view or anywhere else you like.
  3. First, notice at the top-left corner of the window, the Configuration dropdown menu. It should already contain the following configurations: Standalone, Uncompressed, and UniversaliOS.
  4. The Assets List below the Configuration Dropdown shows you the assets that belong to this specific configuration. Currently, none of the configurations have any assets in them. Let's add a texture asset to the Standalone configuration so we can go into the details of configuration-based asset import settings.
  5. First, make sure that the Configuration Dropdown is set to Standalone.
  6. Next, select any 2D texture asset in your Project View.
  7. Now, click the blue (+) button at the bottom-left corner of the window to add the selected texture asset to the Standalone configuration. You will now see the texture you selected appear in the Assets List below the Configuration Dropdown and it should be highlighted in blue, indicating that it's selected.
  8. When an asset is selected, you will notice that the Properties List on the right-hand side of the Assets List displays all the import settings belonging to that asset.
  9. The Configuration Dropdown, the Assets List, and the Properties List together, allow you to create and preserve different import settings for all the assets in your project that need to be customized per-configuration.

Now, let's delve into the details of each of these sections of the Asset Settings window.

Configurations


  1. On the same toolbar as the Configuration Dropdown, you will see the Add Configuration (blue (+) button), Remove Configuration (red (-) button), and Edit Configuration (gear button), as well as Apply Configuration and Compare Configurations buttons. Feel free to play around with these buttons, since at this stage, they won't change anything related to your project and they all have their own confirmation dialogs (except Apply).
  2. The Add Configuration button allows you to add new configurations, such as Android, WebPlayer, Demo etc.
  3. The Remove Configuration button allows you to remove the current configuration in the Configuration Dropdown. It will bring up a confirmation dialog before it removes the configuration, so don't panic.
  4. The Edit Configuration button allows you to change the name of the current configuration in the Configuration Dropdown.
  5. The Apply button goes through all the assets in the current configuration and applies their specified import settings to your Project. It starts an import process that is cancelable using the black (x) button that appears at the bottom left corner of the window, next to a Progress Bar.
  6. The Compare button brings up a separate window that allows you to compare all configurations with one another. This is useful for detecting differences between configurations and allows you to keep the list of assets in different configurations in-sync, if need be. The Mode Dropdown at the bottom of the Compare Configurations window lets you switch between different viewing modes that make it easier to detect if an asset exists in one configuration but not in another, or if an asset exists in both configurations but has different import settings in each.

Assets List


  1. The Assets List is a scrollable and sortable list that displays the assets that belong to the current configuration.
  2. If you want to sort the assets alphabetically, simply click the Sort button at the top-right corner of the Assets List.
  3. The Assets List's selection is synced with Unity's internal selection of assets. When you select an asset in the Assets List, you will notice that the Inspector view changes to show the importer for that asset, assuming that it still exists in your project.
  4. If the Assets List contains an asset reference that no longer exists in your project, its name will be in red. At this point, you may select and remove the asset by using the Remove Assets button mentioned in steps 5 and 7.
  5. You can create selection with multiple elements by holding down the Shift or Ctrl/Cmd keys in the same manner that you would in the Project view.
  6. Below the Assets List, you will notice another toolbar that has the following buttons: Add Assets, Remove Assets, Read in Asset Settings, and Apply Asset Settings.
  7. The Add Assets button allows you to add the selected assets in the Project view to the current configuration. If some of the selected assets already exist in the configuration, they will simply be ignored and won't be added a second time.
  8. The Remove Assets button allows you to remove the selected assets from the current configuration.
  9. The Read in Asset Settings button allows you to sync the configuration-based import settings of the selected assets with the import settings set via the Inspector.
  10. The Apply Asset Settings button allows you to apply the configuration-based import settings of the selected assets to your project's asset import settings.

Properties List


  1. The Properties List shows the configuration-based import settings of the currently selected asset in the Assets List.
  2. If a specific import setting shown in the Properties List differs from the asset's current import settings used by Unity, that setting will be shown in Red. If, for example, Unity is in Standalone mode and you're looking at the UniversaliOS configuration, this is normal, since your UniversaliOS asset import settings are likely to be different than your Standalone asset import settings. However, if you're looking at the Standalone configuration and you notice some import settings to be different (shown in red), it might be a good idea to sync those with the import settings that Unity is currently using, by clicking the Read in Asset Settings button mentioned in step 8 of the Assets List section above.
  3. At the top-right corner of the Properties List, you will see the Copy All button and the Apply button. The Copy All button copies all the configuration-specific import settings of the currently selected asset into a buffer. You can then use the Apply button to set the import settings of another asset in the Assets List to be the same as the import settings you copied earlier. This makes it very easy to apply a specific set of import settings to many assets at once, saving you loads of time. Remember that for Unity to use these copied and applied asset import settings in the Editor, you'll need to select the modified assets in the Assets List and click the Apply Asset Settings button mentioned in step 9 of the Assets List section above.

Compatibility and Known Issues with 2D Frameworks

The MultiPlatform ToolKit has been tested with SpriteManager2 and EZGUI with minimal friction. If your 2d framework works with Transforms in the scene hierarchy that can be scaled and positioned at any time, then it's definitely compatible with the MultiPlatform ToolKit. Here are a few things to consider when dealing with 2d:

  • Known Issue: The custom Text classes in 2D frameworks such as SpriteManager's SpriteText are not supported out of the box. For more information, please read the Custom Text Compatibility section.
  • Known Issue: Watch out for swapping materials when using atlasted textures! Depending on the atlasing software and how the atlas is generated you might not be able to use MultiPlatform ToolKit to do the swapping.
  • Known Issue: Using things like EZLayout or checking Pixel Perfect in SpriteManager2 will of course override any positioning or scaling done by the MultiPlatform ToolKit. Same goes for the "Normalize Scene Sprite Scales" box in the ex2D sprite toolkit.

Compatibility with text replacement

The MultiPlatform ToolKit supports replacing text contents on TextMesh objects as well as swapping fonts and font materials. For example, if you want your mobile versions to say "Tap Here!" and your Standalone platforms to say "Click Here!", the Text Mesh Text field will allow you to swap out text for any platform. Or if you want to swap from 60pt font to 24pt font depending on your screen resolution, the toolkit supports that.

Out of the box, the toolkit only supports changes to the TextMesh class, but it could be easily extended to have another text class in its place, such as GUIText, SpriteManager's SpriteText class, 2D Toolkit's BMTextMesh class, or ex2D's SpriteFont class depending on what you're using. Feel free to extend PlatformSpecifics to support it.

In order to extend PlatformSpecifics to support custom text solutions, take a look at PlatformSpecifics' function ApplyFont() and ApplyTextMeshText(). Change these to edit your custom class' text field and material/font field. Then, swap out the instances of "<TextMesh>" within the PlatformSpecificsEditor.cs class to your custom class to ensure proper editor functionality of the PlatformSpecifics class. That's pretty much it.

Compatibility with AutoPilot for TestFlight SDK

AutoPilot takes control of the build process and automatically uploads iOS builds to TestFlight for adhoc testing. AssetSettings and PlatformSpecifics are fully supported and compatible with AutoPilot. MultiPlatform ToolKit users are free to use AutoPilot's build process to auto-upload to TestFlight and can safely disregard the BuildProcess class included in the toolkit, so long as they aren't depending on material stripping. If you're unsure if you need material stripping, read item #7 of Tutorial 5 for more information.

Compatibility with Prime31 plugins or other plugins which modify the build process

The MultiPlatform ToolKit is fully compatible with Prime31 plugins which modify the build process. Prime31's postprocess scripts are handled after the MPTK BuildProcess takes effect, so everything just works. In fact, we used 3 Prime31 plugins with Snuggle Truck on iOS.

Details on extensibility

Asset Settings supports importing all types of content and the BuildProcess is highly customizable to fit your needs, but what about PlatformSpecifics, you may ask! Out of the box, PlatformSpecifics allows for material swapping, scaling, positioning, font swaps, and text replacement because we found these features to be particularly important when building our own projects. If you have needs beyond this, it is entirely possible to modify any arbitrary property of any arbitrary component per-platform and enjoy the benefits of the automation of the MultiPlatform ToolKit.

See the Custom Text Compatibility section for more information on how to extend that particular are of the MultiPlatform ToolKit.

Note: The aspect ratio calculations currently are based off of landscape orientation. Changing the aspect ratio calculation to divide height by width would allow for support of a portrait-only game. This customization would be near the top of AspectRatios.cs, where aspect4By3Ratio is defined. This would be changed to aspect3By4Ratio and the division would be reversed.

Unsure of how to extend the MultiPlatform ToolKit to your own needs? Shoot us an email! (see below)

Support and Contact!

Your purchase includes 6 months of speedy (and friendly) email support. Feel free to contact us at:

info -at- owlchemylabs [dot] com