Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity websocket.onmessage在update或fixedupdate方法中工作_C#_Unity3d - Fatal编程技术网

C# Unity websocket.onmessage在update或fixedupdate方法中工作

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

连接是完美的。我的问题是,当我运行unity时,我得到了“角色正在行走”的信息 我必须对玩家类使用更新或固定更新方法。我怎样才能修好它。每个websocketmessage只想租用1次。我尝试将ws.onmessage放在更新方法中,但我遇到了同样的问题

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(“旋转武器”);
}