业务需求,开始接触一下抖音小游戏相关的内容,开发过程中记录一下流程。
抖音云官方文档:https://developer.open-douyin.com/docs/resource/zh-CN/developer/tools/cloud/develop-guide/cloud-function-debug
1.开通抖音云环境
抖音云地址:https://cloud.douyin.com/
【抖音云】-【小游戏】点击你要开通的小游戏
显示开通中即为申请成功
2.开启云数据库
【组件中心】-【文档型数据库】-【云数据库】。填入申请即可
数据库是json的形式这个和微信一样,通过了之后点击管理就可以创建数据集合了
3.创建云函数环境
【服务管理】-【服务列表】
点击新建后,可以服务类型选择云函数,因为抖音的文档是Ts的示例,接口的都是些Ts,这里可以先把Ts勾上。不勾的话云函数是js的。
4.创建云函数
进来之后,界面是一个云函数编辑器的样式
点击这这里可以创建新的云函数脚本
打勾的是已经发布的。黄色点未发布的
5.云函数调用数据库
创建云函数后已经有一个代码模板了,可以通用后面的一些方法
/**
* @param params 调用参数,HTTP 请求下为请求体
* @param context 调用上下文
*
* @return 函数的返回数据,HTTP 场景下会作为 Response Body
*
*/
import { dySDK } from '@open-dy/node-server-sdk';
export default async function (params: any, context: any) {
return {
"message": "hello",
};
};
function getContext(context: any) {
const serviceContext = dySDK.context(context);
return serviceContext.getContext();
}
async function callContainer(context: any, serviceId: string,
path: string,
method: string,
querys?: Record<string, any>,
data?: any,
headers?: Record<string, any>) {
const serviceContext = dySDK.context(context);
return serviceContext.callContainer({
"serviceId": serviceId,
"path": path,
"method": method,
"querys": querys,
"data": data,
"headers": headers,
});
}
async function openApiInvoke(context: any, url: string,
method: string,
querys?: Record<string, any>,
data?: any,
headers?: Record<string, any>) {
const serviceContext = dySDK.context(context);
return serviceContext.openApiInvoke({
"url": url,
"method": method,
"querys": querys,
"data": data,
"headers": headers
})
}
这里扩展一个加载用户数据的脚本
/**
* @param params 调用参数,HTTP 请求下为请求体
* @param context 调用上下文
*
* @return 函数的返回数据,HTTP 场景下会作为 Response Body
*
*/
import { dySDK } from '@open-dy/node-server-sdk';
export default async function (params: any, context: any) {
const dyContext = getContext(context);
const db = dySDK.database();
const userdata = db.collection('UserData');
let openid = 0;
if (dyContext.openId == '') {
//没有openId,用户没登录,这时候用传参进来的deviceID代替
console.log('no logined')
openid = params.deviceId;
}
else {
console.log('logined')
openid = dyContext.openId
}
const data = await userdata.where({
openid: openid
}).get();
if (data.data.length == 0) {
console.log("没有找到目标数据" + openid + ",," + params.deviceId)
return {
code: 0,
openid: openid
};
}
else {
return {
openid: openid,
data: data.data[0],
};
}
};
function getContext(context: any) {
const serviceContext = dySDK.context(context);
return serviceContext.getContext();
}
async function callContainer(context: any, serviceId: string,
path: string,
method: string,
querys?: Record<string, any>,
data?: any,
headers?: Record<string, any>) {
const serviceContext = dySDK.context(context);
return serviceContext.callContainer({
"serviceId": serviceId,
"path": path,
"method": method,
"querys": querys,
"data": data,
"headers": headers,
});
}
async function openApiInvoke(context: any, url: string,
method: string,
querys?: Record<string, any>,
data?: any,
headers?: Record<string, any>) {
const serviceContext = dySDK.context(context);
return serviceContext.openApiInvoke({
"url": url,
"method": method,
"querys": querys,
"data": data,
"headers": headers
})
}
1.params为小程序调用时候上传的数据。
2.调用getContext().openId可以获得当前用户的唯一id,可以用来识别数据库的用户。但是这个openId只能在登录状况下后去,小游戏没登录的话,会是空。
3.这里可以获得一个数据叫UserData的数据集合。这样就能插入和读取数据了
const db = dySDK.database();
const userdata = db.collection('UserData');
4.可以在当前界面调试代码。console.log会输出带页面下方的调试日志当中
- 函数的最后return最终的返回内容
return {
code: 0,
openid: openid
};
6.Unity端调用
官方文档主要参考:https://developer.open-douyin.com/docs/resource/zh-CN/developer/tools/cloud/develop-guide/cloud-database/client/unity-sdk-clouddatabase
客户端主要通过这个接口实现云函数的调用
StarkSDK.API.GetStarkDouyinCloudManager().
CallContainerCallContainer(
string eveId,
string serviceId,
string path,
Options options,
Action<Response> success,
Action<ErrorResponse> fail);
调用代码中的eveId和ServiceId是云环境和云服务对应Path为执行的函数的文件名,可以通过这里获取
点击后会显示
这里给一个样例
/// <summary>
/// 通过云函数读取存档
/// </summary>
/// <param name="action"></param>
void LoadRecordCloudFunc(Action action)
{
Debugger.Log($"开始获取云存档{unionID}");
string json = "{"+ $"\"deviceId\":\"{unionID}\"" +"}";
JsonData jsondata = JsonMapper.ToObject(json);
StarkSDK.API.GetStarkDouyinCloudManager().CallContainer(
DYCloudID,
DYServerID,
"/getUserData",
new StarkDouyinCloud.Options()
{
Method = "POST",
Data = jsondata
}, (res) =>
{
var jsonOjbect = JsonMapper.ToObject(res.Data);
// 云存档的 json 多包装了一层,需要把 data 对应的
// TODO:Json设置成玩家数据
action?.Invoke();
}
}, (res) =>
{
GameSaver.Instance.Load();
action?.Invoke();
Debugger.LogError($"存档加载失败:{res.StatusCode}-{res.ErrMsg}");
});
}
StarkDouyinCloud.Options 部分比较复杂,主要是上传数据的内容Method 可以选择POST/GET,Data 上传的LitJson的JsonData,抖音的SDK会含有LitJson插件。
返回的成功回调和失败回调的参数分别长这个样子:
成功回调:
public class Response
{
public Dictionary<string, string> Header;
public int StatusCode;
public string Data;
public string ErrMsg;
public Response();
}
云函数返回的数据在Response.Data里面。是一个Json格式的字符串
失败回调:
public class ErrorResponse
{
public int StatusCode;
public string ErrMsg;
public ErrorResponse();
}
开发过程中遇到一个问题:
SDK自己打出来的日志显示云函数返回的结果是正确的,抖音云函数也执行正常,但是Response.Data是空的。问了SDK的技术人员之后发现是
LitJson的JsonData.cs下的OptGetString函数有问题
出错的SDK版本是这样的:
回退版本之后,正常的函数是长这个样子
区别是判断到是Object不是String之后,返回了一个空字符串了。
有遇到的朋友可以注意一下。