Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Advanced Javascript interaction

Discussion in 'WebGL' started by tteneder, Mar 9, 2015.

  1. tteneder

    tteneder

    Unity Technologies

    Joined:
    Feb 22, 2011
    Posts:
    162
    Hi guys,

    according to the docs [1], there are a couple of ways to integrate the Unity WebGL export into a web app/Javascript.
    However, what I'm missing is passing complex data, other than floats and strings (like arrays, custom structs and objects) from Javascript to Unity and vice-verca.

    I've managed to do that successfully on iOS (il2cpp) and even Actionscript/Flash before.

    Does anybody have experience with that?

    One solution I'm about to try is serialization, but a more direct way would be prefered.

    [1] http://docs.unity3d.com/500/Documentation/Manual/webgl-interactingwithbrowserscripting.html
     
  2. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    Simple Arrays are possible (look for PrintFloatArray in the page you linked). Generic Objects or anything more complex will require serialization, though.
     
  3. tteneder

    tteneder

    Unity Technologies

    Joined:
    Feb 22, 2011
    Posts:
    162
    PrintFloatArray covers float arrays from Unity to JS, which is something. I'll give serialization a shot.

    thanks a lot
     
  4. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    If you happen to be using my asset for serialization let me know. I have a webgl build that hasn't been pushed to the asset store yet.
     
  5. tteneder

    tteneder

    Unity Technologies

    Joined:
    Feb 22, 2011
    Posts:
    162
    Hi Dustin,

    thanks for stopping by :)

    This is getting a bit off-topic. but I hope no one minds

    I tried JsonFx 1.4 first, which is nice but cannot handle things like structs (like Vectors) out of the box. So I had to work around it like this:
    Code (csharp):
    1. [JsonName("v")]
    2. public SimpleVector3 vWrapper {
    3.     get {
    4.         return v;
    5.     }
    6.     set {
    7.         v = value;
    8.     }
    9. }
    10.  
    11. [JsonIgnore]
    12. public Vector3 v;
    I'd prefer a way where I don't have to hack around in my data classes too much, so I just tried your library. I works well, but I don't know how to serialize Vectors in a decent way.

    It either includes all the (not needed) properties like this:
    Code (JavaScript):
    1. {"x":2.0,"y":3.0,"z":4.0,"normalized":{"x":0.371390671,"y":0.557086051,"z":0.742781341,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":5.38516474,"sqrMagnitude":29.0}
    or by using the JsonDotNet.Extras.CustomConverters.Vector3Converter it produces something even bigger:
    Code (JavaScript):
    1. {"Keys":["x","y","z"],"x":2.0,"y":3.0,"z":4.0,"normalized":{"x":0.37139067053794861,"y":0.55708605051040649,"z":0.74278134107589722,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":5.385164737701416,"sqrMagnitude":29.0}
    I'll investigate further, but any hint is welcome.

    Edit:

    My code btw is:
    Code (CSharp):
    1. Vector3 v = new Vector3(2,3,4);
    2.  
    3. JsonConverter converter = new JsonDotNet.Extras.CustomConverters.Vector3Converter();
    4. JsonConverter[] converters = new JsonConverter[] { converter };
    5.  
    6. Debug.Log (".net "+ JsonConvert.SerializeObject( v ) );
    7. Debug.Log (".net "+ JsonConvert.SerializeObject( v, converters ) );
    What I'd expect is:
    Code (JavaScript):
    1. {"x":2.0,"y":3.0,"z":4.0}
     
    Last edited: Mar 11, 2015
  6. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    I need to update that converter as it is incorrect. Give me a couple hours to get my kids to school and get into the office and ill send you the updated converter that correctly serializes only the x y and z properties.
     
  7. tteneder

    tteneder

    Unity Technologies

    Joined:
    Feb 22, 2011
    Posts:
    162
    sounds great! thanks!
     
  8. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Ok, here's a modified version of a fixed converter that one of my other customers created. This will work for both Vector2 and Vector3 objects. It can be modified again to support Vector4 if needed. I also need to rewrite the Matrix4x4 converter and test these all out again but this should do what you need it to do. The reason CanRead is false is because it's not needed, the Json created by this will deserialize right back into the proper type.

    Code (csharp):
    1.  
    2. public class VectorConverter : JsonConverter
    3. {
    4.   public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    5.   {
    6.  var objectType = value.GetType();
    7.  
    8.   if (objectType == typeof(Vector2))
    9.   {
    10.   var vec2 = (Vector2)value;
    11.  
    12.   writer.WriteStartObject();
    13.   writer.WritePropertyName("x");
    14.   writer.WriteValue(vec2.x);
    15.   writer.WritePropertyName("y");
    16.   writer.WriteValue(vec2.y);
    17.   writer.WriteEndObject();
    18.   }
    19.   else if(objectType == typeof(Vector3))
    20.   {
    21.   var vec3 = (Vector3)value;
    22.  
    23.   writer.WriteStartObject();
    24.   writer.WritePropertyName("x");
    25.   writer.WriteValue(vec3.x);
    26.   writer.WritePropertyName("y");
    27.   writer.WriteValue(vec3.y);
    28.   writer.WritePropertyName("z");
    29.   writer.WriteValue(vec3.z);
    30.   writer.WriteEndObject();
    31.   }
    32.   }
    33.  
    34.   public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    35.  {
    36.  throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    37.  }
    38.  public override bool CanRead
    39.  {
    40.  get { return false; }
    41.  }
    42.  
    43.   public override bool CanConvert(Type objectType)
    44.   {
    45.   return objectType == typeof(Vector2) || objectType == typeof(Vector3);
    46.   }
    47. }
    48.  
     
  9. tteneder

    tteneder

    Unity Technologies

    Joined:
    Feb 22, 2011
    Posts:
    162
    Thanks Dustin, this creates a perfect JSON.

    One problem though:
    The WebGL export throws an exception, since it seems to use Reflections:

    I guess that's somewhat similar to the AOT problem on iOS. Do you know how to avoid this or do you have a plan on bringing a WebGL compatible version?

    Cheers,
    Andreas
     
  10. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Ohhh... Drop me an email or a PM with your email address. I have a WebGL build already done. It just hasn't been pushed to the asset store yet. I'll email it over to you if you sent me your email address.
     
  11. tteneder

    tteneder

    Unity Technologies

    Joined:
    Feb 22, 2011
    Posts:
    162
    excellent. thanks!
     
  12. alpdogan

    alpdogan

    Joined:
    May 8, 2015
    Posts:
    10
    Hello Dustin,

    Do you have your json.Net WebGl ready?
     
  13. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    It is. I'll be submitting the update by the end of the week, but if you've purchased you can PM me with your email address and invoice number and I'll send you the WebGL update.
     
    liortal likes this.
  14. tteneder

    tteneder

    Unity Technologies

    Joined:
    Feb 22, 2011
    Posts:
    162
    Hi guys,

    I've been working with this now for a while and just wanted to share some experiences:

    JSON serialization works fine, but we ran into performance bottlenecks. Basically we're pushing vector arrays with quite a size into Unity. Originally a call like that took 3.3 seconds.
    I then wrote a custom parser, for this very specific JSON structure, which did run in just under 0.9 seconds.
    Our third try was to convert the array into a binary buffer, and encode it with base64. We're now at around 0.3 seconds.

    So if you need to push lots of data beware that the very generic and handy JSON serialization can be very slow sometimes.

    cheers,
    atti