美文网首页
Laya2.0.2【疯狂怪兽车】游戏制作经验记录

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

作者: 半透明Feng | 来源:发表于2019-05-16 19:29 被阅读0次

    最近用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. 苹果打包

    相关文章

      网友评论

          本文标题:Laya2.0.2【疯狂怪兽车】游戏制作经验记录

          本文链接:https://www.haomeiwen.com/subject/rtemaqtx.html