com.amanotes.gdk 0.2.9 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.11 - 2023-06-29]
4
+ ### SetLogCondition with EventParam
5
+ ### Rename Migrated -> HasMigrated
6
+ ### Fix StopShowAd
7
+
8
+ ## [0.2.10 - 2023-06-23]
9
+ ### Extra package: Project Panel
10
+ ### Remote config: Allow user to enable / disable automatic default valuye updating (in play mode)
11
+ ### Fix ad routine
12
+ ### Expose analytics migration flag
13
+
3
14
  ## [0.2.9 - 2023-06-15]
4
15
  ### Show total init time
5
16
  ### Show adapter version + status at init time
Binary file
Binary file
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: 26e42be832082494fb3eb94a4d9cd300
3
+ DefaultImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
Binary file
Binary file
Binary file
@@ -110,6 +110,9 @@ namespace Amanotes.Core
110
110
  public bool enableRewarded = true;
111
111
  public bool enableBanner = true;
112
112
  public bool autoMute = true;
113
+
114
+ [Header("EDITOR")]
115
+ [Range(0f, 1f)] public float rewardAdShowSuccessRate = 1;
113
116
  }
114
117
 
115
118
  public partial class Ads
@@ -119,9 +122,10 @@ namespace Amanotes.Core
119
122
 
120
123
  internal static AdAdapterConfig _adConfig;
121
124
  internal static IAdAdapter _adapter;
122
- public static AdListener Events = new AdListener();
123
125
  internal static float _savedVolume = -1;
124
- internal static AdsData localData = new AdsData().LoadJsonFromFile();
126
+
127
+ public static readonly AdListener Events = new AdListener();
128
+ internal static readonly AdsData localData = new AdsData().LoadJsonFromFile();
125
129
  }
126
130
 
127
131
  public partial class Ads // Public
@@ -139,13 +143,33 @@ namespace Amanotes.Core
139
143
  public static bool showingBanner => _showingBanner;
140
144
  public static bool showingAd => context != null;
141
145
 
142
- public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
146
+ private static bool ClearPrevContext()
143
147
  {
144
- if (context != null)
148
+ if (context == null) return true;
149
+ float duration = Time.realtimeSinceStartup - context.showCallAt;
150
+ bool willSkip = duration < Mathf.Max(5f, _adConfig.adShowTimeoutInSecs);
151
+ if (willSkip)
145
152
  {
146
- LogWarning("Context != null, might some ad be showing???");
147
- context = null;
153
+ LogWarning($"[AD] ShowRequest IGNORED as another ad is showing (elapsedTime: {duration:n2}s):\n" + JsonUtility.ToJson(context, true));
154
+ return false;
148
155
  }
156
+
157
+ LogWarning($"[AD] FORCE STOPPED the previous ad, as it seems to hang (elapsedTime: {duration:n2}s):\n" + JsonUtility.ToJson(context, true));
158
+ // possibly hang: force stop
159
+ if (context.adType == AdType.Interstitial)
160
+ {
161
+ _adapter.interstitial.StopShowAd();
162
+ } else
163
+ {
164
+ _adapter.rewardVideo.StopShowAd();
165
+ }
166
+ context = null;
167
+ return true;
168
+ }
169
+
170
+ public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
171
+ {
172
+ if (!ClearPrevContext()) return null;
149
173
 
150
174
  context = new ShowAdContext(AdType.Interstitial, placementName, userData);
151
175
  _adapter.interstitial.StartShowAd();
@@ -154,18 +178,14 @@ namespace Amanotes.Core
154
178
 
155
179
  public static IAdCallback ShowRewardedVideo(string placementName = null, Dictionary<string, object> userData = null)
156
180
  {
157
- if (context != null)
158
- {
159
- LogWarning("Context != null, might some ad be showing???");
160
- context = null;
161
- }
162
-
181
+ if (!ClearPrevContext()) return null;
182
+
163
183
  context = new ShowAdContext(AdType.VideoReward, placementName, userData);
164
184
  _adapter.rewardVideo.StartShowAd();
165
185
  return context;
166
186
  }
167
187
 
168
- private static bool _showingBanner = false;
188
+ private static bool _showingBanner;
169
189
  public static void ShowBanner()
170
190
  {
171
191
  if (_showingBanner) return;
@@ -227,16 +247,16 @@ namespace Amanotes.Core.Internal
227
247
  [Flags]
228
248
  public enum AdCallback
229
249
  {
230
- None,
231
- Open,
232
- Reward,
233
- Click,
234
- Cancel,
235
- Close,
236
- Success,
237
- Fail
250
+ None = 0,
251
+ Open = 1,
252
+ Reward = 2,
253
+ Click = 4,
254
+ Cancel = 8,
255
+ Close = 16,
256
+ Success = 32,
257
+ Fail = 64
238
258
  }
239
-
259
+
240
260
  public enum BannerPosition
241
261
  {
242
262
  TOP = 1,
@@ -278,11 +298,10 @@ namespace Amanotes.Core.Internal
278
298
  showFinishAt = 0;
279
299
  }
280
300
 
281
- public bool hasError => (adCallback & (AdCallback.Fail | AdCallback.Cancel)) != 0;
282
- public bool potentiallyCompleted => (adCallback & (AdCallback.Close | AdCallback.Reward | AdCallback.Cancel)) != 0;
301
+ public bool hasFailedOrCancelled => (adCallback & (AdCallback.Fail | AdCallback.Cancel)) != 0;
302
+ public bool potentiallyCompleted => (adCallback & (AdCallback.Close | AdCallback.Fail | AdCallback.Reward | AdCallback.Cancel)) != 0;
283
303
  public bool hasReward => (adCallback & AdCallback.Reward) != 0;
284
304
  public bool hasClosed => (adCallback & AdCallback.Close) != 0;
285
- public bool hasCancel => (adCallback & AdCallback.Cancel) != 0;
286
305
  public bool hasClicked => (adCallback & AdCallback.Click) != 0;
287
306
  }
288
307
 
@@ -303,18 +322,19 @@ namespace Amanotes.Core.Internal
303
322
  return;
304
323
  }
