Reputation: 1937
How do I load resources (text files, textures, etc.) from within a native plugin? I'm in the process of attempting to implement a mono invoke of Resources.Load(), but I am unsure as to how to handle the Object that will be returned from this operation (assuming it is successful). Any help would be greatly appreciated :).
Upvotes: 3
Views: 9572
Reputation: 53
I want to offer an answer to this question in relation to the native side of things.
iOS
It's quite simple really- you can get to the StreamingAssets path on the native side like so:
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
NSString* streamingAssetsPath = [NSString stringWithFormat:@"%@/Data/Raw/", bundlePath];
Android
I don't like using streaming assets on Android, It's a messy solution copying all the files about IMO. A much cleaner way of doing it is by creating the directory structures defined in the docs in your plugin directory.
So for example an image could be located like this in your Unity project:
Assets/Plugins/Android/res/drawable/image.png
Then, on the Android side you can access the resource ID of it like this:
Context context = (Context)UnityPlayer.currentActivity;
String packageName = context.getPackageName();
int imageResourceId = context.getResources().getIdentifier("image", "drawable", packageName);
Up to you how to handle everything else from there! Hope this helps :)
Upvotes: 4
Reputation: 5499
The Unity-supported means for your plugin to load resources directly from the native filesystem is to place those resources into a folder named "StreamingAssets" inside your project. When your Unity-based application is installed, the contents of this folder are copied to the native filesystem (except Android, see below). The path to this folder on the native side varies per platform.
In Unity v4.x and later, this path is available as Application.streamingAssetsPath;
Note that on Android the files you place in StreamingAssets get packaged into a .jar file, though they can be accessed by unzipping the .jar file.
In Unity v3.x, you have to manually construct the path yourself as follows:
Application.dataPath + "/StreamingAssets"
Application.dataPath + "/Raw"
"jar:file://" + Application.dataPath + "!/assets/"
Here is a snippet I used to handle this:
if (Application.platform == RuntimePlatform.IPhonePlayer) dir = Application.dataPath + "/Raw/";
else if (Application.platform == RuntimePlatform.Android) {
// On Android, we need to unpack the StreamingAssets from the .jar file in which
// they're archived into the native file system.
// Set "filesNeeded" to a list of files you want unpacked.
dir = Application.temporaryCachePath + "/";
foreach (string basename in filesNeeded) {
if (!File.Exists(dir + basename)) {
WWW unpackerWWW = new WWW("jar:file://" + Application.dataPath + "!/assets/" + basename);
while (!unpackerWWW.isDone) { } // This will block in the webplayer.
if (!string.IsNullOrEmpty(unpackerWWW.error)) {
Debug.Log("Error unpacking 'jar:file://" + Application.dataPath + "!/assets/" + basename + "'");
dir = "";
break;
}
File.WriteAllBytes(dir + basename, unpackerWWW.bytes); // 64MB limit on File.WriteAllBytes.
}
}
}
else dir = Application.dataPath + "/StreamingAssets/";
Note that on Android, Android 2.2 and earlier cannot directly unpack large .jars (typically larger than 1 MB) so you would need to handle that as an edge case.
References: http://unity3d.com/support/documentation/Manual/StreamingAssets.html, plus http://answers.unity3d.com/questions/126578/how-do-i-get-into-my-streamingassets-folder-from-t.html and http://answers.unity3d.com/questions/176129/accessing-game-files-in-xcode-project.html
Upvotes: 8