日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Unity3D研究院之Android同步方法读取streamingAssets

發布時間:2023/12/10 Android 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity3D研究院之Android同步方法读取streamingAssets 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

版本Unity5.3.3

Android 小米pad1

首先非常感謝 @守著陽光 同學在下面的留言。讓我解決了一個大的謎團。。

?

開始我知道 StreamingAssets 路徑是這個 path = “jar:file://” + Application.dataPath + “!/assets/”;

文檔在這里:?http://docs.unity3d.com/Manual/StreamingAssets.html

后來我知道了一個新API?Application.streamingAssetsPath

Application.streamingAssetsPath 其實就等于?“jar:file://” + Application.dataPath + “!/assets/”;

然而問題就出現在這個路徑上。我打印了一下LOG

Application.streamingAssetsPath = jar:file:///data/app/com.xxx.xxx-1.apk!/assets

Application.dataPath+”!assets” = /data/app/com.xxx.xxx-1.apk!assets

也就是說Application.streamingAssetsPath ?多了一個 ? jar:file://

那么如果想在Android上同步方法AssetBundle.LoadFromFile 就得用?Application.dataPath+”!assets”這個路徑。

從此這段代碼就正常了。

C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using UnityEngine; using System.Collections; public class NewBehaviourScript : MonoBehaviour { public SpriteRenderer spriteRenderer; void Start () { // /data/app/com.xxx.xxx-1.apk!assets/yusong.unity3d string path = Application.dataPath+"!assets/yusong.unity3d"; AssetBundle assetbundle = AssetBundle.LoadFromFile(path); Sprite sprite = assetbundle.LoadAsset<Sprite>("0"); spriteRenderer.sprite =sprite; } }

Unity的坑啊~ 55555555555555555555

還有這個路徑只能用來AssetBundle.LoadFromFile 。如果想用File類操作。 比如File.ReadAllText??或者 File.Exists??Directory.Exists 這樣都是不行的。

———————————-!!從今天以后下面的代碼已經可以作廢了!!—————————

streamingAssets 這個目錄在IOS下是可以同步讀取的,但是在Android下必須用www來異步讀取。。這就很惡心了~所以最近我就在想辦法如何能在Android下也能同步讀取。如下圖所示,我把一個sprite打成assetbundle并且放在StreamingAssets目錄下。

assetbundle的壓縮格式 ,我使用的是unity5.x的lz4方式。

C#
1 2 3 4 5 6 7 8 [MenuItem ("Assets/Build AssetBundles")] static void BuildAllAssetBundles () { BuildPipeline.BuildAssetBundles ("Assets/StreamingAssets",BuildAssetBundleOptions.ChunkBasedCompression,BuildTarget.Android); AssetDatabase.SaveAssets (); AssetDatabase.Refresh(); }

然后創建一個3D Sprite 在Hierarchy里 試圖把這個ab里的sprite加載上去。

C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 using UnityEngine; using System.Collections; public class NewBehaviourScript : MonoBehaviour { public SpriteRenderer spriteRenderer; void Start () { //注釋掉的代碼是 unity自己的同步方式, 但是在Android上不行, 可是在IOS上可以 // AssetBundle assetbundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath +"/yusong.unity3d"); // // Sprite sprite = assetbundle.LoadAsset<Sprite>("0"); // // spriteRenderer.sprite =sprite; //以下代碼通過JAVA代碼來同步讀取并且返回給unity AndroidJavaClass m_AndroidJavaClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject m_AndroidJavaObject??= null; if (m_AndroidJavaClass != null) { m_AndroidJavaObject = m_AndroidJavaClass.GetStatic<AndroidJavaObject>("currentActivity"); } byte[] s = m_AndroidJavaObject.Call<byte[]>("LoadAB","yusong.unity3d"); AssetBundle assetbundle = AssetBundle.LoadFromMemory(s); Sprite sprite = assetbundle.LoadAsset<Sprite>("0"); spriteRenderer.sprite =sprite; } }

然后,把unity導出成android工程。。

用eclipse打開剛剛導出的工程。找到UnityPlayerActivity.java類 添加如下代碼

Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 package com.yusong.momo; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import com.unity3d.player.*; import android.app.Activity; import android.content.res.AssetManager; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; public class UnityPlayerActivity extends Activity { protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code protected AssetManager assetManager; // Setup activity layout @Override protected void onCreate (Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getWindow().setFormat(PixelFormat.RGBX_8888); // <--- This makes xperia play happy mUnityPlayer = new UnityPlayer(this); setContentView(mUnityPlayer); mUnityPlayer.requestFocus(); assetManager = getAssets(); } private byte[] readtextbytes(InputStream inputStream) { ??ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); //長度這里暫時先寫成1024 ??byte buf[] = new byte [1024]; ??int len; ??try { ?? while ((len = inputStream.read(buf)) != -1) { ????outputStream.write(buf, 0, len); ?? } ?? outputStream.close(); ?? inputStream.close(); ??} catch (IOException e) { ??} ??return outputStream.toByteArray(); } //讀取assetbund并且返回字節數組 public byte[] LoadAB(String path) { InputStream inputStream = null ; ??try { ?? inputStream = assetManager.open(path); ??} catch (IOException e) { ?? Log.v ("unity", e.getMessage()); ??} ??return readtextbytes(inputStream); } // Quit Unity @Override protected void onDestroy () { mUnityPlayer.quit(); super.onDestroy(); } // Pause Unity @Override protected void onPause() { super.onPause(); mUnityPlayer.pause(); } // Resume Unity @Override protected void onResume() { super.onResume(); mUnityPlayer.resume(); } // This ensures the layout will be correct. @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mUnityPlayer.configurationChanged(newConfig); } // Notify Unity of the focus change. @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mUnityPlayer.windowFocusChanged(hasFocus); } // For some reason the multiple keyevent type is not supported by the ndk. // Force event injection by overriding dispatchKeyEvent(). @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_MULTIPLE) return mUnityPlayer.injectEvent(event); return super.dispatchKeyEvent(event); } // Pass any events not handled by (unfocused) views straight to UnityPlayer @Override public boolean onKeyUp(int keyCode, KeyEvent event)???? { return mUnityPlayer.injectEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event)?? { return mUnityPlayer.injectEvent(event); } @Override public boolean onTouchEvent(MotionEvent event)??????????{ return mUnityPlayer.injectEvent(event); } /*API12*/ public boolean onGenericMotionEvent(MotionEvent event)??{ return mUnityPlayer.injectEvent(event); } }

?

OK 大功告成, 我的sprite已經可以同步加載了。

如下圖所示,那么實際上unity把已經把streamingAssets目錄下的資源放在了android的assets目錄下。

?

那么我們同步加載的原理也是利用Android的AssetManager這個類來讀取的。

剛和同事討論了一下,如果有效率的問題,我們可以在ndk里讀取assets下的資源。 比如向這樣~ ?c# ?調用 ?ndk 讀取完直接返回給c# 這樣就可以不通過java這一層。。

http://www.cppblog.com/johndragon/archive/2012/12/28/196754.html

最后希望大家可以幫忙多多測試看看,謝謝啦~~

?

  • 本文固定鏈接: http://www.xuanyusong.com/archives/4033
  • 轉載請注明: 雨松MOMO 2016年04月28日 于 雨松MOMO程序研究院 發表

總結

以上是生活随笔為你收集整理的Unity3D研究院之Android同步方法读取streamingAssets的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。