How To Load A Local File as an AssetBundle with WWW - c#

So I have been trying to make it possible for users to load a .obj file and read it as an AssetBundle, but I can't figure it out.
I have figured out how to get the path of the file, but I can't load it as an asset bundle, it just returns null.
Here is my code :
WWW bundleRequest = new WWW(#"file://" + pathName);
while (!bundleRequest.isDone)
{
yield return null;
}
AssetBundle bundle = null;
if (bundleRequest.bytesDownloaded > 0)
{
AssetBundleCreateRequest myRequest = AssetBundle.LoadFromMemoryAsync(bundleRequest.bytes);
while (!myRequest.isDone)
{
Debug.Log("loading....");
yield return null;
}
if (myRequest.assetBundle != null)
{
bundle = myRequest.assetBundle;
GameObject model = null;
if (bundle != null)
{
AssetBundleRequest newRequest = bundle.LoadAssetAsync<GameObject>("Test");
while (!newRequest.isDone)
{
Debug.Log("loading ASSET....");
yield return null;
}
model = (GameObject)newRequest.asset;
bundle.Unload(false);
}
}
else
{
Debug.LogError("COULDN'T DOWNLOAD ASSET BUNDLE FROM URL");
}
}
else
{
Debug.LogError("COULDN'T DOWNLOAD ASSET BUNDLE FROM URL");
}
pathName here is: "C:\\Users\\mySuperCoolName\\OneDrive\\Documents\\Fun\\Programming\\Ungoing projects\\ThiefCop\\Unity Mobile\\Assets\\Prefabs\\TestOBJ.obj". Everything seems to work until AssetBundleCreateRequest when AssetBundle.LoadFromMemoryAsync() is called, where myRequest.assetBundle == null even if the file was downloaded correctly.
I also get an error which probably is linked with my problem : I have searched for what it meant but I couldn't find...
It is really hard to explain what I mean, but I really hope you can find an answer to this, I've been searching for hours and between us, I don't understand much of File loadind and Reading... Don't hesitate to ask if you didn't understand my bad english... Thank you in advance :)

https://docs.unity3d.com/ScriptReference/BuildPipeline.BuildAssetBundles.html
To be short :
Import your object in Unity
Give it a AssetBundle name (click on it then on bottom of the inspector view)
Call this function

for load obj files directly to you project, you need todo code what unpacks object file and then converts it to the Unity engine.
in assert store look at the Runtime OBJ Importer,
this should be right direction for your issue.
https://assetstore.unity.com/packages/tools/modeling/runtime-obj-importer-49547

Related

Unity Android load local MP3 or WAV as AudioClip

I'm able to load audio using UnityWebRequestMultimedia.GetAudioClip in the Unity Editor with the following code but when I run it on Android I am unable to load any files from the user's device.
void Start() {
audio = GetComponent<AudioSource>();
string fullPath = Path.Combine("file://" + previewSong);
StartCoroutine(GetAudioClip(fullPath));
}
IEnumerator GetAudioClip(string fullPath)
{
using (var uwr = UnityWebRequestMultimedia.GetAudioClip(fullPath, AudioType.MPEG))
{
((DownloadHandlerAudioClip)uwr.downloadHandler).streamAudio = true;
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
debugSongPath2.text = uwr.error;
yield break;
}
DownloadHandlerAudioClip dlHandler = (DownloadHandlerAudioClip)uwr.downloadHandler;
if (dlHandler.isDone)
{
audio.clip = dlHandler.audioClip;
if (audio.clip != null)
{
audio.clip = DownloadHandlerAudioClip.GetContent(uwr);
Debug.Log("Playing song using Audio Source!");
}
else
{
Debug.Log("Couldn't find a valid AudioClip.");
}
}
else
{
Debug.Log("The download process is not completely finished.");
}
}
}
The errors I experience vary depending on how I form the start of the URL.
Path.Combine("file:/" + previewSong);
malformed URL
Path.Combine("file://" + previewSong);
http:/1.1 404 not found
Path.Combine("file:///" + previewSong);
unknown error
Path.Combine("file:////" + previewSong);
unknown error
When I output the URLs on my phone they look correct. Here's an example path:
file:///storage/emulated/0/Music/Deorro/Deorro - Five Hours.mp3
I was previously loading audio from this URL successfully with WWW.GetAudioClip but that's obsolete. This leads me to believe the URL is correct. I've tried building with and without Development Mode. Not sure what else to try. I'd like to get this working with UnityWebRequestMultimedia but if there is an alternative, more effective way of loading local files I'm open to it.
Change your build settings to give write access to external sd card. I am using below code to get audio from specified location in android. I tried your code but somehow its not working.
IEnumerator GetAudioClip2(string fullPath)
{
debugSongPath2.text = previewSong;
using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(fullPath, AudioType.MPEG))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
AudioClip myClip = DownloadHandlerAudioClip.GetContent(www);
audioSource.clip = myClip;
audioSource.Play();
}
}
}
My full path was "file:///storage/emulated/0/Samsung/Music/Over the Horizon.mp3"
The issue was with the new Android 11 scoped storage which disables READ_EXTERNAL_STORAGE. I had to add the following to my AndroidManifest.xml:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android 10 or higher. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
https://developer.android.com/training/data-storage/use-cases#opt-out-scoped-storage

