分类目录归档:游戏

游戏栏目将记录本人在学习或开发中得到的知识,并有部分的教程或文档翻译,共同学习,共同进步。

微信小游戏开发笔记(一):基本了解及引擎选择

做任何开发,最重要的起点就是:通读官方文档!

该系列文章是开发微信小游戏时遇到问题的总结,是笔记,非教程。如有BUG,请指正。

Adpter

小游戏的运行环境在 iOS 上是 JavaScriptCore,在 Android 上是 V8,都是没有 BOM 和 DOM 的运行环境,没有全局的 document 和 window 对象。因此当你希望使用 DOM API 来创建 Canvas 和 Image 等元素的时候,会引发错误。

在微信小游戏里面,如果使用第三方库,Adapter是一个非常重要的东西。微信在文档中也有提供源码,可以自行进行修改。尝试下来,基本每款引擎都需要进行适配,包括尝试的一个物理引擎Ammo.js,里面使用了print,所以也需要适配。目前唯一遇到的不需要适配的库就是Oimo.js这个物理引擎了。

适配工作也比较简单,很多时候都是一些不需要写太多代码的修改。例如 XMLHttpRequestaddEventListener 方法,只需要加入如下代码就可以了:

{
    key: 'addEventListener',
    value: function addEventListener(name, callback) {
        this['on' + name] = callback;
    }
},
{
    key: 'removeEventListener',
    value: function removeEventListener(name) {
        this['on' + name] = null;
    }
}

全局对象 GameGlobal

在微信小游戏里,因为没有BOMDOM,所以是没有window的,但Adpater中模拟了window。微信自己提供了一个 GameGlobal 全局对象,需要放入全局的东西都可以加到这个里面。

其他不同

微信实现了自己的音频播放、文件系统、Worker。

引擎选择

2D

做2D游戏其实没有太大的问题,白鹭EgretLayaAir(LayaBox)、Cocos都可以,我尝试过Phaser3版本,发现需要改的地方有点多,就没再尝试了。国内2D引擎已经对微信小游戏做了适配,都有自己的Adapter,基本不会遇到太多问题。

在开放域中使用LayaAir制作UI时,发现了一个坑,发布微信小游戏时,LayaAir不会编译代码,而是直接使用已编译的进行生成项目代码,这个问题之前一直没有注意过。

3D,最终选择:Three.js

3D游戏引擎(框架)也有很多,除国内的LayaAirEgret,国外的有 Three.jsBabylon.jsBabylon.js可以用Unity导出场景,很是方便,物理引擎也很方便的可以使用,在电脑和安卓下调试通过,但iOS下似乎shader有问题,所以没有继续研究。

Three.js是现在最火的3D框架之一,跳一跳也是使用这款引擎开发的,而且搭配物理引擎也比较方便,虽然不像Babylon.js导出就能用,但代码量也不多。

之前3D项目使用LayaAir开发,但后来发现竟然没有内置3D物理引擎,而且与其他物理引擎结合困难,就更换了Three.js

3D物理引擎,最终选择:Oimo.js

3D物理引擎有尝试三款,Ammo.jsCannon.jsOimo.js 。最开始使用 Ammo.js 进行测试,使用的 Physijs 插件,代码写完后能够正常运行,但2个box的物理就已经卡到15帧了。

由于 Cannon.js 2年没更新,而且没有找到可用文档,所以也没使用。

Oimo.js 是在下载 Babylon.js时看到的,使用后发现效果很不错,100个盒子没有使用worker也能保持60帧,而且不需要修改任何代码直接可用,所以最终选择了这款物理引擎。

其他

做微信小游戏开发很重要的一点是,要知道哪些东西在微信小游戏里面可用,哪些不可用。

Unity与iOS交互(四):使用XUPorter在构建XCode工程时自动添加Framework、编辑Info.plist、OC代码等

开发环境:XCode 9.2 , Unity 2017.1.3,XUPorter 2018.02.24

XUPorter是一个可以帮助你在导出XCode工程时,自动添加Framework、自动编辑Info.plist、编辑OC代码的工具,建议先阅读XUPorter作者对该项目的简介。这是一个开源项目,目前最后一次修改是在2016年4月6日,英文文档已更新,但是雨松MOMO的文章和作者的介绍都已经过时,有些方法已被修改,这篇文章主要介绍该项目目前版本该如何使用。

该项目Github地址:https://github.com/onevcat/XUPorter

安装(放入工程中)

首先下载该项目,并放到Unity工程的Editor文件夹中,安装完成了

目录结构

XUPorter项目结构

XUPorter项目结构

projmods使用

