From 40604ebe19dd5af06c69911dcb03e248d7701ac0 Mon Sep 17 00:00:00 2001 From: CORE-FOLDCCCore <1813547935@qq.com> Date: Wed, 18 Mar 2026 16:48:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(topon):=20=E4=BC=98=E5=8C=96=E4=B8=BB?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E8=B0=83=E7=94=A8=E5=8F=8A=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E5=88=9D=E5=A7=8B=E5=8C=96=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ToponUnityThread新增初始化方法并封装主线程安全调用接口 - ADListenerAggregator中所有回调改用ToponUnityThread切换至主线程调用 - ToponAdController新增ToponControllerOptions配置支持,支持更多初始化参数 - 实现SDK初始化前后配置的应用,支持设置渠道、区域、经纬度等选项 - 支持初始化时自动检测区域并通过回调通知 - 新增ToponControllerOptions类,实现多种初始化参数来源解析和合并 - ShowAndroidTest方法根据DebuggerKey选择不同调试器UI展示模式 - 记录并公开最近一次区域检测结果及错误信息,方便外部查询和调试 --- .../Runtime/Scripts/ADListenerAggregator.cs | 46 +-- .../Runtime/Scripts/ToponAdController.cs | 117 ++++++- .../Runtime/Scripts/ToponControllerOptions.cs | 290 ++++++++++++++++++ .../Scripts/ToponControllerOptions.cs.meta | 11 + .../Runtime/Scripts/ToponUnityThread.cs | 55 ++++ .../Runtime/Scripts/ToponUnityThread.cs.meta | 11 + 6 files changed, 507 insertions(+), 23 deletions(-) create mode 100644 Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs create mode 100644 Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs.meta create mode 100644 Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs create mode 100644 Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs.meta diff --git a/Topon_Adapter/Runtime/Scripts/ADListenerAggregator.cs b/Topon_Adapter/Runtime/Scripts/ADListenerAggregator.cs index 85a6328..3b6893c 100644 --- a/Topon_Adapter/Runtime/Scripts/ADListenerAggregator.cs +++ b/Topon_Adapter/Runtime/Scripts/ADListenerAggregator.cs @@ -13,6 +13,8 @@ public class ADListenerAggregator public void BindAwardVideoListener(IATRewardedVideoAdClient client, ATRewardedVideoListener listener) { + ToponUnityThread.Initialize(); + if (this._awardVideoListener == null) { client.onRewardEvent += this.onReward; @@ -29,6 +31,8 @@ public class ADListenerAggregator public void BindInterstitialAdListener(IATInterstitialAdClient client, ATInterstitialAdListener listener) { + ToponUnityThread.Initialize(); + if (this._interstitialListener == null) { client.onAdLoadEvent += this.onInterstitialAdLoad; @@ -45,7 +49,7 @@ public class ADListenerAggregator void onRewardedVideoAdLoaded(object sender, ATAdEventArgs callbackInfo) { - this._awardVideoListener?.onRewardedVideoAdLoaded(callbackInfo.placementId); + ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdLoaded(callbackInfo.placementId)); } /*** @@ -53,8 +57,8 @@ public class ADListenerAggregator */ void onRewardedVideoAdLoadFail(object sender, ATAdErrorEventArgs callbackInfo) { - this._awardVideoListener?.onRewardedVideoAdLoadFail(callbackInfo.placementId, callbackInfo.errorCode, - callbackInfo.errorMessage); + ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdLoadFail(callbackInfo.placementId, + callbackInfo.errorCode, callbackInfo.errorMessage)); } @@ -63,7 +67,8 @@ public class ADListenerAggregator */ void onRewardedVideoAdPlayEnd(object sender, ATAdEventArgs callbackInfo) { - this._awardVideoListener?.onRewardedVideoAdPlayEnd(callbackInfo.placementId, callbackInfo.callbackInfo); + ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayEnd(callbackInfo.placementId, + callbackInfo.callbackInfo)); } /*** @@ -73,8 +78,8 @@ public class ADListenerAggregator */ void onRewardedVideoAdPlayFail(object sender, ATAdErrorEventArgs callbackInfo) { - this._awardVideoListener?.onRewardedVideoAdPlayFail(callbackInfo.placementId, callbackInfo.errorCode, - callbackInfo.errorMessage); + ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayFail(callbackInfo.placementId, + callbackInfo.errorCode, callbackInfo.errorMessage)); } /** @@ -83,8 +88,8 @@ public class ADListenerAggregator */ void onRewardedVideoAdPlayClosed(object sender, ATAdRewardEventArgs callbackInfo) { - this._awardVideoListener?.onRewardedVideoAdPlayClosed(callbackInfo.placementId, callbackInfo.isRewarded, - callbackInfo.callbackInfo); + ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayClosed(callbackInfo.placementId, + callbackInfo.isRewarded, callbackInfo.callbackInfo)); } /*** @@ -92,7 +97,8 @@ public class ADListenerAggregator */ void onRewardedVideoAdPlayClicked(object sender, ATAdEventArgs callbackInfo) { - this._awardVideoListener?.onRewardedVideoAdPlayClicked(callbackInfo.placementId, callbackInfo.callbackInfo); + ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayClicked(callbackInfo.placementId, + callbackInfo.callbackInfo)); } /** @@ -100,7 +106,8 @@ public class ADListenerAggregator */ private void onReward(object sender, ATAdEventArgs callbackInfo) { - this._awardVideoListener?.onReward(callbackInfo.placementId, callbackInfo.callbackInfo); + ToponUnityThread.Post(() => this._awardVideoListener?.onReward(callbackInfo.placementId, + callbackInfo.callbackInfo)); } @@ -110,7 +117,7 @@ public class ADListenerAggregator */ void onInterstitialAdLoad(object sender, ATAdEventArgs atAdEventArgs) { - this._interstitialListener?.onInterstitialAdLoad(atAdEventArgs.placementId); + ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdLoad(atAdEventArgs.placementId)); } /*** @@ -121,8 +128,8 @@ public class ADListenerAggregator */ void onInterstitialAdLoadFail(object sender, ATAdErrorEventArgs atAdErrorEventArgs) { - this._interstitialListener?.onInterstitialAdLoadFail(atAdErrorEventArgs.placementId, - atAdErrorEventArgs.errorCode, atAdErrorEventArgs.errorMessage); + ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdLoadFail(atAdErrorEventArgs.placementId, + atAdErrorEventArgs.errorCode, atAdErrorEventArgs.errorMessage)); } /*** @@ -131,7 +138,8 @@ public class ADListenerAggregator */ void onInterstitialAdShow(object sender, ATAdEventArgs atAdEventArgs) { - this._interstitialListener?.onInterstitialAdShow(atAdEventArgs.placementId, atAdEventArgs.callbackInfo); + ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdShow(atAdEventArgs.placementId, + atAdEventArgs.callbackInfo)); } /*** @@ -140,7 +148,7 @@ public class ADListenerAggregator */ void onInterstitialAdFailedToShow(object sender, ATAdErrorEventArgs atAdErrorEventArgs) { - this._interstitialListener?.onInterstitialAdFailedToShow(atAdErrorEventArgs.placementId); + ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdFailedToShow(atAdErrorEventArgs.placementId)); } /*** @@ -149,7 +157,8 @@ public class ADListenerAggregator */ void onInterstitialAdClose(object sender, ATAdEventArgs atAdEventArgs) { - this._interstitialListener?.onInterstitialAdClose(atAdEventArgs.placementId, atAdEventArgs.callbackInfo); + ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdClose(atAdEventArgs.placementId, + atAdEventArgs.callbackInfo)); } /*** @@ -158,6 +167,7 @@ public class ADListenerAggregator */ void onInterstitialAdClick(object sender, ATAdEventArgs atAdEventArgs) { - this._interstitialListener?.onInterstitialAdClick(atAdEventArgs.placementId, atAdEventArgs.callbackInfo); + ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdClick(atAdEventArgs.placementId, + atAdEventArgs.callbackInfo)); } -} \ No newline at end of file +} diff --git a/Topon_Adapter/Runtime/Scripts/ToponAdController.cs b/Topon_Adapter/Runtime/Scripts/ToponAdController.cs index 3c1285e..a7775d8 100644 --- a/Topon_Adapter/Runtime/Scripts/ToponAdController.cs +++ b/Topon_Adapter/Runtime/Scripts/ToponAdController.cs @@ -5,19 +5,28 @@ using UnityEngine; public class ToponAdController : IAdController { + public static string LastDetectedArea { get; private set; } + public static string LastAreaError { get; private set; } + private Action _maskAction; private Action _logEventAction; private ADConfig _adConfig; + private ToponControllerOptions _controllerOptions; public void Init(ADConfig adConfig, object[] args) { + ToponUnityThread.Initialize(); + _adConfig = adConfig; - // ATSdkUtil. - ATSDKAPI.setChannel(args[0].ToString()); - var isDebug = args.Length > 1 && (bool)args[1]; + _controllerOptions = ToponControllerOptions.Resolve(adConfig, args); + + ApplyPreInitOptions(_controllerOptions); + + var isDebug = _controllerOptions.Debug ?? false; ATSDKAPI.setLogDebug(isDebug); ATSDKAPI.initSDK(adConfig.Id , adConfig.Key); + ApplyPostInitOptions(_controllerOptions); if (isDebug) { ShowAndroidTest (); @@ -58,7 +67,16 @@ public class ToponAdController : IAdController private void ShowAndroidTest () { - ATSDKAPI.showDebuggerUI (); + var debuggerKey = _controllerOptions?.DebuggerKey; + if (string.IsNullOrWhiteSpace(debuggerKey)) + { + ATSDKAPI.showDebuggerUI(); + } + else + { + ATSDKAPI.showDebuggerUI(debuggerKey); + } + // com.anythink.debug.api.ATDebuggerUITest.showDebuggerUI(this); // #if UNITY_EDITOR // return; @@ -77,4 +95,93 @@ public class ToponAdController : IAdController // } // #endif } -} \ No newline at end of file + + private void ApplyPreInitOptions(ToponControllerOptions options) + { + if (options == null) + { + return; + } + + if (!string.IsNullOrWhiteSpace(options.Channel)) + { + ATSDKAPI.setChannel(options.Channel); + } + + if (!string.IsNullOrWhiteSpace(options.SubChannel)) + { + ATSDKAPI.setSubChannel(options.SubChannel); + } + + if (options.SDKArea.HasValue) + { + ATSDKAPI.setSDKArea(options.SDKArea.Value); + } + + if (options.Longitude.HasValue && options.Latitude.HasValue) + { + ATSDKAPI.setLocation(options.Longitude.Value, options.Latitude.Value); + } + + if (options.ExcludeBundleIds != null && options.ExcludeBundleIds.Length > 0) + { + ATSDKAPI.setExcludeBundleIdArray(options.ExcludeBundleIds); + } + } + + private void ApplyPostInitOptions(ToponControllerOptions options) + { + if (options == null) + { + return; + } + + var rewardedPlacementId = _adConfig?.BaseAwardAdKeyValue?.value; + if (!string.IsNullOrWhiteSpace(rewardedPlacementId) && + options.RewardedExcludeAdSourceIds != null && + options.RewardedExcludeAdSourceIds.Length > 0) + { + ATSDKAPI.setExcludeAdSourceIdArrayForPlacementID(rewardedPlacementId, options.RewardedExcludeAdSourceIds); + } + + if (options.QueryAreaOnInit) + { + ATSDKAPI.getArea(new ToponAreaListener(this, options)); + } + } + + private sealed class ToponAreaListener : ATGetAreaListener + { + private readonly ToponAdController _controller; + private readonly ToponControllerOptions _options; + + public ToponAreaListener(ToponAdController controller, ToponControllerOptions options) + { + _controller = controller; + _options = options; + } + + public void onArea(string area) + { + ToponUnityThread.Post(() => + { + LastDetectedArea = area; + LastAreaError = null; + _options?.OnAreaReceived?.Invoke(area); + _controller?._logEventAction?.Invoke("topon_area", area); + Debug.Log($"[Topon] Area detected: {area}"); + }); + } + + public void onError(string message) + { + ToponUnityThread.Post(() => + { + LastAreaError = message; + _options?.OnAreaError?.Invoke(message); + _controller?._logEventAction?.Invoke("topon_area_error", message); + Debug.LogWarning($"[Topon] Area detect failed: {message}"); + }); + } + } +} diff --git a/Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs b/Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs new file mode 100644 index 0000000..546909e --- /dev/null +++ b/Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs @@ -0,0 +1,290 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Runtime.ADAggregator; + +public sealed class ToponControllerOptions +{ + public const string ChannelKey = "topon.channel"; + public const string SubChannelKey = "topon.sub_channel"; + public const string DebugKey = "topon.debug"; + public const string DebuggerKeyKey = "topon.debugger_key"; + public const string SDKAreaKey = "topon.sdk_area"; + public const string LongitudeKey = "topon.longitude"; + public const string LatitudeKey = "topon.latitude"; + public const string ExcludeBundleIdsKey = "topon.exclude_bundle_ids"; + public const string RewardedExcludeAdSourceIdsKey = "topon.rewarded_exclude_ad_source_ids"; + public const string QueryAreaOnInitKey = "topon.query_area_on_init"; + + public string Channel { get; set; } + public string SubChannel { get; set; } + public bool? Debug { get; set; } + public string DebuggerKey { get; set; } + public int? SDKArea { get; set; } + public double? Longitude { get; set; } + public double? Latitude { get; set; } + public string[] ExcludeBundleIds { get; set; } + public string[] RewardedExcludeAdSourceIds { get; set; } + public bool QueryAreaOnInit { get; set; } + public Action OnAreaReceived { get; set; } + public Action OnAreaError { get; set; } + + public static ToponControllerOptions Resolve(ADConfig adConfig, object[] args) + { + var options = new ToponControllerOptions(); + + options.ApplyCommonKeyValues(adConfig?.CommonKeyValues); + options.ApplyLegacyArgs(args); + + if (args == null) + { + return options; + } + + foreach (var arg in args) + { + switch (arg) + { + case ToponControllerOptions explicitOptions: + options.ApplyExplicitOptions(explicitOptions); + break; + case IDictionary dictionary: + options.ApplyDictionary(dictionary); + break; + } + } + + return options; + } + + private void ApplyCommonKeyValues(List keyValues) + { + if (keyValues == null || keyValues.Count == 0) + { + return; + } + + var map = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var keyValue in keyValues) + { + if (keyValue == null || string.IsNullOrWhiteSpace(keyValue.key)) + { + continue; + } + + map[keyValue.key] = keyValue.value; + } + + Channel = GetString(map, ChannelKey, "channel") ?? Channel; + SubChannel = GetString(map, SubChannelKey, "sub_channel") ?? SubChannel; + Debug = GetBool(map, DebugKey, "debug") ?? Debug; + DebuggerKey = GetString(map, DebuggerKeyKey) ?? DebuggerKey; + SDKArea = GetInt(map, SDKAreaKey) ?? SDKArea; + Longitude = GetDouble(map, LongitudeKey) ?? Longitude; + Latitude = GetDouble(map, LatitudeKey) ?? Latitude; + ExcludeBundleIds = GetStringArray(map, ExcludeBundleIdsKey) ?? ExcludeBundleIds; + RewardedExcludeAdSourceIds = GetStringArray(map, RewardedExcludeAdSourceIdsKey) ?? RewardedExcludeAdSourceIds; + QueryAreaOnInit = GetBool(map, QueryAreaOnInitKey) ?? QueryAreaOnInit; + } + + private void ApplyLegacyArgs(object[] args) + { + if (args == null || args.Length == 0) + { + return; + } + + if (args.Length > 0 && args[0] is string channel) + { + Channel = channel; + } + + if (args.Length > 1 && TryConvertBool(args[1], out var debug)) + { + Debug = debug; + } + } + + private void ApplyExplicitOptions(ToponControllerOptions explicitOptions) + { + if (explicitOptions == null) + { + return; + } + + Channel = explicitOptions.Channel ?? Channel; + SubChannel = explicitOptions.SubChannel ?? SubChannel; + Debug = explicitOptions.Debug ?? Debug; + DebuggerKey = explicitOptions.DebuggerKey ?? DebuggerKey; + SDKArea = explicitOptions.SDKArea ?? SDKArea; + Longitude = explicitOptions.Longitude ?? Longitude; + Latitude = explicitOptions.Latitude ?? Latitude; + ExcludeBundleIds = explicitOptions.ExcludeBundleIds ?? ExcludeBundleIds; + RewardedExcludeAdSourceIds = explicitOptions.RewardedExcludeAdSourceIds ?? RewardedExcludeAdSourceIds; + QueryAreaOnInit = explicitOptions.QueryAreaOnInit || QueryAreaOnInit; + OnAreaReceived = explicitOptions.OnAreaReceived ?? OnAreaReceived; + OnAreaError = explicitOptions.OnAreaError ?? OnAreaError; + } + + private void ApplyDictionary(IDictionary dictionary) + { + if (dictionary == null || dictionary.Count == 0) + { + return; + } + + var map = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (DictionaryEntry entry in dictionary) + { + if (entry.Key == null) + { + continue; + } + + map[entry.Key.ToString()] = ConvertDictionaryValue(entry.Value); + } + + Channel = GetString(map, ChannelKey, "channel") ?? Channel; + SubChannel = GetString(map, SubChannelKey, "sub_channel") ?? SubChannel; + Debug = GetBool(map, DebugKey, "debug") ?? Debug; + DebuggerKey = GetString(map, DebuggerKeyKey) ?? DebuggerKey; + SDKArea = GetInt(map, SDKAreaKey) ?? SDKArea; + Longitude = GetDouble(map, LongitudeKey) ?? Longitude; + Latitude = GetDouble(map, LatitudeKey) ?? Latitude; + ExcludeBundleIds = GetStringArray(map, ExcludeBundleIdsKey) ?? ExcludeBundleIds; + RewardedExcludeAdSourceIds = GetStringArray(map, RewardedExcludeAdSourceIdsKey) ?? RewardedExcludeAdSourceIds; + QueryAreaOnInit = GetBool(map, QueryAreaOnInitKey) ?? QueryAreaOnInit; + } + + private static string GetString(IDictionary map, params string[] keys) + { + foreach (var key in keys) + { + if (!string.IsNullOrWhiteSpace(key) && + map.TryGetValue(key, out var value) && + !string.IsNullOrWhiteSpace(value)) + { + return value.Trim(); + } + } + + return null; + } + + private static bool? GetBool(IDictionary map, params string[] keys) + { + var value = GetString(map, keys); + return TryConvertBool(value, out var result) ? result : null; + } + + private static int? GetInt(IDictionary map, params string[] keys) + { + var value = GetString(map, keys); + if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) + { + return result; + } + + return null; + } + + private static double? GetDouble(IDictionary map, params string[] keys) + { + var value = GetString(map, keys); + if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, + out var result)) + { + return result; + } + + return null; + } + + private static string[] GetStringArray(IDictionary map, params string[] keys) + { + var value = GetString(map, keys); + if (string.IsNullOrWhiteSpace(value)) + { + return null; + } + + var normalized = value.Replace("[", string.Empty) + .Replace("]", string.Empty) + .Replace("\"", string.Empty) + .Replace("'", string.Empty); + + var items = normalized + .Split(new[] { ',', ';', '|', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) + .Select(item => item.Trim()) + .Where(item => !string.IsNullOrWhiteSpace(item)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToArray(); + + return items.Length > 0 ? items : null; + } + + private static bool TryConvertBool(object value, out bool result) + { + switch (value) + { + case bool boolValue: + result = boolValue; + return true; + case string stringValue: + if (bool.TryParse(stringValue, out result)) + { + return true; + } + + if (string.Equals(stringValue, "1", StringComparison.OrdinalIgnoreCase)) + { + result = true; + return true; + } + + if (string.Equals(stringValue, "0", StringComparison.OrdinalIgnoreCase)) + { + result = false; + return true; + } + + break; + } + + result = false; + return false; + } + + private static string ConvertDictionaryValue(object value) + { + if (value == null) + { + return null; + } + + if (value is string stringValue) + { + return stringValue; + } + + if (value is IEnumerable enumerable) + { + var items = new List(); + foreach (var item in enumerable) + { + if (item == null) + { + continue; + } + + items.Add(item.ToString()); + } + + return string.Join(",", items); + } + + return value.ToString(); + } +} diff --git a/Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs.meta b/Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs.meta new file mode 100644 index 0000000..a0addda --- /dev/null +++ b/Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43bf6f5142e2bbc438fdfcb5d521d6e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs b/Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs new file mode 100644 index 0000000..33ae0b5 --- /dev/null +++ b/Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs @@ -0,0 +1,55 @@ +using System; +using System.Threading; +using UnityEngine; + +public static class ToponUnityThread +{ + private static readonly object SyncRoot = new object(); + + private static SynchronizationContext _unityContext; + private static int _mainThreadId = -1; + + public static void Initialize() + { + if (SynchronizationContext.Current == null) + { + return; + } + + lock (SyncRoot) + { + _unityContext = SynchronizationContext.Current; + _mainThreadId = Thread.CurrentThread.ManagedThreadId; + } + } + + public static void Post(Action action) + { + if (action == null) + { + return; + } + + var context = _unityContext; + var currentThreadId = Thread.CurrentThread.ManagedThreadId; + if (context == null || currentThreadId == _mainThreadId) + { + SafeInvoke(action); + return; + } + + context.Post(_ => SafeInvoke(action), null); + } + + private static void SafeInvoke(Action action) + { + try + { + action(); + } + catch (Exception exception) + { + Debug.LogException(exception); + } + } +} diff --git a/Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs.meta b/Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs.meta new file mode 100644 index 0000000..c91f70c --- /dev/null +++ b/Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a72c397bbe840342b1a619ec001f28c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: