C# Unity websocket.onmessage在update或fixedupdate方法中工作
连接是完美的。我的问题是,当我运行unity时,我得到了“角色正在行走”的信息 我必须对玩家类使用更新或固定更新方法。我怎样才能修好它。每个websocketmessage只想租用1次。我尝试将ws.onmessage放在更新方法中,但我遇到了同样的问题C# Unity websocket.onmessage在update或fixedupdate方法中工作,c#,unity3d,C#,Unity3d,连接是完美的。我的问题是,当我运行unity时,我得到了“角色正在行走”的信息 我必须对玩家类使用更新或固定更新方法。我怎样才能修好它。每个websocketmessage只想租用1次。我尝试将ws.onmessage放在更新方法中,但我遇到了同样的问题 public class Player : MonoBehaviour { WebSocket ws; int gameData; void Start() { ws = new WebSock
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");
}
}
在这个游戏中,玩家将互相争斗。因此,我必须解决它听起来您更希望
更新
中的内容只对每个收到的消息执行一次
首先,我宁愿先解析int,然后在其上使用开关。比较int
值比string
便宜
然后您可以使用一种模式,这种模式通常被称为“主线程调度程序”,类似于
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");
}
公共类玩家:单行为
{
WebSocket ws;
//我会用一个枚举来给你的命令索引命名
私有枚举命令
{
步行
跳
打
罗特瓦彭
}
//并根据命令存储所有可用回调,而不是使用开关盒
专用只读词典\u IndextocalBack
{
{Command.Walk,HandleWalk},
{Command.Jump,HandleJump},
{Command.Hit,HandleHit},
{Command.rotatewapon,handlerotateWearm},
};
//这是一个线程安全队列(先进先出)
私有只读ConcurrentQueue _actions=new ConcurrentQueue();
void Start()
{
ws=newwebsocketsharp.WebSocket(“ws://localhost:8080/user”);
ws.Connect();
如果(ws==null)
{
Debug.Log(“未连接”);
回来
}
其他的
{
Log(ws.Url);
}
ws.OnMessage+=HandlerReceivedMessage;
}
private void HandlerReceivedMessage(对象发送者,WebSocketSharp.MessageEventArgs e)
{
Log(“从“+((WebSocket)发送方.Url+”接收的消息,数据:“+e.Data”);
如果(!int.TryParse(e.Data,out var intValue)
{
Debug.LogError($“\{Data.e}\”不是一个有效的数字!);
回来
}
var命令=(命令)intValue;
if(!\u indexToCommand.TryGetValue(命令,out var commandAction))
{
LogError($“没有为命令\“{command}\”注册回调”);
回来
}
//因为此方法可能在后台线程上被调用
//这将确保在Unity主线程中执行相应的回调
//您可以安全访问Unity API的地方
_动作。排队(commandAction);
}
// 每帧调用一次更新
无效更新()
{
如果(ws==null)
{
回来
}
// 处理队列中存储的操作
而(_actions.Count>0)
{
if(_actions.TryDequeue(out var action)
{
action?.Invoke();
}
}
if(Input.GetKeyDown(KeyCode.Space))
{
//我对WebSocket不太熟悉。也许有一种方法总的来说比使用“字符串”更好
ws.send(((int)Command.Jump.ToString());
}
}
私有void HandleJump()
{
Log(“跳转”);
}
私有无效HandleWalk()
{
Debug.Log(“Walk”);
}
私有void HandleHit()
{
Log(“Hit”);
}
私有无效句柄旋转武器()
{
Log(“旋转武器”);
}