I'm new to the Monogame content pipeline tool, as opposed to XNA which would do the compiling you need on itself. So I may be having a pretty simple problem I fail to see a solution for. Here's my XML file:
<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:ns="Microsoft.Xna.Framework">
<Asset Type="Game1.Screens.SplashScreen">
<SplashScreen>
<Path>Images/Image1</Path>
</SplashScreen>
</Asset>
</XnaContent>
So I'm not entirely sure as of what <Asset Type="..."> wants as a value, but the debugger tells me there's an error there:
Could not resolve type 'Game1.Screens.SplashScreen'. So it's a simple tutorial I was watching:
The Tutorial
There the person decided to teach on how to use XML serialization. So he was using XNA but most of this code should work on Monogame as well. Anyway, what he did was, add a new XML file to a folder, outside of the Content.RootDiretory and added his XML file in there. Since I've never released a project with Monogame yet, so correct me if I am wrong, but won't that XML file that's set to Copy always to output directory be user-viewable/editable? Or will it be compressed into XNB? Or perhaps it won't be even presented there? So that is the problem's root, now let's see the top:
Being unable to answer to myself whether the XML file will actually be presented in the final product's Content directory, I decided to use the Content pipeline tool and add the above XML file from there as I was sure that it would be converted into XNB. But now I get this error. And I don't know where am I wrong? Should I set the file's build action from the default Build to Copy the error disappears, but the XML file will be in my Content directory instead of the XNB one. Please advice.
Here's some more information about the SplashScreen class:
It inherits from another class, GameScreen.
It is inside the Screens, folder inside the project's folder. That's why I tried to use Game1.Screens.SplashScreen, where Game1 is the name of my project.
Thanks in advance!
Your intuition is correct. The tutorial's version would have to ship the game with the xml file. But the Xna content pipeline can build it into a binary file for shipping your game and the runtime content pipeline can load it into your game.
when it loads it into your game, it needs to know what class the data will fit into so it can plug the data into an instance of that class
Class MyGameInitialConfiguration
{
public string path;
/*
other possible game settings can be added too
public float heroPower;
public string badGuyName;
*/
}
//then in the xml file
<asset type=MyGameInitialConfiguration>
Now, since the first thing the build process does when you hit run is build the assests (convert the fbx into xnb and the images into xnb and your xml into xnb), in needs to know what a "MyGameInitialConfiguration" is before you hit run... but if you add this class to the game project, it wont build the class until after it needs it and you will get an error.
So you actaully have to add an additional project to your solution to hold this class and make your game project and content project dependent on it so it is the first project to build. Then by the time the game project runs, it is aware of what a "MyGameInitialConfiguration" is and can load date into it.
Obviously, you can access that class instance from your game code and pull "path" from it.
Here is the end all for XNA knowledege: http://www.shawnhargreaves.com/blogindex.html
In particular, this blog: http://blogs.msdn.com/b/shawnhar/archive/2009/03/25/automatic-xnb-serialization-in-xna-game-studio-3-1.aspx
thank you for this question, took me back so many years. the Xna content pipeline was awesome.
Related
I have inherited an Xamarin Crossplatform project, (Android only,) that had a 'strings.xml' file with some button-names in it.
Need to find a way to add more languages easily and convert code-strings to translatable too (>300+), not just component-Texts.
I've tried many things so far, but nothing worked as expected: [*]
( Most of the examples and help are for Xamarin.Forms only. )
1.) installed ResX manager
it did not recognized my XML files
created .resx files manually, but those have nothing to do with existing xml-translations
could not get back those texts from C# code I've inserted at the manager window
2.) created a second strings.xml >> placed into values-hu folder >> copied XML content >> translated inside the XML.
It works only for buttons in the IDE placed into the activity
can NOT get text with GetText(...,...) from my C# code because it needs an (int)...I don't know how to generate and pair with my own constants
Resources.Strings... does not pop up any of my own string either
whenever I try to add a new element at the IDE,
I have to search and copy manually the new lines to each XML one by one
there is no "translator window" for them like ResX
can not group strings inside the XML file
3.) installed Multilingual App Toolkit 4.0
seems to be just a different file format than .resx, but same problems
complained about not connected to Azure
offered me a "new english" translation from my original english XML
could not add NEW lines, etc.
4.) installed POEdit + Nuget>GetText
at first sight this seemed to be the perfect solution, but
PoEdit has found only 4 strings in my .cs files
( preferences' I/O strings with GetText() method to read from my config.xml )
could not import string.xml files to translate for 3. lang.
do not understand the .po > .mo conversion concept
installed the nuGet GetText > but no new sub-menu appeared anywhere inside VS.
5.) upgraded to VS2017
6.) asked on a local forum, but nobody answered.
7.) Searched through ca 100 topics here >> ... most of them are about Xamarin Forms ... but those seems to be invalid for droid.
[*] by expected I've imagined having a simple wizard where I can:
go through each string in my *.cs files, where I can give a constant name and it's converting "Really Exit" > to: _tr(Res.Main.really_exit)
or mark to skip
should have a manager to easy translate (like ResX), or ADD new lines!
having both component-texts and code-string inside ONE(/ language?) file
possibly group strings by activity / logic. (So translators can see where is what)
... but nothing seems to be able to handle strings.xml files and .cs file-string all in one easily.
So... Now I am totally confused. I've spent a whole week to see some kind of "order" in this chaos, but could not find a proper writing that explains, WHAT METHOD should someone use to do things easily for droid translation and why? Thank you!
I would go with your second approach because it uses the Android build-in localization system. A benefit of using it is that it already has a fallback-solution included, if a language or a key for one language could not be found.
You can use it in your layout files:
<Button
android:text="#string/LogOn_Login"
or inside code:
var progressDialog = new ProgressDialog(this);
progressDialog.Indeterminate = true;
progressDialog.SetCancelable(false);
progressDialog.SetMessage(GetString(Resource.String.LogOn_ProgressMessage));
But you need to know the difference between an Activity and a Fragment.
In an Activity you just need to call GetString(). Which requires an int, that you get from Resource.String.YOUR_KEY. But in a Fragment you have to give the context. The call changes to Activity.GetString().
New languages or strings can easily added. I usually add new string to the strings.xml inside values-folder first. That way I make sure I have the fallback ready. A new string has the following semantics:
<string name="KEY">VALUE</string>
Filled with real data:
<string name="LogOn_ProgressMessage">Authenticating...</string>
After saving the strings.xml file, it turns out to be good to rebuild the project to make sure the Resource.designer.cs is updated. I sometimes saw the behavior that otherwise my newly added keys where not accessible with Resource.Strings.
When it comes to editing the strings.xml, I am with you that there is no "translator window" and that you have to copy each new key to all supported languages. To overcome this issue we build us a tool that creates all those files for use on every build. This way we support a quite large app with more than 21 languages.
With Xamarin I would go down the .Resx files route. string.xml files are an Android solution and don't fit very well into the .NET world.
How to localize your code is nicely explained here:
https://developer.xamarin.com/guides/xamarin-forms/advanced/localization/
And with Reshaper you can extract all the strings from your code:
https://www.jetbrains.com/resharper/features/internationalization.html
Yes, you will have to convert your XML files. In what format are they? You might be able to use this tool:
http://converter.webtranslateit.com/
To use .NET Resource files inside your Library, you have to add the resources to your project first and configure them like below:
Now you can use them for example like this:
BillManagement.ResourceManager.GetString("TaxSetupWrong")
Or
LibraryName.Resources.BillManagement.TaxSetupWrong
in my project i have some sort of level builder that create a new text file and save all my wanted data as readable json string in 1 line.
while the project run in web build or in unity it self i can read the levels from that text file and every thing working great, in mobile builds that doesn't work.
my question is:
is there a way to create or add lines to a class at runtime?
for example write a new string in the class at run time that will stay there after run time is over?
No, there isn't. At least not at mobile platforms.
But you should be able to parse JSON on mobile platforms if you set the Api Compatibility Level to .Net 2.0, not .Net 2.0 Subset and disable Strip Engine Code in the Player Setting.
As #Tijmen said there is no way to change a C# class at runtime. But I see no reason to do so. Instead you should change the JSON string, write it to the file and recreate the level instance.
Looking at your code reveals that you are writing to Application.dataPath which is not writable in iOS player. So it should work when your are using Application.persistentDataPath.
Further on I would refrain from calling the folder Resources as this has a special meaning in Unity.
No there isn't, but you can make an ArrayList instead and put the info from the text file into the ArrayList. Then extract information from the ArrayList.
at first I would like to try to explain my plan: Sometimes I just have to change some static values in my code (lets say, the path to a folder with data my program needs or the url to upload something) and after that I have to compile again. If lets say the url is changed where I want to upload the files and the url is like I said static in my code - well I have to change it in Visual Studio and compile it again...and again and again. Well thats why I think this is NOT a good idea. It would be better to make a config file (a file where I can store all my values/information that I need) and read this file every time my program is starting. Now I could make changes without compiling - I just have to edit my config file.
I thought I choose the XML format, I could take an normal textfile, but I think an XML is more secure and easier to read if it gets complex. Now there is maybe one problem with this: I have to 'hardcode' the path to my XML file. I think I will never change the path to the config file, but what if I would? Then I have to change the path in my code again. Is there maybe a smarter solution for this?
The next step would be that I have to read the XML file on every startup. Now I would like to know what is the best OOP solution to get the information and use it? I thought I make a class (lets say Myconfig) and in this class I have only final variables (I think final is readonly in c#) with getter and setter. I will create a new Myconfig on every startup and I will parse the XML file - while Im parsing and getting the information Im using the setter to save the information in the class variable. After Im done I have an object with all the information and now I could send/use this object everywhere to get these information (let say with Myconfig.Url , Myconfig.Path ...).
Well thats my plan :-) Im really new to this, Im sure this is not perfect. Any suggestions?
use a configuration file with the ConfigurationManager class to access values in it. .NET has already provided this solution for you - there is no reason for you to write one yourself.
I'm writing a MapEditor in winform with embeded XNA.
And my biggest problem is whenever I try to load any file with the ContentManager, it only reads .XNB files.
I wanted to read an effect file like this:
effect = contentManager.Load<Effect>("Effect2");
But then I get the error that "Effect2.xnb doesn't exists".
And if I add "Effect2.fx" it still give me error with the message "Effect2.fx.xnb doesn't exists" :\
I have no idea what to do.
I saw a solution by set the content properties. But I cannot set those properties in this case,because it's a winform application.
Does anyone have a great idea or anything?
Edit!
Solution found!
I implemented the ContentBuilder from this example with writing a few helper methods for dynamic loading: http://create.msdn.com/en-US/education/catalog/sample/winforms_series_2
You'll have to add an XNA Content project, and include your content in that project. All of those files will be compiled/processed into individual XNB files, which you'll be able to load. Just make sure to reference that project in your WinForms project.
The same rules apply for a Game project: It still needs an accompanying Content project.
EDIT:
Ahh, right... you want to load them dynamically. For that, you'll need to ensure that any computer that tries to use your map editor will have the XNA development framework installed. Then you'll need to process the files manually before loading them with the ContentManager... not entirely sure how to do this.
EDIT:
Take a look at this post for more information about loading unprocessed content at runtime: How do I load a texture in XNA at runtime?
What is the advantage of adding XML files to a visual studio 2008 project (windows form app project for example).
Once added to the project, how could I refer to this XML to use it in a class in the same project? In this case, I would be sending it as a query to a web service.
If you want to use the XML in some form, you could mark it as a "embedded resource" in the properties window, and then access it from your code like so:
Assembly a = Assembly.GetExecutingAssembly();
if(a != null)
{
Stream s = a.GetManifestResourceStream(typeof(yourType), "YourXmlName.xml");
if (s != null)
{
String xmlContents = new StreamReader(s).ReadToEnd();
}
}
Once you're done, you have the XML file's contents in "xmlContents", if all goes well.
Marc
I guess the advantage of having your XML reside there in your project (or solution even) is that you can maintain it in VS with nice formatting and even intelli-sense, but then using something like XML Spy or whatever can give you that too.
To refer to it in a class you'll need to ensure you have access to it, and that it resides in a reliable place.
In the past I've used post build events to move the latest copy of the file to where I need it. As Arnshea writes here is another answer, "to the output directory". You can use the "Copy to Output directory" property on the XML file itself to achieve this. Then your classes can use the XML file, knowing it will reside in a reliable place.
You'll need to make sure it's accessible though especially if you're writing back to it. Make sure it doesn't end up "Read Only" - as Source Control system could do to you. Storing these files in a folder under Program Files could also be problematic especially on Vista, where user privileges are (should be) restricted.
If your app needs to load the XML it can be copied to the output directory. Also simplifies use of Setup/Deployment projects...
Another major advantage would be (assuming it's in place--and it should be!) is that you can apply revision control to the XML file.
I guess that you won't be sending the same XML file to the WebService over and over again.
You will want to modify its content every time for that you have XML Serialization.
If all of the above apply then you don't need the XML file, you just need the class that generates the file at runtime. The XML is just the transport, today its XML and tomorrow it might be some other format (JSON).