com.amanotes.gdk 0.2.73 → 0.2.75
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 +12 -0
- package/Editor/Extra/GDKSymbolDefine.cs +26 -2
- package/Extra/AmaGDKInstaller.unitypackage +0 -0
- package/Extra/CheckDiskSpace.unitypackage +0 -0
- package/Extra/Consent.unitypackage +0 -0
- package/Extra/ForceUpdate.unitypackage +0 -0
- package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
- package/Extra/PostProcessor.unitypackage +0 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/AmaGDKExample.unitypackage +0 -0
- package/Packages/AmaGDKTest.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.AdRevenue.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
- package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
- package/Packages/IronSourceAdapter.unitypackage +0 -0
- package/Packages/MaxAdNetworkAdapter.unitypackage +0 -0
- package/Packages/RevenueCatAdapter.unitypackage +0 -0
- package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
- package/Runtime/Ad/AdLogic.cs +13 -13
- package/Runtime/Ad/AmaGDK.Ads.cs +2 -1
- package/Runtime/AmaGDK.Analytics.cs +4 -1
- package/Runtime/AmaGDK.Consent.cs +2 -1
- package/Runtime/AmaGDK.Mono.cs +1 -1
- package/Runtime/AmaGDK.Singleton.cs +3 -1
- package/Runtime/AmaGDK.UserProfile.cs +3 -2
- package/Runtime/AmaGDK.cs +8 -4
- package/Runtime/GDKAudio/GDKAudio.cs +235 -60
- package/Runtime/GDKAudio/Resources/GDKAudioMixer.mixer +133 -0
- package/Runtime/GDKAudio/Resources/GDKAudioMixer.mixer.meta +8 -0
- package/Runtime/GDKAudio/Resources.meta +8 -0
- package/Runtime/Internal/AmaGDK.WebUtils.cs +4 -4
- package/Runtime/Internal/ForceQuitMonitor.cs +2 -2
- package/Runtime/Internal/GDKGeoLocationcs.cs +2 -1
- package/Runtime/Internal/GDKServerTime.cs +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.75] - 2024-09-20
|
|
4
|
+
- [Dev] Use GDKUtils.StartCoroutine to capture exceptions
|
|
5
|
+
- [Fix] Initialize modules lazily to fix AmaGDK serialization layout mismatch
|
|
6
|
+
|
|
7
|
+
## [0.2.74] - 2024-09-17
|
|
8
|
+
- [Dev] Add GDKAudio Example
|
|
9
|
+
- [Feature] Add AudioSource fallback for unsupported platforms
|
|
10
|
+
- Also: Improve public Audio API
|
|
11
|
+
- [Fix] Wait for ad callback in editor
|
|
12
|
+
- [Dev] Upgrade IronSource 8.3.0
|
|
13
|
+
- [Dev] Some improvements for batch enable / disable symbols in GDKSymbolDefine
|
|
14
|
+
|
|
3
15
|
## [0.2.73] - 2024-09-09
|
|
4
16
|
- [Fix] Disable incorrect in-editor warning for AdLogic
|
|
5
17
|
- [Dev] Remove AdEventTracking dependency on AppsFlyer
|
|
@@ -266,6 +266,7 @@ public partial class {className}
|
|
|
266
266
|
define = (GDKSymbolDefine)target;
|
|
267
267
|
symbolsProp = serializedObject.FindProperty("symbols");
|
|
268
268
|
loggerConfigProp = serializedObject.FindProperty("loggerConfig");
|
|
269
|
+
define.Read();
|
|
269
270
|
}
|
|
270
271
|
|
|
271
272
|
public override void OnInspectorGUI()
|
|
@@ -322,10 +323,33 @@ public partial class {className}
|
|
|
322
323
|
private void DrawSymbolsTab()
|
|
323
324
|
{
|
|
324
325
|
EditorGUILayout.PropertyField(symbolsProp, new GUIContent("DEFINE SYMBOLS"), true);
|
|
325
|
-
if (define.loggerConfig.enabled)
|
|
326
|
+
if (!define.loggerConfig.enabled) return;
|
|
327
|
+
|
|
328
|
+
GUILayout.BeginHorizontal();
|
|
329
|
+
{
|
|
330
|
+
if (GUILayout.Button("Select All"))
|
|
331
|
+
{
|
|
332
|
+
SetSelection(true);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (GUILayout.Button("Deselect All"))
|
|
336
|
+
{
|
|
337
|
+
SetSelection(false);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
GUILayout.EndHorizontal();
|
|
341
|
+
|
|
342
|
+
EditorGUILayout.PropertyField(loggerConfigProp.FindPropertyRelative("tags"), new GUIContent("LOGGER TAGS"), true);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private void SetSelection(bool isOn)
|
|
346
|
+
{
|
|
347
|
+
var tags = define.loggerConfig.tags;
|
|
348
|
+
for (var i = 0; i < tags.Count; i++)
|
|
326
349
|
{
|
|
327
|
-
|
|
350
|
+
tags[i].enabled = isOn;
|
|
328
351
|
}
|
|
352
|
+
EditorUtility.SetDirty(target);
|
|
329
353
|
}
|
|
330
354
|
|
|
331
355
|
private static bool showTemplate = false;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/Runtime/Ad/AdLogic.cs
CHANGED
|
@@ -27,7 +27,7 @@ namespace Amanotes.Core.Internal
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
internal
|
|
30
|
+
internal GDKRoutine _loadRoutine;
|
|
31
31
|
|
|
32
32
|
public void StartLoadAd()
|
|
33
33
|
{
|
|
@@ -38,7 +38,7 @@ namespace Amanotes.Core.Internal
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
Log("[Ad] StartLoadAd");
|
|
41
|
-
_loadRoutine =
|
|
41
|
+
_loadRoutine = GDKUtils.StartCoroutine(LoadAdRoutine());
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
public void StopLoadAd()
|
|
@@ -48,9 +48,8 @@ namespace Amanotes.Core.Internal
|
|
|
48
48
|
{
|
|
49
49
|
_loadState = LoadAdsState.None;
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
_instance.StopCoroutine(_loadRoutine);
|
|
51
|
+
|
|
52
|
+
_loadRoutine?.StopRoutine();
|
|
54
53
|
_loadRoutine = null;
|
|
55
54
|
}
|
|
56
55
|
|
|
@@ -128,7 +127,7 @@ namespace Amanotes.Core.Internal
|
|
|
128
127
|
|
|
129
128
|
// Show Ad logic
|
|
130
129
|
internal ShowAdsState _showState = ShowAdsState.None;
|
|
131
|
-
private
|
|
130
|
+
private GDKRoutine _showAdRoutine;
|
|
132
131
|
protected bool _isRequesting;
|
|
133
132
|
protected bool _isInterstitial => adType == AdType.Interstitial;
|
|
134
133
|
|
|
@@ -160,8 +159,8 @@ namespace Amanotes.Core.Internal
|
|
|
160
159
|
_isInterstitial ? AmaGDK.Event.INTER_SHOW_CALLED : AmaGDK.Event.REWARD_VIDEO_SHOW_CALLED
|
|
161
160
|
);
|
|
162
161
|
|
|
163
|
-
if (_showAdRoutine != null)
|
|
164
|
-
_showAdRoutine =
|
|
162
|
+
if (_showAdRoutine != null) _showAdRoutine.StopRoutine();
|
|
163
|
+
_showAdRoutine = GDKUtils.StartCoroutine(ShowAdRoutine());
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
private void OnApplicationFocus(bool focus)
|
|
@@ -184,7 +183,7 @@ namespace Amanotes.Core.Internal
|
|
|
184
183
|
|
|
185
184
|
TriggerOnAfterAdShow();
|
|
186
185
|
if (_showAdRoutine == null) return;
|
|
187
|
-
|
|
186
|
+
_showAdRoutine.StopRoutine();
|
|
188
187
|
_showAdRoutine = null;
|
|
189
188
|
|
|
190
189
|
if (Ads.context.adType == AdType.Interstitial)
|
|
@@ -260,7 +259,7 @@ namespace Amanotes.Core.Internal
|
|
|
260
259
|
if (_loadState != LoadAdsState.Requesting) StartLoadAd();
|
|
261
260
|
var counter = 0;
|
|
262
261
|
bool? hasInternet = null;
|
|
263
|
-
if (adConfig.checkInternet)
|
|
262
|
+
if (adConfig.checkInternet) GDKUtils.StartCoroutine(WebUtils.CheckInternet(result => hasInternet = result));
|
|
264
263
|
|
|
265
264
|
var wait1Sec = new WaitForSecondsRealtime(1f);
|
|
266
265
|
while (counter < timeout || timeout == -1)
|
|
@@ -285,10 +284,11 @@ namespace Amanotes.Core.Internal
|
|
|
285
284
|
|
|
286
285
|
private IEnumerator WaitForMediationCallback()
|
|
287
286
|
{
|
|
288
|
-
#if
|
|
289
|
-
while (!
|
|
287
|
+
#if UNITY_EDITOR
|
|
288
|
+
while (!context.hasClosed) yield return null;
|
|
289
|
+
yield break;
|
|
290
290
|
#endif
|
|
291
|
-
|
|
291
|
+
while (!isFocus) yield return null;
|
|
292
292
|
var wait4CallbackCounter = 0;
|
|
293
293
|
while (!context.potentiallyCompleted && wait4CallbackCounter <= MAX_FRAMES_WAIT_FOR_CALLBACK)
|
|
294
294
|
{
|
package/Runtime/Ad/AmaGDK.Ads.cs
CHANGED
|
@@ -108,7 +108,8 @@ namespace Amanotes.Core
|
|
|
108
108
|
public static bool allowAdRequest = true;
|
|
109
109
|
|
|
110
110
|
// internal use
|
|
111
|
-
|
|
111
|
+
private static readonly Lazy<AdsData> _localData = new Lazy<AdsData>(() => new AdsData().LoadJsonFromFile());
|
|
112
|
+
internal static AdsData localData => _localData.Value;
|
|
112
113
|
|
|
113
114
|
internal protected static AdShowContext context;
|
|
114
115
|
internal protected static AdAdapter _adapter;
|
|
@@ -308,9 +308,12 @@ namespace Amanotes.Core
|
|
|
308
308
|
internal static Predicate<EventParams> logEventHook;
|
|
309
309
|
internal static readonly ConcurrentQueue<EventParams> eventQueue = new ConcurrentQueue<EventParams>();
|
|
310
310
|
internal static readonly List<AnalyticsAdapter> listAdapters = new List<AnalyticsAdapter>();
|
|
311
|
-
internal static readonly AnalyticsData localData = new AnalyticsData().LoadJsonFromFile().BuildCache();
|
|
312
311
|
internal static SessionStat sessionStat;
|
|
313
312
|
internal static readonly GDKPool.Pool<EventParams> epPool = new GDKPool.Pool<EventParams>(1);
|
|
313
|
+
|
|
314
|
+
private static readonly Lazy<AnalyticsData> _localData = new Lazy<AnalyticsData>(
|
|
315
|
+
() => new AnalyticsData().LoadJsonFromFile().BuildCache());
|
|
316
|
+
internal static AnalyticsData localData => _localData.Value;
|
|
314
317
|
|
|
315
318
|
internal static readonly Dictionary<string, string> reservedPrefixes = new Dictionary<string, string>()
|
|
316
319
|
{
|
|
@@ -123,7 +123,8 @@ namespace Amanotes.Core
|
|
|
123
123
|
|
|
124
124
|
public static partial class Consent //Internal
|
|
125
125
|
{
|
|
126
|
-
private static readonly ConsentData
|
|
126
|
+
private static readonly Lazy<ConsentData> _data = new Lazy<ConsentData>(() => new ConsentData().LoadJsonFromFile());
|
|
127
|
+
private static ConsentData data => _data.Value;
|
|
127
128
|
private static Action _onConsentComplete;
|
|
128
129
|
|
|
129
130
|
internal static bool checkedATT => data.att >= Status.Allowed;
|
package/Runtime/AmaGDK.Mono.cs
CHANGED
|
@@ -76,7 +76,7 @@ namespace Amanotes.Core.Internal
|
|
|
76
76
|
|
|
77
77
|
public static void DelayCall(float seconds, Action action)
|
|
78
78
|
{
|
|
79
|
-
DoOnMainThread(() =>
|
|
79
|
+
DoOnMainThread(() => StartCoroutine(DelayCallRoutine(seconds, action)));
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
public static IEnumerator Timeout(float timeoutInSecs, Func<bool> completeCheckFunc)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
using Amanotes.Core.Internal;
|
|
2
3
|
using System.Threading;
|
|
3
4
|
using static Amanotes.Core.GDKDebug;
|
|
4
5
|
using static Amanotes.Core.Internal.Messsage;
|
|
@@ -21,7 +22,8 @@ namespace Amanotes.Core
|
|
|
21
22
|
_instance = this;
|
|
22
23
|
mainThreadId = Thread.CurrentThread.ManagedThreadId;
|
|
23
24
|
DontDestroyOnLoad(this);
|
|
24
|
-
|
|
25
|
+
|
|
26
|
+
GDKUtils.StartCoroutine(InitRoutine());
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
}
|
|
@@ -13,8 +13,9 @@ namespace Amanotes.Core
|
|
|
13
13
|
{
|
|
14
14
|
public const string GDK_USER_ID_UPDATED = nameof(GDK_USER_ID_UPDATED);
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
|
|
17
|
+
private static readonly Lazy<UserProfile> _user = new Lazy<UserProfile>(() => new UserProfile());
|
|
18
|
+
public static UserProfile User => _user.Value;
|
|
18
19
|
|
|
19
20
|
/// <summary>
|
|
20
21
|
/// We use multiple IDs to do the user mapping between AppsFlyer, IronSource & Firebase
|
package/Runtime/AmaGDK.cs
CHANGED
|
@@ -24,15 +24,19 @@ namespace Amanotes.Core
|
|
|
24
24
|
{
|
|
25
25
|
public partial class AmaGDK : MonoBehaviour
|
|
26
26
|
{
|
|
27
|
-
public const string VERSION = "0.2.
|
|
27
|
+
public const string VERSION = "0.2.75";
|
|
28
28
|
|
|
29
29
|
internal static Status _status = Status.None;
|
|
30
30
|
private static ConfigAsset _config = null;
|
|
31
31
|
|
|
32
|
+
private static readonly Lazy<GDKGeoLocation> _geoLocation = new Lazy<GDKGeoLocation>(() => new GDKGeoLocation());
|
|
33
|
+
private static readonly Lazy<GDKServerTime> _serverTime = new Lazy<GDKServerTime>(() => new GDKServerTime());
|
|
34
|
+
private static readonly Lazy<ForceQuitMonitor> _forceQuit = new Lazy<ForceQuitMonitor>(() => new ForceQuitMonitor());
|
|
35
|
+
|
|
32
36
|
internal static readonly GDKDispatcher dispatcher = new GDKDispatcher();
|
|
33
|
-
internal static
|
|
34
|
-
internal static
|
|
35
|
-
private static
|
|
37
|
+
internal static GDKGeoLocation GeoLocation => _geoLocation.Value;
|
|
38
|
+
internal static GDKServerTime ServerTime => _serverTime.Value;
|
|
39
|
+
private static ForceQuitMonitor ForceQuit => _forceQuit.Value;
|
|
36
40
|
|
|
37
41
|
internal static bool _allowInit = false;
|
|
38
42
|
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
#define UNITY_MOBILE
|
|
3
3
|
#endif
|
|
4
4
|
|
|
5
|
+
#if UNITY_2021_1_OR_NEWER && ((UNITY_MOBILE && !UNITY_EDITOR) || (UNITY_MOBILE && UNITY_EDITOR_OSX))
|
|
6
|
+
#define SUPPORTED_PLATFORMS
|
|
7
|
+
#endif
|
|
8
|
+
|
|
5
9
|
// GDKAudio is supported in the following environments:
|
|
6
10
|
// 1. On iOS devices.
|
|
7
11
|
// 2. On Android devices (excluding the Unity Editor).
|
|
8
12
|
// 3. In the Unity Editor running on macOS with Apple Silicon (M1, M2, etc.).
|
|
9
|
-
|
|
13
|
+
// For unsupported environments, GDKAudio will fallback to setting the AudioSource.pitch for time stretching.
|
|
10
14
|
|
|
11
15
|
using System;
|
|
12
16
|
using System.Runtime.InteropServices;
|
|
@@ -15,6 +19,10 @@ using static Amanotes.Core.GDKDebug;
|
|
|
15
19
|
|
|
16
20
|
using UnityEngine;
|
|
17
21
|
|
|
22
|
+
#if !SUPPORTED_PLATFORMS
|
|
23
|
+
using UnityEngine.Audio;
|
|
24
|
+
#endif
|
|
25
|
+
|
|
18
26
|
namespace Amanotes.Core
|
|
19
27
|
{
|
|
20
28
|
public static class AudioSourceExtensions
|
|
@@ -42,19 +50,43 @@ namespace Amanotes.Core
|
|
|
42
50
|
|
|
43
51
|
public partial class GDKAudio // public API
|
|
44
52
|
{
|
|
45
|
-
public float speed { get; set; } = 1f;
|
|
46
|
-
public bool loop { get; set; } = true;
|
|
47
|
-
public bool
|
|
53
|
+
public float speed { get; private set; } = 1f;
|
|
54
|
+
public bool loop { get; private set; } = true;
|
|
55
|
+
public bool mute { get; private set; } = false;
|
|
56
|
+
private float globalVolume = 1f;
|
|
57
|
+
|
|
48
58
|
|
|
49
|
-
public
|
|
59
|
+
public bool isPlaying { get; private set; } = false;
|
|
60
|
+
public bool isInitialized => initialized;
|
|
61
|
+
|
|
62
|
+
/// <summary>
|
|
63
|
+
/// Set the audio playback speed.
|
|
64
|
+
/// The audio playback speed is capped in range 0.5x and 2x. Set `force` to true to disable this cap. Note: `speed` lower than 0.75 will create audio artifacts.
|
|
65
|
+
/// </summary>
|
|
66
|
+
/// <param name="speed">The desired audio speed. `speed` lower than 0.75 will create artifacts.</param>
|
|
67
|
+
/// <param name="force">Force setting the speed. this will affect the audio pitch on speed faster than 2x and below 0.5x.</param>
|
|
68
|
+
public GDKAudio SetSpeed(float speed, bool force = false)
|
|
50
69
|
{
|
|
70
|
+
if (!force)
|
|
71
|
+
{
|
|
72
|
+
speed = Mathf.Clamp(speed, 0.5f, 2.0f);
|
|
73
|
+
}
|
|
51
74
|
this.speed = speed;
|
|
75
|
+
SetSpeedInternal();
|
|
52
76
|
return this;
|
|
53
77
|
}
|
|
54
78
|
|
|
55
79
|
public GDKAudio SetLoop(bool loop)
|
|
56
80
|
{
|
|
57
81
|
this.loop = loop;
|
|
82
|
+
audioSource.loop = this.loop;
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public GDKAudio SetMute(bool mute)
|
|
87
|
+
{
|
|
88
|
+
this.mute = mute;
|
|
89
|
+
audioSource.mute = this.mute;
|
|
58
90
|
return this;
|
|
59
91
|
}
|
|
60
92
|
|
|
@@ -74,6 +106,7 @@ namespace Amanotes.Core
|
|
|
74
106
|
{
|
|
75
107
|
isPlaying = false;
|
|
76
108
|
audioSource.Stop();
|
|
109
|
+
StopInternal();
|
|
77
110
|
return this;
|
|
78
111
|
}
|
|
79
112
|
|
|
@@ -107,7 +140,7 @@ namespace Amanotes.Core
|
|
|
107
140
|
}
|
|
108
141
|
}
|
|
109
142
|
|
|
110
|
-
partial class GDKAudio: MonoBehaviour
|
|
143
|
+
partial class GDKAudio : MonoBehaviour
|
|
111
144
|
{
|
|
112
145
|
private AudioSource audioSource;
|
|
113
146
|
|
|
@@ -130,8 +163,15 @@ namespace Amanotes.Core
|
|
|
130
163
|
}
|
|
131
164
|
}
|
|
132
165
|
|
|
166
|
+
private void Update()
|
|
167
|
+
{
|
|
168
|
+
// NOTE: AudioListener.volume can only be called in Main-Thread
|
|
169
|
+
globalVolume = AudioListener.volume;
|
|
170
|
+
}
|
|
171
|
+
|
|
133
172
|
private void OnDestroy()
|
|
134
173
|
{
|
|
174
|
+
Stop();
|
|
135
175
|
if (!initialized) return;
|
|
136
176
|
FreeMemory(ptrL, ptrR);
|
|
137
177
|
}
|
|
@@ -145,38 +185,57 @@ namespace Amanotes.Core
|
|
|
145
185
|
}
|
|
146
186
|
}
|
|
147
187
|
|
|
188
|
+
#if SUPPORTED_PLATFORMS
|
|
148
189
|
partial class GDKAudio
|
|
149
190
|
{
|
|
150
|
-
private
|
|
191
|
+
public int numSamples { get; private set; }
|
|
192
|
+
public int numChannels { get; private set; }
|
|
193
|
+
public int sampleRate { get; private set; } = 44100;
|
|
194
|
+
public int numFrames { get; private set; } = 1;
|
|
195
|
+
public float time
|
|
196
|
+
{
|
|
197
|
+
get => timeSamples / (float)sampleRate;
|
|
198
|
+
set => timeSamples = (int)(value * sampleRate);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private int timeSamples
|
|
202
|
+
{
|
|
203
|
+
get => idxFrame * hop;
|
|
204
|
+
set => SetPlaybackFrame(value / hop);
|
|
205
|
+
}
|
|
206
|
+
private float _volume = 1f;
|
|
207
|
+
|
|
208
|
+
public float volume
|
|
209
|
+
{
|
|
210
|
+
get => _volume;
|
|
211
|
+
set => _volume = Mathf.Clamp01(value);
|
|
212
|
+
}
|
|
151
213
|
|
|
152
|
-
private int numSamples;
|
|
153
|
-
private int numChannel;
|
|
154
214
|
|
|
155
|
-
private
|
|
215
|
+
private float[] audioData;
|
|
216
|
+
|
|
156
217
|
private int bufferLength;
|
|
157
218
|
private int numBuffer;
|
|
158
219
|
|
|
159
220
|
private int nFFT = 2048;
|
|
160
221
|
private int hop = 512;
|
|
161
222
|
private int cntSave = 0;
|
|
162
|
-
private int
|
|
163
|
-
private int idxFrame = 0;
|
|
223
|
+
private int idxFrame { get; set; } = 0;
|
|
164
224
|
private float[] hopFrame;
|
|
165
|
-
private float
|
|
166
|
-
private float
|
|
167
|
-
private Vector3 positionOld;
|
|
225
|
+
private float[] dataOut;
|
|
226
|
+
private float[] dataOutSave;
|
|
168
227
|
|
|
169
|
-
|
|
228
|
+
#if UNITY_IOS && !UNITY_EDITOR
|
|
170
229
|
private const string LIBRARY_NAME ="__Internal";
|
|
171
|
-
|
|
172
|
-
private const string LIBRARY_NAME ="atensor";
|
|
173
|
-
|
|
230
|
+
#else
|
|
231
|
+
private const string LIBRARY_NAME = "atensor";
|
|
232
|
+
#endif
|
|
174
233
|
|
|
175
234
|
[DllImport(LIBRARY_NAME, EntryPoint = "ptrResampleMulti")]
|
|
176
|
-
private static extern int ResampleMulti(float
|
|
235
|
+
private static extern int ResampleMulti(float[] inData, ref IntPtr outData, float fs, float targetFs, int numSrcSamples, int numChannels, ref IntPtr ptrL);
|
|
177
236
|
|
|
178
237
|
[DllImport(LIBRARY_NAME, EntryPoint = "ptrTSM_Init")]
|
|
179
|
-
private static extern void TSM_Init(float
|
|
238
|
+
private static extern void TSM_Init(float[] firstFrame, float scale, float fs, int numChannel, int nFft, int hop, ref IntPtr ptrL, ref IntPtr ptrR);
|
|
180
239
|
|
|
181
240
|
[DllImport(LIBRARY_NAME, EntryPoint = "ptrTSM_Processing")]
|
|
182
241
|
private static extern int TSM_Processing(float[] inData, float[] outData, float scale, IntPtr ptrL, IntPtr ptrR);
|
|
@@ -192,81 +251,101 @@ namespace Amanotes.Core
|
|
|
192
251
|
internal void LoadAudioInternal(AudioClip audioClip)
|
|
193
252
|
{
|
|
194
253
|
AudioSettings.GetDSPBufferSize(out bufferLength, out numBuffer);
|
|
195
|
-
hop =
|
|
254
|
+
hop = Mathf.Min(bufferLength, 512);
|
|
196
255
|
numSamples = audioClip.samples;
|
|
197
|
-
|
|
198
|
-
|
|
256
|
+
numChannels = audioClip.channels;
|
|
257
|
+
sampleRate = audioClip.frequency;
|
|
258
|
+
|
|
259
|
+
if (numChannels < 2)
|
|
260
|
+
{
|
|
261
|
+
numChannels = 2;
|
|
262
|
+
audioData = new float[numSamples * numChannels];
|
|
263
|
+
audioClip.GetData(audioData, 0);
|
|
264
|
+
for (int i = numSamples - 1; i > 0; --i)
|
|
265
|
+
{
|
|
266
|
+
audioData[i * 2] = audioData[i];
|
|
267
|
+
audioData[(i * 2) - 1] = audioData[i];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else
|
|
271
|
+
{
|
|
272
|
+
audioData = new float[numSamples * numChannels];
|
|
273
|
+
audioClip.GetData(audioData, 0);
|
|
274
|
+
}
|
|
199
275
|
|
|
200
|
-
audioData = new float[numSamples * numChannel];
|
|
201
|
-
audioClip.GetData(audioData, 0);
|
|
202
276
|
|
|
203
277
|
// Do resampling
|
|
204
|
-
if (
|
|
278
|
+
if (sampleRate != AudioSettings.outputSampleRate)
|
|
205
279
|
{
|
|
206
280
|
var audioDataResample = new IntPtr();
|
|
207
281
|
numSamples = ResampleMulti(
|
|
208
282
|
audioData,
|
|
209
283
|
ref audioDataResample,
|
|
210
|
-
|
|
284
|
+
sampleRate,
|
|
211
285
|
AudioSettings.outputSampleRate,
|
|
212
|
-
numSamples *
|
|
213
|
-
|
|
286
|
+
numSamples * numChannels,
|
|
287
|
+
numChannels,
|
|
214
288
|
ref ptrL
|
|
215
|
-
) /
|
|
216
|
-
audioData = new float[numSamples*
|
|
217
|
-
Marshal.Copy(audioDataResample, audioData, 0, numSamples*
|
|
289
|
+
) / numChannels;
|
|
290
|
+
audioData = new float[numSamples * numChannels];
|
|
291
|
+
Marshal.Copy(audioDataResample, audioData, 0, numSamples * numChannels);
|
|
292
|
+
sampleRate = AudioSettings.outputSampleRate;
|
|
218
293
|
LogWarning(
|
|
219
|
-
"Warning: The input AudioClip has a sample rate of
|
|
220
|
-
" which does not match AudioSetting sample rate of
|
|
294
|
+
$"Warning: The input AudioClip has a sample rate of {sampleRate} Hz," +
|
|
295
|
+
$" which does not match AudioSetting sample rate of {AudioSettings.outputSampleRate} Hz." +
|
|
221
296
|
" GDKAudio will resample the audio to match AudioSetting with high memory usage." +
|
|
222
297
|
" We recommend resampling the audio to 44100 Hz before using it in Unity."
|
|
223
298
|
);
|
|
224
299
|
}
|
|
225
300
|
|
|
226
|
-
|
|
227
|
-
Log("[AAA]numChannel:" + numChannel);
|
|
228
|
-
Log("[AAA]bufferLength:" + bufferLength);
|
|
229
|
-
Log("[AAA]numBuffer:" + numBuffer);
|
|
301
|
+
numFrames = (numSamples - nFFT) / hop;
|
|
230
302
|
|
|
231
|
-
|
|
232
|
-
|
|
303
|
+
Log(
|
|
304
|
+
$"[AAA] audioData: {audioData.Length}\n" +
|
|
305
|
+
$"[AAA] numSamples: {numSamples}\n" +
|
|
306
|
+
$"[AAA] numChannel: {numChannels}\n" +
|
|
307
|
+
$"[AAA] bufferLength: {bufferLength}\n" +
|
|
308
|
+
$"[AAA] numBuffer: {numBuffer}\n" +
|
|
309
|
+
$"[AAA] numFrames: {numFrames}"
|
|
310
|
+
);
|
|
233
311
|
|
|
234
|
-
numFrame = (numSamples - nFFT) / hop;
|
|
235
312
|
// Initialize
|
|
236
313
|
Log("[AAA]TSM_Init");
|
|
237
|
-
TSM_Init(audioData, speed,
|
|
314
|
+
TSM_Init(audioData, speed, sampleRate, numChannels, nFFT, hop, ref ptrL, ref ptrR);
|
|
315
|
+
|
|
238
316
|
initialized = true;
|
|
239
|
-
hopFrame = new float[hop*
|
|
240
|
-
dataOut = new float[4*
|
|
241
|
-
dataOutSave = new float[
|
|
317
|
+
hopFrame = new float[hop * numChannels];
|
|
318
|
+
dataOut = new float[4 * numChannels * hop]; // minimum of scale is 0.25
|
|
319
|
+
dataOutSave = new float[numChannels * bufferLength];
|
|
242
320
|
|
|
243
321
|
audioSource.clip = audioClip;
|
|
244
322
|
audioSource.loop = loop;
|
|
245
|
-
Log("[AAA]AudioSettings.outputSampleRate (later):
|
|
323
|
+
Log($"[AAA]AudioSettings.outputSampleRate (later): {AudioSettings.outputSampleRate}");
|
|
246
324
|
}
|
|
247
325
|
|
|
248
326
|
private void OnAudioFilterRead(float[] data, int channels)
|
|
249
327
|
{
|
|
250
328
|
if (!isPlaying) return;
|
|
251
329
|
|
|
252
|
-
if (idxFrame >=
|
|
330
|
+
if (idxFrame >= numFrames)
|
|
253
331
|
{
|
|
254
332
|
if (!loop)
|
|
255
333
|
{
|
|
256
|
-
for (int i = 0; i < bufferLength *
|
|
334
|
+
for (int i = 0; i < bufferLength * numChannels; i++)
|
|
257
335
|
{
|
|
258
336
|
data[i] = 0;
|
|
259
337
|
}
|
|
260
338
|
return;
|
|
261
339
|
}
|
|
262
340
|
idxFrame = 0;
|
|
263
|
-
Log("[AAA] Loop");
|
|
264
341
|
}
|
|
265
342
|
|
|
266
343
|
|
|
267
344
|
int lengthOut = 0;
|
|
268
345
|
int lengthOutOld = 0;
|
|
269
|
-
int idxSave=0;
|
|
346
|
+
int idxSave = 0;
|
|
347
|
+
int muteModifier = mute ? 0 : 1;
|
|
348
|
+
float volumeModifier = muteModifier * volume * globalVolume;
|
|
270
349
|
|
|
271
350
|
for (; idxSave < cntSave; idxSave++)
|
|
272
351
|
{
|
|
@@ -275,27 +354,27 @@ namespace Amanotes.Core
|
|
|
275
354
|
|
|
276
355
|
cntSave = 0;
|
|
277
356
|
|
|
278
|
-
while (lengthOut < bufferLength*
|
|
357
|
+
while (lengthOut < bufferLength * numChannels - idxSave)
|
|
279
358
|
{
|
|
280
|
-
if (idxFrame >=
|
|
359
|
+
if (idxFrame >= numFrames) break;
|
|
281
360
|
|
|
282
361
|
Array.Copy(
|
|
283
362
|
audioData,
|
|
284
|
-
nFFT*
|
|
363
|
+
nFFT * numChannels + idxFrame * hop * numChannels,
|
|
285
364
|
hopFrame,
|
|
286
365
|
0,
|
|
287
|
-
hop*
|
|
366
|
+
hop * numChannels);
|
|
288
367
|
int temp = TSM_Processing(hopFrame, dataOut, speed, ptrL, ptrR);
|
|
289
368
|
lengthOut = lengthOutOld + temp;
|
|
290
369
|
for (int i = lengthOutOld; i < lengthOut; i++)
|
|
291
370
|
{
|
|
292
|
-
if (
|
|
371
|
+
if (i < bufferLength * numChannels - idxSave)
|
|
293
372
|
{
|
|
294
|
-
data[i + idxSave] = dataOut[i - lengthOutOld];
|
|
373
|
+
data[i + idxSave] = dataOut[i - lengthOutOld] * volumeModifier;
|
|
295
374
|
}
|
|
296
375
|
else
|
|
297
376
|
{
|
|
298
|
-
dataOutSave[i + idxSave - bufferLength*
|
|
377
|
+
dataOutSave[i + idxSave - bufferLength * numChannels] = dataOut[i - lengthOutOld] * volumeModifier;
|
|
299
378
|
cntSave++;
|
|
300
379
|
}
|
|
301
380
|
}
|
|
@@ -303,6 +382,102 @@ namespace Amanotes.Core
|
|
|
303
382
|
idxFrame++;
|
|
304
383
|
}
|
|
305
384
|
}
|
|
385
|
+
|
|
386
|
+
private void SetSpeedInternal()
|
|
387
|
+
{
|
|
388
|
+
// This method is intentionally left empty;
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
private void StopInternal()
|
|
393
|
+
{
|
|
394
|
+
idxFrame = 0;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
private void SetPlaybackFrame(int frame)
|
|
398
|
+
{
|
|
399
|
+
frame = Mathf.Clamp(frame, 0, numFrames - 1);
|
|
400
|
+
idxFrame = frame;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
public float GetAudioDurationInSec()
|
|
404
|
+
{
|
|
405
|
+
return numFrames * hop / sampleRate;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
}
|
|
409
|
+
#else
|
|
410
|
+
#warning "GDKAudio is not supported on this platform. You can still use GDKAudio, but it will fallback to changing AudioSource.pitch"
|
|
411
|
+
partial class GDKAudio
|
|
412
|
+
{
|
|
413
|
+
public int numSamples => audioSource.clip.samples;
|
|
414
|
+
public int numChannels => audioSource.clip.channels;
|
|
415
|
+
public int sampleRate => audioSource.clip.frequency;
|
|
416
|
+
public int numFrames => numSamples;
|
|
417
|
+
|
|
418
|
+
public float time
|
|
419
|
+
{
|
|
420
|
+
get => audioSource.time;
|
|
421
|
+
set => audioSource.time = value;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
public float volume
|
|
425
|
+
{
|
|
426
|
+
get => audioSource.volume;
|
|
427
|
+
set => audioSource.volume = value;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
private AudioMixer audioMixer;
|
|
431
|
+
|
|
432
|
+
// These attributes are intentionally left unused for compatibility.
|
|
433
|
+
private readonly IntPtr ptrL;
|
|
434
|
+
private readonly IntPtr ptrR;
|
|
435
|
+
private bool initialized = false;
|
|
436
|
+
|
|
437
|
+
internal void LoadAudioInternal(AudioClip audioClip)
|
|
438
|
+
{
|
|
439
|
+
audioMixer = Resources.Load("GDKAudioMixer") as AudioMixer;
|
|
440
|
+
audioSource.clip = audioClip;
|
|
441
|
+
audioSource.loop = loop;
|
|
442
|
+
audioSource.outputAudioMixerGroup = audioMixer.FindMatchingGroups("PitchShifter")[0];
|
|
443
|
+
SetSpeedInternal();
|
|
444
|
+
initialized = true;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
#pragma warning disable IDE0060
|
|
448
|
+
private static void FreeMemory(IntPtr ptrL, IntPtr ptrR)
|
|
449
|
+
{
|
|
450
|
+
// This method is intentionally left empty.
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
#pragma warning restore IDE0060
|
|
454
|
+
|
|
455
|
+
private void SetSpeedInternal()
|
|
456
|
+
{
|
|
457
|
+
audioSource.pitch = speed;
|
|
458
|
+
audioMixer.SetFloat("GDKAudioMixer_PitchShifter_Pitch", 1.0f / speed);
|
|
459
|
+
|
|
460
|
+
// Note: using AudioMixer's Pitch Shifter effect makes the audio a bit louder.
|
|
461
|
+
if (speed != 1.0f)
|
|
462
|
+
{
|
|
463
|
+
audioMixer.SetFloat("GDKAudioMixer_PitchShifter_Wet", 0.0f); // disable bypass
|
|
464
|
+
}
|
|
465
|
+
else
|
|
466
|
+
{
|
|
467
|
+
audioMixer.SetFloat("GDKAudioMixer_PitchShifter_Wet", -80.0f); // enable bypass
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
private void StopInternal()
|
|
472
|
+
{
|
|
473
|
+
// This method is intentionally left empty.
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
public float GetAudioDurationInSec()
|
|
478
|
+
{
|
|
479
|
+
return audioSource.clip.length;
|
|
480
|
+
}
|
|
306
481
|
}
|
|
307
|
-
|
|
308
|
-
|
|
482
|
+
#endif
|
|
483
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
%YAML 1.1
|
|
2
|
+
%TAG !u! tag:unity3d.com,2011:
|
|
3
|
+
--- !u!244 &-8349116154838344368
|
|
4
|
+
AudioMixerEffectController:
|
|
5
|
+
m_ObjectHideFlags: 3
|
|
6
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
7
|
+
m_PrefabInstance: {fileID: 0}
|
|
8
|
+
m_PrefabAsset: {fileID: 0}
|
|
9
|
+
m_Name:
|
|
10
|
+
m_EffectID: 62a47044fd08b45cabe751635fe041c0
|
|
11
|
+
m_EffectName: Pitch Shifter
|
|
12
|
+
m_MixLevel: bd39be11d4b2e4d6b8d9eeb4854b6d41
|
|
13
|
+
m_Parameters:
|
|
14
|
+
- m_ParameterName: Pitch
|
|
15
|
+
m_GUID: e55392888f7544d359c260ebe4936b8b
|
|
16
|
+
- m_ParameterName: FFT size
|
|
17
|
+
m_GUID: 35576bb3f03224c908f09c33dcda7d23
|
|
18
|
+
- m_ParameterName: Overlap
|
|
19
|
+
m_GUID: eca58a2b2f2e54e08a192192f13b7093
|
|
20
|
+
- m_ParameterName: Max channels
|
|
21
|
+
m_GUID: 457e26280456e494eaa0151ae35aef65
|
|
22
|
+
m_SendTarget: {fileID: 0}
|
|
23
|
+
m_EnableWetMix: 1
|
|
24
|
+
m_Bypass: 0
|
|
25
|
+
--- !u!243 &-4402511794110498525
|
|
26
|
+
AudioMixerGroupController:
|
|
27
|
+
m_ObjectHideFlags: 0
|
|
28
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
29
|
+
m_PrefabInstance: {fileID: 0}
|
|
30
|
+
m_PrefabAsset: {fileID: 0}
|
|
31
|
+
m_Name: PitchShifter
|
|
32
|
+
m_AudioMixer: {fileID: 24100000}
|
|
33
|
+
m_GroupID: 5da7d04a1a2b04cc0bffe1517ba3a8ae
|
|
34
|
+
m_Children: []
|
|
35
|
+
m_Volume: 84ace98bec1c94eacabcb0b7cb3b7bce
|
|
36
|
+
m_Pitch: 62b46cb0c79874888b6d32635cc94987
|
|
37
|
+
m_Send: 00000000000000000000000000000000
|
|
38
|
+
m_Effects:
|
|
39
|
+
- {fileID: 3247467911740954387}
|
|
40
|
+
- {fileID: -8349116154838344368}
|
|
41
|
+
m_UserColorIndex: 0
|
|
42
|
+
m_Mute: 0
|
|
43
|
+
m_Solo: 0
|
|
44
|
+
m_BypassEffects: 0
|
|
45
|
+
--- !u!241 &24100000
|
|
46
|
+
AudioMixerController:
|
|
47
|
+
m_ObjectHideFlags: 0
|
|
48
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
49
|
+
m_PrefabInstance: {fileID: 0}
|
|
50
|
+
m_PrefabAsset: {fileID: 0}
|
|
51
|
+
m_Name: GDKAudioMixer
|
|
52
|
+
m_OutputGroup: {fileID: 0}
|
|
53
|
+
m_MasterGroup: {fileID: 24300002}
|
|
54
|
+
m_Snapshots:
|
|
55
|
+
- {fileID: 24500006}
|
|
56
|
+
m_StartSnapshot: {fileID: 24500006}
|
|
57
|
+
m_SuspendThreshold: -80
|
|
58
|
+
m_EnableSuspend: 1
|
|
59
|
+
m_UpdateMode: 0
|
|
60
|
+
m_ExposedParameters:
|
|
61
|
+
- guid: bd39be11d4b2e4d6b8d9eeb4854b6d41
|
|
62
|
+
name: GDKAudioMixer_PitchShifter_Wet
|
|
63
|
+
- guid: e55392888f7544d359c260ebe4936b8b
|
|
64
|
+
name: GDKAudioMixer_PitchShifter_Pitch
|
|
65
|
+
m_AudioMixerGroupViews:
|
|
66
|
+
- guids:
|
|
67
|
+
- 363e439911f3f4a8ea067b41152e999e
|
|
68
|
+
- 5da7d04a1a2b04cc0bffe1517ba3a8ae
|
|
69
|
+
name: View
|
|
70
|
+
m_CurrentViewIndex: 0
|
|
71
|
+
m_TargetSnapshot: {fileID: 24500006}
|
|
72
|
+
--- !u!243 &24300002
|
|
73
|
+
AudioMixerGroupController:
|
|
74
|
+
m_ObjectHideFlags: 0
|
|
75
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
76
|
+
m_PrefabInstance: {fileID: 0}
|
|
77
|
+
m_PrefabAsset: {fileID: 0}
|
|
78
|
+
m_Name: Master
|
|
79
|
+
m_AudioMixer: {fileID: 24100000}
|
|
80
|
+
m_GroupID: 363e439911f3f4a8ea067b41152e999e
|
|
81
|
+
m_Children:
|
|
82
|
+
- {fileID: -4402511794110498525}
|
|
83
|
+
m_Volume: 6606288e2cb5341fdb244f298dde03ec
|
|
84
|
+
m_Pitch: 879bd0be0ae3a4cf29389421cfecca55
|
|
85
|
+
m_Send: 00000000000000000000000000000000
|
|
86
|
+
m_Effects:
|
|
87
|
+
- {fileID: 24400004}
|
|
88
|
+
m_UserColorIndex: 0
|
|
89
|
+
m_Mute: 0
|
|
90
|
+
m_Solo: 0
|
|
91
|
+
m_BypassEffects: 0
|
|
92
|
+
--- !u!244 &24400004
|
|
93
|
+
AudioMixerEffectController:
|
|
94
|
+
m_ObjectHideFlags: 3
|
|
95
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
96
|
+
m_PrefabInstance: {fileID: 0}
|
|
97
|
+
m_PrefabAsset: {fileID: 0}
|
|
98
|
+
m_Name:
|
|
99
|
+
m_EffectID: 7983e0a3221f048a99731b59d2cc18c7
|
|
100
|
+
m_EffectName: Attenuation
|
|
101
|
+
m_MixLevel: c382a734e5f624369a85819269419d46
|
|
102
|
+
m_Parameters: []
|
|
103
|
+
m_SendTarget: {fileID: 0}
|
|
104
|
+
m_EnableWetMix: 0
|
|
105
|
+
m_Bypass: 0
|
|
106
|
+
--- !u!245 &24500006
|
|
107
|
+
AudioMixerSnapshotController:
|
|
108
|
+
m_ObjectHideFlags: 0
|
|
109
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
110
|
+
m_PrefabInstance: {fileID: 0}
|
|
111
|
+
m_PrefabAsset: {fileID: 0}
|
|
112
|
+
m_Name: Snapshot
|
|
113
|
+
m_AudioMixer: {fileID: 24100000}
|
|
114
|
+
m_SnapshotID: d21282160540b4f76ae89a904c77c48c
|
|
115
|
+
m_FloatValues:
|
|
116
|
+
bd39be11d4b2e4d6b8d9eeb4854b6d41: 0
|
|
117
|
+
e55392888f7544d359c260ebe4936b8b: 1
|
|
118
|
+
84ace98bec1c94eacabcb0b7cb3b7bce: 0
|
|
119
|
+
m_TransitionOverrides: {}
|
|
120
|
+
--- !u!244 &3247467911740954387
|
|
121
|
+
AudioMixerEffectController:
|
|
122
|
+
m_ObjectHideFlags: 3
|
|
123
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
124
|
+
m_PrefabInstance: {fileID: 0}
|
|
125
|
+
m_PrefabAsset: {fileID: 0}
|
|
126
|
+
m_Name:
|
|
127
|
+
m_EffectID: ba84eaaddd67e4c15a1738b305b3ea16
|
|
128
|
+
m_EffectName: Attenuation
|
|
129
|
+
m_MixLevel: 54ebf4c4d3ebc4055b44df5b15c3fbd9
|
|
130
|
+
m_Parameters: []
|
|
131
|
+
m_SendTarget: {fileID: 0}
|
|
132
|
+
m_EnableWetMix: 0
|
|
133
|
+
m_Bypass: 0
|
|
@@ -96,12 +96,12 @@ namespace Amanotes.Core.Internal
|
|
|
96
96
|
|
|
97
97
|
internal class WebUtils
|
|
98
98
|
{
|
|
99
|
-
public static
|
|
99
|
+
public static GDKRoutine PostJson(string url, string jsonData, Action<bool, string> onComplete = null,
|
|
100
100
|
Dictionary<string, string> headers = null)
|
|
101
101
|
{
|
|
102
|
-
return
|
|
102
|
+
return GDKUtils.StartCoroutine(PostJsonCoroutine(url, jsonData, onComplete, headers));
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
private static IEnumerator PostJsonCoroutine(string url, string jsonData,
|
|
106
106
|
Action<bool, string> onComplete = null, Dictionary<string, string> headers = null)
|
|
107
107
|
{
|
|
@@ -131,7 +131,7 @@ namespace Amanotes.Core.Internal
|
|
|
131
131
|
|
|
132
132
|
public static void CheckInternetConnection(Action<bool> hasInternet)
|
|
133
133
|
{
|
|
134
|
-
|
|
134
|
+
GDKUtils.StartCoroutine(CheckInternet(hasInternet));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
public static IEnumerator CheckInternet(Action<bool> hasInternet)
|
|
@@ -38,8 +38,8 @@ namespace Amanotes.Core.Internal
|
|
|
38
38
|
isDirty = false;
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
private readonly Lazy<ForceQuitData> _localData = new Lazy<ForceQuitData>(() => new ForceQuitData());
|
|
42
|
+
private ForceQuitData localData => _localData.Value;
|
|
43
43
|
|
|
44
44
|
public ForceQuitMonitor()
|
|
45
45
|
{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
using Amanotes.Core.Internal;
|
|
1
2
|
using System;
|
|
2
3
|
using System.Collections;
|
|
3
4
|
using UnityEngine;
|
|
@@ -86,7 +87,7 @@ namespace Amanotes.Core
|
|
|
86
87
|
|
|
87
88
|
void IGeoLocationProvider.FetchGeoLocation(Action<GeoLocationData> result)
|
|
88
89
|
{
|
|
89
|
-
|
|
90
|
+
GDKUtils.StartCoroutine(FetchGeoLocationRoutine(result));
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
private IEnumerator FetchGeoLocationRoutine(Action<GeoLocationData> result)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
using Amanotes.Core.Internal;
|
|
1
2
|
using System;
|
|
2
3
|
using System.Collections;
|
|
3
4
|
using System.Collections.Generic;
|
|
@@ -37,7 +38,7 @@ namespace Amanotes.Core
|
|
|
37
38
|
|
|
38
39
|
public void FetchServerTime(Action<ServerTimeData> result)
|
|
39
40
|
{
|
|
40
|
-
|
|
41
|
+
GDKUtils.StartCoroutine(FetchTimeRoutine(result));
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
private IEnumerator FetchTimeRoutine(Action<ServerTimeData> result)
|