Laya2.0.2【疯狂怪兽车】游戏制作经验记录

最近用Laya2.0.2制作了3D【疯狂怪兽车】的跑酷 + 射击弹幕类微信小游戏项目,在做的过程中躺了不少次坑,最终还是躺过了,在这里分享一下我的一些躺坑经验和解决方案,同时也顺便疯狂打个广告2333333。

疯狂怪兽车

游戏截图

Laya客户端

微信小游戏性能优化
  • 同屏物理组件个数超过10个性能会严重降低,测试3-5个没问题。如果是做飞行弹幕游戏类型的话,或许用距离 + 碰撞盒大小来判断是否击中,这种方案处理还比较理想;
  • 相同音效同时播放超过5个性能会降低,必须限制播放个数;
  • 粒子数量也要控制,同个粒子限制生成次数,间隔多久才能生成;
  • 美术处理的汽车模型,为了能做好动画将模型分成了若干部件,导致每台车的dc都有5个,同屏出现多台汽车,DC会爆炸。最后我废除了敌人汽车动画,并且偷偷用unity的MeshBaker合并了敌人汽车,将敌人汽车的DC降到只有1;
  • 美术提供的道路模型都是在unity里面用不同的物件摆出来的,个体都很分散,而且不利于合并,合并解决有两种方案:
    一种是用Laya自带的静态合并方法Laya.StaticBatchManager.combine(),不过要将物体勾选static选项。另外一种是用unity插件MeshBaker来进行合并。这两种方法都可以达到合并的效果,个人觉得直接用unity插件合并更爽;
  • 根据实际需求减少模型的层次结构,这样可以直接优化Laya的绘制Sprite次数,我最多放3层,之前用Laya2.0的时候,Laya引擎多加了一层root,其实我也不知道为啥,但是Laya2.0.2减少了这一层,确实对性能会好点;
  • 模型面数的控制,还是按照手游那套,由于后面同屏物体比较多,敌人汽车模型控制500-800三角面,主角的面数尽量1500-2000左右;其实感觉在微信上,同屏面数10W估计都能跑得起,虽然没测试过2333。
  • 部分粒子效果最好能转为序列帧动画来表现效果,并且注意序列帧的位图大小;
  • 子弹可以直接用面片和透贴来制作,控制同屏数量20个左右,应该都是没问题的;
物理系统(后面优化移除掉用物理检测了,只有主角车和boss车才有物理)
  • 移除正在运动的物理会报错,可以先暂停移除或者暴力判断Laya物理为空的出错代码(缺少截图);
粒子制作
  1. 需要遵循Laya的粒子规则来制作粒子


    粒子规则
  2. 注意Color over LifeTime的渐变色块不要超过4个,否则会有问题


    Color over LifeTime

插件导出

可使用unity2018.3.8.0f1, Laya2.0.2导出插件

导出管理
考虑到模型会有很多,我将要导出的资源分了多个场景来管理,这样的好处是可以减少导出时间并且能更好维护文件目录。
例如疯狂怪兽车中,我将角色汽车模型分到一个场景,道路一个场景,粒子场景,子弹效果场景,此时场景有4个可以分别导出管理lh模型,如下图

模型场景管理

导出参数如下,以汽车模型为例:
导出参数

最终导出到Laya客户端的效果:
image.png

LayaNative

突然收到要制作原生安卓包并对接渠道,顿时懵逼了的感觉,毕竟安卓没怎么写过,但有挑战才能有进步,还是硬着头皮上了。喵了一下Java的语法有点类似C#,突然心就安乐了。

音乐

  • 原生只支持ogg和wav格式;
  • 用Laya的SoundManager播放背景音乐会卡线程,需要等待3-4秒才能恢复;
  • PlayMusic() 后并马上设置MusicMuted为停止,实测音乐不会停止播放;
  • 如果先设置MusicMuted再PlayMusic(),音乐不执行播放;

原生和Laya2.0互相通讯

Laya的类必须要导出window静态类,并且要暴露静态方法给原生调用,如下JaveCallback.ts代码,必须要注意最后那个if语句,如果不写就会报undefine。

export default class JaveCallback {
    public static CallbackTest() {
        alert("Java 调用 Laya");
    }
}
if (Laya.Browser.window) {
    Laya.Browser.window.JaveCallback = JaveCallback;
}

