Error when downloading AssetBundle from external server during runtime - c#

I'm trying to download a 3d model with AssetBundle during runtime from an external Server.
I created an assetBundle then I uploaded the AssetBundle file to an external Server.
Below is the code:
// Use this for initialization
void Start() {
StartCoroutine("DownloadObject");
}
IEnumerator DownloadObject() {
WWW www = WWW.LoadFromCacheOrDownload("http://infinitodesign.net/amir/dog", 1); //Download from server
yield return www;
if(www != null) {
Debug.Log("wwww is empty");
}
AssetBundle bundle = www.assetBundle;//Get the AssetBundle
AssetBundleRequest request = bundle.LoadAssetAsync<GameObject>("dog");
yield return request;
GameObject dog = request.asset as GameObject;
Instantiate<GameObject>(dog);
}
When I run in Unity i discover that www is empty

Related

assetBundle Returns null

I am downloading assetBundle from server using UnityWebRequest and it is working good in unity editor but in andriod it gives null value can someone help
public IEnumerator DownloadAsset(string url, string assetName)
{
using (UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(url))
{
yield return www.SendWebRequest();
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
if (bundle != null)
{
AGUIMisc.ShowToast("Not Null");
GameObject temp = bundle.LoadAsset(assetName) as GameObject;
var newobjj = Instantiate(temp);
newobjj.transform.parent = maleparent.transform;
}
else
{
AGUIMisc.ShowToast("Null");
}
}
}
Target-platform Android:
The AssetBundles need to be built in the target-platform where they are going to be used at later.
Since you want to use the AssetBundles in Android, the target-platform should also be Android when you build your AssetBundles.
Please also check:
You should set UnityWebRequest.downloadHandler first before call UnityWebRequest.SendWebRequest() to use DownloadHandlerAssetBundle.
public System.Collections.IEnumerator DownloadAsset(string url, string assetName)
{
using (var uwr = new UnityEngine.Networking.UnityWebRequest(url, UnityEngine.Networking.UnityWebRequest.kHttpVerbGET))
{
uwr.downloadHandler = new UnityEngine.Networking.DownloadHandlerAssetBundle(url, 0);
yield return uwr.SendWebRequest();
AssetBundle bundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(uwr);
if (bundle != null)
{
AGUIMisc.ShowToast("Not Null");
GameObject temp = bundle.LoadAsset<GameObject>(assetName);
var newobj = GameObject.Instantiate(temp);
newobj.transform.parent = maleparent.transform;
}
else
{
AGUIMisc.ShowToast("Null");
}
}
}

How to Load assetBundle from android local folder?

I'm trying to Load AssetBunddle form Android Folder from in Unity.
but it doesn't work...
I thought URL is wrong.
Changed URL many time, recommended or specification of Unity document but every case failed
Here is My Code.
public string BundleURL;
public int version;
void Start()
{
CleanCache();
BundleURL = "file://"+Application.persistentDataPath + " /BundleTest";
StartCoroutine(LoadAssetBundle(BundleURL));
version = 0;
}
I thought BundleURL is wrong or has problem
IEnumerator LoadAssetBundle(string BundleURL)
{
//BundleURL = "file://" + path ;
GameObject obj;
//ARLog.d ("LoadAssetBundle" + BundleURL);
while (!Caching.ready)
yield return null;
using (WWW www = WWW.LoadFromCacheOrDownload(BundleURL, version))
{
yield return www;
AssetBundle bundle = www.assetBundle;
String[] mPath = bundle.GetAllAssetNames();
String bundleName = null;
if (bundleName != null)
{
AssetBundleRequest request = bundle.LoadAssetAsync(bundleName, typeof(GameObject));
yield return request;
obj = Instantiate(request.asset) as GameObject;
bundle.Unload(false);
www.Dispose();
}
}
}
}
I want Instance Model in my Scene(from BundelTest Folder in Androind)
You have an additional space there in
BundleURL = "file://"+Application.persistentDataPath + " /BundleTest";
in " /BundleTest"!
For paths in general you allways rather should use Path.Combine instead of manually concatenating strings:
BundleURL = Path.Combine(Application.persistentDataPath,"BundleTest");
this makes sure that in the resulting path automatically the correct path separator (/ or \) for the according atrget system is used.
Than note that WWW is obsolete and not that fast &rightarrow; you should have a look at AssetBundle.LoadFromFileAsync there is an example of how to use it
public void IEnumerator LoadBundle()
{
var bundleLoadRequest = AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, "BundleTest"));
yield return bundleLoadRequest;
var myLoadedAssetBundle = bundleLoadRequest.assetBundle;
if (myLoadedAssetBundle == null)
{
Debug.Log("Failed to load AssetBundle!");
yield break;
}
var assetLoadRequest = myLoadedAssetBundle.LoadAssetAsync<GameObject>("MyObject");
yield return assetLoadRequest;
GameObject prefab = assetLoadRequest.asset as GameObject;
Instantiate(prefab);
myLoadedAssetBundle.Unload(false);
}
If you prefer synchronous loading checkout AssetBundle.LoadFromFile instead.
Another note in general: if you are using
using (WWW www = WWW.LoadFromCacheOrDownload(BundleURL, version))
{
....
}
you don't have to use Dispose as it is disposed at the and of the using block automatically.

How to download image from firebase database, and load it into image in unity

I use Firebase Realtime database to handle some of the UI in my Unity mobile application. I save and retrieve data from my database without any problems.
The problem comes when i want to load an image from Firebase Storage.
I have saved the URL's and names of the images' on my server, and now i try to Instantiate a prefab.
This prefab contains a panel with text and an image for each Firebase-child.
The structure of the image i try to load from my database looks like this:
So in my code I go to the child "Byer", find the first name and add the key as the name of my newly instantiated prefab works fine. But when I try to load the imageURL into the image, I get the trouble - my code looks like this:
DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
FirebaseDatabase.DefaultInstance.GetReference("Byer").ChildAdded += Handle_ChildAdded;
void Handle_ChildAdded(object sender, ChildChangedEventArgs e)
{
if (e.Snapshot.Value != null)
{
var dict = e.Snapshot.Value as Dictionary<string, object>;
Transform scrollViewObj = Instantiate(prefab, new Vector3(0, (downSize * Global.citiesCount) - firstY, 0), Quaternion.identity);
scrollViewObj.transform.Find("Text").gameObject.GetComponent<Text>().text = e.Snapshot.Key;
scrollViewObj.name = e.Snapshot.Key;
//HERE I TRY TO LOAD IMAGE FROM URL (This is my problem)
string data_URL = dict["ImageURL"] as string;
//Start coroutine to download image
StartCoroutine(AccessURL(data_URL, scrollViewObj.transform.Find("Image").gameObject.GetComponent<Image>()));
}
}
//Function to download (This could might also be my problem)
IEnumerator AccessURL(string url, Image img)
{
//Debug.Log("Accessing texture URL in database");
using (WWW www = new WWW(url))
{
yield return www;
Renderer r = GetComponent<Renderer>();
r.material.mainTexture = www.texture;
img.material.mainTexture = www.texture;
Debug.Log("Texture URL: " + www.url);
}
}
Can anyone see what I am doing wrong?
Make sure you imported FirebaseStorage.unitypackage
You will need StorageReference not DatabaseReference
Firebase.Storage.StorageReference storageReference =
Firebase.Storage.FirebaseStorage.DefaultInstance.GetReferenceFromUrl("storage_url");
storageReference.Child("resource_name").GetBytesAsync(1024*1024).
ContinueWith((System.Threading.Tasks.Task<byte[]> task) =>
{
if (task.IsFaulted || task.IsCanceled)
{
Debug.Log(task.Exception.ToString());
}
else
{
byte[] fileContents = task.Result;
Texture2D texture = new Texture2D(1, 1);
texture.LoadImage(fileContents);
//if you need sprite for SpriteRenderer or Image
Sprite sprite = Sprite.Create(texture, new Rect(0.0f, 0.0f,texture.width,
texture.height), new Vector2(0.5f, 0.5f), 100.0f);
Debug.Log("Finished downloading!");
}
});
storage_url: Found in firebase->storage section. will be something like gs://project_name.appspot.com/
resource_name : Name of a resource like image_name.png