305
324
 
325
+ Log("StartLoadAd");
306
326
  _loadRoutine = _instance.StartCoroutine(LoadAdRoutine());
307
327
  }
308
-
328
+
309
329
  public void StopLoadAd()
310
330
  {
331
+ Log("StopLoadAd");
311
332
  if (_loadState == LoadAdsState.Requesting)
312
333
  {
313
334
  _loadState = LoadAdsState.None;
314
335
  }
315
-
336
+
316
337
  if (_loadRoutine == null) return;
317
-
318
338
  _instance.StopCoroutine(_loadRoutine);
319
339
  _loadRoutine = null;
320
340
  }
@@ -338,7 +358,7 @@ namespace Amanotes.Core.Internal
338
358
  _isRequesting = true;
339
359
  RequestAd();
340
360
 
341
- var timeout = Ads._adConfig.adLoadTimeoutInSecs;
361
+ int timeout = Ads._adConfig.adLoadTimeoutInSecs;
342
362
  var counter = 0;
343
363
 
344
364
  while (counter < timeout || timeout == 0)
@@ -383,9 +403,10 @@ namespace Amanotes.Core.Internal
383
403
  {
384
404
  if (_showState != ShowAdsState.None)
385
405
  {
386
- LogWarning("StartShowAd() --> Invalid _showState: " + _showState);
406
+ LogWarning("[Ad] StartShowAd() --> Invalid _showState: " + _showState);
387
407
  }
388
-
408
+
409
+ Log($"[Ad] {adType} StartShowAd");
389
410
  _showState = ShowAdsState.ShowCalled;
390
411
  if (_showAdRoutine != null) _instance.StopCoroutine(_showAdRoutine);
391
412
  _showAdRoutine = _instance.StartCoroutine(ShowAdRoutine());
@@ -393,7 +414,13 @@ namespace Amanotes.Core.Internal
393
414
 
394
415
  public void StopShowAd()
395
416
  {
417
+ Log($"[Ad] {adType} StopShowAd");
396
418
  _showState = ShowAdsState.None;
419
+ if (_loadState == LoadAdsState.Ready && !isAdReady)
420
+ {
421
+ _loadState = LoadAdsState.None;
422
+ StartLoadAd();
423
+ }
397
424
  RestoreVolume();
398
425
  if (_showAdRoutine == null) return;
399
426
  _instance.StopCoroutine(_showAdRoutine);
@@ -407,20 +434,21 @@ namespace Amanotes.Core.Internal
407
434
  {
408
435
  if (_loadState == LoadAdsState.Ready)
409
436
  {
410
- LogWarning("Inconsistent state report: isAdReady == false while _loadState == Ready");
437
+ LogWarning("[Ad] Inconsistent state report: isAdReady == false while _loadState == Ready");
411
438
  _loadState = LoadAdsState.None;
412
439
  }
413
440
 
414
441
  if (Ads._adConfig.checkInternet && !hasInternet)
415
442
  {
416
443
  _showState = ShowAdsState.ShowFail;
444
+ ShowAdRoutineCompleted(false);
417
445
  yield break;
418
446
  }
419
447
 
420
448
  if (_loadState != LoadAdsState.Requesting) StartLoadAd();
421
449
  _showState = ShowAdsState.WaitForAd;
422
450
 
423
- var timeout = Ads._adConfig.adShowTimeoutInSecs;
451
+ int timeout = Ads._adConfig.adShowTimeoutInSecs;
424
452
  var counter = 0;
425
453
 
426
454
  while (counter < timeout || timeout == 0)
@@ -433,12 +461,12 @@ namespace Amanotes.Core.Internal
433
461
  if (!isAdReady)
434
462
  {
435
463
  Ads.Events.OnShowTimeout?.Invoke();
436
- _showState = ShowAdsState.ShowFail;
437
464
  ShowAdRoutineCompleted(false);
438
465
  yield break;
439
466
  }
440
467
  }
441
-
468
+
469
+ _showState = ShowAdsState.Showing;
442
470
  // Ad should be ready here!
443
471
  ShowAd();
444
472
  if (Ads._adConfig.autoMute && AudioListener.volume > 0 && Ads._savedVolume == -1)
@@ -446,9 +474,8 @@ namespace Amanotes.Core.Internal
446
474
  Ads._savedVolume = AudioListener.volume;
447
475
  AudioListener.volume = 0;
448
476
  }
449
-
450
- var context = Ads.context;
451
-
477
+
478
+ ShowAdContext context = Ads.context;
452
479
  while (!context.potentiallyCompleted)
453
480
  {
454
481
  yield return wait1Sec;
@@ -456,51 +483,52 @@ namespace Amanotes.Core.Internal
456
483
 
457
484
  if (adType == AdType.Interstitial)
458
485
  {
459
- _showState = context.hasError ? ShowAdsState.ShowFail : ShowAdsState.ShowSuccess;
460
- ShowAdRoutineCompleted(_showState == ShowAdsState.ShowSuccess);
486
+ ShowAdRoutineCompleted(!context.hasFailedOrCancelled);
461
487
  yield break;
462
488
  }
463
489
 
464
- if (context.hasCancel)
490
+ if (context.hasFailedOrCancelled)
465
491
  {
492
+ Log($"[Ad] {adType} Waiting for [close]");
466
493
  yield return wait1Sec; // wait for close (1s)
467
- _showState = ShowAdsState.ShowFail;
468
494
  ShowAdRoutineCompleted(false);
469
495
  yield break;
470
496
  }
471
497
 
472
498
  if (context.hasClosed)
473
499
  {
474
- while (!context.hasCancel && !context.hasReward)
500
+ while (!context.hasFailedOrCancelled && !context.hasReward)
475
501
  {
502
+ Log($"[Ad] {adType} Waiting for [cancel] or [reward]");
476
503
  yield return wait1Sec;
477
504
  }
478
505
 
479
- _showState = context.hasCancel ? ShowAdsState.ShowFail : ShowAdsState.ShowSuccess;
480
- ShowAdRoutineCompleted(_showState == ShowAdsState.ShowSuccess);
506
+ ShowAdRoutineCompleted(!context.hasFailedOrCancelled);
481
507
  yield break;
482
508
  }
483
509
 
484
510
  while (!context.hasClosed)
485
511
  {
512
+ Log($"[Ad] {adType} Waiting for [close]");
486
513
  yield return wait1Sec;
487
514
  }
488
515
 
489
- _showState = ShowAdsState.ShowSuccess;
490
516
  ShowAdRoutineCompleted(true);
491
-
492
- Ads.context = null;
493
- _showState = ShowAdsState.None;
494
517
  }
495
518
 
496
519
  private void ShowAdRoutineCompleted(bool isSuccess)
497
520
  {
498
- StartLoadAd();
521
+ if (_loadState == LoadAdsState.Ready)
522
+ {
523
+ _loadState = isAdReady ? LoadAdsState.Ready : LoadAdsState.None;
524
+ if (_loadState == LoadAdsState.None) StartLoadAd();
525
+ }
526
+
527
+ _showState = isSuccess ? ShowAdsState.ShowSuccess : ShowAdsState.ShowFail;
499
528
  Ads.context.showFinishAt = Time.realtimeSinceStartup;
500
529
 
501
530
  var localData = Ads.localData;
502
531
  var stat = _isInterstitial ? localData.interstitial : localData.reward;
503
-
504
532
  if (isSuccess)
505
533
  {
506
534
  stat.success++;
@@ -515,6 +543,10 @@ namespace Amanotes.Core.Internal
515
543
 
516
544
  localData.Save();
517
545
  RestoreVolume();
546
+
547
+ Log($"[Ad] {adType} ShowAdRoutineCompleted: {isSuccess}\n{JsonUtility.ToJson(Ads.context)}");
548
+ Ads.context = null;
549
+ _showState = ShowAdsState.None;
518
550
  }
519
551
 
520
552
  private void RestoreVolume()
@@ -528,6 +560,8 @@ namespace Amanotes.Core.Internal
528
560
  // Default implementation
529
561
  protected void OnAdClosed()
530
562
  {
563
+ Log($"[Ad] {adType} OnAdClosed");
564
+
531
565
  if (Ads.context != null)
532
566
  {
533
567
  Ads.context.adCallback |= AdCallback.Close;
@@ -546,6 +580,8 @@ namespace Amanotes.Core.Internal
546
580
 
547
581
  protected void OnAdClicked()
548
582
  {
583
+ Log($"[Ad] {adType} OnAdClicked");
584
+
549
585
  if (Ads.context != null)
550
586
  {
551
587
  Ads.context.adCallback |= AdCallback.Click;
@@ -565,6 +601,8 @@ namespace Amanotes.Core.Internal
565
601
 
566
602
  protected void OnAdShowFailed()
567
603
  {
604
+ Log($"[Ad] {adType} OnAdShowFailed");
605
+
568
606
  if (Ads.context != null)
569
607
  {
570
608
  Ads.context.adCallback |= AdCallback.Fail;
@@ -584,6 +622,8 @@ namespace Amanotes.Core.Internal
584
622
 
585
623
  protected void OnAdShowSucceeded()
586
624
  {
625
+ Log($"[Ad] {adType} OnAdShowSucceeded");
626
+
587
627
  if (Ads.context != null)
588
628
  {
589
629
  Ads.context.adCallback |= AdCallback.Success;
@@ -601,6 +641,8 @@ namespace Amanotes.Core.Internal
601
641
 
602
642
  protected void OnAdOpen()
603
643
  {
644
+ Log($"[Ad] {adType} OnAdOpen");
645
+
604
646
  if (Ads.context != null)
605
647
  {
606
648
  Ads.context.adCallback |= AdCallback.Open;
@@ -619,6 +661,8 @@ namespace Amanotes.Core.Internal
619
661
 
620
662
  protected void OnAdReward()
621
663
  {
664
+ Log($"[Ad] {adType} OnAdReward");
665
+
622
666
  if (Ads.context != null)
623
667
  {
624
668
  Ads.context.adCallback |= AdCallback.Reward;
@@ -635,6 +679,8 @@ namespace Amanotes.Core.Internal
635
679
 
636
680
  protected void OnAdLoadSuccess()
637
681
  {
682
+ Log($"[Ad] {adType} OnAdLoadSuccess");
683
+
638
684
  if (!_isRequesting)
639
685
  {
640
686
  LogWarning("Something wrong? OnAdReady called when no ad is loading!");
@@ -647,6 +693,8 @@ namespace Amanotes.Core.Internal
647
693
 
648
694
  protected void OnAdLoadFailed(string error)
649
695
  {
696
+ Log($"[Ad] {adType} OnAdLoadFailed: {error}");
697
+
650
698
  if (_isInterstitial)
651
699
  Ads.Events.OnInterstitialLoadFailed?.Invoke(error);
652
700
  }
@@ -29,11 +29,13 @@ namespace Amanotes.Core
29
29
  //PUBLIC APIS
30
30
  public static partial class Analytics
31
31
  {
32
+ public static bool HasMigrated => localData.migrationLog.count > 0;
33
+
32
34
  public interface IEventParamsBuilder { }
33
35
 
34
36
  public class EventParams : IEventParamsBuilder
35
37
  {
36
- public string eventName;
38
+ public readonly string eventName;
37
39
  public Dictionary<string, object> parameters = new Dictionary<string, object>();
38
40
  public string funnelSignature;
39
41
  public bool accumulated;
@@ -43,6 +45,8 @@ namespace Amanotes.Core
43
45
  public HashSet<string> ignoreAdapterIds = new HashSet<string>();
44
46
  public HashSet<string> allowAdapterIds = new HashSet<string>();
45
47
 
48
+ public EventDetail EventDetail => localData.GetEventDetail(eventName, true);
49
+
46
50
  public EventParams(string eventName)
47
51
  {
48
52
  this.eventName = eventName;
@@ -124,7 +128,7 @@ namespace Amanotes.Core
124
128
  return eventDetail != null ? (withinSession ? eventDetail.countInSession : eventDetail.totalCount) : 0;
125
129
  }
126
130
 
127
- public static void SetLogEventCondition(Predicate<EventDetail> condition)
131
+ public static void SetLogEventCondition(Predicate<EventParams> condition)
128
132
  {
129
133
  if (logEventHook != null) LogWarning("LogEventCondition has already set! Please make sure to call it once.");
130
134
  logEventHook = condition;
@@ -279,7 +283,7 @@ namespace Amanotes.Core
279
283
  }
280
284
 
281
285
  internal static readonly Dictionary<string, EventConfig> sendAtCount = new Dictionary<string, EventConfig>();
282
- internal static Predicate<EventDetail> logEventHook = null;
286
+ internal static Predicate<EventParams> logEventHook = null;
283
287
  internal static readonly Queue<EventParams> eventQueue = new Queue<EventParams>();
284
288
  internal static readonly List<AdapterContext> listAdapters = new List<AdapterContext>();
285
289
  internal static readonly AnalyticsData localData = new AnalyticsData().LoadJsonFromFile();
@@ -315,7 +319,7 @@ namespace Amanotes.Core
315
319
  string eventNameToSend = GetEventNameToSend(eventData.eventName, countInSession, totalCount);
316
320
  if (Config.common.normalizeEventName) NormalizeEventName(ref eventNameToSend);
317
321
 
318
- if (showAnalyticsLog) Debug.Log($"AmaGDK v{AmaGDK.VERSION} | Event <{eventNameToSend}> (in session: {countInSession}, total: {totalCount})\n{JsonUtils.DictionaryToJson(eventData.parameters, true)}");
322
+ if (showAnalyticsLog) Debug.Log($"AmaGDK | Event <{eventNameToSend}> (in session: {countInSession}, total: {totalCount})\n{JsonUtils.DictionaryToJson(eventData.parameters, true)}");
319
323
 
320
324
  var inUseAdapterIDs = new List<string>();
321
325
  foreach (AdapterContext m in listAdapters)
@@ -404,7 +408,7 @@ namespace Amanotes.Core
404
408
  if (logEventHook != null)
405
409
  {
406
410
  EventDetail eventDetail = localData.GetEventDetail(eventData.eventName, true);
407
- return logEventHook(eventDetail);
411
+ return logEventHook(eventData);
408
412
  }
409
413
 
410
414
  return true;
@@ -3,10 +3,13 @@ using System.Collections.Generic;
3
3
  using System.IO;
4
4
  using System.Text;
5
5
  using UnityEngine;
6
-
7
6
  using Amanotes.Core.Internal;
8
7
  using static Amanotes.Core.Internal.Logging;
9
8
 
9
+ #if UNITY_EDITOR
10
+ using UnityEditor;
11
+ #endif
12
+
10
13
  namespace Amanotes.Core
11
14
  {
12
15
  public partial class AmaGDK //Remote Config
@@ -112,6 +115,7 @@ namespace Amanotes.Core
112
115
  };
113
116
 
114
117
  internal static IRemoteConfig adapter;
118
+ internal static RemoteConfigConfig adapterConfig;
115
119
  internal static Action<bool> onAdapterInitCompleteCallback;
116
120
 
117
121
  internal static void NextState(bool result = true)
@@ -140,6 +144,8 @@ namespace Amanotes.Core
140
144
  NextState(false);
141
145
  return;
142
146
  }
147
+
148
+ adapterConfig = (adapter as AdapterContext)?.GetAdapterConfig<RemoteConfigConfig>();
143
149
  adapter.ResolveDependencies(NextState);
144
150
  }
145
151
 
@@ -171,12 +177,29 @@ namespace Amanotes.Core
171
177
  {
172
178
  _state = FetchState.SaveCache;
173
179
  StringBuilder sb = new StringBuilder();
180
+
181
+
182
+ bool needUpdateDefault = Application.isEditor && adapterConfig.autoUpdateDefaultValue;
183
+ List<KeyValue> list = needUpdateDefault ? new List<KeyValue>() : null;
184
+
174
185
  foreach (var c in dictConfig)
175
186
  {
176
187
  sb.AppendLine($"{c.Key}\t{Encode(c.Value)}");
188
+ if (!needUpdateDefault) continue;
189
+ list.Add(new KeyValue() { key = c.Key, value = c.Value });
177
190
  }
178
-
179
- var filePath = FileUtils.GetPath(fileName);
191
+
192
+ #if UNITY_EDITOR
193
+ if (needUpdateDefault)
194
+ {
195
+ list.Sort((item1, item2) => string.Compare(item1.key, item2.key, StringComparison.Ordinal));
196
+ adapterConfig.defaultValue = list.ToArray();
197
+ EditorUtility.SetDirty(_config);
198
+ Log($"[RemoteConfig] Updated default remote config!");
199
+ }
200
+ #endif
201
+
202
+ string filePath = FileUtils.GetPath(fileName);
180
203
  FileUtils.Save(filePath, sb.ToString());
181
204
  Log($"[RemoteConfig] Saved remote config to {filePath}");
182
205
  NextState();
@@ -301,6 +324,7 @@ namespace Amanotes.Core.Internal
301
324
  [Serializable]
302
325
  public class RemoteConfigConfig
303
326
  {
327
+ public bool autoUpdateDefaultValue;
304
328
  public KeyValue[] defaultValue;
305
329
  public float firstFetchTimeOutInSeconds = 10;
306
330
  public float defaultTimeOutInSeconds = 3;
@@ -8,6 +8,20 @@ using static Amanotes.Core.Internal.Logging;
8
8
 
9
9
  namespace Amanotes.Core.Internal
10
10
  {
11
+ public class Utils
12
+ {
13
+ public static void DelayCall(float seconds, Action action)
14
+ {
15
+ AmaGDK._instance.StartCoroutine(DelayCallRoutine(seconds, action));
16
+ }
17
+
18
+ private static IEnumerator DelayCallRoutine(float seconds, Action callback)
19
+ {
20
+ yield return new WaitForSeconds(seconds);
21
+ callback();
22
+ }
23
+ }
24
+
11
25
  internal class FileUtils
12
26
  {
13
27
 
package/Runtime/AmaGDK.cs CHANGED
@@ -10,7 +10,7 @@ namespace Amanotes.Core
10
10
  {
11
11
  public partial class AmaGDK : MonoBehaviour
12
12
  {
13
- public const string VERSION = "0.2.9";
13
+ public const string VERSION = "0.2.11";
14
14
 
15
15
  internal static AmaGDK _instance;
16
16
  internal static Status _status = Status.None;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.amanotes.gdk",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "displayName": "AmaGDK",
5
5
  "description": "Amanotes Game Development Kit",
6
6
  "unity": "2020.3",