If your game target the Windows Phone 8 or Windows Store platform, you probably want to use some specific feature like the share, live tiles, …
This can be done by using some tricks that I already explain in a previous thread (http://blog.lordinaire.fr/2014/09/unity-interact-between-unity-and-windows-phone-8-windows-store-apps/) but I might be pretty cool to build automatically custom files like splashscreen, MainPage or tiles.
Create a specific menu item
The first step is to create a menu item to easily access to our build.
using System.Linq; using System.Security.Policy; using UnityEngine; using UnityEditor; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System; public class AutoBuilderMenu : MonoBehaviour { [MenuItem("AutoBuilder/WP8")] private static void PerformBuild() { // TODO : Build and replace files } }
For more information about MenuItem see http://blog.lordinaire.fr/2014/10/unity-create-custom-menu-items/
Simple build
using System.Linq; using System.Security.Policy; using UnityEngine; using UnityEditor; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System; public class AutoBuilderMenu : MonoBehaviour { [MenuItem("AutoBuilder/WP8")] private static void PerformBuild() { // Save current editor build target var currentTarget = EditorUserBuildSettings.activeBuildTarget; EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTarget.WP8Player); var buildPath = GetBuildPath(target); var path = Path.GetDirectoryName(buildPath); var folderExists = Directory.Exists(path); if (!folderExists) Directory.CreateDirectory(path); // Create solution folder and project files BuildPipeline.BuildPlayer(GetScenePaths(), buildPath, target, BuildOptions.None); // Set saved build target EditorUserBuildSettings.SwitchActiveBuildTarget(currentTarget); } private static string GetProjectName() { string[] s = Application.dataPath.Split('/'); return s[s.Length - 2]; } private static string[] GetScenePaths() { return EditorBuildSettings.scenes.Where(s => s.enabled).Select(s => s.path).ToArray(); } private static string GetBuildPath(BuildTarget target) { var extension = String.Empty; return String.Format("../Builds/{0}/{1}/{2}/{3}", GetProjectName(), PlayerSettings.bundleVersion, target.ToString(), PlayerSettings.bundleIdentifier); } }
The project will be create in the folder ../Builds/{ProjectName}/{BundleVersion}/{TargetPlatform}/{BundleIdentifier} so we have a build for each version of our game in a specific folder.
Custom build
using System.Linq; using System.Security.Policy; using UnityEngine; using UnityEditor; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System; public class AutoBuilderMenu : MonoBehaviour { [MenuItem("AutoBuilder/WP8")] private static void PerformBuild() { // Save current editor build target var currentTarget = EditorUserBuildSettings.activeBuildTarget; EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTarget.WP8Player); var buildPath = GetBuildPath(target); var path = Path.GetDirectoryName(buildPath); var folderExists = Directory.Exists(path); if (!folderExists) Directory.CreateDirectory(path); // First build to create solution folder and project files BuildPipeline.BuildPlayer(GetScenePaths(), buildPath, target, BuildOptions.None); // Replace custom files UpdateWP8Settings(buildPath); // Rebuild with replacing files BuildPipeline.BuildPlayer(GetScenePaths(), buildPath, target, BuildOptions.None); // Set saved editor build target EditorUserBuildSettings.SwitchActiveBuildTarget(currentTarget); } private static void UpdateWP8Settings(string buildPath) { // SplashScreenImage var replace = string.Concat(Application.dataPath, "/../BuildSettings/WP8/SplashScreenImage.jpg"); var current = string.Format("{0}/{1}/SplashScreenImage.jpg", buildPath, PlayerSettings.bundleIdentifier); if (File.Exists(replace)) File.Copy(replace, current, true); // MainPage.xaml.cs replace = string.Concat(Application.dataPath, "/../BuildSettings/WP8/MainPage.xaml.cs"); current = string.Format("{0}/{1}/MainPage.xaml.cs", buildPath, PlayerSettings.bundleIdentifier); if (File.Exists(replace)) File.Copy(replace, current, true); // ApplicationIcon replace = string.Concat(Application.dataPath, "/../BuildSettings/WP8/ApplicationIcon.png"); current = string.Format("{0}/{1}/Assets/ApplicationIcon.png", buildPath, PlayerSettings.bundleIdentifier); if (File.Exists(replace)) File.Copy(replace, current, true); // WMAppManifest replace = string.Concat(Application.dataPath, "/../BuildSettings/WP8/WMAppManifest.xml"); current = string.Format("{0}/{1}/Properties/WMAppManifest.xml", buildPath, PlayerSettings.bundleIdentifier); if (File.Exists(replace)) File.Copy(replace, current, true); } private static string GetProjectName() { string[] s = Application.dataPath.Split('/'); return s[s.Length - 2]; } private static string[] GetScenePaths() { return EditorBuildSettings.scenes.Where(s => s.enabled).Select(s => s.path).ToArray(); } private static string GetBuildPath(BuildTarget target) { return String.Format("../Builds/{0}/{1}/{2}/{3}", GetProjectName(), PlayerSettings.bundleVersion, target.ToString(), PlayerSettings.bundleIdentifier); } }
The trick is to build twice the game. First we build to create all files then we replace our custom files and we rebuild to use these new files.
A more elegant way
private static void PerformBuild(BuildTarget target, bool isBeta = false) { var currentTarget = EditorUserBuildSettings.activeBuildTarget; EditorUserBuildSettings.SwitchActiveBuildTarget(target); var buildPath = GetBuildPath(target); var path = Path.GetDirectoryName(buildPath); var folderExists = Directory.Exists(path); if (!folderExists) { Directory.CreateDirectory(path); } BuildPipeline.BuildPlayer(GetScenePaths(), buildPath, target, BuildOptions.None); if (target == BuildTarget.WP8Player) { UpdateWP8Settings(buildPath, string.Concat(Application.dataPath, "/../BuildSettings/WP8/"), string.Concat(buildPath, "/")); if (isBeta) { UpdateWP8Settings(buildPath, string.Concat(Application.dataPath, "/../BuildSettings/WP8_Beta/"), string.Concat(buildPath, "/")); } BuildPipeline.BuildPlayer(GetScenePaths(), buildPath, target, BuildOptions.None); } EditorUserBuildSettings.SwitchActiveBuildTarget(currentTarget); } private static void UpdateWP8Settings(string buildPath, string sourceRootPath, string destinationRootPath = "") { var files = Directory.GetFiles(sourceRootPath); foreach (var file in files) { var replace = file; var fileName = replace.Split('/').LastOrDefault().Split('\\').LastOrDefault(); var current = string.Concat(destinationRootPath, "/" + fileName); File.Copy(replace, current, true); } var directories = Directory.GetDirectories(sourceRootPath); foreach (var directory in directories) { var folderName = directory.Split('/').LastOrDefault().Split('\\').LastOrDefault(); UpdateWP8Settings(buildPath, directory, destinationRootPath + "/" + folderName); } }
You just need to add all your files in the folder BuildSettings/WP8 and/or BuildSettings/WP8_Beta with the same hierarchy as the project and it’s done ! Thanks Jonathan for the tips ;)
It’s the same way with Windows Store apps :)
Leave a Reply