使用 Unity 和 Utage 来开发 Galgame 时遇到的问题系列 1 之资源加载方式和打包

开了一个系列来记录下在开发过程中遇到的问题。

这里面有些是 Unity 自身的问题,只要使用 Unity 来开发项目都会遇到,有些是使用 Utage 时才会遇到。

目前 Utage 有多种资源加载方式,完整版加载方式可参考 Utage 文档里的 AdvEngineStarter StrageType

  • Local 使用 Resources 加载
  • StreamingAssets 使用 StreamingAssets 加载

这里主要说的是这 2 种资源加载方式和打包(Build)时遇到的问题。

初期开发时最方便的加载方式 Resources

Utage 的 Sample 示例就是使用的 Resouces 方式加载,整个开发过程都很简单:

  1. 放需要用到的资源到 Resources 里指定的文件夹。
  2. 写好项目配置文件。

之后,就可以在演出脚本里使用定义好的 Label 来显示图片等资源了。

方便归方便,随着项目使用的资源文件数量变多,项目变的复杂之后,会遇到下面几个问题。

  • Resources 文件在 Build 的时候超过 4GB 会无法打包。Bug: 4GB limit to Textures in standalone build
  • 打包时间很长。(项目资源数量多的时候,Build 一次耗费 30分钟以上时间。)
  • 打包之后加载图片的时候,有些图片加载失败显示花屏。

这些问题都会导致自己开发了游戏,但是发布的时候却遇到了问题,一般会再开发后期需要进行测试的时候发现,于是开始寻找解决方案。

经过搜索之后发现在 Unity Tutorial 的 Assets, Resources and AssetBundles 中,Chapter3 的 Resources 里有写到

3.1. Best Practices for the Resources System

Don't use it.

好的,Unity Official 在最佳实践教程里面说 不要使用 Resources。

我们经过专业训练,就算再好笑,我们都不会笑。(哈哈哈哈哈哈)

Unity 在挖了一个坑之后,必然会给你指引去使用另一个新的坑,Resources 使用起来有问题,那不如去试试 StreamingAssets?

后期开发,发布时使用 StreamingAssets

Utage 在官方教程里有一篇文章介绍如何使用 StreamingAssets 来减小 app 大小的。传送门:StreamigAssets を使ってアプリサイズ削減

使用 StreamingAssets 的优点就是解决了上面的使用 Resources 时出现的问题。

  • 解决了在使用 Resources build 时 .resS 文件大小超过 4GB 时无法 build 问题。

在 Build 的时候 Unity 会把 StreamingAssets 文件夹里的所有文件拷贝到最终包里面,所以不会出现使用 Resources 的时候,明明 Resources 只有 1.x GB 大小的素材,打包出来之后 .resS 文件体积变的超大。

  • 打包时间很短。

能做到每次打包时间在 1分钟内,具体时间视电脑配置而定,CPU 和 SSD 性能最影响打包时间。

StreamingAssets 里的素材,不会像使用 Resources 的时候每次 build 都会将 Resources 里的素材进行 compress 等耗时操作。

加载图片时出现花屏这个问题,使用 StreamingAssets 方式没出现。

也许是 Unity 在 Build 时压缩 Texture 生成 .resS 文件的时候 出现错误导致的,也有可能是其它问题,具体原因时什么,我也不清楚。


开始吐槽的分割线


使用 Resources 时出现的问题解决了,那用 StreamingAssets 岂不是很完美?世上哪有这么好的事情,下面来说说使用 StreamingAssets 时出现的问题。

  • Build AssetBundle 很耗时。

第一次 Build 的时候,会给每个资源添加 AssetBundleName,对资源进行 Compress 等操作整个过程非常耗时。

后面 Build 可以选择只将未命名的资源 Rename AssetBundleName,会快点。

  • 开发过程变的更加繁琐

每次导入资源之后,都需要 Build AssetBundle 之后,才能启动游戏来验证资源是否更新了。


那么,我应该使用什么方式来管理加载资源?

当然是自己权衡利弊,自己选择适合该项目的方式啦。

Resources 很方便,但出现无法解决的 build 问题之后,可以试试 StreamingAssets。

StreamingAssets 使用时出现了问题,如果是时间和开发机器配置性能的问题,那都不是问题。顶配 + NVMe SSD 会给你带来更好的开发体验的。

如果是 AssetBundle 的视频不能播放,那 Untiy 官方都没啥 workaround,可以试试第三方插件?

也许 Unity 新推荐的使用 Addressable Assets System 也可以试试?不过这个 Utage 虽然有给 Sample package,但后面一句又一句的请自力扩张,让我不敢用到项目上。(你太菜了。)

 

Adobe Air Native Extension 开发笔记

这次 mission 的主要内容是将 Facebook 相关的库,Firebase 和 Google 登录的 SDK集成到 Adobe Air Native Extension (ANE)中去。

由于写这个笔记前后时间相差 1周多,中间经历了换电脑,换新开发环境,既有繁体文字又有简体文字。

開發環境

macOS Mojave 10.14.6
Xcode 11.2
IntelliJ IDEA 2019.2.4 Ultimate Edition
Adobe AIR SDK 32
Oracle JDK 8 Update 231

IntelliJ IDEA

如果要使用 IntelliJ IDEA 来开发 Adobe Air/Flex app 的话,需要 Ultimate 版本才能使用。

我已经订阅了很久 JetBrains Toolbox 了,不过使用频率高的只有 Rider,拿来开发正在制作的 Unity 游戏。

在和 Adobe Air 游戏开发者讨论过程中,谈到 Adobe Air 2020 年之后的 SDK 更新的时候,说是被三星的一个开发工作室接手了后续的开发工作,于是我就也去了后续新的官网上查了下,看到 Adobe Air SDK 33 的使用说明,里面有说使用 IDEA 开发 Adobe Air 应用的说明,搜索了一下,按照 IDEA 的文档进行了环境配置之后,就开始进行开发了。

目前 Air SDK 33 不支持 iOS,只支持 Android 打包,最终还是使用 Air SDK 32 进行开发了。

KeyRemap

个人习惯调成了 IntelliJ IDEA Classic

添加外部庫

Shift Shift 打開 Search Everywhere

輸入 Project Structure 打開項目配置

切換到 Modules 裏的 Dependencies

點擊 New 來進

更改最低 iOS linker 版本

更改 linker 中的 minimum ios 版本爲 9.0 之後打包顯示下列錯誤。

Undefined symbols for architecture arm64:

猜測是因爲第三方 Framework 還是沒有打包進去。

Facebook SDK Undefined symbols

Undefined symbols for architecture arm64:
  "___isOSVersionAtLeast", referenced from:
      -[FBSDKApplicationDelegate application:openURL:options:] in FBSDKCoreKit(FBSDKApplicationDelegate.o)
      -[FBSDKApplicationDelegate application:openURL:sourceApplication:annotation:] in FBSDKCoreKit(FBSDKApplicationDelegate.o)
      

看 Adobe 論壇裏討論,是這個樣子

AIR-4198557 @available keyword in ANE causes IPA build to fail

To do this without using a custom DEFINE ( and to use closed source Frameworks which use @available such as latest Firebase )

1. Copy this file /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/cl ang/9.1.0/lib/darwin/libclang_rt.ios.a
to
[AIRSDK_PATH]/lib/aot/lib/libclang_rt.ios.a

2. Add this to your linkerOptions in platform.xml
<linkerOptions>  
  <option>-lclang_rt.ios</option>  
</linkerOptions>  


Hopefully Adobe can add libclang_rt.ios.a to AIR SDK dist

*Credit to Eugene Petrenko @JetBrains
https://jonnyzzz.com/blog/2018/06/05/link-error-2/

Comment by Eoin L.

更換完 clang 編譯器之後可以自動編譯成功了。

ANE 使用 ThirdPartyLibrary 的總結

解決 Facebook 和 Firebase 最新版 SDK 集成的時候出現的編譯問題

  1. 在 Iphone-ARM 文件夾下新建 Frameworks 文件夾,將第三方庫都拷貝到裏面。
  2. 在 iOS 的 platformoptions.xml 里添加對應的 packagedDependency 定義。
<packagedDependencies>
    <!-- Facebook -->
    <packagedDependency>Frameworks/FBSDKLoginKit.framework</packagedDependency>
    <!-- ...示例中省略其它的必须的库配置 -->
</packagedDependencies>

3. 根據 AIR-4198557 @available keyword in ANE causes IPA build to fail 里的解決方法,將 Xcode 里的 clang 編譯器拷貝到 AIRSDK 文件夾對應的位置。

4. 在 linkerOptions 添加 clang 編譯器的 option

<linkerOptions>
    <option>-ios_version_min 9.0</option>
    <option>-lclang_rt.ios</option>
    <option>-rpath @executable_path/Frameworks</option>
</linkerOptions>

5. 打包 ANE,在項目中引用,啓動 app,應該就可以編譯通過了。(第三方庫已經在 packagedDependencies 里定義好了,編譯器會自動查找到 ANE 里面引用的庫進行 auto link,無須手動在 linkerOptions 里定義。)

6. 也可以尝试将第三方库拷贝到 AIRSDK 文件夹里(clang 编译器同级的位置),再尝试进行 ANE 打包。

参考链接:

  1. Adobe AIR SDK from HARMAN FAQ
  2. IntelliJ IDEA ActionScript and Flex
  3. Building a native extension for iOS and Android – Part 3: Building the iOS library | Adobe Developer Connection
  4. Adobe Flash Platform * Building the native library

Konachan 收圖工具

解析從 Konachan 收到的 JSON 數據,提取出圖片的下載地址,核心代碼不到 30 行,重要的是思路 >_Q
/

思路:

  • Konachan API Documentation 中得知 JSON 地址
  • 目測出原文件下載地址的 Key 是 file_url(題圖的 poi)
  • 將返回的 JSON 數據放入到一個 NSArray 中
  • 從 NSArray 中提取出每一個 picture 的 NSDictionary 對象
  • 從 NSDictionary 中根據 Key(file_url) 取出 Value(http://xxx.jpg)
  • 將 取出的 Value(http://xxx.jpg) 放入到一個 NSArray 中
  • 遍歷包含網址的 NSArray ,將每一個元素轉換成 NSURL 對象,之後下載到本地 Downloads 文件夾下

源碼