.projmods文件你可以理解为一个SDK的配置的文件,我们每需要接一个SDK,就可以创建一个该类型的文件,当然你也可以全部放在一个文件中,但推荐分开存放,防止混淆。

我们先看之前接入微信支付时的配置文件,该配置文件内容是JSON格式:

微信支付projmods配置文件

微信支付projmods配置文件

group:组名称,可以简单理解为该配置的名称

libs:需要加入XCode工程的dylib文件,这里我全部放入了frameworks里,该字段并没有放入内容

frameworks:需要加入工程的各种Framework,这里是系统的Framework,并不是第三方Framework

headerpaths:需要加入搜索的头文件路径

files:需要加入到工程中的文件名,例如第三方Framework是一个当前配置文件所在目录的相对地址,不支持通配符

folders:需要加入到工程中的文件夹名,是一个当前配置文件所在目录的相对地址,不支持通配符

excludes:排除的文件类型,支持正则表达式

compiler_flags:需要加入的编译标签

linker_flags:需要加入的链接标签,微信SDK需要加入-Objc-all_load两个,其他SDK也会有类似要求

plist:需要修改的Info.plist的内容,这个功能是之后的贡献者提交的,所以在中文介绍中并没有提到,在Github上的版本中,只支持urltype的操作。因为微信支付SDK需要添加LSApplicationQueriesSchemes,所以我通过修改代码,支持了这个字段,但因为并不是通用解决办法,所以没有提交 pull request

当了解了上面的这些内容后,接入SDK也就非常简单了,每次 不可Append 构建后不再需要修改这些内容了。因为可以直接扩展UnityAppController,所以我们不再需要通过XUPorter来修改UnityAppController.mm的代码。

另外,修改plist文件的方法也不存在了,如果需要的话你可能需要自行修改代码来实现。上面修改代码支持修改plist的LSApplicationQueriesSchemes的代码为XCPlist.cs文件中AddPlistItems函数,代码如下:

修改XCPlist的AddPlistItems函数

修改XCPlist的AddPlistItems函数

某些情况下,我们可能需要修改其他文件,例如接入极光推送时,需要修改 Classes/Preprocessor.h 里的 UNITY_USES_REMOTE_NOTIFICATIONS 0来使程序支持极光推送,我们可以通过如下代码来修改:

修改Preprocessor.h文件

修改Preprocessor.h文件

以上就是目前使用到的XUPorter功能,在我接入微信支付SDK和极光推送时,通过上面介绍到的功能已经可以完成全部的修改了,如果有遗漏,欢迎反馈。

Unity与iOS交互(三):扩展UnityAppController来接入SDK

开发环境:XCode 9.2 , Unity 2017.1.3

在接入很多SDK时,都会被要求在 UnityAppController 中加入代码,而如果每次都在构建 XCode 工程后再修改的话,会是一件很麻烦的事情。Unity给我们提供了扩展UnityAppController的方法,我们可以通过继承UnityAppController来实现自己的AppController,并放入Unity工程的 Assets / Plugins / iOS 文件夹中,这样每次构建时,都会被自动加入XCode工程中。

首先我们来写一个AppController,我推荐在XCode中编写代码,完成后放入Unity工程中。因为在XCode中有代码提示、代码检查,可以避免问题无法被发现。

在构建后的XCode工程中新建一个 MyAppController.m 文件,这里可以不需要新建 .h 头文件,直接在 .m 中定义:

@interface MyAppController : UnityAppController<WXApiDelegate>
@end

我们只需要继承 UnityAppController 即可, <WXApiDelegate> 是我们接入微信支付SDK时添加的,如果某些SDK要求加入协议,都可以在这里加入,例如 <UIApplicationDelegate,WXApiDelegate> 使用逗号分割。

之后我们就可以加入SDK要求的代码,一般的SDK都会要求在 didFinishLaunchingWithOptions 中(这只是OC中方法签名的一部分,这并不是一个方法,我们只是通过这个字符串来查找方法位置,如果不理解建议学习OC基础教程)初始化SDK,我们可以直接重写 UnityAppController 中定义过的这个方法,加入SDK的代码,例如:

扩展并重写UnityAppController的方法

扩展并重写UnityAppController的方法

OC中的成员方法是需要放在 @implementation MyAppController 中的,很多SDK要求的代码,例如回调函数等,都可以放在这里。

将代码全部编写完成后,我们需要在构建的XCode工程中,默认使用此文件为程序入口,Unity也给我们提供了相应的方法:

IMPL_APP_CONTROLLER_SUBCLASS(MyAppController)

我们可以直接使用这个宏来完成构建时自动修改入口,参数为你编写的类,注意这里并不是字符串。

