{"id":1862,"date":"2021-09-09T12:17:28","date_gmt":"2021-09-09T19:17:28","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=1862"},"modified":"2021-09-09T12:17:28","modified_gmt":"2021-09-09T19:17:28","slug":"unity-jetpack-window-manager-beta","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/unity-jetpack-window-manager-beta\/","title":{"rendered":"Unity and Jetpack Window Manager"},"content":{"rendered":"<p>\n  Hello game developers!\n<\/p>\n<p>\n  We\u2019ve covered Jetpack Window Manager in the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/platform\/jetpack-window-manager\">docs<\/a>, and <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/dual-screen-games-with-unity-for-android\">previously blogged<\/a> about how to integrate the DisplayMask API into a Unity sample. In this post I\u2019ll describe how to <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk-unity-samples\/pull\/6\">extend a Unity project<\/a> to integrate native Android code and configuration to include the Jetpack Window Manager package and provide dual-screen and foldable device information to your Unity app or game.\n<\/p>\n<p>\n  By providing folding feature information you can adapt your Unity code to move user interface elements away from the hinge, adapt gameplay for foldable devices, or even incorporate device features like the device hinge angle sensor in your user interactions.\n<\/p>\n<p>\n  <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/unity-beta01-800.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/unity-beta01-800.png\" alt=\"Surface Duo showing the Unity sample, which shows data about the device including screen size and hinge position in text on the screen\" width=\"800\" height=\"620\" class=\"alignnone size-full wp-image-1871\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/unity-beta01-800.png 800w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/unity-beta01-800-300x233.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/unity-beta01-800-768x595.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><br\/><em>Figure 1: Unity demo showing Window Manager Folding Feature data (as well as legacy DisplayMask data and the hinge angle)<\/em>\n<\/p>\n<p>\n  This blog post explains how to incorporate the latest Jetpack Window Manager package into a Unity project. These instructions are also available in the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/unity\/jetpack-window-manager\">dual-screen developer documentation<\/a>.\n<\/p>\n<h2>Extending the Unity Activity<\/h2>\n<p>\n  To customize the relevant Android build files, go to <strong>Edit &gt; Project Settings\u2026 &gt; Player &gt; (Android) &gt; Publishing Settings<\/strong> and check these <strong>Build<\/strong> options:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"651\" height=\"442\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/graphical-user-interface-text-application-descr.png\" class=\"wp-image-1864\" alt=\"Unity Publishing Settings Build options, showing the checkboxes you need to check to customize the files updated in the following instructions, including Custom Main Manifest, Custom Main Gradle Template, and Custom Gradle Properties Template\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/graphical-user-interface-text-application-descr.png 651w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/graphical-user-interface-text-application-descr-300x204.png 300w\" sizes=\"(max-width: 651px) 100vw, 651px\" \/>\n<\/p>\n<p>\n  This will place new items in the Project\u2019s <strong>Assets\/Plugins\/Android<\/strong> folder (plus a Java file that is added manually):\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"972\" height=\"429\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/word-image.png\" class=\"wp-image-1865\" alt=\"Unity Project tab showing the files created by checking boxes in the Publishing Settings Build tab, which are AndroidManifest.xml, FoldablePlayerActivity.java, gradleTemplate.properties, and mainTemplate.gradle\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/word-image.png 972w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/word-image-300x132.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2021\/09\/word-image-768x339.png 768w\" sizes=\"(max-width: 972px) 100vw, 972px\" \/>\n<\/p>\n<p>\n  The purpose of each file is explained below:\n<\/p>\n<ul>\n<li><strong>mainTemplate.gradle<\/strong> \u2013 This file allows for customization of various build options for the Android app. It contains placeholders like <code>**APIVERSION**<\/code> so that Unity can insert values from the project\u2019s configuration but allows for user-entered items as well. To include Jetpack Window Manager in the project, we need to add the following:\n<pre>  dependencies {\r\n      implementation \"androidx.window:window:1.0.0-beta02\"\r\n      implementation \"androidx.window:window-java:1.0.0-beta02\"\r\n      implementation \"org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.61\"\r\n      implementation 'androidx.appcompat:appcompat:1.2.0'\r\n      implementation 'androidx.core:core-ktx:1.3.2'\r\n  }<\/pre>\n<\/li>\n<li><strong>gradleTemplate.properties<\/strong> \u2013 Once again allows placeholders for Unity (such as <code>**ADDITIONAL_PROPERTIES**<\/code>) but also allows for customization. For Jetpack Window Manager, we need to add the following line:\n<pre>  android.useAndroidX = true<\/pre>\n<\/li>\n<li><strong>AndroidManifest.xml<\/strong> \u2013 Unity will generate an AndroidManifest.xml using project properties set in the development environment. To customize elements not exposed in the Project Settings dialog, you can create this file and the Unity build system will merge everything together. Because we want to specify our own activity class, the custom XML just contains the &lt;activity&gt; element with our custom classname, leaving all other important things to the IDE properties:\n<pre>  &lt;activity android:name&gt;=\"com.microsoft.device.dualscreen.unity.FoldablePlayerActivity\"<\/pre>\n<\/li>\n<li><strong>FoldablePlayerActivity.java<\/strong> \u2013  This is where we write the code to implement Jetpack Window Manager and make it available for the Unity app to access via C#. See the next section for implementation details \u2013 you can just copy and paste this file into your game project, and then access the information it provides in your code.\n  <\/li>\n<\/ul>\n<h2>FoldablePlayerActivity.java<\/h2>\n<p>\n  Review the <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk-unity-samples\/blob\/main\/duo-screenhelper\/Assets\/Plugins\/Android\/FoldablePlayerActivity.java\">FoldablePlayerActivity sample code<\/a> for an example of how you can access Window Manager \u2013 <em>you can copy this file directly into your game code<\/em>. Most apps will not need to access all the values available \u2013 just choose the information that works for your use case. The high-level features of the code are:\n<\/p>\n<ol>\n<li>\n  <b>Package name<\/b> \u2013 This must match the AndroidManifest class name.\n<\/li>\n<li>\n  <b>Imports<\/b> \u2013 We need to ensure all the classes required by Window Manager are included.\n<\/li>\n<li>\n  <b>Activity extends UnityPlayerActivity<\/b> \u2013 The base class provided by Unity must be implemented so that the main Unity code is started.\n<\/li>\n<li>\n  <b>Window Manager<\/b> \u2013 Follow the documentation to implement Window Manager and extract the information needed for your Unity project.\n<\/li>\n<li>\n  <b>Properties<\/b> \u2013 Expose the Window Manager values via a public API so they can be consumed in Unity.\n<\/li>\n<\/ol>\n<p>\n  Thanks to Unity\u2019s native integration this file can be placed in the <strong>Assets\/Plugins\/Android<\/strong> folder, and it will be compiled as part of the Android build process (including the references to the UnityPlayerActivity class, as well as the libraries added to gradle). It\u2019s important that the <strong>AndroidManifest.xml<\/strong> file is updated to reference the new class (as shown above, and in the sample project).\n<\/p>\n<h2>WindowManagerHelper.cs<\/h2>\n<p>\n  To access the native API from C#, use the interop features of Unity to get the values set by Jetpack Window Manager. The example <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk-unity-samples\/blob\/main\/duo-screenhelper\/Assets\/SurfaceDuo\/Plugins\/WindowManagerHelper.cs\">WindowManagerHelper.cs<\/a> shows how to use <code>OnPlayer.Run<\/code> and the <code>AndroidJavaObject<\/code> class to query the native code \u2013 <em>you can copy this file directly into your game code<\/em>.\n<\/p>\n<p>\n  The static constructor for WindowManagerHelper caches a reference to the FoldablePlayerActivity in its constructor:\n<\/p>\n<pre>  foldablePlayerActivity = OnPlayer.Run(p =&gt;\r\n  {\r\n      return p.GetStatic&lt;AndroidJavaObject&gt;(\"currentActivity\");\r\n  });<\/pre>\n<p><em>NOTE: the FoldablePlayerActivity is the \u201ccurrentActivity\u201d for the Unity app because we configured it in the AndroidManifest.xml<\/em>\n<\/p>\n<p>\n  Methods matching each of the different properties in Window Manager can then use the activity reference to retrieve information such as isSeparating, orientation, occlusionType, or the folding feature bounds. Here\u2019s an example method that retrieves one of the values from native Java code:\n<\/p>\n<pre>  public static bool IsSeparating() {}\r\n      var foldingFeatureObject = foldablePlayerActivity.Call&lt;AndroidJavaObject&gt;(\"getFoldingFeature\");\r\n      if (foldingFeatureObject == null)\r\n      {\r\n          return false;\r\n      }\r\n      else \r\n      {\r\n          return foldingFeatureObject.Call&lt;bool&gt;(\"isSeparating\");\r\n      }\r\n  }<\/pre>\n<h2>Feedback and resources<\/h2>\n<p>\n  The sample <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk-unity-samples\/\">duo-screenhelper<\/a> project is available on GitHub.\n<\/p>\n<p>\n  If you have any questions, or would like to tell us about your games, use the\u00a0<a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a>\u00a0or message us on Twitter\u00a0<a href=\"https:\/\/twitter.com\/surfaceduodev\">@surfaceduodev<\/a>.\u00a0\n<\/p>\n<p>\n  Finally, please join us for our <a href=\"https:\/\/twitch.tv\/surfaceduodev\">dual screen developer livestream<\/a> at 11am (Pacific time) each Friday \u2013 mark it in your calendar and check out the <a href=\"https:\/\/www.youtube.com\/channel\/UClGu9QLtPNz8OdddBfhZXPA\">archives on YouTube<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello game developers! We\u2019ve covered Jetpack Window Manager in the docs, and previously blogged about how to integrate the DisplayMask API into a Unity sample. In this post I\u2019ll describe how to extend a Unity project to integrate native Android code and configuration to include the Jetpack Window Manager package and provide dual-screen and foldable [&hellip;]<\/p>\n","protected":false},"author":570,"featured_media":1871,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[31,46,338],"class_list":["post-1862","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-dual-screen-development","tag-surface-duo","tag-unity"],"acf":[],"blog_post_summary":"<p>Hello game developers! We\u2019ve covered Jetpack Window Manager in the docs, and previously blogged about how to integrate the DisplayMask API into a Unity sample. In this post I\u2019ll describe how to extend a Unity project to integrate native Android code and configuration to include the Jetpack Window Manager package and provide dual-screen and foldable [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/users\/570"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=1862"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/1862\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/1871"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=1862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=1862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=1862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}