Last active
September 18, 2018 17:38
-
-
Save WikkidEdd/d8f7edc474103aa8db16ff841e267ec9 to your computer and use it in GitHub Desktop.
Build process and asset to add 3d app launchers to Hololens apps. Add AppLauncher3DEditor.cs in to an "Editor" folder. Create a new 3DAppLauncher asset in your project and enter the path to your glb.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
[CreateAssetMenu(fileName="3DAppLauncher", menuName = "3D App Launcher")] | |
public class AppLauncher3D : ScriptableObject | |
{ | |
[Tooltip("Path to glb relative to Assets folder. Include file extension")] | |
public string _Model; | |
public bool _OverrideBoundingBox = false; | |
public Vector3 _Center; | |
public Vector3 _Extents = Vector3.one; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.IO; | |
using System.Xml; | |
using UnityEditor; | |
using UnityEditor.Callbacks; | |
using UnityEngine; | |
[CustomEditor(typeof(AppLauncher3D))] | |
public class AppLauncher3DEditor : Editor | |
{ | |
[PostProcessBuild(1)] | |
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) | |
{ | |
if (target == BuildTarget.WSAPlayer) | |
{ | |
// Find App Launcher Asset, if not we don't need to do anything | |
string[] applauncher3DAssets = AssetDatabase.FindAssets("t:AppLauncher3D"); | |
if (applauncher3DAssets.Length > 0) | |
{ | |
// Load in asset | |
string assetPath = AssetDatabase.GUIDToAssetPath(applauncher3DAssets[0]); | |
AppLauncher3D appLauncher = AssetDatabase.LoadAssetAtPath<AppLauncher3D>(assetPath); | |
// Add app launcher to project | |
Add3DAppLauncher(pathToBuiltProject, appLauncher); | |
} | |
} | |
} | |
// Define DEBUG_BUTTON to quickly iterate in editor without having to build. | |
#if DEBUG_BUTTON | |
public override void OnInspectorGUI() | |
{ | |
base.OnInspectorGUI(); | |
if(GUILayout.Button("Add 3D App Launcher")) | |
{ | |
Add3DAppLauncher(AbsoluteBuildDirectory, target as AppLauncher3D); | |
} | |
} | |
public static string AbsoluteBuildDirectory | |
{ | |
get { return Path.GetFullPath(Path.Combine(Path.Combine(Application.dataPath, ".."), "WindowsStoreApp")); } | |
} | |
#endif | |
private static void Add3DAppLauncher(string buildPath, AppLauncher3D settings) | |
{ | |
string pathToProjectFiles = Path.Combine(buildPath, Application.productName); | |
AddToPackageManifest(pathToProjectFiles, settings); | |
if (PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup) == ScriptingImplementation.IL2CPP) | |
AddToVCXProj(pathToProjectFiles); | |
else | |
AddToCSProj(pathToProjectFiles); | |
CopyModel(pathToProjectFiles, settings); | |
} | |
private static void CopyModel(string buildPath, AppLauncher3D settings) | |
{ | |
string launcherFileSourcePath = Path.Combine(Application.dataPath, settings._Model); | |
string launcherFileTargetPath = Path.Combine(buildPath, "Assets\\AppLauncher_3D.glb"); | |
FileUtil.ReplaceFile(launcherFileSourcePath, launcherFileTargetPath); | |
} | |
private static void AddToVCXProj(string buildPath) | |
{ | |
// Load project file xml | |
string projFilename = Path.Combine(buildPath, PlayerSettings.productName + ".vcxproj"); | |
XmlDocument document = new XmlDocument(); | |
document.Load(projFilename); | |
// Check if we've already added model to the project | |
bool alreadyAdded = false; | |
XmlNodeList nones = document.GetElementsByTagName("None"); | |
foreach (var none in nones) | |
{ | |
XmlElement element = none as XmlElement; | |
if (element.GetAttribute("Include") == "Assets\\AppLauncher_3D.glb") | |
{ | |
alreadyAdded = true; | |
} | |
} | |
// If not add the content object | |
if (!alreadyAdded) | |
{ | |
XmlElement newItemGroup = document.CreateElement("ItemGroup", document.DocumentElement.NamespaceURI); | |
XmlElement newNoneElement = document.CreateElement("None", document.DocumentElement.NamespaceURI); | |
XmlNode deploymentContentNode = document.CreateElement("DeploymentContent", document.DocumentElement.NamespaceURI); | |
newNoneElement.AppendChild(deploymentContentNode); | |
deploymentContentNode.AppendChild(document.CreateTextNode("true")); | |
newNoneElement.SetAttribute("Include", "Assets\\AppLauncher_3D.glb"); | |
newItemGroup.AppendChild(newNoneElement); | |
document.DocumentElement.AppendChild(newItemGroup); | |
} | |
// Save project xml file | |
document.Save(projFilename); | |
} | |
private static void AddToCSProj(string buildPath) | |
{ | |
ScriptingImplementation scriptingImplementation = PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup); | |
// Load project file xml | |
string projFilename = Path.Combine(buildPath, PlayerSettings.productName + ".csproj"); | |
XmlDocument document = new XmlDocument(); | |
document.Load(projFilename); | |
// Check if we've already added model to the project | |
bool alreadyAdded = false; | |
XmlNodeList contents = document.GetElementsByTagName("Content"); | |
foreach (var content in contents) | |
{ | |
XmlElement element = content as XmlElement; | |
if (element.GetAttribute("Include") == "Assets\\AppLauncher_3D.glb") | |
{ | |
alreadyAdded = true; | |
} | |
} | |
// If not add the content object | |
if (!alreadyAdded) | |
{ | |
XmlElement itemGroup = document.CreateElement("ItemGroup", document.DocumentElement.NamespaceURI); | |
XmlElement content = document.CreateElement("Content", document.DocumentElement.NamespaceURI); | |
content.SetAttribute("Include", "Assets\\AppLauncher_3D.glb"); | |
itemGroup.AppendChild(content); | |
document.DocumentElement.AppendChild(itemGroup); | |
} | |
// Save project xml file | |
document.Save(projFilename); | |
} | |
private static void AddToPackageManifest(string buildPath, AppLauncher3D settings) | |
{ | |
// Load package appxmanifest xml | |
string packageManifestPath = Path.Combine(buildPath, "Package.appxmanifest"); | |
XmlDocument document = new XmlDocument(); | |
document.Load(packageManifestPath); | |
// Find the package node | |
XmlNodeList packages = document.GetElementsByTagName("Package"); | |
XmlElement package = packages.Item(0) as XmlElement; | |
// Set the require attributes | |
package.SetAttribute("xmlns:uap5", "http://schemas.microsoft.com/appx/manifest/uap/windows10/5"); | |
package.SetAttribute("xmlns:uap6", "http://schemas.microsoft.com/appx/manifest/uap/windows10/6"); | |
package.SetAttribute("IgnorableNamespaces", "uap uap2 uap5 uap6 mp"); | |
// Check if we've already added the mixedl reality model node | |
XmlNodeList mixedRealityModels = document.GetElementsByTagName("uap5:MixedRealityModel"); | |
XmlElement mixedRealityModel = null; | |
if (mixedRealityModels.Count == 0) | |
{ | |
// Add mixed reality model node | |
XmlNodeList defaultTiles = document.GetElementsByTagName("uap:DefaultTile"); | |
XmlNode defaultTile = defaultTiles.Item(0); | |
mixedRealityModel = document.CreateElement("uap5", "MixedRealityModel", "http://schemas.microsoft.com/appx/manifest/uap/windows10/5"); | |
defaultTile.AppendChild(mixedRealityModel); | |
} | |
else | |
{ | |
mixedRealityModel = mixedRealityModels.Item(0) as XmlElement; | |
} | |
// Set the path of the mixed reality model | |
mixedRealityModel.SetAttribute("Path", "Assets\\AppLauncher_3D.glb"); | |
// Check if we've already got a bounding box and remove it | |
XmlNodeList boundingBoxes = document.GetElementsByTagName("uap6:SpatialBoundingBox"); | |
if (boundingBoxes.Count == 1) | |
{ | |
mixedRealityModel.RemoveChild(boundingBoxes.Item(0)); | |
} | |
// Add it back in if we want to override bounding box | |
if (settings._OverrideBoundingBox) | |
{ | |
// Add mixed reality model node | |
XmlElement boundingBox = document.CreateElement("uap6", "SpatialBoundingBox", "http://schemas.microsoft.com/appx/manifest/uap/windows10/6"); | |
string center = settings._Center.x + "," + settings._Center.y + "," + settings._Center.z; | |
string extents = settings._Extents.x + "," + settings._Extents.y + "," + settings._Extents.z; | |
boundingBox.SetAttribute("Center", center); | |
boundingBox.SetAttribute("Extents", extents); | |
mixedRealityModel.AppendChild(boundingBox); | |
} | |
// Save xml | |
document.Save(packageManifestPath); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment