Grab the Enviroment.CurrentDirectory at the start of the app and stick it in front of that,
or use AppDomain.CurrentDomain.BaseDirectory
They are slightly different current directory can change or be changed like by a file dialog ect.
You can use Path.Combine(…) to concencate these paths and probably should also use Path.AltDirectorySeparatorChar ‘/’ or Path.DirectorySeparatorChar .
Thanks for your reply. I tried your suggestions but they didn’t work for me.
AppDomain.CurrentDomain.BaseDirectory returns null when you deploy for Android. It returns a valid path for Windows though.
Enviroment.CurrentDirectory returns ‘/’ for Android and the whole path for Windows.
So it seems these functions only work for Windows.
Just FYI, this is the whole code I had so far to load all the content automatically that works on Windows.
Thanks for your help.
Song song;
try
{
DirectoryInfo dir = new DirectoryInfo(theContentManager.RootDirectory + "/Music");
FileInfo[] files = dir.GetFiles("*.xnb");
foreach (FileInfo file in files)
{
string key = Path.GetFileNameWithoutExtension(file.Name);
song = theContentManager.Load<Song>("Music/" + key);
mSongList.Add(song);
}
}
catch (Exception)
{
}
Try TitleContainer.OpenStream on Android. I’ve never worked with it before, but try the same path you’re using now. The comments for the name parameter mention that it’s relative to the “title storage area,” which may be the Content folder on Android? Hopefully playing around with it a bit will get you to load your content.
You may try this solution which works on my end, first off, if you open your apk it’s a zip file you can open it on 7zip you will notice the the 3 directory in there res,lib and assets. working in MG on android you get the the content file information from it’s context assets and there a lot of method out there.
This will give you the list of all files you want in your particular content directory e:g:
var m_ListOfMusicFiles = Android.App.Application.Context.Assets.List(“Content/Music”);
Problem solved here? right ? ok…
But I don’t think it’s a good idea to load everything on a content directory path, specially if you have multiple levels. what you can do is to have a text file which describe all you files you wanted to load for a center level and with your implementation you cannot show LOADING STATUS to the end users, load that text file using TitleContainer.OpenStream.
Thanks so much! That works fine. And you are right, you kept me thinking and I agree it’s not a good idea to load everything from the beginning, especially because I have multiple levels.
Just one more thing, if I want to unload a specific song that has been loaded using
song = theContentManager.Load<Song>("Music/" + key);
There isn’t currently a way to unload a single item from a ContentManager to my knowledge. If you load the song from it and dispose it, the next time you load that same song, it’ll be unsuitable for use since it was already disposed and ContentManager will return that same reference, as it caches the objects it loads until you call Unload. You can try using multiple ContentManagers if you need to unload specific assets at specific times.
I was about to edit my last message to ask about that, because that’s the problem I was just facing!
Glad to see your answer.
Basically what I was just doing was to load the music for the level the player is playing, and disposing it after that.
If I don’t end up using multiple ContentManagers as you suggested, does it mean the memory will keep growing as the user moves through different levels? Maybe not a good idea?
In my engine I implemented 3 content manager content manager for the assets System Content manager assets that needs to stay the whole application life time, and Scene content manager that will be unload every level, and Self for big assets that needs to be dispose after usage. implment something like below:
But for simplicity you can just use TWO content manager to store your assets
__SystemContentMngr << Store all assets that will stay the whole apps lifetime eg. fonts etcc.
__SceneContenrMngr << Store all assets that you will only need the specific level
At the end of every level just unload only __SceneContentMngr.Unload() and load again another contents to __SceneContentMngr for the next level assets.
Sounds good. I will do that. I like your solution.
Just a quick question that I wasn’t able to find the right way. In order to create a new ContentManager, the constructor requires a serviceprovider. Should I pass Content.ServiceProvider from the main Game class or do I have another alternative? It’s just I don’t like to use a global variable for that so maybe there’s a better way of doing it.