* * *
WINDOWS 10 特殊问题 (2015)
# 游戏开发 - 使用 Unity 为通用 Windows 平台编写游戏
作者 [Jaime Rodriguez](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=Jaime+Rodriguez)、[Brian Peek](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=Brian+Peek) | Windows 2015
Windows 10 为游戏开发者和玩家提供了许多新功能。借助通用 Windows 平台 (UWP),开发者可以使用一段基本代码来定位 Windows 10 平板电脑和 PC、Windows 10 移动设备(即手机)、Xbox One 和 HoloLens。此外,我们还已将 Windows 应用商店融合为一,且 Microsoft 已在 Windows 10 中引入了 Xbox Live 服务以及 Xbox 应用,以提高玩家跨所有 Windows 设备系列的参与度。
对于游戏开发者,Unity 是最常用的游戏开发引擎之一。它支持 21 个平台,提供了目前所有可用中间件的最佳跨平台开发支持。结合 C# 脚本支持,它的编辑器可以实现极高效率的游戏开发环境。资产应用商店、Unity 社区以及 Unity 不断增加的广告、互动和分析功能让沉浸式游戏的开发变得空前容易。
一切进展得都十分顺利,我们必须写下来! 本文介绍了让 Unity 游戏在 Windows 10 上完美运行您所需知道的全部详情。这并非是对 Unity 或 UWP 应用的简单介绍。要理解本文的内容,您需要熟悉这两个主题。相反,我们将重点介绍 Windows 10 的变化,以及创建精彩的通用 Windows 游戏 (UWG) 的必知提示和技巧。为此,我们将以实战方式进行介绍,逐个讲解我们为了优化 Chomp 这一示例游戏(见图 1)以适应 Windows 10 所做的一些更改。
![](https://box.kancloud.cn/2016-01-08_568f407191768.png)
图 1:Chomp
Chomp 最初是一款使用 Unity 进行编写的 Windows 8.1 游戏。从图 1 中的屏幕截图可以看出,它是一款相当小型的迷宫游戏,类似于 Pac-Man。此示例旨在为开发者提供指导,向他们展示如何使用 Unity 编写游戏,因此简明易懂就很关键。不过,随着 Windows 10 的推出以及 Unity 支持新的操作系统,我们不得不对 Chomp 进行更新。有关 Chomp 的源代码,请访问 [bit.ly/UnityChomp](http://bit.ly/UnityChomp)。请下载源代码,并在我们的演示过程中继续参考。
若要获取游戏的 UWP 版本,我们只需使用 Unity 中的 Windows 10 配置文件,即可导出游戏,但这样做无法生成针对 Windows 10 运行方式优化的应用程序。它无法在全屏窗口模式下运行,也无法供用户触控等。那么,接下来就看看我们是如何将这款游戏从 Windows 8.1 迁移到 Windows 10 的。
## 入门(前提条件)
UWP 应用(和 UWG)要求您使用 Windows 10 和 Visual Studio 2015 进行开发和测试。所有 Visual Studio 2015 版本都会为您提供创建游戏所需的一切功能,包括免费的 Visual Studio Community 2015!
在 Unity 方面,您需要获得 Unity 5.2.1p2 或更高版本。Unity 5.2 现在安装有 Visual Studio Community 2015 和 Visual Studio 2015 Tools for Unity (VSTU)。因此,在实践中,您只需安装 Unity,并在安装过程中选择正确的选项即可入门。有关详情,请参阅图 2。
![](https://box.kancloud.cn/2016-01-08_568f4071dde43.png)
图 2:只需安装 Unity 并选择正确的选项即可入门
注意: 对于使用 Mac 的开发者,新的备选方法是对 Unity 项目使用 Visual Studio Code 编辑器。有关此选项的更多详细信息,请访问 [bit.ly/UnityVSCode](http://bit.ly/UnityVSCode)。
## 针对 Windows 10 构建
针对 Windows 10 构建的过程与您熟悉的过程完全相同。新增的 SDK 可以将 UWP 应用定位到 Windows 应用商店平台(见图 3)下,从而将游戏导出为 UWP 应用。
![](https://box.kancloud.cn/2016-01-08_568f407210788.png)
图 3:在 Unity 中定位 Windows 10
对于 Windows 10 和 UWP 开发,导出期间后台发生了下面一些重要变化:
* 您可以使用新增的 UNITY_UWP 和 UNITY_WSA_10_0 预处理器,调整游戏的 UWP 逻辑和体验。
* Unity 5.2 现在包含全新的简化 WinRTLegacy DLL,其中所含的类型比旧版更少。有了 Windows 10,Microsoft 已将多个类型重新引入 .NET Core 配置文件,导致 WinRTLegacy 中包含的某些解决方法不再是必需方法。
* Unity 5.2 使用的是 Unity 5 中引入的全新插件模型。这极大地简化了参与工作流的插件,本文后面对此进行了介绍。
* Unity 5.2 包括对 DirectX 12 的实验支持(Windows 10 自带)。若要尝试实验支持,请打开 Unity 中的“播放器设置”,取消选中“自动图形 API”选项,然后手动添加 Direct3D12 支持。
## 新项目模板
Unity 构建过程现在会生成与 UWP 兼容的 Visual Studio 2015 项目。您可能已经知道,这一全新的项目系统具有一些显著变化。
例如,每个 UWP 应用现在都自带各自的 .NET Core 副本,因此您始终可以获取用来测试的 .NET 版本。为了适应此变化,Unity 会生成相应的 project.json 文件。此文件会通过 NuGet 来提取合适的 .NET 部分。
此外,UWP 应用使用的是 .NET 本机,这样可以在将应用下载到客户计算机之前生成优化的本机计算机代码,并缩短启动时间,同时降低游戏的耗电量。虽然这些优化的影响因游戏的复杂程度而异,但是绝对不会影响性能的。唯一需要注意的是,.NET 本机确实会(显著)延长 Visual Studio 内的编译时。对于常规应用,Visual Studio 使用 .NET 本机仅编译项目的“发布”配置。对于 Unity 生成的项目文件,实现的是类似方法,仅“主机”配置是使用 .NET 本机进行编译。如果您不熟悉 Unity 中的配置目标,请参阅下文,配置目标分为三种:
* 调试配置是不含优化的完整调试项目。
* 发布配置是含优化的编译项目,但也包含探查器支持。
* 主机配置是您应提交给应用商店的配置。由于不含调试代码,因此所有优化都会启用,并且分析支持会遭删除。
您绝对应该在开发周期的早期使用 .NET 本机进行编译和测试。Unity 可以编辑许多高级中间语言 (IL)。因此,如果有可以充分利用 .NET 本机的应用类型,那一定就是 Unity 游戏。为了确保达到预期效果,请在 .NET 本机编译期间注意输出窗口中的警告。
虽然之前提到的区别在运行时非常显著,但新的 Unity 模板让这些变化对开发者一目了然,因此我们要重点介绍的是如何调整和优化 Windows 10 游戏。
## 调整和优化 Windows 10 游戏
跨多个外形规格的一段基本代码是 UWP 的重要特性,但提到游戏,可能仍有必要针对特定的外形规格进行一些调整和优化。最常见的调整和优化包括:输入机制(如触控、键盘、鼠标和游戏板);窗口重设大小;优化资源和资产;以及对每个特定外形规格实现本机平台集成(如动态磁贴、通知或 Cortana)。我们将探讨与 UWG 相关的调整和优化。
窗口化:通用 Windows 应用现在托管在可重设大小的窗口中,而不是像在 Windows 8 和 8.1 中一样以全屏模式运行。因此,可以考虑对游戏和应用程序使用窗口化。其中大多数区别对 Unity 开发者来说都一目了然,因为 Screen.height 和 Screen.width 属性仍可报告本机(像素)尺寸的可用空间。
Windows 10 还新增了用于进入和退出全屏的 API,设置 Screen.fullScreen 属性后可通过 Unity 屏幕类来公开这些 API。窗口化的最佳做法是实现标准键加速器,以进入和退出全屏。虽然最佳做法在发布服务器中的差异很大,但进入和退出全屏的常用加速器是 F11 或 Alt+Enter。对于 Chomp,我们想为玩家提供此选项以便他们可以全屏玩游戏,因此我们通过以下方式切换全屏模式:
~~~
if (Input.GetKeyUp (KeyCode.F11))
{
Screen.fullScreen = !Screen.fullScreen;
}
if (Input.GetKeyUp (KeyCode.F11))
{
Screen.fullScreen = !Screen.fullScreen;
}
~~~
配备多窗口桌面需要对 Windows 10 游戏进行另一项更改: 必须处理焦点变化。在多窗口桌面中,如果您的游戏窗口没有焦点,那么您应暂停游戏和音乐,因为用户可能在与其他窗口进行交互。Unity 使用在其他平台中公开的同一 API 对此交互进行抽象:OnApplicationPause 方法。当焦点变化时,系统会对所有有效的 MonoBehaviours 调用此方法。我们在 Chomp 中对此进行处理,如图 4 所示。
图 4:当焦点变化时暂停游戏
~~~
public void OnApplicationPause(bool pause)
{
FocusChanged(!pause);
}
public void FocusChanged(bool isFocused)
{
if (isFocused)
musicSource.UnPause();
else
{
musicSource.Pause();
GameState.Instance.SetState(GameState.GameStatus.Paused);
}
}
~~~
请注意以下不对称性: 当游戏失去焦点时,游戏和音频会暂停,但在游戏获得焦点时,我们只会取消暂停音频。这是因为,当游戏暂停时,我们还会在游戏本身中显示一个暂停的对话框;在焦点恢复时,游戏会等待用户确认是否要继续玩游戏。此对话框用于将游戏状态从“暂停”设置回“正在运行”。
在执行这两项更改后,我们可以正确处理进入/退出全屏,以及在窗口失去焦点时暂停游戏。
输入:旧版 Unity 非常支持 Windows 游戏输入,这一点在 Windows 10 中保持不变。Unity 中的输入类和输入管理器仍可方便地对鼠标、触控和游戏板进行抽象。
关于输入最重要的一点是,确保实现尽可能多对游戏有意义的输入机制。对于 Chomp,我们希望支持键盘、游戏板和触控。请注意,由于 UWG 可以在任意位置上运行,因此尽可能为玩家提供最佳输入/游戏体验。有关输入的最常见问题是,如何检测您是否需要在使用触控设备(如手机)时显示触控控件(如虚拟游戏杆或方向键)。
确定是否应显示触控游戏杆的一种方法是,确定游戏是否是在手机上运行。如果是,可以默认显示并启用游戏杆。若要确定游戏是否是在特定平台(如手机或 Xbox)上运行,您可以检查是否实现了相应的协定。下面介绍了 Chomp 如何检测自身是否是在 Windows 10 移动版上运行:
~~~
public static bool IsWindowsMobile
{
get
{
#if UNITY_WSA_10_0 && NETFX_CORE
return Windows.Foundation.Metadata.ApiInformation.
IsApiContractPresent ("Windows.Phone.PhoneContract", 1);
#else
return false;
#endif
}
}
~~~
请注意,在此代码中,我们使用 UNITY_WSA_10_0 预处理器来确定我们是否针对 Windows 10 进行编译。如果未执行此检查,则代码将无法在非 Windows 10 版本上进行编译。
虽然始终显示虚拟游戏杆是一种方法,但最好只当用户在设备上实际使用的是触控时才显示游戏杆。Windows 10 新增的 API 可以确定用户是在平板电脑模式(触控)下还是在传统桌面模式(鼠标/键盘)下运行 Windows 10: Windows.UI.ViewManagement.UIViewSettings.UserInteractionMode。此 API 必须在 Windows UI 线程上运行,因此必须从 Unity 内部封送对 UI 线程的调用。我们已向 Chomp 添加了图 5 中的代码,以确定用户是否在使用触控与应用进行交互。
图 5:确定用户是否在使用触控的代码
~~~
public static bool IsWindows10UserInteractionModeTouch
{
get
{
bool isInTouchMode = false;
#if UNITY_WSA_10_0 && NETFX_CORE
UnityEngine.WSA.Application.InvokeOnUIThread(() =>
{
isInTouchMode =
UIViewSettings.GetForCurrentView().UserInteractionMode ==
UserInteractionMode.Touch;
}, true);
#endif
return isInTouchMode;
}
}
~~~
现在,我们已实现了这两种方法,可以更新 Chomp 以更为完善地估算游戏杆的显示时间了。如果游戏是在移动设备上运行,或用户交互模式是触控,则 UseJoystick 会返回 true,然后我们会显示游戏杆:
~~~
public static bool UseJoystick
{
get
{
return (IsWindowsMobile || IsWindows10UserInteractionModeTouch) ;
}
}
~~~
通过处理窗口化和输入,我们现在可以继续利用新本机 Windows API 来为游戏添加更多功能。
与 Windows 10 本机集成: 平台触发 - 从 Unity 游戏内与操作系统本机集成的处理方式与之前相同: 如果您要在 Unity 中使用 .NET Core 编译选项进行编译(使用 NETFX_CORE 预处理器),则可以内联本机代码,如前面的示例所示。
如果要添加的代码多于要内联的代码,或需要对行为进行抽象(跨平台),则您仍可以使用插件。对于 Windows 10,Microsoft 开发者体验游戏传播团队(我们属于这个团队)开放了多个新插件的源代码,以便您可以更轻松地与 Windows 10 集成。有关这些插件,请访问 [bit.ly/Win10UnityPlugins](http://bit.ly/Win10UnityPlugins)。目前,已共享以下插件:
* 应用商店: 适用于应用内购买的应用商店插件,支持应用模拟器、消费品、耐用品和收据。其中有您需要与 Windows 应用商店交易的任何内容。
* AzureMobile: Microsoft Azure 插件,可执行 Azure 存储空间的创建、读取、更新和删除 (CRUD) 基本操作。
* 核心: 提供与核心操作系统功能(如动态磁贴、本地通知、推送通知和 Cortana)的本机集成的“核心”插件。
* 广告: 封装新的 Windows 10 Microsoft 广告 SDK 的插件,现在支持视频插页式广告。
以前,Chomp 不含应用内购买,因此我们决定了使用应用商店插件向游戏添加应用内购买。现在,Chomp 支持购买消费品(增强程序)和耐用品(迷宫)。
使用这些插件的最简单方法是,从 GitHub 下载 Unity 包,然后使用 Unity 编辑器中的“资产 | 导入包 | 自定义包”将此包导入 Chomp。在您导入包后,Unity 的“插件”文件夹中包含正确的二进制文件。安装后,这些二进制文件位于“插件\WSA”目录中;Unity 需要在编辑器内使用占位符程序集(与 Microsoft .NET Framework 3.5 兼容),因此这些程序集也会纳入和复制到“插件”文件夹本身中。
在您导入包后,我们现在可以从 Chomp 内引用应用商店 API。我们先调用 Store.LoadListingInformation,提供在完成后立即运行的回叫方法,以获取可以购买的所有项目的列表。如果调用成功,则我们会循环访问返回的 ProductListing 项目,然后使用这些项目来填充 UI 中的价格,如图 6 所示。
图 6:列出可以进行应用内购买的项目
~~~
void Start()
{
Store.LoadListingInformation(OnListingInformationCompleted);
...
}
void OnListingInformationCompleted(
CallbackResponse<ListingInformation> response)
{
if (response.Status == CallbackStatus.Success)
{
ListingInformation result = response.Result;
PopulatePrices(result.ProductListings);
}
}
~~~
在用户选择了要购买的项目后,只需再添加几行代码即可执行交易。图 7 展示了我们添加用来购买耐用品(游戏的新迷宫)的代码。
图 7:执行应用内购买
~~~
public void OnDurablePurchase(GameObject buttonClicked)
{
string productId = GetProductId(buttonClicked.name);
if (!string.IsNullOrEmpty (productId))
{
Store.RequestProductPurchase(productId, (response) =>
{
if (response.Status == CallbackStatus.Success)
{
// response.Status just tells us if callback was successful.
// The CallbackResponse tells us the actual Status
// as returned from store.
// Check both.
if (response.Result.Status == ProductPurchaseStatus.Succeeded)
{
EnableLevels(productId);
return;
}
}
});
}
}
~~~
如您所见,使用这些新插件实现本机功能很简单。
## 提交至应用商店
提交至 Windows 应用商店不再是难事。您现在可以提交一个包含所有二进制文件的包,也可以为每个平台/体系结构都提交一个包(如果需要)。
如果您想拆分包或仅在特定平台上支持游戏,则可以手动编辑 package.appxmanifest 文件,并调整 TargetDeviceFamily 元素:
~~~
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.10240.0"
MaxVersionTested="10.0.10240.0" />
</Dependencies>
~~~
三种可能的设备系列:
* Windows.Universal: 方便您在满足硬件要求的所有位置上部署二进制文件。
* Windows.Mobile: 应该对进入 Windows 10 移动版 SKU(即 Windows Phone)的二进制文件使用,尽管将来可能有其他并非手机但运行此 SKU 的小型设备(六英寸或更小),因此请勿假设只有手机。
* Windows.Desktop: 应对只能在桌面设备和平板电脑上运行的游戏使用。
如果您想定位移动设备和桌面设备,而不是控制台或其他更高版本的 Windows 系列,则可以在清单中添加两个设备系列(替换相应的“x”和“y”)。
~~~
<Dependencies>
<TargetDeviceFamily Name="Windows.Mobile" MinVersion="10.0.x.0"
MaxVersionTested="10.0.y.0"/>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.x.0"
MaxVersionTested="10.0.y.0"/>
</Dependencies>
~~~
请注意,每个设备系列均可以有不同的 MinVersion 和 MaxVersion。将来会很方便,因为 Windows 10 移动版将自带版本号高于 Windows 10 的桌面版。不过,目前我们建议您保留默认版本 (10.0.10240.0)。
如我们之前在讨论 .NET 本机时所述,提交包时应务必提交主机配置。此外,我们还建议您添加完整的程序数据库 (PDB) 符号文件进行故障分析。新的应用商店不提供下载 cab 文件进行本地分析的选项。相反,您必须将 PDB 提交至 Windows 应用商店,然后应用商店会为您完成相关工作,同时提供故障的堆栈跟踪(见图 8)。
![](https://box.kancloud.cn/2016-01-08_568f407249ba8.png)
图 8:添加程序数据库符号文件
最后,当您通过开发者门户提交至 Windows 应用商店时,请务必选择正确的硬件配置。应用商店现在允许您指定硬件要求(如触控或键盘),以便游戏只在正确的设备上安装(见图 9)。
![](https://box.kancloud.cn/2016-01-08_568f4072723cf.png)
图 9:开发者门户中的硬件首选项
## 相关内容还有很多!
本文通过展示我们如何将简单的游戏移植到了 Windows 10 中以及如何添加了一些新功能,概述了面向 Unity 开发者的“新增功能探秘”。在有限的篇幅内,我们重点介绍了基础知识和游戏的“必做之事”,而不是向您展示 Windows 10 平台中的每个新功能。如果您想开发酷炫的沉浸式游戏,请考虑利用其他功能,如桌面上的新通知中心(旨在提高参与度)、Cortana、新动态磁贴模板和新 Xbox Live 服务 API。借助 Windows 10,Microsoft 正在逐步开放对 Xbox Live 服务的访问。您无需编写控制台游戏,只需有在 Windows 10 上运行的酷炫游戏,并希望利用排行榜、成就、跨设备运行等服务即可。若要申请访问权限,请注册 ID@Xbox 计划(网址为 [xbox.com/id](http://xbox.com/id))。
### Visual Studio 2015 Tools for Unity
对于第 5.2 版及更高版本,Unity 包括 Visual Studio 2015 Tools for Unity (VSTU),让 Visual Studio 成为 Windows 上 Unity 项目的新默认代码编辑器。此变化将带来改进后的 IntelliSense、编辑器中的语法着色,以及出色的 C# 调试程序。若要配置默认的脚本编辑器,请选择 Unity 编辑器中的“编辑 | 首选项”菜单选项。您可以选择 MonoDevelop(内置)、Visual Studio 2015、Visual Studio 2013,也可以选择浏览更多选项。
VSTU 也包括一些快捷方式,以便您可以更轻松地编写 Unity 代码。例如,如果您在 MonoBehaviour 类中右键单击,则上下文菜单会显示新的“实现 MonoBehaviours”条目,以便您可以快速地将 MonoBehaviour 方法签名插入类。
相同的上下文菜单中还包含“快速 MonoBehaviours”条目,以便您可以执行类似功能(但您会看到一个干扰程度较低的对话框,您可以在其中键入要搜索的方法名称),然后即可再次插入签名。以上两种方法均可通过快捷键加速器使用,以提高使用速度(Ctrl+Shift+M 和 Ctrl+Shift+Q)。
除了编辑器增强功能之外,使用 VSTU 时的最佳功能之一就是,简化了与 Unity 编辑器的调试程序集成。在 Visual Studio 中打开 Unity 项目时,您会自动看到“附加到 Unity”按钮(用于在标准调试工具栏进行调试)。图 A 展示了此按钮的位置。此按钮会自动查找 Unity 编辑器的进程并附加到其中。从此,您可以顺畅设置断点、分析变量值,并能执行其他所有大部分的 Visual Studio 预期操作。VSTU 甚至包括对中断异常的实验支持。有关 VSTU 2.0 功能的更多详细信息,请查看博客文章“Visual Studio Tools for Unity 2.0”([bit.ly/VSTUInfo](http://bit.ly/VSTUInfo))。
注意: 如果您定位的不是 Windows 10,也没有使用 Visual Studio 2013 ,则可通过可下载的包将此处所述的全部优势带给 Visual Studio 2013 社区版用户。您可以访问 [bit.ly/VSTU2013](http://bit.ly/VSTU2013),下载此扩展程序。
* * *
Jaime Rodriguez *是 Microsoft 开发者体验游戏传播团队的负责人。您可以通过以下方式与他联系:Twitter [@jaimerodriguez](https://twitter.com/@jaimerodriguez) 和博客 [jaimerodriguez.com](http://jaimerodriguez.com/)。*
Brian Peek *是 Microsoft 高级游戏开发者传播团队成员。他是一位资深玩家,自有记忆起他便在 Windows、控制台以及其他任何可以编程的平台上开发游戏。您可以在开发者会议的全国巡讲中看到他,也可以通过以下方式关注他:Twitter [@BrianPeek](https://twitter.com/@BrianPeek) 和博客 [brianpeek.com](http://brianpeek.com/)。*
- 介绍
- Microsoft .NET - .NET 和通用 Windows 平台开发
- 图形和动画 - Windows 组合支持 10 倍缩放
- 应用生命周期 - 通过后台任务和扩展执行使应用处于活动状态
- 通知 - Windows 10 中的自适应和交互式通知
- 应用集成 - 在 Windows 10 上链接和集成应用
- Visual Studio 工具 - NuGet 功能增强了 Windows 10 的开发功能
- UI 设计 - 通用 Windows 应用的响应式设计
- UI 设计 - 适用于 Windows 10 的自适应应用
- 数字墨迹 - Windows 10 中的墨迹交互
- 游戏开发 - 使用 Unity 为通用 Windows 平台编写游戏
- 结束语 - 欢迎使用 Windows 10 应用开发
- 编者寄语 - 从 3.0 开始的发展之路