-1

Hello i want to parse data that i get from a websocket server but it says "cannot convert from 'string' to 'int'


And when I do then it gives me a wrong number Example:

  • real value: -11.6666342423411
  • value it says: -1.166663424234E + 16
    void Update()
    {
        ws.OnMessage += (sender, e) =>
        {
            JSONNode data = JSON.Parse(e.Data);
            Debug.Log(data);
            // position.x = int.Parse(e.Data["position"]["x"]);
            // position.y = int.Parse(e.Data["position"]["y"]);
            // Debug.Log(position);
            // gameObject.transform.position = position;

            // float rotation = data["rotation"];
            // rb.rotation = rotation;
        };
    }
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using WebSocketSharp;
using SimpleJSON;

public class Enemy : MonoBehaviour
{
    public Rigidbody2D rb;

    Vector2 position;

    WebSocket ws;
    void Start()
    {
        ws = new WebSocket("ws://localhost:8080");
        ws.Connect();
    }

    void Update()
    {
        ws.OnMessage += (sender, e) =>
        {
            // JSONNode data = JSON.Parse(e.Data);
            Debug.Log(e.Data["position"]);
            // position.x = int.Parse(e.Data["position"]["x"]);
            // position.y = int.Parse(e.Data["position"]["y"]);
            // Debug.Log(position);
            // gameObject.transform.position = position;

            // float rotation = data["rotation"];
            // rb.rotation = rotation;
        };
    }
}

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
robinnlmn
  • 21
  • 1
  • 9

1 Answers1

0

What you get parsed is the value of

-116666342423411

because int.Parse by default doesn't use a decimal point ... because there is none in an int. And then it returns an int and Unity just displays it in sceintific notation.


What you rather want to use is float.Parse since your value is supposed to be a floating point value.

Or actually now that I see you are using SimpleJson you can also simply use JsonNode.AsFloat since they already have an implementation for that.

Or if you would also use the SimpleJSONUnity.cs (Extension file) then you can actually just use JsonNode.ReadVector2!


And then you also want to access these values not in e.Data but rather in your parsed json node

position.x = float.Parse(data["position"]["x"].Value);
position.y = float.Parse(data["position"]["y"].Value);

or as said

position.x = data["position"]["x"].AsFloat();
position.y = data["position"]["y"].AsFloat();

or (using the extensions)

position = data["position"].ReadVector2();

And then in general let me immediately tell you that it won't work the way you have it!

You want to attach the listener ONCE!

And also most of Unity API can only be used in the Unity main thread and OnMessage most probably is called async.

You code should rather be e.g.

public class Enemy : MonoBehaviour
{
    public Rigidbody2D rb;

    private readonly ConcurrentQueue<Action> _actions = new ConcurrentQueue<Action>();

    WebSocket ws;
    void Start()
    {
        ws = new WebSocket("ws://localhost:8080");

        ws.OnMessage += (sender, e) =>
        {
            // dispatch this into the main thread so it is executed in the next Update call
            _actions.Enqueue(() =>
            {
                JSONNode data = JSON.Parse(e.Data);
            
                var x = float.Parse(data["position"]["x"].Value);     
                //var x = data["position"]["x"].AsFloat();
                var y = float.Parse(data["position"]["y"].Value);     
                //var y = data["position"]["y"].AsFloat();

                var position = new Vector2(x, y);
                //var position = data["position"].ReadVector2();

                Debug.Log($"Received position {position.ToString("G8")}");
                // NOTE: you should not set anything via Transform
                // otherwise you break the physics and collision detection
                rb.MovePosition(position);

                var rotation = float.Parse(data["rotation"].Value); 
                //var rotation = data["rotation"].AsFloat();
                rb.MoveRotation(rotation);
            });
        };

        ws.Connect();
    }

    void FixedUpdate()
    {
        while(_actions.Count > 0 && _actions.TryDequeue(out var action))
        {
            action?.Invoke();
        }
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
  • Then it says to me cannot convert string to int in Lines where you set the x and y – robinnlmn Sep 01 '21 at 14:10
  • @robinnlmn Could you show me the JSON format you are receiving? – derHugo Sep 01 '21 at 14:15
  • {"position":{"x":-15.184359550476075,"y":-5.733031749725342},"rotation":-322.5946350097656,"id":"1"} – robinnlmn Sep 01 '21 at 14:18
  • @robinnlmn can you check your code ... I just copied it exactly as it is into a new project together with the SimpleJson and the WebSocket stuff and have no errors ... – derHugo Sep 01 '21 at 15:31
  • @robinnlmn the one of my answer – derHugo Sep 02 '21 at 08:54
  • The threading doesn't work for me? Which import do i need to have? – robinnlmn Sep 02 '21 at 09:12
  • and for the `ConcurrentQueue` you need `using System.Collections.Concurrent;` and for the `Action` it is `using System;` (in addition to the ones you already have) if that is what you mean ;) – derHugo Sep 02 '21 at 09:15
  • Now i get an error: unity object reference not set to an instance of an object simplejson.JSONNode.Parse – robinnlmn Sep 02 '21 at 09:26