版本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相关推荐

  1. unity3d android assets,Unity3D之Android同步方法读取streamingAssets(八十八)

    版本unity5.3.3 android 小米pad1 streamingAssets 这个目录在IOS下是可以同步读取的,但是在Android下必须用www来异步读取..这就很恶心了-所以最近我就在 ...

  2. Unity3D研究院之在Unity中打开第三方数据库配合Android开发(三十二)

    http://www.xuanyusong.com/archives/831 http://www.xuanyusong.com/archives/1454 如果大家对Unity中如何使用数据库还不是 ...

  3. Unity3D研究院之与Android相互传递消息

       上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了.恰好Unity for Andoid 和 IOS一样都是可以相互与Unity发送 ...

  4. Unity3D研究院之Unity中连接本地或局域网MySQL数据库

    用户名 Email 游戏蛮牛 手机端 开启辅助访问 腾讯QQ 立即注册 登录 用户名 自动登录  找回密码 密码 登录  注册帐号 [Unity5.X版本开始预售啦!] 扫一扫,访问微社区 </ ...

  5. 匹夫细说Unity3D(一)——移动平台动态读取外部文件全解析

    前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖总结成一套相同 问题 的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大 ...

  6. ugui 转轮_Unity3D研究院之Android NDK编译C/C++结合Unity实现本地数据共享(二十八)...

    开始本篇文章之前我先为大家简单的介绍一下Android NDK编程的原理, 我们知道Android开发使用JAVA语言来编程它的运行效率要比C/C++低很多,为了让JAVA语言可以调用 C/C++ 这 ...

  7. 转:Unity3D研究院之提取游戏资源的三个工具支持Unity5(八十四)

    这两天无意间又发现了两个提取Unity游戏资源的工具,这会儿刚好有时间我就码点字总结一下. 一.disunity 因为之前写过了所以这里就不介绍了 .Unity3D研究院之mac上从.ipa中提取un ...

  8. unity读取服务器上的文件夹,unity 如何使用文件流读取streamingassets下的资源

    目的:读取streamingassets下的文件中指定的一段字节 已知:文件中的起始位置,和需要读取的长度 1.android下读取 1.1 不能直接使用c#的filestream,读取失败 报错: ...

  9. android studio 读取内存txt文件_SharedPreference与文件存储

    Android常用数据存储方式有SharedPreferences存储数据(虽然还是属于内部存储).文件存储(内部,外部).SQLite数据库存储.ContentProvider存储数据.网络存储数据 ...

最新文章

  1. Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(andro
  2. Juniper的路由器、防火墙、交换机如何恢复出厂配置
  3. linux hosts文件如何修改_如何修改hosts文件?让你简单方便快捷管理
  4. Linux中source命令的用法
  5. Android实现一个自己定义相机的界面
  6. 接口文档示例_在示例中使用Android中的Work Manager
  7. Linux文件系统之df
  8. ElasticSearch Pipeline 为新增数据设置更新时间
  9. svm回归matlab工具箱很慢,PSO优化SVM参数进行回归预测,结果很不理想
  10. es6 async函数的基本用法
  11. 华为ap配置_13、了解下POE交换机以及AP供电几种方式
  12. UIPickerView的使用
  13. html网页中获取vf数据到mysql_vfp教程之用FoxWeb在网上快速发布你的FOXPRO数据库
  14. iPhone 11 820-01523 N104手机电路原理图+位号图
  15. qq三国2015最新服务器,合服服务器查询
  16. 论文阅读:Semantic Aware Attention Based Deep Object Co-segmentation(ACCV2018)
  17. Centos下搭建个人网站
  18. python代码设置超参数_超参数调优总结,贝叶斯优化Python代码示例
  19. 考研政治---马克思主义基本原理概论---唯物史观
  20. AJAX-客户端服务器端通信

热门文章

  1. android home键后计时拉起app_使用React Native完成App软件
  2. Unity3D研究院之获取摄像机的视口区域
  3. 【WebGL】《WebGL编程指南》读书笔记——第5章
  4. DIV常用属性大全自己整理
  5. (五)DOM4j进行XML文件的解析及生成
  6. 【BZOJ-4631】踩气球 线段树 + STL
  7. 【朴灵评注】JavaScript 运行机制详解:再谈Event Loop
  8. 使用友盟分享心得(SSO登陆,不能获取accesstoken,不能跳转APPSSO登陆的问题)
  9. viewDidLoad、viewWillAppear、viewWillDisappear
  10. [摘记]数值方法04——函数求值