Downloaded Json File, not Working after Building the Game

Good Day Community,
Im Working on a silly drinking game since a few weeks. Its all fine and dandy. Worked my way through all my ideas and got it done. I was pretty proud of my self. Now hereĀ“s the kicker. The game downloads a Json file from my Nextcloud using www in Unity. The Json Holds all the Game_Cards. It worked Really well in Unity, But after i build the game, Its just doing nothing. Im pretty Sure im missing something here. But i have no Clue how to Debug it. And to be frank, i think i have Workblindness on this one. I hope its a simple fix.
What i think is going on Maybe:
Download works Fine but Json file is saved to wrong or inaccesible Path
Download is not Working at all.
Card Path:
cardPath = Application.dataPath + "/Saves/cards.json";
Download Method
IEnumerator Cards()
{
UnityWebRequest www = new UnityWebRequest("https://my.link.wich/nobody/should/know");
www.downloadHandler = new DownloadHandlerBuffer();
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.LogError(www.error);
}
else
{
string downloadedText = www.downloadHandler.text;
File.WriteAllText(cardPath, downloadedText);
ReadCards();
}
}
Reading Cards from Json
public void ReadCards()
{
string cardFile = File.ReadAllText(cardPath);
cardDatabase = JsonUtility.FromJson<CardListObject>(cardFile);
}
First time using StackOverflow an actually posting something. Be kind on me :D
Update
Got it Working!
I had to create the Folder first.
cardPath = Application.persistentDataPath + "/Saves/cards.json";
if (!System.IO.Directory.Exists(Application.persistentDataPath + "/Saves"))
{
System.IO.Directory.CreateDirectory(Application.persistentDataPath + "/Saves");
}
In build, you need to use Application.persistentDataPath not Application.dataPath
UPD: My bad, you are reading only if downloading. So you can ignore next part.
You need to do something in your ReadCards method in case the file does not exists, because you can have a download error and file will not be created.
For example:
public void ReadCards()
{
if (!System.IO.File.Exists(cardPath) return;
string cardFile = File.ReadAllText(cardPath);
cardDatabase = JsonUtility.FromJson<CardListObject>(cardFile);
}
Then your cardDatabase will stay with default values and you will not have a FileNotFoundException.

How to get hash from Unity AssetBundle to check cache?

I am newbie in AssetBundle and try to learn about this. Currently, I can load the asset from the server, but I cannot get hash from the asset file itself. It's keeping return NullException.
I have tried follow the doc here:
https://docs.unity3d.com/ScriptReference/Caching.html
But still have no idea, and get the NullException at Hash too.
Found this as well and no luck:
How to get AssetBundleManifest from AssetBundle in Unity3D
Then I tried follow the instruction in this post:
Get Hash128 from AssetBundle for the Caching.IsVersionCached function
But still get NullException()
Here is the code I follow the latest link:
IEnumerator DownloadAssetBundle()
{
UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle("https://www.dropbox.com/s/66psd4aphlgpo2j/testasset?dl=1");
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
AssetBundleRequest asset = bundle.LoadAssetAsync<AssetBundleManifest>("assetManifestName");
yield return asset;
//Get the AssetBundleManifest
AssetBundleManifest loadedAssetMf = asset.asset as AssetBundleManifest;
//Get Hash128 from the AssetBundleManifest
Hash128 tempHash128 = loadedAssetMf.GetAssetBundleHash("");
//Pass to the IsVersionCached function
Caching.IsVersionCached("https://www.dropbox.com/s/66psd4aphlgpo2j/testasset?dl=1", tempHash128);
//Instantiate(bundle.LoadAsset("RayBan_Sunglasses"));
}
}
Could anyone explain how to get the Hash from assetBundle what I have done wrong?
The file name of my Asset Bundle is "testasset"
If you please, specify where to put the "testasset", it would be a pleasure. Thank you so much for every answer.
the asset bundle manifest you need is stored at the platform bundle that has the same name as the folder that its inside according to this page,
first you need to load the asset bundle of the platform and then you get the the asset bundle manifest object from it, from that manifest you will be able to get the hash code
private IEnumerator LoadAssetBundleManifest(string uri)
{
using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle(uri))
{
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log(uwr.error);
}
else
{
// Get downloaded asset bundle
bundleManifest = DownloadHandlerAssetBundle.GetContent(uwr);
AssetBundleManifest testManifst = bundleManifest.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
Debug.Log(testManifst.GetAssetBundleHash("bundlename").ToString());
}
}
}

