using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Threading.Tasks;
using System;
public class SdkConfig
{
public string openid; // 微信openid
public string unionid; // 微信unionid
public string user_id; // 游戏业务的角色id
public string nickname; // 游戏业务的角色名
public string ab_test_id; // 当用户参与ab test时,所分配的ab test id
}
public class ExpConfig
{
public string game_id;
public string api_key;
public string user_id;
public bool enable_auto_exposure;
}
public class StoreData
{
public string nickname;
public int score;
}
public class CloudConfig
{
public string env;
}
[System.Serializable]
public class BoolValue
{
public bool testBoolean;
public bool is_show_banner;
}
[System.Serializable]
public class StringValue
{
public string testString;
public string testJson;
}
[System.Serializable]
public class NumberValue
{
public float testNumber1;
public float testNumber;
}
[System.Serializable]
public class VarParams
{
public BoolValue boolValue;
public StringValue stringValue;
public NumberValue numberValue;
}
[System.Serializable]
public class VariationInfo
{
public string layerName;
public VarParams varParams;
}
// 备用的通用实验信息类,用于处理不同的 JSON 结构
[System.Serializable]
public class GenericExperimentInfo
{
public string experimentId;
public string variationId;
public string variationName;
public string layerName;
public bool isControl;
public string groupName;
// 可以添加更多可能的字段
}
// 上报参数,具体以excel说明为准
public class EventData
{
public string adunitid; // 广告位id
public string adposition; // 广告位置
public string levelid; // 关卡id
public string curlevelnumber; // 当前
public string curtitleid; // 当前等级id
public string isended; // 广告视频是否被用户完整看完,
public string isrewardgranted; // 是否给玩家发放了奖励
public string viewdurationseconds; //玩家从看视频到关闭之间的时长
public string totaldurationseconds; // 激励视频广告自身总时长(秒)。
public string pagename; // 事件发生的页面名
public string amount; // 金额
public string paymenttype; // 支付类型,支付宝、微信、苹果内购等
public string currency; // 货币类型,人民币
public string channel; // 渠道
}
public class GameManager : MonoBehaviour
{
// UI元素
public TextMeshProUGUI logText;
public Button initButton;
// public Button loginButton;
// public Button
// public Button setUserIdButton;
// public Button setConfigButton;
// Start is called before the first frame update
void Start()
{
SetConfig();
TrackEventLogin();
TrackEventAdStart();
TrackEventAdEnd();
TrackEventCustom();
ReportError();
GetAttributionParams();
// Login();
CallLogin();
CallGetIpLocation();
InitCloud();
CallSetKv();
// CallGetKv();
OnPayment();
OnRegister();
OnShare();
OnTutorialFinish();
// 实验
// 调用初始化
CallInitExperiment();
}
// Update is called once per frame
void Update()
{
}
///
/// 设置用户配置
///
private void SetConfig()
{
SdkConfig sdkConfig = new SdkConfig()
{
user_id = "user123",
openid = "123",
unionid = "union55555",
nickname = "小红",
ab_test_id = "test_group_a"
};
#if UNITY_WEBGL && !UNITY_EDITOR
OSDKHelper.SetConfig(JsonUtility.ToJson(sdkConfig));
#else
Debug.Log("Login 仅在 WebGL 运行时有效");
#endif
}
///
/// 追踪事件
///
private void TrackEventLogin()
{
EventData eventData = new EventData()
{
curlevelnumber = "2",
curtitleid = "10"
};
OSDKHelper.TrackEvent("playerlogin", JsonUtility.ToJson(eventData));
}
///
/// 追踪事件
///
private void TrackEventAdStart()
{
EventData eventData = new EventData()
{
adunitid = "adunit-xxxxxxxx",
adposition = "top_banner",
curlevelnumber = "2",
curtitleid = "10",
levelid = "556",
};
OSDKHelper.TrackEvent("rewardedvideoadshow", JsonUtility.ToJson(eventData));
}
///
/// 追踪事件
///
private void TrackEventAdEnd()
{
EventData eventData = new EventData()
{
adunitid = "adunit-xxxxxxxx",
adposition = "top_banner",
isended = "1",
isrewardgranted = "1",
viewdurationseconds = "20",
totaldurationseconds = "21",
curlevelnumber = "2",
curtitleid = "title101",
levelid = "level556",
};
OSDKHelper.TrackEvent("rewardedvideoadclose", JsonUtility.ToJson(eventData));
}
///
/// 追踪事件 自定义事件,小游戏内的按钮点击行为等自定义事件名
///
private void TrackEventCustom()
{
EventData eventData = new EventData()
{
pagename = "home", // 事件发生的场景名或页面名
curlevelnumber = "2", // 当前关卡数
curtitleid = "title101", // 当前用户称号id
};
OSDKHelper.TrackEvent("home_btn_share_click", JsonUtility.ToJson(eventData));
}
private void OnPayment()
{
EventData eventData = new EventData()
{
amount = "100", // 事件发生的场景名或页面名
paymenttype = "alipay", // 支付类型,支付宝、微信、苹果内购等
currency = "cny", // 货币类型,人民币
};
OSDKHelper.OnPayment(JsonUtility.ToJson(eventData));
}
private void OnRegister()
{
EventData eventData = new EventData()
{
channel = "wx", // 支付类型,支付宝、微信、苹果内购等
};
OSDKHelper.OnRegister(JsonUtility.ToJson(eventData));
}
private void OnShare()
{
EventData eventData = new EventData()
{
pagename = "home", // 事件发生的场景名或页面名
curlevelnumber = "2", // 当前关卡数
curtitleid = "title101", // 当前用户称号id
};
OSDKHelper.OnShare(JsonUtility.ToJson(eventData));
}
private void OnTutorialFinish()
{
EventData eventData = new EventData()
{
pagename = "home", // 事件发生的场景名或页面名
curlevelnumber = "2", // 当前关卡数
curtitleid = "title101", // 当前用户称号id
};
OSDKHelper.OnTutorialFinish(JsonUtility.ToJson(eventData));
}
private void ReportError() {
EventData eventData = new EventData()
{
pagename = "home", // 事件发生的场景名或页面名
curlevelnumber = "2", // 当前关卡数
curtitleid = "title101", // 当前用户称号id
};
OSDKHelper.ReportError("home_btn_share_click", JsonUtility.ToJson(eventData));
}
private void GetAttributionParams()
{
string testData = OSDKHelper.GetAttributionParams();
Debug.Log("test: " + testData);
}
// private void Login()
// {
// Task task = Task.Run(() =>
// {
// // return OSDKHelper.Login();
// });
// try
// {
// task.Wait();
// }
// catch(AggregateException aex)
// {
// if(aex.InnerException is NullReferenceException)
// {
// Console.WriteLine("Null");
// }
// else
// {
// throw;
// }
// }
// }
public void CallLogin()
{
#if UNITY_WEBGL && !UNITY_EDITOR
OSDKHelper.Login(gameObject.name, "OnLogin");
#else
Debug.Log("Login 仅在 WebGL 运行时有效");
#endif
}
// JS 通过 SendMessage(goName, methodName, payload) 回调此方法,参数为 JSON 字符串
public void OnLogin(string json)
{
Debug.Log($"Login 回调: {json}");
// 成功:Login 回调: {"id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","openid":"xxx","unionid":"","sessionToken":"xxx","timestamp":1760684102881}
// 失败:Login 回调: {"code":500,"msg":"code2session error"}
// TODO: 解析并处理登录结果,例如:
// var result = JsonUtility.FromJson(json);
}
public void CallGetIpLocation()
{
#if UNITY_WEBGL && !UNITY_EDITOR
OSDKHelper.GetIpLocation(gameObject.name, "OnGetIpLocation");
#else
Debug.Log("Login 仅在 WebGL 运行时有效");
#endif
}
public void OnGetIpLocation(string json)
{
Debug.Log($"GetIpLocation 回调: {json}");
}
public void InitCloud()
{
CloudConfig cloudConfig = new CloudConfig()
{
env = "test", // test || prod
};
#if UNITY_WEBGL && !UNITY_EDITOR
OSDKHelper.InitCloud(JsonUtility.ToJson(cloudConfig));
#else
Debug.Log("InitCloud 仅在 WebGL 运行时有效");
#endif
}
public void CallSetKv() {
StoreData storeData = new StoreData()
{
nickname = "John",
score = 50
};
#if UNITY_WEBGL && !UNITY_EDITOR
OSDKHelper.SetKv(gameObject.name, "OnSetKv", "testName", JsonUtility.ToJson(storeData));
#else
Debug.Log("SetKv 仅在 WebGL 运行时有效");
#endif
}
public void OnSetKv(string json) {
Debug.Log($"set kv 回调: {json}");
// 设置成功后,可以通过GetKv读取值进行校验
CallGetKv();
}
public void CallGetKv()
{
#if UNITY_WEBGL && !UNITY_EDITOR
OSDKHelper.GetKv(gameObject.name, "OnGetKv", "testName");
#else
Debug.Log("GetKv 仅在 WebGL 运行时有效");
#endif
}
public void OnGetKv(string json)
{
Debug.Log($"get kv 回调: {json}");
}
public void CallInitExperiment() {
ExpConfig expConfig = new ExpConfig()
{
// game_id = "******", // 必选:项目游戏 ID,联系「苏」获取
// api_key = "***", // 必选:项目 API KEY,联系「苏」获取
// 填了未注册的 game_id 和 api_key,导致tab sdk它既不走then也不走catch,已反馈bug
user_id = "union55555", // 必选:玩家小游戏 openid,玩家唯一标识
enable_auto_exposure = false, // 可选:自动上报实验曝光(默认 true)。当该值为 true时,在调用 getVariation() 时会自动上报实验曝光,如果该值为 false 时,需要手动调用 trackExposure() 上报实验曝光。实验曝光应该在玩家真正“看到”或“使用到”实验变体时才调用上报,比如用户看到了变体的 UI,体验到变体的功能时才上报
};
#if UNITY_WEBGL && !UNITY_EDITOR
OSDKHelper.InitExperiment(gameObject.name, "OnInitExperiment", JsonUtility.ToJson(expConfig));
#else
Debug.Log("InitExperiment 仅在 WebGL 运行时有效");
#endif
}
public void OnInitExperiment(int initResult) {
Debug.Log($"init experiment 回调: {initResult}");
if (initResult == 1) {
// 初始化成功
Debug.Log("init experiment 回调成功");
// string expId = "1763024427";
string expId = "1764727184";
// get variation与init同理,如果传入的expId是错误的,会导致OnInitExperiment执行两次,init experiment 回调:0,回调失败
// 获取内容
GetVariation(expId);
// 曝光
TrackExposure(expId);
} else {
// 初始化失败
Debug.Log("init experiment 回调失败");
}
}
private void GetVariation(string experimentId) {
string variation = OSDKHelper.GetVariation(experimentId);
Debug.Log("GetVariation 原始返回值: " + variation);
if (string.IsNullOrEmpty(variation)) {
// 如果是空字符串
Debug.Log("该用户的流量不参与该实验(即不会分流到对照组或实验组) 或 其他异常,请执行默认版本");
} else {
// 用户被分流到该实验的对照组或实验组,即用户被分配到所属的实验变体了
// 现在可以获取实验变体的配置参数并在代码中直接使用这些参数
// 返回的 variation 为 json 字符串
Debug.Log("info:" + variation);
// 将 json 字符串反序列化(解析)为 C# 对象
VariationInfo variationInfo = JsonUtility.FromJson(variation);
// 如下 is_show_banner 为实验配置的参数 key,true 为获取不到配置参数时的默认值,默认值可自行定义,但类型要匹配
bool isShowBanner = variationInfo.varParams?.boolValue?.is_show_banner ?? true;
if (isShowBanner) {
Debug.Log("展示 Banner");
} else {
Debug.Log("不展示 Banner");
}
// 其他示例(请自行定义好获取不到配置参数时的默认值)
// 1. 在实验平台配置 boolean 参数(采用 boolValue)
bool testBoolean = variationInfo.varParams?.boolValue?.testBoolean ?? false;
Debug.Log($"布尔值参数: {testBoolean}");
// 2. 在实验平台配置 string 参数(采用 stringValue)
string testString = variationInfo.varParams?.stringValue?.testString ?? "red";
Debug.Log($"字符串参数: {testString}");
// 3. 在实验平台配置 json 参数(json 会转为字符串,采用 stringValue)
string testJson = variationInfo.varParams?.stringValue?.testJson ?? "{\"a\":1,\"b\":2}";
Debug.Log($"字符参数: {testJson}");
// 4. 在实验平台配置 number 参数(采用 numberValue)
float testNumber = variationInfo.varParams?.numberValue?.testNumber ?? 10f;
Debug.Log($"数字参数: {testNumber}");
}
// if (!string.IsNullOrEmpty(variation))
// {
// // 首先尝试使用主要的 variationInfo 结构
// bool parseSuccess = false;
// try
// {
// VariationInfo variationInfo = JsonUtility.FromJson(varInfo);
// Debug.Log("=== 使用 VariationInfo 反序列化成功 ===");
// Debug.Log($"实验层名称: {variationInfo.layerName ?? "null"}");
// if (variationInfo.varParams != null)
// {
// Debug.Log("--- 变量参数 ---");
// if (variationInfo.varParams.boolValue != null)
// {
// Debug.Log($"布尔值参数: {variationInfo.varParams.boolValue.testBoolean}");
// }
// else
// {
// Debug.Log("布尔值参数: null");
// }
// if (variationInfo.varParams.stringValue != null)
// {
// Debug.Log($"字符串参数: {variationInfo.varParams.stringValue.testString ?? "null"}");
// }
// else
// {
// Debug.Log("字符串参数: null");
// }
// if (variationInfo.varParams.numberValue != null)
// {
// Debug.Log($"数字参数: {variationInfo.varParams.numberValue.testNumber1 ?? "null"}");
// }
// else
// {
// Debug.Log("数字参数: null");
// }
// }
// else
// {
// Debug.Log("varParams 为 null");
// }
// Debug.Log("================================");
// parseSuccess = true;
// }
// catch (System.Exception e)
// {
// Debug.LogWarning($"使用 VariationInfo 反序列化失败: {e.Message}");
// }
// // // 如果主要结构失败,尝试使用通用结构
// // if (!parseSuccess)
// // {
// // try
// // {
// // GenericExperimentInfo genericInfo = JsonUtility.FromJson(varInfo);
// // Debug.Log("=== 使用 GenericExperimentInfo 反序列化成功 ===");
// // Debug.Log($"实验ID: {genericInfo.experimentId ?? "null"}");
// // Debug.Log($"变体ID: {genericInfo.variationId ?? "null"}");
// // Debug.Log($"变体名称: {genericInfo.variationName ?? "null"}");
// // Debug.Log($"层名称: {genericInfo.layerName ?? "null"}");
// // Debug.Log($"是否为对照组: {genericInfo.isControl}");
// // Debug.Log($"组名: {genericInfo.groupName ?? "null"}");
// // Debug.Log("================================");
// // parseSuccess = true;
// // }
// // catch (System.Exception e)
// // {
// // Debug.LogWarning($"使用 GenericExperimentInfo 反序列化也失败: {e.Message}");
// // }
// // }
// // 如果两种结构都失败,提供详细的错误信息
// if (!parseSuccess)
// {
// Debug.LogError("所有反序列化尝试都失败了");
// Debug.LogError($"原始数据: {varInfo}");
// Debug.Log($"字符串长度: {varInfo.Length}");
// Debug.Log($"字符串是否为空: {string.IsNullOrEmpty(varInfo)}");
// Debug.Log($"字符串是否为空白: {string.IsNullOrWhiteSpace(varInfo)}");
// // 尝试检查是否是有效的 JSON 格式
// if (varInfo.Trim().StartsWith("{") && varInfo.Trim().EndsWith("}"))
// {
// Debug.Log("数据看起来像 JSON 格式,可能是字段名不匹配");
// Debug.Log("建议检查实际的 JSON 结构并相应调整数据类");
// }
// else
// {
// Debug.Log("数据不是有效的 JSON 格式");
// }
// }
// }
// else
// {
// Debug.LogWarning("GetVariation 返回空字符串或 null");
// }
}
private void TrackExposure(string experimentId) {
OSDKHelper.TrackExposure(experimentId);
Debug.Log("trackExposure");
}
}