0

I am using the 'Socket.IO for Unity' plugin and sending data to the server using JSONObject, but I can't convert from string to float.

Using:

Debug.Log(e.data.GetField("vertical").ToString());

Correctly returns me the string "0,978"

But 'float.Parse' works with any string except from a JsonObject, such as taking the JsonObject string above and using float.Parse:

float.Parse (e.data.GetField("vertical").ToString())

Simply interrupting the rest of the code without any console errors, the game goes on perfectly but without returning the float! What may be happening? Does anyone have any ideas?

My code:

public void PlayerAnim(SocketIOEvent e){
    if(e.data.GetField("id").ToString () == id){
        anim.SetFloat ("IsRunning", Mathf.Abs (float.Parse (e.data.GetField("vertical").ToString()) + Mathf.Abs (float.Parse (e.data.GetField("horizontal").ToString()))));
    }
}
Will John
  • 25
  • 7
  • Unlikely that a line gets just skipped .. you should get an exception somewhere in the console? – derHugo Dec 05 '19 at 20:46
  • @derHugo Amazingly I don't get anything on the console! So I already have a headache for not knowing what the problem is! – Will John Dec 05 '19 at 20:48

3 Answers3

1

You can use comma as the separator.

Excerpt from here:

var culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.NumberFormat.NumberDecimalSeparator = ",";

// If this is supposed to return a value from a method, use return
return float.Parse (e.data.GetField("vertical").ToString(), culture);

EDIT:

public void PlayerAnim(SocketIOEvent e){
    var culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
    culture.NumberFormat.NumberDecimalSeparator = ",";

    if(e.data.GetField("id").ToString () == id){
        anim.SetFloat ("IsRunning", Mathf.Abs (float.Parse (e.data.GetField("vertical").ToString(), culture) + Mathf.Abs (float.Parse (e.data.GetField("horizontal").ToString(), culture))));
    }
    else 
    {
      // Throw or some other statement to see if id does not match
    }
}
Jawad
  • 11,028
  • 3
  • 24
  • 37
  • Still the same thing, nothing happens! I do not understand, it makes no sense not to convert if when I debug returns a string! – Will John Dec 05 '19 at 20:24
  • are you assigning the value once you are done parsing? like var result = float.Parse(...); – Jawad Dec 05 '19 at 20:31
  • or perhaps add the "return" statement. – Jawad Dec 05 '19 at 20:31
  • Using like this: anim.SetFloat ("IsRunning", Mathf.Abs (float.Parse (e.data.GetField ("vertical"). ToString ()) + Mathf.Abs (float.Parse (e.data.GetField (" horizontal "). ToString ()))))); And also: Debug.Log (float.Parse (e.data.GetField ("vertical"). ToString ()); – Will John Dec 05 '19 at 20:34
  • Please post it in your question – Jawad Dec 05 '19 at 20:35
  • I used CultureInfo, even copied your code in your current answer but it didn't work either! – Will John Dec 05 '19 at 20:54
  • Get rid of the if statement and see if that fixes it – Jawad Dec 05 '19 at 20:58
  • If statement is not the problem, because anything above the code where the conversion happens works, but nothing below it works as errors happen but are not displayed in the console. – Will John Dec 05 '19 at 21:06
  • try / catch -> debug.log – Jawad Dec 05 '19 at 21:07
1

You need to use the JSONObject extensions. There is a f extension that will extract a float for you.

Server:

socket.emit('hello', {float: 0.978});

Unity:

socket.On ("hello", (message) => {
   var myValue = message.data.GetField("float").f; 
   // or var myValue = message.data["float"].f;
});

The asset is really old and there are issues with using the default JSONObject class as I remember that it would swallow errors during serializing/parsing. It is worth looking at the Best HTTP 2 asset which is updated more regularly.

However, your code even with the additional casting, may work and would set a breakpoint and simply evaluate the float.Parse (e.data.GetField("vertical").ToString()) statement to make sure.

Samuel Goldenbaum
  • 18,391
  • 17
  • 66
  • 104
  • It worked perfectly, thank you <3. I really wanted to buy this asset, it sounds interesting, but I live in Brazil, the dollar is extremely expensive, in the future I think about buying it, could I easily replace my code in the future from Socketio for Unity with Best HTTP / 2? – Will John Dec 05 '19 at 21:23
  • 1
    You would have to do some work abstracting your server service. The problem I recall is that `Socket.IO for Unity` is pretty tightly coupled to `JSONObject` which is a pain. I used this for 3+ years on a large MMO game so it works, but I am now switching away as it has been deprecated. I believe Best HTTP socket.io allows you to plug in your favorite Json decoder. Assets are on sale at the moment so would be a good time to invest, – Samuel Goldenbaum Dec 05 '19 at 21:32
0

The default format provider expects a . as decimal marker. You can parse floats with commas by providing an appropriate IFormatProvider

float.Parse (e.data.GetField("vertical").ToString(), System.Globalization.CultureInfo.GetCultureInfo("de-DE"));
  • Still the same thing, nothing happens! I do not understand, it makes no sense not to convert if when I debug returns a string! – Will John Dec 05 '19 at 20:24
  • What happens if you assign to a string first and debug? Example `string vertical = e.data.GetField("vertical").ToString();`? Do you get the correct result when you parse this string? –  Dec 05 '19 at 20:28
  • Yes, it returns correctly, and if I convert a string for example string s = "0,9562"; Converts perfectly from string to float, just doesn't work from JsonObject to float! – Will John Dec 05 '19 at 20:29
  • Yeah that's really bizarre. I would just cache it to a string and then just parse the string version. Could you post more of the code? I've only seen this sort of behavior in thread racing but I don't think that is whats going on here. –  Dec 05 '19 at 20:34
  • Yes, but nothing happened – Will John Dec 05 '19 at 20:42