一切完成之后,你就可以将文件放入Unity工程的 Assets / Plugins / iOS 文件夹中了,构建后会自动生成到XCode工程中并设置为入口,这样就避免了我们在每次构建后手动修改UnityAppController中的代码,接多个SDK时更加方便。

同样,如果你对这篇文章中的部分内容不懂的话,建议阅读基本的OC开发教程。

Unity与iOS交互(二):接入微信支付SDK

开发环境:XCode 9.2 , Unity 2017.1.3

在开发项目时需要接入的SDK中,微信的SDK是最……坑……的,微信的SDK包括微信分享、微信登录、微信支付。接入的方式是一样的,坑的点在于,微信开放平台官方文档的极其不完善。其他SDK例如ShareSDK或极光推送等,都有专门的UnityPackage包,而且有文档教程,虽然也有些坑的地方,但还是可以很容易的接入。但微信的SDK只有原生接入方式,而且文档中的XCode版本是很古老的,这个也不是大问题,大问题是他的示例代码也是很古老且不完整的。

这篇文章就介绍如何接入微信支付SDK(微信分享SDK方式相同),你可以在微信开放平台的资源中心中找到SDK的文档及下载,阅读“iOS接入指南”来开始SDK的接入,从手动接入部分开始。

你可以将SDK的文件放入到Unity工程的 Assets / Plugins / iOS 文件夹中,到构建 XCode 工程后,会直接存放于 XCode 工程的 Libraries 文件夹中。或者,你可以构建 XCode 工程后,再将 SDK 文件导入,直接将三个文件 libWeChatSDK.a,WXApi.h,WXApiObject.h 拖入到 XCode 工程中,并勾选 Copy items if needed :

将SDK加入到XCode工程中

将SDK加入到XCode工程中

之后,我们进行将需要的 Frameworks 手动加入(自动加入请阅读后续的XUPorter教程)等步骤,这些步骤都可以按照官方文档中的3.2.3到3.2.6直接进行,为了防止官方文档更新后导致步骤对不上号,我这里简单列出这些步骤:

3.2.3:将Framework加入到工程中,在 XCode 工程的 Build Phases -> Link Binary With Libraries 中点击下面的 + 号添加:

添加Framework到XCode工程中

添加Framework到XCode工程中

3.2.4:在你的工程文件中选择Build Setting,在”Other Linker Flags”中加入”-Objc -all_load”,在Search Paths中添加 libWeChatSDK.a ,WXApi.h,WXApiObject.h

3.2.5:在XCode中,选择你的工程设置项,选中 TARGETS 一栏,在 info 标签栏的 URL type 添加 URL scheme 为你所注册的应用程序id

3.2.6:在XCode中,选择你的工程设置项,选中 TARGETS 一栏,在 info 标签栏的 LSApplicationQueriesSchemes 添加 weixin

接下来是3.2.7:在你需要使 用微信终端API的文件中import WXApi.h 头文件,并增加 WXApiDelegate 协议,这个操作我们在 UnityAppController.h 中完成(我们同样可以扩展UnityAppController.mm来进行这个操作,避免每次打包后重新修改UnityAppController,参考后续的扩展UnityAppController文章),查看下图中画线的地方:

UnityAppController.h中加入WXApiDelegate协议

UnityAppController.h中加入WXApiDelegate协议

接下来的在代码中使用工具包这一步的4.1我们在 UnityAppController.mm 中完成,首先找到文件中 didFinishLaunchingWithOptions 函数的位置,加入 [WXApi registerApp:@"wxa72a15850b99c773"];代码。

4.2中重写AppDelegate的handleOpenURL和openURL方法,Unity生成的代码中并不包含这两个函数,按文档中的代码直接增加即可。

4.3中实现WXApiDelegate协议的两个方法 onReq 和 sendReq 。这两个方法可以参考官方支付demo的代码,这里提供最简单的实现:

实现WXApiDelegate协议的两个方法 onReq 和 sendReq

实现WXApiDelegate协议的两个方法 onReq 和 sendReq

至此,XCode中 微信支付SDK 的接入就全部完成了,而且这里我们已经在 XCode 中使用 UnitySendMessage 向 Unity 端发送支付结果,Unity中接收后根据结果进行处理即可。但我们还没有完成调用支付的功能,我们新建一个 .h 和 .m 文件,文件名随意,我这里使用 NativeBridge 来命名,在里面实现原生的调用微信支付的代码。这两个文件我们可以在构建后 XCode 中引入,也可以直接存放于 Unity 项目的 Assets / Plugins / iOS 中,构建时会自动存放于 XCode 工程的 Libraries 文件夹中。

在 NativeBridge.h 中写入代码:

NativeBridge.h中的代码

NativeBridge.h中的代码

在 NativeBridge.m 中,写入代码:

NativeBridge.m中的代码

