分类存档: unity3d

unity MonoBehaviour也可以实现单例

<code>public class GameLaunch:MonoBehaviour
{
    
    public static GameLaunch _instance;

    public static GameLaunch instance
    {
        get{
            if (_instance == null)
            {
                GameObject go = new GameObject("GameLaunch");
                DontDestroyOnLoad(go);
                _instance = go.AddComponent&lt;GameLaunch>();
            }
            return _instance;
        }
    }
}</code>

unity install location最好设置为Automatic

Unity install location,根据 unity 官方文档:https://docs.unity3d.com/Manual/class-PlayerSettingsAndroid.html

Install Location 	Specifies application install location on the device (for detailed information, refer to Android Developer documentation on install locations.
        Automatic 	Let the operating system decide. User will be able to move the app back and forth.
        Prefer External 	Install the application to external storage (SD card) if possible. The operating system does not guarantee it; if not possible, the app will be installed to internal memory.
        Force Internal 	Force the application to be installed to internal memory. The user will be unable to move the app to external storage.

项目组最初选择的是 Prefer External,本意是想尽量安装在SD卡上,不占用玩家手机内存储。

今天在一台手机上,程序死活安装不上去,抓到Log:

01-30 15:17:33.801 3109-3242/? D/PackageManager: return install result to caller: 1141892560

01-30 15:17:33.801 3109-3242/? D/PackageManager: returnCode: -18

找到PackageManager.java的源码:https://android.googlesource.com/platform/frameworks/base/+/534a67c/core/java/android/content/pm/PackageManager.java

    // ------ Errors related to sdcard
    /**
     * Installation return code: this is passed to the {@link IPackageInstallObserver} by
     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
     * a secure container mount point couldn't be accessed on external media.
     * @hide
     */
    public static final int INSTALL_FAILED_CONTAINER_ERROR = -18;

然后在google上搜索 INSTALL_FAILED_CONTAINER_ERROR
http://www.cnblogs.com/lovecode/articles/3658211.html

https://stackoverflow.com/questions/5744298/what-does-this-mean-failure-install-failed-container-error

获得解决方案:


Change the install location from

android:installLocation="preferExternal"

into

android:installLocation="auto"

in your project's AndroidManifest.xml.

修改后重新出包,安装,成功。

AssetBundle解析音频文件

使用 Unity Studio 解析 ab 时,发现在 obb 中的 ab 未解析出来。

disunity 又N年未更新了。

用 ABE 发现可以提取出 ab data和dump信息,但是工具无自动导出音频功能。

只能自己手动处理下了。

1、obb本身是压缩的ab格式,需要先将其解压,用 Unity Studio 解压即可。

2、对于这部分文件 UnityStudio无法正常解析(有时间可以看下源码找下原因),使用 UAB 打开后,将AudioClip 提取出 raw data(文件名类似: Select-voice-02_AudioClip_117_1854432161) ,提取出 raw dump (文件名类似:Raw_117_1854432161.dat)

我们需要做的事件就是将 ab的文件头从 raw dump中去除,即可得到音频文件。

0 AudioClip Base
 1 string m_Name = "Select_voice_02"
 0 int m_Format = 2
 0 int m_Type = 13
 0 bool m_3D = false
 1 bool m_UseHardware = false
 0 int m_Stream = 2
 0 vector m_AudioData
  1 Array Array (95608 items)

raw data 中列明了文件头信息,对我们有用的是 Array Array 行,指明了 音频文件的大小长度。

之后只需要从 raw dump中取最后 arraylength+1 字节内容即为音频内容。

unity官方出的内存查看工具

https://bitbucket.org/Unity-Technologies/memoryprofiler

学习导航网格

现在开发游戏,基本上不存在解决不了的技术难点了,所有的难点都有成熟的解决方案了。

寻路解决方案:导航网格,虽然unity自带导航网格解决方案,但还是希望自己能多学习些知识。

先解决第一步,如何生成导航网格:

这里先从开源的解决方案些开始学习:https://github.com/luzexi/Unity3DNavMesh.

看起来,应该有算法,可以直接生成,还没找到生成算法。如果是三角形,应该可以合并为多边凸边形。

unity中的音频插件

查看了几个大公司的作品,发现使用aksoundengine的比较多,

查了一下,AkSoundEngine官方地址:https://www.audiokinetic.com/

是其提供的wwsize音频工作流中间件,看费用不适合小团队,提供的功能大而全,而且可能很多之前的端游积累的工具链都可以进行无缝整合使用。

除此之外,Master Audio高居unity store音频分类榜首,而且价格便宜,对小团队是一个非常好的选择。

https://www.assetstore.unity3d.com/en/#!/content/5607

assetbundle打包

终于开始处理每个项目都会遇到的assetbundle的问题了。

研究了一下,还是使用传统的手动代码打包方式,好处是可以更细粒度的掌控好资源分包。

而且打包时,有些资源必须提取为公共包。

举例:

1、两个UI,打两个assetbundle包,如果将依赖全打进去,则会发现,unityengine.ui.dll两个包都被打进去了。遇到这种情况,我们就可以将重复资源提取出来,打为一个公共包。

如果打为公共包,则如何组织包的结构是一个大问题。

现在初步的想法是,最大限度的避免重复的资源,如果资源分的太细,导致某个assetbundle依赖过多时,则使用多线程将文件读入内存(避免读取过慢导致耗时过长),单线程内存中加载。

备用方案,最细粒度打包资源,在玩家手机上合并资源为一个拥有所有依赖的整包,这样也可以同时避免了加载依赖导致的耗时。只是会在玩家第一次打开游戏时,会有一个合并包的过程。

unity中的SceneCamera

在设置场景相机时,发现使用GameObject.Find(“SceneCamera”)获得了一个对象,很奇怪的是场景中并没有这个对象。

测试一下, 发现应该是SceneView中的camera,竟然连各种文档上都找不到对应的描述,应该是unity自己保留的对象,连用FindByType都无法查询到这个对象,却通过名字可以直接获取到。

 

一个抓取手机上gles渲染代码的工具

adreno profiler

高通出品,只能用在高通CPU的安卓手机上,非常棒。

IOS上可以使用 frame capture.

如果遇到问题:

Found a device, but no Adreno Profiler-enabled app.

用以下方式解决:

1、执行
adb shell setprop debug.egl.profiler 1
2、退出profiler,重新启动。

一般情况下,上面的问题都会解决,可以看到设置,虽然文档上写说profiler2.x, 会自动设置,不需要我们手动再执行一下。
我只想说,文档有时也不全对。

游戏可能用到的一些第三方工具

1、腾讯开源的行为树组件  http://tencentopen.github.io/behaviac/

1)需要找下 饥荒 源码中的行为树lua代码组件

2、unity中的聊天图文混排插件 emoji_extension 、hypertext

3、游戏开发好网站:

http://aigamedev.com/premium/interview/dont-starve/

 


Warning: Use of undefined constant XML - assumed 'XML' (this will throw an Error in a future version of PHP) in /opt/wordpress/wp-content/plugins/wp-syntaxhighlighter/wp-syntaxhighlighter.php on line 1048