How to access file saved on server and local?

I'm working on an iOS app on Unity. Eventually, the app should be able to download, import and load .obj files saved on my website server. But I'm currently developing locally so the files are saved in my laptop file system (local server side of my website).
My question is what I should use to access those files. I used WWW to access it but it seems not working. Please see my code below.
public void OnClick()
{
StartCoroutine(ImportObject());
}
IEnumerator ImportObject (){
Debug.Log("being called");
WWW www = new WWW("http://localhost:8080/src/server/uploads/user-id/file name");
Debug.Log("being called");
yield return www;
Debug.Log("NOT BEING CALLED !");
**//Everything below here seems not being called...**
if (string.IsNullOrEmpty(www.error)) {
Debug.Log("Download Error");
} else {
string write_path = Application.dataPath + "/Objects/";
System.IO.File.WriteAllBytes(write_path, www.bytes);
Debug.Log("Success!");
}
GameObject spawnedPrefab;
Mesh importedMesh = objImporter.ImportFile(Application.dataPath + "/Objects/");
spawnedPrefab = Instantiate(emptyPrefabWithMeshRenderer);
spawnedPrefab.transform.position = new Vector3(0, 0, 0);
spawnedPrefab.GetComponent<MeshFilter>().mesh = importedMesh;
}
I tried multiple solutions from the internet and finally find the correct method to download and save the file by using the code below:
IEnumerator DownloadFile(string url) {
var docName = url.Split('/').Last();
var uwr = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
string modelSavePath = Path.Combine(Application.dataPath, "Objects");
modelSavePath = Path.Combine(modelSavePath, docName);
//Create Directory if it does not exist
if (!Directory.Exists(Path.GetDirectoryName(modelSavePath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(modelSavePath));
}
var dh = new DownloadHandlerFile(modelSavePath);
dh.removeFileOnAbort = true;
uwr.downloadHandler = dh;
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
Debug.LogError(uwr.error);
else
Debug.Log("File successfully downloaded and saved to " + modelSavePath);
}

You are using download over http. Currently Unity adds NSAllowsArbitraryLoads to Info.plist to simplify transition, but it will be removed soon [duplicate]

This question already has an answer here:
You are using download over http. Currently Unity adds NSAllowsArbitraryLoads to Info.plist to simplify transition
(1 answer)
Closed 4 years ago.
I am uploading data to database using WWW.
I have two data classes for data object.
[Serializable]
public class pushdatawrapper{
public string email;
public pushdata[] shotsArray=new pushdata[1];
}
[Serializable]
public class pushdata{
public string timehappened;
public string clubtype;
public pushdata(string timestamp_,string clubtype_)
{
timehappened = timestamp_;
clubtype = clubtype_;
}
}
Loading Json array of data object to database, I tried two approaches.
The first one was ok, but the second one is always failed at calling StartCoroutine function.
First approach
public class BLEBridge : MonoBehaviour {
void Start () {
pushdata_ pdata = new pushdata_("123123123123.0","15","123.0","123.0", "123.0", "123.0","123.0", "123.0","123.0","123.0","123.0","123.0", "First");
pushdatawrapper_ pw = new pushdatawrapper_ ();
pw.email = "test#gmail.com";
pw.shotsArray[0] = pdata;
StartCoroutine (PushData_ (pw));
}
private IEnumerator PushData_(pushdatawrapper_ pdata){
WWW www;
Hashtable postHeader = new Hashtable();
postHeader.Add("Content-Type", "application/json");
string dataToJason = JsonUtility.ToJson(pdata);
Debug.Log ("dataToJason " + dataToJason);
// convert json string to byte
var formData = System.Text.Encoding.UTF8.GetBytes(dataToJason);
www = new WWW("http://rmotion.rapsodo.com/api/push/new", formData, postHeader);
StartCoroutine(WaitForRequest(www));
return www;
}
IEnumerator WaitForRequest(WWW data)
{
yield return data; // Wait until the download is done
if (data.error != null)
{
Debug.Log("There was an error sending request: " + data.text);
}
else
{
Debug.Log("WWW Request: " + data.text);
}
}
}
This first method is always ok.
But in actual implementation, I need to upload data from a static function. Those private IEnumerator PushData_(pushdatawrapper_ pdata) and IEnumerator WaitForRequest(WWW data) can't be static.
So what I did was
I made a separate class as
public class UploadData: MonoBehaviour{
public void uploadindividualshot(pushdatawrapper pw){
StartCoroutine (PushData (pw));
}
private IEnumerator PushData(pushdatawrapper pdata){
WWW www;
Hashtable postHeader = new Hashtable();
postHeader.Add("Content-Type", "application/json");
string dataToJason = JsonUtility.ToJson(pdata);
Debug.Log ("dataToJason " + dataToJason);
// convert json string to byte
var formData = System.Text.Encoding.UTF8.GetBytes(dataToJason);
Debug.Log ("before www ");
www = new WWW("http://rmotion.rapsodo.com/api/push/new", formData, postHeader);
Debug.Log ("after new ");
StartCoroutine(WaitForRequest(www));
Debug.Log ("after WaitForRequest ");
return www;
}
IEnumerator WaitForRequest(WWW data)
{
Debug.Log ("start pushing ");
yield return data; // Wait until the download is done
if (data.error != null)
{
Debug.Log("There was an error sending request: " + data.text);
}
else
{
Debug.Log("WWW Request: " + data.text);
}
}
}
Then call the instance of the class from static method as
public class BLEBridge : MonoBehaviour {
void Start(){}
public unsafe static void GetGolfREsult()
{
pushdata pdata = new pushdata("123123123123.0","15","123.0","123.0", "123.0", "123.0","123.0", "123.0","123.0","123.0","123.0","123.0", "First");
pushdatawrapper pw = new pushdatawrapper();
pw.email = Login.loginName;
pw.shotsArray[0] = pdata;
UploadData up = new UploadData ();
up.uploadindividualshot (pw);
}
}
I always have error as
after new
UploadData:PushData(pushdatawrapper)
BLEBridge:GetGolfREsult()
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
libc++abi.dylib: terminating with uncaught exception of type Il2CppExceptionWrapper
2018-04-29 17:25:25.565292+0800 RMotion[270:7241] You are using download over http. Currently Unity adds NSAllowsArbitraryLoads to Info.plist to simplify transition, but it will be removed soon. Please consider updating to https.
The program has error at StartCoroutine(WaitForRequest(www));
What is wrong with second approach?
In unity calling this line of code automatically start http request
WWW www = new WWW("url");
yield is just the convenience way to tell the coroutine to wait for the process to finish. Don't separate your calls in 2 IEnumerator.
private IEnumerator PushData_(pushdatawrapper_ pdata){
WWW www;
Hashtable postHeader = new Hashtable();
postHeader.Add("Content-Type", "application/json");
string dataToJason = JsonUtility.ToJson(pdata);
Debug.Log ("dataToJason " + dataToJason);
// convert json string to byte
var formData = System.Text.Encoding.UTF8.GetBytes(dataToJason);
www = new WWW("http://rmotion.rapsodo.com/api/push/new", formData, postHeader)
Debug.Log ("start pushing ");
yield return www; // Wait until the download is done
if (www.error != null)
{
Debug.Log("There was an error sending request: " + www.text);
}
else
{
Debug.Log("WWW Request: " + www.text);
}
}
And I don't see any use of pointer in your static method so why did you use the unsafe keyword?

Categories