com.amanotes.gdk 0.2.66 → 0.2.68

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/Editor/Extra/GDKAutoUpdateAdapter.cs +67 -0
  3. package/Editor/Extra/GDKAutoUpdateAdapter.cs.meta +11 -0
  4. package/Extra/AmaGDKInstaller.unitypackage +0 -0
  5. package/Extra/CheckDiskSpace.unitypackage +0 -0
  6. package/Extra/ForceUpdate.unitypackage +0 -0
  7. package/Extra/GoogleCMP.unitypackage +0 -0
  8. package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
  9. package/Extra/LegacyGDKUpdateHelper.unitypackage.meta +7 -0
  10. package/Extra/PostProcessor.unitypackage +0 -0
  11. package/Packages/AmaGDKConfig.unitypackage +0 -0
  12. package/Packages/AmaGDKExample.unitypackage +0 -0
  13. package/Packages/AmaGDKTest.unitypackage +0 -0
  14. package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
  15. package/Packages/AppsFlyerAdapter.unitypackage +0 -0
  16. package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
  17. package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
  18. package/Packages/IronSourceAdapter.unitypackage +0 -0
  19. package/Packages/RevenueCatAdapter.unitypackage +0 -0
  20. package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
  21. package/Runtime/Ad/AdExtension.cs +111 -0
  22. package/Runtime/Ad/AdExtension.cs.meta +3 -0
  23. package/Runtime/Ad/AdLogic.cs +530 -0
  24. package/Runtime/Ad/AdLogic.cs.meta +3 -0
  25. package/Runtime/Ad/AdModuleConfig.cs +39 -0
  26. package/Runtime/Ad/AdModuleConfig.cs.meta +3 -0
  27. package/Runtime/Ad/AdShowContext.cs +43 -0
  28. package/Runtime/Ad/AdShowContext.cs.meta +3 -0
  29. package/Runtime/Ad/AmaGDK.Ads.cs +383 -0
  30. package/Runtime/Ad.meta +8 -0
  31. package/Runtime/AmaGDK.Analytics.cs +20 -1
  32. package/Runtime/AmaGDK.Device.cs +105 -0
  33. package/Runtime/AmaGDK.Device.cs.meta +3 -0
  34. package/Runtime/AmaGDK.Mono.cs +0 -1
  35. package/Runtime/AmaGDK.cs +6 -2
  36. package/Runtime/AudioToolkit/AmaGDK.Audio.cs +16 -0
  37. package/Runtime/AudioToolkit/Plugins/Android/GDKAudioDeviceDetector.java +1 -1
  38. package/Runtime/Fps/AmaFPS.Utils.cs +44 -0
  39. package/Runtime/Fps/AmaFPS.Utils.cs.meta +3 -0
  40. package/Runtime/Fps/AmaFPS.cs +197 -0
  41. package/Runtime/Fps/AmaFPS.cs.meta +11 -0
  42. package/Runtime/Fps/AmaFPSVisualizer.cs +246 -0
  43. package/Runtime/Fps/AmaFPSVisualizer.cs.meta +11 -0
  44. package/Runtime/Fps/BollingerBands.cs +99 -0
  45. package/Runtime/Fps/BollingerBands.cs.meta +11 -0
  46. package/Runtime/Fps/FPSVisualizer.prefab +406 -0
  47. package/Runtime/Fps/FPSVisualizer.prefab.meta +7 -0
  48. package/Runtime/Fps/FrameRecorder.cs +172 -0
  49. package/Runtime/Fps/FrameRecorder.cs.meta +3 -0
  50. package/Runtime/Fps.meta +8 -0
  51. package/package.json +1 -1
  52. package/Runtime/AmaGDK.Ads.cs +0 -1077
  53. /package/Runtime/{AmaGDK.Ads.cs.meta → Ad/AmaGDK.Ads.cs.meta} +0 -0
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: f9be250eab01474da9eea488bef071e0
3
+ timeCreated: 1716886847
@@ -0,0 +1,197 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using Amanotes.Core.Internal;
4
+ using static Amanotes.Core.Internal.Logging;
5
+ using UnityEngine;
6
+ using UnityEngine.Events;
7
+
8
+ namespace Amanotes.Core.Internal
9
+ {
10
+ public partial class ConfigAsset
11
+ {
12
+ [SerializeField]
13
+ public FPSConfig fpsConfig;
14
+ }
15
+ }
16
+
17
+ namespace Amanotes.Core
18
+ {
19
+ public partial class AmaGDK
20
+ {
21
+ public static readonly AmaFPS FPS = new AmaFPS();
22
+ }
23
+
24
+
25
+ [Serializable]
26
+ public class FPSConfig
27
+ {
28
+ [Tooltip("Enable this to always record FPS for the app session. This allows developers to get the current FPS and current average FPS at any time.")]
29
+ public bool enableRealtimeFPS = false;
30
+
31
+ [Tooltip("The number of frames over which FPS is calculated. The FPS will be averaged after every 'frameGroup' frames.")]
32
+ [Range(1, 60)]
33
+ public int frameGroup = 20;
34
+
35
+ [Header("Lagging Tolerance")]
36
+ [Tooltip("The size of the sliding window used to calculate the Simple Moving Average (SMA) of the FPS.")]
37
+ [Range(10, 100)]
38
+ public int windowSize = 15;
39
+
40
+ [Tooltip("The allowed deviation from the SMA to detect an FPS drop.")]
41
+ [Range(0f, 0.3f)]
42
+ public float deviation = 0.1f;
43
+
44
+ [Tooltip("Number of frames to skip after OnApplicationFocus to avoid false alarms.")]
45
+ [Range(0, 60)]
46
+ public int skipFrameFocus = 10;
47
+
48
+ [Header("Callback")]
49
+ [Tooltip("This callback is invoked when an FPS drop is detected.")]
50
+ public UnityEvent onFrameDrop = new UnityEvent();
51
+ }
52
+
53
+ public partial class AmaFPS // public API
54
+ {
55
+
56
+ public float CurrentFPS => _realtime?.lastFPS ?? 0;
57
+ public float AverageFPS => _realtime?.avgFPS ?? 0;
58
+ public float MinFPS => _realtime?.minFPS ?? 0;
59
+ public float MaxFPS => _realtime?.maxFPS ?? 0;
60
+ public Action<string, Dictionary<string, object>> LogEventHook;
61
+
62
+ private bool _isAppReady = false;
63
+ private int _playCount = 0;
64
+
65
+ public void TrackLaunchTime()
66
+ {
67
+ if (_isAppReady)
68
+ {
69
+ Log("TrackAppReady() being called multiple time!");
70
+ return;
71
+ }
72
+ _isAppReady = true;
73
+
74
+ var dict = new Dictionary<string, object>()
75
+ {
76
+ {"loading_time", Time.realtimeSinceStartup},
77
+ {"session", AmaGDK.User.Session},
78
+ {"device_name", SystemInfo.deviceModel},
79
+ {"device_os_version", SystemInfo.operatingSystem},
80
+
81
+ // Update
82
+ {"game_time", Time.time},
83
+ };
84
+
85
+ Utils.InjectDeviceInfo(dict);
86
+ Utils.InjectDeviceStatus(dict);
87
+
88
+ LogEvent("pm_launch_time", dict);
89
+ }
90
+
91
+ public void StartRecordFPS(string context, Dictionary<string, object> userData = null)
92
+ {
93
+ _recorder ??= new FrameRecorder(_config ?? AmaGDK.Config.fpsConfig);
94
+ if (_recorder.isRecording)
95
+ {
96
+ LogWarning("Not yet support - Start multiple recorders at the same time! Please stop the previous session first!");
97
+ return;
98
+ }
99
+
100
+ _recorder.Start(context, userData);
101
+ }
102
+
103
+ public Dictionary<string, object> StopRecordFPS(bool logEvent = true)
104
+ {
105
+ if (_recorder == null || !_recorder.isRecording)
106
+ {
107
+ LogWarning("No tracking session found!");
108
+ return null;
109
+ }
110
+
111
+ var data = _recorder.Stop();
112
+ if (logEvent) LogEvent("fps_measurement", data);
113
+ return data;
114
+ }
115
+
116
+ private void LogEvent(string eventName, Dictionary<string, object> parameters)
117
+ {
118
+ if (LogEventHook == null)
119
+ {
120
+ AmaGDK.Analytics.LogEvent(eventName, parameters);
121
+ return;
122
+ }
123
+ LogEventHook(eventName, parameters);
124
+ }
125
+ }
126
+
127
+ public partial class AmaFPS: IOnApplicationFocus, IOnApplicationPause, IOnFrameUpdate // Internal logic
128
+ {
129
+ private FrameRecorder _recorder;
130
+ private FrameRecorder _realtime;
131
+ private int _skipFrames = 0;
132
+ private FPSConfig _config;
133
+
134
+ internal AmaFPS()
135
+ {
136
+ AmaGDK.SetCallback_OnGDKInit(OnGDKInit);
137
+ AmaGDK.unityCallbacks.AddObserver(this);
138
+ }
139
+
140
+ internal AmaFPS(FPSConfig config)
141
+ {
142
+ // Constructor for unit test
143
+ _config = config;
144
+ _realtime = new FrameRecorder(config);
145
+ }
146
+
147
+ private void OnGDKInit()
148
+ {
149
+ _config = AmaGDK.Config.fpsConfig;
150
+ _realtime ??= new FrameRecorder(_config);
151
+
152
+ _realtime.bands.onFPSDrop -= OnFrameDrop;
153
+ _realtime.bands.onFPSDrop += OnFrameDrop;
154
+ }
155
+
156
+ private void OnFrameDrop()
157
+ {
158
+ if (_config.onFrameDrop.GetPersistentEventCount() > 0)
159
+ {
160
+ _config.onFrameDrop.Invoke();
161
+ }
162
+ }
163
+
164
+ public void OnFrameUpdate()
165
+ {
166
+ UpdateFrame(Time.unscaledDeltaTime);
167
+ }
168
+
169
+ internal void UpdateFrame(float unscaledDeltaTime)
170
+ {
171
+ if (unscaledDeltaTime <= 1 / 1200f) unscaledDeltaTime = 1 / 1200f; // prevent the case when unscaledDeltaTime == 0
172
+
173
+ if (_skipFrames > 0)
174
+ {
175
+ _skipFrames--;
176
+ return;
177
+ }
178
+
179
+ if (_realtime != null && _config.enableRealtimeFPS) _realtime.UpdateFrame(unscaledDeltaTime);
180
+
181
+ if (_recorder != null && _recorder.isRecording)
182
+ {
183
+ _recorder.UpdateFrame(unscaledDeltaTime);
184
+ }
185
+ }
186
+
187
+ public void OnApplicationFocus(bool hasFocus)
188
+ {
189
+ _skipFrames = _config?.skipFrameFocus ?? 0;
190
+ }
191
+
192
+ public void OnApplicationPause(bool pauseStatus)
193
+ {
194
+ _skipFrames = _config?.skipFrameFocus ?? 0;
195
+ }
196
+ }
197
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: b012260b19f6145b8afc7dcd17904085
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,246 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using UnityEngine;
4
+ using UnityEngine.Profiling;
5
+ using UnityEngine.UI;
6
+ using static Amanotes.Core.Internal.Logging;
7
+
8
+ namespace Amanotes.Core
9
+ {
10
+
11
+ [RequireComponent(typeof(RectTransform))]
12
+ [RequireComponent(typeof(CanvasRenderer))]
13
+ public class AmaFPSVisualizer : Graphic
14
+ {
15
+ [Serializable]
16
+ private class FlashOnDrop
17
+ {
18
+ public bool enabled = true;
19
+ public Color flashColor = new Color(1, 0, 0, 0.5f);
20
+ [Range(1f, 10f)] public float flashingSpeed = 10f;
21
+
22
+ public Image flashImage;
23
+ private float _alpha = 0;
24
+
25
+ public void OnFrameDrop()
26
+ {
27
+ _alpha = flashColor.a;
28
+ flashImage.color = flashColor;
29
+ }
30
+
31
+ public void Update()
32
+ {
33
+ float dAlpha = flashingSpeed * Time.deltaTime;
34
+ _alpha = Mathf.Max(0, _alpha - dAlpha);
35
+
36
+ Color c = flashColor;
37
+ c.a = _alpha;
38
+ flashImage.color = c;
39
+ }
40
+ }
41
+
42
+ [Serializable]
43
+ private class FPSTextUpdate
44
+ {
45
+ private static readonly Dictionary<int, string> intMap = new Dictionary<int, string>();
46
+ private static string GetString(float value)
47
+ {
48
+ Profiler.BeginSample("FPSTextUpdate.GetString");
49
+ int intValue = Mathf.RoundToInt(value * 10);
50
+ if (intMap.TryGetValue(intValue, out string result))
51
+ {
52
+ Profiler.EndSample();
53
+ return result;
54
+ }
55
+
56
+ result = $"{(intValue/10f):F1}";
57
+ intMap.Add(intValue, result);
58
+ Profiler.EndSample();
59
+ return result;
60
+ }
61
+
62
+ public bool enabled = true;
63
+ public GameObject parent = null;
64
+
65
+ public Text currentFPS;
66
+ private int frame;
67
+
68
+ public void Update(float fps)
69
+ {
70
+ if (frame-- > 0) return;
71
+ currentFPS.text = GetString(fps);
72
+ frame = 60;
73
+ }
74
+ }
75
+
76
+ struct FPSVertex
77
+ {
78
+ public float fps;
79
+ public int colorIndex;
80
+ public Vector3 position;
81
+ }
82
+
83
+ [Serializable]
84
+ private class FPSGraph : FrameRecorder
85
+ {
86
+ const int RESOLUTION = 64;
87
+ public bool enabled = true;
88
+ public Graphic graphic = null;
89
+
90
+ public int minFPS = 15;
91
+ public int maxFPS = 60;
92
+ public int goodFPS = 55;
93
+ public int acceptableFPS = 45;
94
+ public int badFPS = 30;
95
+
96
+ public Color[] colors = new Color[]{
97
+ Color.red, // min -> bad
98
+ new Color(1f, 0.65f, 0f), // bad -> ok
99
+ Color.yellow, // ok --> good
100
+ Color.green, // very good
101
+ };
102
+
103
+ private readonly float[] fpsHistory = new float[RESOLUTION];
104
+ private int vCount = 0;
105
+
106
+ public void Clear()
107
+ {
108
+ vCount = 0;
109
+ }
110
+
111
+ protected override void UpdateGroupFrame(){
112
+ var hIndex = vCount % RESOLUTION;
113
+ fpsHistory[hIndex] = lastFPS;
114
+ vCount++;
115
+ }
116
+
117
+ public void PopulateMesh(VertexHelper vh)
118
+ {
119
+ var rect = ((RectTransform)graphic.transform).rect;
120
+ var barW = rect.width / (RESOLUTION-1);
121
+ var barH = rect.height;
122
+
123
+ var barX = vCount < RESOLUTION ? (RESOLUTION - vCount) * barW : 0;
124
+ var stIndex = vCount <= RESOLUTION ? 0 : (vCount % RESOLUTION);
125
+ var nVertex = vCount <= RESOLUTION ? vCount : RESOLUTION;
126
+
127
+ for (var i = 0; i < nVertex; i++)
128
+ {
129
+ var idx = (i + stIndex) % RESOLUTION;
130
+ var fps = fpsHistory[idx];
131
+ var h = fps <= minFPS ? 0 :
132
+ fps >= maxFPS ? 1 : (fps - minFPS) / (maxFPS - minFPS);
133
+
134
+ var v0 = new Vector3(barX, 0, 0);
135
+ var v1 = new Vector3(barX, h * barH, 0);
136
+ var c1 = colors[
137
+ fps <= badFPS ? 0 :
138
+ fps <= acceptableFPS ? 1 :
139
+ fps <= goodFPS ? 2 : 3
140
+ ];
141
+ var c0 = c1;
142
+ c0.a = 0;
143
+
144
+ // Add 2 vertices
145
+ vh.AddVert(v0, c0, Vector2.zero);
146
+ vh.AddVert(v1, c1, Vector2.zero);
147
+
148
+ if (i > 0)
149
+ {
150
+ var vIndex = vh.currentVertCount - 2;
151
+ vh.AddTriangle(vIndex - 2, vIndex - 1, vIndex + 1);
152
+ vh.AddTriangle(vIndex - 2, vIndex + 1, vIndex);
153
+ }
154
+
155
+ barX += barW;
156
+ }
157
+
158
+ AddHorzLine(vh, rect.width, barH * ((goodFPS-minFPS) / (float)(maxFPS-minFPS)), colors[2], 2f);
159
+ AddHorzLine(vh, rect.width, barH * ((acceptableFPS-minFPS) / (float)(maxFPS-minFPS)), colors[1], 2f);
160
+ AddHorzLine(vh, rect.width, barH * ((badFPS-minFPS) / (float)(maxFPS-minFPS)), colors[0], 2f);
161
+ }
162
+
163
+ void AddHorzLine(VertexHelper vh, float w, float h, Color color, float thickness = 1f)
164
+ {
165
+ var v0 = new Vector3(0, h, 0);
166
+ var v1 = new Vector3(w, h, 0);
167
+ var v2 = new Vector3(w, h+thickness, 0);
168
+ var v3 = new Vector3(0, h+thickness, 0);
169
+
170
+ var vIndex = vh.currentVertCount;
171
+
172
+ vh.AddVert(v0, color, new Vector2(0, 0));
173
+ vh.AddVert(v1, color, new Vector2(0, 0));
174
+ vh.AddVert(v2, color, new Vector2(0, 0));
175
+ vh.AddVert(v3, color, new Vector2(0, 0));
176
+
177
+ vh.AddTriangle(vIndex, vIndex+1, vIndex+2);
178
+ vh.AddTriangle(vIndex+2, vIndex+3, vIndex);
179
+ }
180
+
181
+ public FPSGraph(FPSConfig config) : base(config)
182
+ {
183
+ }
184
+ }
185
+
186
+ [SerializeField] private FlashOnDrop flashOnDropFrame = new FlashOnDrop();
187
+ [SerializeField] private FPSTextUpdate textUpdate = new FPSTextUpdate();
188
+
189
+ private FPSGraph graph;
190
+
191
+ protected override void Awake()
192
+ {
193
+ flashOnDropFrame.flashImage.enabled = flashOnDropFrame.enabled;
194
+ textUpdate.parent.SetActive(textUpdate.enabled);
195
+
196
+ graph = new FPSGraph(AmaGDK.Config.fpsConfig)
197
+ {
198
+ graphic = GetComponent<Graphic>()
199
+ };
200
+
201
+ Application.targetFrameRate = Screen.currentResolution.refreshRate;
202
+ Log($"Target FrameRate: {Application.targetFrameRate}");
203
+ }
204
+
205
+ protected override void Start()
206
+ {
207
+ var rect = Screen.safeArea;
208
+ var trans = transform as RectTransform;
209
+ var transRect = trans.rect;
210
+ trans.anchoredPosition = new Vector2(rect.x / rect.width * transRect.width, -rect.y / rect.height * transRect.height);
211
+ }
212
+
213
+ public void OnFrameDrop()
214
+ {
215
+ flashOnDropFrame.OnFrameDrop();
216
+ }
217
+
218
+ private void Update()
219
+ {
220
+ if (!Application.isPlaying) return;
221
+ Profiler.BeginSample("AmaFPSVisualiser.Update()");
222
+ {
223
+ if (flashOnDropFrame.enabled) flashOnDropFrame.Update();
224
+ if (textUpdate.enabled) textUpdate.Update(1f/Time.unscaledDeltaTime);
225
+ if (graph != null && graph.enabled)
226
+ {
227
+ graph.UpdateFrame(Time.unscaledDeltaTime);
228
+ Profiler.BeginSample("SetVerticesDirty()");
229
+ {
230
+ SetVerticesDirty();
231
+ }
232
+ Profiler.EndSample();
233
+ }
234
+ }
235
+ Profiler.EndSample();
236
+ }
237
+
238
+ protected override void OnPopulateMesh(VertexHelper vh)
239
+ {
240
+ vh.Clear();
241
+
242
+ if (graph == null || !graph.enabled) return;
243
+ graph.PopulateMesh(vh);
244
+ }
245
+ }
246
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 397288ec883c349c3a58f123972df467
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,99 @@
1
+ using System;
2
+ using Amanotes.Core.Internal;
3
+
4
+ namespace Amanotes.Core
5
+ {
6
+ internal class BollingerBands
7
+ {
8
+ internal event Action onFPSDrop;
9
+ internal int currentDropCount { get; private set; }
10
+ internal int totalDrop { get; private set; }
11
+ internal int isoDrop { get; private set; }
12
+
13
+ private readonly float[] buffer;
14
+ private readonly float tolerance;
15
+ private int bIndex;
16
+ private float sum;
17
+
18
+ internal BollingerBands(int window = 20, float deviation = 0.1f)
19
+ { // ~10%
20
+ buffer = new float[window];
21
+ tolerance = 1f - deviation;
22
+ }
23
+
24
+ internal void Reset(float v)
25
+ {
26
+ for (var i = 0; i < buffer.Length; i++)
27
+ {
28
+ buffer[i] = v;
29
+ }
30
+
31
+ bIndex = 0;
32
+ currentDropCount = 0;
33
+ totalDrop = 0;
34
+ isoDrop = 0;
35
+ _last = v;
36
+ sum = v * buffer.Length;
37
+ }
38
+
39
+ internal float last => _last;
40
+ internal float avg => sum / buffer.Length;
41
+ internal float min => (_min == -1) ? CalculateMinMax()._min : _min;
42
+ internal float max => (_max == -1) ? CalculateMinMax()._max : _max;
43
+
44
+ internal bool Add(float v)
45
+ {
46
+ // update cached min / max
47
+ if (_min != -1 && v < _min) _min = v;
48
+ if (_max != -1 && v > _max) _max = v;
49
+
50
+ float v0 = buffer[bIndex];
51
+ buffer[bIndex] = v;
52
+ sum += v - v0;
53
+ bIndex = (bIndex + 1) % buffer.Length;
54
+ _last = v;
55
+
56
+ // clear cached min / max
57
+ if (v0 == _min) _min = -1;
58
+ if (v0 == _max) _max = -1;
59
+
60
+ float sma = sum / buffer.Length;
61
+ bool isDrop = v < sma * tolerance;
62
+
63
+ if (!isDrop)
64
+ {
65
+ currentDropCount = 0;
66
+ return false;
67
+ }
68
+
69
+ totalDrop++;
70
+ currentDropCount++;
71
+
72
+ if (currentDropCount == 1)
73
+ {
74
+ isoDrop++;
75
+ GDKUtils.SafeInvoke(onFPSDrop);
76
+ }
77
+ return true;
78
+ }
79
+
80
+ private float _min;
81
+ private float _max;
82
+ private float _last;
83
+
84
+ private BollingerBands CalculateMinMax()
85
+ {
86
+ _min = buffer[0];
87
+ _max = _min;
88
+
89
+ for (var i = 1; i < buffer.Length; i++)
90
+ {
91
+ float v = buffer[i];
92
+ if (v < _min) _min = v;
93
+ if (v > _max) _max = v;
94
+ }
95
+
96
+ return this;
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: ccdde79627b05443192937d71354ab4b
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant: