Android全局桌面宠物 Unity方案实现
Android全局桌面寵物 Unity方案實現
最近接到一個任務是Android設備上實現一個全局的指引動畫,開始想著就用普通動畫控件或者svga、lottie控件實現,最近正好在學習Unity,所以試著用unity實現。經過三天努力,居然實現了。話不多說,馬上開始:
1、準備素材
在愛給網找到一個蝴蝶3D模型,然后通過3Dmax導出為FBX模型,然后倒入到unity里,具體操作相對比較簡單,只是說明一下,模型紋理需要跟導出文件放在一起,否者到unity里面沒有紋理皮膚。然后就是在unity修改Animation Type為Legacy,以及動畫循環設置:Wrap Mode設置為Loop。
模型下載地址:http://www.aigei.com/3d/model/lactation/
2、導出透明Unity工程
Unity導出透明應用比較麻煩,耗時最多,找了很久只有這個文章有提及:
https://www.jianshu.com/p/a67f77cd2e62
也看了英文原地址:
https://forum.unity.com/threads/unity3d-export-to-android-with-transparent-background.512129/
于是開始嘗試,按照文檔所說,只需要修改兩個地方就能實現:
1、修改Main Camera 的背景顏色為 Solid Color,并且透明度設置為0。
2、導出設置勾選preserveFramebufferAlpha。
我裝的Unity 5.5.0f3 (64-bit)和Unity 2019.1.0a8 (64-bit),沒有找到文檔所說的preserveFramebufferAlpha選項,按文檔所說的2018.1版本可以,我又裝了Unity 2018.1.1f1 (64-bit),選項是有了,但是按照設置導出還是不透明。
反復排查和對比,發現我的顏色設置透明度不起作用,只顯示6位顏色,而沒有透明度顯示:
只能嘗試下載其他版本。
找到官方操作手冊,發現這個版本也有設置選項
https://docs.unity3d.com/cn/2017.4/Manual/class-PlayerSettingsAndroid.html
于是嘗試下了Unity 2017.4.2f2 (64-bit)版本,看到了8位的顏色值,心里大喜:
本來想著直接導出apk運行,但是一直報錯,導出失敗,懷疑是版本比較舊,嘗試更換了舊版本NDKK和jdk版本,以及自定義了Gradle,都不行。最后只好導出工程,然后自己創建Android工程編譯。還算順利很快運行實現了效果。
中間還出現個小問題,就是渲染的圖像顏色不對,有點過曝光。后來發現是camera顏色值問題,設置成#00000000后解決。
3、做全局window窗口
Unity直接導出的工程是activity顯示動畫,要做全局widow,需要把UnityPlayer放service里生成。我直接拷貝相關方法,放到service里生成,然后放入系統window,結果什么都不顯示。
看UnityPlayer生成傳入的context居然是activity類型,頓時心的都涼了。
我不會輕易放棄,我通過Application保存了全局的activity和UnityPlayer,然后從window里面獲取,驗證可行性,多次嘗試都是顯示空白。
public class MainApp extends Application {private static Activity mActivity;static UnityPlayer mUnityPlayer;public static Application app;@Overridepublic void onCreate() {super.onCreate();app = this;}public static Activity getActivity() {return mActivity;}public static void setActivity(Activity activity) {mActivity = activity;}public static UnityPlayer getUnityPlayer() {return mUnityPlayer;}public static void setUnityPlayer(UnityPlayer unityPlayer) {mUnityPlayer = unityPlayer;} }偶然間發現,UnityPlayer在activity里面生成,并且生命周期全部放activity,只是把UnityPlayer加載到window窗口,居然可以實現。只是activity不能切換后臺,切換到后臺動畫就暫停了。
嘗試各參數,最后發現是 mUnityPlayer.windowFocusChanged(true);這句對顯示有關鍵作用。
于是推到重來,new UnityPlayer用了getApplicationContext,成功!
所以改變service全部生成,結果成功。
代碼如下:
另外值得一提的是全局懸浮窗需要設置權限,參考 https://www.jianshu.com/p/ac63c57d2555:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/><uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>以及代碼判斷用戶手動開啟:
//當AndroidSDK>=23及Android版本6.0及以上時,需要獲取OVERLAY_PERMISSION. //使用canDrawOverlays用于檢查,下面為其源碼。其中也提醒了需要在manifest文件中添加權限./*** Checks if the specified context can draw on top of other apps. As of API* level 23, an app cannot draw on top of other apps unless it declares the* {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission in its* manifest, <em>and</em> the user specifically grants the app this* capability. To prompt the user to grant this approval, the app must send an* intent with the action* {@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}, which* causes the system to display a permission management screen.**/if (Build.VERSION.SDK_INT >= 23) {if (Settings.canDrawOverlays(UnityPlayerActivity.this)) {Intent intent = new Intent(UnityPlayerActivity.this, MainService.class);Toast.makeText(UnityPlayerActivity.this, "已開啟Toucher", Toast.LENGTH_SHORT).show(); // startService(intent); // finish();// moveTaskToBack(true);} else {//若沒有權限,提示獲取.Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);Toast.makeText(UnityPlayerActivity.this, "需要取得權限以使用懸浮窗", Toast.LENGTH_SHORT).show();startActivity(intent);}} else {//SDK在23以下,不用管.Intent intent = new Intent(UnityPlayerActivity.this, MainService.class);startService(intent);moveTaskToBack(true); // finish();}總結
以上是生活随笔為你收集整理的Android全局桌面宠物 Unity方案实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Rundll32.exe在批处理里的应用
- 下一篇: Lightroom显示无法打开Light