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();
    }
}
相关推荐
在路上看风景9 小时前
15. 纹理尺寸是4的倍数
unity
AT~12 小时前
unity 使用Socket和protobuf实现网络连接
unity·游戏引擎
怣疯knight18 小时前
Cocos creator判断节点是否能用的方法
unity·cocos2d
tealcwu18 小时前
Google Play的Keystore不可用时的解决方法
unity
呼呼突突18 小时前
Unity使用TouchSocket的RPC
unity·rpc·游戏引擎
qq 180809511 天前
从零构建一个多目标多传感器融合跟踪器
unity
平行云1 天前
实时云渲染支持在网页上运行UE5开发的3A大作Lyra项目
unity·云原生·ue5·webgl·虚拟现实·实时云渲染·像素流送
鹏飞于天1 天前
Shader compiler initialization error: Failed to read D3DCompiler DLL file
unity
wonder135791 天前
UGUI重建流程和优化
unity·游戏开发·ugui
那个村的李富贵2 天前
Unity打包Webgl后 本地运行测试
unity·webgl