如何作一个跨平台的游戏App?node
iOS和安卓系统上的应用程序,根据提供的内容不一样,按照开发方式和用户体验不一样,可区分为app和游戏;react
首先从开发方式不一样来讲明,app开发通常是用操做系统官方提供的开发套件来作对应的开发;android
这里的开发套件就系统不一样可作如下区别:ios
iOS: Xcode, Objective-Cgit
android: AndroidStudio, Java/Kotlingithub
游戏的开发方式就不少了,不过最终一步通常都是生成对应IDE的项目工程,而后在对应的项目工程上进行配置设置,签名配置等步骤,最后完成打包.ipa和.apk的打包; 在最后一步前开发方式就根据项目需求以及其余因素考量,可采起不一样的开发方案了; 以前有幸在作iOS的SDK开发,对接了上百款游戏,也算对游戏的开发环境有所了解了。react-native
2D游戏通常用: Cocos2dx, Cordova,Corona,Contruct2等,固然也能够用Unity来开发2D游戏;xcode
3D游戏通常用: Unity为主流;app
最后从用户体验不一样来讲明,框架
app在前几年时间里,界面通常要根据不一样系统来作开发,市面上看到的不少app的iOS版本和安卓版本有一些UI是长的不同的, 这里就致使用户体验不一致的问题,若是领导须要,可采起混合网页的方式,可是同时会带来体验不流畅的问题,这就要看沟通了,最终采起哪一种方式了。
通常状况下,市面上的应用程序要么是app要么是游戏类型,可是碰到一些需求,须要吸收app和游戏的特性,融合在一块儿,丰富应用程序的功能和体验,这时候咱们开发的应用程序,我一般称它为游戏app.
前段时间参与过一个项目,功能和体验就是这样的一个应用程序,我把用到的基本技术抽出来,整理代码出来一个小demo, 其它相似的游戏混合app均可以借鉴此思路进行开发; 这个小demo的效果以下所示:
iOS Android
demo说明:
演示场景最后一个画面是Unity的游戏场景,倒数第二个界面是React-Native界面,其它页面是原生界面;
相关开发环境说明:
Unity2018.3.11f1
AndroidStudio3.3.2 (gradle插件版本3.2.0,gradle版本4.10.1,buildToolsVersion 29.0.0-rc1)
ReactNative0.59.5
XCode10.2.1
demo效果参考步骤以下:
一. 建立ReactNative工程
参考文档https://facebook.github.io/react-native/docs/getting-started,逐步实现RN功能,下面截图就是我demo工程里建立的一个测试登陆界面:
二.Unity导出原生项目
这步网上有不少教程,参考就能够了,基本没什么特别须要注意的地方,主要是一些打包配置设置问题,在我demo工程里,因为我引入了ReactNative功能,我须要把导出的xcode工程和as工程放到指定的文件夹层次,我把导出的原生项目工程截图所示以下:
使用的Unity版本在iOS和安卓打包的时候,有一些区别;
iOS端: 打包生成Xcode工程,能够选择replace或者append, 建议用append方式,这样每次打包不影响原生工程的东西。
安卓端: 打包生成AS工程,会直接替换老的文件,建议用github Desktop进行代码文件管理,否则原生工程修改的相关配置一不当心就被覆盖了。
下面说一下Unity每次修改打包成Xcode工程和AS工程的时候,会改变哪些代码和哪些文件? 此类混合项目要清楚,否则在功能协做的时候,很容易发生混乱,代码相互覆盖等问题!
开发场景一: 每次修改Unity里的.scene里的场景数据,打包出来Xcode工程,截图所示文件夹内的代码文件会发生大幅度的修改
iOS
android
开发场景二: 脚本代码发生修改后,打包出来的文件,截图所示红框部分文件每次新打包都会改变,黄框部分文件是脚本代码发生修改后,打包出来发生修改的文件
iOS android
测试发现Unity打包出Xcode工程以及Unity里功能变动,打包出来的Xcode工程,涉及到文件和项目配置众多,以前网上看到的不少文章大都是把Unity打包出来的新文件和配置,手动在原生项目里进行修改和文件引用众 多工做,我我的操做很麻烦,也有不少问题,每次Unity端功能发生更新,代码和文件更新到原生项目就有点麻烦了,我这边的操做步骤是在Unity端打包出来的Xcode工程上进行原生模块功能添加,原生模块功能以动态 库.framework形式引入,彼此松耦合!
三.原生项目框架引入
这一步按照ReactNative官方文档https://facebook.github.io/react-native/docs/integration-with-existing-apps来就能够了,这里须要注意;
我在iOS端使用CocoaPods (建议最好用CocoaPods集成方式,跟以前的项目工程造成松耦合)方式的时候,有一些第三方React-Native库没有CocoaPods集成方式,这时候就须要查看源码来手动link和项目配置了,或者换第三方库,再或者本身写,本身写的话,可按照官方指引https://facebook.github.io/react-native/docs/native-modules-setup来;
下面分享一段我项目中使用的Podfile文件
# Uncomment the next line to define a global platform for your project # platform :ios, '9.0' target 'Unity-iPhone' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! # Pods for Unity-iPhone # 'node_modules'目录通常位于根目录中 # 可是若是你的结构不一样,那你就要根据实际路径修改下面的`:path` pod 'React', :path => '../node_modules/react-native', :subspecs => [ 'Core', 'CxxBridge', # 若是RN版本 >= 0.47则加入此行 'DevSupport', # 若是RN版本 >= 0.43,则须要加入此行才能开启开发者菜单 'RCTText', 'RCTNetwork', 'RCTWebSocket', # 调试功能须要此模块 'RCTAnimation', # FlatList和原生动画功能须要此模块 # 在这里继续添加你所须要的其余RN模块 'RCTImage', ] # 若是你的RN版本 >= 0.42.0,则加入下面这行 pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' # 若是RN版本 >= 0.45则加入下面三个第三方编译依赖 pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' # # CodePush plugin dependency # pod 'CodePush', :path => '../node_modules/react-native-code-push' # pod 'react-native-blur', :path => '../node_modules/react-native-blur' # pod 'react-native-fetch-blob',:path => '../node_modules/react-native-fetch-blob' # pod 'react-native-fast-image',:path => '../node_modules/react-native-fast-image' # pod 'react-native-orientation',:path => '../node_modules/react-native-orientation' # pod 'RNFS', :path => '../node_modules/react-native-fs' # pod 'RNSVG',:path => '../node_modules/react-native-svg' target 'Unity-iPhone Tests' do inherit! :search_paths # Pods for testing # pod 'react-native-blur', :path => '../node_modules/react-native-blur' end end
四. 功能整合
这里要以iOS和android两端作对应处理,区别有点大,因为iOS和安卓端都是我一我的弄,而我自己是iOS出身,对iOS端会更熟悉些,安卓端处理可能会不太专业,但也算初步实现了。
以iOS端为例:
前面的步骤能够算ReactNative功能跟Unity功能初步集成到一块儿了,接下来就要再加入iOS原生功能,最后再把ReactNative功能,Unity功能串接到一块儿了!
1. 加入iOS原生功能
demo里我是加入了两个导航页面,我是直接在Unity导出的Xcode工程上加入的,由于Unity导出Xcode工程是能够增量更新的,后续Unity测功能更新,从新打包也不会影响我旧有Xcode工程的代码。
2.引入ReactNative功能
在第一步里,咱们已经建立好ReactNative项目,也建立了一个登陆测试页面,在这一步里咱们须要导航到这个页面,这个页面咱们须要用一个原生视图控制器来承载,而后就是原生功能的简单导航了
-(UIViewController*) getRNDisplayVC { if(!self.rnVC) { NSURL* jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; jsCodeLocation=[[NSBundle mainBundle] URLForResource:@"/bundle/index" withExtension:@"jsbundle"]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"myApp" initialProperties:nil launchOptions:self.launchOptions]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.rnVC=rootViewController; } return self.rnVC; }
代码里我使用的是已经打包好的.jsbundle文件,下面给出打包命令,在ReactNative文件夹下建立bundle文件夹,而后在ReactNative项目根文件夹里打开终端命令,输入下面代码
react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ./bundle/index.jsbundle --assets-dest ./bundle
最后把bundle文件夹引入到项目工程里,使用视图控制器的导航相关代码,就已经完成原生页面向ReactNative页面导航了,而ReactNative页面向原生页面导航,实质就是ReactNative访问原生模块的问题了,参考官方指引 https://facebook.github.io/react-native/docs/native-modules-ios#content
3.Unity跟原生互调或者Unity跟ReactNative互调
本质就是Unity跟原生的通讯了,网上文章不少,这里就不阐述了。
demo的开发思路初步是这样,其中有一些步骤还不算完美,有作相似此类项目的同窗,能够一块儿讨论!