NativeBridge.m中的代码

_WXPay是我们定义的调用微信支付的函数,参数全部使用 char *name 来传入,使用 [NSString stringWithUTF8String:name] 来转换为 NSString ,这里需要注意两点

  1. request.openID 必须赋值,这一条在官方文档中没有说明,是在百度其他教程时发现的,android端也是如此。另外iOS端没有appid,只有android端有。
  2. timeStamp 必须是整形且为10位,精度是秒,上面代码中有转换方法。

如果调用时提示签名错误,那么很有可能是上面2点造成的。

调用的函数已经写好了,现在我们需要在 Unity 里面进行调用了,先引入原生代码中定义的调用函数:

引入原生代码中的调用函数

引入原生代码中的调用函数

之后在需要的地方传入参数并进行调用,参数应由服务器返回:

Unity中调起微信支付

Unity中调起微信支付

在微信支付处理完成或取消之后,会调用之前在 UnityAppController.mm 中定义的回调函数 OnResp ,再使用 UnitySendMessage 向 Unity 发送支付结果,UnitySendMessage 的使用方式可以参考Unity官方文档。

到这里,所有的微信支付的步骤就全部完成了,如有遗漏,欢迎反馈。

如果在 XCode 中添加的 OC 代码看不懂的话,强烈建议先阅读 OC 的基本教程。

Unity与iOS交互(一):构建XCode工程

开发环境:XCode 9.2 , Unity 2017.1.3

在使用Unity开发游戏时,我们经常会被要求接入各种SDK,例如微信支付、微信分享、推送等。而大部分Unity开发人员并没有iOS相关开发经验,所以接原生SDK一直以来都是一件很头疼的事情,不过当我查阅各种文档,看了各种教程之后,发现接iOS的SDK还是比较简单的一件事情。

所以这个系列文章将会介绍我接入SDK过程中学到的知识、要点及过程。

构建过程

在Unity官方文档中有专门的iOS平台开发文档,阅读这些文档是非常有帮助的。这一篇我将先介绍iOS平台的构建及生成的XCode工程结构。这两点都是Unity官方文档中的内容。

在点击Build构建iOS工程时,如果不是首次构建,则会弹出一个警告:

iOS构建警告

iOS构建警告

当我们不勾选Enable replacesshi时,Replace按钮是不可用的。官方文档中也有介绍ReplaceAppend的区别

  • replace – 所有目标文件夹的文件将被移除,并且生成新的内容
  • append – “Data”,”Libraries”和项目根目录将被清理并放入新生成的文件。XCode项目文件将会根据Unity中的更改被更新。XCode工程中的”Classes”文件夹是存放本机代码的安全场所,但建议定期进行备份。追加模式仅支持使用相同Unity iOS版本生成的现有XCode项目。

所以在我们构建XCode工程后,我们所有的Info.plist、Build Settings等的修改,在Append模式下都不会被覆盖,在后续接SDK时,也会少很多麻烦。但如果你使用了不同版本的Unity来构建项目,那么构建时将只能Replace,之后所有的修改需要重新再来一遍,如果SDK多或者修改操作多的话,这会是一件很麻烦的事情。不过,我们还有别的办法来解决这个麻烦:使用XUPorter。XUPorter的使用会在后面的文章中介绍。

工程结构

构建后的XCode工程应该是下面这样的:

Unity构建后的XCode工程结构

Unity构建后的XCode工程结构

对我们来讲,”Classes”、”Libraries”文件夹和Info.plist文件是最常用到的。其余目录及文件可以参考Unity官方文档中XCode项目结构的介绍

在”Classes”文件夹中,有一个名为UnityAppController.mm的文件,这个文件是main.mm中设置的程序的入口。通常接入微信SDK或极光推送时,都需要在这个文件中加入代码,初始化SDK等。而官方文档中指出,我们可以扩展这个类,在下一篇文档中我会介绍扩展UnityAppController.mm的方法。

“Libraries”文件夹中,存放着我们在Unity中放入的原生代码,当在Unity中你将原生代码放入Plugins/iOS文件夹中时,这些代码会被拷贝到”Libraries”文件夹中。而在Plugins/iOS中放入原生代码文件,也是Unity官方文档中介绍的iOS插件使用方法。

Info.plist中存放的项目配置,接入SDK时也会需要修改的,可以按照SDK的文档来修改此文件,也可以阅读之后的XUPorter的使用教程来在Unity的代码中修改此文件。

通过这篇文章我们可以看到,Unity官方文档中有各种你需要的知识,不过遗憾的是文档没有中文化,而且各种知识在不同的文章里,很容易忽略,这个专题的目的,也就是为了帮助大家使用这些只是来更加容易的接入SDK。