How to properly split string received from server to update Vector3?
Hi guys,
I've been trying to update my player's position and rotation with the values received via UDP socket. The data comes without any difficulties, however the final step of assigning the received values to the Vector3 is problematic for me. I'm poorly experienced in C#, that's why all the errors appear because of incorrect syntaxes. Could somebody please fix my code. Thanks a lot in advance.
I won't post the whole code here, since it's working and the data is received. Here is the final step of the data application. Please, tell me if the whole code is needed.
private void receiveData() {
Debug.Log("Trying to receive data...");
byte[] data = udpServer.Receive(ref remoteEP);
if (data.Length > 0)
{
var str = System.Text.Encoding.Default.GetString(data);
Debug.Log("Received Data" + str);
string[] messageParts = str.Split(',');
Vector3.transform.position = new Vector3(
messageParts[0],
messageParts[1],
messageParts[2]
);
Vector3 transform.rotation = new Vector3(
messageParts[3],
messageParts[4],
messageParts[5]
);
}
}
EDIT The issue is solved now, thanks to @Hellium Here is the final working script (must be cleaned though). The object receives the coordinates and updates Transform component properly.
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class PlayerBehavior : MonoBehaviour {
private UdpClient udpServer;
public GameObject cube;
private Vector3 tempPos;
private Thread t;
public float movementSpeed;
private long lastSend;
private IPEndPoint remoteEP;
private float[] transformPosition = new float[3] ;
void Start()
{
udpServer = new UdpClient(1234);
t = new Thread(() => {
while (true) {
this.receiveData();
}
});
t.Start();
t.IsBackground = true;
remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 41234);
}
void Update()
{
transform.position = new Vector3(transformPosition[0], transformPosition[1], transformPosition[2]) ;
}
private void OnApplicationQuit()
{
udpServer.Close();
t.Abort();
}
private void receiveData() {
byte[] data = udpServer.Receive(ref remoteEP);
if (data.Length > 0)
{
var str = System.Text.Encoding.Default.GetString(data);
Debug.Log("Received Data" + str);
string[] messageParts = str.Split(',');
transformPosition[0] = float.Parse(messageParts[0]) ;
transformPosition[1] = float.Parse(messageParts[1]) ;
transformPosition[2] = float.Parse(messageParts[2]) ;
}
}
}
If it's not a problem for you, I would suggest you using a standard data format (JSON / X$$anonymous$$L / ...) in order to transmit your data, and having libraries do the serialization / deserialization for you.
Unity has a simple JSONUtility class which may cover your needs.
Thanks for your advice, but the server is written not by me. And I would really like not to bother that person too much. Of course if standardization of the data into JSON is the only option, I will do that. But thanks anyways
Answer by tormentoarmagedoom · Aug 02, 2018 at 09:35 AM
Good day, I'm not sure what you recieve with recieve data, but if you have a string with numbers and need to transfomr it into a vector3, you should take a look at these 2 functions:
Substring: To take only the characters you need from the string data
Parse: To transform the string numbers to float values
Then you can build your Vector3.
Bye!
Answer by ivanshv · Aug 02, 2018 at 10:05 AM
@tormentoarmagedoom Sorry for commenting as a reply, don't know why "add comment" button doesn't work for me.
Thank you very much for your reply. Yes, I receive a string with 3 different numbers split by ",". Here is the part of a python code of the server (written not by me)
msg = '%s, %s, %s'%(update_dict['x'], update_dict['y'], update_dict['z'])
sock.sendto(msg,addr)
# print('send message %r to %s'%(msg,addr))
# these "%s values are retrieved from another server, and in unity I get pure numbers
Parse function is great, and causes no errors with syntaxes (for now). However, I get another error. If you could spend some time and have a quick look, that would be great.
Here is the code i have now:
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class PlayerBehavior : MonoBehaviour {
private UdpClient udpServer;
public GameObject cube;
private Vector3 tempPos;
private Thread t;
public float movementSpeed;
private long lastSend;
private IPEndPoint remoteEP;
void Start()
{
udpServer = new UdpClient(1234);
t = new Thread(() => {
while (true) {
this.receiveData();
}
});
t.Start();
t.IsBackground = true;
remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 41234);
}
private long UnixTimeNow()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalMilliseconds;
}
private void OnApplicationQuit()
{
udpServer.Close();
t.Abort();
}
void Update()
{
var isShift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
if (isShift)
{
Debug.Log("Shift");
}
var x = Input.GetAxis("Horizontal") * Time.deltaTime * this.movementSpeed;
var z = Input.GetAxis("Vertical") * Time.deltaTime * this.movementSpeed;
cube.transform.Translate(x, 0, 0);
cube.transform.Translate(0, 0, z);
if (cube.transform.position != tempPos)
{
if (UnixTimeNow() - this.lastSend > 1000 / 24)
{
this.lastSend = UnixTimeNow();
byte[] arr = Encoding.ASCII.GetBytes(cube.transform.position.x + ";" + cube.transform.position.y + ";" + cube.transform.position.z);
udpServer.Send(arr, arr.Length, remoteEP);
}
}
tempPos = cube.transform.position;
}
private void receiveData() {
Debug.Log("Trying to receive data...");
byte[] data = udpServer.Receive(ref remoteEP);
if (data.Length > 0)
{
var str = System.Text.Encoding.Default.GetString(data);
Debug.Log("Received Data" + str);
string[] messageParts = str.Split(',');
transform.position = new Vector3(
float.Parse(messageParts[0]),
float.Parse(messageParts[1]),
float.Parse(messageParts[2])
);
}
}
}
And here is the error: "get_transform can only be called from the main thread. Constructors and field initializers will be executed from the loading thread when loading a scene."
Thank you!
Good day.
I'm sorry i dont have enough scripting knowladge, not even sure what are you saying..... $$anonymous$$aybe Hellium or Bunny can help you.
Bye!
The issue is solved now, thanx to Hellium. I will post the final working code here for future users. But thank you for the effort and the parse function.
Your answer
Follow this Question
Related Questions
Vector3.MoveTowards moving transform 0 Answers
(26,47): error CS1525: Unexpected symbol `)' 1 Answer
Operator '==' is ambiguous on operands of type 'Vector2' and 'Vector3' 1 Answer
Need help with this code? thanks. 2 Answers
Can’t keep the position 0 Answers