com.azerion.bluestack 3.3.0 → 3.3.1
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 +21 -3
- package/Editor/BlueStackDependenciesSource.xml +3 -3
- package/Editor/iOS/BlueStackBuildPostProcess.cs +1 -1
- package/Example/Scripts/NativeAdManager.cs +1 -1
- package/Plugins/Android/bluestack-unity-android-bridge-5.3.3.aar +0 -0
- package/Plugins/Android/bluestack-unity-android-bridge-5.3.3.aar.meta +2 -0
- package/Plugins/iOS/BSUBanner.swift +28 -59
- package/Plugins/iOS/BSUBanner.swift.wip +303 -0
- package/{Resources.meta → Plugins/iOS/BSUBanner.swift.wip.meta} +1 -2
- package/Plugins/iOS/BSUPluginUtil.swift +9 -5
- package/Runtime/API/Banner/BannerAd.cs +3 -1
- package/Runtime/API/NativeAd/NativeAdObject.cs +3 -4
- package/Runtime/Common/NativeAd/NativeUtils.cs +6 -1
- package/Runtime/Platforms/Android/AndroidJavaObjectFactory.cs +7 -0
- package/Runtime/Platforms/Android/BannerAdClient.cs +54 -23
- package/Runtime/Platforms/Android/BlueStackClient.cs +9 -3
- package/Runtime/Platforms/Android/InterstitialAdClient.cs +22 -7
- package/Runtime/Platforms/Android/RewardedVideoAdClient.cs +22 -7
- package/Runtime/Platforms/Unity/BannerAdClient.cs +1 -1
- package/Runtime/Platforms/Unity/BaseAdClient.cs +1 -1
- package/Runtime/Platforms/Unity/InterstitialAdClient.cs +1 -1
- package/Runtime/Platforms/Unity/RewardedVideoAdClient.cs +1 -1
- package/package.json +1 -1
- package/Plugins/Android/bluestack-unity-android-bridge-5.3.0.aar +0 -0
- package/Plugins/Android/bluestack-unity-android-bridge-5.3.0.aar.meta +0 -2
- /package/{Resources → Editor/Prefabs}/AdImages/banner-320x50.png +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/banner-320x50.png.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/bluestack-logo.png +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/bluestack-logo.png.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/close.png +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/close.png.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/full-banner-468x60.png +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/full-banner-468x60.png.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/large-banner-320x100.png +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/large-banner-320x100.png.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/leaderboard-728x90.png +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/leaderboard-728x90.png.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/medium-rectangle-300x250.png +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages/medium-rectangle-300x250.png.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdImages.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/Banner.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/Banner.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/DynamicBanner.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/DynamicBanner.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/FullBanner.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/FullBanner.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/LargeBanner.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/LargeBanner.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/Leaderboard.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/Leaderboard.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/MediumRectangle.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners/MediumRectangle.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Banners.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Interstitial/InterstitialLandscape.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Interstitial/InterstitialLandscape.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Interstitial/InterstitialPortrait.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Interstitial/InterstitialPortrait.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Interstitial.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Rewarded/RewardedLandscape.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Rewarded/RewardedLandscape.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Rewarded/RewardedPortrait.prefab +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Rewarded/RewardedPortrait.prefab.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs/Rewarded.meta +0 -0
- /package/{Resources → Editor/Prefabs}/AdPrefabs.meta +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.3.1] - 2025-12-10
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- BlueStack iOS Core SDK version upgraded to 5.3.1
|
|
8
|
+
- BlueStack Android Core SDK version upgraded to 5.3.3
|
|
9
|
+
- Moved ad prefabs from Resources to Editor folder to avoid loading when not needed.
|
|
10
|
+
- Android: Equativ mediation adapter upgraded to 5.2.1.0
|
|
11
|
+
- Android: Updated Unity bridge calls to execute on the UI thread to prevent crashes and improve stability.
|
|
12
|
+
- iOS: Removed linker flag -ld64 from PostProcessBuild script, previously added as a temporary fix for Xcode 15.0+ build issue.
|
|
13
|
+
- iOS: Adjusted banner position to properly respect safe area.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Replaced deprecated `FindObjectsOfType` with `FindObjectsByType` for Unity 6+ compatibility.
|
|
18
|
+
- Android: Fixed extra banner spacing when system already reserves nav bar area (non edge-to-edge).
|
|
19
|
+
- iOS: Fixed banner view constraint issue caused by height mismatch between `UIView` and `MNGContainerView`.
|
|
20
|
+
|
|
3
21
|
## [3.3.0] - 2025-10-09
|
|
4
22
|
|
|
5
23
|
### Changed
|
|
@@ -12,7 +30,7 @@
|
|
|
12
30
|
- Upgraded Texture loading process for Native ads in Unity by improving URL validation, network and texture creation error handling.
|
|
13
31
|
- Improved native ad impression validation.
|
|
14
32
|
|
|
15
|
-
###
|
|
33
|
+
### Fixed
|
|
16
34
|
|
|
17
35
|
- Fixed wrong Android `bluestack-sdk-core` dependency version
|
|
18
36
|
- Fixed an issue where the banner ad sat under the bottom navigation bar on Android by updating `BannerAdUtils.getSafeInsets` to use `WindowInsetsCompat` `systemBars`, ensuring banners clear the navigation bar.
|
|
@@ -42,14 +60,14 @@
|
|
|
42
60
|
- Updated the iOS Post Processor to include AdMob App IDs based on the inclusion of AdMob mediation adapters.
|
|
43
61
|
- onIOSMediationNetworksUpdateEvent will trigger after changes to Settings serializedObject properties are applied.
|
|
44
62
|
|
|
45
|
-
###
|
|
63
|
+
### Fixed
|
|
46
64
|
|
|
47
65
|
- Fixed the subspec inclusion process in the Podfile to ensure the full subspec string is removed when no adapters are selected and the subspec array is empty.
|
|
48
66
|
- Fixed a Null Reference issue by updating the Destroy and distractor methods for Native Ads.
|
|
49
67
|
|
|
50
68
|
## [3.1.9] - 2024-11-07
|
|
51
69
|
|
|
52
|
-
###
|
|
70
|
+
### Fixed
|
|
53
71
|
|
|
54
72
|
- Removed unused namespaces and fixed assembly reference missing issue.
|
|
55
73
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<dependencies version="3.3.
|
|
1
|
+
<dependencies version="3.3.1">
|
|
2
2
|
<androidPackages>
|
|
3
3
|
<androidPackage alias="BlueStack" spec="com.azerion:bluestack-sdk-core:5.3.0">
|
|
4
4
|
<repositories>
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
<repository>https://packagecloud.io/smartadserver/android/maven2</repository>
|
|
13
13
|
</repositories>
|
|
14
14
|
</androidPackage>
|
|
15
|
-
<androidPackage alias="Equativ" spec="com.azerion:bluestack-mediation-equativ:5.1.
|
|
15
|
+
<androidPackage alias="Equativ" spec="com.azerion:bluestack-mediation-equativ:5.2.1.0">
|
|
16
16
|
<repositories>
|
|
17
17
|
<repository>https://packagecloud.io/smartadserver/android/maven2</repository>
|
|
18
18
|
</repositories>
|
|
19
19
|
</androidPackage>
|
|
20
20
|
</androidPackages>
|
|
21
21
|
<iosPods>
|
|
22
|
-
<iosPod alias="BlueStack" name="BlueStack-SDK" version="5.3.
|
|
22
|
+
<iosPod alias="BlueStack" name="BlueStack-SDK" version="5.3.1" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
23
23
|
<iosPod alias="Google Mobile Ads" name="BlueStackGoogleAdapter" version="5.3.0.0" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
24
24
|
<iosPod alias="Equativ" name="BlueStackEquativAdapter" version="5.1.4.1" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
25
25
|
</iosPods>
|
|
@@ -54,7 +54,7 @@ namespace Azerion.BlueStack.Editor.iOS
|
|
|
54
54
|
AddSKAdNetworkIdentifier(pathToBuildProject);
|
|
55
55
|
AddAppTransportSecurity(pathToBuildProject);
|
|
56
56
|
project.AddBuildProperty(unityFrameworkGuid, "ENABLE_BITCODE", "NO");
|
|
57
|
-
project.AddBuildProperty(unityFrameworkGuid, "OTHER_LDFLAGS", "-ld64");
|
|
57
|
+
// project.AddBuildProperty(unityFrameworkGuid, "OTHER_LDFLAGS", "-ld64");
|
|
58
58
|
|
|
59
59
|
// Modulemap
|
|
60
60
|
project.AddBuildProperty(unityFrameworkGuid, "DEFINES_MODULE", "YES");
|
|
@@ -98,7 +98,7 @@ namespace Azerion.BlueStack.Example
|
|
|
98
98
|
if (iconTexture != null)
|
|
99
99
|
{
|
|
100
100
|
Debug.Log("NativeAdManager: Register Icon Texture");
|
|
101
|
-
appIcon.GetComponent<
|
|
101
|
+
appIcon.GetComponent<MeshRenderer>().material.mainTexture = iconTexture;
|
|
102
102
|
if (!this.nativeAd.RegisterIconImageGameObject(appIcon))
|
|
103
103
|
{
|
|
104
104
|
Debug.Log("RegisterIconImageGameObject Unsuccessful");
|
|
Binary file
|
|
@@ -49,7 +49,7 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
49
49
|
if Thread.isMainThread {
|
|
50
50
|
initializeBannerFactory()
|
|
51
51
|
} else {
|
|
52
|
-
DispatchQueue.main.
|
|
52
|
+
DispatchQueue.main.async {
|
|
53
53
|
initializeBannerFactory()
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -60,7 +60,7 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
60
60
|
if Thread.isMainThread {
|
|
61
61
|
self.loadBannerAd(requestOptions: nil)
|
|
62
62
|
} else {
|
|
63
|
-
DispatchQueue.main.
|
|
63
|
+
DispatchQueue.main.async { [weak self] in
|
|
64
64
|
self?.loadBannerAd(requestOptions: nil)
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -73,7 +73,7 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
73
73
|
if Thread.isMainThread {
|
|
74
74
|
self.loadBannerAd(requestOptions: sdkOptions)
|
|
75
75
|
} else {
|
|
76
|
-
DispatchQueue.main.
|
|
76
|
+
DispatchQueue.main.async { [weak self] in
|
|
77
77
|
self?.loadBannerAd(requestOptions: sdkOptions)
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -83,7 +83,7 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
83
83
|
if Thread.isMainThread {
|
|
84
84
|
showBannerAd()
|
|
85
85
|
} else {
|
|
86
|
-
DispatchQueue.main.
|
|
86
|
+
DispatchQueue.main.async { [weak self] in
|
|
87
87
|
self?.showBannerAd()
|
|
88
88
|
}
|
|
89
89
|
}
|
|
@@ -93,7 +93,7 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
93
93
|
if Thread.isMainThread {
|
|
94
94
|
hideBannerAd()
|
|
95
95
|
} else {
|
|
96
|
-
DispatchQueue.main.
|
|
96
|
+
DispatchQueue.main.async { [weak self] in
|
|
97
97
|
self?.hideBannerAd()
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -134,9 +134,12 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
// Set up new banner container
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
let bannerWidth: Int = (bannerAdSize!.width == -1)
|
|
138
|
+
? Int(UIScreen.main.bounds.width) // FULL WIDTH for dynamicBanner
|
|
139
|
+
: bannerAdSize!.width
|
|
140
|
+
|
|
141
|
+
self.adFrame = CGRect(x: 0, y: 0, width: bannerWidth, height: self.bannerAdSize!.height)
|
|
142
|
+
|
|
140
143
|
self.bannerContainerView = UIView(frame: self.adFrame)
|
|
141
144
|
self.bannerContainerView?.clipsToBounds = true
|
|
142
145
|
|
|
@@ -186,7 +189,7 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
186
189
|
self.bannerView?.removeFromSuperview()
|
|
187
190
|
self.bannerView = nil
|
|
188
191
|
} else {
|
|
189
|
-
DispatchQueue.main.
|
|
192
|
+
DispatchQueue.main.async { [weak self] in
|
|
190
193
|
guard let strongSelf = self else { return }
|
|
191
194
|
strongSelf.bannerView?.removeFromSuperview()
|
|
192
195
|
strongSelf.bannerView = nil
|
|
@@ -201,7 +204,7 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
201
204
|
self.bannerContainerView?.removeFromSuperview()
|
|
202
205
|
self.bannerContainerView = nil
|
|
203
206
|
} else {
|
|
204
|
-
DispatchQueue.main.
|
|
207
|
+
DispatchQueue.main.async { [weak self] in
|
|
205
208
|
guard let strongSelf = self else { return }
|
|
206
209
|
strongSelf.bannerContainerView?.removeFromSuperview()
|
|
207
210
|
strongSelf.bannerContainerView = nil
|
|
@@ -210,38 +213,20 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
private func setupBannerContainerViewConstraints(with view: UIView, width: CGFloat, height: CGFloat) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
constant: width))
|
|
228
|
-
|
|
229
|
-
view.addConstraint(NSLayoutConstraint(item: self.bannerContainerView!,
|
|
230
|
-
attribute: .height,
|
|
231
|
-
relatedBy: .equal,
|
|
232
|
-
toItem: nil,
|
|
233
|
-
attribute: .notAnAttribute,
|
|
234
|
-
multiplier: 1,
|
|
235
|
-
constant: height))
|
|
236
|
-
|
|
237
|
-
let verticalAttribute: NSLayoutConstraint.Attribute = (self.adPosition == .init(rawValue: 0)!) ? .top : .bottom
|
|
238
|
-
view.addConstraint(NSLayoutConstraint(item: self.bannerContainerView!,
|
|
239
|
-
attribute: verticalAttribute,
|
|
240
|
-
relatedBy: .equal,
|
|
241
|
-
toItem: view,
|
|
242
|
-
attribute: verticalAttribute,
|
|
243
|
-
multiplier: 1,
|
|
244
|
-
constant: 0))
|
|
216
|
+
guard let container = bannerContainerView else { return }
|
|
217
|
+
container.translatesAutoresizingMaskIntoConstraints = false
|
|
218
|
+
|
|
219
|
+
let guide = view.safeAreaLayoutGuide // Use safe area anchors for top/bottom
|
|
220
|
+
var isTopPosition: Bool { adPosition.rawValue == 0 } // 0 == top
|
|
221
|
+
|
|
222
|
+
NSLayoutConstraint.activate([
|
|
223
|
+
container.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
|
224
|
+
container.widthAnchor.constraint(equalToConstant: width),
|
|
225
|
+
container.heightAnchor.constraint(equalToConstant: height),
|
|
226
|
+
isTopPosition
|
|
227
|
+
? container.topAnchor.constraint(equalTo: guide.topAnchor) // guide.topAnchor for safe area
|
|
228
|
+
: container.bottomAnchor.constraint(equalTo: guide.bottomAnchor) // view.bottomAnchor to ignore safe area and just bottom or top align
|
|
229
|
+
])
|
|
245
230
|
}
|
|
246
231
|
|
|
247
232
|
private func setupBannerViewConstraints(with view: UIView) {
|
|
@@ -261,22 +246,6 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
261
246
|
attribute: .centerY,
|
|
262
247
|
multiplier: 1,
|
|
263
248
|
constant: 0))
|
|
264
|
-
|
|
265
|
-
view.addConstraint(NSLayoutConstraint(item: bannerView,
|
|
266
|
-
attribute: .width,
|
|
267
|
-
relatedBy: .equal,
|
|
268
|
-
toItem: view,
|
|
269
|
-
attribute: .width,
|
|
270
|
-
multiplier: 1,
|
|
271
|
-
constant: 0))
|
|
272
|
-
|
|
273
|
-
view.addConstraint(NSLayoutConstraint(item: bannerView,
|
|
274
|
-
attribute: .height,
|
|
275
|
-
relatedBy: .equal,
|
|
276
|
-
toItem: view,
|
|
277
|
-
attribute: .height,
|
|
278
|
-
multiplier: 1,
|
|
279
|
-
constant: 0))
|
|
280
249
|
}
|
|
281
250
|
|
|
282
251
|
func getBannerAdSize(from string: String?) -> BSUAdSize? {
|
|
@@ -326,7 +295,7 @@ public class BSUBanner: NSObject, BannerViewDelegate {
|
|
|
326
295
|
}
|
|
327
296
|
|
|
328
297
|
public func onRefresh(_ bannerView: BlueStackSDK.BannerView) {
|
|
329
|
-
|
|
298
|
+
// print("Banner Ad refreshed")
|
|
330
299
|
self.onBannerDidRefreshCallback?(self.bannerClient)
|
|
331
300
|
}
|
|
332
301
|
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BSUBanner.swift
|
|
3
|
+
// UnityFramework
|
|
4
|
+
//
|
|
5
|
+
// Created by Moin Hasan on 5/23/25.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import BlueStackSDK
|
|
10
|
+
import UIKit
|
|
11
|
+
|
|
12
|
+
@MainActor
|
|
13
|
+
@objc(BSUBanner)
|
|
14
|
+
public class BSUBanner: NSObject {
|
|
15
|
+
@objc public var bannerClient: BSUTypeBannerClientRefPointer?
|
|
16
|
+
@objc public var onBannerDidLoadCallback: BSUOnBannerDidLoadCallback?
|
|
17
|
+
@objc public var onBannerDidFailedCallback: BSUOnBannerDidFailedCallback?
|
|
18
|
+
@objc public var onAdClickedCallback: BSUOnAdClickedCallback?
|
|
19
|
+
@objc public var onBannerDidRefreshCallback: BSUOnBannerDidRefreshCallback?
|
|
20
|
+
@objc public var onBannerDidFailToRefreshCallback: BSUOnBannerDidFailToRefreshCallback?
|
|
21
|
+
@objc public var onBannerHideCallback: BSUOnBannerHideCallback?
|
|
22
|
+
@objc public var onBannerDisplayCallback: BSUOnBannerDisplayCallback?
|
|
23
|
+
|
|
24
|
+
private var adPosition: BSUAdPosition = .init(rawValue: 0)!
|
|
25
|
+
private var adFrame: CGRect = .zero
|
|
26
|
+
private var bannerAdSize: BSUAdSize?
|
|
27
|
+
private var bannerAdsFactory: BannerView?
|
|
28
|
+
private var bannerView: UIView?
|
|
29
|
+
private var bannerContainerView: UIView?
|
|
30
|
+
private var placementId: String?
|
|
31
|
+
|
|
32
|
+
@objc public init(bannerClientReference: BSUTypeBannerClientRefPointer?, placementId: String, adPosition: BSUAdPosition) {
|
|
33
|
+
self.bannerClient = bannerClientReference
|
|
34
|
+
self.adPosition = adPosition
|
|
35
|
+
self.placementId = placementId
|
|
36
|
+
super.init()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private func createBannerAd(_ adSize: String) {
|
|
40
|
+
destroy()
|
|
41
|
+
bannerAdSize = getBannerAdSize(from: adSize)
|
|
42
|
+
bannerAdsFactory = BannerView(adSize: bannerAdSize!.size)
|
|
43
|
+
bannerAdsFactory?.placementID = placementId
|
|
44
|
+
bannerAdsFactory?.delegate = self
|
|
45
|
+
bannerAdsFactory?.viewController = BSUPluginUtil.unityGLViewController()
|
|
46
|
+
// bannerAdsFactory?.startAutoRefresh()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@objc public func loadAd(withAdSize size: String) {
|
|
50
|
+
createBannerAd(size)
|
|
51
|
+
loadBannerAd(requestOptions: nil)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@objc public func loadAd(withAdSize size: String, requestOptions requestOptionsRef: BSUTypeRequestOptionsRef) {
|
|
55
|
+
createBannerAd(size)
|
|
56
|
+
let bsuOptions = Unmanaged<BSURequestOptions>.fromOpaque(requestOptionsRef).takeUnretainedValue()
|
|
57
|
+
let sdkOptions = bsuOptions.toSDKRequestOptions()
|
|
58
|
+
loadBannerAd(requestOptions: sdkOptions)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@objc public func show() {
|
|
62
|
+
showBannerAd()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@objc public func hide() {
|
|
66
|
+
hideBannerAd()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@objc public func setPosition(_ adPosition: BSUAdPosition) {
|
|
70
|
+
guard self.adPosition != adPosition else { return }
|
|
71
|
+
self.adPosition = adPosition
|
|
72
|
+
guard let bannerContainerView = self.bannerContainerView else { return }
|
|
73
|
+
bannerContainerView.removeFromSuperview()
|
|
74
|
+
|
|
75
|
+
guard let unityView = BSUPluginUtil.unityGLViewController()?.view else { return }
|
|
76
|
+
|
|
77
|
+
unityView.addSubview(bannerContainerView)
|
|
78
|
+
bannerContainerView.translatesAutoresizingMaskIntoConstraints = false
|
|
79
|
+
self.setupBannerContainerViewConstraints(with: unityView,
|
|
80
|
+
width: self.adFrame.size.width,
|
|
81
|
+
height: self.adFrame.size.height)
|
|
82
|
+
unityView.layoutIfNeeded()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@objc public func destroy() {
|
|
86
|
+
self.removeBannerView()
|
|
87
|
+
self.removeBannerContainerView()
|
|
88
|
+
self.bannerAdsFactory?.delegate = nil
|
|
89
|
+
self.bannerAdsFactory = nil
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// MARK: - Private Methods
|
|
93
|
+
|
|
94
|
+
private func loadBannerAd(requestOptions: RequestOptions?) {
|
|
95
|
+
guard let bannerAdsFactory = self.bannerAdsFactory else { return }
|
|
96
|
+
|
|
97
|
+
// Remove existing banner views if they exist
|
|
98
|
+
if self.bannerContainerView != nil {
|
|
99
|
+
self.removeBannerView()
|
|
100
|
+
self.removeBannerContainerView()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Set up new banner container
|
|
104
|
+
self.adFrame = CGRect(x: 0, y: 0,
|
|
105
|
+
width: self.bannerAdSize!.width,
|
|
106
|
+
height: self.bannerAdSize!.height)
|
|
107
|
+
self.bannerContainerView = UIView(frame: self.adFrame)
|
|
108
|
+
self.bannerContainerView?.clipsToBounds = true
|
|
109
|
+
|
|
110
|
+
guard let unityView = BSUPluginUtil.unityGLViewController()?.view else {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Add to Unity's view hierarchy
|
|
115
|
+
unityView.addSubview(self.bannerContainerView!)
|
|
116
|
+
self.bannerContainerView?.isHidden = true
|
|
117
|
+
self.bannerContainerView?.translatesAutoresizingMaskIntoConstraints = false
|
|
118
|
+
|
|
119
|
+
// Set constraints
|
|
120
|
+
self.setupBannerContainerViewConstraints(with: unityView,
|
|
121
|
+
width: self.adFrame.size.width,
|
|
122
|
+
height: self.adFrame.size.height)
|
|
123
|
+
unityView.layoutIfNeeded()
|
|
124
|
+
|
|
125
|
+
print("BSUBanner: loadBannerAd!!")
|
|
126
|
+
|
|
127
|
+
// Load the ad
|
|
128
|
+
if requestOptions == nil {
|
|
129
|
+
bannerAdsFactory.load()
|
|
130
|
+
} else {
|
|
131
|
+
bannerAdsFactory.load(requestOptions: requestOptions)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private func hideBannerAd() {
|
|
136
|
+
guard let bannerContainerView = self.bannerContainerView else { return }
|
|
137
|
+
bannerContainerView.isHidden = true
|
|
138
|
+
// self.bannerAdsFactory?.stopAutoRefresh()
|
|
139
|
+
self.onBannerHideCallback?(self.bannerClient)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private func showBannerAd() {
|
|
143
|
+
guard let bannerContainerView = self.bannerContainerView else { return }
|
|
144
|
+
bannerContainerView.isHidden = false
|
|
145
|
+
// self.bannerAdsFactory?.startAutoRefresh()
|
|
146
|
+
self.onBannerDisplayCallback?(self.bannerClient)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private func removeBannerView() {
|
|
150
|
+
guard bannerView != nil else { return }
|
|
151
|
+
bannerView?.removeFromSuperview()
|
|
152
|
+
bannerView = nil
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private func removeBannerContainerView() {
|
|
156
|
+
guard bannerContainerView != nil else { return }
|
|
157
|
+
bannerContainerView?.removeFromSuperview()
|
|
158
|
+
bannerContainerView = nil
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private func setupBannerContainerViewConstraints(with view: UIView, width: CGFloat, height: CGFloat) {
|
|
162
|
+
guard let container = bannerContainerView else { return }
|
|
163
|
+
container.translatesAutoresizingMaskIntoConstraints = false
|
|
164
|
+
|
|
165
|
+
// let guide = view.safeAreaLayoutGuide // Use safe area anchors for top/bottom
|
|
166
|
+
var isTopPosition: Bool { adPosition.rawValue == 0 } // 0 == top
|
|
167
|
+
|
|
168
|
+
NSLayoutConstraint.activate([
|
|
169
|
+
container.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
|
170
|
+
container.widthAnchor.constraint(equalToConstant: width),
|
|
171
|
+
container.heightAnchor.constraint(equalToConstant: height),
|
|
172
|
+
isTopPosition
|
|
173
|
+
? container.topAnchor.constraint(equalTo: view.topAnchor) // guide.topAnchor for safe area
|
|
174
|
+
: container.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
|
175
|
+
])
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// private func setupBannerContainerViewConstraints(with view: UIView, width: CGFloat, height: CGFloat) {
|
|
179
|
+
// view.addConstraint(NSLayoutConstraint(item: self.bannerContainerView!,
|
|
180
|
+
// attribute: .centerX,
|
|
181
|
+
// relatedBy: .equal,
|
|
182
|
+
// toItem: view,
|
|
183
|
+
// attribute: .centerX,
|
|
184
|
+
// multiplier: 1,
|
|
185
|
+
// constant: 0))
|
|
186
|
+
//
|
|
187
|
+
// view.addConstraint(NSLayoutConstraint(item: self.bannerContainerView!,
|
|
188
|
+
// attribute: .width,
|
|
189
|
+
// relatedBy: .equal,
|
|
190
|
+
// toItem: nil,
|
|
191
|
+
// attribute: .notAnAttribute,
|
|
192
|
+
// multiplier: 1,
|
|
193
|
+
// constant: width))
|
|
194
|
+
//
|
|
195
|
+
// view.addConstraint(NSLayoutConstraint(item: self.bannerContainerView!,
|
|
196
|
+
// attribute: .height,
|
|
197
|
+
// relatedBy: .equal,
|
|
198
|
+
// toItem: nil,
|
|
199
|
+
// attribute: .notAnAttribute,
|
|
200
|
+
// multiplier: 1,
|
|
201
|
+
// constant: height))
|
|
202
|
+
//
|
|
203
|
+
// let verticalAttribute: NSLayoutConstraint.Attribute = (self.adPosition == .init(rawValue: 0)!) ? .top : .bottom
|
|
204
|
+
// view.addConstraint(NSLayoutConstraint(item: self.bannerContainerView!,
|
|
205
|
+
// attribute: verticalAttribute,
|
|
206
|
+
// relatedBy: .equal,
|
|
207
|
+
// toItem: view,
|
|
208
|
+
// attribute: verticalAttribute,
|
|
209
|
+
// multiplier: 1,
|
|
210
|
+
// constant: 0))
|
|
211
|
+
// }
|
|
212
|
+
|
|
213
|
+
private func setupBannerViewConstraints(with view: UIView) {
|
|
214
|
+
guard let bannerView = self.bannerView else { return }
|
|
215
|
+
view.addConstraint(NSLayoutConstraint(item: bannerView,
|
|
216
|
+
attribute: .centerX,
|
|
217
|
+
relatedBy: .equal,
|
|
218
|
+
toItem: view,
|
|
219
|
+
attribute: .centerX,
|
|
220
|
+
multiplier: 1,
|
|
221
|
+
constant: 0))
|
|
222
|
+
|
|
223
|
+
view.addConstraint(NSLayoutConstraint(item: bannerView,
|
|
224
|
+
attribute: .centerY,
|
|
225
|
+
relatedBy: .equal,
|
|
226
|
+
toItem: view,
|
|
227
|
+
attribute: .centerY,
|
|
228
|
+
multiplier: 1,
|
|
229
|
+
constant: 0))
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
func getBannerAdSize(from string: String?) -> BSUAdSize? {
|
|
233
|
+
switch string {
|
|
234
|
+
case "BANNER":
|
|
235
|
+
return .banner
|
|
236
|
+
case "LARGE_BANNER":
|
|
237
|
+
return .largeBanner
|
|
238
|
+
case "FULL_BANNER":
|
|
239
|
+
return .fullBanner
|
|
240
|
+
case "MEDIUM_RECTANGLE":
|
|
241
|
+
return .mediumRectangle
|
|
242
|
+
case "LEADERBOARD":
|
|
243
|
+
return .leaderboard
|
|
244
|
+
case "DYNAMIC_BANNER":
|
|
245
|
+
return .dynamicBanner
|
|
246
|
+
case "DYNAMIC_LEADERBOARD":
|
|
247
|
+
return .dynamicLeaderboard
|
|
248
|
+
default:
|
|
249
|
+
return .banner
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// MARK: - BannerViewDelegate
|
|
255
|
+
|
|
256
|
+
extension BSUBanner: @MainActor BannerViewDelegate {
|
|
257
|
+
public func onLoad(_ bannerView: BlueStackSDK.BannerView, _ preferredHeight: CGFloat) {
|
|
258
|
+
// print("Banner successfully loaded with preferredHeight: \(preferredHeight)")
|
|
259
|
+
self.removeBannerView()
|
|
260
|
+
self.bannerView = bannerView
|
|
261
|
+
self.bannerContainerView?.addSubview(bannerView)
|
|
262
|
+
self.bannerView?.translatesAutoresizingMaskIntoConstraints = false
|
|
263
|
+
if let containerView = self.bannerContainerView {
|
|
264
|
+
self.setupBannerViewConstraints(with: containerView)
|
|
265
|
+
containerView.layoutIfNeeded()
|
|
266
|
+
}
|
|
267
|
+
self.onBannerDidLoadCallback?(self.bannerClient)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
public func onFailedToLoad(_ bannerView: BlueStackSDK.BannerView, _ error: any Error) {
|
|
271
|
+
// print("Banner Ad failed to load with error: \(error.localizedDescription)")
|
|
272
|
+
if let nsError = error as NSError? {
|
|
273
|
+
let errorPointer = Unmanaged.passUnretained(nsError).toOpaque()
|
|
274
|
+
self.onBannerDidFailedCallback?(self.bannerClient, errorPointer)
|
|
275
|
+
} else {
|
|
276
|
+
self.onBannerDidFailedCallback?(self.bannerClient, nil)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
public func onRefresh(_ bannerView: BlueStackSDK.BannerView) {
|
|
281
|
+
// print("Banner Ad refreshed")
|
|
282
|
+
self.onBannerDidRefreshCallback?(self.bannerClient)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
public func onFailedToRefresh(_ bannerView: BlueStackSDK.BannerView, _ error: any Error) {
|
|
286
|
+
print("Banner Ad failed to refresh with error: \(error.localizedDescription)")
|
|
287
|
+
if let nsError = error as NSError? {
|
|
288
|
+
let errorPointer = Unmanaged.passUnretained(nsError).toOpaque()
|
|
289
|
+
self.onBannerDidFailToRefreshCallback?(self.bannerClient, errorPointer)
|
|
290
|
+
} else {
|
|
291
|
+
self.onBannerDidFailToRefreshCallback?(self.bannerClient, nil)
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
public func onClick(_ bannerView: BlueStackSDK.BannerView) {
|
|
296
|
+
// print("Banner Ad clicked")
|
|
297
|
+
self.onAdClickedCallback?(self.bannerClient)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
public func onResize(_ bannerView: BlueStackSDK.BannerView, _ size: CGSize) {
|
|
301
|
+
print("Banner Ad resized to size: \(size)")
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -12,12 +12,16 @@ import BlueStackSDK
|
|
|
12
12
|
public class BSUPluginUtil: NSObject {
|
|
13
13
|
/// Returns the Unity view controller.
|
|
14
14
|
@objc public static func unityGLViewController() -> UIViewController? {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
// If already on main thread, access directly
|
|
16
|
+
if Thread.isMainThread {
|
|
17
|
+
return UIApplication.shared.delegate?.window??.rootViewController
|
|
18
|
+
} else {
|
|
19
|
+
// Otherwise, run synchronously on main thread
|
|
20
|
+
var rootVC: UIViewController?
|
|
21
|
+
DispatchQueue.main.sync {
|
|
22
|
+
rootVC = UIApplication.shared.delegate?.window??.rootViewController
|
|
23
|
+
}
|
|
19
24
|
return rootVC
|
|
20
25
|
}
|
|
21
|
-
return nil
|
|
22
26
|
}
|
|
23
27
|
}
|
|
@@ -21,7 +21,9 @@ namespace Azerion.BlueStack.API.Banner
|
|
|
21
21
|
|
|
22
22
|
public event EventHandler<EventArgs> OnBannerDisplay;
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
// TODO: Refactor the BannerAdClient lifecycle (creation, destruction, disposal) across across all platforms
|
|
25
|
+
// to improve and ensure consistent behavior.
|
|
26
|
+
|
|
25
27
|
public BannerAd(string placementId, AdPosition adPosition) : this(placementId, adPosition,
|
|
26
28
|
BlueStackAds.GetClientsFactory().CreatBannerAdClient())
|
|
27
29
|
{
|
|
@@ -294,13 +294,12 @@ namespace Azerion.BlueStack.API
|
|
|
294
294
|
|
|
295
295
|
_frameLastUpdated = currentFrame;
|
|
296
296
|
CachedRaycasters.Clear();
|
|
297
|
-
|
|
298
297
|
#if UNITY_6000_0_OR_NEWER
|
|
299
|
-
|
|
298
|
+
GraphicRaycaster[] raycasters = FindObjectsByType<GraphicRaycaster>(FindObjectsSortMode.None);
|
|
300
299
|
#else
|
|
301
|
-
|
|
300
|
+
GraphicRaycaster[] raycasters = FindObjectsOfType<GraphicRaycaster>();
|
|
302
301
|
#endif
|
|
303
|
-
foreach (
|
|
302
|
+
foreach (GraphicRaycaster r in raycasters)
|
|
304
303
|
{
|
|
305
304
|
if (r != null && r.isActiveAndEnabled)
|
|
306
305
|
CachedRaycasters.Add(r);
|
|
@@ -29,7 +29,12 @@ namespace Azerion.BlueStack.Common
|
|
|
29
29
|
public static Canvas GetTopCanvas()
|
|
30
30
|
{
|
|
31
31
|
// Find all Canvas components in the scene
|
|
32
|
-
|
|
32
|
+
#if UNITY_6000_0_OR_NEWER
|
|
33
|
+
Canvas[] allCanvases = UnityEngine.Object.FindObjectsByType<Canvas>(FindObjectsSortMode.None);
|
|
34
|
+
#else
|
|
35
|
+
Canvas[] allCanvases = UnityEngine.Object.FindObjectsOfType<Canvas>();
|
|
36
|
+
#endif
|
|
37
|
+
|
|
33
38
|
Canvas topCanvas = null;
|
|
34
39
|
int highestSortingOrder = int.MinValue;
|
|
35
40
|
|
|
@@ -7,6 +7,13 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
7
7
|
{
|
|
8
8
|
public static AndroidJavaObjectFactory Instance { get; } = new AndroidJavaObjectFactory();
|
|
9
9
|
|
|
10
|
+
public void RunOnUiThread(System.Action action)
|
|
11
|
+
{
|
|
12
|
+
AndroidJavaClass playerClass = new AndroidJavaClass(BlueStackNativeClassNames.UnityActivityClassName);
|
|
13
|
+
AndroidJavaObject activity = playerClass.GetStatic<AndroidJavaObject>("currentActivity");
|
|
14
|
+
activity.Call("runOnUiThread", new AndroidJavaRunnable(action));
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
public virtual AndroidJavaObject CreateUnityRewardedAdAndroidJavaObject(object unityRewardedAdListener)
|
|
11
18
|
{
|
|
12
19
|
AndroidJavaClass playerClass = new AndroidJavaClass(BlueStackNativeClassNames.UnityActivityClassName);
|
|
@@ -20,8 +20,11 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
20
20
|
private AndroidJavaObject _unityBannerAd;
|
|
21
21
|
private readonly BlueStackErrorUtils _blueStackErrorUtils;
|
|
22
22
|
|
|
23
|
-
public BannerAdClient(
|
|
24
|
-
|
|
23
|
+
public BannerAdClient(
|
|
24
|
+
AndroidJavaObjectFactory androidJavaObjectFactory,
|
|
25
|
+
BlueStackErrorUtils blueStackErrorUtils
|
|
26
|
+
)
|
|
27
|
+
: base(BlueStackNativeClassNames.UnityBannerAdListenerClassName)
|
|
25
28
|
{
|
|
26
29
|
_unityBannerAd = androidJavaObjectFactory.CreateUnityBannerAdAndroidJavaObject(this);
|
|
27
30
|
_blueStackErrorUtils = blueStackErrorUtils;
|
|
@@ -29,49 +32,73 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
29
32
|
|
|
30
33
|
public void CreateBannerAd(string placementId, AdPosition adPosition)
|
|
31
34
|
{
|
|
32
|
-
|
|
35
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
36
|
+
{
|
|
37
|
+
_unityBannerAd.Call("createBannerAd", placementId, (int)adPosition);
|
|
38
|
+
});
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
public void Load(AdSize adSize)
|
|
36
42
|
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
44
|
+
{
|
|
45
|
+
_unityBannerAd.Call("setSize", adSize.Size, adSize.Height, adSize.Width);
|
|
46
|
+
PreferenceClient preferenceClient = new PreferenceClient();
|
|
47
|
+
_unityBannerAd.Call("load", preferenceClient.getRequestOptions());
|
|
48
|
+
});
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
public void Load(AdSize adSize, IPreferenceClient iPreferenceClient)
|
|
44
52
|
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
54
|
+
{
|
|
55
|
+
_unityBannerAd.Call("setSize", adSize.Size, adSize.Height, adSize.Width);
|
|
56
|
+
PreferenceClient preferenceClient = (PreferenceClient)iPreferenceClient;
|
|
57
|
+
_unityBannerAd.Call("load", preferenceClient.getRequestOptions());
|
|
58
|
+
});
|
|
49
59
|
}
|
|
50
60
|
|
|
51
61
|
public void Show()
|
|
52
62
|
{
|
|
53
|
-
|
|
63
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
64
|
+
{
|
|
65
|
+
_unityBannerAd.Call("show");
|
|
66
|
+
});
|
|
54
67
|
}
|
|
55
68
|
|
|
56
69
|
public void Hide()
|
|
57
70
|
{
|
|
58
|
-
|
|
71
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
72
|
+
{
|
|
73
|
+
_unityBannerAd.Call("hide");
|
|
74
|
+
});
|
|
59
75
|
}
|
|
60
|
-
|
|
76
|
+
|
|
61
77
|
public void Destroy()
|
|
62
78
|
{
|
|
63
|
-
|
|
64
|
-
|
|
79
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
80
|
+
{
|
|
81
|
+
_unityBannerAd.Call("destroy");
|
|
82
|
+
_unityBannerAd.Dispose();
|
|
83
|
+
});
|
|
65
84
|
}
|
|
66
85
|
|
|
86
|
+
//TODO: Fix top adPosition
|
|
67
87
|
public void SetPosition(AdPosition adPosition)
|
|
68
88
|
{
|
|
69
|
-
|
|
89
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
90
|
+
{
|
|
91
|
+
_unityBannerAd.Call("setPosition", (int)adPosition);
|
|
92
|
+
});
|
|
70
93
|
}
|
|
71
94
|
|
|
72
95
|
private AndroidJavaObject mngAdSize(AdSize adSize)
|
|
73
96
|
{
|
|
74
|
-
var mngFrame = new AndroidJavaObject(
|
|
97
|
+
var mngFrame = new AndroidJavaObject(
|
|
98
|
+
BlueStackNativeClassNames.MNGFrameClass,
|
|
99
|
+
adSize.Width,
|
|
100
|
+
adSize.Height
|
|
101
|
+
);
|
|
75
102
|
return mngFrame;
|
|
76
103
|
}
|
|
77
104
|
|
|
@@ -82,8 +109,10 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
82
109
|
|
|
83
110
|
public void onBannerDidFailed(AndroidJavaObject adsErrorJavaObject)
|
|
84
111
|
{
|
|
85
|
-
OnBannerDidFailed?.Invoke(
|
|
86
|
-
|
|
112
|
+
OnBannerDidFailed?.Invoke(
|
|
113
|
+
this,
|
|
114
|
+
_blueStackErrorUtils.CreateBlueStackErrorFromJavaObject(adsErrorJavaObject)
|
|
115
|
+
);
|
|
87
116
|
}
|
|
88
117
|
|
|
89
118
|
public void onAdClicked()
|
|
@@ -98,8 +127,10 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
98
127
|
|
|
99
128
|
public void onBannerDidFailToRefresh(AndroidJavaObject adsErrorJavaObject)
|
|
100
129
|
{
|
|
101
|
-
OnBannerDidFailToRefresh?.Invoke(
|
|
102
|
-
|
|
130
|
+
OnBannerDidFailToRefresh?.Invoke(
|
|
131
|
+
this,
|
|
132
|
+
_blueStackErrorUtils.CreateBlueStackErrorFromJavaObject(adsErrorJavaObject)
|
|
133
|
+
);
|
|
103
134
|
}
|
|
104
135
|
|
|
105
136
|
public void onBannerHide()
|
|
@@ -113,4 +144,4 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
113
144
|
}
|
|
114
145
|
}
|
|
115
146
|
}
|
|
116
|
-
#endif
|
|
147
|
+
#endif
|
|
@@ -175,7 +175,10 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
175
175
|
// Set pref as cross platform client
|
|
176
176
|
var crossPlatformClientSetup =
|
|
177
177
|
AndroidJavaObjectFactory.Instance.CreateCrossPlatformClientSetupAndroidJavaObject();
|
|
178
|
-
|
|
178
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
179
|
+
{
|
|
180
|
+
crossPlatformClientSetup.Call("setPlatformPref");
|
|
181
|
+
});
|
|
179
182
|
|
|
180
183
|
this.sdkInitCompleteAction = sdkInitCompleteAction;
|
|
181
184
|
this.adaptersInitCompleteAction = adaptersInitCompleteAction;
|
|
@@ -186,8 +189,11 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
186
189
|
var blueStackClass = new AndroidJavaClass(BlueStackNativeClassNames.BlueStackClassName);
|
|
187
190
|
var blueStackInstance = blueStackClass.GetStatic<AndroidJavaObject>("INSTANCE");
|
|
188
191
|
|
|
189
|
-
|
|
190
|
-
|
|
192
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
193
|
+
{
|
|
194
|
+
blueStackInstance.Call("setDebugModeEnabled", settings.IsDebugModeEnabled);
|
|
195
|
+
blueStackInstance.Call("initialize", activity, appId, this);
|
|
196
|
+
});
|
|
191
197
|
}
|
|
192
198
|
}
|
|
193
199
|
}
|
|
@@ -26,29 +26,44 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
26
26
|
|
|
27
27
|
public void Create(string placementId)
|
|
28
28
|
{
|
|
29
|
-
|
|
29
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
30
|
+
{
|
|
31
|
+
_unityInterstitialAd.Call("create", placementId);
|
|
32
|
+
});
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
public void Load()
|
|
33
36
|
{
|
|
34
|
-
|
|
37
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
38
|
+
{
|
|
39
|
+
_unityInterstitialAd.Call("load", null);
|
|
40
|
+
});
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
public void Load(IPreferenceClient iPreferenceClient)
|
|
38
44
|
{
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
46
|
+
{
|
|
47
|
+
PreferenceClient preferenceClient = (PreferenceClient)iPreferenceClient;
|
|
48
|
+
_unityInterstitialAd.Call("load", preferenceClient.getRequestOptions());
|
|
49
|
+
});
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
public void Show()
|
|
44
53
|
{
|
|
45
|
-
|
|
54
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
55
|
+
{
|
|
56
|
+
_unityInterstitialAd.Call("show");
|
|
57
|
+
});
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
public void Destroy()
|
|
49
61
|
{
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
63
|
+
{
|
|
64
|
+
_unityInterstitialAd.Call("destroy");
|
|
65
|
+
_unityInterstitialAd.Dispose();
|
|
66
|
+
});
|
|
52
67
|
}
|
|
53
68
|
|
|
54
69
|
public void onInterstitialDidLoaded()
|
|
@@ -28,29 +28,44 @@ namespace Azerion.BlueStack.Platforms.Android
|
|
|
28
28
|
|
|
29
29
|
public void Create(string placementId)
|
|
30
30
|
{
|
|
31
|
-
|
|
31
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
32
|
+
{
|
|
33
|
+
_unityRewardedVideoAd.Call("create", placementId);
|
|
34
|
+
});
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
public void Load()
|
|
35
38
|
{
|
|
36
|
-
|
|
39
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
40
|
+
{
|
|
41
|
+
_unityRewardedVideoAd.Call("load", null);
|
|
42
|
+
});
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
public void Load(IPreferenceClient iPreferenceClient)
|
|
40
46
|
{
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
48
|
+
{
|
|
49
|
+
PreferenceClient preferenceClient = (PreferenceClient)iPreferenceClient;
|
|
50
|
+
_unityRewardedVideoAd.Call("load", preferenceClient.getRequestOptions());
|
|
51
|
+
});
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
public void Show()
|
|
46
55
|
{
|
|
47
|
-
|
|
56
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
57
|
+
{
|
|
58
|
+
_unityRewardedVideoAd.Call("show");
|
|
59
|
+
});
|
|
48
60
|
}
|
|
49
61
|
|
|
50
62
|
public void Destroy()
|
|
51
63
|
{
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
AndroidJavaObjectFactory.Instance.RunOnUiThread(() =>
|
|
65
|
+
{
|
|
66
|
+
_unityRewardedVideoAd.Call("destroy");
|
|
67
|
+
_unityRewardedVideoAd.Dispose();
|
|
68
|
+
});
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
public void onRewardedVideoLoaded()
|
|
@@ -36,7 +36,7 @@ namespace Azerion.BlueStack.Platforms.UnityEditor
|
|
|
36
36
|
// Fires when the banner ad is displayed
|
|
37
37
|
public event EventHandler<EventArgs> OnBannerDisplay;
|
|
38
38
|
|
|
39
|
-
private static readonly string _adPrefabsDir = "Packages/com.azerion.bluestack/
|
|
39
|
+
private static readonly string _adPrefabsDir = "Packages/com.azerion.bluestack/Editor/Prefabs/AdPrefabs/";
|
|
40
40
|
|
|
41
41
|
private Dictionary<AdSize, string> _prefabAds = new Dictionary<AdSize, string>()
|
|
42
42
|
{
|
|
@@ -19,7 +19,7 @@ namespace Azerion.BlueStack.Platforms.UnityEditor
|
|
|
19
19
|
adPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabName);
|
|
20
20
|
if (adPrefab == null)
|
|
21
21
|
{
|
|
22
|
-
Debug.
|
|
22
|
+
Debug.LogWarning("No Prefab found: " + prefabName);
|
|
23
23
|
}
|
|
24
24
|
#endif
|
|
25
25
|
}
|
|
@@ -30,7 +30,7 @@ namespace Azerion.BlueStack.Platforms.UnityEditor
|
|
|
30
30
|
// Interstitial ad size
|
|
31
31
|
private static readonly AdSize _interstitialPortrait = new AdSize(768, 1024, "768x1024");
|
|
32
32
|
private static readonly AdSize _interstitialLandscape = new AdSize(1024, 768, "1024x768");
|
|
33
|
-
private static readonly string _adPrefabsDir = "Packages/com.azerion.bluestack/
|
|
33
|
+
private static readonly string _adPrefabsDir = "Packages/com.azerion.bluestack/Editor/Prefabs/AdPrefabs/";
|
|
34
34
|
|
|
35
35
|
private Dictionary<AdSize, string> _prefabAds = new Dictionary<AdSize, string>()
|
|
36
36
|
{
|
|
@@ -33,7 +33,7 @@ namespace Azerion.BlueStack.Platforms.UnityEditor
|
|
|
33
33
|
// Rewarded ad size
|
|
34
34
|
private static readonly AdSize _rewardedPortrait = new AdSize(768, 1024, "768x1024");
|
|
35
35
|
private static readonly AdSize _rewardedLandscape = new AdSize(1024, 768, "1024x768");
|
|
36
|
-
private static readonly string _adPrefabsDir = "Packages/com.azerion.bluestack/
|
|
36
|
+
private static readonly string _adPrefabsDir = "Packages/com.azerion.bluestack/Editor/Prefabs/AdPrefabs/";
|
|
37
37
|
|
|
38
38
|
private Dictionary<AdSize, string> _prefabAds = new Dictionary<AdSize, string>()
|
|
39
39
|
{
|
package/package.json
CHANGED
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{Resources → Editor/Prefabs}/AdPrefabs/Interstitial/InterstitialLandscape.prefab.meta
RENAMED
|
File without changes
|
|
File without changes
|
/package/{Resources → Editor/Prefabs}/AdPrefabs/Interstitial/InterstitialPortrait.prefab.meta
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|