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的更多相关文章
- Unity3D研究院之Jenkins的使用(七十八)
长夜漫漫无心睡眠,来一篇嘿嘿.我相信如果已经用Shell脚本完成IOS和Android打包的朋友一定需要Jenkins 怎么才能让策划打包ipa和apk?怎么才能彻底省去程序的时间,只要在同一局域网内 ...
- Unity3D研究院之与Android相互传递消息
原地址:http://www.xuanyusong.com/archives/676 上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了. ...
- (转)Unity3D研究院之Assetbundle的实战(六十三)
上一篇文章中我们相惜讨论了Assetbundle的原理,如果对原理还不太了解的朋友可以看这一篇文章:Unity3D研究院之Assetbundle的原理(六十一) 本篇文章我们将说说assetbundl ...
- Unity3D研究院之Assetbundle的实战(六十三)
http://www.xuanyusong.com/archives/2405 上一篇文章中我们相惜讨论了Assetbundle的原理,如果对原理还不太了解的朋友可以看这一篇文章:Unity3D研究院 ...
- (转)Unity3D研究院之将场景导出XML或JSON或二进制并且解析还原场景
自:http://www.xuanyusong.com/archives/1919 导出Unity场景的所有游戏对象信息,一种是XML一种是JSON.本篇文章我们把游戏场景中游戏对象的.旋转.缩放.平 ...
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条
Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条 异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Ap ...
- 基于unity3d游戏的android版本逆向初探
https://bbs.pediy.com/thread-212532.htm [文章标题]: 基于unity3d游戏的android版本逆向初探 [文章作者]: dreaman [作者邮箱]: [e ...
- Unity读取StreamingAssets路径下的文件
/// <summary> ///读取StreamingAssets中的文件 /// </summary> /// <param name="path" ...
- Android中读取短信信息
Android中读取的短信文件有 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /** * 所有的短信 */ public static final Strin ...
随机推荐
- DirectX 总结和DirectX 9.0 学习笔记
转自:http://www.cnblogs.com/graphics/archive/2009/11/25/1583682.html DirectX 总结 DDS DirectXDraw Surfac ...
- VM虚拟机中Ubuntu无法连接网络
之前Ubuntu是可以上网的,但是今天打开后发现上不了网了,经过一番折腾,弄好了,记录下. 方案一:将网络连接设置为自定义NAT VM ->设置-> 硬件->网络适配器 这么已修改就 ...
- Non-constant Fields in Case Labels
Non-constant Fields in Case Labels in android library project http://tools.android.com/tips/non-cons ...
- C++数据结构之链式队列(Linked Queue)
C++数据结构之链式队列,实现的基本思想和链式栈的实现差不多,比较不同的一点也是需要注意的一点是,链式队列的指向指针有两个,一个是队头指针(front),一个是队尾指针(rear),注意指针的指向是从 ...
- 2016-1-6第一个完整APP 私人通讯录的实现 3:添加联系人
一:创建模型对象:contact用于存放数据,也便于读取加载 #import <Foundation/Foundation.h> @interface contact : NSObject ...
- Ubuntu 环境变量及 ADB 配置
Ubuntu Linux 环境变量 同Windows一样,Ubuntu Linux系统包含两类环境变量:系统环境变量和用户环境变量.系统环境变量对所有系统用户都有效,用户环境变量仅仅对当前的用户有效. ...
- 前端开发者应该知道的 CSS 小技巧
一些小技巧让你的CSS技术更专业 使用:not()去除导航上不需要的边框 为body添加行高 垂直居中任何元素 逗号分离的列表 使用负nth-child选择元素 使用SVG图标 文本显示优化 在纯CS ...
- linux常用命令:4文件压缩和解压命令
文件压缩和解压命令 压缩命令:gzip.tar[-czf].zip.bzip2 解压缩命令:gunzip.tar[-xzf].unzip.bunzip2 1. 命令名称:gzip 命令英文原意:GNU ...
- ios oc ui 路径和颜色设置--崩溃解决方案
- (id)init{ self = [super init]; if (self) { _lineColor = CGColorCreateCopy([UIColor whiteColor].CGC ...
- 修复Dll文件
for %1 in (%windir%\system32\*.dll) do regsvr32.exe /s %1