Search Unity

CSharpatron - the definitive Unityscript to C# converter!

Discussion in 'Assets and Asset Store' started by trepan, Jul 31, 2014.

  1. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Wow - all done.

    That's like 400 or so scripts in a 4 year project in less than a week.

    There will be some cleanup, but the game is running 99% clean.

    The last run converted like 120 or so scripts, all highly interdependent, using shadow mode (thats such a great idea)

    I've been worried sick about this since Unity announced they were dropping unityScript. Thanks again for Csharpatron - just amazing.
     
  2. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    I just tried csharpatron on a file that unity's version unityscript2csharp really mangled. Unfortunately I get a failure immediately. Failed to locate container object joints.Joint
    The project is joints.js and it has a class called Joint at the beginning.

    Processed file: Scripts/joints.js.
    [-1] - Warning: W00: Class 'Joint{' will be relocated outside of Mono class scope to maintain global name scope in C#.
    [-1] - Fatal: System.Exception: [90]: Failed to locate container object: 'joints.Joint'.

    How do I troubleshoot a failure?
     
  3. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    Hi there,

    Sorry to hear you’re having trouble. That certainly sounds like a very simple issue, although unfortunately I’m away on vacation for the next couple of weeks so it’s going to be hard for me to help too directly

    The first, golden rule with CSharpatron is that you have to maintain compiling code at all times since reflection is used to look up class information and this is only available for fully compiled assemblies (whether they started as .js or .cs).

    Another quick thing to check in the options is that no assemblies are being excluded (an option to give faster startup times... it excludes certain library classes that I didn’t think most Unity users would be utilizing). ...Although it sounds like Joint is your own class?

    Poke around in the options and you may see some other things that could help.

    I do have an updated build that I submitted to Unity a while back but which must have gotten ‘lost’ in the system somehow. When I’m back at my computer I’ll chase that up and can forward it to you directly.

    You can mail me directly on the support address found in the app. I’ll do my best to help further when I’m back (after 11th July). Really sorry about that delay.
     
  4. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    No problem. It's not an urgent project.

    I switched the library exclusion off but it had the same error.
    Thanks for offering to send the new version.

    I pared down the file to just the class and it still gives the same result
    Code (CSharp):
    1. #pragma strict
    2. import System.Text.RegularExpressions;
    3. import System.Collections.Generic;
    4.  
    5.  
    6. class Joint{
    7. //set these 4 when you create a Joint
    8. var base:GameObject;
    9. var body:GameObject;
    10. var joint:ConfigurableJoint;
    11. var name:String;
    12.  
    13. }
    14.  
    Log
    CSharpatron v1.3.2 Work Log
    Conversion date: 06/27/2018 09:15:51

    Processed file: Scripts/joints.js.
    [-1] - Warning: W00: Class 'Joint{' will be relocated outside of Mono class scope to maintain global name scope in C#.
    [-1] - Fatal: System.Exception: [6]: Failed to locate container object: 'joints.Joint'.
    at CSharpatron.SSSourceConverter.EmitFatalError (System.String text, Int32 lineNumber) [0x00000] in <filename unknown>:0
    at CSharpatron.SSSourceConverter.ConvertBlock (Int32 start, Int32 end) [0x00000] in <filename unknown>:0
    at CSharpatron.SSSourceConverter.Convert (System.String className, System.String source) [0x00000] in <filename unknown>:0
    at CSharpatron.SSCSharpatron.Convert (UnityEditor.MonoScript scriptObj) [0x00000] in <filename unknown>:0
    LAST CONVERSION LINE: 6
    1 fatal error. 0 errors. 1 warning.
    NOTE: No file could be written :(

    Work complete. 1 file.
    Elapsed time: 0m 19s.
    Final status: 1 fatal error. 0 errors. 1 warning.

    NOTE: All warning/error line numbers refer to the original .js file.
     
  5. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Could it be that Unity already has a Joint class? A javascript Joint.js wouldn;t conflict with it, but maybe it does once its switched to C#?

    Could you rename your Joint.js to something like JointExtended.js and then try converting that?
     
  6. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    @protopop agreed - that’s a theory worth some investigation.

    @dansav thanks for your patience (and the example). I’ll take a proper look into this as soon as I’m back at my computer.
     
  7. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    Yeah Unity does have a class called Joint. But I renamed it and still the same error. After I change a file and reconvert it uses the new one right? I don't have to reload it?
     
  8. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    I'm back home now - sorry for the delay. I just tried creating a test file named 'joints.js' with your example class from above and it seemed to convert as intended (perhaps because I was using my latest version?). The only output I get is one error complaining that the Joint field named 'base' has a name that is a reserved keyword under C# - that would ideally be renamed _before_ conversion. ...I don't think this error could be related to the fatal error you're seeing though.

    I'd suggest that you email me @ the support address and I can then send you the latest dll to see if that resolves your issue. If not, we can discuss further...
     
  9. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    I wasn't sure where the support address was so I emailed you from the form on your website.
     
  10. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    That works :)

    For anyone else needing to make contact: the support address can found in the About panel of CSharpatron's editor window.
     
  11. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    The new dll you sent got rid of the main bug. Now I'm able to start fixing other things. CSharpatron correctly flagged some reserved words. Now I've run into a problem with getters and setters for the following code. The error is:

    Scripts/joints.js[-1]. Fatal:System.Exception: [0]: Cannot add nested scope: funcVarScopeStack is empty.
    at CSharpatron.SSSourceConverter.EmitFatalError (System.String text, Int32 lineNumber) [0x00000] in <filename unknown>:0
    at CSharpatron.SSSourceConverter.AddNestedFunctionScope (Int32 preScopeIndex, Boolean canPrefixVars) [0x00000] in <filename unknown>:0
    at CSharpatron.SSSourceConverter.ConvertBlock (Int32 start, Int32 end) [0x00000] in <filename unknown>:0
    at CSharpatron.SSSourceConverter.Convert (System.String className, System.String source) [0x00000] in
    etc...

    Code (CSharp):
    1. class Joint{
    2. var jbase:GameObject;
    3. var jbody:GameObject;
    4. var j:ConfigurableJoint;
    5. var name:String;
    6.  
    7. //set axis
    8. private var _axis:Vector3;
    9. public function get axis():Vector3{
    10. _axis=j.axis;
    11. return _axis;
    12. }
    13. public function set axis(value:Vector3){
    14. _axis=value;
    15. j.axis=value;
    16. }
    17. }
     
  12. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    I'm glad you're making some progress with the new version.

    Regarding your new issue, I don't think I was aware that getters and setters were even supported in Unityscript (you're the first person I can recall mentioning them). So... I'm not sure there's much I can do to help with this one I'm afraid :(

    Which is to say that while I have risen to the challenge of adding support for unexpected features like this in the past, it's sadly no longer viable to do that. If you can make no further progress and want to submit a refund request then I quite understand (sorry).
     
  13. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    I can rewrite these manually with find/replace if need be there's about 35 of them. It's still going to save me tons of time in general to use CSharpatron because the projects I'm converting are huge. The unityscript2csharp version Unity made for this completely choked on the whole file and turned it into gibberish. Plus no one is supporting it. I asked a question on their forum months ago and didn't get any response. I'll stick with CSharpatron it seems to be extremely well built and documented, and the interface is easy to understand and use.
     
  14. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    Yikes - sounds like a daunting conversion challenge!

    Well I'm glad to hear CSharpatron is helping at least, even if it can't handle everything.

    If only they'd provided an actual, thorough reference for Unityscript it would have made writing the converter a lot easier and removed the 'surprise' factor of someone such as yourself using a language feature I've never encountered before. ...Stupid half-baked language :)

    Best of luck!
     
  15. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    What does Cannot add nested scope mean?

    I have some classes in my unityscripts. C# encloses everything in a monoBehaviour class which is the same name as the filename. Does that mean I should move my classes outside of the Main MonoBehaviour class? What should be in the Main class and what should be moved out?

    public class Main : MonoBehaviour{

    public class innerClass{

    }

    }
     
  16. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    So 'Cannot add nested scope' is an internal error - the converter expected to be adding a new class scope but couldn't (there was no available name is the only easy conclusion I can draw from looking at the converter source). Without debugging (and having access to your project) I can't say exactly why that would be, but perhaps there's parsing confusion caused by your getter/setter methods?

    What I can offer is a description of how Unityscript allows classes to be scoped. It's messy and AFAIK undocumented, but seems to be this...

    Basically Unityscript let's you create a file called foo.js which - with no specific class declaration being present within the file - will cause the creation of a MonoBehaviour derived class: 'foo'. You are expected to then provide variables and functions that will automatically be scoped to this implicit class. You may also use your own class declarations within the file to add nested classes , e.g. foo.nested. However, AFAIK you cannot create a non-nested class within such a file.

    Alternatively you might create foo.js and within that file declare 'class foo extends MonoBehaviour'. So long as your class name matches the filename Unity is happy. Within such a file (and outside of foo's scope) you can declare any number of additional 'globally scoped' classes.

    A third option is to create a file - foo.js - and within that file declare one or more non MonoBehaviour derived classes (that aren't named 'foo'). In this case I believe the Unityscript compiler is 'smart' enough not to create the class 'foo' (because there're no actual var or function elements to be added to that class). If I recall correctly (I haven't touched any Unityscript for years now) then you need to avoid creating a non MonoBehaviour class called 'foo' or adding any other MonoBehaviour derived class(es) with any other name within such a file otherwise Unity gets confused.

    ...So these are the approaches that CSharpatron attempts to support. In all cases it is trying to generate either a .cs file containing one explicitly declared MonoBehaviour class whose name matches the filename OR any number of non MB classes OR one MB derived class (matching filename) plus other global classes. In the (common) case where the main MB derived class had no explicit declaration within the .js file, CSharpatron must gather together the member elements of the class to be grouped within an explicit class declaration.

    Hope this helps...
     
  17. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    Thanks for the information. I took the getters and setters out and am redoing those manually. A reserved keyword
    'Joint' was causing one of the 'Cannot add nested scope' problems. I think that and/or cleaning up some global variables and removing code not attached to any functions.

    So I'm making real progress:

    Can you explain why this conversion occurs?
    boneZ.GetComponent(ConfigurableJoint).angularXDrive.positionSpring=0;

    turns into

    var tmp_cs1=boneZ.GetComponent<ConfigurableJoint>().angularXDrive;
    tmp_cs1.positionSpring=0.0f;

    with a Warning of
    [1709] - Warning: W15: Auto fix-up for assignment to a value type return value (not legal in C#): 'boneZ.GetComponent(ConfigurableJoint).angularXDrive.positionSpring'.
     
  18. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    So that fix up is happening because angularXDrive is of type JointDrive which is a struct (see: https://docs.unity3d.com/530/Documentation/ScriptReference/JointDrive.html).

    In C# an attempted assignment to a field of a temporary struct yields an error because behind the scenes, access to that struct is creating a temporary copy (of the whole struct). Assignment to that temporary would thus be lost. Instead we have to create a managed copy of the struct, assign our field, and then assign our modified version back to the original. Conversely in Unityscript this problem is somehow handled for us (not sure what technique is used).

    You can find various discussion on this issue, such as this thread: https://stackoverflow.com/questions/3729873/problem-with-struct-and-property-in-c-sharp

    In your cited example, hopefully CSharpatron would have also reassigned temp_cs1 back to angularXDrive to complete the intended assignment. The warning is emitted to allow you to double-check that this is the case. (I can totally vouch for this behavior for simple assignments, e.g. a field of a Vector, but your case here occurs within a fairly complex sequence of operations - fingers crossed!)
     
  19. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    CSharpatron is amazing. After getting through the issues described above, I was able to convert an entire project of about 20 scripts, one of which is 20K lines of code and another which is 4K lines of code in one day of hacking through CSharpatron's JS fixes it found. With the new converted CS scripts I had to spend a few hours fixing new bugs that showed up -- mostly from bad coding practices that unityscript let me get away with such as:

    variables declared and assigned out of functions
    returns needing to be replaced by yield return null,
    some for loops that all paths didn't return the same value
    misc problems such as an int that was cast as a float
    etc.

    After fixing the new bugs, amazingly the project is working again!
    This has saved me weeks of work!

    Don't bother with the UnityScript2csharp "unity" git hub project. It was hard to use and mangled my code into something that I couldn't even understand. Plus no one is supporting it as far as I can tell. I asked a question 2 months ago and it has still not been answered.
     
  20. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    Awesome!

    Congratulations, and thank you for your kind words :)

    I've never tried UnityScript2csharp myself but I did read their announcement blog where they said that they 'weren’t happy with the approaches' that other converters used. I believe their approach is to re-generate source from the compiled app. To me that approach is an absolute non starter when code quality, formatting and above all, comments are things that I take very seriously in my source-code, especially code that I might want to build upon moving forward.

    Sales of CSharpatron will certainly never cover the time it took to build, but the fact that it allowed me to salvage my own codebase from the mess of Unityscript and - I believe - that it has has done the same for a fair few others makes it feel worthwhile :)
     
  21. dansav

    dansav

    Joined:
    Sep 22, 2005
    Posts:
    510
    CSharpatron does not have a problem with class getters and setters after all. I took the getters and setters out then ran Csharpatron -- I made the resulting cs file live and fixed the csharp errors in the console -- in doing so I noticed some problems with some variable definitions particular a Dictionary variable and some others. I'm not sure which one it was, but I fixed those in the javascript files and ran CSharpatron again figuring that maybe some of those errors were preventing it converting the getters and setters. On the next try it did a beautiful job converting all the getters and setters.
     
    Last edited: Aug 1, 2018
  22. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    Oh, ok! I don't remember adding that support, but... it's been a while :D
     
  23. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    Just to note that I have now removed CSharpatron from the Asset Store.

    I felt this was necessary because CSharpatron could no longer work with Unity 2018.2 or greater. This is because 2018.2 dropped support for Unityscript. Without that Unity won't build Unityscript assemblies. ...And without those, CSharpatron loses the ability to lookup type information for your project and therefore cannot function correctly!

    I'd like to thank everyone that purchased CSharpatron; I'm glad it seems to have helped quite a few people.

    For those of you still with Unityscript files to convert, if CSharpatron interests you and you can accept installing a pre 2018.2 version of Unity in order to use it, I guess you could drop me a DM and I could mail you the latest version (NO support promise though!).
     
    Vagabond_Games and protopop like this.