Using Unity 3d asset bundles on Hololens from device folders - unity3d

We are building a Hololens app which is going to use asset bundles from the device folders, but we are getting a 'Unable to open archive file' error when trying to load the bundle files.
As we don't have much experience with asset bundles we started this by creating a very simple bundle file (just a few Unity primitives and materials) and we made a first try loading them into the app from the Unity editor. That is working as expected but it fails when we deploy the app into our Hololens.
This is our loading method:
#if WINDOWS_UWP
public async void CallForBundles()
#else
public void CallForBundles()
#endif
{
string bundleFile = "--- NO BUNDLE ---";
#if UNITY_EDITOR
bundleFile = #"D:\temp\UnityBuilds\AssetBundles\exportablebundle";
#endif
#if WINDOWS_UWP
Windows.Storage.StorageFolder objectsFolder = Windows.Storage.KnownFolders.Objects3D;
Windows.Storage.StorageFile bundleFilePointer = await objectsFolder.GetFileAsync("exportablebundle");
bundleFile = bundleFilePointer.Path;
#endif
var myLoadedAB = AssetBundle.LoadFromFile(bundleFile);
//instante bundle components from myLoadedAB//
}
As you see is something very simple. We find the bundle path by different methods depending on the platform (we already used this system for text files, pngs and others) and the UNITY_EDITOR side is working. The WINDOWS_UWP is throwing this error just on the call to AssetBundle.LoadFromFile(bundleFile);:
Unable to open archive file: C:/Data/Users/edata/3D Objects/exportablebundle
(Filename: C:\buildslave\unity\build\Runtime/VirtualFileSystem/ArchiveFileSystem/ArchiveStorageReader.cpp Line: 542)
'Holoplan.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\HoloplanVS.Release_x86.jalfonso\System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
NullReferenceException: Object reference not set to an instance of an object.
at GameManager.<CallForBundles>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_0(Object state)
at UnityEngine.UnitySynchronizationContext.WorkRequest.Invoke()
at UnityEngine.UnitySynchronizationContext.Exec()
at UnityEngine.UnitySynchronizationContext.ExecuteTasks()
at UnityEngine.UnitySynchronizationContext.$Invoke1(Int64 instance, Int64* args)
at UnityEngine.Internal.$MethodUtility.InvokeMethod(Int64 instance, Int64* args, IntPtr method)
(Filename: <Unknown> Line: 0)
"Unable to open archive file: C:/Data/Users/edata/3D Objects/exportablebundle"
seems to be the same error that happens when the app try to load a bunde with wrong file name or path even when running on the editor so it looks like that for some reason 'AssetBundle.LoadFromFile' can't locate de file. We checked the bundleFile at that line and it contains the right filepath ('C:\Data\Users\edata\3D Objects\exportablebundle' where 'exportablebundle' is the bundle file name), so we guess that 'AssetBundle.LoadFromFile' has issues when reading from the Hololens local folder but we don't have much idea about how to address this.
¿Anyone can lend us a hand, please?
EDIT-
We are building our asset bundle with the sample code from the Unity manual in 'Asset bundle workflow'. Is like this:
static void BuildAllAssetBundles(){
string assetBundleDirectory = "Assets/AssetBundles";
if (!Directory.Exists(assetBundleDirectory)){
Directory.CreateDirectory(assetBundleDirectory);
}
BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
}
'StandaloneWindows' as build target seems the closest to hololens from the available list so we went for it.

Sorry, asset bundling isn't working in HL devices right now. It's known issue that has to be fixed.

Related

Creating and loading AssetBundle manifest in Unity

I am loading some assets from assetBundles that I store online. I want to cash some of them but I need a bundle manifest for That.I am using this to build the bundle.
BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.Android);
This gives me enter image description here, first file is assetBundle, the secound is manifest for that assetbundle. Based on what I found online I think it should also create a manifest named atlases (for the folder), but it doesnt.
If i try to load one of the assetBundle manifests using this
AssetBundle manifestBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "atlases/atlascity1") //fails with error: "Unable to open archive file: C:/ProjectPath/StreamingAssets/atlases/atlascity1"
//ver. B:
AssetBundle manifestBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "atlases/atlascity1.manifest") //fails with error: "Unable to read header from archive file: C:/ProjectPath/StreamingAssets/atlases/atlascity1.manifest"
What am I missing?

