You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中通过WebSocket实时发送GameObject位置至面板失败求助

问题分析与解决方案

核心问题在于:WebSocketBehavior 确实无法继承 MonoBehaviour,且直接在其中编写死循环会阻塞WebSocket的工作线程,同时Unity的主线程与WebSocket线程相互独立,无法直接通过Behavior内的循环触发实时数据推送。以下是具体解决思路和代码实现:


解决思路

  1. 拆分职责:将WebSocket服务器的生命周期管理、连接维护放在单例MonoBehaviour脚本中,利用Unity的帧更新(Update)机制触发数据发送;WebSocketBehavior仅负责处理连接、断开等会话事件。
  2. 会话管理:在MonoBehaviour中维护已连接的WebSocket会话列表,通过Unity的Update每帧遍历列表,主动推送位置数据。
  3. 线程安全:避免在WebSocket线程中直接操作Unity GameObject,所有与Unity对象相关的操作都放在主线程的Update中执行。

示例代码实现

1. WebSocket服务器管理器(MonoBehaviour单例)

using UnityEngine;
using WebSocketSharp;
using WebSocketSharp.Server;
using System.Collections.Generic;

public class WebSocketLocationServer : MonoBehaviour
{
    public static WebSocketLocationServer Instance;
    private WebSocketServer _server;
    private List<WebSocketSession> _connectedSessions = new List<WebSocketSession>();
    public Transform targetObject; // 拖拽需要追踪的GameObject Transform到这里

    private void Awake()
    {
        if (Instance == null)
            Instance = this;
        else
            Destroy(gameObject);

        // 启动WebSocket服务
        _server = new WebSocketServer("ws://localhost:8080");
        _server.AddWebSocketService<LocationSession>("/location");
        _server.Start();
    }

    private void Update()
    {
        if (targetObject == null || _connectedSessions.Count == 0)
            return;

        // 序列化位置数据(这里用简易JSON格式,也可改用Newtonsoft.Json等库)
        string locationJson = $"{{\"x\":{targetObject.position.x:F2},\"y\":{targetObject.position.y:F2},\"z\":{targetObject.position.z:F2}}}";

        // 遍历会话发送数据,用ToArray避免遍历中修改列表引发异常
        foreach (var session in _connectedSessions.ToArray())
        {
            if (session.Context.WebSocket.ReadyState == WebSocketState.Open)
                session.Send(locationJson);
            else
                _connectedSessions.Remove(session);
        }
    }

    private void OnDestroy()
    {
        _server?.Stop();
    }

    // 供WebSocket会话调用的添加/移除方法
    public void AddConnectedSession(WebSocketSession session)
    {
        if (!_connectedSessions.Contains(session))
            _connectedSessions.Add(session);
    }

    public void RemoveConnectedSession(WebSocketSession session)
    {
        if (_connectedSessions.Contains(session))
            _connectedSessions.Remove(session);
    }
}

2. WebSocket会话处理类(WebSocketBehavior)

using WebSocketSharp.Server;

public class LocationSession : WebSocketBehavior
{
    protected override void OnOpen()
    {
        WebSocketLocationServer.Instance.AddConnectedSession(this);
    }

    protected override void OnClose(CloseEventArgs e)
    {
        WebSocketLocationServer.Instance.RemoveConnectedSession(this);
    }
}

注意事项

  • 不要在WebSocketBehavior内编写无限循环,会直接阻塞WebSocket工作线程,导致连接事件无法响应。
  • 发送数据时尽量使用轻量化的序列化格式,避免频繁发送大体积数据影响性能。
  • 确保前端面板的连接地址与Unity服务器地址(ws://localhost:8080/location)完全一致,端口无冲突。

内容的提问来源于stack exchange,提问作者Jan Arend

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:35:06