跳到主要内容
版本:PN

接入指南

说明

  • XDSDK-PNSDK 模式是对 PNSDK 的二次封装,旨在简化和统一游戏接入的流程。
  • 该模式下接口保持和 XDSDK 模式的统一,但部分接口不可用,请详细阅读 接口使用
  • 目前仅支持 Unity 接入,覆盖 iOS/Android/Windows 三大平台。
  • 目前仅支持海外应用。

配置

添加依赖

Packages/manifest.json 文件的 dependenciesscopedRegistries 中添加如下内容:

{
"dependencies": {
"com.xd.sdk.announcement": "7.4.0-pn",
"com.xd.sdk.foundation": "7.4.0-pn",
"com.xd.sdk.pn": "3.0.3-xd.1",
"com.xd.sdk.pn.oversea": "3.0.3-xd.1",
"com.xd.sdk.pn.ios-remote": "3.0.3-xd.1",
"com.unity.nuget.newtonsoft-json": "3.2.1"
},
"scopedRegistries": [
{
// NPMJS 访问不通时可以切换到淘宝源试试 https://registry.npmmirror.com
// 公司内网可使用 http://npm.xindong.com
"name": "NPMJS",
"url": "https://registry.npmjs.org/",
"scopes": [
"com.xd.sdk"
]
}
]
}

添加 PNSDK 宏

Player Settings -> Other Settings -> Scripting Define Symbols 中添加宏 PN_SDK

添加配置文件

将平台给的 PNConfig.json 文件放置在项目根目录下(请注意不是 /Assets 目录,是同级的根目录)。

iOS 配置

游戏需要自行处理 iOS 系统功能的配置,比如In-App Purchase(苹果支付)、Push Notifications(推送)、Sign In With Apple(苹果登录)。

Android 配置

环境要求:

  • minSdkVersion 24
  • targetSdkVersion 35
  • buildToolsVersion "35.0.0"
  • JDK >= 17
  • AGP >= 8.8.2
  • Gradle >= 8.10.2

开启 Android 平台配置模板文件:

  1. gradleTemplate.properties 增加配置:

    android.useAndroidX=true
    android.enableJetifier=true
  2. settings.gradle 中增加 PnSDK 的仓库配置:

    dependencyResolutionManagement {
    repositories {
    // ...
    maven {//PnSDK
    allowInsecureProtocol = true
    url 'http://git-maven.17995api.net:8888/api/v4/projects/112/packages/maven'
    }
    }
    }
  3. mainTemplate.gradle 中增加配置(解决编译重复问题 + PnSDK 缓存策略):

    android {
    // ...

    // 解决编译时的重复问题
    packagingOptions {
    exclude 'META-INF/INDEX.LIST'
    exclude 'META-INF/DEPENDENCIES'
    }
    }

    // 建议配置动态版本的缓存策略,保证能够及时更新 SDK 的版本
    configurations.all {
    resolutionStrategy.cacheDynamicVersionsFor 10, 'minutes'
    }

Windows 配置

接口使用

注意

除了本文档中列出的接口外,其余接口在 PNSDK 模式下均不可使用。

初始化

using XD.SDK.Common;

/// 初始化可配置渠道和语言参数
XDGInitParam initParam = XDGInitParam.CreateToPNSDK("android", LangType.EN);
XDGCommon.InitSDK(initParam, (success, msg) =>
{
if (success)
{
// 初始化成功
}
else
{
// 初始化失败
}
});

埋点和评分

using XD.SDK.Common;
/// 上报埋点
/// PNSDK 模式下仅支持事件名称参数
XDGCommon.TrackEvent("eventName");

/// 评分
var role = new XDGRoleInfo()
{
RoleId = "roleId",
RoleName = "roleName",
ServerId = "roleServerId",
Extra = "{ \"key1\": \"value1\", \"key2\": true, \"key3\": 1234567890 }",
RoleLevel = 10,
GameVersion = "0.0.1"
};
XDGCommon.StoreReview(role);

登录

using XD.SDK.Account;

/// 设置账户状态回调
/// PNSDK 下只有 退出登录 的回调
XDGAccount.AddUserStatusChangeCallback((type, s) =>
{
switch (type)
{
case XDGUserStatusCodeType.BIND:
/// 绑定成功
break;
case XDGUserStatusCodeType.UNBIND:
/// 解绑成功
break;
case XDGUserStatusCodeType.LOGOUT:
/// 退出登录成功
break;
case XDGUserStatusCodeType.ProtocolAgreedAfterLogout:
/// 用户在退出登录后同意了隐私协议
break;
default:
/// 其他情况
break;
}
});

