Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

UnityScript 2 CSharp conversion tool

Discussion in 'Experimental Scripting Previews' started by AdrianoVerona_Unity, Aug 11, 2017.

  1. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Hi

    As announced in this blog post we are planning to deprecate support for UnityScript and, in order to make this process as smooth as possible, we want to provide help for developers to convert their existing UnityScripts to C#. After evaluating some existing AS solutions we decided to implement a converter ourselves, which you can download (including source) from this github repository.

    Keep in mind that we will probably never have 100% syntax coverage; our goal is to make sure that the most commonly used (UnityScript) features are supported.

    If you have a project that relies on UnityScript it would be nice if you could give it a try and help us iron out potential issues.

    Best

    Adriano
     
    protopop, Mauri, petey and 2 others like this.
  2. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,816
    I have a good project to test it on, I’ll give this a go soon and let you know.
    Thanks Adriano!
     
    AdrianoVerona_Unity likes this.
  3. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,686
    What about a version for macOS?
     
    protopop likes this.
  4. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Hi @VIC20

    You can run the tool on OSX; you only need to install mono (I recommend installing the latest version available)

    Best
     
  5. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,492
    The irony is that I just bought that converter from the asset store and you released a free one lol
     
    protopop likes this.
  6. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    Since it's C# you could use it as the foundation for an in-editor tool too, although I hope UT get around to that first :)
     
    protopop likes this.
  7. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,557
    I'm glad you're releasing this tool and I will give it a try. But I think it would be helpful for non-coders like me (who are probably the biggest UnityScript users anyways) if the converter could be downloaded as a simple app for Mac / PC. I know many people are used to GitHub and Mono, but not everyone is as comfortable with that process (i'm one of them:)
     
    petey likes this.
  8. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,816
    I agree, I've never used mono but just looking at the site makes me think, yeah I'm gonna stuff some part of this up before I even get to the convert process. :)
     
    protopop likes this.
  9. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    don't like command line tools much but anyway tried it with not much luck:

    "Internal compiler error: Object reference not set to an instance of an object.."

    (it does run in editor)

    Also why does it strip all comments?
     
    protopop likes this.
  10. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,557
    :) Hopefully they will make a converter that's more accessible to non coders. I'm an artist who codes by necessity to realize my visions, and I have a few engineering friends who are very comfortable with GitHub and the like. But for me it's a big barrier and not something that comes naturally. I kind of feel like its a sign of things to come when it comes to non coders and Unity in general. After all, it was the accessibility of Unity that drew me to it in the first place.
     
  11. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,557
    I'm starting to plan how to deal with this and I have a few questions

    Lets say i convert the scripts successfully. I have maybe a few thousand instances of various scripts attached to hundreds of game objects in my open world. Each script might reference another script elsewhere and have various settings and variables set, like in the attached image.

    Using the attached image as an example, Lets say i convert my DayManager.js script to DayManager.cs. What is the next step to replace the current script

    • Can i add the new CS script to the same game object as the original JS, and then copy and paste the vales between the JS and CS components?
    • Will I need to manually type in all variable values between scripts? Is there a way to automate copying the data between CS and JS components?
    • Can JS and CS scripts with the same name exist with the same project directory? ie there wont be any conflict?
    • Do i have to change all my JS scripts to CS at the same time? Or will I be able to say change one to CS and still reference it froma JS script that hasn't been converted yet? i seem to remember something about an issue accessing CS fro JS and vice versa. This way i can start converting scripts one by one now before its too late.
    • I'm using over 100 Asset Store assets in the game. If some devs do not or cannot update their assets to C#, will I still be able to use them in the game? Or after a certain time will JS files not work at all in a project?
    • Do you have a roadmap for how long before our JS based projects stop working? 6 months? 2 years? even a rough guesstimate will help planning

    A suggestion: if there isn't one already, how about a dedicated Forum for UnityScript to C# conversion where everyone could ask questions and find answers specific to this? I could port all my questions there and you could pin a link to the conversion tool

    Sorry to ask all of this, but Ive invested many thousands of dollars in unity, assets and this game, and I want to try and get the worst possible scenarios out of the way so there's no surprises when I attempt this:)

    If anybody else can think of any potential issues I haven't thought of, please let me know. Nimian Legends BrightRidge is a very complex game and I want to attempt to do it as efficiently as possible.

    Thank you

     
  12. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,646
    Thanks for the questions!

    I think the best bet here is actually going to be to have the CS component 'assume the identity of' the JS component, by having it remove/rename the JS component and then hijack the ID of the JS component from the .meta file. I believe this isn't something the tool does today, though it sounds like something that it probably should. When this is done successfully, you will not need to recreate any components or copy/paste any values around - Unity will simply start using the C# definitions of your components instead of your UnityScript ones.

    Unity won't have a problem with it, but your own code might - if you have both MyBehaviour.cs and MyBehaviour.js, then there will technically be two different 'MyBehaviour' classes in your project, and this can cause problems such as GetComponent not returning what you expect. I'd say it is probably fine for scripts that you're not actually referencing from elsewhere in code, but otherwise I would recommend against it.

    Yes, here's the relevant manual page. In effect, because C# and UnityScript code is compiled in separate assemblies, it means you cannot freely reference back-and-forth between the two languages. So, converting files one-at-a-time might not work well, depending on how much they refer to other scripts. It's not something I would really recommend as an approach.

    That said, there is a new feature in Unity 2017.2 called 'Assembly Definition Files' that can make life easier; it allows you to group scripts together into assemblies, above and beyond the special folders mentioned on that manual page. If you break your scripts up into assemblies using Assembly Definition Files, then you could convert your project one assembly at a time, and that should be OK. Note that you also get other benefits from using Assembly Definition Files, such as improved compile times.

    At some point, we will release a version of Unity in which .js files do not work at all - it won't matter whether they were authored by you or downloaded from the Asset Store.

    Roadmap-wise, we will probably not release that version for at least 6 months. Bear in mind that when we do, you will still be able to keep using older versions of Unity just fine - we're not removing support retroactively. The UnityScript compiler is also open source, so it should also be possible to find a way to manually compile your scripts with it even after we drop support.

    If we get a lot of questions, we'll consider it, but for now this thread is fine.

    I wholeheartedly endorse this :)

    Provided your project is backed up / committed to source control, you can try running the converter ASAP and then just throw away the results - that'd be the best way to find out how good of a job it's doing, and give us the feedback. I'm not sure if we will ever reach a point where it "just works" for everyone's projects, but if there's obvious things we can do to improve the tool and make the transition easier for you, we are interested in doing them.
     
  13. sledgeman

    sledgeman

    Joined:
    Jun 23, 2014
    Posts:
    389
    Good to see, Unity is investigating in such a conversion-tool. But the current version / solution isn´t easy to use. First, its a command-line method. Second, its outside unity. I hope the direction of this conversion-tool will be like all other assets integrated with unity, via *.unitypackage. Its simple to install. And It has a gui. And it should have something like a list function, where you can put as many *.js files into as you want and they all will be converted at the same time.
     
    SomeGuy22 and protopop like this.
  14. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,557
    Thank you for the feedback. And I agree with sledgeman and your meta file suggestion. I dont know what meta files are although i have seen them in the project file, but it points to the notion that for a casual coder many of us dont use command lines,github etc. They are foreign concepts to me just like the use of composition and color theory may be forign to some professional coders (not all of course because some lucky people have a grasp on both skillsets). If The converter could eventually in Unity just convert in situ the scripts and preserve the settings, or at least the variables if not the script references to other scripts because i understand that these change one at a time, that would go a long way to making this change a positive thing and not a disaster for people who have already invested years in JS development - i hope you guys can make that work.

    This is also beyond me but it sounds like it makes sense. I'm actually still using Unity 5.2 because it has great performance on mobile (which is where my games are released) so I couldnt use this, but its good to know there might be a solution when new versions of Unity are mobile steady.

    This is my current backup plan. Ill stay on Unity 5 and it should be great - the only 2 drawbackas are 1) apple,xcode, ios etc change a lot so eventually Unity 5 might not be able to deliver an IOS 12+ compatible archive and 2) It locks us out of a lot of asset store purchases, although until know i am just buying incompatible ones because many of them still work undocumented in earlier versions of Unity

    Anyways now that I know this is coming I will start experimenting with converting very carefully single files and porting in the values for some of my less critical files. I have some JS that communicate with CS and the link you sent will help. one thing I just want to put out there. i think most people at Unity are engineer minded, and its good to remember some of us dont have pro coder experience, use command lines, etc. I actually brought up my fear that this was going to happen a while back in this post: https://forum.unity3d.com/threads/will-javascript-become-deprecated.410416/#post-2877105 and I just want people to acknowledge that for many learning C# is a big deal. Some of the feedback ive been hearing is that its dead simple, but by not acknowledging how difficult it will be for us it feels like those concerns are not taken seriously or that somehow as an artists and casual coders we are not up to snuff. Unity was so accessible that even a javascript web designer like me was able to make a 120,000 selling open world rpg on mobile - i cant overstate how sometimes accessibility can be a large selling point for use of a software program, especially when it makes it inviting for web people who already work and will continue to work with JavaScript on the web. Im very happy that you answered everything so thoroughly and are honest about what is coming and although i would rather see UnityScript kept as a deprecated option and not removed to ease this transition, i know it is happening and at least by keeping us informed we can better prepare ourselves to try and solve this in our JS based games.
     
  15. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    I'm one of 3.6% :( Already left my thoughts on the UnityScript deprecation on the blog post itself, but as for the conversion tool, I agree that it needs to be bundled under a standalone application instead of a command line--this should be pretty simple to do, and it's something that will make the process easier for all of us. Also, the tool should at least keep comments and as much formatting as possible.

    Protopop brought up some good points on staying on Unity 5, iOS compatibility changes constantly, and the Asset Store has weird Unity version requirements as well. Luckily for me, I don't build for iOS and I don't use the Asset Store frequently, but other people aren't as lucky. After my current project, I will be making the switch to C# and keeping up to date with newer Unity versions (As stated on the blog post I'm fluent in C# already, so switching will be easier for me). I'm just hoping that this transition is made as smooth as possible, this is a huge change for us UnityScript users.
     
  16. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    I think it does this already? Otherwise only does half the job and would leave your project in a mess.

    Currently it fails (stops converting) when it finds a class with a js Function pointer (not surprising but needs message). Then leaves the project in an uncompilable state since the new cs files need to be in plugins while there are still js files left that access those classes!
    (error is "Internal compiler error: Object reference not set to an instance of an object..")
     
  17. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,292
    Is there a built-in way to do this? Possibly an internal method we could reflect into? Currently the solution I have for changing the GUID of a file is pretty ugly:

    Code (csharp):
    1.  
    2. public static void SetGUIDForAssetAtPath(string assetsFolderRelativePath, string GUID) {
    3.     var absolutePath = RelativeToAbsolutePath(assetsFolderRelativePath);
    4.  
    5.     if (!File.Exists(absolutePath)) {
    6.         throw new FileNotFoundException("Not file at " + absolutePath);
    7.     }
    8.  
    9.     var metaFile = absolutePath + ".meta";
    10.     if (!File.Exists(metaFile)) {
    11.         throw new UnityException("The file at " + assetsFolderRelativePath + " has no .meta file. If it has been recently generated, " +
    12.                                     "please use AssetDatabase.ImportAsset first to generate the .meta file. Can't set the GUID if there's" +
    13.                                     "no existing file already, sadly.");
    14.     }
    15.  
    16.     var allLines = File.ReadAllLines(metaFile);
    17.     var newGUIDData = "guid: " + GUID;
    18.     allLines[1] = newGUIDData;
    19.     File.WriteAllLines(metaFile, allLines);
    20. }
    Could we get a preview for that? I've been wanting something like that for a very long time.
     
  18. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Yes, the tool already renames any .js.meta to its equivalent .cs.meta. (@protopop, @superpig)

    @andyz what you mean by function pointer? Something like
    Code (JavaScript):
    1. var f = function() { ... }
    ?

    If you can provide a small repro case I'll investigate / fix ASAP

    Best

    Adriano
     
    protopop likes this.
  19. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    sorry I mean like:
    Code (csharp):
    1. public var loadCallback:Function;
     
  20. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Ok, I'll give it a try now

    This happens because UnistyScript parser does not pass these comments along with the AST (sorry for the jargon) so the converter never see them. We'll investigate some approaches to try to preserve comments.
     
    SomeGuy22 likes this.
  21. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    @andyz I could not reproduce this , but the converted code is not correct anyway (for curiosity, it got converted to
    Code (CSharp):
    1.  public Boo.Lang.ICallable fnt;
    )

    I'll investigate what is the best type to convert this to.

    Can you share full console output when you run the conversion tool ?

    Anyway, if you can provide a small repro case I can investigate why it is crashing (last alternative is to you to share your project if me (Unity) and I can investigate)

    Best

    Adriano
     
  22. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    Yes in trying to do a minimal example I got the boo type too which then lead to an error in the tool - maybe the bad conversion is leading to unpredictable errors, not got time just now to be sure.

    Converting 'runtime' (1 scripts)
    Finish processing 'D:\Unity\js2cs\Assets\test.js'
    Converting 'editor' (0 scripts)
    Cannot find assembly: 'System'

    System.ApplicationException: Cannot find assembly: 'System'
    at Boo.Lang.Compiler.CompilerParameters.LoadAssemblyFromLibPaths(String assembly, Boolean throwOnError)
    at Boo.Lang.Compiler.CompilerParameters.ForName(String assembly, Boolean throwOnError)
    at Boo.Lang.Compiler.CompilerParameters.LoadDefaultReferences()
    at Boo.Lang.Compiler.CompilerParameters..ctor(IReflectionTypeSystemProvider reflectionProvider, Boolean loadDefaultReferences)
    at UnityScript.UnityScriptCompilerParameters..ctor(IReflectionTypeSystemProvider reflectionTypeSystemProvider, Boolean loadDefaultReferences)
    at UnityScript.UnityScriptCompilerParameters..ctor(Boolean loadDefaultReferences)
    at UnityScript.UnityScriptCompilerParameters..ctor()
    at UnityScript.UnityScriptCompiler..ctor()
    at UnityScript2CSharp.UnityScript2CSharpConverter.CreatAndInitializeCompiler(IEnumerable`1 inputs, IEnumerable`1 definedSymbols, IEnumerable`1 referencedAssemblies) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\UnityScript2CSharpConverter.cs:line 68
    at UnityScript2CSharp.UnityScript2CSharpConverter.Convert(IEnumerable`1 inputs, IEnumerable`1 definedSymbols, IEnumerable`1 referencedAssemblies, Action`3 onScriptConverted) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\UnityScript2CSharpConverter.cs:line 28
    at UnityScript2CSharp.Program.ConvertScripts(String scriptType, IList`1 scripts, UnityScript2CSharpConverter converter, IEnumerable`1 references, CommandLineArguments args, List`1 referencedSymbols) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\Program.cs:line 192
    at UnityScript2CSharp.Program.Main(String[] args) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\Program.cs:line 72

    test.js:
    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. public var callback:Function;
    5.  
    6. function Start () {
    7. }
    8.  
    9. function Update () {
    10. }
    11.  
     
  23. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    BTW I do not think any way to convert a js Function to a C# delegate as type/parameters unknown. Perhaps should just post a message saying to change Function to an Action before conversion.
     
  24. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,816
    I hope you guys can get something like this working, without it I think any project would turn out really broken.
    Have you seen the CSharpatron Asset, it kinda seems to do something like this.
     
    protopop likes this.
  25. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    I was not aware
    The tool already does that by renaming the .js.meta file to its equivalent converted C#

    Best
     
    petey likes this.
  26. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,816
    Oh! That’s great thanks!
     
  27. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    I was not aware that UnityScript has a Function type !

    Makes sense

    Best

    Adriano
     
  28. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,646
    It's in the 2017.2 beta - here's more information.
     
    Baste likes this.
  29. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    @Vagaus I think your best bet is converting it to a System.Delegate and call it using DynamicInvoke. (you should put a warning, because it's slow (uses reflection) and is not type-safe)

    also, as there is no implicit conversion from either lambda or method group to System.Delegate, you need to explicitly cast any assignment to the corresponding delegate type (i.e. Action or Func - I hope UnityScript didn't have out or ref parameters - or declare the delegate type for each one)
     
  30. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    I think the first two limitations are big issues at present, as a consequence of using the UnityScript parser/compiler as you do, however am still impressed with the results so far.

    - Comments are not preserved
    - Guarded code (#if … )

    Not tried CSharpatron but it obviously has a very different [slow and complex] approach which preserves all the things you strip out by using your simpler approach.
    Would be interested to know how in testing you found CSharpatron.
    There are some other converters too but not sure why some have been allowed to stay on the store since they appear to be barely functional or just broken - would suggest asset store team look through the converters as this official one progresses...
     
  31. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Indeed, both are simply limitations of the compiler technology we are using (to be fair, the guarded code issue is very unlikely we'll be able to overcome).

    Regarding not being able to preserve the comments I am investigating an approach that may allow the tool to, at least, copy most comments but it may happen that those comment may end up being placed a little off their original location.

    BTW, I've experimented most of the converters I could find (IIRIC, 3 of them) and we decided to provide an alternative, should our users want /need it.

    Best

    Adriano
     
  32. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Hi

    I've just pushed a new release of the tool with some improvements (bug fixes) and support for preserving most of the comment from the original UnityScript sources. You can download it here.

    Please, give it a try and report any issues so we can investigate.

    Best

    Adriano
     
    Last edited: Aug 18, 2017
    SomeGuy22, andyz and protopop like this.
  33. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    Got stuck on another issue. not sure what to do with yet:
    Code (csharp):
    1.  
    2. Internal compiler error: Object reference not set to an instance of an object..
    3.  
    4.    at Boo.Lang.Compiler.Ast.DepthFirstVisitor.OnError(Node node, Exception error) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\Ast\DepthFirstVisitor.cs:line 83
    5.    at Boo.Lang.Compiler.Ast.DepthFirstVisitor.Visit(Node node) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\Ast\DepthFirstVisitor.cs:line 55
    6.    at Boo.Lang.Compiler.Ast.DepthFirstVisitor.Visit(Node[] array) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\Ast\DepthFirstVisitor.cs:line 112
    7.    at Boo.Lang.Compiler.Ast.DepthFirstVisitor.Visit[T](NodeCollection`1 collection) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\Ast\DepthFirstVisitor.cs:line 119
    8.    at Boo.Lang.Compiler.Ast.DepthFirstVisitor.OnBlock(Block node) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\Ast\Impl\DepthFirstVisitor.cs:line 722
    9.    at UnityScript2CSharp.UnityScript2CSharpConverterVisitor.OnBlock(Block node) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\UnityScript2CSharpConverterVisitor.cs:line 493
    10.  
    11. //lots more DepthFirst...
    12.  
    13.    at Boo.Lang.Compiler.Ast.CompileUnit.Accept(IAstVisitor visitor) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\Ast\Impl\CompileUnitImpl.cs:line 69
    14.    at UnityScript2CSharp.UnityScript2CSharpConverter.Convert(IEnumerable`1 inputs, IEnumerable`1 definedSymbols, IEnumerable`1 referencedAssemblies, Action`3 onScriptConverted) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\UnityScript2CSharpConverter.cs:line 43
    15.    at UnityScript2CSharp.Program.ConvertScripts(String scriptType, IList`1 scripts, UnityScript2CSharpConverter converter, IEnumerable`1 references, CommandLineArguments args, List`1 referencedSymbols) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\Program.cs:line 220
    16.    at UnityScript2CSharp.Program.Main(String[] args) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\Program.cs:line 73
    17.  
    Edit - you can re-create with this js class:
    Code (csharp):
    1.  
    2. #pragma strict
    3. public class SimpleObject
    4. {
    5.     function SimpleObject(parent:Transform)
    6.     {
    7.         if (parent == null) return;
    8.         Debug.Log("ok");
    9.     }
    10. }
    11.  
     
    Last edited: Aug 21, 2017
  34. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    Also try converting this simple js class:
    The result is a little ugly as you can not easily convert the Vector3 .x but also why does it end up as a 'partial' class in C#?

    Code (csharp):
    1.  
    2. #pragma strict
    3. var tf:Transform;
    4. function Start ()
    5. {
    6.    tf.localPosition.x = 666f;  
    7. }
    8.  
    result:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5. [System.Serializable]
    6. public partial class Test : MonoBehaviour
    7. {
    8.     public Transform tf;
    9.     public virtual void Start()
    10.     {
    11.         {
    12.             float _1 = 666f;
    13.             Vector3 _2 = this.tf.localPosition;
    14.             _2.x = _1;
    15.             this.tf.localPosition = _2;
    16.         }
    17.     }
    18. }
    19.  
     
  35. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Yeah, I agree, this is not the most elegant solution; but it works ;) (besides that, this is a clear pattern that can be easily be found)


    Because the UnityScript compiler flags the class as such.. But thinking more about this I guess it is safe to ignore it and simply emit a non partial class. I'll experiment a little.

    Bets

    Adriano
     
  36. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Hi
    Strange. I cannot get the same call stack (I do get an NRE, but in a different place; I'll investigate and fix this crash).

    Can you share more details? (Command line options used, version of Unity, OS, etc) ?

    Adriano

    [edit1] I manage to reproduce exactly the same call stack
     
    Last edited: Aug 21, 2017
  37. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    Ok fine, I can see how problematic js is by some of the C# code it ends up as! But that's another reason to try and convert any left.
     
  38. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    @andyz Just pushed a release that should fix the issues you reported (Function + crash).

    If you find any other issues, please, run the conversion tool with -i -v args and send me the console output (if possible attach any file mentioned in the console output)

    Best

    Adriano
     
    andyz likes this.
  39. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    That is how I implemented it in the last released version.

    Best

    Adriano
     
  40. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    Nice, it will now complete processing on the largest of projects though with Unity 5.5.1 (and -i -v) at least it will crash at the end with:
    Code (csharp):
    1.  
    2. Cannot find assembly: 'System'
    3.  
    4.    at Boo.Lang.Compiler.CompilerParameters.LoadAssemblyFromLibPaths(String assembly, Boolean throwOnError) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\CompilerParameters.cs:line 274
    5.    at Boo.Lang.Compiler.CompilerParameters.ForName(String assembly, Boolean throwOnError) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\CompilerParameters.cs:line 224
    6.    at Boo.Lang.Compiler.CompilerParameters.LoadAssembly(String assemblyName, Boolean throwOnError) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\CompilerParameters.cs:line 203
    7.    at Boo.Lang.Compiler.CompilerParameters.LoadDefaultReferences() in m:\Work\Repo\boo\src\Boo.Lang.Compiler\CompilerParameters.cs:line 146
    8.    at Boo.Lang.Compiler.CompilerParameters..ctor(IReflectionTypeSystemProvider reflectionProvider, Boolean loadDefaultReferences) in m:\Work\Repo\boo\src\Boo.Lang.Compiler\CompilerParameters.cs:line 119
    9.    at UnityScript.UnityScriptCompilerParameters..ctor(IReflectionTypeSystemProvider reflectionTypeSystemProvider, Boolean loadDefaultReferences) in M:\Work\Repo\unityscript\src\UnityScript\UnityScriptCompilerParameters.boo:line 36
    10.    at UnityScript.UnityScriptCompilerParameters..ctor(Boolean loadDefaultReferences) in M:\Work\Repo\unityscript\src\UnityScript\UnityScriptCompilerParameters.boo:line 33
    11.    at UnityScript.UnityScriptCompilerParameters..ctor() in M:\Work\Repo\unityscript\src\UnityScript\UnityScriptCompilerParameters.boo:line 11
    12.    at UnityScript.UnityScriptCompiler..ctor() in M:\Work\Repo\unityscript\src\UnityScript\UnityScriptCompiler.boo:line 12
    13.    at UnityScript2CSharp.UnityScript2CSharpConverter.CreatAndInitializeCompiler(IEnumerable`1 inputs, IEnumerable`1 definedSymbols, IEnumerable`1 referencedAssemblies, IDictionary`2 comments) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\UnityScript2CSharpConverter.cs:line 137
    14.    at UnityScript2CSharp.UnityScript2CSharpConverter.Convert(IEnumerable`1 inputs, IEnumerable`1 definedSymbols, IEnumerable`1 referencedAssemblies, Action`3 onScriptConverted) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\UnityScript2CSharpConverter.cs:line 36
    15.    at UnityScript2CSharp.Program.ConvertScripts(AssemblyType assemblyType, IList`1 scripts, UnityScript2CSharpConverter converter, CommandLineArguments args, List`1 referencedSymbols, HashSet`1 compilerErrors) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\Program.cs:line 248
    16.    at UnityScript2CSharp.Program.Main(String[] args) in M:\Work\Repo\UnityScript2CSharp\UnityScript2CSharp\Program.cs:line 75
    17.  
    There are still some js code cases where the resulting C# code is not valid, I will try and create examples
     
  41. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    @andyz After investigating the reported failures with switch, the problem is the usage of non const expression in case which is not supported in C#. For instance:

    Code (JavaScript):
    1. switch(var)
    2. {
    3.     case System.Environment.MachineName:  // do whatever
    4. }
    I'm checking whether we can convert that type of case to an if instead.

    Adriano
     
    andyz likes this.
  42. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
  43. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,292
    Just tried this on an old asset store package we imported from an old project. It's this one. There were some things that failed.

    1: Array.Sort:
    Code (csharp):
    1. //old us code:
    2. var particles:GameObject[];
    3.  
    4. ...
    5.  
    6. function Start(){
    7.     //Sort particle system list alphabeticly
    8.     particles.Sort(particles, function(g1,g2) String.Compare(g1.name, g2.name));
    9.     ...
    10. }
    11.  
    12. //converted cs code:
    13.  
    14. public GameObject[] particles;
    15.  
    16. ...
    17.  
    18. public virtual void Start()
    19. {
    20.     //Sort particle system list alphabeticly
    21.     (UnityEngine.GameObject).Sort(this.particles, (GameObject g1, GameObject g2) =>
    22.     {
    23.         return string.Compare(g1.name, g2.name);
    24.     }
    Seems like UnityScript's arrays have access to Array methods? The correct C# code should be:

    Code (csharp):
    1. Array.Sort(...
    Note that this also requires a System import.

    2: Using object instead of UnityEngine.Object:

    Code (csharp):
    1. //old us code:
    2.     function DoCreateSimplePrefab(){
    3.         for (var gameObj: GameObject in Selection.gameObjects) {
    4.             var prefab:Object  = PrefabUtility.CreateEmptyPrefab("Assets/"+gameObj.gameObject.name+".prefab");
    5.             PrefabUtility.ReplacePrefab(gameObj.gameObject, prefab, ReplacePrefabOptions.ConnectToPrefab);
    6.         }
    7.     }
    8.  
    9. //converted cs code:
    10.  
    11. public virtual void DoCreateSimplePrefab()
    12. {
    13.     foreach (GameObject gameObj in Selection.gameObjects)
    14.     {
    15.         object prefab = PrefabUtility.CreateEmptyPrefab(("Assets/" + gameObj.gameObject.name) + ".prefab");
    16.         PrefabUtility.ReplacePrefab(gameObj.gameObject, prefab, ReplacePrefabOptions.ConnectToPrefab);
    17.     }
    18. }
    The object there should be Object.


    Otherwise there's just some Array.Push and ToBuiltin calls that I can handle. Great tool!
     
    AdrianoVerona_Unity likes this.
  44. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    The array handling is a known limitation; tbh I am not sure we'll fix that. The problem is that UnityScript relies on its own type for handling arrays (which is implemented in UnityScript.Lang.dll) and we want to get rid of this type.

    Regarding the second issue, your conclusion is not 100% correct. Actually the variable declaration is correct. For instance, if you run the following code:

    Code (JavaScript):
    1.  
    2. function Start () {
    3.     Debug.Log(typeof(Object).FullName);
    4. }
    you will get System.Object as the result.

    The real issue is in the call to CreateEmptyPrefab()
    The UnityScript compiler does not include the required cast to UnityEngine.Object (the cast is inject in the code emission phase that happens later) thus the converter does not include that also.

    It is very likely we'll not going to invest time on fixing this right now.

    Best

    Adriano
     
  45. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    Unfortunately there remain a lot of issues that I do not have time to give examples for at the moment, but some of the things I have encountered:

    GetComponent(xxx) in js can end up as same in C# when they should be GetComponent<xxx>()
    same with AddComponent

    type conversions often missing e.g. float x = (float)inty;

    @script RequireComponent(CharacterController) converts to UnityEngine.RequireComponent(CharacterController), not UnityEngine.RequireComponent(typeof(CharacterController))

    txt.Split("|"[0]); becomes txt.Split("|".get_Chars(0)); not txt.Split('|');

    !classInst does not get converted to classInst == null
    if (classInst || does not get converted to if (classInst != null ||

    the scope differences of variables in js vs C# are not taken into account (js variables last for rest of function not just {} section)
     
  46. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Hi @andyz

    Sorry to hear that. Any chances to share your project privately with Unity?

    Can you do me a favor? Run the converter with no arguments and send me the output? (want to check which version you are using)

    This should just work (I have tests to make sure this conversion is applied). Without a repro project it will be harder to find the issue.

    I fail to see the problem. No casts are needed to convert from int to float.

    That should also work (we have tests in place) but you may be hitting some corner case.

    This one I can reproduce (I fixed it in my repo; will push to github soon)

    That should also work (we have tests in place) but you may be hitting some corner case.

    We are aware of that; this is one of the limitations of the converter (we may try to improve this in future but there's no plan for now)

    Best

    Adriano
     
    Last edited: Sep 27, 2017
  47. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,243
    Sorry, for the conversion I was thinking the other way around - float to int of course.
    I was using the latest version.

    I am happy to have the converter though, I have converted over 400 js scripts to C# now, they just needed a fair bit of manual fixing post-conversion, but I have done what I needed to do!

    It may be that errors in converting one class leads to a kind of waterfall effect where other classes that rely on it then have issues, but the scope differences were a common issue.
    Also something went wrong with the vector fixes (someVector.x = y) which were no longer being converted out to the multi-line C# equivalent so a lot of them needed fixing manually.

    I will try and provide examples when time permits.

    Thanks for your efforts
     
    AdrianoVerona_Unity likes this.
  48. AdrianoVerona_Unity

    AdrianoVerona_Unity

    Unity Technologies

    Joined:
    Apr 11, 2013
    Posts:
    317
    Hi @andyz

    No problem at all :)

    Regarding injecting casts from float to int it was a deliberate decision to not do so (since these my introduce data loss and stubble errors)

    If possible report all of them and I'll keep fixing.


    I don't think this is the case. The conversion only relies on the original UnityScript code. Unless you convert some scripts, build your game, and them try to convert the rest. This is the only scenario in which I can see the output of the conversion playing a role in errors during the conversion of other scripts

    That is odd; we do have tests in place, but it may be a corner case. I'll double check

    Many thanks!!! I do understand that it takes time to reproduce and report; your help has been invaluable to improve the tool :)

    You are more than welcome

    Best

    Adriano
     
  49. funkyboy

    funkyboy

    Joined:
    May 15, 2013
    Posts:
    41
    Hello,
    I use UnityScript all the time... sad to hear it's going to disappear :/
    sure, real devs use C#, it's dope, clean and more effective.
    but i'm not a real developer, I learned UnityScript by myself, (i handle the 3D part where i work, graphics) still I write little scripts all the time for simple fonctionalities, 95% of them in UnityScript.
    I don't like to re-learn something I already know how to do :/

    Can't you just put a checkbox somewhere in PlayerSettings like "Include old depreceated UnityScript"
    with a bunch of warnings like "don't use this, C# is better, some stuff might not work..."

    you guys spent so much time and effort maintaining UnityScript up to date so far, getting rid of it so abruptly would be such a waste of your time and those efforts.
    also for the sake of retrocompatibility, it would be nice to have such an option.

    it won't be up to date at all, it's fine, i won't most likely need those fancy functionalities you're going to implement...
    i'd just like my actual scripts to work the way they always have.

    Is it that big of an issue technicaly to leave UnityScript dormant the way it is and enable it if needed per project ?
    does it cripple the Engine somehow ? does it prevent further C# improvements just because it's there ?

    if 90% of the devs out there wants to use C# so bad, doesn't mean you have to cut off a hand to the 10% remaining devs.

    cheers !
     
    Lars-Steenhoff, protopop and VIC20 like this.
  50. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    It's not happening so abruptly though - the warnings have been there for a couple of years.

    They said only .8% of projects were exclusively UnityScript, and 3.6% had more than 20% UnityScript. That means a lot fewer than 10% of developers are UnityScript-focused. 10% would be reason to keep it around if these people used it exclusively, but it's not even half that number who use it in parts.

    It's dead. Time to bury it and get some transition tools to bring the stragglers into the present.
     
    Ostwind likes this.