仿效微信的onShow和onHide方法
游戏中有一个需求是当app进入后台或前台需要关闭或开启音效,如果直接执行回调onShow和onHide,是会报错的,因为此时游戏还没初始化完成,调用就会报undefine。
所以暂时想到了一个解决方案:Laya进入游戏后先通知原生初始化,然后原生记录初始化标记后再执行回调onShow和onHide函数,这样才能避免一开始就报错。具体代码如下:

Laya端的代码

export default class JaveCallback {
    private static readonly conchIOS: string = "Conch-ios";
    private static readonly conchAndroid: string = "Conch-android";
    private static os: string = "";
    private static bridge: Laya.IPlatformClass = null;

    public static onShow() {
        alert("Java 调用 Laya onShow()");
    }

    public static onHide() {
        alert("Java 调用 Laya onHide()");
    }
    //进入游戏后,执行init函数
    public static init(){
        if (Laya.Browser.window.conch) {
            this.os = conchConfig.getOS();
            if (this.os == JaveCallback.conchIOS) {
                this.bridge = Laya.PlatformClass.createClass("JSBridge");
                this.bridge.call("initGame:");
            }
            else if (this.os == JaveCallback.conchAndroid) {
                this.bridge = Laya.PlatformClass.createClass("demo.JSBridge");
                this.bridge.call("initGame");
            }
        }
    }
}
if (Laya.Browser.window) {
    Laya.Browser.window.JaveCallback = JaveCallback;
}

android studio端的代码
先找到Laya的JSBridge代码,增加一个Init属性,并增加一个initGame方法给Laya调用

public class JSBridge {
    public static Handler m_Handler = new Handler(Looper.getMainLooper());
    public static Activity mMainActivity = null;

    public static Boolean Init = false;
    public static void initGame(){
        Init = true;
    }
    //后面省略..........
    //一堆代码..........
    //后面省略..........
    //一堆代码..........
}

找到Laya的MainActivity代码,然后找到onPause和onResume方法.
在onPause方法除插入

 if(JSBridge.Init == true) {
   ConchJNI.RunJS("JaveCallback.onHide()");
 }

在onResume方法除插入

if(JSBridge.Init == true){
   ConchJNI.RunJS("JaveCallback.onShow()");
}

最终代码如下:

protected void onPause()
{
    super.onPause();
    if(isLoad){
        if(JSBridge.Init == true) {
           ConchJNI.RunJS("JaveCallback.onHide()");
        }
        mPlugin.game_plugin_onPause();
    }
}
protected void onResume()
{
    super.onResume();
    if(isLoad){
       mPlugin.game_plugin_onResume();
       if(JSBridge.Init == true){
           ConchJNI.RunJS("JaveCallback.onShow()");
       }
    }
}

Laya2.0打安卓原生包
按文档处理即可正常发包

Laya1.0打包安卓后gradle报错
需要修改Gradle Script里面的build.gradle,并将下面两行代码增加到里面

 google()
 jcenter()
buildscript {
    repositories {
        mavenLocal()
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
    }
}

然后修改 compileSdkVersion 26targetSdkVersion 26,最后升级一下SDK即发布APK包

遗留问题

  1. 发热问题
  2. 苹果打包
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容

  • 一:什么是协同程序?答:在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行。换句话说,开启协程就是开启一个...
    CrixalisAs阅读 2,062评论 1 7
  • 转自:https://blog.csdn.net/dingxiaowei2013/article/details/...
    豆铮阅读 1,257评论 0 2
  • 今天是来上海第四天,也是行程的最后一天! 早晨一觉醒来已经8点多了,因为太累的缘故,又磨磨蹭蹭到九点多才起来,然后...
    刹那芳华2004阅读 551评论 0 0
  • 如果我在16岁时喜欢你,我会坚持不懈地给你写信,期待你的每一张亲笔 如果我在18岁时喜欢你,我会在手机通讯录里给你...
    陳佩榆阅读 62评论 0 0
  • 我们来复习下高中生物知识:男宝宝和女宝宝是怎样来的? 男生是XY,X (卵)是来自母亲,Y(精子)是来自父亲。 女...
    Lucky_Angel心空间阅读 272评论 0 1