Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Is Unity planning to kill JavaScript support?

Discussion in 'Scripting' started by gtapperdesign, May 10, 2016.

Thread Status:
Not open for further replies.
  1. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    Seriously, to all those of you who could not hide that they were looking forward for this to happen, especially those who were not affected by any extra work due to the existence of UnityScript at all:
    I hope you will find yourself on the other side one day, by being one of the few percent of long time users of something on that you somehow depend on. And I really hope you will have to watch others let the corks pop when it gets killed – exactly like some do now – while you are starting to estimate your necessary amount of extra work and hassle.

    I remember times when Unity Script was an advertised feature and the preferred language of the manual. For me, when I had the choice in 2007 it was the logical step to take the Unity Script route. (I had zero knowledge of JS before). I wonder how long it will take till they drop Mac support, I guess iOS is the only reason why they still support us.
     
  2. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    When something I used gets into such low numbers as UnityScript did I've already switched. It's not like there weren't any warning signs. This happens all the time with technology and we can either complain or adapt.
     
  3. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    We've pretty much all been there already. That's part and parcel of the tech business. I doubt there is a dev out there who hasn't had a critical technology pulled on them at least once.

    So yeah, we've been there. We can empathise. And I understand it sucks to be in that boat.

    But no matter how much it sucks for the handful of people that still use UnityScript, it's still very good news for C# developers.
     
    BlackPete and Dave-Carlile like this.
  4. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    I switched but I still have a lot old scripts. My main project is 8 years old now, and just converting them won’t work because I have to setup a lot of things in inspector too.

    I wan’t talking about change, I was talking about the hateful human behavior. Please reread it and try to understand the essence of what I tried to say (keep in mind that I don’t really speak english)
     
    protopop likes this.
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Keeping your English skills in mind, is it possible you have misinterpreted the response? No one has been particularly hateful about this, even going back through multiple years of forum discussions on the topic.
     
  6. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    Maybe it is because of the different culture. If someone frequently calls for a change just because the person does not like Unity Script (this topic started many years ago and I don’t think there was any other reason to drop it then), while exactly knowing this change would be a huge problem for other people, then I consider this as kind of hateful. At least it is a public act of disrespect which is not that different to hate.

    The news is already 4 months old (was posted on publisher group) and it is in no way an emotional thing for me, except that I usually preferred US over C#. I see only marginal differences between the two languages anyway. I just can’t understand people who openly show that this makes them kind of happy while they know that others might have some serious problems now. Bad manners.

    Just the upcoming hassle with my really old stuff is annoying.
     
  7. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,958
    Agreed. We've known at least as far back as 2014 that UnityScript was losing popularity. We knew the rough percentage of people who were making at least some use of the language. We also knew that Boo was discontinued because it had already reached the point where almost no one used it.

    With some custom editor scripts and some reflection you might be able to copy the contents of one inspector to another.
     
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I think it is. None of the things you've mentioned are considered offensive where I come from.

    Read the initial posts on this thread, and compare it to the blog post. The reasoning is the same. The reasons to stop supporting UnityScript have been there almost since UnityScript was first released.

    Now I'm curious as to what your cultural background is. It's hard for me to envision a functional society where celebrating success and progress is considered hateful.

    Dropping UnityScript is going to bring benefits to pretty much all Unity developers, at the cost of a little bit of pain for a small fraction of the userbase.
     
  9. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    The nearest I can think of is the Amish.
     
    Dave-Carlile likes this.
  10. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I have shipped 3 finished games in JS, I was super familiar with it. But C# is just as easy, and it honestly just is a matter of getting new habits.

    Not sure about inspector conversion. That does seem like a big problem. I think that it might be possible to dump the contents of each or just bite the bullet and do a manual conversion...

    I feel for you if it's been a while and you should have a proper moan.
     
    protopop and Dave-Carlile like this.
  11. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,958
    Yes, I thought it would be too...

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. [CustomEditor(typeof(MonoBehaviour), true)]
    7. [CanEditMultipleObjects]
    8. public class CopyMonobehaviourInspector : Editor {
    9.     private static Object source;
    10.  
    11.     public override void OnInspectorGUI()
    12.     {
    13.         base.OnInspectorGUI();
    14.  
    15.         GUILayout.BeginHorizontal();
    16.  
    17.         if (GUILayout.Button("Copy"))
    18.         {
    19.             source = serializedObject.targetObject;
    20.         }
    21.  
    22.         if (GUILayout.Button("Paste"))
    23.         {
    24.             EditorUtility.CopySerialized(source, serializedObject.targetObject);
    25.         }
    26.  
    27.         GUILayout.EndHorizontal();
    28.     }
    29. }
     
    Dave-Carlile and hippocoder like this.
  12. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I suspect just renaming the file in the editor will work. As far as I am aware, Unity serialises inspector data the same way no matter what language you are using.

    If that doesn't work I seem to recall @lordofduct sharing a magic trick involving manipulating the meta files and GUIDs that could transfer all of the serialised data. He shared it for doing bulk renaming of scripts. Something similar should work for this.

    In any case I expect the auto updater to deal with this. Of all the problems to solve for the auto updater, preserving meta data should be the simplest.
     
  13. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    I think you're talking about the tool I wrote for renaming scripts/components that are stored in a dll.

    Because of the way unity references what script to attach to GameObjects, it does so via a guid that is stored in the *.meta file that goes with your scripts.

    So if you like port a *.js file to *.cs, you an name it whatever you want, and then just go into the meta file for the new file and paste in the old guid from the js file (not forgetting to purge the js files guid). And the serializer will now point at the new script.

    The magic I think Kiwasi might be talking about is that if your scripts are in a dll, there can be more than one to the single dll (and single meta file). So how unity resolves it then is that it resolves the dll by guid, and then the class by what is called the fileid in the yaml, which is a weird hash calculated as following (I reversed engineered it from the Unity serialization):

    Code (csharp):
    1.  
    2.     public static class FileIDUtil
    3.     {
    4.         public static int Compute(Type t)
    5.         {
    6.             string toBeHashed = "s\0\0\0" + t.Namespace + t.Name;
    7.  
    8.             using (HashAlgorithm hash = new MD4())
    9.             {
    10.                 byte[] hashed = hash.ComputeHash(System.Text.Encoding.UTF8.GetBytes(toBeHashed));
    11.  
    12.                 int result = 0;
    13.  
    14.                 for (int i = 3; i >= 0; --i)
    15.                 {
    16.                     result <<= 8;
    17.                     result |= hashed[i];
    18.                 }
    19.  
    20.                 return result;
    21.             }
    22.         }
    23.  
    24.  
    25.  
    26.         #region Special Types
    27.  
    28.         // Taken from http://www.superstarcoders.com/blogs/posts/md4-hash-algorithm-in-c-sharp.aspx
    29.         // Probably not the best implementation of MD4, but it works.
    30.         private class MD4 : HashAlgorithm
    31.         {
    32.             private uint _a;
    33.             private uint _b;
    34.             private uint _c;
    35.             private uint _d;
    36.             private uint[] _x;
    37.             private int _bytesProcessed;
    38.  
    39.             public MD4()
    40.             {
    41.                 _x = new uint[16];
    42.  
    43.                 Initialize();
    44.             }
    45.  
    46.             public override void Initialize()
    47.             {
    48.                 _a = 0x67452301;
    49.                 _b = 0xefcdab89;
    50.                 _c = 0x98badcfe;
    51.                 _d = 0x10325476;
    52.  
    53.                 _bytesProcessed = 0;
    54.             }
    55.  
    56.             protected override void HashCore(byte[] array, int offset, int length)
    57.             {
    58.                 ProcessMessage(Bytes(array, offset, length));
    59.             }
    60.  
    61.             protected override byte[] HashFinal()
    62.             {
    63.                 try
    64.                 {
    65.                     ProcessMessage(Padding());
    66.  
    67.                     return new[] { _a, _b, _c, _d }.SelectMany(word => Bytes(word)).ToArray();
    68.                 }
    69.                 finally
    70.                 {
    71.                     Initialize();
    72.                 }
    73.             }
    74.  
    75.             private void ProcessMessage(IEnumerable<byte> bytes)
    76.             {
    77.                 foreach (byte b in bytes)
    78.                 {
    79.                     int c = _bytesProcessed & 63;
    80.                     int i = c >> 2;
    81.                     int s = (c & 3) << 3;
    82.  
    83.                     _x[i] = (_x[i] & ~((uint)255 << s)) | ((uint)b << s);
    84.  
    85.                     if (c == 63)
    86.                     {
    87.                         Process16WordBlock();
    88.                     }
    89.  
    90.                     _bytesProcessed++;
    91.                 }
    92.             }
    93.  
    94.             private static IEnumerable<byte> Bytes(byte[] bytes, int offset, int length)
    95.             {
    96.                 for (int i = offset; i < length; i++)
    97.                 {
    98.                     yield return bytes[i];
    99.                 }
    100.             }
    101.  
    102.             private IEnumerable<byte> Bytes(uint word)
    103.             {
    104.                 yield return (byte)(word & 255);
    105.                 yield return (byte)((word >> 8) & 255);
    106.                 yield return (byte)((word >> 16) & 255);
    107.                 yield return (byte)((word >> 24) & 255);
    108.             }
    109.  
    110.             private IEnumerable<byte> Repeat(byte value, int count)
    111.             {
    112.                 for (int i = 0; i < count; i++)
    113.                 {
    114.                     yield return value;
    115.                 }
    116.             }
    117.  
    118.             private IEnumerable<byte> Padding()
    119.             {
    120.                 return Repeat(128, 1)
    121.                    .Concat(Repeat(0, ((_bytesProcessed + 8) & 0x7fffffc0) + 55 - _bytesProcessed))
    122.                    .Concat(Bytes((uint)_bytesProcessed << 3))
    123.                    .Concat(Repeat(0, 4));
    124.             }
    125.  
    126.             private void Process16WordBlock()
    127.             {
    128.                 uint aa = _a;
    129.                 uint bb = _b;
    130.                 uint cc = _c;
    131.                 uint dd = _d;
    132.  
    133.                 foreach (int k in new[] { 0, 4, 8, 12 })
    134.                 {
    135.                     aa = Round1Operation(aa, bb, cc, dd, _x[k], 3);
    136.                     dd = Round1Operation(dd, aa, bb, cc, _x[k + 1], 7);
    137.                     cc = Round1Operation(cc, dd, aa, bb, _x[k + 2], 11);
    138.                     bb = Round1Operation(bb, cc, dd, aa, _x[k + 3], 19);
    139.                 }
    140.  
    141.                 foreach (int k in new[] { 0, 1, 2, 3 })
    142.                 {
    143.                     aa = Round2Operation(aa, bb, cc, dd, _x[k], 3);
    144.                     dd = Round2Operation(dd, aa, bb, cc, _x[k + 4], 5);
    145.                     cc = Round2Operation(cc, dd, aa, bb, _x[k + 8], 9);
    146.                     bb = Round2Operation(bb, cc, dd, aa, _x[k + 12], 13);
    147.                 }
    148.  
    149.                 foreach (int k in new[] { 0, 2, 1, 3 })
    150.                 {
    151.                     aa = Round3Operation(aa, bb, cc, dd, _x[k], 3);
    152.                     dd = Round3Operation(dd, aa, bb, cc, _x[k + 8], 9);
    153.                     cc = Round3Operation(cc, dd, aa, bb, _x[k + 4], 11);
    154.                     bb = Round3Operation(bb, cc, dd, aa, _x[k + 12], 15);
    155.                 }
    156.  
    157.                 unchecked
    158.                 {
    159.                     _a += aa;
    160.                     _b += bb;
    161.                     _c += cc;
    162.                     _d += dd;
    163.                 }
    164.             }
    165.  
    166.             private static uint ROL(uint value, int numberOfBits)
    167.             {
    168.                 return (value << numberOfBits) | (value >> (32 - numberOfBits));
    169.             }
    170.  
    171.             private static uint Round1Operation(uint a, uint b, uint c, uint d, uint xk, int s)
    172.             {
    173.                 unchecked
    174.                 {
    175.                     return ROL(a + ((b & c) | (~b & d)) + xk, s);
    176.                 }
    177.             }
    178.  
    179.             private static uint Round2Operation(uint a, uint b, uint c, uint d, uint xk, int s)
    180.             {
    181.                 unchecked
    182.                 {
    183.                     return ROL(a + ((b & c) | (b & d) | (c & d)) + xk + 0x5a827999, s);
    184.                 }
    185.             }
    186.  
    187.             private static uint Round3Operation(uint a, uint b, uint c, uint d, uint xk, int s)
    188.             {
    189.                 unchecked
    190.                 {
    191.                     return ROL(a + (b ^ c ^ d) + xk + 0x6ed9eba1, s);
    192.                 }
    193.             }
    194.         }
    195.  
    196.         #endregion
    197.  
    198.  
    199.     }
    200.  
    This the bulk rename tool:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections.Generic;
    5. using System.Linq;
    6. using System.IO;
    7.  
    8. using com.spacepuppy.Utils;
    9. using com.spacepuppyeditor;
    10.  
    11. namespace com.spacepuppyeditor.Commands
    12. {
    13.     class ScanAndUpdateGuidForComponents : EditorWindow
    14.     {
    15.  
    16.  
    17.         #region Menu
    18.  
    19.         [MenuItem(SPMenu.MENU_NAME_TOOLS + "/Scan and Update Guid for Components", priority = SPMenu.MENU_PRIORITY_TOOLS)]
    20.         static void CreateRigWizard()
    21.         {
    22.             var wizard = EditorWindow.GetWindow<ScanAndUpdateGuidForComponents>(true, "Scane Component Guid Move", true);
    23.         }
    24.  
    25.         #endregion
    26.  
    27.  
    28.  
    29.         #region Fields
    30.  
    31.         private System.Type _typeToReplace;
    32.         private System.Type _typeToReplaceWith;
    33.  
    34.         #endregion
    35.  
    36.         #region Methods
    37.  
    38.         private void OnGUI()
    39.         {
    40.             _typeToReplace = SPEditorGUILayout.TypeDropDown(EditorHelper.TempContent("Type to Replace"), typeof(MonoBehaviour), _typeToReplace);
    41.             _typeToReplaceWith = SPEditorGUILayout.TypeDropDown(EditorHelper.TempContent("New Type"), typeof(MonoBehaviour), _typeToReplaceWith);
    42.  
    43.             if (GUILayout.Button("Scan"))
    44.             {
    45.                 this.DoScan();
    46.             }
    47.         }
    48.  
    49.         private void DoScan()
    50.         {
    51.             if (_typeToReplace == _typeToReplaceWith) return;
    52.             if (_typeToReplace == null) return;
    53.             if (_typeToReplaceWith == null) return;
    54.  
    55.             //get guids
    56.             MonoScript script1;
    57.             MonoScript script2;
    58.             if (!GetMonoScripts(_typeToReplace, _typeToReplaceWith, out script1, out script2)) return;
    59.  
    60.             var spath1 = AssetDatabase.GetAssetPath(script1);
    61.             var spath2 = AssetDatabase.GetAssetPath(script2);
    62.             var sMetaPath1 = spath1 + ".meta";
    63.             var sMetaPath2 = spath2 + ".meta";
    64.  
    65.             string sguid1;
    66.             string sguid2;
    67.             if (!this.GetGUIDs(sMetaPath1, sMetaPath2, out sguid1, out sguid2)) return;
    68.  
    69.             string fileid1 = (spath1.EndsWith(".dll", System.StringComparison.OrdinalIgnoreCase)) ? FileIDUtil.Compute(_typeToReplace).ToString() : "11500000";
    70.             string fileid2 = (spath2.EndsWith(".dll", System.StringComparison.OrdinalIgnoreCase)) ? FileIDUtil.Compute(_typeToReplaceWith).ToString() : "11500000";
    71.  
    72.             const string MATCH_PATTERN = "{{fileID: {0}, guid: {1}, type: 3}}";
    73.             foreach (var sfile in Directory.GetFiles(Application.dataPath, "*.unity", SearchOption.AllDirectories))
    74.             {
    75.                 var pattern = string.Format(MATCH_PATTERN, fileid1, sguid1);
    76.                 string contents;
    77.                 using (var tr = new StreamReader(sfile))
    78.                 {
    79.                     contents = tr.ReadToEnd();
    80.                 }
    81.  
    82.                 if (contents.Contains(pattern))
    83.                 {
    84.                     contents = contents.Replace(pattern, string.Format(MATCH_PATTERN, fileid2, sguid2));
    85.                     using (var tw = new StreamWriter(sfile, false))
    86.                     {
    87.                         tw.Write(contents);
    88.                         Debug.Log(sfile);
    89.                     }
    90.                 }
    91.             }
    92.             foreach (var sfile in Directory.GetFiles(Application.dataPath, "*.prefab", SearchOption.AllDirectories))
    93.             {
    94.                 var pattern = string.Format(MATCH_PATTERN, fileid1, sguid1);
    95.                 string contents;
    96.                 using (var tr = new StreamReader(sfile))
    97.                 {
    98.                     contents = tr.ReadToEnd();
    99.                 }
    100.  
    101.                 if (contents.Contains(pattern))
    102.                 {
    103.                     contents = contents.Replace(pattern, string.Format(MATCH_PATTERN, fileid2, sguid2));
    104.                     using (var tw = new StreamWriter(sfile, false))
    105.                     {
    106.                         tw.Write(contents);
    107.                         Debug.Log(sfile);
    108.                     }
    109.                 }
    110.             }
    111.         }
    112.  
    113.         private bool GetMonoScripts(System.Type type1, System.Type type2, out MonoScript script1, out MonoScript script2)
    114.         {
    115.             script1 = null;
    116.             script2 = null;
    117.  
    118.             var go = new GameObject("temp");
    119.             var c1 = go.AddComponent(type1) as MonoBehaviour;
    120.             var c2 = go.AddComponent(type2) as MonoBehaviour;
    121.             if (c1 == null || c2 == null)
    122.             {
    123.                 GameObject.DestroyImmediate(go);
    124.                 return false;
    125.             }
    126.  
    127.             script1 = MonoScript.FromMonoBehaviour(c1);
    128.             script2 = MonoScript.FromMonoBehaviour(c2);
    129.  
    130.             GameObject.DestroyImmediate(go);
    131.  
    132.             return true;
    133.         }
    134.  
    135.         private bool GetGUIDs(string sMetaPath1, string sMetaPath2, out string sguid1, out string sguid2)
    136.         {
    137.             sguid1 = null;
    138.             sguid2 = null;
    139.  
    140.             try
    141.             {
    142.                 //var yaml = new YamlStream();
    143.                 //var idGUID = new YamlScalarNode("guid");
    144.  
    145.                 //using (var tr = new StreamReader(EditorHelper.GetFullPathForAssetPath(sMetaPath1)))
    146.                 //{
    147.                 //    yaml.Load(tr);
    148.                 //    var mapping = (YamlMappingNode)yaml.Documents[0].RootNode;
    149.                 //    sguid1 = (mapping.Children[idGUID] as YamlScalarNode).Value;
    150.                 //}
    151.                 //using (var tr = new StreamReader(EditorHelper.GetFullPathForAssetPath(sMetaPath2)))
    152.                 //{
    153.                 //    yaml.Load(tr);
    154.                 //    var mapping = (YamlMappingNode)yaml.Documents[0].RootNode;
    155.                 //    sguid2 = (mapping.Children[idGUID] as YamlScalarNode).Value;
    156.                 //}
    157.  
    158.                 var rx = new System.Text.RegularExpressions.Regex(@"\s*guid:\s*(?<id>[a-zA-Z0-9]+?)\s*$");
    159.                 string line;
    160.                 using (var tr = new StreamReader(EditorHelper.GetFullPathForAssetPath(sMetaPath1)))
    161.                 {
    162.                     while(!tr.EndOfStream)
    163.                     {
    164.                         line = tr.ReadLine();
    165.                         var match = rx.Match(line);
    166.                         if (match.Success)
    167.                         {
    168.                             sguid1 = match.Groups["id"].Value;
    169.                             break;
    170.                         }
    171.                     }
    172.                 }
    173.                 using (var tr = new StreamReader(EditorHelper.GetFullPathForAssetPath(sMetaPath2)))
    174.                 {
    175.                     while (!tr.EndOfStream)
    176.                     {
    177.                         line = tr.ReadLine();
    178.                         var match = rx.Match(line);
    179.                         if (match.Success)
    180.                         {
    181.                             sguid2 = match.Groups["id"].Value;
    182.                             break;
    183.                         }
    184.                     }
    185.                 }
    186.                 return true;
    187.             }
    188.             catch
    189.             {
    190.                 return false;
    191.             }
    192.         }
    193.  
    194.         #endregion
    195.  
    196.  
    197.     }
    198. }
    199.  
    200.  
    Like I said though, this is for renaming classes found in a dll.

    I don't think that's what hippocoder was talking about.
     
    Ryiah and Kiwasi like this.
  14. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    No I was blathering on about something I'd not even tested :p
     
  15. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    I'm having Delphi flashbacks. Still a better IDE than Visual Studio. Pascal was my first love.
     
    Kiwasi likes this.
  16. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    "Horse whip manufacturers did not survive the automobile revolution". It's an unfortunate feature of life that progress nearly always causes pain for someone. I think celebrating progress is not the same as being hateful to those hurt by it, but I feel your pain. Perhaps look at it as a chance to clean up your code base, refactor some things, make them better.
     
    Kiwasi likes this.
  17. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,557
    I understand exactly what you mean VIC20, and I'm glad you said this.

    You are not alone.

    People with JS project years in development will be facing a very difficult time now. It's not about C# - it's a wonderful, powerful language. It's about the relatively sudden extra work for people who are probably already worked to the bone. It's about the mental stress of understanding the logistics that will be involved in this. It's about relying on a core first-day feature that's being stripped from software we love.

    I think some of the people popping the corks (well said) are focusing mostly on how this change will benefit themselves as professional and/or C# programmers. I think it's difficult for some people to see why anyone wouldn't want to use a 'superior' language.

    About 8 years ago I wrote this blog post: http://protopop.com/blog/2008/12/27/flash-vs-unity-3d/

    I was full of enthusiasm for a fresh, young program called Unity. It was Mac only, and I was drooling over everything it did right. Unity contacted me directly and encouraged me to use the software. It was wonderful and exciting.

    At the time, Flash was king of the hill. But Adobe had recently switched Flash's language ActionScript 2, which was messy but great for quick artistic iteration, to ActionScript 3, which was a more logical, powerful, and well structured language that was more suited to the professional programmer.

    Sound familiar?

    Casual coders complained that it now took 3 lines of code to achieve the same thing one could before. And in a case of history repeating itself, their concerns were largely dismissed and they were told that the new way was the better way. I think many people had a difficult time understanding why this, in part, led to artists abandoning Flash. The lack of empathy towards people who happened to prefer a different way of working was almost as alienating as the change in language itself.

    I think it makes sense that Unity focus on C#, but it would be encouraging if more people understood that in exchange for efficiency, we will be losing something else along the way.

    Efficiency is not the only hallmark of a great game designer. The Unity I knew was for everyone, including pro coders but not limited to them. And part of it's appeal was that there were many ways of doing things. Now it seems there will be one way, that the change will be best for everyone, and we all have to adapt or leave. Resistance is futile.

    Now some practical advice :)

    I have been auditing converters, and there is more to do than just convert scripts - we have to transfer the values and references, swap components on perhaps thousands of game objects, and more. Csharpatron was mentioned in the Blog post comments: https://www.assetstore.unity3d.com/en/#!/content/20232 I haven't tested it yet, but on paper it seems like the best option for people who have a lot of work ahead of us.

    From my iPad - a screenshot of a mobile game lovingly made in UnityScript :)

     
    funkyboy likes this.
  18. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    The following quote wasn't in the blog post, but in a comment from the blog author...

    So don't lose hope. The intent is to continue to support those for whom programming isn't their primary skill.

    Edit: clarified quotes
     
    Last edited: Aug 14, 2017
    protopop likes this.
  19. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    But it won't be sudden. And honestly, if you have projects that are entirely JS then you simply freeze Unity on the last version that supports it. Don't upgrade to the version that removes the thing you need and breaks your entire project. It's pretty simple.
     
    Kiwasi and protopop like this.
  20. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,557
    I appreciate your advice, and that is a good temporary solution, especially if you're developing for desktop. But it's not sustainable for mobile developers, and I don't think it's as simple as you suggest.

    Apple and Xcode change submission requirements every now and then. So older versions of Unity eventually may not be able to deliver a valid Xcode archive for submission to the App Store. We saw a dramatic example of this when they switched to a 64bit requirement, obsoleting versions of Unity without it when i comes to IOS development.

    And some Unity features are version based. For example, AppleTV support requires Unity5.3 or higher, and many assets on teh asset store are now only available for newer versions of Unity, although i often install them anyways because many of them will work undocumented in earlier versions.

    Right now I am frozen on Unity 5.2 because of it's strong mobile performance, and i use newer versions of Unity to create content when assets are truly incompatible with 5.2 and export them back to my project.

    So we can freeze a version, but it requires a substantial increase in production overhead as well as a more complex production pipeline and the pretty much inevitable risk of obsolescence.

    I'm all for C#. I just wanted the poster to know that he wasn't alone in all this, and that i understand that this is not a simple thing for people in his position to deal with.
     
    Dave-Carlile likes this.
  21. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,557
    I'm not sure what you mean here, - i was the author of that comment in the Unity Blog post

    Thank you:) This will be a very difficult obstacle for some developers to overcome, and it's good to hear that kind of positive support.
     
  22. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    I was referring to the quote that followed, which was authored by Richard Fine who was also the blog post author.
     
    protopop likes this.
  23. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,557
    Ahhh - I was looking at the quote above it - thank you :)

    I find it encouraging to read what's happening on the conversion tool thread - smarter minds than me are churning away to find ways to improve the tool, and trying to answer some of the practical concerns UnityScripters and casual coders have about the process. I can see Unity's intentions are in the right place.
     
    Dave-Carlile likes this.
  24. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I understand the trepidation and some of those concerns are valid but its frankly par for the course when doing business in the tech industry. You've built an application on something that has been deemed obsolete. You made the decision - and no one can blame you for not knowing that this would happen when you started your project. Now you have to decide if you're going to pay the technical debt of upgrading your project to support all the new stuff or finish on an older version that still supports what you need albeit with a potentially diminished feature-set. This happens all the time in the Enterprise world. Those decisions can be tough, and it stinks to have to make them, but you can't have it both ways.

    Frankly - this seems like a correction to a poor decision Unity made in the very beginning. Custom in-house languages are an enormous organizational burden. The time spent maintaining them can almost always be spent doing something else more valuable.
     
    protopop, Kiwasi, Ryiah and 1 other person like this.
  25. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    You still ignore the important tiny detail which makes the huge difference. Celebrating progress on other people’s cost. This is rude.

    My cultural background is Germany. I can tell you many other differences to the American culture:
    – It is considered a bad behavior to flaunt wealth.
    – We don’t talk about money. Sometimes people don’t even know the salary of their partners. (I have no idea what my GF makes per month)
    – Rich politicians are generally seen as not trustworthy and would have no chance here. If you are rich then you are for sure compromised. And the chance is high that you made your money on cost of other people.
    – Business failure is not accepted. Insolvency is not seen as a chance to move ahead and create a new better business, it is a stigma for your entire career.
    – Any kind of private debt (except for housing) is considered as a bad thing here.
    – A lot of people think the stock market is generally a bad thing.
    – Most people don’t use Credit Cards
    – 15:00 means 15:00 and not 15:05
    – Patriotism is one of the worst things we can imagine.
    – Privacy. We take this extremely serious. Just look at Google Streetmap. They gave up and stopped it in Germany. Hard to find a German street without blurred houses on Google Street Map.
    – We don’t like small talk or superficial smiles for no reason.
    – We are direct. Directness is much more important than friendliness. If you say „Hi, how are you?“ then we consider this as a real question, you might get a detailed answer – the amount of details depends on how bad things are.


    I don’t think it is a question of skills. It is just annoying amount of work to change an entire project. Like Hippo already said: the differences between UnityScript and C# are marginal. UnityScript isn’t easier than C# – I use both.
    Many people started to use UnityScript because in the 2000s it was advertised as the primary language of choice for Unity. For many years everything (manual, examples, Unity demos, scripts on the UnifyWiki etc.) was clearly UnityScript first.

    Csharpatron looks like a solution. But I hope Unity will give us something similar.

    Nonsense:

    It’s all just software, and we could take the time to implement these missing pieces into UnityScript. Time is not free …

    The one and only reason is money. Supporting three languages was a feature of Unity – this has changed, that’s all.
    In the old days UnityScript was the language of choice. C# became stronger many years later when they introduced Unity for Windows.
    They were able to support three languages and the manual when they were just a few people. Do you remember the pictures of the entire Unity staff on the homepage before the HQ moved to the USA and how the number of the employees changed from picture to picture? I think the first picture I saw had 8 people on it. In 2009 it was still just something like 30-40 people. Last time I checked they hired more than that in a single month. Should be enough people, but they want to optimize the business because they have a lot of investors and dropping a language to save money is something investors love.

    Its not about horses and cars. C# is not that different to UnityScript. Dropping UnityScript is not progress it is mostly a business decision to save money.

    Actually I see it as a chance to make things better in my main project.
    But not for some old projects whichjust requires minor updates in the future to keep them in the App Store.

    You can’t just stay on some certain version of Unity for a longer time – the rules of the App Store change frequently, not updating Unity means your app might get a reject by Apple within the next year. Just check the iOS section for how often it happened during thr last 8 years that games got a reject because of Unity itself.
     
  26. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Techs come and go. Even languages come and go. It's a necessary evil if the industry is to continue to progress.

    Technologies I've worked on that are now either unsupported, left in some unknown state, or are dead:
    - MFC (to be fair, it was an abomination)
    - WinForms (technically "supported" but is ugly as hell without major reskinning)
    - WPF (technically "supported" but the WPF blog has been quiet for years while MS is working on the next big .Net thing)
    - Silverlight
    - Renderware (thanks EA)
    - Flash (currently a zombie that will finally be executed in 2020)

    Plus a bunch of other internal engines I'm not allowed to name.

    Even C# itself has gone through major revisions over the years. C++ is barely recognizable these days compared to the C++ from the 90's.

    So when developing middleware, it's better to embrace change rather than resisting it. The last thing you want is to get tangled up in legacy issues preventing you from implementing the latest and greatest technologies because they're not compatible with stuff that barely anyone uses anyway.
     
    guavaman, Kiwasi and LiterallyJeff like this.
  27. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Did you read the blog post? Supporting the language is blocking or impeding them from making improvements to the engine. Again - the time they spend supporting the language can be better spent on other things that a larger portion of the userbase will find value in. You allocate resources to efforts that net you the most value for your product. That's how this all works.
    Yup - that's the risk you run when you are dependent on middleware and other third party solutions. You save a bunch of time by having the fiddly bits of engine/pipeline development abstracted away from you but sometimes you're faced with decisions like this.
     
    Denisowator likes this.
  28. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    I'm really not seeing anyone celebrating that UnityScripts developers are "suffering". In Unity's blog, they were pretty apologetic that UnityScript developers will now need to make the transition to C#, and they made it very clear that this was not an easy decision for them to make, and backed it up with metrics and statistics.

    Even now, they're still not removing it just yet. It's the beginning of a process of its removal over the next few releases, and they're giving everyone a heads up that the process has started. I'm not sure what else they could've done to be more fair to anyone.

    Now, let's look at the other side of the coin:

    You know there's lots of C# developers using Unity, right? Now, imagine how frustrated those C# developers were in the fact they were stuck on some weird hybrid of .Net 2.0/.Net3.5, with an old version of C#. For each new C# version that comes out, all we could do is wistfully look over the release notes and wishing we could have those in Unity.

    We keep hoping they'd eventually have more manpower to devote to a .Net upgrade, which is not a trivial task. They sort of screwed themselves at the beginning when trying to create so much internal tech to make Unity look more attractive and user friendly, and are now paying the price for that in terms of lack of progress.
     
    Denisowator, KelsoMRK and orb like this.
  29. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    Of course I have. And I have quoted the essence of the same part which you quoted: Time is not free. They clearly wrote this is the main problem. They could do it but they don’t like the costs.

    Seriously: Are you trolling or why do you try to put those words in my mouth? There is an essential difference to what I wrote.

    Its not like there was more progress for UnityScript users.

    The point is UnityScript was advertised as first class citizen. At the beginning a huge portion (I think it was the majority) of customers who paid for Unity used it – without those people who paid for it, there would be no Unity today (and no majority of C# users) because it would have failed business wise:

    Side note: up until now, our internal procedure has been to write sample code using UnityScript / JavaScript, which is then automatically converted to C# and Boo. We’ve now made it possible for Unity engineers to author their examples in C# and auto-convert them to UnityScript, using a newly developed and improved C#-to-UnityScript converter.
    https://blogs.unity3d.com/2014/09/03/documentation-unity-scripting-languages-and-you/

    But anyway: as I said before I am not emotional about it. It is a business they run. Today they have more C#-only users and I have to live with it. I am just upset by the arrogance of some of the C# customers.

    Discussing about fairness is kind of pointless anyway because it is not about logic – it is like with Spock’s famous quote “The Needs of the Many Outweigh the Needs of the Few” in ST2 & ST3.

    I wonder if you ever have used Unity 1.x
    I think one of the problems is the number of platforms they started to support over the years. This multiplied the amount of necessary work per language.

    BTW: you could use that as a reason to drop any feature – like the Mac Editor for example.
     
  30. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You're missing an important piece. They don't like the cost as it relates to the number of users that cost serves. And that continued support slows down progress that is beneficial to all users
     
    Dave-Carlile likes this.
  31. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    Exactly this. It's really not even smart to continue to expend time and money supporting a feature that is barely used anymore.
     
  32. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    No, I don’t miss that point. Where exactly do you think I missed that? This is obvious.
    I don’t understand the need for the discussion at this point anyway. My point was rude behavior. Nothing else.
     
  33. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    The number of platforms supported is a big reason that a lot of businesses choose Unity. And they have sunsetted a lot of platforms as the platforms fell out of common use.

    If someone argues that the sky is green, I may come across as arrogant while I try to convince them the sky is blue. Should I stop trying?

    I can make a pretty good case that it's objectively better to use C# - does that make me arrogant, or do I just have a more right answer? C# has better tools available, it has orders of magnitude more usable sample code out there, and the community is more knowledgeable. Unity's official tutorials are all C#, and most of the learning resources that are in UnityScript are years out of date - written in Unity 3.x, 2.x, even 1.x - because most of their creators wised up and switched to C#. When a user searches for javascript sample code, they'll be very unlikely to find usable code, because their search will return web JS code; conversely, any arbitrary C# code from the web is very likely to work as written within Unity.

    This isn't meant to be a knock on any particular JS user, but every professional coder or company I've worked with in at least the last 7 of my 11 years using Unity - 100% have used C#. My sole interaction with UnityScript users in the last several years: week-one newbies needing help on the forums, often asking for help because they're following a tutorial that was abandoned three Unity versions ago.

    My point with all of that is this: A new user picking up Unity and learning UnityScript, is going to have a bad experience. They're more likely to get frustrated and quit using Unity because they followed a bad tutorial or think Unity doesn't support stuff like Intellisense (when it's just JS that doesn't support it). I've seen people who have tried both Unity and Unreal later argue in favor of Unreal for these reasons. If the new user sticks it out through the subpar tutorials and resources and tries to go pro, they'll again be frustrated by the fact that nearly any company they want to work for will need them to know C#.

    Unity supporting JS makes it a worse product for these users. I would advocate for its removal - or at the very least, the first phase of this removal (getting rid of the quick creation menu items) - even if it didn't involve additional maintenance work.
     
    guavaman, BlackPete, Kiwasi and 2 others like this.
  34. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,958
    From a practical standpoint I believe that people are blowing this whole transition way out of proportion. I don't know how many people bothered trying out the script I wrote earlier, but with only 29 lines of code I was able to copy the contents of an inspector for UnityScript to an inspector for C#.

    It's understandable why it would work too. When you're working with the inspectors you have already compiled the code for the scripts and both languages compile down to the exact same bytecode language. Unity doesn't care what the language is for public properties, it just cares about the name of the property, the type of it, and the value (as well as GUID and all that nonsense where applicable).

    Regardless of how it works though it stands to reason that if I was able to create a simple script to convert the inspector then there is no reason whatsoever that Unity cannot do the exact same thing with their conversion tool. Worst case if they don't do it then third party assets will.
     
    Kiwasi likes this.
  35. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Progress always comes at a cost to someone. Always. So by your definition, celebrating any progress is rude.

    Huh. I totally had the German cultural mindset wrong in my head. It genuinely surprised me that those tenants can produce a country known for industry, efficiency and high quality.

    Still, if you prize directness, I can be direct.

    Grow up and get over yourself. This change is happening, and it's going to be a good thing for everyone.

    For years C# users have put up with a substandard programming environment to deal with UnityScript users. You've been using UnityScript at a direct cost to us, both in dollar terms and in development time.

    The signs that UnityScript is dying have been there for years. It's not my problem some people have been to stupid or stubborn to notice.
     
    StarManta likes this.
  36. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    OK. You are a troll.

    How often shall I repeat, that I don’t really care about that they drop UnityScript? It just sux that I have to change my old stuff now.

    Although progress often (not always) comes at a cost for someone, people (of a civilized culture) does not make fun of those who are at a real disadvantage due to a decision by celebrating it in front of them. This is not a game or a contest, this it is about work.
    If your culture handles that different then I consider the culture you are living in as a degenerated and morally bankrupt culture full of egoists. Was that direct too?

    The question of this thread was “Is Unity planning to kill JavaScript support?“ and we’ve got a definite answer. The thread should be closed.
     
    protopop likes this.
  37. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Only minor trolling intended. I am genuinely curious about what makes other people and cultures tick. I apologize if my lack of manners offends you.

    The traditional definition of civilized has always boiled down to 'people like me'. What one culture consider civilized, others consider to be backwards. There tend not to be absolute rights and wrongs in this sort of discussion, simply different ways to approach life.

    In my country we certainly work to mitigate disadvantages caused by progress. But we don't avoid celebrating progress just because it isn't good for everyone. Nor do we associate celebration with making fun of people. When we choose to make fun of people, its much more direct.

    I'll wear that. My surprise is not at the description, I'm simply surprised that there are productive western cultures that don't fit that description.
     
  38. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,687
    Why shouldn’t we be productive with a different culture?

    I guess you know that this applause thing by the staff of an Apple Store? Or other motivation rituals? This stuff is considered as an absolutely ridiculous clown show in Germany. Secondhand embarrassment is what we feel when we see a company like Apple opening a subsidiary in Germany and trying to introduce this motivation nonsense to the German staff. Or the Plegde of Allegiance, this is unbelievable for us, just not possible that we would ever do something similar in schools. It looks like a suspicious collectively brainwash ritual for us.

    Do you think this stuff makes a culture more productive?
     
  39. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Cultural reasons tend to underlie a lot of productivity differences between countries*. Germany is currently the economic powerhouse of Western Europe. It stands to reason Germany has a strong productive culture. Which means your culture has useful ideas I can steal.

    I've had to implement American style 'congratulate everyone for just doing the job you paid them for' stuff. It can be quite cringe worthy. I'm not sure celebrating the ordinary is really a useful approach outside of the US. It seems to work for the Americans, but I haven't seen it used effectively elsewhere.

    Can't say I've ever been in an American school to make a judgement. It doesn't sound especially productive. The American schooling system has a pretty poor reputation. So I wouldn't use that as a standard for judging anything.

    Despite the problems with the American system, they are currently a dominant super power. And have been so for a while now. So it stands to reason there must be some things worth stealing from their culture.

    * There are plenty of other reasons too.
     
Thread Status:
Not open for further replies.