Unity接入Steamworks.NET实现通信功能

研究了下怎么使用Steam平台提供的方式实现网络通信。

以下是基础功能代码,MessageBase没有上传,后续研究透彻了会补充更新。

需要保证电脑上登录了Steam平台应用程序,目前先测试了获取自身SteamID,实现了自己的收发消息功能。
Steamworks.NET

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Steamworks;


public class SteamNetworkController : MonoBehaviour
{
    public static bool showLog = true;
    private CSteamID m_steamId;

    private Callback<P2PSessionRequest_t> m_P2PSessionRequest;
    private Callback<P2PSessionConnectFail_t> m_P2PSessionConnectFail;
    private Callback<SocketStatusCallback_t> m_SocketStatusCallback;
    //private Callback<P2PSessionState_t> m_P2PSessionState;

    private void Awake()
    {
        //初始化SteamAPI
        SteamAPI.Init();
    }
    private void Start()
    {
        m_steamId = SteamUser.GetSteamID();
        Debug.Log("当前steamId=" + SteamUser.GetSteamID());
        //Debug.Log("当前登录用户名:" + SteamFriends.GetPersonaName());

        m_P2PSessionRequest = Callback<P2PSessionRequest_t>.Create(OnP2PSessionRequest);
        m_P2PSessionConnectFail = Callback<P2PSessionConnectFail_t>.Create(OnP2PSessionConnectFail);
        m_SocketStatusCallback = Callback<SocketStatusCallback_t>.Create(OnSocketStatusCallback);

    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            //模拟发送消息
            SendP2PPacket(m_steamId, EMsgType.Content, "test");
        }
        //循环接收消息
        UpdateReadP2PPacket();
    }
    private void OnP2PSessionRequest(P2PSessionRequest_t pCallback)
    {
        bool ret = SteamNetworking.AcceptP2PSessionWithUser(pCallback.m_steamIDRemote);
        m_steamId = pCallback.m_steamIDRemote;

        if (showLog) Debug.LogFormat("获取的用户ID结果={0} id={1}", ret, m_steamId.m_SteamID);
    }

    private void OnP2PSessionConnectFail(P2PSessionConnectFail_t pCallback)
    {
        if (showLog) Debug.LogFormat("OnP2PSessionConnectFail steamIDRemote={0},error={1}", pCallback.m_steamIDRemote, pCallback.m_eP2PSessionError);
    }

    private void OnSocketStatusCallback(SocketStatusCallback_t pCallback)
    {
        if (showLog) Debug.LogFormat("OnSocketStatusCallback steamIDRemote={0},socketState={1}", pCallback.m_steamIDRemote, pCallback.m_eSNetSocketState);
    }

    private void OnP2PSessionState(P2PSessionState_t pCallback)
    {
        if (showLog) Debug.LogFormat("OnP2PSessionState connect={0},error={1}", pCallback.m_bConnecting, pCallback.m_eP2PSessionError);
    }
    /// <summary>
    /// 发送消息
    /// </summary>
    /// <param name="steamID"></param>
    /// <param name="msgType"></param>
    /// <param name="msg"></param>
    public static void SendP2PPacket(CSteamID steamID, EMsgType msgType, string msg)
    {
        uint msgIndex = CreateMsgIndex();
        MessageBase messageBase = new MessageBase();
        byte[] bytes = messageBase.Combination(msgType, msgIndex, msg);
        SteamNetworking.SendP2PPacket(steamID, bytes, (uint)bytes.Length, EP2PSend.k_EP2PSendReliable);
        if (showLog) Debug.LogFormat("发送消息,index={0},type={1},msg={2},长度={3}", msgIndex, msgType.ToString(), msg,bytes.Length);
    }
    /// <summary>
    /// 接收消息
    /// </summary>
    public bool UpdateReadP2PPacket()
    {
        uint MsgSize;
        bool ret = SteamNetworking.IsP2PPacketAvailable(out MsgSize);
        if (MsgSize <= 0)
        {
            return false;
        }
        byte[] bytes = new byte[MsgSize];
        uint newMsgSize;
        CSteamID SteamIdRemote;
        ret = SteamNetworking.ReadP2PPacket(bytes, MsgSize, out newMsgSize, out SteamIdRemote);
        if (ret)
        {
            MessageBase messageBase = new MessageBase();
            messageBase.AnalysisMsg(bytes);
            ProcessMessage(messageBase, SteamIdRemote);
            if (showLog) Debug.LogFormat("接收的消息,steaId={0},length={1},index={2},type={3},msg={4}", SteamIdRemote, bytes.Length, messageBase.MsgIndex, messageBase.MsgType, messageBase.MsgContent);
        }
        return true;
    }
    /// <summary>
    /// 处理接收到的消息
    /// </summary>
    /// <param name="msgBase"></param>
    /// <param name="steamID"></param>
    private void ProcessMessage(MessageBase msgBase, CSteamID steamID)
    {
        switch (msgBase.MsgType)
        {
            case EMsgType.Heartbeat:
                break;
            case EMsgType.Content:
                break;
            case EMsgType.Chat:
                break;
            case EMsgType.Invite:
                break;
            case EMsgType.Step:
                break;
            case EMsgType.Rectify:
                break;
            case EMsgType.Wait:
                break;
            default:
                break;
        }
    }

    private static uint msgIndex = 0;
    private static uint CreateMsgIndex()
    {
        msgIndex++;
        return msgIndex;
    }

    private void OnDestroy()
    {
        // Just incase we have it open when we close/assemblies get reloaded.
        if (!m_steamId.IsValid())
        {
            SteamNetworking.CloseP2PSessionWithUser(m_steamId);
        }
        SteamAPI.Shutdown();
    }
}
相关推荐
Thomas_YXQ5 小时前
Unity3D游戏内存优化指南
游戏·unity·职场和发展·性能优化·蓝桥杯·游戏引擎·unity3d
枯萎穿心攻击14 小时前
响应式编程入门教程第二节:构建 ObservableProperty<T> — 封装 ReactiveProperty 的高级用法
开发语言·unity·c#·游戏引擎
X_StarX1 天前
【Unity笔记02】订阅事件-自动开门
笔记·学习·unity·游戏引擎·游戏开发·大学生
Thomas_YXQ1 天前
Unity URP法线贴图实现教程
开发语言·unity·性能优化·游戏引擎·unity3d·贴图·单一职责原则
徐子竣2 天前
[学习记录]Unity-Shader-几何着色器
unity·游戏引擎·着色器
EQ-雪梨蛋花汤2 天前
【Part 3 Unity VR眼镜端播放器开发与优化】第四节|高分辨率VR全景视频播放性能优化
unity·音视频·vr
与火星的孩子对话2 天前
Unity进阶课程【六】Android、ios、Pad 终端设备打包局域网IP调试、USB调试、性能检测、控制台打印日志等、C#
android·unity·ios·c#·ip
幻世界2 天前
【Unity智能模型系列】Unity + MediaPipe + Sentis + ArcFace模型:构建高效人脸识别比对系统
unity·游戏引擎
死也不注释3 天前
【Unity 编辑器工具开发:GUILayout 与 EditorGUILayout 对比分析】
unity·编辑器·游戏引擎