版本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

最后希望大家可以帮忙多多测试看看,谢谢啦~~

Unity3D研究院之Android同步方法读取streamingAssets的更多相关文章

  1. Unity3D研究院之Jenkins的使用(七十八)

    长夜漫漫无心睡眠,来一篇嘿嘿.我相信如果已经用Shell脚本完成IOS和Android打包的朋友一定需要Jenkins 怎么才能让策划打包ipa和apk?怎么才能彻底省去程序的时间,只要在同一局域网内 ...

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

    原地址:http://www.xuanyusong.com/archives/676 上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了. ...

  3. (转)Unity3D研究院之Assetbundle的实战(六十三)

    上一篇文章中我们相惜讨论了Assetbundle的原理,如果对原理还不太了解的朋友可以看这一篇文章:Unity3D研究院之Assetbundle的原理(六十一) 本篇文章我们将说说assetbundl ...

  4. Unity3D研究院之Assetbundle的实战(六十三)

    http://www.xuanyusong.com/archives/2405 上一篇文章中我们相惜讨论了Assetbundle的原理,如果对原理还不太了解的朋友可以看这一篇文章:Unity3D研究院 ...

  5. (转)Unity3D研究院之将场景导出XML或JSON或二进制并且解析还原场景

    自:http://www.xuanyusong.com/archives/1919 导出Unity场景的所有游戏对象信息,一种是XML一种是JSON.本篇文章我们把游戏场景中游戏对象的.旋转.缩放.平 ...

  6. Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条

    Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条 异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Ap ...

  7. 基于unity3d游戏的android版本逆向初探

    https://bbs.pediy.com/thread-212532.htm [文章标题]: 基于unity3d游戏的android版本逆向初探 [文章作者]: dreaman [作者邮箱]: [e ...

  8. Unity读取StreamingAssets路径下的文件

    /// <summary> ///读取StreamingAssets中的文件 /// </summary> /// <param name="path" ...

  9. Android中读取短信信息

    Android中读取的短信文件有 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /**  * 所有的短信  */ public static final Strin ...

随机推荐

  1. c++高质量编程手册

    怡化主管强烈要求我读这本书.... 笔记尚未完成,持续更新呗.. 第1章 高质量软件开发之道 1.1 软件质量基本概念 1.1.1 如何理解软件的质量:功能性和非公能性 1.1.2 提高软件质量的基本 ...

  2. 爬虫再探实战(三)———爬取动态加载页面——selenium

    自学python爬虫也快半年了,在目前看来,我面临着三个待解决的爬虫技术方面的问题:动态加载,多线程并发抓取,模拟登陆.目前正在不断学习相关知识.下面简单写一下用selenium处理动态加载页面相关的 ...

  3. 【Zhejiang University PATest】02-3. 求前缀表达式的值

    算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4.请设计程序计算 ...

  4. UITableView详解(2)

    承接上文,再续本文 一,首先我们对上次的代码进行改进,需要知道的一点是,滚动视图的时候,我们要创建几个视图,如果一个视图显示一个图片占据整个屏幕,对于滚动视图我们只需要创建三个视图就可以显示几千给图片 ...

  5. HDU 3966 (树链剖分+线段树)

    Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...

  6. HDU 1002 A + B Problem II(AC代码)

    #include <stdio.h> #include <string.h> #define MAX 1009 int main() { },b[MAX]={}; ,z=,r= ...

  7. csdn第四名

    编号:1027时间:2016年7月18日11:10:42功能:csdn第四名URL :http://blog.csdn.net/yuanmeng001

  8. js之阻止事件冒泡(待修改)和阻止默认事件

    阻止默认事件(event.stopPropagation()): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// ...

  9. 解决"waitForCondition(LockCondition) timed out (identity=23, status=0). CPU may be pegged. trying again."问题

    前几天在跑游戏引擎的时候,遇到了一个比较奇怪的问题,logcat不断地打印下面的错误: waitForCondition(LockCondition) timed out (identity=23, ...

  10. CentOS下Web服务器环境搭建LNMP一键安装包

    CentOS下Web服务器环境搭建LNMP一键安装包 时间:2014-09-04 00:50来源:osyunwei.com 作者:osyunwei.com 举报 点击:3797次 最新版本:lnmp- ...