/// 发起登录
/// 登录类型实际没有效果,SDK 会自动显示登录的选择页面。
/// TokenKid 和 TokenMacKey 可用于后续的服务端验证
XDGAccount.LoginByType(LoginType.Default, user =>
{
var userId = user.UserId;
var tokenKid = user.Token.Kid;
var tokenMacKey = user.Token.MacKey;
}, error =>
{
// 登录失败
});

/// 获取当前登录用户信息
var user = XDGAccount.GetCurrentUser();

/// 退出登录
XDGAccount.Logout();


/// 打开用户中心
var role = new XDGRoleInfo()
{
RoleId = "roleId",
RoleName = "roleName",
ServerId = "roleServerId",
Extra = "{ \"key1\": \"value1\", \"key2\": true, \"key3\": 1234567890 }",
RoleLevel = 10,
GameVersion = "0.0.1"
};
XDGAccount.OpenUserCenter(role);

/// 打开客服
/// PNSDK 模式下参数只有角色信息有效,其他参数无效
var role = new XDGRoleInfo()
{
RoleId = "roleId",
RoleName = "roleName",
ServerId = "roleServerId",
Extra = "{ \"key1\": \"value1\", \"key2\": true, \"key3\": 1234567890 }",
RoleLevel = 10,
GameVersion = "0.0.1"
};
XDGAccount.OpenCustomerService(GetRole(), "", null);

内购

using XD.SDK.Payment;

/// 查询商品价格
XDGPayment.QueryWithProductIds(new []{"com.demo.stone30"}, info =>
{
if (info == null || info.Count == 0) return;
foreach (var product in info)
{
var productId = product.ProductId;
var displayPrice = product.DisplayPrice;
}
}, error =>
{
// 查询失败
});

/// 发起购买
var paymentParams = new XDGPaymentParams
{
GameOrderId = "游戏订单ID,PNSDK 模式下无效",
ProductId = "商品ID",
RoleId = "角色ID",
ServerId = "服务器ID",
Extra = "透传参数",
};
XDGPayment.PayWithParams(paymentParams,
result => {
var orderId = result.GameOrderId;
var productId = result.ProductId;
var extra = result.Extra;
},
error => {
// 购买失败
});

/// 查询未完成订单
XDGPayment.QueryPendingPurchases(info =>
{
if (info == null || info.Count == 0) return;
foreach (var purchase in info)
{
var productId = purchase.ProductId;
var purchaseToken = purchase.PurchaseToken;
}
}, error =>
{
// 查询失败
});

/// 完成未完成订单
var paymentParams = new XDGPaymentParams
{
PendingPurchaseToken = "待完成订单凭据",
GameOrderId = "游戏订单ID,PNSDK 模式下无效",
ProductId = "商品ID",
RoleId = "角色ID",
ServerId = "服务器ID",
Extra = "透传参数",
};
XDGPayment.PayWithParams(paymentParams,
result => {
var orderId = result.GameOrderId;
var productId = result.ProductId;
var extra = result.Extra;
},
error => {
// 购买失败
});

分享

分享仅支持 Facebook 链接分享、Facebook 图片分享和 Instagram 图片分享。

using XD.SDK.Share;

/// facebook 图片分享,有图片时优先走图片分享
let shareParam = new XDGFacebookShareParam {
ImageUrl = "本地图片地址",
ContentText = "分享内容文本",
};

/// facebook 链接分享
let shareParam = new XDGFacebookShareParam {
LinkUrl = "链接地址",
ContentText = "分享内容文本",
};

/// instagram 图片分享
let shareParam = new XDGInstagramShareParam {
ImageUrl = "本地图片地址",
ContentText = "分享内容文本",
};

XDGSharing.Share(shareParam, new XDGShareCallback {
OnSuccess = () => {
Debug.Log("分享成功");
},
OnFailed = (code, message) => {
Debug.Log("分享失败,错误码:" + code + ",错误信息:" + message);
},
OnCancel = () => {
Debug.Log("分享取消");
}
});

公告

using XD.SDK.Announcement;

/// 获取公告列表
XDGAnnouncementManager.GetAnnouncements(announcements =>
{
if (announcements == null || announcements.Count == 0) return;
foreach (var announcement in announcements)
{
var id = announcement.Id;
var type = announcement.Type;
var shortTitle = announcement.ShortTitle;
var longTitle = announcement.LongTitle;
var publishTime = announcement.PublishTime;
var expireTime = announcement.ExpireTime;
var link = announcement.Link;
var image = announcement.Image;
var dimensions = announcement.Dimensions;
var content = announcement.Content;
}
}, error =>
{
// 获取公告失败
});