<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Dino Fejzagić on Medium]]></title>
        <description><![CDATA[Stories by Dino Fejzagić on Medium]]></description>
        <link>https://medium.com/@dinofejzagi?source=rss-266786097a24------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*f2std0TerhWfPdQSEkZ0Cg.png</url>
            <title>Stories by Dino Fejzagić on Medium</title>
            <link>https://medium.com/@dinofejzagi?source=rss-266786097a24------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 04:49:54 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@dinofejzagi/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Using Flask to optimize performance with Mask R-CNN segmentation]]></title>
            <link>https://medium.com/medialesson/using-flask-to-optimize-performance-with-mask-r-cnn-segmentation-39752f153029?source=rss-266786097a24------2</link>
            <guid isPermaLink="false">https://medium.com/p/39752f153029</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[tensorflow]]></category>
            <category><![CDATA[keras]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[flask]]></category>
            <dc:creator><![CDATA[Dino Fejzagić]]></dc:creator>
            <pubDate>Mon, 06 Jul 2020 09:41:50 GMT</pubDate>
            <atom:updated>2020-07-06T09:41:50.508Z</atom:updated>
            <content:encoded><![CDATA[<h4>How to improve Mask R-CNN segmentation performance using a Flask web service.</h4><p>In a recent project I was facing the challenge of creating a machine learning powered photo booth solution. The software allows its users to take pictures of themselves in a car, have the background automagically removed without the usage of a greenscreen, and replaced with another more pleasing background scenery. Among other things, performance was key here. The segmentation needed to be finished by the time it takes the user to exit the car and walk up to the nearby pickup station. That gives us around five to ten seconds.</p><p>In this story you’ll learn how you can use <a href="https://en.wikipedia.org/wiki/Flask_(web_framework)">Flask</a>, a micro web framework written in Python, to drastically reduce the time it takes for the pre-trained <a href="https://github.com/matterport/Mask_RCNN">Mask R-CNN</a> model to generate bounding boxes and segmentation masks for the captured photograph.</p><h4>Mask R-CNN</h4><p>The <a href="https://github.com/matterport/Mask_RCNN">Mask R-CNN</a> for object detection and segmentation framework is a Python implementation based on the work published by <a href="https://arxiv.org/abs/1703.06870">Facebook Research</a> and allows to get bounding boxes and classifications for a variety of object types, such as cars and people, for any input image provided. Of course its performance is heavily bound to the computational power of the host machine.</p><figure><img alt="A busy street with objects classified by Mask R-CNN." src="https://cdn-images-1.medium.com/max/858/1*URsmoj1pYn5V3g6H9Ii1uA.png" /><figcaption>Source: <a href="https://github.com/matterport/Mask_RCNN/raw/master/assets/street.png">https://github.com/matterport/Mask_RCNN/raw/master/assets/street.png</a></figcaption></figure><p>That said, we built a powerful rig equipped with a Nvidia Titan RTX GPU with CUDA support and a high end CPU for any CPU bound work that needed to be done, which is mostly OpenCV based image processing and error corrections. With this setup we achieved a total computation time of around <strong>15 seconds per photograph for an input / output resolution of 1920x1920 pixels</strong>.</p><p>Here’s one example of the processing steps from input to output with me and my colleague:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3jYJRZoeswAs3fJH0gzjeQ.png" /><figcaption>Background segmentation steps and output</figcaption></figure><h4>So how does Flask help here?</h4><p>Once you have started playing around with Mask R-CNN you will notice that the model and its weights need to be loaded and initialized whenever you want to run segmentation on an image. Say you had a Python script called my_segmentation_script.py which takes the path to the input image as an argument, you’d execute it like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4cf10951417f20b7962309fe2087a11a/href">https://medium.com/media/4cf10951417f20b7962309fe2087a11a/href</a></iframe><p>Now this runs fine and will perform the required work, assuming you have setup Mask R-CNN properly. The issue here is that once the script is done it will clean up any allocated resources and release the model and its weights again. So for any subsequent image they have to be loaded again, <strong>which costs us around up to 10 seconds of time! </strong>So let’s try and get rid of this overhead using Flask.</p><p>Follow the instructions over <a href="https://flask.palletsprojects.com/en/1.1.x/installation/">here</a> to install and setup your Flask web service. Once it’s running you’ll be able to create Views which you can think of as API endpoints. Following example code creates a GET endpoint for the api/v1/ route of your flask app that returns &quot;Hello World&quot; when called in a browser:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6d21b39e93472b0ee3c4078748e38a3a/href">https://medium.com/media/6d21b39e93472b0ee3c4078748e38a3a/href</a></iframe><p>All we need to do now is create a view / endpoint for our segmentation python code to execute and pass it an input and output path as parameters so it can read in the image and output the segmentation at the desired path. The important differentiation is that we will only load the model and the weights once when the Flask app starts and then re-use it throughout the session / lifetime of the service. Here’s the full code and then we’ll take a look at it in more detail:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7f4ef4138f97750460a65ac785cd29ad/href">https://medium.com/media/7f4ef4138f97750460a65ac785cd29ad/href</a></iframe><p>Most if this is just boilerplate code for importing the required Python modules and creating the Flask view. Pay attention to <strong>lines 11 through 23 </strong>as we are initializing the keras session here and then loading in the model weights. At line <strong>23</strong> we are then finally assigning the created session to be the active session.</p><p>Next we are simply defining a POST endpoint that takes the input and output path in its request body. Note lines <strong>30, 31 and 32</strong> here as this is where we are making sure that we are using the globally defined session and graph variables we just created.</p><p>Using main.doSegmentation(rcnn, input_file_path, output_file_path) we are then passing everything to our segmentation code, which makes use of the pre-loaded weights.</p><h4>Summary</h4><p>By loading the model weights only once and then using them in a shared session throughout the lifetime of the Flask service we were able to save another ~10 seconds of computation time for a captured photograph to run through background segmentation. Combined with decent hardware this fulfills our requirements in performance for the photo booth to work.</p><p>Please share in the comments if you run in to any issues or if you have questions. I hope you find this little trick useful and can boost your performance just as I did!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=39752f153029" width="1" height="1" alt=""><hr><p><a href="https://medium.com/medialesson/using-flask-to-optimize-performance-with-mask-r-cnn-segmentation-39752f153029">Using Flask to optimize performance with Mask R-CNN segmentation</a> was originally published in <a href="https://medium.com/medialesson">Medialesson</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Simple service locator for your Unity project]]></title>
            <link>https://medium.com/medialesson/simple-service-locator-for-your-unity-project-40e317aad307?source=rss-266786097a24------2</link>
            <guid isPermaLink="false">https://medium.com/p/40e317aad307</guid>
            <category><![CDATA[unity3d]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-patterns]]></category>
            <category><![CDATA[game-development]]></category>
            <category><![CDATA[unity-game-development]]></category>
            <dc:creator><![CDATA[Dino Fejzagić]]></dc:creator>
            <pubDate>Wed, 22 Jan 2020 10:37:28 GMT</pubDate>
            <atom:updated>2020-01-22T19:54:54.102Z</atom:updated>
            <content:encoded><![CDATA[<p>There are many great tutorials on Unity out there on the internet for you to learn from. Most of them target Unity beginners though or keep their samples very simple and do not pay attention to more advanced coding techniques. In this article we’ll learn how we can write our very own simple service locator in Unity and use it to optimize our code architecture and maintainability.</p><p>Very often you’ll find awesome coding tutorials on Unity which will include a combination of these “pitfalls” for simplicity:</p><ul><li>Only public fields in scripts</li><li>Make everything a Singleton</li><li>Non performance-optimized code</li><li>Synchronous scene loading</li><li>Only MonoBehaviours</li><li>…</li></ul><p>We could go on here. Don’t get me wrong, nothing wrong about it. They still carry the message and instructions they intend to teach their audience. Let’s take a look at how we can implement a simple Service Locator pattern to improve on some of these aspects.</p><h4>Creating a new Unity project</h4><p>You can go ahead and create a new Unity project to work with or implement it right into your existing project, as you like. I am using Unity 2019.3.0f5 here.</p><ul><li>Open Unity Hub</li><li>Create a new project using whichever template you like</li><li>In your Assets folder create a new folder and name it ServiceLocator, we’ll put all the code in here</li></ul><h4>Implementing the service locator</h4><p>In the first step let’s create a service interface for our service locator to work with. Inside yourAssets/ServiceLocator folder create a new script file IGameService.cs:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/adeb5192740aaa79becb089f327e38a8/href">https://medium.com/media/adeb5192740aaa79becb089f327e38a8/href</a></iframe><p>As you can see we leave it empty for now. We want to keep this sample really simple. Once you we got everything in place, you can use this interface to define what your services have in common and should look like and which APIs they provide.</p><p>Next we actually already get to implement the service locator. Again in Assets/ServiceLocator create a new script file ServiceLocator.cs:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6e49d1f249dd3d4066109b8a0dc50b2b/href">https://medium.com/media/6e49d1f249dd3d4066109b8a0dc50b2b/href</a></iframe><p>A few more things going on here. Let’s step through:</p><ul><li>private ServiceLocator() {} we make default constructor private to avoid misuse of the service locator by creating new instances of it randomly.</li><li>Dictionary&lt;string, IGameService&gt; services will hold all currently registered services using their type name as the key to retrieve them.</li><li>public static ServiceLocator Current { get; private set; } a static property which will hold the currently active service locator instance. This should be the only Singleton in your application basically from now on.</li><li>Initialize() will initialize the active service locator with a new instance.</li><li>public T Get&lt;T&gt;() where T : IGameService is used to get a service instance from the service locator. We are restricting the generic type T to types implementing our IGameService interface.</li><li>public void Register&lt;T&gt;(T service) where T : IGameService is used to register a service instance with our locator. It will then be available using Get&lt;T&gt; .</li><li>public void Unregister&lt;T&gt;() where T : IGameService for completeness we provide a way here to unregister a service of a given type from the locator.</li></ul><p>And that’s it regarding the locator itself! Did I mention we want to keep this locator simple? Doesn’t get any simpler I think. Worth nothing here is that this service locator will only allow one instance of a service of a given type. Which should do the trick on most cases. You can modify it to support multiple instances of a type easily.</p><h4>Bootstrapping the service locator</h4><p>Now that we have our locator implemented let’s see how we can initialize it when the application starts.</p><p>In Assets/ServiceLocator create a new script file Bootstrapper.cs:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cd0c7e98a1de60cac4fc6b59cf53542f/href">https://medium.com/media/cd0c7e98a1de60cac4fc6b59cf53542f/href</a></iframe><p>Ok. Let’s see what’s going on here. I am assuming for this bootstrapper script that you have some sort of “Base Scene” in your Uniy project. This should be the scene at index 0 of your overall scenes. Use it to get your application ready and initialize everything other scenes may need to work with.</p><p>[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] using this attribute we tell Unity to run the static method Initialize() once the base scene has fully loaded. Inside Intialize() we create the service locator instance and then proceed to register all our game services with it. Once that is done, we can load our main scene which will contain appilcation content using those services eventually. You can extend this bootstrapper as needed.</p><h4>What we learned and gained</h4><p>In this short sample we learned how to implement our very own service locator and use it in our Unity project. But what did we gain?</p><ul><li>You will find that it’s much easier for you now to separate business logic code from visualization code. Your game services can take care of handling data and such, while you’ll be creating MonoBehaviours to visualize it and use it.</li><li>This service locator is a good starting point to think about how you can implement Dependency Injection in your project next.</li><li>You can now easily write Unit Tests out of Unity for your services since they are not MonoBehvaiours anymore.</li></ul><h4>About reinventing the wheel</h4><p>Of course you don’t have to reinvent the wheel here. There is existing service locator implementations for Unity out there. If you like the idea, I can recommend taking a look at</p><p><a href="https://xrtk.io/README.html">XRTK</a> and <a href="https://github.com/microsoft/MixedRealityToolkit-Unity">MRTK</a> for two examples of existing implementations. Both provide a very good starting point for you and ways to implement your own services and register them with their service locator.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40e317aad307" width="1" height="1" alt=""><hr><p><a href="https://medium.com/medialesson/simple-service-locator-for-your-unity-project-40e317aad307">Simple service locator for your Unity project</a> was originally published in <a href="https://medium.com/medialesson">Medialesson</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Continuous integration for Unity 3D projects using Azure Pipelines]]></title>
            <link>https://medium.com/medialesson/continuous-integration-for-unity-3d-projects-using-azure-pipelines-e61ddf64ad79?source=rss-266786097a24------2</link>
            <guid isPermaLink="false">https://medium.com/p/e61ddf64ad79</guid>
            <category><![CDATA[game-development]]></category>
            <category><![CDATA[continuous-integration]]></category>
            <category><![CDATA[unity3d]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[azure-pipelines]]></category>
            <dc:creator><![CDATA[Dino Fejzagić]]></dc:creator>
            <pubDate>Mon, 10 Dec 2018 15:03:19 GMT</pubDate>
            <atom:updated>2018-12-11T08:12:52.586Z</atom:updated>
            <content:encoded><![CDATA[<p>When working with Unity 3D, have you ever found yourself thinking “Wouldn’t it be cool if I could just push my code to the repository and then magically I get a build with the latest changes ready for distribution to my testers or the client?” — Think no more! This article will teach you how to setup continuous integration for your Unity project using <a href="https://azure.microsoft.com/en-us/services/devops/pipelines/">Microsoft’s Azure Pipelines</a>, which are part of the awesome <a href="https://azure.microsoft.com/en-us/services/devops/">Azure DevOps</a> suite.</p><h4>Step 1: Install the required extension to build Unity projects</h4><p>As of now Azure Pipelines does not have a built-in task for building Unity projects. Luckily it’s extendible and we can create our own build task for use in our pipelines. “Ain’t nobody got time for this!” you say? No worries, I already went ahead and created an extension for you to use. Head to the <a href="https://marketplace.visualstudio.com/items?itemName=DinomiteStudios.64e90d50-a9c0-11e8-a356-d3eab7857116">marketplace </a>and install it for use in your organization:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6MO5i5yUgI3WtU40FlXv4A.jpeg" /><figcaption>Searching for “Unity” in the marketplace to install the needed extension</figcaption></figure><p><em>Please note:</em> There is another Unity build extension. But that one targets specifically HoloLens Unity projects and requires the HoloToolkit to be in the project. Make sure you get the right one for this article, which is the one titled <strong>“Unity Build”.</strong></p><p><em>Please note also:</em> I’ve made the extension <a href="https://github.com/Dinomite-Studios/unity-build-task">open source on GitHub</a>. If you feel the need to improve on it please feel free to do a pull request. Also please report any issues over there, so I can fix them.</p><h4>Step 2: Create and configure your custom build agent</h4><p>While you could use the Microsoft hosted agents, I recommend setting up your own agent for Unity builds. This gives you full control over the available Unity versions and modules. Let’s get started. Navigate to your Azure DevOps homepage and in the top right corner click on your profile picture, in the menu then select <strong>“Security”</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/311/1*YQ8vXrOG7iZIY0nL7QCCGg.png" /><figcaption>Opening the security settings for your Azure DevOps account</figcaption></figure><p>This will open the security settings when you can create a Personal Access Token (PAT) that your agent can use to configure itself with the DevOps Organzation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jN8Iqf5E3f_ay-HnyYH6Jg.jpeg" /><figcaption>Creating the PAT for your agent</figcaption></figure><p>Select<strong> “New Token”</strong> right below the page header, then give a meaningful name to your PAT. Select <strong>“Custom defined”</strong> scopes and in the lower end of the panel find <strong>“Show more scopes”</strong>. Now find the <strong>“Agent Pools”</strong> scope and tick the <strong>“Read &amp; manage”</strong> checkbox. Finally click <strong>“Create”</strong> to create the PAT. Make sure to note the PAT somewhere until we need it. You will not be able to see it again, once the panel has closed. Next we will setup the agent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8wQsN1PFnvg44wrFL_LXkw.jpeg" /><figcaption>Creating a new agent pool</figcaption></figure><p>Select <strong>“Organzation settings”</strong> and then <strong>“Agent pools”</strong>. Click <strong>“New agent pool…”</strong> to create a new pool. Name it<em> Unity Windows Agents</em> e.g. If you are creating a Mac agent, name the pool accordingly. You will need this name later. Last but not least click <strong>“Download agent”</strong>. Please follow the instructions to download and configure your agent. You will need the PAT and Agent pool name in this process. Let me know in the comments, if you have any issues. Last but not least, please install the <a href="https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup.exe?_ga=2.262761861.828649431.1544441110-706689545.1521281363">Unity Hub</a> on the agent and install the Unity versions you need.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1003/1*nLqIK9iQkaD_hprFSgLGng.jpeg" /><figcaption>Installilng Unity versions you need using the Unity Hub</figcaption></figure><h4>Step 3: Setting up an example build pipeline</h4><p>For this article we’ll create a build pipeline targeting the Android platform. The steps may differ a bit depending on your project’s target platform but should generally be similar. So head over to your Azure DevOps project and in the pipelines section, create a new build pipeline, by clicking <strong>“New”</strong> -&gt; <strong>“New build pipeline”</strong>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iFz1MHEO1aP5_MMjADKAXw.jpeg" /><figcaption>Creating a new Azure Pipeline</figcaption></figure><p>Next you need to tell the pipeline wizard where to get the source code from. In my case, it’s all hosted on Azure Repos. You can change these settings later on, if you need to:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D9mQQE51mTnU3T7x4cnoIQ.jpeg" /><figcaption>Selecting the repository to build from</figcaption></figure><p>The wizard will now offer some templates to start from. Please select the empty job template. We want to start from scratch:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Fhq6yPYMp8me4SVhYzNV_Q.png" /><figcaption>Creating an empty pipeline using the Empty job template</figcaption></figure><p>Alright. Now click the plus icon button as highlighted in the screenshot below, enter “Unity” in the task search textbox and add the Unity Build task, you installed in the beginning of this article, to the job:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8atJmKWiDo4F6Ai4H3bnvw.jpeg" /><figcaption>Adding the Unity build task to your pipeline</figcaption></figure><p>Now please repeat and add the following tasks as well <strong>“Android Signing”</strong>, <strong>“Copy Files”</strong> and <strong>“Publish Build Artifacts”</strong>. Your pipeline should now look something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/622/1*nUBqwmIahiKlH1z303nUig.jpeg" /><figcaption>Example pipeline for building a signed Android APK</figcaption></figure><p>I am not going into details with the Microsoft built-in tasks. If you have issues configuring them, please refer to the official documentation or let me know, maybe I can help out. We’ll focus on the Unity Build task and how to configure it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/989/1*i8URGcVxT_j0jST2ZVU3OQ.png" /><figcaption>Configuring the Unity build task</figcaption></figure><p>Basically the only thing you need to do here, is tell the task which target platform you are building for. We are targeting Android in this example, so make sure to select <strong>“Android”</strong> in the <strong>“Build Target”</strong> dropdown. For <strong>“Unity Version”</strong> select <strong>“Project Version”</strong>. This will build the project with the Unity version it was last opened with. Make sure it’s installed on the agent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/970/1*U8o0LiC1mvCfFhMrM8dDcg.png" /><figcaption>Assigning a reference name to access output variables</figcaption></figure><p>Next unfold the <strong>“Output Variables”</strong> section of the task and enter a reference name here. The task provides a <strong>buildOutputPath</strong> variable you can use in following tasks to get the build output files.</p><p>That’s it! This pipeline will build your Unity project, sign the APK and publish it to the Azure DevOps artifact store so others can download it. In an advanced scenario you could let the pipeline publish it to the App center or some store e.g. for testing.</p><h4>Conclusion</h4><p>Setting up your own build agent is a one time process that will definitely pay out once you get comfortable building your projects using Azure Pipelines. Once you’ve done that, you can use it across all projects in your organization.</p><p>Please share your feedback and let me know if it worked for you or you want to discuss things for advanced scenarios. Happy building!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e61ddf64ad79" width="1" height="1" alt=""><hr><p><a href="https://medium.com/medialesson/continuous-integration-for-unity-3d-projects-using-azure-pipelines-e61ddf64ad79">Continuous integration for Unity 3D projects using Azure Pipelines</a> was originally published in <a href="https://medium.com/medialesson">Medialesson</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to add a 3D app launcher to your Mixed Reality app right out of Unity]]></title>
            <link>https://medium.com/medialesson/how-to-add-a-3d-app-launcher-to-your-mixed-reality-app-right-out-of-unity-4c0c75889cef?source=rss-266786097a24------2</link>
            <guid isPermaLink="false">https://medium.com/p/4c0c75889cef</guid>
            <category><![CDATA[virtual-reality]]></category>
            <category><![CDATA[unity-game-development]]></category>
            <category><![CDATA[mixed-reality]]></category>
            <category><![CDATA[windows-mixed-reality]]></category>
            <category><![CDATA[hololens]]></category>
            <dc:creator><![CDATA[Dino Fejzagić]]></dc:creator>
            <pubDate>Wed, 19 Sep 2018 08:02:27 GMT</pubDate>
            <atom:updated>2018-11-13T17:24:20.705Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6-sqFNEWIuXyV1sq5nQ7fQ.jpeg" /><figcaption>3D App Launcher for Microsoft’s RoboRaid game</figcaption></figure><p>When the Windows Mixed Reality platform was introduced a couple of applications had these really cool 3D app launchers you could place somewhere in the mixed reality world and launch the app when selecting them. Unfortunately back then, there was no way for developers to use this feature for their own applications. Luckily those days are gone, Microsoft introduced new APIs in the 2017 Fall Creators Update (RS3) for their immersive headsets. Since April 2018 Update (RS4) even HoloLens devices can use them.</p><p>As you might know, most of the Windows Mixed Reality appilcations out there are made using the <a href="https://unity3d.com/">Unity Engine</a>. Once you are done developing and want to deploy to a device, you’re going to do a Unity build which will create a Visual Studio Solution for us targeting the Universal Windows Platform. All good so far. Now if you’ve read through the <a href="https://docs.microsoft.com/en-us/windows/mixed-reality/implementing-3d-app-launchers">3D app launchers documentation</a> you’ll notice that in order for them to work, there is some changes we need to do to the Visual Studio project file and the appmanifest file for them to work. This is where things get complicated, since those changes are gone when you create a new Unity build in a different folder or build your app using continuous integration somewhere in the cloud. So let’s fix this by creating a Unity post build script to do the required changes for us whenever we build. Credit for most part of the code goes to <a href="http://fracturereality.io/">Edd Smith, Head of Creative Tech at Fracture Reality</a>. I applied some minor tweaks to get it working with IL2CPP scripting backend.</p><p>First, we’ll create scriptable object to conveniently hold our 3D launcher data. So create a folder <strong>3DLauncher </strong>in your Unity project Assets folder. Then create a new Script file and name it <strong>AppLauncher3D</strong>. Insert the following code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/95a2433700b35797bdcc7e1a018c4c79/href">https://medium.com/media/95a2433700b35797bdcc7e1a018c4c79/href</a></iframe><p>Once Unity has compiled the script, you’ll get a new menu item in the Editor Assets menu under <strong>Assets-&gt;Create-&gt;3D App Launcher</strong>. Next create a new folder <strong>Editor </strong>in your 3DLauncher folder and create another script file in it, name it <strong>AppLauncher3DEditor</strong>. This script is going to use the UnityEditor namespace, that’s why it must be inside a folder called Editor, so it’s not included when building for the target platform. Anyway, here’s the code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/70c09902018c5adf1278155ad11974b5/href">https://medium.com/media/70c09902018c5adf1278155ad11974b5/href</a></iframe><p>Let’s break this into smaller pieces:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/edbafbd3524e4339c649fd44ebcf23b7/href">https://medium.com/media/edbafbd3524e4339c649fd44ebcf23b7/href</a></iframe><p>This is our entry point. Since we added the PostProcessBuild attribute to this static method, Unity will execute it, once it has finished building the UWP solution and give as the path to the exported project. Since Unity will do this, even when not targeting the UWP platform, we have to make sure, we are targeting it. Then we lookup the AppLauncher3D asset we created to read the configuration from it. Remember it contains the path to the .glb file and eventually overrides bounding box and center.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0c580bc0fdd4ed0c52ad4e4097d088bb/href">https://medium.com/media/0c580bc0fdd4ed0c52ad4e4097d088bb/href</a></iframe><p>This is where we peform the 3 steps necessary for the 3D launcher to work:</p><ol><li>Add the required definition to the package manifest</li><li>Add the asset to the project and mark is as deployment content</li><li>Copy the .glb file into the projects assets folder</li></ol><p>I’ll leave it up to you to dig into the specific methods and discover them!</p><p>And we’re done! Go ahead and create a .glb file for your 3D launcher, then add it to your Unity project assets and create the scriptable object asset to configur it. Build your project and you’ll have a shiny new 3D app launcher!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4c0c75889cef" width="1" height="1" alt=""><hr><p><a href="https://medium.com/medialesson/how-to-add-a-3d-app-launcher-to-your-mixed-reality-app-right-out-of-unity-4c0c75889cef">How to add a 3D app launcher to your Mixed Reality app right out of Unity</a> was originally published in <a href="https://medium.com/medialesson">Medialesson</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>