Unity 的大多数 API 和项目结构对于所有支持的平台都是相同的,在某些情况下,可以简单地重新构建项目来在不同设备上运行。但是,硬件和部署方法的根本区别意味着项目的某些部分需要进行更改才能在平台之间移植。以下是一些常见的跨平台问题的详细信息以及解决这些问题的建议。
平台之间不同行为的最明显的例子是硬件提供的输入方法。
Input.GetAxis 函数作为整合键盘和游戏手柄输入的方式,在桌面平台上非常方便。但是,此函数对依赖触摸屏输入的移动平台没有意义。同样,除了输入的文本之外,标准桌面键盘输入也不能很好地移植到移动设备上。如果打算将来移植到其他平台,那么为输入代码添加一个抽象层是值得的。举个简单的例子,如果要开发驾驶类游戏,那么您可以创建自己的输入类并将 Unity API 调用封装在您自己的函数中:
// 返回 -1.0 到+1.0 范围内的值 (== left .. right)。
function Steering() {
return Input.GetAxis("Horizontal");
}
// 返回 -1.0 到+1.0 范围内的值 (== accel .. brake)。
function Acceleration() {
return Input.GetAxis("Vertical");
}
var currentGear: int;
// 返回一个对应于所选设备的整数。
function Gears() {
if (Input.GetKeyDown("p"))
currentGear++;
else if (Input.GetKeyDown("l"))
currentGear--;
return currentGear;
}
将 API 调用封装在这样的类中的一个优点在于,它们都集中在单个源文件中,因此易于定位和替换。但是,更重要的思路在于,应该根据游戏中输入的逻辑含义来设计输入函数。这有助于将其余游戏代码与特定平台使用的特定输入方法隔离开来。例如,可以修改上面的 Gears 函数,以便实际输入来自移动设备屏幕上的触摸操作。使用整数表示所选设备的做法适用于所有平台,但将特定于平台的 API 调用与其余代码混合会产生问题。有时可能会发现使用平台相关的编译可以很方便地将输入函数的不同实现合并到同一源文件中,并避免手动交换。
根据设计,__Input.GetMouseButtonXXX__ 函数在移动设备上也能有相当合理的解释,即使在移动设备上没有实际“鼠标”。屏幕上的单次触摸报告为左键单击,只要手指触摸屏幕,__Input.mousePosition__ 属性就会给出触摸的位置。这意味着具有简单鼠标交互的游戏通常可以在桌面平台和移动平台之间透明地工作。但是,转换通常比这简单得多。桌面游戏可以使用多个鼠标按钮,而移动游戏可以一次检测屏幕上的多点触摸。
与 API 调用一样,可以通过使用逻辑值表示输入来部分管理问题(这些逻辑值随后由其余游戏代码使用)。例如,移动设备上实现缩放的捏合手势可以被桌面设备上的加/减键击取代;输入函数可以简单地返回一个指定缩放因子的浮点值。同样,可以在移动设备上使用双指点击操作来替代桌面设备上的右键单击操作。但是,如果输入设备的属性是游戏的组成部分,那么可能无法在不同的平台上重新构建它们。这可能意味着游戏根本无法移植,或者输入和/或游戏玩法需要进行全面修改。
这些输入来自手持设备的移动特性,因此在桌面设备上可能没有任何有意义的等价方式。但是,一些用例只镜像标准游戏控制方式,可以很容易地移植。例如,驾驶类游戏可以通过移动设备的倾斜(由加速度计确定)实现转向控制。在这种情况下,输入 API 调用通常很容易替换,因此加速计输入可以替换为键击等方式。但是,可能需要重新校准输入或甚至改变游戏的难度来顾及不同的输入方法。倾斜设备比按键更慢并在总体上更加费劲,还可能导致更难以将注意力集中在显示屏上。这可能造成在移动设备上更难以掌控游戏,因此可能适合减慢游戏速度或为每个关卡提供更多时间。这种情况下需要设计游戏代码,确保可以轻松调整这些因素。
移动设备显然具有比桌面设备更少的存储、内存和 CPU 性能,因此游戏可能由于其性能在低功耗硬件上处于不可接受的水平而难以移植。有些资源问题是可以管理的,但如果在桌面设备上将硬件的性能发挥到极致,那么这样的游戏可能不适合移植到移动平台。
目前,移动设备高度依赖于硬件对电影播放的支持。因此播放选项有限,显然不能提供 MovieTexture 资源在桌面平台上所提供的灵活性。虽然可以在移动设备上全屏播放电影,但是没有任何余地可以使用它们来对游戏中的对象进行纹理处理(例如,不可能在游戏中的电视屏幕上显示电影)。在可移植性方面,可以将电影用于介绍、过场动画、游戏说明和其他简单的演示。但是,如果电影需要在游戏世界中可见,那么应该考虑移动播放选项是否能满足要求。
视频、音频甚至纹理都可能占用大量存储空间,如果想要移植游戏,可能不得不注意这一点。存储空间(通常也对应于下载时间)在桌面设备上通常不是问题,但在移动设备上却并非如此。此外,移动平台应用商店通常会对提交的产品的最大大小施加限制。在游戏开发过程中,可能需要制定一些计划来解决这些问题。例如,可能需要为移动设备提供资源的简化版本来节省空间。另一种可能性是可能需要设计游戏,从而实现大型资源的按需下载,而不是将其作为应用程序初始下载的一部分。
从“死亡”对象回收未使用的内存由 Unity 自动进行处理,通常在桌面设备上不知不觉地发生。但是,移动设备上较低的内存和 CPU 性能意味着垃圾收集可能需要更加频繁,并且这些过程占用的时间可能会严重影响性能(导致游戏中出现不必要的暂停等)。即使游戏在可用内存中运行,仍可能需要优化代码来避免垃圾收集暂停。如需了解更多信息,请参阅内存管理页面。
在桌面设备上运行良好的游戏可能会因移动设备的帧率不佳而受到影响,因为移动 CPU 难以处理游戏的复杂性。因此,当项目移植到移动平台时,可能需要特别注意代码效率。本手册的此页面列出了许多提高效率的简单步骤。