So I’ve been working on my first project for 3 years. About 1 year in I switched from JS to C#, but thought I’d be ok without converting my code at that point to C#.
Now I’m in a position where about 40% of the code base is in JS and I’m looking to switch it to C#. Its a large project, where there so many dependencies between JS and C# scripts. I’m having a hard time knowing what the best way to approach this is, given that my ability to test is diminished significantly once I start and everything breaks.
I could use any advice or pointers with what typically is the best way to approach things like this is.
Can’t you just convert one thing at a time? As long as you’re not changing interfaces or names it’s just a matter of converting the syntax. Do it one file at a time until the project compiles again, test the functionality relevant to that file, then move on to the next one.
You might also do some searching to see if anyone has made a syntax converter.
The issue is the dependencies between scripts, working with one script to the point where it compiles is one thing, but knowing that it works without first completing everything else is another. I’m just wondering what the best way to approach it is.
I think it’s not that easy.
You might have ScriptA, ScriptB and ScriptC in UnityScript. And some others in C#.
So at one point you must have decided which script language will be compiled first. As he started out in UnityScript, let’s say these will be compiled first.
Imagine ScriptB is now converted into C#, i.e. it compiles after UnityScript. But if ScriptA and/or ScriptC depend on ScriptB, it should fail to compile as ScriptB isn’t “known” at this point. Correct me if I’m wrong.
Anyway, that’d be rather a huge problem if the scripts were extremly tighly coupled. Otherwise you could always convert a few scripts at a time unless there are no language-based dependencies left.
Ah, yes, if that’s the issue then it would be more complex. I guess you’d need to find the ones with the least dependencies and start there. If your classes are tightly coupled enough that you have to convert most of them at the same time then I think you’re just going to have to bite the bullet and do it.
Rather than a straight conversion, another option is to just re-engineer the same functionality in C#, preferably without all of the dependencies where possible. This should allow you to do things in smaller pieces.
I’d start out by drawing a dependency graph. It might take some time, but it might indicate a few points where you can make the switch without breaking dependencies.
If your dependencies are one way, you may be able to convert pieice meal from one end. On the other hand any circular dependencies will have to done in a single hit.
This hinges on the fact that unity’s serialization/scene does not reference scripts by name, but rather by a uuid stored in the .meta for the script. So as long as we change everything and the .meta files line up, we’re good.
OK… so for starters, first back up your game. Just create a zip file of the entire project and put it aside (or commit to your version control and flag it… you ARE using version control right???)
OK, now go into your project settings and make sure that show .meta files is enabled. We want those out in the open in our folder structure moving forward (if you are using version control, this should already be done… since you should always show meta files when using version control).
Now, close Unity… don’t need it from now on.
Get a unityscript to C# converter, they exist out there. I find a lot of ‘online’ ones when I google. Just find one.
Now start up a new C# project in Visual Studio (or whatever IDE/language you prefer). Write a program that then goes through the Assets folder of your project, opens every *.js file, extracts the string, renames it to *.cs, renames the related *.js.meta file to *.cs.meta file, run the string through the converter, and overwrite the *.cs file with the output.
Run.
Reopen your project.
Let Unity do its thing.
If it works, YAY! If it failed… revert back to the previous version, and go the route like BoredMormon describes. Building out a dependency tree and converting one at a time in order.
Thanks for the suggestions folks. I’ve went the route of the dependency graph and working through in isolated chunks.
The .meta trick is pretty clever, unfortunately the converters I’ve found are more hassle than they’re worth with more complex scripts. For others in the same situation though, if your scripts are straight forward enough for the converters, I see no reason this wouldn’t work.