Connection is perfect. My problem when i run unity i am getting 'character is walking' message endlessly and i must use update or fixed update methods for player classes. how i can fix it. Only ı want to hire 1 time per websocketmessage. I tryed put ws.onmessage in update method but I faced with same problem.
public class Player : MonoBehaviour
{
WebSocket ws;
int gameData;
void Start()
{
ws = new WebSocketSharp.WebSocket("ws://localhost:8080/user");
ws.Connect();
if (ws == null)
{
Debug.Log("not connected");
return;
}
else
{
Debug.Log(ws.Url);
}
ws.OnMessage += (sender, e) =>
{
Debug.Log("Message received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
switch (e.Data)
{
case "1":
// code block
gameData = Int32.Parse(e.Data);
Debug.Log("walking");
break;
case "2":
// code block
gameData = Int32.Parse(e.Data);
Debug.Log("jumping");
break;
case "3":
// code block
gameData = Int32.Parse(e.Data);
Debug.Log("hitting");
break;
case "4":
// code block
gameData = Int32.Parse(e.Data);
Debug.Log("rotation of weapon");
break;
default:
// code block
break;
}
};
}
// Update is called once per frame
void Update()
{
if(ws == null)
{
return;
}
if(Input.GetKeyDown(KeyCode.Space))
{
ws.send("jumping");
}
if(gameData == 1)
{
Debug.Log("character is walking");
}
}
in this game players will fight each other. So i must solve it
It sounds like you rather want the thing in Update to be only executed once for each received message.
First of all I would rather first parse the int and then use a switch on it. Comparing int values is cheaper than string.
And then you could use a pattern that is often referred to as "Main thread dispatcher" and goes somewhat like
public class Player : MonoBehaviour
{
WebSocket ws;
// I would use an enum to give your command indices proper names
private enum Commands
{
Walk,
Jump,
Hit,
RotateWeapon
}
// And store all available callbacks according to the commands instead of using a switch-case
private readonly Dictionary<Command, Action> _indexToCallback
{
{Command.Walk, HandleWalk},
{Command.Jump, HandleJump},
{Command.Hit, HandleHit},
{Command.RotateWeapon, HandleRotateWeapon},
};
// This is a thread-safe Queue (first-in first-out)
private readonly ConcurrentQueue<Action> _actions = new ConcurrentQueue<Action>();
void Start()
{
ws = new WebSocketSharp.WebSocket("ws://localhost:8080/user");
ws.Connect();
if (ws == null)
{
Debug.Log("not connected");
return;
}
else
{
Debug.Log(ws.Url);
}
ws.OnMessage += HandleReceivedMessage;
}
private void HandleReceivedMessage(object sender, WebSocketSharp.MessageEventArgs e)
{
Debug.Log("Message received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
if(!int.TryParse(e.Data, out var intValue)
{
Debug.LogError($"\"{Data.e}\" is not a valid number!");
return
}
var command = (Command) intValue;
if(!_indexToCommand.TryGetValue(command, out var commandAction))
{
Debug.LogError($"No callback registered for command \"{command}\"");
return;
}
// As this method might be getting called on a background thread
// this makes sure the according callback will be executed in the Unity main thread
// where you have safe access to the Unity API
_actions.Enqueue(commandAction);
}
// Update is called once per frame
void Update()
{
if(ws == null)
{
return;
}
// Work off the actions stored in the queue
while(_actions.Count > 0)
{
if(_actions.TryDequeue(out var action)
{
action?.Invoke();
}
}
if(Input.GetKeyDown(KeyCode.Space))
{
// I am not familiar with WebSocket .. maybe there is a better way than going through a `string` in general
ws.send(((int)Command.Jump).ToString());
}
}
private void HandleJump()
{
Debug.Log("Jump");
}
private void HandleWalk()
{
Debug.Log("Walk");
}
private void HandleHit()
{
Debug.Log("Hit");
}
private void HandleRotateWeapon()
{
Debug.Log("Rotate weapon");
}