Flutter : Play Audio File From Application Directory ( Storage )

In Stack Overflow or other example, I found that from asset folder and from network I can play audio file easily.
But, There is no clear approach That I can play audio file from Application Storage or mobile device.
My Audio path is : String playebleFilePath = '/Users/noorhossain/Library/Developer/CoreSimulator/Devices/5C9813C4-7773-4013-B086-279DB8FCA64F/data/Containers/Data/Application/F905830C-C698-4FEB-80F1-FB386BE18882/Library/Application Support/VocalDatabaseAudio/word_audio_one/2.mp3'
final assetsAudioPlayer = AssetsAudioPlayer();
assetsAudioPlayer.open(
Audio.file(playebleFilePath),
);
How can I play Audio from this storage path ?
My error log says : plugin Exception, cannot find the file in this server.
Any solution ?
I think the exception is due to the fact that the file you are trying to play is not in the assets folder which will cause the plugin to throw an exception.
i have been using audioplayers plugin and for assets it actually has a prefix to the path that actually points to an "assets" folder, the assets folder should also be correctly referenced in the pubspec.yaml file...
then more importantly since it seems you want to use app directory, consider using something like:await audioPlayer .play(DeviceFileSource("directory/path to your song"));
just check out the getting started of the audioplayers library: [ [1]: https://github.com/bluefireteam/audioplayers/blob/main/getting_started.md][1]

Mac: Bundle not found in embedded Helper app

I have a Swift Package with shared code.
With Xcode's SPM added to my Xcode project.
Works great in the main app.
Doesn't work in the helper app when exported. Running the helper app in Xcode itself works fine. But when running as an exported and signed app it doesn't work.
This error message was found in console:
Fatal error: unable to find bundle named MySwiftPackageName: file MySwiftPackageName/resource_bundle_accessor.swift, line 27
I double checked, the package is really added at
Build Phase -> Link Binary With Libraries
When I inspect the exported main app and helper app I found the package in the main resources folder but not in the helper app resources folder.
How can I fix this?
In the Swift Package Manager the use of Bundle changes a bit, when you compile the source or open up Xcode a autogenerated code is available to you, which is Bundle.module.
The Bundle.module code is fairly simple and should resolve the issue, it is used like this.
SwiftUI
Image("ImageName", bundle: Bundle.module)
UIKit
UIImage(named: "ImageName", in: .module, with: nil)

Eclipse IDE 2020‑03 Debugger is doing weird stuff

So I am stuck with a problem when debugging with the most recent version of Eclipse 2020-03, which I installed for a new project I'm working on.
It first struck me that things were not working correctly when I couldn't read a resource with Class.getResource( String name ), as the debugger at the breakpoint in getResource(..) kept telling me that the name was null, while I definitely had provided a path name.
Clearing, cleaning, reloading the target (Running Platform), refreshing and rebuilding did not change anything, so I decided to create a simple OSGI plugin project with just an Activator, and a debug configuration with only the bare minimum bundles.
The Activator looks like this:
public class Activator implements BundleActivator {
public static final String BUNDLE_ID = "test.myapp.core";
private static BundleContext context;
private Logger logger = Logger.getLogger(this.getClass().getName());
static BundleContext getContext() {
return context;
}
public Activator() {
super();
logger.info("STARTED: " + BUNDLE_ID);
}
#Override
public void start(BundleContext bundleContext) throws Exception {
logger.info("ACTIVATED: " + BUNDLE_ID);
Activator.context = bundleContext;
InputStream in = getClass().getResourceAsStream( "/test.cfg" );
}
#Override
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
}
}
EDIT: Changed the original link to build.properties to test.cfg in order to avoid confusion.
But when I start the debugger, it will activate the bundle, but will not show any of the log messages. Also the debugger will not respond to the breakpoints I put in. Strangely enough, selecting 'ss' shows me far more bundles than the ones provided in the debug configuration.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.15.200.v20200214-1600
1 ACTIVE test.myapp.core_1.0.0.qualifier
2 ACTIVE org.apache.lucene.core.source_8.4.1.v20200122-1459
3 ACTIVE javax.annotation.source_1.2.0.v201602091430
....
It seems as if a different debug configuration is launched, and is using an previously built version of my bundle, where the log messages were not yet included. clearing the bin folder, and eventually all the metadata also had no effect.
I'm totally stumped as of what I'm experiencing here. Hopefully someone can help!
Well..as it seems, I found out what was wrong. There were two problems that were occuring all at once:
1: Regarding the problems with getResource( String name). The Bundle-ClassPath setting in Manifest.MF MUST include . (see https://www.eclipse.org/forums/index.php/t/287184/), so in my case:
Bundle-ClassPath: .,
test.myapp.core
Bundle-ClassPath is not added automatically by the plugin wizards, so that can cause some problems.
2: The Debug configuration screen in the new IDE seems to be very slow, and does not change the selected bundles if you switch from "only show selected" and back. As a result, the previous list of bundles remained active, while they were unchecked in the Debug Configuration Editor.
I'll file a report for these issues
ADDITIONAL
So I have made some further investigations on the Bundle-ClassPath issue, and what probably has happened that this entry in the Manifest.MF occured when adding some libraries. After they were removed again, the Bundle-ClassPath entry remained, and caused all sorts of problems. If you ever:
1: Notice that certain classes from bundle A cause a NoClassDefFound exception when used in bundle B
2: The build.properties file from bundle A give a warning that sources are missing
3: Other bundles don't seem to give that problem
Check to see if there is a Bundle-ClassPath entry in your Manifest.MF file. Most probably that entry is causing the problems. Either remove the entry in the manifest, or add ,. at the end.
see:
1: What is the intended use case for Bundle-Classpath in OSGI bundles
2: https://bugs.eclipse.org/bugs/show_bug.cgi?id=139271

DllNotFoundException in unity3d plugin for c++ dll

I am working on the Unity Plugin project and try to import the c++ native dll from c# file.
But I keep getting dllnotfoundexception.
c++ dll code:
extern "C" {
extern __declspec( dllexport ) bool IGP_IsActivated();
}
c# code:
[DllImport("mydll")]
private static extern bool IGP_IsActivated();
Dll is in place and FIle.Exists work properly. All dependent dlls are present at same hierarchy, but I still end up in dllnotfound exception.
Any help, much appreciated!!
Thanks to this Unity forum post I came up with a nice solution which modifies the PATH-environment variable at runtime:
Put all DLLs (both the DLLs which Unity interfaces with and their dependent DLLs) in Project\Assets\Wherever\Works\Best\Plugins.
Put the following static constructor into a class which uses the plugin:
static MyClassWhichUsesPlugin() // static Constructor
{
var currentPath = Environment.GetEnvironmentVariable("PATH",
EnvironmentVariableTarget.Process);
#if UNITY_EDITOR_32
var dllPath = Application.dataPath
+ Path.DirectorySeparatorChar + "SomePath"
+ Path.DirectorySeparatorChar + "Plugins"
+ Path.DirectorySeparatorChar + "x86";
#elif UNITY_EDITOR_64
var dllPath = Application.dataPath
+ Path.DirectorySeparatorChar + "SomePath"
+ Path.DirectorySeparatorChar + "Plugins"
+ Path.DirectorySeparatorChar + "x86_64";
#else // Player
var dllPath = Application.dataPath
+ Path.DirectorySeparatorChar + "Plugins";
#endif
if (currentPath != null && currentPath.Contains(dllPath) == false)
Environment.SetEnvironmentVariable("PATH", currentPath + Path.PathSeparator
+ dllPath, EnvironmentVariableTarget.Process);
}
Add [InitializeOnLoad] to the class to make sure that the constructor is run at editor launch:
[InitializeOnLoad]
public class MyClassWhichUsesPlugin
{
...
static MyClassWhichUsesPlugin() // static Constructor
{
...
}
}
With this script there is no need to copy around DLLs. The Unity editor finds them in the Assets/.../Plugins/...-folder and the executable finds them in ..._Data/Plugins-directory (where they get automatically copied when building).
Well I got it working.
For others who may face this problem, if you have more than one dll, you need to put the secondary dlls at root level of the Unity editor (e.g. C:\Program Files\Unity\Editor) and the actual referenced dll from script into plugins folder.
This worked for me.
Put the DLL(s) Unity interfaces with in Project\Assets\Wherever\Works\Best\Plugins.
Place any dependency DLLs that are not directly accessed by your scripts in Project. This will allow your program to run in the editor.
When you build, again copy the dependency DLL files, this time to the root of the build directory (right next to the generated executable). This should allow your application to load them at runtime.
(Tip: you can use Dependency Walker look at you DLLs and see what they depends on.)
I spent one day with this error. My issue was that Android doesn't get the library and always get and DDLNotFound error. My solution was:
1.- Be sure that you have the libraries for the proper architecture in the Plugins folder.
Plugins/Android/x86 and Plugins/Android/armeabi-v7a if your build settings is FAT(x86&arm)
2.- Check that Unity recognizes them as libraries. If you select them in the Project tab you should see them as a library and the platform and architecture related.
3.- After the build (don't close Unity Editor!), you can check in the Temp/StagingArea/libs if your libraries are there. If there are there for sure the libraries are going to be in the APK. As a double check, you can open your APK (change to zip extension) and see the libraries in the lib folder.
4.- In C# you should remove any lib prefix in your library name, for example:
If your library name is "libdosomething.so" you should call it as
[DllImport ("dosomething")]
I hope this work for you :)
Cheers.
Make sure the following chacklist is satisfied:
Plugins should all stay in a folder called Plugins.
The architecture your dll is built for (x86 or x86_64) must correspond to the architecture version of Unity Editor. Unity Editor 32-bit will not load 64 bit plugins and viceversa.
If you are targeting both 32 and 64 bit architectures you should put your dlls in special named folders inside the Plugins folder. The names are Plugins/x86 for 32 bit dlls and Plugins/x86_64 (x64 also works) for 64 bit dlls.
Visual C++ Redistributables must be installed. I have all from 2008.
When you build all your dlls should be copied into the root where your executable is (and again built for the correct x86/x64 architecture)
If you keep getting a namespace error it means the dll you are importing has unmanaged code and it must be wrapped into another managed dll Pugin in order to work.
These threads are a bit outdated but still relevant
DLLNotFoundException - Unity3D Plugin
Unity internal compiler error with custom dll
In my case, I have DllNotFoundException: ovrplatiformloader
Unity : DllNotFoundException: ovrplatformloader
Unity : at (wrapper managed-to-native) Oculus.Platform.CAPI.ovr_UnityInitWrapperAsynchronous(string)
Unity : at Oculus.Platform.AndroidPlatform.AsyncInitialize (System.String appId) [0x00013] in <29065e843b82403894fca6c6f2974090>:0
Unity : at Oculus.Platform.Core.AsyncInitialize (System.String appId) [0x0004f] in <29065e843b82403894fca6c6f2974090>:0
Unity : at DBHelper.Start () [0x00019] in <29065e843b82403894fca6c6f2974090>:0
My solution is:
Re-import files that doesn't work (libovrplatformloader.so)
Reconstruct the Platform/Plugins architecture. Old: Platform/Plugins/Android32/libovrplatformloader.so. New: Platform/Plugins/Android/x86/libovrplatformloader.so and Platform/Plugins/Android/armeabi-v7a/libovrplatformloader.so
Modify the import setting of libovrplatformloader.so. Change any platform to only Android platform and enable 'load on startup' selection. Choose ARMv7 CPU in armeabit-v7a while choose x86 CPU in x86 folder.
just put the dlls under Plugins folder and that works for me
I was having the same issue, and the solutions described here didn't work.
I think my case was a little different.
I think that the .dll I was importing depended on other .dll files. So I imported the other files related to that .dll (which I thought were unnecessary since I am not calling them directly on c# code) and that solved the issue.