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

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

Laya2.0.2【疯狂怪兽车】游戏制作经验记录_第1张图片
疯狂怪兽车

Laya2.0.2【疯狂怪兽车】游戏制作经验记录_第2张图片
游戏截图

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的粒子规则来制作粒子


    Laya2.0.2【疯狂怪兽车】游戏制作经验记录_第3张图片
    粒子规则
  2. 注意Color over LifeTime的渐变色块不要超过4个,否则会有问题


    Laya2.0.2【疯狂怪兽车】游戏制作经验记录_第4张图片
    Color over LifeTime

插件导出

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

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

Laya2.0.2【疯狂怪兽车】游戏制作经验记录_第5张图片
模型场景管理

导出参数如下,以汽车模型为例:
Laya2.0.2【疯狂怪兽车】游戏制作经验记录_第6张图片
导出参数

最终导出到Laya客户端的效果:
Laya2.0.2【疯狂怪兽车】游戏制作经验记录_第7张图片
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【疯狂怪兽车】游戏制作经验记录)