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"); } }