La conexión es perfecta. Mi problema cuando ejecuto Unity, recibo el mensaje "El personaje está caminando" sin cesar y debo usar métodos de actualización o actualización fija para las clases de jugadores. como puedo arreglarlo Solo quiero contratar 1 vez por mensaje websocket. Intenté poner ws.onmessage en el método de actualización, pero me encontré con el mismo problema.
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"); } }en este juego los jugadores lucharán entre sí. entonces debo resolverlo
Parece que prefiere que la cosa en Update solo se ejecute una vez por cada mensaje recibido.
En primer lugar, preferiría analizar primero el int y luego usar un switch en él. Comparar valores int es más barato que string .
Y luego podría usar un patrón que a menudo se conoce como "Despachador de hilo principal" y es algo así como
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"); }