Vimeo: Get download link from API

I've Vimeo PRO and I'm trying to get the download link so the end user can download the video source. However, the lack of documentation makes it really hard to figure that out.
I'm trying VimeoDotNet but I cannot authenticate, I'm doing the following:
var client = new VimeoClientFactory().GetVimeoClient(key, secret)
var downloadLink = client.GetVideo(video_id).download;
However, the call to GetVideo throws an error saying I have to authenticate first, but I don't see how!
I've also tried with another VimeoClient, but it doesn't seem to implement the download link part.
Can anyone help? Or better yet, share a working example. Thanks.
After 2 days I was finally able to do it, I'll share what I did in case someone needs it. First, download this library:
https://github.com/saeedafshari/VimeoDotNet3
Open in Visual Studio and compile it. It's pretty simple so it compiled right away.
Then reference that compiled DLL from your project and do the following:
var VimeoClient3 = Vimeo.VimeoClient.ReAuthorize(_vimeoAccessToken,
_vimeoAppConsumerKey, _vimeoAppClientSecret);
// videoId is the ID of the video as in the public URL (eg, 123874983)
var result = VimeoClient3.Request("/videos/" + videoId, null, "GET");
if (result == null)
{
throw new Exception("Video not found.");
}
if (result["download"] == null)
{
throw new Exception("Download link not available.");
}
foreach (var item in (ArrayList)result["download"])
{
var downloadLinkInfo = item as Dictionary<string, object>;
if (downloadLinkInfo == null) continue;
// For example, get the link for SD quality.
// As of today, Vimeo was returning an HD quality and a 'mobile' one
// that is for streaming.
if (string.Equals((downloadLinkInfo["quality"] as string), "sd", StringComparison.InvariantCultureIgnoreCase))
{
return downloadLinkInfo["link"] as string;
}
}

C# Unity3D JSON Hanging

Firstly I must point out that I am very new to C#.
I am developing an application using Unity3D, and part of the application requires that I parse a JSON file stored on my server.
The problem that I am having is that sometimes everything works perfectly, and other times the app hangs on the downloading the JSON. I don't receive any errors, the script just never reaches 100% on the progress.
Here is my code:
public IEnumerator DownloadJSONFile(string url)
{
Debug.Log("JSON URL: "+ url);
mJsonInfo = new WWW(url);
yield return mJsonInfo;
mIsJSONRequested = true;
}
private void LoadJSONData(string jsonUrl)
{
Debug.LogWarning("LoadJSONData, url= "+jsonUrl);
if(!mIsJSONRequested){
StartCoroutine(DownloadJSONFile(jsonUrl));
} else {
if(mJsonInfo.progress >= 1)
{
if(mJsonInfo.error == null )
{
//** PARSE THE JSON HERE **//
}else
{
Debug.LogError("Error downloading JSON");
mIsLoadingData = false;
}
} else {
Debug.LogWarning("!! ### JSON DOWNLOADING: "+mJsonInfo.progress+"%");
if(mJsonInfo.error != null )
{
Debug.LogError("Error downloading JSON");
Debug.LogError("JSON Error:"+mJsonInfo.error);
mIsLoadingData = false;
}
}
}
}
Like I said, 50% of the time the JSON data gets loaded nearly instantly, and 50% of the time the progress never reaches 1. I never receive an error in form the mJsonInfo.error variable.
Any suggestions as to what I am doing wrong would be greatly appreciated!
You need to wait until the download is complete.
As stated in the documentation you need to:
var www = new WWW(...);
yield return www;
So you need to modify the return type of your method from void to IEnumerator.
private IEnumerator LoadJSONData(string jsonUrl)
{
Debug.LogWarning("LoadJSONData, url= "+jsonUrl);
if(!mIsJSONRequested)
{
// Gets the json book info from the url
mJsonInfo = new WWW(jsonUrl);
yield return mJsonInfo; //Wait for download to complete
mIsJSONRequested = true;
}
else
{
...
}
}
isDone is that you need,
WWW lWWW = new WWW(...)
if(lWWW.isDone)
then parse it
I found the problem, I thought I would post my solution for anyone else experiencing the same problem.
The solution in the end was the JSON file on the server. I was using PHP (CakePHP) to generate the JSON, when opening the PHP generated file via the browser the response time was instant, but from my mobile app for some reason it would hang. So I changed my server side code to actually create and updated an actual JSON file, and now everything works fine.

Categories

Resources