write / add / rewrite a class at runtime c# unity - c#

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.

Related

Can't load Mono.CSharp.dll in either Unity3D or a C# project

I'm working on an online video game project using Unity3D for the clients, and C# servers.
I'm trying to use some code eval for a specific feature, but I can't get it to work.
I went with Mono, because it seemed to be one of the lightest and one of the simplest. I installed Mono and got the "Mono.CSharp.dll" for .Net 4.6 from "Mono\lib\mono\4.6-api". (Both Unity and my servers are configured to use this version of .Net). I dropped it in the Unity assets, and referenced it on my servers.
But I have errors on both Unity and the servers. In Unity there is :
Loading script assembly "Assets/Scripts/Common/References/Mono.CSharp.dll" failed!
And there is an exception on the servers (my IDE is in French so I can't really copy/paste it), but it basically tells me it can't use Reference Assemblies for build, but only for reflection.
To describe the feature I want to create (because you'll maybe have a better solution), I want to be able to create spells from an external tool. Spells are made of SpellEffects. Let's say there is a SpellEffect called DealDamage, constructor takes an int (for the damage amount). I want to be able to write "DealDamage(50)" on my external tool, then take the string, and build a new DealDamage(50) from it.
I know I could find a way to interpret some code by myself, but it would be a lot more work for a far less flexible system.
It was really hard to find any help online for this problem, so as a last hope I'm turning to you.
I'm not exactly sure why you're trying to import Mono into Unity. It's already included in the installation package. If you want to make a modular spell builder, just create a regular application with your preferred language, in your preferred IDE, and save all of your spells as a JSON or XML file, and then import those into Unity. On the Unity side, just build a class to parse the files.
To get you started, take a look at the JSON.Net library. You can serialize your files into C# classes with it.

Compare Xamarin.Android CPL localization techniques (.xml .po .mo .resx .xlf)

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

C#.NET & Translation of external component

I'm maintaining one program written in C# 2.0 (VS2005). It has pretty large codebase, lot of authors, it is almost internal app, but currently it is also one of our customers using it.
App is multilingual and translation of own forms and components works OK. But, there is one component - DockPanel Suite by WeifenLuo and I need to translate it to another language (zh-CN) - one of the chinese guys translated resource file to his language and now I'm trying to include and use in application, but I'm failing in it - although whole app is in chinese, this component remains in english. The untranslated resource file can be found on github: https://github.com/dockpanelsuite/dockpanelsuite/blob/master/WinFormsUI/Docking/Strings.resx
How to do that? I tried almost everything, naive approach (just resgen and compile by al, and trying to use it as satellite assembly - also tried ilmerge), then opening DockPanelSuite in VS2013 Express, adding resx as Strings.zh-CN.resx, but nothing works and tooltips and others are still in english.
Tried also stepping-in with debugger, but debugger broke at tooltip = Strings.DockPaneCaption_ToolTipAutoHide but it didn't step into getter defined in Strings.Designer.cs
I'm stuck and I don't know, how to do that. Any idea? Thanks very much!
I was able to translate a label in the demo application in a very simple process:
git clone the library
Copy & paste the Strings.resx file
Rename the copy into Strings.pt-BR.resx
Compile, it's done (in my case, I translated the "Close" label)
however, this project contains many Strings.resx files
Did you change all of them? Or did you just change one? (maybe a wrong one, like I did in my first try)

Configuring PCL project with a JSON file

I'm currently designing a cross-plateform application in Visual Studio 2013 using a Portable Class Library.
At startup, I want to have a certain object, created by deserializing a JSON file. This object will be used to configure certain resources in my project (e.g. certain button names, etc.).
I know how to parse the JSON file using Json.NET and to create the wanted object.
What I don't know is how to use it, and especially, where must it be generated? I don't think this JSON reading part could (and should) be added to the PCL, for the file reading part at least.
Thanks in advance (I hope this isn't a duplicate!)

How do you embed app.config in C# projects?

When you compile a C# project, the app settings from app.config are saved along with the exe file. For example, if the program name is "solve_np.exe", there will be a "solve_np.exe.config" next to it, making it look less neat than I want it to. How can you embed it into the .exe?
I tried to set Build Action to Embed Resource, but that did not do the trick.
Aha. I guess you're falling foul of Visual Studio automatically placing stuff in configuration that you DONT want configured by the end user.
In this case use resources. Simply add a new file of type .resx. With this you'll be able to add things like strings and images to the resource file. After you build this it should provide static access to the resources (it typically generates a code file from the resources for you so you don't have to access ResourceManager yourself).
E.G. If I made resources.resx with a string called MyConfigValue after a build I should be able to access this like:
textBox.Text = Resources.MyConfigValue;
If you want values that are kinda variable but shouldn't be configurable then this is the right place to put them.
HTH.
It isn't unprofessional to have an app.config file shipped alongside your exe. I think the word you may be looking for is untidy. I personally don't find this is the case myself however everyone is different! Perhaps you could simply make the app.config file hidden by default?
Or another alternative is to create your own config file which you could save to the App Data folder or even storing the settings in the registry instead.
Here's another factor to consider. Seasoned .Net developers are accustomed to the standard application design, which incorporates using config files in both web apps and desktop apps. If you depart from that practice, you will make it more difficult for any developers who follow you to understand what you have done. Even sa's on the web server may be confused by the absence of a config file.
Since pretty much everybody does it this way, your code does not look "untidy" to others. On the contrary, it would be befuddling not to see a config file where one is expected.
Typically the theory of a configuration file, is that it stores settings you may want to change once you've deployed the application (for something like user preferences). To do this, you need to be storing somewhere external to your application. If you use the default setup, you get "[Your].exe.config". There are many other options you could look at, but nearly every one of them ends up with a file written somewhere, if you providing a mechanism that saves settings of some kind.
I agree with serhio darasd and Quibblesome but you can just delete "solve_np.exe.config" and it'll just use default configs.
After considering what was written in these comments and other searching, I decided that the best way to handle my issue of wanting my Entity Framework connection string to be embedded into my executable instead of needing the MyApplication.exe.config file with my deployed solution was to created a derived class like such:
Public Class MyEFDataContainerLocal
Inherits MyEFDataContainer
Public Sub New()
MyBase.New(My.Settings.MyEFContainerConnectionString)
End Sub
End Class
I just created an Application Setting of type Connection String that contained the same string as what is found in the App.Config file. I just had to replace the &quote;'s with actual quotes.
Then whenever I wanted to use the MyEFDataContainer as in Dim db As New MyEFDataContainer I would just use Dim db As New MyEFDataContainerLocal instead.

Categories

Resources