如何下载 AssetBundle 并将其保存在设备中
How to Download an AssetBundle and then save it in the device
我正在使用 LoadFromCacheOrDownload 函数,我只是不确定如何才能从 unity 内部下载资产包,然后将资产包加载到设备中的本地。谢谢!这是我目前使用的代码:
using UnityEngine.UI;
using System;
public class LoadScenes : MonoBehaviour
{
public string sceneAssetBundle;
public string sceneName;
public string sName;
public string bName;
public string BundleURL;
public int version;
public int downloaded = 0;
IEnumerator Start() {
if (downloaded == 0){
using (WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)) {
yield return www;
if (www.error != null)
throw new Exception ("WWW download had an error:" + www.error);
if (www.error == null) {
AssetBundle bundle = www.assetBundle;
}
}
if (Caching.ready == true) {
downloaded = 1;
yield return InitializeLevelAsync (sceneName, true);
}
}
}
public void getScene(string sName){
sceneName = sName;
}
public void getBundle(string bName){
sceneAssetBundle = bName;
}
public IEnumerator InitializeLevelAsync (string levelName, bool isAdditive)
{
// This is simply to get the elapsed time for this phase of AssetLoading.
float startTime = Time.realtimeSinceStartup;
// Load level from assetBundle.
AssetBundleLoadOperation request = AssetBundleManager.LoadLevelAsync(sceneAssetBundle, levelName, isAdditive);
if (request == null)
yield break;
yield return StartCoroutine(request);
// Calculate and display the elapsed time.
float elapsedTime = Time.realtimeSinceStartup - startTime;
Debug.Log("Finished loading scene " + levelName + " in " + elapsedTime + " seconds" );
}
}
您应该使用 PlayerPrefs
了解资产何时下载,在尝试再次下载之前检查它是否已下载。这是一个例子
if (PlayerPrefs.GetInt("AssetLoaded", 0) == 0)
{
//Save that we have down loaded Asset
PlayerPrefs.SetInt("AssetLoaded", 1);
Debug.Log("Asset has NOT been downloaded. Downloading....");
//DOWNLOAD ASSET HERE
//.......
}
else
{
Debug.Log("Asset already loaded. Can't download it again!");
}
将其与您问题中的代码合并:
IEnumerator Start() {
if (PlayerPrefs.GetInt("AssetLoaded", 0) == 0){
Debug.Log("Asset has NOT been downloaded. Downloading....");
using (WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)) {
yield return www;
if (www.error != null)
throw new Exception ("WWW download had an error:" + www.error);
if (www.error == null) {
AssetBundle bundle = www.assetBundle;
}
}
if (Caching.ready == true) {
downloaded = 1;
//Save that we have down loaded Asset
PlayerPrefs.SetInt("AssetLoaded", 1);
yield return InitializeLevelAsync (sceneName, true);
}
}else
{
Debug.Log("Asset already loaded. Can't download it again! Loading it instead");
yield return InitializeLevelAsync (sceneName, true);
}
}
要重置它,只需调用 PlayerPrefs.DeleteKey("AssetLoaded");
。
我认为您不想使用 LoadFromCacheOrDownload 函数,因为显然它会将您想要下载的任何内容保存在缓存内存中,这是您不想要的,因为该内存只能加载而不能通过代码。
对我来说最好的解决方案是使用 WebClient。
它是如何工作的?
- 您必须导入 C# System.Net 库(使用 System.Net;)
由于下载文件不是立竿见影的事情,你必须使用协程,它可以让你等到文件下载完成。
如何在代码中下载 AssetBundle 或任何文件
using System.Collections;
using UnityEngine;
using System;
using System.Net; //Most important Library
public class DownloadClass: MonoBehaviour
{
//Your URL path
string url = "https://yourUrl.com/fileName.extension";
//Create a WebRequest instance
Uri uri = new Uri(url);
//Create a Client instance to download the WebRequest
WebClient client = new WebClient();
//Suscribe to the event ProgressChanged
client.DownloadProgressChanged += Client_DownloadProgressChanged;
//Create your coroutine to download your AssetBundle or any file (mp3, jpeg, etc)
public IEnumerator DownLoadAsset()
{
//Start download and specify the save path
client.DownloadFileAsync(uri, Application.persistentDataPath + "/yourPath/fileName");
while(client.IsBusy) // Wait until the file download is complete
yield return null;
//Now your file is completely downloaded and saved
}
//Create your ProgressChanged "Listener"
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
//Show download progress
Debug.Log("Download Progress: " + e.ProgressPercentage);
}
}
如何在代码中加载 AssetBundle 或任何文件
using System.Collections;
using UnityEngine;
using System;
public class LoadClass : MonoBehaviour
{
//Variable to hold the asset bundle
private AssetBundle bundle;
public void LoadAsset()
{
//Check to load the bundle only once
if (bundle != null)
bundle.Unload(true);
//Load an AssetBundle in a specific path
bundle = AssetBundle.LoadFromFile(Application.persistentDataPath + "/yourPath/fileName");
//Your file is Now loaded, you can access to your data
}
}
如何在代码中删除 AssetBundle 或任何文件
using System.Collections;
using UnityEngine;
using System;
using System.IO; //Most important Library
public class DeleteClass : MonoBehaviour
{
public void DeleteAsset()
{
//If the file exits, Delete the file
if (File.Exists(Application.persistentDataPath + "/yourPath/fileName"))
File.Delete(Application.persistentDataPath + "/yourPath/fileName");
//Your file was delete from memory
}
}
我希望这个解决方案对你有用。
我正在使用 LoadFromCacheOrDownload 函数,我只是不确定如何才能从 unity 内部下载资产包,然后将资产包加载到设备中的本地。谢谢!这是我目前使用的代码:
using UnityEngine.UI;
using System;
public class LoadScenes : MonoBehaviour
{
public string sceneAssetBundle;
public string sceneName;
public string sName;
public string bName;
public string BundleURL;
public int version;
public int downloaded = 0;
IEnumerator Start() {
if (downloaded == 0){
using (WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)) {
yield return www;
if (www.error != null)
throw new Exception ("WWW download had an error:" + www.error);
if (www.error == null) {
AssetBundle bundle = www.assetBundle;
}
}
if (Caching.ready == true) {
downloaded = 1;
yield return InitializeLevelAsync (sceneName, true);
}
}
}
public void getScene(string sName){
sceneName = sName;
}
public void getBundle(string bName){
sceneAssetBundle = bName;
}
public IEnumerator InitializeLevelAsync (string levelName, bool isAdditive)
{
// This is simply to get the elapsed time for this phase of AssetLoading.
float startTime = Time.realtimeSinceStartup;
// Load level from assetBundle.
AssetBundleLoadOperation request = AssetBundleManager.LoadLevelAsync(sceneAssetBundle, levelName, isAdditive);
if (request == null)
yield break;
yield return StartCoroutine(request);
// Calculate and display the elapsed time.
float elapsedTime = Time.realtimeSinceStartup - startTime;
Debug.Log("Finished loading scene " + levelName + " in " + elapsedTime + " seconds" );
}
}
您应该使用 PlayerPrefs
了解资产何时下载,在尝试再次下载之前检查它是否已下载。这是一个例子
if (PlayerPrefs.GetInt("AssetLoaded", 0) == 0)
{
//Save that we have down loaded Asset
PlayerPrefs.SetInt("AssetLoaded", 1);
Debug.Log("Asset has NOT been downloaded. Downloading....");
//DOWNLOAD ASSET HERE
//.......
}
else
{
Debug.Log("Asset already loaded. Can't download it again!");
}
将其与您问题中的代码合并:
IEnumerator Start() {
if (PlayerPrefs.GetInt("AssetLoaded", 0) == 0){
Debug.Log("Asset has NOT been downloaded. Downloading....");
using (WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)) {
yield return www;
if (www.error != null)
throw new Exception ("WWW download had an error:" + www.error);
if (www.error == null) {
AssetBundle bundle = www.assetBundle;
}
}
if (Caching.ready == true) {
downloaded = 1;
//Save that we have down loaded Asset
PlayerPrefs.SetInt("AssetLoaded", 1);
yield return InitializeLevelAsync (sceneName, true);
}
}else
{
Debug.Log("Asset already loaded. Can't download it again! Loading it instead");
yield return InitializeLevelAsync (sceneName, true);
}
}
要重置它,只需调用 PlayerPrefs.DeleteKey("AssetLoaded");
。
我认为您不想使用 LoadFromCacheOrDownload 函数,因为显然它会将您想要下载的任何内容保存在缓存内存中,这是您不想要的,因为该内存只能加载而不能通过代码。
对我来说最好的解决方案是使用 WebClient。
它是如何工作的?
- 您必须导入 C# System.Net 库(使用 System.Net;)
由于下载文件不是立竿见影的事情,你必须使用协程,它可以让你等到文件下载完成。
如何在代码中下载 AssetBundle 或任何文件
using System.Collections; using UnityEngine; using System; using System.Net; //Most important Library public class DownloadClass: MonoBehaviour { //Your URL path string url = "https://yourUrl.com/fileName.extension"; //Create a WebRequest instance Uri uri = new Uri(url); //Create a Client instance to download the WebRequest WebClient client = new WebClient(); //Suscribe to the event ProgressChanged client.DownloadProgressChanged += Client_DownloadProgressChanged; //Create your coroutine to download your AssetBundle or any file (mp3, jpeg, etc) public IEnumerator DownLoadAsset() { //Start download and specify the save path client.DownloadFileAsync(uri, Application.persistentDataPath + "/yourPath/fileName"); while(client.IsBusy) // Wait until the file download is complete yield return null; //Now your file is completely downloaded and saved } //Create your ProgressChanged "Listener" private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { //Show download progress Debug.Log("Download Progress: " + e.ProgressPercentage); } }
如何在代码中加载 AssetBundle 或任何文件
using System.Collections; using UnityEngine; using System; public class LoadClass : MonoBehaviour { //Variable to hold the asset bundle private AssetBundle bundle; public void LoadAsset() { //Check to load the bundle only once if (bundle != null) bundle.Unload(true); //Load an AssetBundle in a specific path bundle = AssetBundle.LoadFromFile(Application.persistentDataPath + "/yourPath/fileName"); //Your file is Now loaded, you can access to your data } }
如何在代码中删除 AssetBundle 或任何文件
using System.Collections; using UnityEngine; using System; using System.IO; //Most important Library public class DeleteClass : MonoBehaviour { public void DeleteAsset() { //If the file exits, Delete the file if (File.Exists(Application.persistentDataPath + "/yourPath/fileName")) File.Delete(Application.persistentDataPath + "/yourPath/fileName"); //Your file was delete from memory } }
我希望这个解决方案对你有用。