I need to fetch the audioClip in the resources folder so as I understand I need to use Resources.Load<AudioClip>(path) or Resources.Load(path) as AudioClip but this just doesn't work, it doesn't even return a null it just stops the code
my code sample:
private void FetchAudioClipAndStartPlay(int userPos, int index)
{
AudioClip clip = Resources.Load($"Audio/Demo_ENG/D{userPos}a") as AudioClip;
Debug.Log("Starting Coroutine " + index);
StartCoroutine(PlayAudioClipAndStartRetrievingFromDatabase(index, clip));
}
IEnumerator PlayAudioClipAndStartRetrievingFromDatabase(int index, AudioClip clip)
{
Debug.Log("Starting to play " + index);
audioSource.PlayOneShot(clip, 1f);
yield return new WaitForSeconds(clip.length);
if (index < numberOfPlayers)
{
RetrieveFromDatabase(index++);
}
}
(it doesn't enter the coroutine)
All the audio files are .mp3
Any guidance and tips are very appreciated!
Unity does not support loading mp3 at runtime.
Unity does not recommend using the Resources folder:
Don't use it.
This strong recommendation is made for several reasons:
Use of the Resources folder makes fine-grained memory management more
difficult Improper use of Resources folders will increase application
startup time and the length of builds
As the number of Resources
folders increases, management of the Assets within those folders
becomes very difficult
The Resources system degrades a project's
ability to deliver custom content to specific platforms and
eliminates the possibility of incremental content upgrades
AssetBundle Variants are Unity's primary tool for adjusting content
on a per-device basis
Check this answer for a solution how to load audio files:
public void LoadSong()
{
StartCoroutine(LoadSongCoroutine());
}
IEnumerator LoadSongCoroutine()
{
string url = string.Format("file://{0}", path);
WWW www = new WWW(url);
yield return www;
song.clip = www.GetAudioClip(false, false);
songName = song.clip.name;
length = song.clip.length;
}
Related
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
I am creating an editor for a game using Unity game engine and I want to allow a designer to make new spells. What I am trying to achieve is that a designer will download a Unity particle system (or GameObject), save it on the computer and will give the game full path to it. Then the game should load the object and use it as a particle for a new spell.
I need to be able to load a Unity GameObject (particle system) during runtime from a folder. I tried it with Asset Bundles, but I don’t know how to use Asset Bundles when I only want to download the file from the computer (local file system) not from the server. Asset bundles work perfectly in Debug but not when I build and run it (It tries to connect to some server instead).
I use the default script for Asset Bundles:
public class LoadAssets : MonoBehaviour
public const string AssetBundlesOutputPath = "/AssetBundles/";
public string assetBundleName;
public string assetName;
public GameObject loadedObject;
public bool finished;
public MessageWindow messWindow;
// Use this for initialization
//originally was start here might create problems
public IEnumerator Begin ()
{
messWindow.changeMessageAndShow("Asset " + assetName + " is loading.","Loading");
yield return StartCoroutine(Initialize() );
// Load asset.
yield return StartCoroutine(InstantiateGameObjectAsync (assetBundleName, assetName) );
finished=true;
messWindow.Close();
}
public GameObject LoadObject()
{
StartCoroutine(Begin());
//TODO wait for end of couroutine
return loadedObject;
}
// Initialize the downloading url and AssetBundleManifest object.
protected IEnumerator Initialize()
{
// Don't destroy this gameObject as we depend on it to run the loading script.
DontDestroyOnLoad(gameObject);
// With this code, when in-editor or using a development builds: Always use the AssetBundle Server
// (This is very dependent on the production workflow of the project.
// Another approach would be to make this configurable in the standalone player.)
#if DEVELOPMENT_BUILD || UNITY_EDITOR
AssetBundleManager.SetDevelopmentAssetBundleServer ();
#else
// Use the following code if AssetBundles are embedded in the project for example via StreamingAssets folder etc:
// Or customize the URL based on your deployment or configuration
//AssetBundleManager.SetSourceAssetBundleURL("http://www.MyWebsite/MyAssetBundles");
#endif
AssetBundleManager.SetSourceAssetBundleURL(Application.dataPath + "/");
// Initialize AssetBundleManifest which loads the AssetBundleManifest object.
var request = AssetBundleManager.Initialize();
if (request != null)
yield return StartCoroutine(request);
}
protected IEnumerator InstantiateGameObjectAsync (string assetBundleName, string assetName)
{
// This is simply to get the elapsed time for this phase of AssetLoading.
float startTime = Time.realtimeSinceStartup;
// Load asset from assetBundle.
AssetBundleLoadAssetOperation request = AssetBundleManager.LoadAssetAsync(assetBundleName, assetName, typeof(GameObject) );
if (request == null)
yield break;
yield return StartCoroutine(request);
// Get the asset.
GameObject prefab = request.GetAsset<GameObject> ();
if (prefab != null)
{
loadedObject = GameObject.Instantiate(prefab);
DontDestroyOnLoad(loadedObject);
}
// Calculate and display the elapsed time.
float elapsedTime = Time.realtimeSinceStartup - startTime;
Debug.Log(assetName + (prefab == null ? " was not" : " was")+ " loaded successfully in " + elapsedTime + " seconds" );
}
}
Thank you so much.
To load Asset bundle from local system you need Local AssetBundle Server. When Local Asset Server is enabled, AssetBundles must be built and placed in a folder explicitly called AssetBundles in the root of the Project, which is on the same level as the Assets folder.
The built AssetBundles will be available to the Editor and all builds running locally that can reach the Editor on the local network.
Use Assets>AssetBundles>Local AssetBundle Server to enable the Local AssetBundle Server.
Reference to asset bundles and asset bundle manager.
I am using the AssetBundleManager API in my unity 5.3 project.
My set-up: I have two scenes. One main scene and another scene that will be loaded as a multi scene into the main scene, which works fine in the editor right now.
Now I wanted to built my main scene to my android device, but when I click on the load level button, nothing happens. I already made a built of my assetbundle which is placed in the AssetBundles folder of my root. This is what I read in the documentations and what should be right?
What am I missing, do I need to put the assetbundle files anywhere else?
I am using this script, which I got from the example of the AssetBundleManager Plugin.
using UnityEngine;
using System.Collections;
using AssetBundles;
using UnityEngine.SceneManagement;
public class LoadScenes : MonoBehaviour
{
public string sceneAssetBundle;
public string sceneName;
public bool load;
public bool destroy;
string curLevel;
// Use this for initialization
IEnumerator Start ()
{
yield return StartCoroutine(Initialize() );
// Load level.
//yield return StartCoroutine(InitializeLevelAsync (sceneName, true) );
}
void Update(){
if (load) {
load = false;
// Load level.
StartCoroutine(InitializeLevelAsync (sceneName, true) );
}
if (destroy) {
destroy = false;
SceneManager.UnloadScene(sceneName);
}
}
public void loadLevel(string level){
curLevel = level;
StartCoroutine (InitializeLevelAsync (level, true));
}
public void unloadLevel(){
SceneManager.UnloadScene(curLevel);
}
// Initialize the downloading url and AssetBundleManifest object.
protected IEnumerator Initialize()
{
// Don't destroy this gameObject as we depend on it to run the loading script.
DontDestroyOnLoad(gameObject);
// With this code, when in-editor or using a development builds: Always use the AssetBundle Server
// (This is very dependent on the production workflow of the project.
// Another approach would be to make this configurable in the standalone player.)
#if DEVELOPMENT_BUILD || UNITY_EDITOR
AssetBundleManager.SetDevelopmentAssetBundleServer ();
#else
// Use the following code if AssetBundles are embedded in the project for example via StreamingAssets folder etc:
AssetBundleManager.SetSourceAssetBundleURL(Application.dataPath + "/");
// Or customize the URL based on your deployment or configuration
//AssetBundleManager.SetSourceAssetBundleURL("http://www.MyWebsite/MyAssetBundles");
#endif
// Initialize AssetBundleManifest which loads the AssetBundleManifest object.
var request = AssetBundleManager.Initialize();
if (request != null)
yield return StartCoroutine(request);
}
protected 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" );
}
}
Instead of using:
AssetBundleManager.SetSourceAssetBundleURL(Application.dataPath + "/");
Try using Application.persistentDataPath, hopefully that'll solve the problem.
Link to the manual.
You will have to set the datapath to your folder where the assetbundle is, i.e myassetbundle.unity3d
For example:-
AssetBundleManager.SetSourceAssetBundleURL(Application.dataPath +
"file:////D:\ptech-user\Documents\assetbundle3\Assets\Assets\AssetBundle
");
I am trying to allow the user to Import a song using a file browser Add on from the unity store. Currently I am trying to just play the song in the menu, just to see if I have loaded it correctly but it seems I cannot get past this stage. The WWW function makes no sense to me and I will need someone to explain it very simply. In my eyes this should open the file browser, the user then selects that file, then the selected file should be loaded into the audio clip. then the debug play button should play that audio clip, but from pausing the game I can see that the file browser finds the file and has the correct string but the audio is never assigned to the clip correctly. I am using .wav and .ogg files so no problem with formats.
public FileBrowser fb = new FileBrowser();
public bool toggleBrowser = true;
public string userAudio;
public AudioSource aSource;
public AudioListener aListener;
public AudioClip aClip;
void Start()
{
if (aSource == null)
{
aSource = gameObject.AddComponent<AudioSource>();
aListener = gameObject.AddComponent<AudioListener>();
}
}
void OnGUI()
{
// File browser, cancel returns to menu and select chooses music file to load
if (fb.draw())
{
if (fb.outputFile == null)
{
Application.LoadLevel("_WaveRider_Menu");
}
else
{
Debug.Log("Ouput File = \"" + fb.outputFile.ToString() + "\"");
// Taking the selected file and assigning it a string
userAudio = fb.outputFile.ToString();
}
}
}
public void playTrack()
{
//assigns the clip to the audio source and plays it
aSource.clip = aClip;
aSource.Play();
}
IEnumerator LoadFilePC(string filePath)
{
filePath = userAudio;
print("loading " + filePath);
//Loading the string file from the File browser
WWW www = new WWW("file:///" + filePath);
//create audio clip from the www
aClip = www.GetAudioClip(false);
while (!aClip.isReadyToPlay)
{
yield return www;
}
}
}
There are a few things that may be causing you some trouble.
I'm not sure how exactly the file browser add-on works, but in the code you posted the PlayTrack() function is never called, and the LoadFilePC coroutine is never started. Even if you're loading the file correctly, it's never being assigned to the AudioSource or playing.
Try adding "playTrack();" at the end of your coroutine, and starting it using the MonoBehaviour.StartCoroutine() function after the file is selected.
I am trying to load a scene but I am getting the error from title and I simply don't know why because I call Unload(false) on AssetBundle. Can someone help me? Thanks.
void Start() {
...
StartCoroutine (DownloadAndCache());
...
}
IEnumerator DownloadAndCache (){
// Wait for the Caching system to be ready
while (!Caching.ready)
yield return null;
// Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
using(WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)){
yield return www;
if (www.error != null)
throw new Exception("WWW download had an error:" + www.error);
AssetBundle bundle = www.assetBundle;
bundle.LoadAll();
AsyncOperation async = Application.LoadLevelAsync("main");
Debug.Log (async.progress);
yield return async;
bundle.Unload(false);
}
}
if you do not want to use Unload() function clear the cache after asset bundle is used:-
Caching.CleanCache();
And every things will work fine but you have to download the asset bundle every time as you clearing out the cache after bundle use.
Or you can do this way
First of all call DoNotDestroyOnLoad() (for keeping the reference through out) function in Start() function and make a static variable to store a reference of the asset bundle when you use WWW.LoadFromCacheOrDownload to download the asset,assign the reference to the static variable and unload the asset after its use. if you don not unload the asset bundle and use WWW.LoadFromCacheOrDownload again the same error will be thrown as you have stated.
Suppose if you loaded a scene using asset bundle then before quitting the scene unload the asset bundle reference stored in that static variable. That is why static variable is used so that we can access it from any script and unload it whenever we want also be careful about version.
class LoadScene:MonoBehaviour{
***public static AssetBundle refrenceOfAsset;***
private AssetBundle assetBundle;
void Start(){
***DoNotDestroyOnLoad(gameObject);*** }
protected IEnumerator LoadTheScene()
{
if (!Caching.IsVersionCached(url, version)){
WWW www = WWW.LoadFromCacheOrDownload(url, version);
yeild return www; assetBundle = www.assetBundle;
***refrenceOfAsset = assetBundle;***
www.Dispose();
// Do what ever you want to do with the asset bundle but do not for get to unload it
refrenceOfAsset.Unload(true);
}
}
else{
Debug.Log("Asset Already Cached...");
if(refrenceOfAsset!=null)
refrenceOfAsset.Unload(true);
}
}
or
or you can visit unity http://docs.unity3d.com/Manual/keepingtrackofloadedassetbundles.html