Unity 接入 Steam 平台

需求

使用 Unity 引擎为游戏接入 steam 渠道,上架 steam 平台。需要接入 steam 登录和支付功能。
登录功能:https://partner.steamgames.com/doc/features/auth
应用内购买功能:https://partner.steamgames.com/doc/features/microtransactions/implementation

实现

根据 steam 文档 商用引擎和非 C++ 语言支持 ,steam sdk 不支持 unity 原生端,需要使用第三方插件 Steamworks.NET

  1. 安装 Steamworks.NET ,推荐使用 方式 A 安装。安装完成后,项目的 Assets/ 文件下会增加 com.rlabrecque.steamworks.net 文件夹,和 Script/Steamworks.NET 下有 SteamManager 文件。项目的根目录还会自动生成一个 steam_appid.txt 文件(注意这个文件不能删除)。

  2. 修改 steam_appid.txt 文件里的 AppId(480)修改成你项目的 AppId。

  3. 找到 SteamManager 文件下的 SteamAPI.RestartAppIfNecessary(AppId_t.Invalid) 打开 AppId_t 类,替换 Invalid 的属性,使用你项目的 AppId .
    在这里插入图片描述

  4. 重启 Unity 使 steam_appid.txt 文件生效。

  5. 经过以上步骤,steamworks 安装成功。

  6. 根据 Getting Started with Steamworks.NET 初始化 Steamworks 。具体操作如下:

    1. 将 SteamManager.cs 挂在项目第一个场景上,这个场景不会被销毁的。
    2. 创建一个实现 steam 的脚本,将这个脚本也挂在 项目的第一个场景上。
    3. Start() 生命周期方法中发送获取登录票证的方法: SteamUser.GetAuthTicketForWebApi(mSteamID.ToString());
    4. OnEnable() 生命周期方法中注册监听票据的回调。
    5. 在回调中获取到 steam 返回的票据发送到您的服务器验证。

由于 steam 文档不是特别清晰,可以参考 steamworks 的示例代码:https://github.com/rlabrecque/Steamworks.NET-Test

代码如下:

public class SteamScript : MonoBehaviour
    {
        private const string Tag = "[SteamScript]";

        //每次激活或停用 Steam Overlay 时,它都会向您发送回调。
        protected Callback<GameOverlayActivated_t> m_GameOverlayActivated;

        // 等待票据验证
        protected Callback<GetTicketForWebApiResponse_t> m_GetTicketForWebApiResponse;

        void Start()
        {
            if (SteamManager.Initialized)
            {
              // 获取 steam 用户信息
                CSteamID cSteamID = SteamUser.GetSteamID();
                var mSteamID = cSteamID.m_SteamID;
                // 发起获取票据请求https://partner.steamgames.com/doc/api/ISteamUser#GetAuthTicketForWebApi
                SteamUser.GetAuthTicketForWebApi(mSteamID.ToString());
            }
            
        }

        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                SteamAPICall_t handle = SteamUserStats.GetNumberOfCurrentPlayers();
                m_NumberOfCurrentPlayers.Set(handle);
                NtLog.Log(NtLog.NtLogLevel.Debug, Tag, "Called GetNumberOfCurrentPlayers()");
            }
        }

        /**
         * 我们通常在 OnEnable 中执行此操作,因为这允许我们在 Unity 重新加载程序集后重新创建回调。
         */
        private void OnEnable()
        {
            m_GameOverlayActivated = Callback<GameOverlayActivated_t>.Create(OnGameOverlayActivated);

            m_GetTicketForWebApiResponse = Callback<GetTicketForWebApiResponse_t>.Create(OnGetTicketForWebApiResponse);
        }

        private void OnDisable()
        {
            m_GameOverlayActivated = null;
            m_GetTicketForWebApiResponse = null;
        }

        private void OnGameOverlayActivated(GameOverlayActivated_t pCallback)
        {
            if (pCallback.m_bActive != 0)
            {
                NtLog.Log(NtLog.NtLogLevel.Debug, Tag, "Steam Overlay has been activated");
            }
            else
            {
                NtLog.Log(NtLog.NtLogLevel.Debug, Tag, "Steam Overlay has been closed");
            }
        }

        private void OnGetTicketForWebApiResponse(GetTicketForWebApiResponse_t pCallback)
        {
            NtLog.Log(NtLog.NtLogLevel.Information, tag, "Get ticket code:", pCallback.m_eResult);
            if (pCallback.m_eResult == EResult.k_EResultOK)
            {
                // 获取成功
                // 将 GetAuthTicketForWebApi 中的二进制票证数据转换为十六进制字符串
                // 
                string ticket = BitConverter.ToString(pCallback.m_rgubTicket);
                // 请求验证
                var mSteamID = SteamUser.GetSteamID().m_SteamID;
                if (mSteamID == 0 || string.IsNullOrEmpty(ticket))
                {
                    NtLog.Log(NtLog.NtLogLevel.Error, Tag, "steam id or ticket is null.");
                    return;
                }
// 将票据发送到你的服务器验证
                GetThirdLoginUserInfo(mSteamID.ToString(), ticket);
            }
            else
            {
                // 其他失败的处理
            }
        }


        /**
         * 三方登录,后续有其他三方登录,可以移到其他地方封装,整理框架模式
         */
        internal void GetThirdLoginUserInfo(string thirdUid, string thirdToken)
        {
            // 将 steam 票据信息发送到你的服务器验证
        }

       
    }

遇到的问题及注意点:

  1. 测试阶段,使用的不是商店的steam 账号,初始化也失败了。

  2. appId 需要修改 两个地方,且必须修改,一个是项目自动生成的steam_appid.txt 文件,否则登录会失败,一个是 AppId_t 文件下的appId 。不能删除,否则还会自动生成错误的。除非修改自动生成的文件路径。

  3. 没有安装steam 时,无法初始化成功。下载 steam 和 登录账号后初始化成功。

  4. 没有登录steam 账号也会初始化失败。

  5. 以下情况都会初始化失败。参考官方文档:https://partner.steamgames.com/doc/api/steam_api#SteamAPI_RunCallbacks

    1. Steam 客户端未运行。 需要有运行的 Steam 客户端才能提供各种 Steamworks 接口的实现。

    2. Steam 客户端无法判定游戏的 App ID。 如果您直接通过可执行文件或调试器运行您的应用程序,那么您的游戏目录中的可执行文件旁,必须有一个 steam_appid.txt,其中只记录了您的应用 ID,此外不含有任何其他内容。 Steam 将在当前工作目录中查找此文件。 如果您从不同的目录中运行可执行文件,您也许需要重新定位 steam_appid.txt 文件。

    3. 您的应用程序运行的 OS 用户上下文,与 Steam 客户端并不相同,比如用户或管理员访问权限级别不同。

    4. 确定您在当前活跃的 Steam 帐户中拥有该 App ID 的许可。 您的游戏必须显示在您的 Steam 库中。

    5. 您的 AppID 未完全设置,如 发行状态:不可用,或缺失默认程序包。

支付的实现

待实现

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值