[A] Add Applovin Max SDK
This commit is contained in:
8
sdk-intergration/Assets/ExternalDependencyManager.meta
Normal file
8
sdk-intergration/Assets/ExternalDependencyManager.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98396871203e74c1e8a0d65711103588
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 988f512d014ef4b1fba391f4fa250483
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b59b38cb2f793414ea9935846aa50ea0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 052fc6841b304ce4801cd850704efc6b
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.179/Google.IOSResolver.dll
|
||||
- gvhp_targets-editor
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8c5c28ca63d4b998365d84dd183658d
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.179/Google.JarResolver.dll
|
||||
- gvhp_targets-editor
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a22e43395e864125aec54dc456a4eda0
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.179/Google.PackageManagerResolver.dll
|
||||
- gvhp_targets-editor
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76d0a5f5ee7f4a72a3d2de688e3bd51a
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.179/Google.VersionHandlerImpl.dll
|
||||
- gvhp_targets-editor
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1399
sdk-intergration/Assets/ExternalDependencyManager/Editor/CHANGELOG.md
Executable file
1399
sdk-intergration/Assets/ExternalDependencyManager/Editor/CHANGELOG.md
Executable file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8d928a6df80469ab6cd8eca7bf6d273
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/CHANGELOG.md
|
||||
timeCreated: 1584567712
|
||||
licenseType: Pro
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efd2c569f89a449498a0c946cd37a752
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/Google.VersionHandler.dll
|
||||
- gvhp_targets-editor
|
||||
timeCreated: 1480838400
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
245
sdk-intergration/Assets/ExternalDependencyManager/Editor/LICENSE
Executable file
245
sdk-intergration/Assets/ExternalDependencyManager/Editor/LICENSE
Executable file
@@ -0,0 +1,245 @@
|
||||
Copyright (C) 2014 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
====================================================================================================
|
||||
This package uses MiniJSON
|
||||
|
||||
Copyright (c) 2013 Calvin Rien
|
||||
|
||||
Based on the JSON parser by Patrick van Bergen
|
||||
http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
|
||||
|
||||
Simplified it so that it doesn't throw exceptions
|
||||
and can be used in Unity iPhone with maximum code stripping.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9be3e4155c3148d298ad390b9db89273
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/LICENSE
|
||||
timeCreated: 1584567712
|
||||
licenseType: Pro
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
897
sdk-intergration/Assets/ExternalDependencyManager/Editor/README.md
Executable file
897
sdk-intergration/Assets/ExternalDependencyManager/Editor/README.md
Executable file
@@ -0,0 +1,897 @@
|
||||
# External Dependency Manager for Unity
|
||||
|
||||
[](https://openupm.com/packages/com.google.external-dependency-manager/)
|
||||
[](https://openupm.com/packages/com.google.external-dependency-manager/)
|
||||
|
||||
## Overview
|
||||
|
||||
The External Dependency Manager for Unity (EDM4U) (formerly Play Services
|
||||
Resolver/Jar Resolver) is intended to be used by any Unity package or user that
|
||||
requires:
|
||||
|
||||
* Android specific libraries (e.g
|
||||
[AARs](https://developer.android.com/studio/projects/android-library.html))
|
||||
|
||||
* iOS [CocoaPods](https://cocoapods.org/)
|
||||
|
||||
* Version management of transitive dependencies
|
||||
|
||||
* Management of Package Manager (PM) Registries
|
||||
|
||||
If you want to add and use iOS/Android dependencies directly in your project,
|
||||
then you should to install EDM4U in your project.
|
||||
|
||||
If you are a package user and the plugin you are using depends on EDM4U, *and*
|
||||
the package does not include EDM4U as a package dependency already, then you
|
||||
should to install EDM4U in your project.
|
||||
|
||||
If you are a UPM package maintainer and your package requires EDM4U, then you
|
||||
should add EDM4U as a
|
||||
[package dependency](https://docs.unity3d.com/2019.3/Documentation/Manual/upm-dependencies.html)
|
||||
in your package manifest (`package.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"com.google.external-dependency-manager": "1.2.178"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You should still install EDM4U to test out the package during development.
|
||||
|
||||
If you are a legacy `.unitypackage` package maintainer and your package requires
|
||||
EDM4U, please ask the user to install EDM4U separately. You should install EDM4U
|
||||
to test out the package during development.
|
||||
|
||||
Updated releases are available on
|
||||
[GitHub](https://github.com/googlesamples/unity-jar-resolver)
|
||||
|
||||
## Requirements
|
||||
|
||||
The *Android Resolver* and *iOS Resolver* components of the plugin only work
|
||||
with Unity version 4.6.8 or higher.
|
||||
|
||||
The *Version Handler* component only works with Unity 5.x or higher as it
|
||||
depends upon the `PluginImporter` UnityEditor API.
|
||||
|
||||
The *Package Manager Resolver* component only works with Unity 2018.4 or above,
|
||||
when [scoped registry](https://docs.unity3d.com/Manual/upm-scoped.html) support
|
||||
was added to the Package Manager.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Check out [troubleshooting](troubleshooting-faq.md) if you need help.
|
||||
|
||||
### Install via OpenUPM
|
||||
|
||||
EDM4U is available on
|
||||
[OpenUPM](https://openupm.com/packages/com.google.external-dependency-manager/):
|
||||
|
||||
```shell
|
||||
openupm add com.google.external-dependency-manager
|
||||
```
|
||||
|
||||
### Install via Google APIs for Unity
|
||||
|
||||
EDM4U is available both in UPM and legacy `.unitypackage` formats on
|
||||
[Google APIs for Unity](https://developers.google.com/unity/archive#external_dependency_manager_for_unity).
|
||||
|
||||
You may install the UPM version (.tgz) as a
|
||||
[local UPM package](https://docs.unity3d.com/Manual/upm-ui-local.html).
|
||||
|
||||
You can also install EDM4U in your project as a `.unitypackage`. This is not
|
||||
recommended due to potential conflicts.
|
||||
|
||||
### Conflict Resolution
|
||||
|
||||
For historical reasons, a package maintainer may choose to embed EDM4U in their
|
||||
package for ease of installation. This will create a conflict when you try to
|
||||
install EDM4U with the steps above, or with another package with embedded EDM4U.
|
||||
If your project imported a `.unitypackage` that has a copy of EDM4U embedded in
|
||||
it, you may safely delete it from your Assets folder. If your project depends on
|
||||
another UPM package with EDM4U, please reach out to the package maintainer and
|
||||
ask them to replace it with a dependency to this package. In the meantime, you
|
||||
can workaround the issue by copying the package to your Packages folder (to
|
||||
create an
|
||||
[embedded package](https://docs.unity3d.com/Manual/upm-concepts.html#Embedded))
|
||||
and perform the steps yourself to avoid a dependency conflict.
|
||||
|
||||
### Config file
|
||||
|
||||
To start adding dependencies to your project, copy and rename the
|
||||
[SampleDependencies.xml](https://github.com/googlesamples/unity-jar-resolver/blob/master/sample/Assets/ExternalDependencyManager/Editor/SampleDependencies.xml)
|
||||
file into your plugin and add the dependencies your project requires.
|
||||
|
||||
The XML file needs to be under an `Editor` directory and match the name
|
||||
`*Dependencies.xml`. For example, `MyPlugin/Editor/MyPluginDependencies.xml`.
|
||||
|
||||
## Usages
|
||||
|
||||
### Android Resolver
|
||||
|
||||
The Android Resolver copies specified dependencies from local or remote Maven
|
||||
repositories into the Unity project when a user selects Android as the build
|
||||
target in the Unity editor.
|
||||
|
||||
For example, to add the Google Play Games library
|
||||
(`com.google.android.gms:play-services-games` package) at version `9.8.0` to the
|
||||
set of a plugin's Android dependencies:
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.google.android.gms:play-services-games:9.8.0">
|
||||
<androidSdkPackageIds>
|
||||
<androidSdkPackageId>extra-google-m2repository</androidSdkPackageId>
|
||||
</androidSdkPackageIds>
|
||||
</androidPackage>
|
||||
</androidPackages>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
The version specification (last component) supports:
|
||||
|
||||
* Specific versions e.g `9.8.0`
|
||||
|
||||
* Partial matches e.g `9.8.+` would match 9.8.0, 9.8.1 etc. choosing the most
|
||||
recent version
|
||||
|
||||
* Latest version using `LATEST` or `+`. We do *not* recommend using this
|
||||
unless you're 100% sure the library you depend upon will not break your
|
||||
Unity plugin in future
|
||||
|
||||
The above example specifies the dependency as a component of the Android SDK
|
||||
manager such that the Android SDK manager will be executed to install the
|
||||
package if it's not found. If your Android dependency is located on Maven
|
||||
central it's possible to specify the package simply using the `androidPackage`
|
||||
element:
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.google.api-client:google-api-client-android:1.22.0" />
|
||||
</androidPackages>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
#### Auto-resolution
|
||||
|
||||
By default the Android Resolver automatically monitors the dependencies you have
|
||||
specified and the `Plugins/Android` folder of your Unity project. The resolution
|
||||
process runs when the specified dependencies are not present in your project.
|
||||
|
||||
The *auto-resolution* process can be disabled via the `Assets > External
|
||||
Dependency Manager > Android Resolver > Settings` menu.
|
||||
|
||||
Manual resolution can be performed using the following menu options:
|
||||
|
||||
* `Assets > External Dependency Manager > Android Resolver > Resolve`
|
||||
|
||||
* `Assets > External Dependency Manager > Android Resolver > Force Resolve`
|
||||
|
||||
#### Deleting libraries
|
||||
|
||||
Resolved packages are tracked via asset labels by the Android Resolver. They can
|
||||
easily be deleted using the `Assets > External Dependency Manager > Android
|
||||
Resolver > Delete Resolved Libraries` menu item.
|
||||
|
||||
#### Android Manifest Variable Processing
|
||||
|
||||
Some AAR files (for example play-services-measurement) contain variables that
|
||||
are processed by the Android Gradle plugin. Unfortunately, Unity does not
|
||||
perform the same processing when using Unity's Internal Build System, so the
|
||||
Android Resolver plugin handles known cases of this variable substitution by
|
||||
exploding the AAR into a folder and replacing `${applicationId}` with the
|
||||
`bundleID`.
|
||||
|
||||
Disabling AAR explosion and therefore Android manifest processing can be done
|
||||
via the `Assets > External Dependency Manager > Android Resolver > Settings`
|
||||
menu. You may want to disable explosion of AARs if you're exporting a project to
|
||||
be built with Gradle/Android Studio.
|
||||
|
||||
#### ABI Stripping
|
||||
|
||||
Some AAR files contain native libraries (.so files) for each ABI supported by
|
||||
Android. Unfortunately, when targeting a single ABI (e.g x86), Unity does not
|
||||
strip native libraries for unused ABIs. To strip unused ABIs, the Android
|
||||
Resolver plugin explodes an AAR into a folder and removes unused ABIs to reduce
|
||||
the built APK size. Furthermore, if native libraries are not stripped from an
|
||||
APK (e.g you have a mix of Unity's x86 library and some armeabi-v7a libraries)
|
||||
Android may attempt to load the wrong library for the current runtime ABI
|
||||
completely breaking your plugin when targeting some architectures.
|
||||
|
||||
AAR explosion and therefore ABI stripping can be disabled via the `Assets >
|
||||
External Dependency Manager > Android Resolver > Settings` menu. You may want to
|
||||
disable explosion of AARs if you're exporting a project to be built with
|
||||
Gradle/Android Studio.
|
||||
|
||||
#### Resolution Strategies
|
||||
|
||||
By default the Android Resolver will use Gradle to download dependencies prior
|
||||
to integrating them into a Unity project. This works with Unity's internal build
|
||||
system and Gradle/Android Studio project export.
|
||||
|
||||
It's possible to change the resolution strategy via the `Assets > External
|
||||
Dependency Manager > Android Resolver > Settings` menu.
|
||||
|
||||
##### Download Artifacts with Gradle
|
||||
|
||||
Using the default resolution strategy, the Android resolver executes the
|
||||
following operations:
|
||||
|
||||
- Remove the result of previous Android resolutions. E.g Delete all files and
|
||||
directories labeled with "gpsr" under `Plugins/Android` from the project.
|
||||
|
||||
- Collect the set of Android dependencies (libraries) specified by a project's
|
||||
`*Dependencies.xml` files.
|
||||
|
||||
- Run `download_artifacts.gradle` with Gradle to resolve conflicts and, if
|
||||
successful, download the set of resolved Android libraries (AARs, JARs).
|
||||
|
||||
- Process each AAR/JAR so that it can be used with the currently selected
|
||||
Unity build system (e.g Internal vs. Gradle, Export vs. No Export). This
|
||||
involves patching each reference to `applicationId` in the
|
||||
`AndroidManifest.xml` with the project's bundle ID. This means resolution
|
||||
must be run again if the bundle ID has changed.
|
||||
|
||||
- Move the processed AARs to `Plugins/Android` so they will be included when
|
||||
Unity invokes the Android build.
|
||||
|
||||
##### Integrate into mainTemplate.gradle
|
||||
|
||||
Unity 5.6 introduced support for customizing the `build.gradle` used to build
|
||||
Unity projects with Gradle. When the *Patch mainTemplate.gradle* setting is
|
||||
enabled, rather than downloading artifacts before the build, Android resolution
|
||||
results in the execution of the following operations:
|
||||
|
||||
- Remove the result of previous Android resolutions. E.g Delete all files and
|
||||
directories labeled with "gpsr" under `Plugins/Android` from the project and
|
||||
remove sections delimited with `// Android Resolver * Start` and `// Android
|
||||
Resolver * End` lines.
|
||||
|
||||
- Collect the set of Android dependencies (libraries) specified by a project's
|
||||
`*Dependencies.xml` files.
|
||||
|
||||
- Rename any `.srcaar` files in the build to `.aar` and exclude them from
|
||||
being included directly by Unity in the Android build as
|
||||
`mainTemplate.gradle` will be patched to include them instead from their
|
||||
local maven repositories.
|
||||
|
||||
- Inject the required Gradle repositories into `mainTemplate.gradle` at the
|
||||
line matching the pattern `.*apply plugin:
|
||||
'com\.android\.(application|library)'.*` or the section starting at the line
|
||||
`// Android Resolver Repos Start`. If you want to control the injection
|
||||
point in the file, the section delimited by the lines `// Android Resolver
|
||||
Repos Start` and `// Android Resolver Repos End` should be placed in the
|
||||
global scope before the `dependencies` section.
|
||||
|
||||
- Inject the required Android dependencies (libraries) into
|
||||
`mainTemplate.gradle` at the line matching the pattern `***DEPS***` or the
|
||||
section starting at the line `// Android Resolver Dependencies Start`. If
|
||||
you want to control the injection point in the file, the section delimited
|
||||
by the lines `// Android Resolver Dependencies Start` and `// Android
|
||||
Resolver Dependencies End` should be placed in the `dependencies` section.
|
||||
|
||||
- Inject the packaging options logic, which excludes architecture specific
|
||||
libraries based upon the selected build target, into `mainTemplate.gradle`
|
||||
at the line matching the pattern `android +{` or the section starting at the
|
||||
line `// Android Resolver Exclusions Start`. If you want to control the
|
||||
injection point in the file, the section delimited by the lines `// Android
|
||||
Resolver Exclusions Start` and `// Android Resolver Exclusions End` should
|
||||
be placed in the global scope before the `android` section.
|
||||
|
||||
#### Dependency Tracking
|
||||
|
||||
The Android Resolver creates the
|
||||
`ProjectSettings/AndroidResolverDependencies.xml` to quickly determine the set
|
||||
of resolved dependencies in a project. This is used by the auto-resolution
|
||||
process to only run the expensive resolution process when necessary.
|
||||
|
||||
#### Displaying Dependencies
|
||||
|
||||
It's possible to display the set of dependencies the Android Resolver would
|
||||
download and process in your project via the `Assets > External Dependency
|
||||
Manager > Android Resolver > Display Libraries` menu item.
|
||||
|
||||
### iOS Resolver
|
||||
|
||||
The iOS resolver component of this plugin manages
|
||||
[CocoaPods](https://cocoapods.org/). A CocoaPods `Podfile` is generated and the
|
||||
`pod` tool is executed as a post build process step to add dependencies to the
|
||||
Xcode project exported by Unity.
|
||||
|
||||
Dependencies for iOS are added by referring to CocoaPods.
|
||||
|
||||
For example, to add the AdMob pod, version 7.0 or greater with bitcode enabled:
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<iosPods>
|
||||
<iosPod name="Google-Mobile-Ads-SDK" version="~> 7.0" bitcodeEnabled="true"
|
||||
minTargetSdk="6.0" addToAllTargets="false" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
#### Integration Strategies
|
||||
|
||||
The `CocoaPods` are either:
|
||||
|
||||
* Downloaded and injected into the Xcode project file directly, rather than
|
||||
creating a separate xcworkspace. We call this `Xcode project` integration.
|
||||
|
||||
* If the Unity version supports opening a xcworkspace file, the `pod` tool is
|
||||
used as intended to generate a xcworkspace which references the CocoaPods.
|
||||
We call this `Xcode workspace` integration.
|
||||
|
||||
The resolution strategy can be changed via the `Assets > External Dependency
|
||||
Manager > iOS Resolver > Settings` menu.
|
||||
|
||||
##### Appending text to generated Podfile
|
||||
|
||||
In order to modify the generated Podfile you can create a script like this:
|
||||
|
||||
```csharp
|
||||
using System.IO;
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEngine;
|
||||
|
||||
public class PostProcessIOS : MonoBehaviour
|
||||
{
|
||||
// Must be between 40 and 50 to ensure that it's not overriden by Podfile generation (40) and
|
||||
// that it's added before "pod install" (50).
|
||||
[PostProcessBuildAttribute(45)]
|
||||
private static void PostProcessBuild_iOS(BuildTarget target, string buildPath)
|
||||
{
|
||||
if (target == BuildTarget.iOS)
|
||||
{
|
||||
using (StreamWriter sw = File.AppendText(buildPath + "/Podfile"))
|
||||
{
|
||||
// E.g. add an app extension
|
||||
sw.WriteLine("\ntarget 'NSExtension' do\n pod 'Firebase/Messaging', '6.6.0'\nend");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Package Manager Resolver
|
||||
|
||||
Adding registries to the
|
||||
[Package Manager](https://docs.unity3d.com/Manual/Packages.html) (PM) is a
|
||||
manual process. The Package Manager Resolver (PMR) component of this plugin
|
||||
makes it easy for plugin maintainers to distribute new PM registry servers and
|
||||
easy for plugin users to manage PM registry servers.
|
||||
|
||||
#### Adding Registries
|
||||
|
||||
For example, to add a registry for plugins in the scope `com.coolstuff`:
|
||||
|
||||
```xml
|
||||
<registries>
|
||||
<registry name="Cool Stuff"
|
||||
url="https://unityregistry.coolstuff.com"
|
||||
termsOfService="https://coolstuff.com/unityregistry/terms"
|
||||
privacyPolicy="https://coolstuff.com/unityregistry/privacy">
|
||||
<scopes>
|
||||
<scope>com.coolstuff</scope>
|
||||
</scopes>
|
||||
</registry>
|
||||
</registries>
|
||||
```
|
||||
|
||||
When PMR is loaded it will prompt the developer to add the registry to their
|
||||
project if it isn't already present in the `Packages/manifest.json` file.
|
||||
|
||||
For more information, see Unity's documentation on
|
||||
[scoped package registries](https://docs.unity3d.com/Manual/upm-scoped.html).
|
||||
|
||||
#### Managing Registries
|
||||
|
||||
It's possible to add and remove registries that are specified via PMR XML
|
||||
configuration files via the following menu options:
|
||||
|
||||
* `Assets > External Dependency Manager > Package Manager Resolver > Add
|
||||
Registries` will prompt the user with a window which allows them to add
|
||||
registries discovered in the project to the Package Manager.
|
||||
|
||||
* `Assets > External Dependency Manager > Package Manager Resolver > Remove
|
||||
Registries` will prompt the user with a window which allows them to remove
|
||||
registries discovered in the project from the Package Manager.
|
||||
|
||||
* `Assets > External Dependency Manager > Package Manager Resolver > Modify
|
||||
Registries` will prompt the user with a window which allows them to add or
|
||||
remove registries discovered in the project.
|
||||
|
||||
#### Migration
|
||||
|
||||
PMR can migrate Version Handler packages installed in the `Assets` folder to PM
|
||||
packages. This requires the plugins to implement the following:
|
||||
|
||||
* `.unitypackage` must include a Version Handler manifests that describes the
|
||||
components of the plugin. If the plugin has no dependencies the manifest
|
||||
would just include the files in the plugin.
|
||||
|
||||
* The PM package JSON provided by the registry must include a keyword (in the
|
||||
`versions.VERSION.keyword` list) that maps the PM package to a Version
|
||||
Handler package using the format `vh-name:VERSION_HANDLER_MANIFEST_NAME`
|
||||
where `VERSION_HANDLER_MANIFEST_NAME` is the name of the manifest defined in
|
||||
the `.unitypackage`. For more information see the description of the
|
||||
`gvhp_manifestname` asset label in the [Version Handler](#version-handler)
|
||||
section.
|
||||
|
||||
When using the `Assets > External Dependency Manager > Package Manager
|
||||
Resolver > Migrate Packages` menu option, PMR then will:
|
||||
|
||||
* List all Version Handler manager packages in the project.
|
||||
|
||||
* Search all available packages in the PM registries and fetch keywords
|
||||
associated with each package parsing the Version Handler manifest names for
|
||||
each package.
|
||||
|
||||
* Map each installed Version Handler package to a PM package.
|
||||
|
||||
* Prompt the user to migrate the discovered packages.
|
||||
|
||||
* Perform package migration for all selected packages if the user clicks the
|
||||
`Apply` button.
|
||||
|
||||
#### Configuration
|
||||
|
||||
PMR can be configured via the `Assets > External Dependency Manager > Package
|
||||
Manager Resolver > Settings` menu option:
|
||||
|
||||
* `Add package registries` when enabled, when the plugin loads or registry
|
||||
configuration files change, this will prompt the user to add registries that
|
||||
are not present in the Package Manager.
|
||||
|
||||
* `Prompt to add package registries` will cause a developer to be prompted
|
||||
with a window that will ask for confirmation before adding registries. When
|
||||
this is disabled registries are added silently to the project.
|
||||
|
||||
* `Prompt to migrate packages` will cause a developer to be prompted with a
|
||||
window that will ask for confirmation before migrating packages installed in
|
||||
the `Assets` directory to PM packages.
|
||||
|
||||
* `Enable Analytics Reporting` when enabled, reports the use of the plugin to
|
||||
the developers so they can make imrpovements.
|
||||
|
||||
* `Verbose logging` when enabled prints debug information to the console which
|
||||
can be useful when filing bug reports.
|
||||
|
||||
### Version Handler
|
||||
|
||||
The Version Handler component of this plugin manages:
|
||||
|
||||
* Shared Unity plugin dependencies.
|
||||
|
||||
* Upgrading Unity plugins by cleaning up old files from previous versions.
|
||||
|
||||
* Uninstallation of plugins that are distributed with manifest files.
|
||||
|
||||
* Restoration of plugin assets to their original install locations if assets
|
||||
are tagged with the `exportpath` label.
|
||||
|
||||
Since the Version Handler needs to modify Unity asset metadata (`.meta` files),
|
||||
to enable/disable components, rename and delete asset files it does not work
|
||||
with Package Manager installed packages. It's still possible to include EDM4U in
|
||||
Package Manager packages, the Version Handler component simply won't do anything
|
||||
to PM plugins in this case.
|
||||
|
||||
#### Using Version Handler Managed Plugins
|
||||
|
||||
If a plugin is imported at multiple different versions into a project, if the
|
||||
Version Handler is enabled, it will automatically check all managed assets to
|
||||
determine the set of assets that are out of date and assets that should be
|
||||
removed. To disable automatic checking managed assets disable the `Enable
|
||||
version management` option in the `Assets > External Dependency Manager >
|
||||
Version Handler > Settings` menu.
|
||||
|
||||
If version management is disabled, it's possible to check managed assets
|
||||
manually using the `Assets > External Dependency Manager > Version Handler >
|
||||
Update` menu option.
|
||||
|
||||
##### Listing Managed Plugins
|
||||
|
||||
Plugins managed by the Version Handler, those that ship with manifest files, can
|
||||
displayed using the `Assets > External Dependency Manager > Version Handler >
|
||||
Display Managed Packages` menu option. The list of plugins are written to the
|
||||
console window along with the set of files used by each plugin.
|
||||
|
||||
##### Uninstalling Managed Plugins
|
||||
|
||||
Plugins managed by the Version Handler, those that ship with manifest files, can
|
||||
be removed using the `Assets > External Dependency Manager > Version Handler >
|
||||
Uninstall Managed Packages` menu option. This operation will display a window
|
||||
that allows a developer to select a set of plugins to remove which will remove
|
||||
all files owned by each plugin excluding those that are in use by other
|
||||
installed plugins.
|
||||
|
||||
Files managed by the Version Handler, those labeled with the `gvh` asset label,
|
||||
can be checked to see whether anything needs to be upgraded, disabled or removed
|
||||
using the `Assets > External Dependency Manager > Version Handler > Update` menu
|
||||
option.
|
||||
|
||||
##### Restore Install Paths
|
||||
|
||||
Some developers move assets around in their project which can make it harder for
|
||||
plugin maintainers to debug issues if this breaks Unity's
|
||||
[special folders](https://docs.unity3d.com/Manual/SpecialFolders.html) rules. If
|
||||
assets are labeled with their original install/export path (see
|
||||
`gvhp_exportpath` below), Version Handler can restore assets to their original
|
||||
locations when using the `Assets > External Dependency Manager > Version
|
||||
Handler > Move Files To Install Locations` menu option.
|
||||
|
||||
##### Settings
|
||||
|
||||
Some behavior of the Version Handler can be configured via the `Assets >
|
||||
External Dependency Manager > Version Handler > Settings` menu option.
|
||||
|
||||
* `Enable version management` controls whether the plugin should automatically
|
||||
check asset versions and apply changes. If this is disabled the process
|
||||
should be run manually when installing or upgrading managed plugins using
|
||||
`Assets > External Dependency Manager > Version Handler > Update`.
|
||||
|
||||
* `Rename to canonical filenames` is a legacy option that will rename files to
|
||||
remove version numbers and other labels from filenames.
|
||||
|
||||
* `Prompt for obsolete file deletion` enables the display of a window when
|
||||
obsolete files are deleted allowing the developer to select which files to
|
||||
delete and those to keep.
|
||||
|
||||
* `Allow disabling files via renaming` controls whether obsolete or disabled
|
||||
files should be disabled by renaming them to `myfilename_DISABLED`. Renaming
|
||||
to disable files is required in some scenarios where Unity doesn't support
|
||||
removing files from the build via the PluginImporter.
|
||||
|
||||
* `Enable Analytics Reporting` enables/disables usage reporting to plugin
|
||||
developers to improve the product.
|
||||
|
||||
* `Verbose logging` enables *very* noisy log output that is useful for
|
||||
debugging while filing a bug report or building a new managed plugin.
|
||||
|
||||
* `Use project settings` saves settings for the plugin in the project rather
|
||||
than system-wide.
|
||||
|
||||
#### Redistributing a Managed Plugin
|
||||
|
||||
The Version Handler employs a couple of methods for managing version selection,
|
||||
upgrade and removal of plugins.
|
||||
|
||||
* Each plugin can ship with a manifest file that lists the files it includes.
|
||||
This makes it possible for Version Handler to calculate the difference in
|
||||
assets between the most recent release of a plugin and the previous release
|
||||
installed in a project. If a files are removed the Version Handler will
|
||||
prompt the user to clean up obsolete files.
|
||||
|
||||
* Plugins can ship using assets with unique names, unique GUIDs and version
|
||||
number labels. Version numbers can be attached to assets using labels or
|
||||
added to the filename (e.g `myfile.txt` would be `myfile_version-x.y.z.txt).
|
||||
This allows the Version Handler to determine which set of files are the same
|
||||
file at different versions, select the most recent version and prompt the
|
||||
developer to clean up old versions.
|
||||
|
||||
Unity plugins can be managed by the Version Handler using the following steps:
|
||||
|
||||
1. Add the `gvh` asset label to each asset (file) you want Version Handler to
|
||||
manage.
|
||||
|
||||
1. Add the `gvh_version-VERSION` label to each asset where `VERSION` is the
|
||||
version of the plugin you're releasing (e.g 1.2.3).
|
||||
|
||||
1. Add the `gvhp_exportpath-PATH` label to each asset where `PATH` is the
|
||||
export path of the file when the `.unitypackage` is created. This is used to
|
||||
track files if they're moved around in a project by developers.
|
||||
|
||||
1. Optional: Add `gvh_targets-editor` label to each editor DLL in your plugin
|
||||
and disable `editor` as a target platform for the DLL. The Version Handler
|
||||
will enable the most recent version of this DLL when the plugin is imported.
|
||||
|
||||
1. Optional: If your plugin is included in other Unity plugins, you should add
|
||||
the version number to each filename and change the GUID of each asset. This
|
||||
allows multiple versions of your plugin to be imported into a Unity project,
|
||||
with the Version Handler component activating only the most recent version.
|
||||
|
||||
1. Create a manifest text file named `MY_UNIQUE_PLUGIN_NAME_VERSION.txt` that
|
||||
lists all the files in your plugin relative to the project root. Then add
|
||||
the `gvh_manifest` label to the asset to indicate this file is a plugin
|
||||
manifest.
|
||||
|
||||
1. Optional: Add a `gvhp_manifestname-NAME` label to your manifest file to
|
||||
provide a human readable name for your package. If this isn't provided the
|
||||
name of the manifest file will be used as the package name. NAME can match
|
||||
the pattern `[0-9]+[a-zA-Z -]` where a leading integer will set the priority
|
||||
of the name where `0` is the highest priority and preferably used as the
|
||||
display name. The lowest value (i.e highest priority name) will be used as
|
||||
the display name and all other specified names will be aliases of the
|
||||
display name. Aliases can refer to previous names of the package allowing
|
||||
renaming across published versions.
|
||||
|
||||
1. Redistribute EDM4U Unity plugin with your plugin. See the
|
||||
[Plugin Redistribution](#plugin-redistribution) section for details.
|
||||
|
||||
If you follow these steps:
|
||||
|
||||
* When users import a newer version of your plugin, files referenced by the
|
||||
older version's manifest are cleaned up.
|
||||
|
||||
* The latest version of the plugin will be selected when users import multiple
|
||||
packages that include your plugin, assuming the steps in
|
||||
[Plugin Redistribution](#plugin-redistribution) are followed.
|
||||
|
||||
## Background
|
||||
|
||||
Many Unity plugins have dependencies upon Android specific libraries, iOS
|
||||
CocoaPods, and sometimes have transitive dependencies upon other Unity plugins.
|
||||
This causes the following problems:
|
||||
|
||||
* Integrating platform specific (e.g Android and iOS) libraries within a Unity
|
||||
project can be complex and a burden on a Unity plugin maintainer.
|
||||
* The process of resolving conflicting dependencies on platform specific
|
||||
libraries is pushed to the developer attempting to use a Unity plugin. The
|
||||
developer trying to use your plugin is very likely to give up when faced
|
||||
with Android or iOS specific build errors.
|
||||
* The process of resolving conflicting Unity plugins (due to shared Unity
|
||||
plugin components) is pushed to the developer attempting to use your Unity
|
||||
plugin. In an effort to resolve conflicts, the developer will very likely
|
||||
attempt to resolve problems by deleting random files in your plugin, report
|
||||
bugs when that doesn't work and finally give up.
|
||||
|
||||
EDM4U provides solutions for each of these problems.
|
||||
|
||||
### Android Dependency Management
|
||||
|
||||
The *Android Resolver* component of this plugin will download and integrate
|
||||
Android library dependencies and handle any conflicts between plugins that share
|
||||
the same dependencies.
|
||||
|
||||
Without the Android Resolver, typically Unity plugins bundle their AAR and JAR
|
||||
dependencies, e.g. a Unity plugin `SomePlugin` that requires the Google Play
|
||||
Games Android library would redistribute the library and its transitive
|
||||
dependencies in the folder `SomePlugin/Android/`. When a user imports
|
||||
`SomeOtherPlugin` that includes the same libraries (potentially at different
|
||||
versions) in `SomeOtherPlugin/Android/`, the developer using `SomePlugin` and
|
||||
`SomeOtherPlugin` will see an error when building for Android that can be hard
|
||||
to interpret.
|
||||
|
||||
Using the Android Resolver to manage Android library dependencies:
|
||||
|
||||
* Solves Android library conflicts between plugins.
|
||||
* Handles all of the various processing steps required to use Android
|
||||
libraries (AARs, JARs) in Unity 4.x and above projects. Almost all versions
|
||||
of Unity have - at best - partial support for AARs.
|
||||
* (Experimental) Supports minification of included Java components without
|
||||
exporting a project.
|
||||
|
||||
### iOS Dependency Management
|
||||
|
||||
The *iOS Resolver* component of this plugin integrates with
|
||||
[CocoaPods](https://cocoapods.org/) to download and integrate iOS libraries and
|
||||
frameworks into the Xcode project Unity generates when building for iOS. Using
|
||||
CocoaPods allows multiple plugins to utilize shared components without forcing
|
||||
developers to fix either duplicate or incompatible versions of libraries
|
||||
included through multiple Unity plugins in their project.
|
||||
|
||||
### Package Manager Registry Setup
|
||||
|
||||
The [Package Manager](https://docs.unity3d.com/Manual/Packages.html) (PM) makes
|
||||
use of [NPM](https://www.npmjs.com/) registry servers for package hosting and
|
||||
provides ways to discover, install, upgrade and uninstall packages. This makes
|
||||
it easier for developers to manage plugins within their projects.
|
||||
|
||||
However, installing additional package registries requires a few manual steps
|
||||
that can potentially be error prone. The *Package Manager Resolver* component of
|
||||
this plugin integrates with [PM](https://docs.unity3d.com/Manual/Packages.html)
|
||||
to provide a way to auto-install PM package registries when a `.unitypackage` is
|
||||
installed which allows plugin maintainers to ship a `.unitypackage` that can
|
||||
provide access to their own PM registry server to make it easier for developers
|
||||
to manage their plugins.
|
||||
|
||||
### Unity Plugin Version Management
|
||||
|
||||
Finally, the *Version Handler* component of this plugin simplifies the process
|
||||
of managing transitive dependencies of Unity plugins and each plugin's upgrade
|
||||
process.
|
||||
|
||||
For example, without the Version Handler plugin, if:
|
||||
|
||||
* Unity plugin `SomePlugin` includes `EDM4U` plugin at version 1.1.
|
||||
* Unity plugin `SomeOtherPlugin` includes `EDM4U` plugin at version 1.2.
|
||||
|
||||
The version of `EDM4U` included in the developer's project depends upon the
|
||||
order the developer imports `SomePlugin` or `SomeOtherPlugin`.
|
||||
|
||||
This results in:
|
||||
|
||||
* `EDM4U` at version 1.2, if `SomePlugin` is imported then `SomeOtherPlugin`
|
||||
is imported.
|
||||
* `EDM4U` at version 1.1, if `SomeOtherPlugin` is imported then `SomePlugin`
|
||||
is imported.
|
||||
|
||||
The Version Handler solves the problem of managing transitive dependencies by:
|
||||
|
||||
* Specifying a set of packaging requirements that enable a plugin at different
|
||||
versions to be imported into a Unity project.
|
||||
* Providing activation logic that selects the latest version of a plugin
|
||||
within a project.
|
||||
|
||||
When using the Version Handler to manage `EDM4U` included in `SomePlugin` and
|
||||
`SomeOtherPlugin`, from the prior example, version 1.2 will always be the
|
||||
version activated in a developer's Unity project.
|
||||
|
||||
Plugin creators are encouraged to adopt this library to ease integration for
|
||||
their customers. For more information about integrating EDM4U into your own
|
||||
plugin, see the [Plugin Redistribution](#plugin-redistribution) section of this
|
||||
document.
|
||||
|
||||
## Analytics
|
||||
|
||||
The External Dependency Manager for Unity plugin by default logs usage to Google
|
||||
Analytics. The purpose of the logging is to quantitatively measure the usage of
|
||||
functionality, to gather reports on integration failures and to inform future
|
||||
improvements to the developer experience of the External Dependency Manager
|
||||
plugin. Note that the analytics collected are limited to the scope of the EDM4U
|
||||
plugin’s usage.
|
||||
|
||||
For details of what is logged, please refer to the usage of
|
||||
`EditorMeasurement.Report()` in the source code.
|
||||
|
||||
## Plugin Redistribution
|
||||
|
||||
If you are a package maintainer and your package depends on EDM4U, it is highly
|
||||
recommended to use the UPM format and add EDM4U as a dependency. If you must
|
||||
include it in your `.unitypackage`, redistributing `EDM4U` inside your own
|
||||
plugin might ease the integration process for your users.
|
||||
|
||||
If you wish to redistribute `EDM4U` inside your plugin, you **must** follow
|
||||
these steps when importing the `external-dependency-manager-*.unitypackage`, and
|
||||
when exporting your own plugin package:
|
||||
|
||||
1. Import the `external-dependency-manager-*.unitypackage` into your plugin
|
||||
project by
|
||||
[running Unity from the command line](https://docs.unity3d.com/Manual/CommandLineArguments.html),
|
||||
ensuring that you add the `-gvh_disable` option.
|
||||
1. Export your plugin by
|
||||
[running Unity from the command line](https://docs.unity3d.com/Manual/CommandLineArguments.html),
|
||||
ensuring that you:
|
||||
- Include the contents of the `Assets/PlayServicesResolver` and
|
||||
`Assets/ExternalDependencyManager` directory.
|
||||
- Add the `-gvh_disable` option.
|
||||
|
||||
You **must** specify the `-gvh_disable` option in order for the Version Handler
|
||||
to work correctly!
|
||||
|
||||
For example, the following command will import the
|
||||
`external-dependency-manager-1.2.46.0.unitypackage` into the project
|
||||
`MyPluginProject` and export the entire Assets folder to
|
||||
`MyPlugin.unitypackage`:
|
||||
|
||||
```shell
|
||||
Unity -gvh_disable \
|
||||
-batchmode \
|
||||
-importPackage external-dependency-manager-1.2.46.0.unitypackage \
|
||||
-projectPath MyPluginProject \
|
||||
-exportPackage Assets MyPlugin.unitypackage \
|
||||
-quit
|
||||
```
|
||||
|
||||
### Background
|
||||
|
||||
The *Version Handler* component relies upon deferring the load of editor DLLs so
|
||||
that it can run first and determine the latest version of a plugin component to
|
||||
activate. The build of `EDM4U` plugin has Unity asset metadata that is
|
||||
configured so that the editor components are not initially enabled when it's
|
||||
imported into a Unity project. To maintain this configuration when importing the
|
||||
`external-dependency-manager.unitypackage` into a Unity plugin project, you
|
||||
*must* specify the command line option `-gvh_disable` which will prevent the
|
||||
Version Handler component from running and changing the Unity asset metadata.
|
||||
|
||||
## Building from Source
|
||||
|
||||
To build this plugin from source you need the following tools installed: * Unity
|
||||
2021 and below (with iOS and Android modules installed) * Java 11
|
||||
|
||||
You can build the plugin by running the following from your shell (Linux / OSX):
|
||||
|
||||
```shell
|
||||
./gradlew build
|
||||
|
||||
```
|
||||
|
||||
or Windows:
|
||||
|
||||
```shell
|
||||
./gradlew.bat build
|
||||
```
|
||||
|
||||
If Java 11 is not your default Java command, add
|
||||
`-Dorg.gradle.java.home=<PATH_TO_JAVA_HOME>` to the command above.
|
||||
|
||||
## Testing
|
||||
|
||||
You can run the tests by running the following from your shell (Linux / OSX):
|
||||
|
||||
```shell
|
||||
./gradlew test
|
||||
```
|
||||
|
||||
or Windows:
|
||||
|
||||
```shell
|
||||
./gradlew.bat test
|
||||
```
|
||||
|
||||
The following properties can be set to narrow down the tests to run or change
|
||||
the test run behavior.
|
||||
|
||||
* `INTERACTIVE_MODE_TESTS_ENABLED` - Default to `1`. Set to `1` to enable
|
||||
interactive mode tests, which requires GPU on the machine. Otherwise, only
|
||||
run tests in the batch mode.
|
||||
* `INCLUDE_TEST_TYPES` - Default to empty string, which means to include every
|
||||
type of the test. To narrow down the types of test to run, set this
|
||||
properties with a list of case-insensitive type strings separated by comma.
|
||||
For instance, `-PINCLUDE_TEST_TYPES="Python,NUnit"` means to include only
|
||||
Python tests and NUnit tests. See `TestTypeEnum` in `build.gradle` for
|
||||
available options.
|
||||
* `EXCLUDE_TEST_TYPES` - Default to empty string, which means to exclude none.
|
||||
To add types of tests to exclude, set this properties with a list of
|
||||
case-insensitive type strings separated by comma. For instance,
|
||||
`-PEXCLUDE_TEST_TYPES="Python,NUnit"` means to exclude Python tests and
|
||||
NUnit tests. See `TestTypeEnum` in `build.gradle` for available options.
|
||||
* `INCLUDE_TEST_MODULES` - Default to empty string, which means to include the
|
||||
tests for every modules. To narrow down modules to test, set this properties
|
||||
with a list of case-insensitive module strings separated by comma. For
|
||||
instance, `-PINCLUDE_TEST_MODULES="Tool,AndroidResolver"` means to run tests
|
||||
for tools and Android Resolver only. See `TestModuleEnum` in `build.gradle`
|
||||
for available options.
|
||||
* `EXCLUDE_TEST_MODULES` - Default to empty string, which means to exclude
|
||||
none. To add modules to exclude, set this properties with a list of
|
||||
case-insensitive module strings separated by comma. For instance,
|
||||
`-PEXCLUDE_TEST_MODULES="Tool,AndroidResolver"` means to run tests for any
|
||||
modules other than tools and Android Resolver. See `TestModuleEnum` in
|
||||
`build.gradle` for available options.
|
||||
* `EXCLUDE_TESTS` - Default to empty string, which means to exclude none. To
|
||||
add tests to exclude, set this properties with a list of case-insensitive
|
||||
test names separated by comma. For instance,
|
||||
`-PEXCLUDE_TESTS="testGenGuids,testDownloadArtifacts"` means to run tests
|
||||
except the tests with name of `testGenGuids` and `testDownloadArtifacts`.
|
||||
* `CONTINUE_ON_FAIL_FOR_TESTS_ENABLED` - Default to `1`. Set to `1` to
|
||||
continue running the next test when the current one fails. Otherwise, the
|
||||
build script stops whenever any test fails.
|
||||
|
||||
For instance, by running the following command, it only runs the Unity
|
||||
integration tests that does not requires GPU, but exclude tests for Android
|
||||
Resolver module and iOS Resolver module.
|
||||
|
||||
```shell
|
||||
./gradlew test \
|
||||
-PINTERACTIVE_MODE_TESTS_ENABLED=0 \
|
||||
-PINCLUDE_TEST_TYPES="Integration" \
|
||||
-PEXCLUDE_TEST_MODULES="AndroidResolver,iOSResolver"
|
||||
```
|
||||
|
||||
## Releasing
|
||||
|
||||
Each time a new build of this plugin is checked into the source tree you need to
|
||||
do the following:
|
||||
|
||||
* Bump the plugin version variable `pluginVersion` in `build.gradle`
|
||||
* Update `CHANGELOG.md` with the new version number and changes included in
|
||||
the release.
|
||||
* Build the release using `./gradlew release` which performs the following:
|
||||
* Updates `external-dependency-manager-*.unitypackage`
|
||||
* Copies the unpacked plugin to the `exploded` directory.
|
||||
* Updates template metadata files in the `plugin` directory. The GUIDs of
|
||||
all asset metadata is modified due to the version number change. Each
|
||||
file within the plugin is versioned to allow multiple versions of the
|
||||
plugin to be imported into a Unity project which allows the most recent
|
||||
version to be activated by the Version Handler component.
|
||||
* Create release commit using `./gradlew gitCreateReleaseCommit` which
|
||||
performs `git commit -a -m "description from CHANGELOG.md"`
|
||||
* Once the release commit is merge, tag the release using `./gradlew
|
||||
gitTagRelease` which performs the following:
|
||||
* `git tag -a pluginVersion -m "version RELEASE"` to tag the release.
|
||||
* Update tags on remote branch using `git push --tag REMOTE HEAD:master`
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8f8f1a310f5441f9598e2c40ac77058
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/README.md
|
||||
timeCreated: 1584567712
|
||||
licenseType: Pro
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
Assets/ExternalDependencyManager/Editor/1.2.179/Google.IOSResolver.dll
|
||||
Assets/ExternalDependencyManager/Editor/1.2.179/Google.IOSResolver.pdb
|
||||
Assets/ExternalDependencyManager/Editor/1.2.179/Google.JarResolver.dll
|
||||
Assets/ExternalDependencyManager/Editor/1.2.179/Google.JarResolver.pdb
|
||||
Assets/ExternalDependencyManager/Editor/1.2.179/Google.PackageManagerResolver.dll
|
||||
Assets/ExternalDependencyManager/Editor/1.2.179/Google.PackageManagerResolver.pdb
|
||||
Assets/ExternalDependencyManager/Editor/1.2.179/Google.VersionHandlerImpl.dll
|
||||
Assets/ExternalDependencyManager/Editor/1.2.179/Google.VersionHandlerImpl.pdb
|
||||
Assets/ExternalDependencyManager/Editor/CHANGELOG.md
|
||||
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll
|
||||
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.pdb
|
||||
Assets/ExternalDependencyManager/Editor/LICENSE
|
||||
Assets/ExternalDependencyManager/Editor/README.md
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53a0906dfc3143ba8bf0193c245ad230
|
||||
labels:
|
||||
- gvh
|
||||
- gvh_manifest
|
||||
- gvh_version-1.2.179
|
||||
- gvhp_exportpath-ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.179_manifest.txt
|
||||
- gvhp_manifestname-0External Dependency Manager
|
||||
- gvhp_manifestname-play-services-resolver
|
||||
timeCreated: 1474401009
|
||||
licenseType: Pro
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
sdk-intergration/Assets/MaxSdk.meta
Normal file
8
sdk-intergration/Assets/MaxSdk.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30111a133e0c14b7c85f133882f7b282
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
sdk-intergration/Assets/MaxSdk/AppLovin.meta
Normal file
8
sdk-intergration/Assets/MaxSdk/AppLovin.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4c20985b26094f70b0bc44cd95eb1ba
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
sdk-intergration/Assets/MaxSdk/AppLovin/Editor.meta
Normal file
8
sdk-intergration/Assets/MaxSdk/AppLovin/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce14de298f23c4bb198d6f1bded11d72
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin:applovin-sdk:12.6.0" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinSDK" version="12.6.0" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 746da98302dc0402aaa37e8f7bd97e77
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Editor/Dependencies.xml
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
sdk-intergration/Assets/MaxSdk/AppLovin/Plugins.meta
Normal file
8
sdk-intergration/Assets/MaxSdk/AppLovin/Plugins.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44d1cbc50e8ee4a5598c77229b695fdf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e99b4053620214bb792c53550c79838a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,35 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1db980bd612824d2097f78fd779e6051
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/Android/applovin-max-unity-plugin.aar
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
sdk-intergration/Assets/MaxSdk/AppLovin/Plugins/iOS.meta
Normal file
8
sdk-intergration/Assets/MaxSdk/AppLovin/Plugins/iOS.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 125fa3d9de30e4a089c720e502224457
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// MAUnityAdManager.h
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppLovinSDK/AppLovinSDK.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
typedef const void *MAUnityRef;
|
||||
typedef void (*ALUnityBackgroundCallback)(const char* args);
|
||||
|
||||
@interface MAUnityAdManager : NSObject
|
||||
|
||||
- (void)initializeSdkWithConfiguration:(ALSdkInitializationConfiguration *)initConfig andCompletionHandler:(ALSdkInitializationCompletionHandler)completionHandler;
|
||||
|
||||
- (void)createBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier atPosition:(nullable NSString *)bannerPosition;
|
||||
- (void)createBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset;
|
||||
- (void)loadBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)setBannerBackgroundColorForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier hexColorCode:(nullable NSString *)hexColorCode;
|
||||
- (void)setBannerPlacement:(nullable NSString *)placement forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)startBannerAutoRefreshForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)stopBannerAutoRefreshForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)setBannerExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setBannerLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
- (void)setBannerCustomData:(nullable NSString *)customData forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)setBannerWidth:(CGFloat)width forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)updateBannerPosition:(nullable NSString *)bannerPosition forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)updateBannerPosition:(CGFloat)xOffset y:(CGFloat)yOffset forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)destroyBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)hideBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (NSString *)bannerLayoutForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
+ (CGFloat)adaptiveBannerHeightForWidth:(CGFloat)width;
|
||||
|
||||
- (void)createMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier atPosition:(nullable NSString *)mrecPosition;
|
||||
- (void)createMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset;
|
||||
- (void)loadMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)setMRecPlacement:(nullable NSString *)placement forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)startMRecAutoRefreshForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)stopMRecAutoRefreshForAdUnitIdentifier:(nullable NSString *)adUnitIdentifer;
|
||||
- (void)setMRecExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setMRecLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
- (void)setMRecCustomData:(nullable NSString *)customData forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)destroyMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)hideMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)updateMRecPosition:(nullable NSString *)mrecPosition forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)updateMRecPosition:(CGFloat)xOffset y:(CGFloat)yOffset forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (NSString *)mrecLayoutForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
|
||||
- (void)loadInterstitialWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (BOOL)isInterstitialReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showInterstitialWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData;
|
||||
- (void)setInterstitialExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setInterstitialLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
|
||||
- (void)loadAppOpenAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (BOOL)isAppOpenAdReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showAppOpenAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData;
|
||||
- (void)setAppOpenAdExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setAppOpenAdLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
|
||||
- (void)loadRewardedAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (BOOL)isRewardedAdReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showRewardedAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData;
|
||||
- (void)setRewardedAdExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setRewardedAdLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
|
||||
- (void)loadRewardedInterstitialAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (BOOL)isRewardedInterstitialAdReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showRewardedInterstitialAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData;
|
||||
- (void)setRewardedInterstitialAdExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setRewardedInterstitialAdLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
|
||||
// Event Tracking
|
||||
- (void)trackEvent:(nullable NSString *)event parameters:(nullable NSString *)parameters;
|
||||
|
||||
// Ad Info
|
||||
- (NSString *)adInfoForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
|
||||
// Ad Value
|
||||
- (NSString *)adValueForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier withKey:(nullable NSString *)key;
|
||||
|
||||
// User Service
|
||||
- (void)didDismissUserConsentDialog;
|
||||
|
||||
// CMP Service
|
||||
- (void)showCMPForExistingUser;
|
||||
|
||||
// Utils
|
||||
+ (NSString *)serializeParameters:(NSDictionary<NSString *, id> *)dict;
|
||||
+ (NSDictionary<NSString *, id> *)deserializeParameters:(nullable NSString *)serialized;
|
||||
|
||||
+ (void)setUnityBackgroundCallback:(ALUnityBackgroundCallback)unityBackgroundCallback;
|
||||
|
||||
/**
|
||||
* Creates an instance of @c MAUnityAdManager if needed and returns the singleton instance.
|
||||
*/
|
||||
+ (instancetype)shared;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,115 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4209563f82b8a4f7dabf03705ab761c6
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.h
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
Exclude tvOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,109 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2973e70bd2fa74984b35aea07ae9db52
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.m
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
Exclude tvOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1169
sdk-intergration/Assets/MaxSdk/AppLovin/Plugins/iOS/MAUnityPlugin.mm
Normal file
1169
sdk-intergration/Assets/MaxSdk/AppLovin/Plugins/iOS/MAUnityPlugin.mm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,109 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e373ed7168b243e6b706e991ab5a643
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/iOS/MAUnityPlugin.mm
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
Exclude tvOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
11
sdk-intergration/Assets/MaxSdk/Mediation.meta
Normal file
11
sdk-intergration/Assets/MaxSdk/Mediation.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcf2020c4018447c9b91170c0f62d799
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Mediation
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,2 @@
|
||||
A placeholder file to make sure that the Mediation folder asset is exported with the base plugin.
|
||||
This ensures that the adapters are imported into this directory even when the plugin has been moved to a different folder.
|
||||
@@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a8f83e97729443c86120be3bb24190d
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Mediation/MediationAdapters.txt
|
||||
timeCreated: 1609308536
|
||||
8
sdk-intergration/Assets/MaxSdk/Prefabs.meta
Normal file
8
sdk-intergration/Assets/MaxSdk/Prefabs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5c56269cce4b41f2ad38fce6fa492c2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
402
sdk-intergration/Assets/MaxSdk/Prefabs/BannerBottom.prefab
Normal file
402
sdk-intergration/Assets/MaxSdk/Prefabs/BannerBottom.prefab
Normal file
@@ -0,0 +1,402 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3149432657757030138
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5965516886513985157}
|
||||
- component: {fileID: 3167928293195730454}
|
||||
- component: {fileID: 6048907697713132302}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5965516886513985157
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4118862295226300947}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 84}
|
||||
m_SizeDelta: {x: 0, y: 168}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3167928293195730454
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6048907697713132302
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &3829518492429360636
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4118862295226300947}
|
||||
- component: {fileID: 5582763645243389146}
|
||||
- component: {fileID: 1436650035481827287}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4118862295226300947
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 5084927109723455527}
|
||||
- {fileID: 8189983859356672495}
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 1}
|
||||
m_AnchorMax: {x: 0.5, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -50}
|
||||
m_SizeDelta: {x: 640, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5582763645243389146
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &1436650035481827287
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &4772536868390647122
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8189983859356672495}
|
||||
- component: {fileID: 7216515036998124610}
|
||||
- component: {fileID: 3801875349924125266}
|
||||
m_Layer: 5
|
||||
m_Name: InfoText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &8189983859356672495
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4772536868390647122}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4118862295226300947}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 3}
|
||||
m_SizeDelta: {x: 0, y: -6}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7216515036998124610
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4772536868390647122}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3801875349924125266
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4772536868390647122}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.29411766, g: 0.29411766, b: 0.29411766, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 18
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 7
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Actual banner size may vary on mobile devices
|
||||
--- !u!1 &7742712311334970126
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3413013686078446151}
|
||||
- component: {fileID: 2511819091764556577}
|
||||
- component: {fileID: 2638196187645015298}
|
||||
- component: {fileID: 633018877563332563}
|
||||
m_Layer: 5
|
||||
m_Name: BannerBottom
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3413013686078446151
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 5965516886513985157}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2511819091764556577
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 500
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2638196187645015298
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &633018877563332563
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!1 &8436952342056443077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5084927109723455527}
|
||||
- component: {fileID: 7267203896389005665}
|
||||
- component: {fileID: 5500603550844857255}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5084927109723455527
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4118862295226300947}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -4}
|
||||
m_SizeDelta: {x: 0, y: -8}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7267203896389005665
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5500603550844857255
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 26
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 0
|
||||
m_MaxSize: 71
|
||||
m_Alignment: 1
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: MAX Banner Ad
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54c062c0526b148efa2ea2e9489b3aa0
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs/BannerBottom.prefab
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
402
sdk-intergration/Assets/MaxSdk/Prefabs/BannerTop.prefab
Normal file
402
sdk-intergration/Assets/MaxSdk/Prefabs/BannerTop.prefab
Normal file
@@ -0,0 +1,402 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3149432657757030138
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5965516886513985157}
|
||||
- component: {fileID: 3167928293195730454}
|
||||
- component: {fileID: 6048907697713132302}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5965516886513985157
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4118862295226300947}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -50}
|
||||
m_SizeDelta: {x: 0, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3167928293195730454
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6048907697713132302
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &3829518492429360636
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4118862295226300947}
|
||||
- component: {fileID: 5582763645243389146}
|
||||
- component: {fileID: 1436650035481827287}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4118862295226300947
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 5084927109723455527}
|
||||
- {fileID: 7429934296583149777}
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0}
|
||||
m_AnchorMax: {x: 0.5, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 640, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5582763645243389146
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &1436650035481827287
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &5625059666589051168
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7429934296583149777}
|
||||
- component: {fileID: 6576623406533516677}
|
||||
- component: {fileID: 5405475098690228567}
|
||||
m_Layer: 5
|
||||
m_Name: InfoText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &7429934296583149777
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5625059666589051168}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4118862295226300947}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 3}
|
||||
m_SizeDelta: {x: 0, y: -6}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6576623406533516677
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5625059666589051168}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5405475098690228567
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5625059666589051168}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.29411766, g: 0.29411766, b: 0.29411766, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 18
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 7
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Actual banner size may vary on mobile devices
|
||||
--- !u!1 &7742712311334970126
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3413013686078446151}
|
||||
- component: {fileID: 2511819091764556577}
|
||||
- component: {fileID: 2638196187645015298}
|
||||
- component: {fileID: 633018877563332563}
|
||||
m_Layer: 5
|
||||
m_Name: BannerTop
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3413013686078446151
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 5965516886513985157}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2511819091764556577
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 500
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2638196187645015298
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &633018877563332563
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!1 &8436952342056443077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5084927109723455527}
|
||||
- component: {fileID: 7267203896389005665}
|
||||
- component: {fileID: 5500603550844857255}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5084927109723455527
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4118862295226300947}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -4}
|
||||
m_SizeDelta: {x: 0, y: -8}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7267203896389005665
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5500603550844857255
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 26
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 0
|
||||
m_MaxSize: 71
|
||||
m_Alignment: 1
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: MAX Banner Ad
|
||||
10
sdk-intergration/Assets/MaxSdk/Prefabs/BannerTop.prefab.meta
Normal file
10
sdk-intergration/Assets/MaxSdk/Prefabs/BannerTop.prefab.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6521750c87fd14f709d09a1e38ffde47
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs/BannerTop.prefab
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
523
sdk-intergration/Assets/MaxSdk/Prefabs/Interstitial.prefab
Normal file
523
sdk-intergration/Assets/MaxSdk/Prefabs/Interstitial.prefab
Normal file
@@ -0,0 +1,523 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3149432657757030138
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5965516886513985157}
|
||||
- component: {fileID: 3167928293195730454}
|
||||
- component: {fileID: 6048907697713132302}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5965516886513985157
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 5084927109723455527}
|
||||
- {fileID: 8681486192829137138}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3167928293195730454
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6048907697713132302
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.88235295, g: 0.88235295, b: 0.88235295, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &5668641863723001099
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8681486192829137138}
|
||||
- component: {fileID: 8217482188885705039}
|
||||
- component: {fileID: 3177344817093501532}
|
||||
- component: {fileID: 4415703054918645549}
|
||||
m_Layer: 5
|
||||
m_Name: MaxInterstitialCloseButton
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &8681486192829137138
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 763654547095120985}
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -200, y: -100}
|
||||
m_SizeDelta: {x: 250, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8217482188885705039
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3177344817093501532
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!114 &4415703054918645549
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3177344817093501532}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &6155160063690407013
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1672649117655046507}
|
||||
- component: {fileID: 2484422763836779945}
|
||||
- component: {fileID: 1332063313327512547}
|
||||
- component: {fileID: 9160434328933334999}
|
||||
m_Layer: 5
|
||||
m_Name: EventSystem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1672649117655046507
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6155160063690407013}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &2484422763836779945
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6155160063690407013}
|
||||
m_Enabled: 0
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_FirstSelected: {fileID: 0}
|
||||
m_sendNavigationEvents: 1
|
||||
m_DragThreshold: 10
|
||||
--- !u!114 &1332063313327512547
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6155160063690407013}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalAxis: Horizontal
|
||||
m_VerticalAxis: Vertical
|
||||
m_SubmitButton: Submit
|
||||
m_CancelButton: Cancel
|
||||
m_InputActionsPerSecond: 10
|
||||
m_RepeatDelay: 0.5
|
||||
m_ForceModuleActive: 0
|
||||
--- !u!114 &9160434328933334999
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6155160063690407013}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e0acf281ba86b4929a6942ecd998395b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &6462551400748024402
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 763654547095120985}
|
||||
- component: {fileID: 6719360953530842803}
|
||||
- component: {fileID: 4616290306121202327}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &763654547095120985
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8681486192829137138}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6719360953530842803
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &4616290306121202327
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 40
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 4
|
||||
m_MaxSize: 47
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Close
|
||||
--- !u!1 &7742712311334970126
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3413013686078446151}
|
||||
- component: {fileID: 2511819091764556577}
|
||||
- component: {fileID: 2638196187645015298}
|
||||
- component: {fileID: 633018877563332563}
|
||||
m_Layer: 5
|
||||
m_Name: Interstitial
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3413013686078446151
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 5965516886513985157}
|
||||
- {fileID: 1672649117655046507}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2511819091764556577
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 999
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2638196187645015298
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &633018877563332563
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!1 &8436952342056443077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5084927109723455527}
|
||||
- component: {fileID: 7267203896389005665}
|
||||
- component: {fileID: 5500603550844857255}
|
||||
m_Layer: 5
|
||||
m_Name: MaxInterstitialTitle
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5084927109723455527
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 300}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7267203896389005665
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5500603550844857255
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 50
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 0
|
||||
m_MaxSize: 71
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: MAX Interstitial Ad
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fc0c2627ce8a4490b8e319326f8a535
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs/Interstitial.prefab
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
795
sdk-intergration/Assets/MaxSdk/Prefabs/Rewarded.prefab
Normal file
795
sdk-intergration/Assets/MaxSdk/Prefabs/Rewarded.prefab
Normal file
@@ -0,0 +1,795 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &288832541099509301
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6736833388881778366}
|
||||
- component: {fileID: 738723989743429661}
|
||||
- component: {fileID: 3366016410383180441}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &6736833388881778366
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 288832541099509301}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2219183527695013266}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &738723989743429661
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 288832541099509301}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3366016410383180441
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 288832541099509301}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 35
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 3
|
||||
m_MaxSize: 48
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 'Grant Reward
|
||||
|
||||
(5 coins)'
|
||||
--- !u!1 &2620135977249264498
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3035265698078104281}
|
||||
- component: {fileID: 7277178523579209441}
|
||||
- component: {fileID: 8085319417655039649}
|
||||
m_Layer: 5
|
||||
m_Name: MaxRewardStatus
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3035265698078104281
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2620135977249264498}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: -250}
|
||||
m_SizeDelta: {x: 0, y: 200}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7277178523579209441
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2620135977249264498}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &8085319417655039649
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2620135977249264498}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 40
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 69
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Reward not yet granted.
|
||||
--- !u!1 &3096027301306273604
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2219183527695013266}
|
||||
- component: {fileID: 3687429596110321440}
|
||||
- component: {fileID: 3757577222601629632}
|
||||
- component: {fileID: 87227930114769318}
|
||||
m_Layer: 5
|
||||
m_Name: MaxRewardButton
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2219183527695013266
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3096027301306273604}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 6736833388881778366}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: -150}
|
||||
m_SizeDelta: {x: 300, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3687429596110321440
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3096027301306273604}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3757577222601629632
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3096027301306273604}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!114 &87227930114769318
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3096027301306273604}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3757577222601629632}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &3149432657757030138
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5965516886513985157}
|
||||
- component: {fileID: 3167928293195730454}
|
||||
- component: {fileID: 6048907697713132302}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5965516886513985157
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 5084927109723455527}
|
||||
- {fileID: 8681486192829137138}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3167928293195730454
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6048907697713132302
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.88235295, g: 0.88235295, b: 0.88235295, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &4010021198786516228
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3074011789293951898}
|
||||
- component: {fileID: 301935380126337495}
|
||||
- component: {fileID: 535359239537776472}
|
||||
- component: {fileID: 1463999766055390634}
|
||||
m_Layer: 5
|
||||
m_Name: EventSystem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3074011789293951898
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4010021198786516228}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &301935380126337495
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4010021198786516228}
|
||||
m_Enabled: 0
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_FirstSelected: {fileID: 0}
|
||||
m_sendNavigationEvents: 1
|
||||
m_DragThreshold: 10
|
||||
--- !u!114 &535359239537776472
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4010021198786516228}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalAxis: Horizontal
|
||||
m_VerticalAxis: Vertical
|
||||
m_SubmitButton: Submit
|
||||
m_CancelButton: Cancel
|
||||
m_InputActionsPerSecond: 10
|
||||
m_RepeatDelay: 0.5
|
||||
m_ForceModuleActive: 0
|
||||
--- !u!114 &1463999766055390634
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4010021198786516228}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e0acf281ba86b4929a6942ecd998395b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &5668641863723001099
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8681486192829137138}
|
||||
- component: {fileID: 8217482188885705039}
|
||||
- component: {fileID: 3177344817093501532}
|
||||
- component: {fileID: 4415703054918645549}
|
||||
m_Layer: 5
|
||||
m_Name: MaxRewardedCloseButton
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &8681486192829137138
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 763654547095120985}
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -200, y: -100}
|
||||
m_SizeDelta: {x: 250, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8217482188885705039
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3177344817093501532
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!114 &4415703054918645549
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3177344817093501532}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &6462551400748024402
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 763654547095120985}
|
||||
- component: {fileID: 6719360953530842803}
|
||||
- component: {fileID: 4616290306121202327}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &763654547095120985
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8681486192829137138}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6719360953530842803
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &4616290306121202327
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 40
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 4
|
||||
m_MaxSize: 47
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Close
|
||||
--- !u!1 &7742712311334970126
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3413013686078446151}
|
||||
- component: {fileID: 2511819091764556577}
|
||||
- component: {fileID: 2638196187645015298}
|
||||
- component: {fileID: 633018877563332563}
|
||||
m_Layer: 5
|
||||
m_Name: Rewarded
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3413013686078446151
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 5965516886513985157}
|
||||
- {fileID: 3035265698078104281}
|
||||
- {fileID: 2219183527695013266}
|
||||
- {fileID: 3074011789293951898}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2511819091764556577
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 999
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2638196187645015298
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &633018877563332563
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!1 &8436952342056443077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5084927109723455527}
|
||||
- component: {fileID: 7267203896389005665}
|
||||
- component: {fileID: 5500603550844857255}
|
||||
m_Layer: 5
|
||||
m_Name: MaxRewardTitle
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5084927109723455527
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 300}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7267203896389005665
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5500603550844857255
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 50
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 0
|
||||
m_MaxSize: 71
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: MAX Rewarded Ad
|
||||
10
sdk-intergration/Assets/MaxSdk/Prefabs/Rewarded.prefab.meta
Normal file
10
sdk-intergration/Assets/MaxSdk/Prefabs/Rewarded.prefab.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a28c1544d6f094d5eafc8da2343c9119
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs/Rewarded.prefab
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
sdk-intergration/Assets/MaxSdk/Resources.meta
Normal file
8
sdk-intergration/Assets/MaxSdk/Resources.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3dcc66076f7f149d0b7cec600661f368
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ebc0ba1b5ef6b4a6b9dd53d7eadfea16, type: 3}
|
||||
m_Name: AppLovinSettings
|
||||
m_EditorClassIdentifier:
|
||||
qualityServiceEnabled: 1
|
||||
sdkKey: OmDRO8whS_xJT0fChdR0d_v0wqSKGaEhzs6W8SKO-Lspt2WA_ZpCmlTTHBVTEEDMET5hw4vN9SmtK5x4_eEHsR
|
||||
setAttributionReportEndpoint: 0
|
||||
addApsSkAdNetworkIds: 0
|
||||
customGradleVersionUrl:
|
||||
customGradleToolsVersion:
|
||||
consentFlowEnabled: 0
|
||||
consentFlowPlatform: 0
|
||||
consentFlowPrivacyPolicyUrl:
|
||||
consentFlowTermsOfServiceUrl:
|
||||
userTrackingUsageDescriptionEn:
|
||||
userTrackingUsageLocalizationEnabled: 0
|
||||
userTrackingUsageDescriptionDe:
|
||||
userTrackingUsageDescriptionEs:
|
||||
userTrackingUsageDescriptionFr:
|
||||
userTrackingUsageDescriptionJa:
|
||||
userTrackingUsageDescriptionKo:
|
||||
userTrackingUsageDescriptionZhHans:
|
||||
userTrackingUsageDescriptionZhHant: default_localization
|
||||
adMobAndroidAppId:
|
||||
adMobIosAppId:
|
||||
showInternalSettingsInIntegrationManager: 0
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25a56c4f35ecd4cb6a23b6c60ad64b89
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
sdk-intergration/Assets/MaxSdk/Resources/Images.meta
Normal file
8
sdk-intergration/Assets/MaxSdk/Resources/Images.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f910dbfcaedf94ec98c031489a7f6797
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
sdk-intergration/Assets/MaxSdk/Resources/Images/alert_icon.png
Normal file
BIN
sdk-intergration/Assets/MaxSdk/Resources/Images/alert_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,94 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 572fee4574afa4f6dbf2846e0c152fe8
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources/Images/alert_icon.png
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
sdk-intergration/Assets/MaxSdk/Resources/Images/uninstall_icon.png
Executable file
BIN
sdk-intergration/Assets/MaxSdk/Resources/Images/uninstall_icon.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 159 B |
@@ -0,0 +1,94 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d24994f48fdd0430692e3d49279cd782
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources/Images/uninstall_icon.png
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
sdk-intergration/Assets/MaxSdk/Resources/Images/warning_icon.png
Normal file
BIN
sdk-intergration/Assets/MaxSdk/Resources/Images/warning_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 959 B |
@@ -0,0 +1,91 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b504c956e7ed744b6b0e7f014e1cac5a
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources/Images/warning_icon.png
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
sdk-intergration/Assets/MaxSdk/Scripts.meta
Normal file
8
sdk-intergration/Assets/MaxSdk/Scripts.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a983cd3d5fdeb444d98b53c332a04b5e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e01816bc45c944d03afb95d035caf0e1
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0da229e279400497786c39933fe02e52
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,164 @@
|
||||
//
|
||||
// AppLovinAutoUpdater.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 1/27/20.
|
||||
// Copyright © 2020 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles auto updates for AppLovin MAX plugin.
|
||||
/// </summary>
|
||||
public class AppLovinAutoUpdater
|
||||
{
|
||||
public const string KeyAutoUpdateEnabled = "com.applovin.auto_update_enabled";
|
||||
private const string KeyLastUpdateCheckTime = "com.applovin.last_update_check_time_v2"; // Updated to v2 to force adapter version checks in plugin version 3.1.10.
|
||||
private static readonly DateTime EpochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
private static readonly int SecondsInADay = (int) TimeSpan.FromDays(1).TotalSeconds;
|
||||
|
||||
// TODO: Make this list dynamic.
|
||||
public static readonly Dictionary<string, string> MinAdapterVersions = new Dictionary<string, string>()
|
||||
{
|
||||
{"ADMOB_NETWORK", "android_19.3.0.3_ios_7.65.0.0"},
|
||||
{"CHARTBOOST_NETWORK", "android_8.1.0.7_ios_8.2.1.3"},
|
||||
{"FACEBOOK_MEDIATE", "android_6.0.0.1_ios_6.0.0.3"},
|
||||
{"FYBER_NETWORK", "android_7.7.0.1_ios_7.6.4.1"},
|
||||
{"GOOGLE_AD_MANAGER_NETWORK", "android_19.3.0.3_ios_7.65.0.0"},
|
||||
{"INMOBI_NETWORK", "android_9.0.9.2_ios_9.0.7.9"},
|
||||
{"IRONSOURCE_NETWORK", "android_7.0.1.1.1_ios_7.0.1.0.1"},
|
||||
{"MYTARGET_NETWORK", "android_5.9.1.2_ios_5.7.5.1"},
|
||||
{"SMAATO_NETWORK", "android_21.5.2.5_ios_21.5.2.3"},
|
||||
{"TIKTOK_NETWORK", "android_3.1.0.1.6_ios_3.2.5.1.1"},
|
||||
{"UNITY_NETWORK", "android_3.4.8.2_ios_3.4.8.2"},
|
||||
{"VUNGLE_NETWORK", "android_6.7.1.2_ios_6.7.1.3"},
|
||||
{"YANDEX_NETWORK", "android_2.170.2_ios_2.18.0.1"}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a new version of the plugin is available and prompts the user to update if one is available.
|
||||
/// </summary>
|
||||
public static void Update()
|
||||
{
|
||||
var now = (int) (DateTime.UtcNow - EpochTime).TotalSeconds;
|
||||
if (EditorPrefs.HasKey(KeyLastUpdateCheckTime))
|
||||
{
|
||||
var elapsedTime = now - EditorPrefs.GetInt(KeyLastUpdateCheckTime);
|
||||
|
||||
// Check if we have checked for a new version in the last 24 hrs and skip update if we have.
|
||||
if (elapsedTime < SecondsInADay) return;
|
||||
}
|
||||
|
||||
// Update last checked time.
|
||||
EditorPrefs.SetInt(KeyLastUpdateCheckTime, now);
|
||||
|
||||
// Load the plugin data
|
||||
AppLovinEditorCoroutine.StartCoroutine(AppLovinIntegrationManager.Instance.LoadPluginData(data =>
|
||||
{
|
||||
if (data == null) return;
|
||||
|
||||
ShowPluginUpdateDialogIfNeeded(data);
|
||||
ShowNetworkAdaptersUpdateDialogIfNeeded(data.MediatedNetworks);
|
||||
ShowGoogleNetworkAdaptersUpdateDialogIfNeeded(data.MediatedNetworks);
|
||||
}));
|
||||
}
|
||||
|
||||
private static void ShowPluginUpdateDialogIfNeeded(PluginData data)
|
||||
{
|
||||
// Check if publisher has disabled auto update.
|
||||
if (!EditorPrefs.GetBool(KeyAutoUpdateEnabled, true)) return;
|
||||
|
||||
// Check if the current and latest version are the same or if the publisher is on a newer version (on beta). If so, skip update.
|
||||
var comparison = data.AppLovinMax.CurrentToLatestVersionComparisonResult;
|
||||
if (comparison == MaxSdkUtils.VersionComparisonResult.Equal || comparison == MaxSdkUtils.VersionComparisonResult.Greater) return;
|
||||
|
||||
// A new version of the plugin is available. Show a dialog to the publisher.
|
||||
var option = EditorUtility.DisplayDialogComplex(
|
||||
"AppLovin MAX Plugin Update",
|
||||
"A new version of AppLovin MAX plugin is available for download. Update now?",
|
||||
"Download",
|
||||
"Not Now",
|
||||
"Don't Ask Again");
|
||||
|
||||
if (option == 0) // Download
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Downloading plugin...");
|
||||
AppLovinIntegrationManager.downloadPluginProgressCallback = AppLovinIntegrationManagerWindow.OnDownloadPluginProgress;
|
||||
AppLovinEditorCoroutine.StartCoroutine(AppLovinIntegrationManager.Instance.DownloadPlugin(data.AppLovinMax));
|
||||
}
|
||||
else if (option == 1) // Not Now
|
||||
{
|
||||
// Do nothing
|
||||
MaxSdkLogger.UserDebug("Update postponed.");
|
||||
}
|
||||
else if (option == 2) // Don't Ask Again
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Auto Update disabled. You can enable it again from the AppLovin Integration Manager");
|
||||
EditorPrefs.SetBool(KeyAutoUpdateEnabled, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShowNetworkAdaptersUpdateDialogIfNeeded(Network[] networks)
|
||||
{
|
||||
var networksToUpdate = networks.Where(network => network.RequiresUpdate).ToList();
|
||||
|
||||
// If all networks are above the required version, do nothing.
|
||||
if (networksToUpdate.Count <= 0) return;
|
||||
|
||||
// We found a few adapters that are not compatible with the current SDK, show alert.
|
||||
var message = "The following network adapters are not compatible with the current version of AppLovin MAX Plugin:\n";
|
||||
foreach (var networkName in networksToUpdate)
|
||||
{
|
||||
message += "\n- ";
|
||||
message += networkName.DisplayName + " (Requires " + MinAdapterVersions[networkName.Name] + " or newer)";
|
||||
}
|
||||
|
||||
message += "\n\nPlease update them to the latest versions to avoid any issues.";
|
||||
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog(message);
|
||||
}
|
||||
|
||||
private static void ShowGoogleNetworkAdaptersUpdateDialogIfNeeded(Network[] networks)
|
||||
{
|
||||
// AdMob and GAM use the same SDKs so their adapters should use the same underlying SDK version.
|
||||
var googleNetwork = networks.FirstOrDefault(network => network.Name.Equals("ADMOB_NETWORK"));
|
||||
var googleAdManagerNetwork = networks.FirstOrDefault(network => network.Name.Equals("GOOGLE_AD_MANAGER_NETWORK"));
|
||||
|
||||
// If both AdMob and GAM are not integrated, do nothing.
|
||||
if (googleNetwork == null || string.IsNullOrEmpty(googleNetwork.CurrentVersions.Unity) ||
|
||||
googleAdManagerNetwork == null || string.IsNullOrEmpty(googleAdManagerNetwork.CurrentVersions.Unity)) return;
|
||||
|
||||
var isAndroidVersionCompatible = GoogleNetworkAdaptersCompatible(googleNetwork.CurrentVersions.Android, googleAdManagerNetwork.CurrentVersions.Android, "19.8.0.0");
|
||||
var isIosVersionCompatible = GoogleNetworkAdaptersCompatible(googleNetwork.CurrentVersions.Ios, googleAdManagerNetwork.CurrentVersions.Ios, "8.0.0.0");
|
||||
|
||||
if (isAndroidVersionCompatible && isIosVersionCompatible) return;
|
||||
|
||||
var message = "You may see unexpected errors if you use different versions of the AdMob and Google Ad Manager adapter SDKs. " +
|
||||
"AdMob and Google Ad Manager share the same SDKs.\n\n" +
|
||||
"You can be sure that you are using the same SDK for both if the first three numbers in each adapter version match.";
|
||||
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog(message);
|
||||
}
|
||||
|
||||
private static bool GoogleNetworkAdaptersCompatible(string googleVersion, string googleAdManagerVersion, string breakingVersion)
|
||||
{
|
||||
var googleResult = MaxSdkUtils.CompareVersions(googleVersion, breakingVersion);
|
||||
var googleAdManagerResult = MaxSdkUtils.CompareVersions(googleAdManagerVersion, breakingVersion);
|
||||
|
||||
// If one is less than the breaking version and the other is not, they are not compatible.
|
||||
if (googleResult == MaxSdkUtils.VersionComparisonResult.Lesser &&
|
||||
googleAdManagerResult != MaxSdkUtils.VersionComparisonResult.Lesser) return false;
|
||||
|
||||
if (googleAdManagerResult == MaxSdkUtils.VersionComparisonResult.Lesser &&
|
||||
googleResult != MaxSdkUtils.VersionComparisonResult.Lesser) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bcdd5226273242c5bd9ec79568202e6
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinAutoUpdater.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// AppLovinBuildPostProcessor.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 10/30/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_IOS || UNITY_IPHONE
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class to run command line tools.
|
||||
///
|
||||
/// TODO: Currently only supports shell (Linux). Add support for Windows machines.
|
||||
/// </summary>
|
||||
public class AppLovinCommandLine
|
||||
{
|
||||
/// <summary>
|
||||
/// Result obtained by running a command line command.
|
||||
/// </summary>
|
||||
public class Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Standard output stream from command line.
|
||||
/// </summary>
|
||||
public string StandardOutput;
|
||||
|
||||
/// <summary>
|
||||
/// Standard error stream from command line.
|
||||
/// </summary>
|
||||
public string StandardError;
|
||||
|
||||
/// <summary>
|
||||
/// Exit code returned from command line.
|
||||
/// </summary>
|
||||
public int ExitCode;
|
||||
|
||||
/// <summary>
|
||||
/// The description of the result that can be used for error logging.
|
||||
/// </summary>
|
||||
public string Message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a command line tool using the provided <see cref="toolPath"/> and <see cref="arguments"/>.
|
||||
/// </summary>
|
||||
/// <param name="toolPath">The tool path to run</param>
|
||||
/// <param name="arguments">The arguments to be passed to the command line tool</param>
|
||||
/// <param name="workingDirectory">The directory from which to run this command.</param>
|
||||
/// <returns></returns>
|
||||
public static Result Run(string toolPath, string arguments, string workingDirectory)
|
||||
{
|
||||
var stdoutFileName = Path.GetTempFileName();
|
||||
var stderrFileName = Path.GetTempFileName();
|
||||
|
||||
var process = new Process();
|
||||
process.StartInfo.UseShellExecute = true;
|
||||
process.StartInfo.CreateNoWindow = false;
|
||||
process.StartInfo.RedirectStandardInput = false;
|
||||
process.StartInfo.RedirectStandardOutput = false;
|
||||
process.StartInfo.RedirectStandardError = false;
|
||||
|
||||
process.StartInfo.WorkingDirectory = workingDirectory;
|
||||
process.StartInfo.FileName = "bash";
|
||||
process.StartInfo.Arguments = string.Format("-l -c '\"{0}\" {1} 1> {2} 2> {3}'", toolPath, arguments, stdoutFileName, stderrFileName);
|
||||
process.Start();
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
var stdout = File.ReadAllText(stdoutFileName);
|
||||
var stderr = File.ReadAllText(stderrFileName);
|
||||
|
||||
File.Delete(stdoutFileName);
|
||||
File.Delete(stderrFileName);
|
||||
|
||||
var result = new Result();
|
||||
result.StandardOutput = stdout;
|
||||
result.StandardError = stderr;
|
||||
result.ExitCode = process.ExitCode;
|
||||
|
||||
var messagePrefix = result.ExitCode == 0 ? "Command executed successfully" : "Failed to run command";
|
||||
result.Message = string.Format("{0}: '{1} {2}'\nstdout: {3}\nstderr: {4}\nExit code: {5}", messagePrefix, toolPath, arguments, stdout, stderr, process.ExitCode);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d0aa55f9a7d2440f871dfb256372a33
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinCommandLine.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// AppLovinEditorCoroutine.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 7/25/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// A coroutine that can update based on editor application update.
|
||||
/// </summary>
|
||||
public class AppLovinEditorCoroutine
|
||||
{
|
||||
/// <summary>
|
||||
/// Keeps track of the coroutine currently running.
|
||||
/// </summary>
|
||||
private IEnumerator enumerator;
|
||||
|
||||
/// <summary>
|
||||
/// Keeps track of coroutines that have yielded to the current enumerator.
|
||||
/// </summary>
|
||||
private readonly List<IEnumerator> history = new List<IEnumerator>();
|
||||
|
||||
private AppLovinEditorCoroutine(IEnumerator enumerator)
|
||||
{
|
||||
this.enumerator = enumerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and starts a coroutine.
|
||||
/// </summary>
|
||||
/// <param name="enumerator">The coroutine to be started</param>
|
||||
/// <returns>The coroutine that has been started.</returns>
|
||||
public static AppLovinEditorCoroutine StartCoroutine(IEnumerator enumerator)
|
||||
{
|
||||
var coroutine = new AppLovinEditorCoroutine(enumerator);
|
||||
coroutine.Start();
|
||||
return coroutine;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EditorApplication.update += OnEditorUpdate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the coroutine.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (EditorApplication.update == null) return;
|
||||
|
||||
EditorApplication.update -= OnEditorUpdate;
|
||||
}
|
||||
|
||||
private void OnEditorUpdate()
|
||||
{
|
||||
if (enumerator.MoveNext())
|
||||
{
|
||||
// If there is a coroutine to yield for inside the coroutine, add the initial one to history and continue the second one
|
||||
if (enumerator.Current is IEnumerator)
|
||||
{
|
||||
history.Add(enumerator);
|
||||
enumerator = (IEnumerator) enumerator.Current;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current coroutine has ended, check if we have more coroutines in history to be run.
|
||||
if (history.Count == 0)
|
||||
{
|
||||
// No more coroutines to run, stop updating.
|
||||
Stop();
|
||||
}
|
||||
// Step out and finish the code in the coroutine that yielded to it
|
||||
else
|
||||
{
|
||||
var index = history.Count - 1;
|
||||
enumerator = history[index];
|
||||
history.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95747c688378548eeb92aeb528ac96ff
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinEditorCoroutine.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,141 @@
|
||||
//
|
||||
// MaxInitialization.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Thomas So on 5/24/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using AppLovinMax.Scripts.IntegrationManager.Editor;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class AppLovinInitialize
|
||||
{
|
||||
private static readonly List<string> ObsoleteNetworks = new List<string>
|
||||
{
|
||||
"AdColony",
|
||||
"Criteo",
|
||||
"Nend",
|
||||
"Snap",
|
||||
"Tapjoy",
|
||||
"VerizonAds",
|
||||
"VoodooAds"
|
||||
};
|
||||
|
||||
private static readonly List<string> ObsoleteFileExportPathsToDelete = new List<string>
|
||||
{
|
||||
// The `MaxSdk/Scripts/Editor` folder contents have been moved into `MaxSdk/Scripts/IntegrationManager/Editor`.
|
||||
"MaxSdk/Scripts/Editor",
|
||||
"MaxSdk/Scripts/Editor.meta",
|
||||
|
||||
// The `EventSystemChecker` has been renamed to `MaxEventSystemChecker`.
|
||||
"MaxSdk/Scripts/EventSystemChecker.cs",
|
||||
"MaxSdk/Scripts/EventSystemChecker.cs.meta",
|
||||
|
||||
// Google AdMob adapter pre/post process scripts. The logic has been migrated to the main plugin.
|
||||
"MaxSdk/Mediation/Google/Editor/MaxGoogleInitialize.cs",
|
||||
"MaxSdk/Mediation/Google/Editor/MaxGoogleInitialize.cs.meta",
|
||||
"MaxSdk/Mediation/Google/Editor/MaxMediationGoogleUtils.cs",
|
||||
"MaxSdk/Mediation/Google/Editor/MaxMediationGoogleUtils.cs.meta",
|
||||
"MaxSdk/Mediation/Google/Editor/PostProcessor.cs",
|
||||
"MaxSdk/Mediation/Google/Editor/PostProcessor.cs.meta",
|
||||
"MaxSdk/Mediation/Google/Editor/PreProcessor.cs",
|
||||
"MaxSdk/Mediation/Google/Editor/PreProcessor.cs.meta",
|
||||
"MaxSdk/Mediation/Google/Editor/MaxSdk.Mediation.Google.Editor.asmdef",
|
||||
"MaxSdk/Mediation/Google/MaxSdk.Mediation.Google.Editor.asmdef.meta",
|
||||
"Plugins/Android/MaxMediationGoogle.androidlib",
|
||||
"Plugins/Android/MaxMediationGoogle.androidlib.meta",
|
||||
|
||||
// Google Ad Manager adapter pre/post process scripts. The logic has been migrated to the main plugin.
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/MaxGoogleAdManagerInitialize.cs",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/MaxGoogleAdManagerInitialize.cs.meta",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/PostProcessor.cs",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/PostProcessor.cs.meta",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/MaxSdk.Mediation.GoogleAdManager.Editor.asmdef",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/MaxSdk.Mediation.GoogleAdManager.Editor.asmdef.meta",
|
||||
"Plugins/Android/MaxMediationGoogleAdManager.androidlib",
|
||||
"Plugins/Android/MaxMediationGoogleAdManager.androidlib.meta",
|
||||
|
||||
// The `VariableService` has been removed.
|
||||
"MaxSdk/Scripts/MaxVariableServiceAndroid.cs",
|
||||
"MaxSdk/Scripts/MaxVariableServiceAndroid.cs.meta",
|
||||
"MaxSdk/Scripts/MaxVariableServiceiOS.cs",
|
||||
"MaxSdk/Scripts/MaxVariableServiceiOS.cs.meta",
|
||||
"MaxSdk/Scripts/MaxVariableServiceUnityEditor.cs",
|
||||
"MaxSdk/Scripts/MaxVariableServiceUnityEditor.cs.meta",
|
||||
|
||||
// TODO: Add MaxTargetingData and MaxUserSegment when the plugin has enough traction.
|
||||
};
|
||||
|
||||
static AppLovinInitialize()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
// Check that the publisher is targeting iOS 9.0+
|
||||
if (!PlayerSettings.iOS.targetOSVersionString.StartsWith("9.") && !PlayerSettings.iOS.targetOSVersionString.StartsWith("1"))
|
||||
{
|
||||
MaxSdkLogger.UserError("Detected iOS project version less than iOS 9 - The AppLovin MAX SDK WILL NOT WORK ON < iOS9!!!");
|
||||
}
|
||||
#endif
|
||||
|
||||
var pluginParentDir = AppLovinIntegrationManager.PluginParentDirectory;
|
||||
var isPluginOutsideAssetsDir = AppLovinIntegrationManager.IsPluginOutsideAssetsDirectory;
|
||||
var changesMade = AppLovinIntegrationManager.MovePluginFilesIfNeeded(pluginParentDir, isPluginOutsideAssetsDir);
|
||||
if (isPluginOutsideAssetsDir)
|
||||
{
|
||||
// If the plugin is not under the assets folder, delete the MaxSdk/Mediation folder in the plugin, so that the adapters are not imported at that location and imported to the default location.
|
||||
var mediationDir = Path.Combine(pluginParentDir, "MaxSdk/Mediation");
|
||||
if (Directory.Exists(mediationDir))
|
||||
{
|
||||
FileUtil.DeleteFileOrDirectory(mediationDir);
|
||||
FileUtil.DeleteFileOrDirectory(mediationDir + ".meta");
|
||||
changesMade = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var obsoleteFileExportPathToDelete in ObsoleteFileExportPathsToDelete)
|
||||
{
|
||||
var pathToDelete = MaxSdkUtils.GetAssetPathForExportPath(obsoleteFileExportPathToDelete);
|
||||
if (CheckExistence(pathToDelete))
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Deleting obsolete file '" + pathToDelete + "' that are no longer needed.");
|
||||
FileUtil.DeleteFileOrDirectory(pathToDelete);
|
||||
changesMade = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any obsolete networks are installed
|
||||
foreach (var obsoleteNetwork in ObsoleteNetworks)
|
||||
{
|
||||
var networkDir = Path.Combine(pluginParentDir, "MaxSdk/Mediation/" + obsoleteNetwork);
|
||||
if (CheckExistence(networkDir))
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Deleting obsolete network " + obsoleteNetwork + " from path " + networkDir + "...");
|
||||
FileUtil.DeleteFileOrDirectory(networkDir);
|
||||
changesMade = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh UI
|
||||
if (changesMade)
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
MaxSdkLogger.UserDebug("AppLovin MAX Migration completed");
|
||||
}
|
||||
|
||||
AppLovinAutoUpdater.Update();
|
||||
}
|
||||
|
||||
private static bool CheckExistence(string location)
|
||||
{
|
||||
return File.Exists(location) ||
|
||||
Directory.Exists(location) ||
|
||||
(location.EndsWith("/*") && Directory.Exists(Path.GetDirectoryName(location)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b7dce7fe193a4058bc51d9f4d3a2aed
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinInitialize.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,754 @@
|
||||
//
|
||||
// MaxIntegrationManager.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 6/1/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using VersionComparisonResult = MaxSdkUtils.VersionComparisonResult;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class PluginData
|
||||
{
|
||||
public Network AppLovinMax;
|
||||
public Network[] MediatedNetworks;
|
||||
public Network[] PartnerMicroSdks;
|
||||
public DynamicLibraryToEmbed[] ThirdPartyDynamicLibrariesToEmbed;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Network
|
||||
{
|
||||
//
|
||||
// Sample network data:
|
||||
//
|
||||
// {
|
||||
// "Name": "adcolony",
|
||||
// "DisplayName": "AdColony",
|
||||
// "DownloadUrl": "https://bintray.com/applovin/Unity-Mediation-Packages/download_file?file_path=AppLovin-AdColony-Adapters-Android-3.3.10.1-iOS-3.3.7.2.unitypackage",
|
||||
// "PluginFileName": "AppLovin-AdColony-Adapters-Android-3.3.10.1-iOS-3.3.7.2.unitypackage",
|
||||
// "DependenciesFilePath": "MaxSdk/Mediation/AdColony/Editor/Dependencies.xml",
|
||||
// "LatestVersions" : {
|
||||
// "Unity": "android_3.3.10.1_ios_3.3.7.2",
|
||||
// "Android": "3.3.10.1",
|
||||
// "Ios": "3.3.7.2"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
public string Name;
|
||||
public string DisplayName;
|
||||
public string DownloadUrl;
|
||||
public string DependenciesFilePath;
|
||||
public string[] PluginFilePaths;
|
||||
public Versions LatestVersions;
|
||||
[NonSerialized] public Versions CurrentVersions;
|
||||
[NonSerialized] public VersionComparisonResult CurrentToLatestVersionComparisonResult = VersionComparisonResult.Lesser;
|
||||
[NonSerialized] public bool RequiresUpdate;
|
||||
public DynamicLibraryToEmbed[] DynamicLibrariesToEmbed;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DynamicLibraryToEmbed
|
||||
{
|
||||
public string PodName;
|
||||
public string[] FrameworkNames;
|
||||
|
||||
// Min and max versions are inclusive, so if the adapter is the min or max version, the xcframework will get embedded.
|
||||
public string MinVersion;
|
||||
public string MaxVersion;
|
||||
|
||||
public DynamicLibraryToEmbed(string podName, string[] frameworkNames, string minVersion, string maxVersion)
|
||||
{
|
||||
PodName = podName;
|
||||
FrameworkNames = frameworkNames;
|
||||
MinVersion = minVersion;
|
||||
MaxVersion = maxVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A helper data class used to get current versions from Dependency.xml files.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Versions
|
||||
{
|
||||
public string Unity;
|
||||
public string Android;
|
||||
public string Ios;
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var versions = value as Versions;
|
||||
|
||||
return versions != null
|
||||
&& Unity.Equals(versions.Unity)
|
||||
&& (Android == null || Android.Equals(versions.Android))
|
||||
&& (Ios == null || Ios.Equals(versions.Ios));
|
||||
}
|
||||
|
||||
public bool HasEqualSdkVersions(Versions versions)
|
||||
{
|
||||
return versions != null
|
||||
&& AdapterSdkVersion(Android).Equals(AdapterSdkVersion(versions.Android))
|
||||
&& AdapterSdkVersion(Ios).Equals(AdapterSdkVersion(versions.Ios));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return new {Unity, Android, Ios}.GetHashCode();
|
||||
}
|
||||
|
||||
private static string AdapterSdkVersion(string adapterVersion)
|
||||
{
|
||||
var index = adapterVersion.LastIndexOf(".");
|
||||
return index > 0 ? adapterVersion.Substring(0, index) : adapterVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A manager class for MAX integration manager window.
|
||||
///
|
||||
/// TODO: Decide if we should namespace these classes.
|
||||
/// </summary>
|
||||
public class AppLovinIntegrationManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate to be called when downloading a plugin with the progress percentage.
|
||||
/// </summary>
|
||||
/// <param name="pluginName">The name of the plugin being downloaded.</param>
|
||||
/// <param name="progress">Percentage downloaded.</param>
|
||||
/// <param name="done">Whether or not the download is complete.</param>
|
||||
public delegate void DownloadPluginProgressCallback(string pluginName, float progress, bool done);
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to be called when a plugin package is imported.
|
||||
/// </summary>
|
||||
/// <param name="network">The network data for which the package is imported.</param>
|
||||
public delegate void ImportPackageCompletedCallback(Network network);
|
||||
|
||||
private static readonly AppLovinIntegrationManager instance = new AppLovinIntegrationManager();
|
||||
|
||||
public static readonly string GradleTemplatePath = Path.Combine("Assets/Plugins/Android", "mainTemplate.gradle");
|
||||
public static readonly string DefaultPluginExportPath = Path.Combine("Assets", "MaxSdk");
|
||||
private const string MaxSdkAssetExportPath = "MaxSdk/Scripts/MaxSdk.cs";
|
||||
|
||||
internal static readonly string PluginDataEndpoint = "https://unity.applovin.com/max/1.0/integration_manager_info?plugin_version={0}";
|
||||
|
||||
/// <summary>
|
||||
/// Some publishers might re-export our plugin via Unity Package Manager and the plugin will not be under the Assets folder. This means that the mediation adapters, settings files should not be moved to the packages folder,
|
||||
/// since they get overridden when the package is updated. These are the files that should not be moved, if the plugin is not under the Assets/ folder.
|
||||
///
|
||||
/// Note: When we distribute the plugin via Unity Package Manager, we need to distribute the adapters as separate packages, and the adapters won't be in the MaxSdk folder. So we need to take that into account.
|
||||
/// </summary>
|
||||
private static readonly List<string> PluginPathsToIgnoreMoveWhenPluginOutsideAssetsDirectory = new List<string>
|
||||
{
|
||||
"MaxSdk/Mediation",
|
||||
"MaxSdk/Mediation.meta",
|
||||
"MaxSdk/Resources.meta",
|
||||
AppLovinSettings.SettingsExportPath,
|
||||
AppLovinSettings.SettingsExportPath + ".meta"
|
||||
};
|
||||
|
||||
private static string externalDependencyManagerVersion;
|
||||
|
||||
public static DownloadPluginProgressCallback downloadPluginProgressCallback;
|
||||
public static ImportPackageCompletedCallback importPackageCompletedCallback;
|
||||
|
||||
private UnityWebRequest webRequest;
|
||||
private Network importingNetwork;
|
||||
|
||||
/// <summary>
|
||||
/// An Instance of the Integration manager.
|
||||
/// </summary>
|
||||
public static AppLovinIntegrationManager Instance
|
||||
{
|
||||
get { return instance; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The parent directory path where the MaxSdk plugin directory is placed.
|
||||
/// </summary>
|
||||
public static string PluginParentDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
// Search for the asset with the default exported path first, In most cases, we should be able to find the asset.
|
||||
// In some cases where we don't, use the platform specific export path to search for the asset (in case of migrating a project from Windows to Mac or vice versa).
|
||||
var maxSdkScriptAssetPath = MaxSdkUtils.GetAssetPathForExportPath(MaxSdkAssetExportPath);
|
||||
|
||||
// maxSdkScriptAssetPath will always have AltDirectorySeparatorChar (/) as the path separator. Convert to platform specific path.
|
||||
return maxSdkScriptAssetPath.Replace(MaxSdkAssetExportPath, "")
|
||||
.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the base plugin is outside the <c>Assets/</c> directory, the mediation plugin files are still imported to the default location under <c>Assets/</c>.
|
||||
/// Returns the parent directory where the mediation adapter plugins are imported.
|
||||
/// </summary>
|
||||
public static string MediationSpecificPluginParentDirectory
|
||||
{
|
||||
get { return IsPluginOutsideAssetsDirectory ? "Assets" : PluginParentDirectory; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the plugin is under the Assets/ folder.
|
||||
/// </summary>
|
||||
public static bool IsPluginOutsideAssetsDirectory
|
||||
{
|
||||
get { return !PluginParentDirectory.StartsWith("Assets"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not gradle build system is enabled.
|
||||
/// </summary>
|
||||
public static bool GradleBuildEnabled
|
||||
{
|
||||
get { return GetEditorUserBuildSetting("androidBuildSystem", "").ToString().Equals("Gradle"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not Gradle template is enabled.
|
||||
/// </summary>
|
||||
public static bool GradleTemplateEnabled
|
||||
{
|
||||
get { return GradleBuildEnabled && File.Exists(GradleTemplatePath); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the Quality Service settings can be processed which requires Gradle template enabled or Unity IDE newer than version 2018_2.
|
||||
/// </summary>
|
||||
public static bool CanProcessAndroidQualityServiceSettings
|
||||
{
|
||||
get { return GradleTemplateEnabled || GradleBuildEnabled; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The External Dependency Manager version obtained dynamically.
|
||||
/// </summary>
|
||||
public static string ExternalDependencyManagerVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(externalDependencyManagerVersion)) return externalDependencyManagerVersion;
|
||||
|
||||
try
|
||||
{
|
||||
var versionHandlerVersionNumberType = Type.GetType("Google.VersionHandlerVersionNumber, Google.VersionHandlerImpl");
|
||||
externalDependencyManagerVersion = versionHandlerVersionNumberType.GetProperty("Value").GetValue(null, null).ToString();
|
||||
}
|
||||
#pragma warning disable 0168
|
||||
catch (Exception ignored)
|
||||
#pragma warning restore 0168
|
||||
{
|
||||
externalDependencyManagerVersion = "Failed to get version.";
|
||||
}
|
||||
|
||||
return externalDependencyManagerVersion;
|
||||
}
|
||||
}
|
||||
|
||||
private AppLovinIntegrationManager()
|
||||
{
|
||||
// Add asset import callbacks.
|
||||
AssetDatabase.importPackageCompleted += packageName =>
|
||||
{
|
||||
if (!IsImportingNetwork(packageName)) return;
|
||||
|
||||
var pluginParentDir = PluginParentDirectory;
|
||||
var isPluginOutsideAssetsDir = IsPluginOutsideAssetsDirectory;
|
||||
MovePluginFilesIfNeeded(pluginParentDir, isPluginOutsideAssetsDir);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
CallImportPackageCompletedCallback(importingNetwork);
|
||||
importingNetwork = null;
|
||||
};
|
||||
|
||||
AssetDatabase.importPackageCancelled += packageName =>
|
||||
{
|
||||
if (!IsImportingNetwork(packageName)) return;
|
||||
|
||||
MaxSdkLogger.UserDebug("Package import cancelled.");
|
||||
importingNetwork = null;
|
||||
};
|
||||
|
||||
AssetDatabase.importPackageFailed += (packageName, errorMessage) =>
|
||||
{
|
||||
if (!IsImportingNetwork(packageName)) return;
|
||||
|
||||
MaxSdkLogger.UserError(errorMessage);
|
||||
importingNetwork = null;
|
||||
};
|
||||
}
|
||||
|
||||
static AppLovinIntegrationManager() { }
|
||||
|
||||
public static PluginData LoadPluginDataSync()
|
||||
{
|
||||
var url = string.Format(PluginDataEndpoint, MaxSdk.Version);
|
||||
using (var unityWebRequest = UnityWebRequest.Get(url))
|
||||
{
|
||||
var operation = unityWebRequest.SendWebRequest();
|
||||
|
||||
// Just wait till www is done
|
||||
while (!operation.isDone) { }
|
||||
|
||||
return CreatePluginDataFromWebResponse(unityWebRequest);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the plugin data to be display by integration manager window.
|
||||
/// </summary>
|
||||
/// <param name="callback">Callback to be called once the plugin data download completes.</param>
|
||||
public IEnumerator LoadPluginData(Action<PluginData> callback)
|
||||
{
|
||||
var url = string.Format(PluginDataEndpoint, MaxSdk.Version);
|
||||
using (var unityWebRequest = UnityWebRequest.Get(url))
|
||||
{
|
||||
var operation = unityWebRequest.SendWebRequest();
|
||||
|
||||
while (!operation.isDone) yield return new WaitForSeconds(0.1f); // Just wait till www is done. Our coroutine is pretty rudimentary.
|
||||
|
||||
var pluginData = CreatePluginDataFromWebResponse(unityWebRequest);
|
||||
|
||||
callback(pluginData);
|
||||
}
|
||||
}
|
||||
|
||||
private static PluginData CreatePluginDataFromWebResponse(UnityWebRequest unityWebRequest)
|
||||
{
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (unityWebRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
|
||||
#endif
|
||||
{
|
||||
MaxSdkLogger.E("Failed to load plugin data. Please check your internet connection.");
|
||||
return null;
|
||||
}
|
||||
|
||||
PluginData pluginData;
|
||||
try
|
||||
{
|
||||
pluginData = JsonUtility.FromJson<PluginData>(unityWebRequest.downloadHandler.text);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.WriteLine(exception);
|
||||
pluginData = null;
|
||||
}
|
||||
|
||||
if (pluginData == null) return null;
|
||||
|
||||
// Get current version of the plugin
|
||||
var appLovinMax = pluginData.AppLovinMax;
|
||||
UpdateCurrentVersions(appLovinMax, PluginParentDirectory);
|
||||
|
||||
// Get current versions for all the mediation networks.
|
||||
var mediationPluginParentDirectory = MediationSpecificPluginParentDirectory;
|
||||
foreach (var network in pluginData.MediatedNetworks)
|
||||
{
|
||||
UpdateCurrentVersions(network, mediationPluginParentDirectory);
|
||||
}
|
||||
|
||||
foreach (var partnerMicroSdk in pluginData.PartnerMicroSdks)
|
||||
{
|
||||
UpdateCurrentVersions(partnerMicroSdk, mediationPluginParentDirectory);
|
||||
}
|
||||
|
||||
return pluginData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the CurrentVersion fields for a given network data object.
|
||||
/// </summary>
|
||||
/// <param name="network">Network for which to update the current versions.</param>
|
||||
/// <param name="mediationPluginParentDirectory">The parent directory of where the mediation adapter plugins are imported to.</param>
|
||||
public static void UpdateCurrentVersions(Network network, string mediationPluginParentDirectory)
|
||||
{
|
||||
var currentVersions = GetCurrentVersions(MaxSdkUtils.GetAssetPathForExportPath(network.DependenciesFilePath));
|
||||
|
||||
network.CurrentVersions = currentVersions;
|
||||
|
||||
// If AppLovin mediation plugin, get the version from MaxSdk and the latest and current version comparison.
|
||||
if (network.Name.Equals("APPLOVIN_NETWORK"))
|
||||
{
|
||||
network.CurrentVersions.Unity = MaxSdk.Version;
|
||||
|
||||
var unityVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Unity, network.LatestVersions.Unity);
|
||||
var androidVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Android, network.LatestVersions.Android);
|
||||
var iosVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Ios, network.LatestVersions.Ios);
|
||||
|
||||
// Overall version is same if all the current and latest (from db) versions are same.
|
||||
if (unityVersionComparison == VersionComparisonResult.Equal &&
|
||||
androidVersionComparison == VersionComparisonResult.Equal &&
|
||||
iosVersionComparison == VersionComparisonResult.Equal)
|
||||
{
|
||||
network.CurrentToLatestVersionComparisonResult = VersionComparisonResult.Equal;
|
||||
}
|
||||
// One of the installed versions is newer than the latest versions which means that the publisher is on a beta version.
|
||||
else if (unityVersionComparison == VersionComparisonResult.Greater ||
|
||||
androidVersionComparison == VersionComparisonResult.Greater ||
|
||||
iosVersionComparison == VersionComparisonResult.Greater)
|
||||
{
|
||||
network.CurrentToLatestVersionComparisonResult = VersionComparisonResult.Greater;
|
||||
}
|
||||
// We have a new version available if all Android, iOS and Unity has a newer version available in db.
|
||||
else
|
||||
{
|
||||
network.CurrentToLatestVersionComparisonResult = VersionComparisonResult.Lesser;
|
||||
}
|
||||
}
|
||||
// For all other mediation adapters, get the version comparison using their Unity versions.
|
||||
else
|
||||
{
|
||||
// If adapter is indeed installed, compare the current (installed) and the latest (from db) versions, so that we can determine if the publisher is on an older, current or a newer version of the adapter.
|
||||
// If the publisher is on a newer version of the adapter than the db version, that means they are on a beta version.
|
||||
if (!string.IsNullOrEmpty(currentVersions.Unity))
|
||||
{
|
||||
network.CurrentToLatestVersionComparisonResult = MaxSdkUtils.CompareUnityMediationVersions(currentVersions.Unity, network.LatestVersions.Unity);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(network.CurrentVersions.Unity) && AppLovinAutoUpdater.MinAdapterVersions.ContainsKey(network.Name))
|
||||
{
|
||||
var comparisonResult = MaxSdkUtils.CompareUnityMediationVersions(network.CurrentVersions.Unity, AppLovinAutoUpdater.MinAdapterVersions[network.Name]);
|
||||
// Requires update if current version is lower than the min required version.
|
||||
network.RequiresUpdate = comparisonResult < 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset value so that the Integration manager can hide the alert icon once adapter is updated.
|
||||
network.RequiresUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Downloads the plugin file for a given network.
|
||||
/// </summary>
|
||||
/// <param name="network">Network for which to download the current version.</param>
|
||||
/// <param name="showImport">Whether or not to show the import window when downloading. Defaults to <c>true</c>.</param>
|
||||
/// <returns></returns>
|
||||
public IEnumerator DownloadPlugin(Network network, bool showImport = true)
|
||||
{
|
||||
var path = Path.Combine(Application.temporaryCachePath, GetPluginFileName(network)); // TODO: Maybe delete plugin file after finishing import.
|
||||
var downloadHandler = new DownloadHandlerFile(path);
|
||||
webRequest = new UnityWebRequest(network.DownloadUrl)
|
||||
{
|
||||
method = UnityWebRequest.kHttpVerbGET,
|
||||
downloadHandler = downloadHandler
|
||||
};
|
||||
|
||||
var operation = webRequest.SendWebRequest();
|
||||
while (!operation.isDone)
|
||||
{
|
||||
yield return new WaitForSeconds(0.1f); // Just wait till webRequest is completed. Our coroutine is pretty rudimentary.
|
||||
CallDownloadPluginProgressCallback(network.DisplayName, operation.progress, operation.isDone);
|
||||
}
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (webRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (webRequest.isNetworkError || webRequest.isHttpError)
|
||||
#endif
|
||||
{
|
||||
MaxSdkLogger.UserError(webRequest.error);
|
||||
}
|
||||
else
|
||||
{
|
||||
importingNetwork = network;
|
||||
AssetDatabase.ImportPackage(path, showImport);
|
||||
}
|
||||
|
||||
webRequest.Dispose();
|
||||
webRequest = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels the plugin download if one is in progress.
|
||||
/// </summary>
|
||||
public void CancelDownload()
|
||||
{
|
||||
if (webRequest == null) return;
|
||||
|
||||
webRequest.Abort();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a dialog to the user with the given message and logs the error message to console.
|
||||
/// </summary>
|
||||
/// <param name="message">The failure message to be shown to the user.</param>
|
||||
public static void ShowBuildFailureDialog(string message)
|
||||
{
|
||||
var openIntegrationManager = EditorUtility.DisplayDialog("AppLovin MAX", message, "Open Integration Manager", "Dismiss");
|
||||
if (openIntegrationManager)
|
||||
{
|
||||
AppLovinIntegrationManagerWindow.ShowManager();
|
||||
}
|
||||
|
||||
MaxSdkLogger.UserError(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not an adapter with the given version or newer exists.
|
||||
/// </summary>
|
||||
/// <param name="adapterName">The name of the network (the root adapter folder name in "MaxSdk/Mediation/" folder.</param>
|
||||
/// <param name="iosVersion">The min adapter version to check for. Can be <c>null</c> if we want to check for any version.</param>
|
||||
/// <returns><c>true</c> if an adapter with the min version is installed.</returns>
|
||||
public static bool IsAdapterInstalled(string adapterName, string iosVersion = null) // TODO: Add Android version check.
|
||||
{
|
||||
var dependencyFilePath = MaxSdkUtils.GetAssetPathForExportPath("MaxSdk/Mediation/" + adapterName + "/Editor/Dependencies.xml");
|
||||
if (!File.Exists(dependencyFilePath)) return false;
|
||||
|
||||
// If version is null, we just need the adapter installed. We don't have to check for a specific version.
|
||||
if (iosVersion == null) return true;
|
||||
|
||||
var currentVersion = GetCurrentVersions(dependencyFilePath);
|
||||
var iosVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Ios, iosVersion);
|
||||
return iosVersionComparison != VersionComparisonResult.Lesser;
|
||||
}
|
||||
|
||||
#region Utility Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current versions for a given network's dependency file path.
|
||||
/// </summary>
|
||||
/// <param name="dependencyPath">A dependency file path that from which to extract current versions.</param>
|
||||
/// <returns>Current versions of a given network's dependency file.</returns>
|
||||
public static Versions GetCurrentVersions(string dependencyPath)
|
||||
{
|
||||
XDocument dependency;
|
||||
try
|
||||
{
|
||||
dependency = XDocument.Load(dependencyPath);
|
||||
}
|
||||
#pragma warning disable 0168
|
||||
catch (IOException exception)
|
||||
#pragma warning restore 0168
|
||||
{
|
||||
// Couldn't find the dependencies file. The plugin is not installed.
|
||||
return new Versions();
|
||||
}
|
||||
|
||||
// <dependencies>
|
||||
// <androidPackages>
|
||||
// <androidPackage spec="com.applovin.mediation:network_name-adapter:1.2.3.4" />
|
||||
// </androidPackages>
|
||||
// <iosPods>
|
||||
// <iosPod name="AppLovinMediationNetworkNameAdapter" version="2.3.4.5" />
|
||||
// </iosPods>
|
||||
// </dependencies>
|
||||
string androidVersion = null;
|
||||
string iosVersion = null;
|
||||
var dependenciesElement = dependency.Element("dependencies");
|
||||
if (dependenciesElement != null)
|
||||
{
|
||||
var androidPackages = dependenciesElement.Element("androidPackages");
|
||||
if (androidPackages != null)
|
||||
{
|
||||
var adapterPackage = androidPackages.Descendants().FirstOrDefault(element => element.Name.LocalName.Equals("androidPackage")
|
||||
&& element.FirstAttribute.Name.LocalName.Equals("spec")
|
||||
&& element.FirstAttribute.Value.StartsWith("com.applovin"));
|
||||
if (adapterPackage != null)
|
||||
{
|
||||
androidVersion = adapterPackage.FirstAttribute.Value.Split(':').Last();
|
||||
// Hack alert: Some Android versions might have square brackets to force a specific version. Remove them if they are detected.
|
||||
if (androidVersion.StartsWith("["))
|
||||
{
|
||||
androidVersion = androidVersion.Trim('[', ']');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var iosPods = dependenciesElement.Element("iosPods");
|
||||
if (iosPods != null)
|
||||
{
|
||||
var adapterPod = iosPods.Descendants().FirstOrDefault(element => element.Name.LocalName.Equals("iosPod")
|
||||
&& element.FirstAttribute.Name.LocalName.Equals("name")
|
||||
&& element.FirstAttribute.Value.StartsWith("AppLovin"));
|
||||
if (adapterPod != null)
|
||||
{
|
||||
iosVersion = adapterPod.Attributes().First(attribute => attribute.Name.LocalName.Equals("version")).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var currentVersions = new Versions();
|
||||
if (androidVersion != null && iosVersion != null)
|
||||
{
|
||||
currentVersions.Unity = string.Format("android_{0}_ios_{1}", androidVersion, iosVersion);
|
||||
currentVersions.Android = androidVersion;
|
||||
currentVersions.Ios = iosVersion;
|
||||
}
|
||||
else if (androidVersion != null)
|
||||
{
|
||||
currentVersions.Unity = string.Format("android_{0}", androidVersion);
|
||||
currentVersions.Android = androidVersion;
|
||||
}
|
||||
else if (iosVersion != null)
|
||||
{
|
||||
currentVersions.Unity = string.Format("ios_{0}", iosVersion);
|
||||
currentVersions.Ios = iosVersion;
|
||||
}
|
||||
|
||||
return currentVersions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not the given package name is the currently importing package.
|
||||
/// </summary>
|
||||
/// <param name="packageName">The name of the package that needs to be checked.</param>
|
||||
/// <returns>true if the importing package matches the given package name.</returns>
|
||||
private bool IsImportingNetwork(string packageName)
|
||||
{
|
||||
// Note: The pluginName doesn't have the '.unitypacakge' extension included in its name but the pluginFileName does. So using Contains instead of Equals.
|
||||
return importingNetwork != null && GetPluginFileName(importingNetwork).Contains(packageName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the imported plugin files to the MaxSdk directory if the publisher has moved the plugin to a different directory. This is a failsafe for when some plugin files are not imported to the new location.
|
||||
/// </summary>
|
||||
/// <returns>True if the adapters have been moved.</returns>
|
||||
public static bool MovePluginFilesIfNeeded(string pluginParentDirectory, bool isPluginOutsideAssetsDirectory)
|
||||
{
|
||||
var pluginDir = Path.Combine(pluginParentDirectory, "MaxSdk");
|
||||
|
||||
// Check if the user has moved the Plugin and if new assets have been imported to the default directory.
|
||||
if (DefaultPluginExportPath.Equals(pluginDir) || !Directory.Exists(DefaultPluginExportPath)) return false;
|
||||
|
||||
MovePluginFiles(DefaultPluginExportPath, pluginDir, isPluginOutsideAssetsDirectory);
|
||||
if (!isPluginOutsideAssetsDirectory)
|
||||
{
|
||||
FileUtil.DeleteFileOrDirectory(DefaultPluginExportPath + ".meta");
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A helper function to move all the files recursively from the default plugin dir to a custom location the publisher moved the plugin to.
|
||||
/// </summary>
|
||||
private static void MovePluginFiles(string fromDirectory, string pluginRoot, bool isPluginOutsideAssetsDirectory)
|
||||
{
|
||||
var files = Directory.GetFiles(fromDirectory);
|
||||
foreach (var file in files)
|
||||
{
|
||||
// We have to ignore some files, if the plugin is outside the Assets/ directory.
|
||||
if (isPluginOutsideAssetsDirectory && PluginPathsToIgnoreMoveWhenPluginOutsideAssetsDirectory.Any(pluginPathsToIgnore => file.Contains(pluginPathsToIgnore))) continue;
|
||||
|
||||
// Check if the destination folder exists and create it if it doesn't exist
|
||||
var parentDirectory = Path.GetDirectoryName(file);
|
||||
var destinationDirectoryPath = parentDirectory.Replace(DefaultPluginExportPath, pluginRoot);
|
||||
if (!Directory.Exists(destinationDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(destinationDirectoryPath);
|
||||
}
|
||||
|
||||
// If the meta file is of a folder asset and doesn't have labels (it is auto generated by Unity), just delete it.
|
||||
if (IsAutoGeneratedFolderMetaFile(file))
|
||||
{
|
||||
FileUtil.DeleteFileOrDirectory(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
var destinationPath = file.Replace(DefaultPluginExportPath, pluginRoot);
|
||||
|
||||
// Check if the file is already present at the destination path and delete it.
|
||||
if (File.Exists(destinationPath))
|
||||
{
|
||||
FileUtil.DeleteFileOrDirectory(destinationPath);
|
||||
}
|
||||
|
||||
FileUtil.MoveFileOrDirectory(file, destinationPath);
|
||||
}
|
||||
|
||||
var directories = Directory.GetDirectories(fromDirectory);
|
||||
foreach (var directory in directories)
|
||||
{
|
||||
// We might have to ignore some directories, if the plugin is outside the Assets/ directory.
|
||||
if (isPluginOutsideAssetsDirectory && PluginPathsToIgnoreMoveWhenPluginOutsideAssetsDirectory.Any(pluginPathsToIgnore => directory.Contains(pluginPathsToIgnore))) continue;
|
||||
|
||||
MovePluginFiles(directory, pluginRoot, isPluginOutsideAssetsDirectory);
|
||||
}
|
||||
|
||||
if (!isPluginOutsideAssetsDirectory)
|
||||
{
|
||||
FileUtil.DeleteFileOrDirectory(fromDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsAutoGeneratedFolderMetaFile(string assetPath)
|
||||
{
|
||||
// Check if it is a meta file.
|
||||
if (!assetPath.EndsWith(".meta")) return false;
|
||||
|
||||
var lines = File.ReadAllLines(assetPath);
|
||||
var isFolderAsset = false;
|
||||
var hasLabels = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line.Contains("folderAsset: yes"))
|
||||
{
|
||||
isFolderAsset = true;
|
||||
}
|
||||
|
||||
if (line.Contains("labels:"))
|
||||
{
|
||||
hasLabels = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If it is a folder asset and doesn't have a label, the meta file is auto generated by
|
||||
return isFolderAsset && !hasLabels;
|
||||
}
|
||||
|
||||
private static void CallDownloadPluginProgressCallback(string pluginName, float progress, bool isDone)
|
||||
{
|
||||
if (downloadPluginProgressCallback == null) return;
|
||||
|
||||
downloadPluginProgressCallback(pluginName, progress, isDone);
|
||||
}
|
||||
|
||||
private static void CallImportPackageCompletedCallback(Network network)
|
||||
{
|
||||
if (importPackageCompletedCallback == null) return;
|
||||
|
||||
importPackageCompletedCallback(network);
|
||||
}
|
||||
|
||||
private static object GetEditorUserBuildSetting(string name, object defaultValue)
|
||||
{
|
||||
var editorUserBuildSettingsType = typeof(EditorUserBuildSettings);
|
||||
var property = editorUserBuildSettingsType.GetProperty(name);
|
||||
if (property != null)
|
||||
{
|
||||
var value = property.GetValue(null, null);
|
||||
if (value != null) return value;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static string GetPluginFileName(Network network)
|
||||
{
|
||||
return network.Name.ToLowerInvariant() + "_" + network.LatestVersions.Unity + ".unitypackage";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5b874c1e65274159bcc0dc15d9458cc
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManager.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84c61b4c05e114cec91df447d1b585f8
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManagerWindow.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,297 @@
|
||||
//
|
||||
// AppLovinInternalSettigns.cs
|
||||
// AppLovin User Engagement Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 9/15/22.
|
||||
// Copyright © 2022 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="ScriptableObject"/> representing the AppLovin internal settings that can be set in the Integration Manager Window.
|
||||
///
|
||||
/// The scriptable object asset is saved under ProjectSettings as <c>AppLovinInternalSettings.json</c>.
|
||||
/// </summary>
|
||||
public class AppLovinInternalSettings : ScriptableObject
|
||||
{
|
||||
private static AppLovinInternalSettings instance;
|
||||
|
||||
public const string DefaultUserTrackingDescriptionEn = "This uses device info for more personalized ads and content";
|
||||
public const string DefaultUserTrackingDescriptionDe = "Dies benutzt Gerätinformationen für relevantere Werbeinhalte";
|
||||
public const string DefaultUserTrackingDescriptionEs = "Esto utiliza la información del dispositivo para anuncios y contenido más personalizados";
|
||||
public const string DefaultUserTrackingDescriptionFr = "Cela permet d'utiliser les informations du téléphone pour afficher des contenus publicitaires plus pertinents.";
|
||||
public const string DefaultUserTrackingDescriptionJa = "これはユーザーデータをもとに、より関連性の高い広告コンテンツをお客様に提供します";
|
||||
public const string DefaultUserTrackingDescriptionKo = "보다 개인화된 광고 및 콘텐츠를 위해 기기 정보를 사용합니다.";
|
||||
public const string DefaultUserTrackingDescriptionZhHans = "我们使用设备信息来提供个性化的广告和内容。";
|
||||
public const string DefaultUserTrackingDescriptionZhHant = "我們使用設備信息來提供個性化的廣告和內容。";
|
||||
|
||||
[SerializeField] private bool consentFlowEnabled;
|
||||
[SerializeField] private string consentFlowPrivacyPolicyUrl = string.Empty;
|
||||
[SerializeField] private string consentFlowTermsOfServiceUrl = string.Empty;
|
||||
[SerializeField] private bool overrideDefaultUserTrackingUsageDescriptions;
|
||||
[SerializeField] private MaxSdkBase.ConsentFlowUserGeography debugUserGeography;
|
||||
[SerializeField] private string userTrackingUsageDescriptionEn = string.Empty;
|
||||
[SerializeField] private bool userTrackingUsageLocalizationEnabled;
|
||||
[SerializeField] private string userTrackingUsageDescriptionDe = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionEs = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionFr = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionJa = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionKo = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionZhHans = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionZhHant = string.Empty;
|
||||
|
||||
private const string SettingsFilePath = "ProjectSettings/AppLovinInternalSettings.json";
|
||||
|
||||
public static AppLovinInternalSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance != null) return instance;
|
||||
|
||||
instance = CreateInstance<AppLovinInternalSettings>();
|
||||
|
||||
var projectRootPath = Path.GetDirectoryName(Application.dataPath);
|
||||
var settingsFilePath = Path.Combine(projectRootPath, SettingsFilePath);
|
||||
if (!File.Exists(settingsFilePath))
|
||||
{
|
||||
instance.Save();
|
||||
return instance;
|
||||
}
|
||||
|
||||
var settingsJson = File.ReadAllText(settingsFilePath);
|
||||
if (string.IsNullOrEmpty(settingsJson))
|
||||
{
|
||||
instance.Save();
|
||||
return instance;
|
||||
}
|
||||
|
||||
JsonUtility.FromJsonOverwrite(settingsJson, instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
var settingsJson = JsonUtility.ToJson(instance);
|
||||
try
|
||||
{
|
||||
var projectRootPath = Path.GetDirectoryName(Application.dataPath);
|
||||
var settingsFilePath = Path.Combine(projectRootPath, SettingsFilePath);
|
||||
File.WriteAllText(settingsFilePath, settingsJson);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to save internal settings.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not AppLovin Consent Flow is enabled.
|
||||
/// </summary>
|
||||
public bool ConsentFlowEnabled
|
||||
{
|
||||
get { return consentFlowEnabled; }
|
||||
set
|
||||
{
|
||||
var previousValue = consentFlowEnabled;
|
||||
consentFlowEnabled = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// If the value didn't change, we don't need to update anything.
|
||||
if (previousValue) return;
|
||||
|
||||
UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEn;
|
||||
UserTrackingUsageLocalizationEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsentFlowPrivacyPolicyUrl = string.Empty;
|
||||
ConsentFlowTermsOfServiceUrl = string.Empty;
|
||||
UserTrackingUsageDescriptionEn = string.Empty;
|
||||
UserTrackingUsageLocalizationEnabled = false;
|
||||
OverrideDefaultUserTrackingUsageDescriptions = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A URL pointing to the Privacy Policy for the app to be shown when prompting the user for consent.
|
||||
/// </summary>
|
||||
public string ConsentFlowPrivacyPolicyUrl
|
||||
{
|
||||
get { return consentFlowPrivacyPolicyUrl; }
|
||||
set { consentFlowPrivacyPolicyUrl = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional URL pointing to the Terms of Service for the app to be shown when prompting the user for consent.
|
||||
/// </summary>
|
||||
public string ConsentFlowTermsOfServiceUrl
|
||||
{
|
||||
get { return consentFlowTermsOfServiceUrl; }
|
||||
set { consentFlowTermsOfServiceUrl = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in English to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionEn
|
||||
{
|
||||
get { return userTrackingUsageDescriptionEn; }
|
||||
set { userTrackingUsageDescriptionEn = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional string to set debug user geography
|
||||
/// </summary>
|
||||
public MaxSdkBase.ConsentFlowUserGeography DebugUserGeography
|
||||
{
|
||||
get { return debugUserGeography; }
|
||||
set { debugUserGeography = value; }
|
||||
}
|
||||
|
||||
public bool OverrideDefaultUserTrackingUsageDescriptions
|
||||
{
|
||||
get { return overrideDefaultUserTrackingUsageDescriptions; }
|
||||
set
|
||||
{
|
||||
var previousValue = overrideDefaultUserTrackingUsageDescriptions;
|
||||
overrideDefaultUserTrackingUsageDescriptions = value;
|
||||
|
||||
if (!value)
|
||||
{
|
||||
if (!previousValue) return;
|
||||
|
||||
UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEn;
|
||||
UserTrackingUsageDescriptionDe = DefaultUserTrackingDescriptionDe;
|
||||
UserTrackingUsageDescriptionEs = DefaultUserTrackingDescriptionEs;
|
||||
UserTrackingUsageDescriptionFr = DefaultUserTrackingDescriptionFr;
|
||||
UserTrackingUsageDescriptionJa = DefaultUserTrackingDescriptionJa;
|
||||
UserTrackingUsageDescriptionKo = DefaultUserTrackingDescriptionKo;
|
||||
UserTrackingUsageDescriptionZhHans = DefaultUserTrackingDescriptionZhHans;
|
||||
UserTrackingUsageDescriptionZhHant = DefaultUserTrackingDescriptionZhHant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to localize User Tracking Usage Description.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public bool UserTrackingUsageLocalizationEnabled
|
||||
{
|
||||
get { return userTrackingUsageLocalizationEnabled; }
|
||||
set
|
||||
{
|
||||
var previousValue = userTrackingUsageLocalizationEnabled;
|
||||
userTrackingUsageLocalizationEnabled = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// If the value didn't change, don't do anything
|
||||
if (previousValue) return;
|
||||
|
||||
// Don't set the default values if they are being overriden.
|
||||
if (OverrideDefaultUserTrackingUsageDescriptions) return;
|
||||
|
||||
UserTrackingUsageDescriptionDe = DefaultUserTrackingDescriptionDe;
|
||||
UserTrackingUsageDescriptionEs = DefaultUserTrackingDescriptionEs;
|
||||
UserTrackingUsageDescriptionFr = DefaultUserTrackingDescriptionFr;
|
||||
UserTrackingUsageDescriptionJa = DefaultUserTrackingDescriptionJa;
|
||||
UserTrackingUsageDescriptionKo = DefaultUserTrackingDescriptionKo;
|
||||
UserTrackingUsageDescriptionZhHans = DefaultUserTrackingDescriptionZhHans;
|
||||
UserTrackingUsageDescriptionZhHant = DefaultUserTrackingDescriptionZhHant;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserTrackingUsageDescriptionDe = string.Empty;
|
||||
UserTrackingUsageDescriptionEs = string.Empty;
|
||||
UserTrackingUsageDescriptionFr = string.Empty;
|
||||
UserTrackingUsageDescriptionJa = string.Empty;
|
||||
UserTrackingUsageDescriptionKo = string.Empty;
|
||||
UserTrackingUsageDescriptionZhHans = string.Empty;
|
||||
UserTrackingUsageDescriptionZhHant = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in German to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionDe
|
||||
{
|
||||
get { return userTrackingUsageDescriptionDe; }
|
||||
set { userTrackingUsageDescriptionDe = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Spanish to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionEs
|
||||
{
|
||||
get { return userTrackingUsageDescriptionEs; }
|
||||
set { userTrackingUsageDescriptionEs = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in French to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionFr
|
||||
{
|
||||
get { return userTrackingUsageDescriptionFr; }
|
||||
set { userTrackingUsageDescriptionFr = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Japanese to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionJa
|
||||
{
|
||||
get { return userTrackingUsageDescriptionJa; }
|
||||
set { userTrackingUsageDescriptionJa = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Korean to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionKo
|
||||
{
|
||||
get { return userTrackingUsageDescriptionKo; }
|
||||
set { userTrackingUsageDescriptionKo = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Chinese (Simplified) to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionZhHans
|
||||
{
|
||||
get { return userTrackingUsageDescriptionZhHans; }
|
||||
set { userTrackingUsageDescriptionZhHans = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Chinese (Traditional) to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionZhHant
|
||||
{
|
||||
get { return userTrackingUsageDescriptionZhHant; }
|
||||
set { userTrackingUsageDescriptionZhHant = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65c51e21887ae42c2839962fb9585e9f
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinInternalSettings.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// MaxMenuItems.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 5/27/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public class AppLovinMenuItems
|
||||
{
|
||||
/**
|
||||
* The special characters at the end represent a shortcut for this action.
|
||||
*
|
||||
* % - ctrl on Windows, cmd on macOS
|
||||
* # - shift
|
||||
* & - alt
|
||||
*
|
||||
* So, (shift + cmd/ctrl + i) will launch the integration manager
|
||||
*/
|
||||
[MenuItem("AppLovin/Integration Manager %#i")]
|
||||
private static void IntegrationManager()
|
||||
{
|
||||
ShowIntegrationManager();
|
||||
}
|
||||
|
||||
[MenuItem("AppLovin/Documentation")]
|
||||
private static void Documentation()
|
||||
{
|
||||
Application.OpenURL("https://developers.applovin.com/en/unity/overview/integration");
|
||||
}
|
||||
|
||||
[MenuItem("AppLovin/Contact Us")]
|
||||
private static void ContactUs()
|
||||
{
|
||||
Application.OpenURL("https://www.applovin.com/contact/");
|
||||
}
|
||||
|
||||
[MenuItem("AppLovin/About")]
|
||||
private static void About()
|
||||
{
|
||||
Application.OpenURL("https://www.applovin.com/about/");
|
||||
}
|
||||
|
||||
[MenuItem("Assets/AppLovin Integration Manager")]
|
||||
private static void AssetsIntegrationManager()
|
||||
{
|
||||
ShowIntegrationManager();
|
||||
}
|
||||
|
||||
private static void ShowIntegrationManager()
|
||||
{
|
||||
AppLovinIntegrationManagerWindow.ShowManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02c2d277874f649d18a59d382420bf65
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,547 @@
|
||||
//
|
||||
// MaxPostProcessBuildAndroid.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 4/10/20.
|
||||
// Copyright © 2020 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_ANDROID
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using AppLovinMax.ThirdParty.MiniJson;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Android;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// A post processor used to update the Android project once it is generated.
|
||||
/// </summary>
|
||||
public class AppLovinPostProcessAndroid : IPostGenerateGradleAndroidProject
|
||||
{
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
private const string PropertyAndroidX = "android.useAndroidX";
|
||||
private const string PropertyJetifier = "android.enableJetifier";
|
||||
private const string EnableProperty = "=true";
|
||||
#endif
|
||||
private const string PropertyDexingArtifactTransform = "android.enableDexingArtifactTransform";
|
||||
private const string DisableProperty = "=false";
|
||||
|
||||
private const string KeyMetaDataAppLovinVerboseLoggingOn = "applovin.sdk.verbose_logging";
|
||||
private const string KeyMetaDataGoogleApplicationId = "com.google.android.gms.ads.APPLICATION_ID";
|
||||
private const string KeyMetaDataGoogleOptimizeInitialization = "com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION";
|
||||
private const string KeyMetaDataGoogleOptimizeAdLoading = "com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING";
|
||||
|
||||
private const string KeyMetaDataMobileFuseAutoInit = "com.mobilefuse.sdk.disable_auto_init";
|
||||
private const string KeyMetaDataMyTargetAutoInit = "com.my.target.autoInitMode";
|
||||
|
||||
private const string KeyMetaDataAppLovinSdkKey = "applovin.sdk.key";
|
||||
|
||||
private const string AppLovinSettingsFileName = "applovin_settings.json";
|
||||
|
||||
private const string KeyTermsFlowSettings = "terms_flow_settings";
|
||||
private const string KeyTermsFlowEnabled = "terms_flow_enabled";
|
||||
private const string KeyTermsFlowTermsOfService = "terms_flow_terms_of_service";
|
||||
private const string KeyTermsFlowPrivacyPolicy = "terms_flow_privacy_policy";
|
||||
|
||||
private const string KeySdkKey = "sdk_key";
|
||||
private const string KeyConsentFlowSettings = "consent_flow_settings";
|
||||
private const string KeyConsentFlowEnabled = "consent_flow_enabled";
|
||||
private const string KeyConsentFlowTermsOfService = "consent_flow_terms_of_service";
|
||||
private const string KeyConsentFlowPrivacyPolicy = "consent_flow_privacy_policy";
|
||||
private const string KeyConsentFlowDebugUserGeography = "consent_flow_debug_user_geography";
|
||||
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
// To match "'com.android.library' version '7.3.1'" line in build.gradle
|
||||
private static readonly Regex TokenGradleVersionLibrary = new Regex(".*id ['\"]com\\.android\\.library['\"] version");
|
||||
private static readonly Regex TokenGradleVersion = new Regex(".*id ['\"]com\\.android\\.application['\"] version");
|
||||
#else
|
||||
// To match "classpath 'com.android.tools.build:gradle:4.0.1'" line in build.gradle
|
||||
private static readonly Regex TokenGradleVersion = new Regex(".*classpath ['\"]com\\.android\\.tools\\.build:gradle:.*");
|
||||
#endif
|
||||
|
||||
// To match "distributionUrl=..." in gradle-wrapper.properties file
|
||||
private static readonly Regex TokenDistributionUrl = new Regex(".*distributionUrl.*");
|
||||
|
||||
private static readonly XNamespace AndroidNamespace = "http://schemas.android.com/apk/res/android";
|
||||
|
||||
private static string PluginMediationDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
var pluginParentDir = AppLovinIntegrationManager.MediationSpecificPluginParentDirectory;
|
||||
return Path.Combine(pluginParentDir, "MaxSdk/Mediation/");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
var rootGradleBuildFilePath = Path.Combine(path, "../build.gradle");
|
||||
var gradlePropertiesPath = Path.Combine(path, "../gradle.properties");
|
||||
var gradleWrapperPropertiesPath = Path.Combine(path, "../gradle/wrapper/gradle-wrapper.properties");
|
||||
#else
|
||||
var rootGradleBuildFilePath = Path.Combine(path, "build.gradle");
|
||||
var gradlePropertiesPath = Path.Combine(path, "gradle.properties");
|
||||
var gradleWrapperPropertiesPath = Path.Combine(path, "gradle/wrapper/gradle-wrapper.properties");
|
||||
#endif
|
||||
|
||||
UpdateGradleVersionsIfNeeded(gradleWrapperPropertiesPath, rootGradleBuildFilePath);
|
||||
|
||||
var gradlePropertiesUpdated = new List<string>();
|
||||
|
||||
// If the gradle properties file already exists, make sure to add any previous properties.
|
||||
if (File.Exists(gradlePropertiesPath))
|
||||
{
|
||||
var lines = File.ReadAllLines(gradlePropertiesPath);
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
// Add all properties except AndroidX, Jetifier, and DexingArtifactTransform since they may already exist. We will re-add them below.
|
||||
gradlePropertiesUpdated.AddRange(lines.Where(line => !line.Contains(PropertyAndroidX) && !line.Contains(PropertyJetifier) && !line.Contains(PropertyDexingArtifactTransform)));
|
||||
#else
|
||||
// Add all properties except DexingArtifactTransform since it may already exist. We will re-add it below.
|
||||
gradlePropertiesUpdated.AddRange(lines.Where(line => !line.Contains(PropertyDexingArtifactTransform)));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
// Enable AndroidX and Jetifier properties
|
||||
gradlePropertiesUpdated.Add(PropertyAndroidX + EnableProperty);
|
||||
gradlePropertiesUpdated.Add(PropertyJetifier + EnableProperty);
|
||||
#endif
|
||||
|
||||
// `DexingArtifactTransform` has been removed in Gradle 8+ which is the default Gradle version for Unity 6.
|
||||
#if !UNITY_6000_0_OR_NEWER
|
||||
// Disable dexing using artifact transform (it causes issues for ExoPlayer with Gradle plugin 3.5.0+)
|
||||
gradlePropertiesUpdated.Add(PropertyDexingArtifactTransform + DisableProperty);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(gradlePropertiesPath, string.Join("\n", gradlePropertiesUpdated.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to enable AndroidX and Jetifier. gradle.properties file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
|
||||
ProcessAndroidManifest(path);
|
||||
AddSdkSettings(path);
|
||||
}
|
||||
|
||||
public int callbackOrder
|
||||
{
|
||||
get { return int.MaxValue; }
|
||||
}
|
||||
|
||||
private static void ProcessAndroidManifest(string path)
|
||||
{
|
||||
var manifestPath = Path.Combine(path, "src/main/AndroidManifest.xml");
|
||||
XDocument manifest;
|
||||
try
|
||||
{
|
||||
manifest = XDocument.Load(manifestPath);
|
||||
}
|
||||
#pragma warning disable 0168
|
||||
catch (IOException exception)
|
||||
#pragma warning restore 0168
|
||||
{
|
||||
MaxSdkLogger.UserWarning("[AppLovin MAX] AndroidManifest.xml is missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the `manifest` element.
|
||||
var elementManifest = manifest.Element("manifest");
|
||||
if (elementManifest == null)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("[AppLovin MAX] AndroidManifest.xml is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
var elementApplication = elementManifest.Element("application");
|
||||
if (elementApplication == null)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("[AppLovin MAX] AndroidManifest.xml is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
var metaDataElements = elementApplication.Descendants().Where(element => element.Name.LocalName.Equals("meta-data"));
|
||||
|
||||
EnableVerboseLoggingIfNeeded(elementApplication);
|
||||
AddGoogleApplicationIdIfNeeded(elementApplication, metaDataElements);
|
||||
AddGoogleOptimizationFlagsIfNeeded(elementApplication, metaDataElements);
|
||||
DisableAutoInitIfNeeded(elementApplication, metaDataElements);
|
||||
RemoveSdkKeyIfNeeded(metaDataElements);
|
||||
|
||||
// Save the updated manifest file.
|
||||
manifest.Save(manifestPath);
|
||||
}
|
||||
|
||||
private static void EnableVerboseLoggingIfNeeded(XElement elementApplication)
|
||||
{
|
||||
var enabled = EditorPrefs.GetBool(MaxSdkLogger.KeyVerboseLoggingEnabled, false);
|
||||
|
||||
var descendants = elementApplication.Descendants();
|
||||
var verboseLoggingMetaData = descendants.FirstOrDefault(descendant => descendant.FirstAttribute != null &&
|
||||
descendant.FirstAttribute.Name.LocalName.Equals("name") &&
|
||||
descendant.FirstAttribute.Value.Equals(KeyMetaDataAppLovinVerboseLoggingOn) &&
|
||||
descendant.LastAttribute != null &&
|
||||
descendant.LastAttribute.Name.LocalName.Equals("value"));
|
||||
|
||||
// check if applovin.sdk.verbose_logging meta data exists.
|
||||
if (verboseLoggingMetaData != null)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
// update applovin.sdk.verbose_logging meta data value.
|
||||
verboseLoggingMetaData.LastAttribute.Value = enabled.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove applovin.sdk.verbose_logging meta data.
|
||||
verboseLoggingMetaData.Remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
// add applovin.sdk.verbose_logging meta data if it does not exist.
|
||||
var metaData = CreateMetaDataElement(KeyMetaDataAppLovinVerboseLoggingOn, enabled.ToString());
|
||||
elementApplication.Add(metaData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddGoogleApplicationIdIfNeeded(XElement elementApplication, IEnumerable<XElement> metaDataElements)
|
||||
{
|
||||
if (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.IsAdapterInstalled("GoogleAdManager")) return;
|
||||
|
||||
var googleApplicationIdMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataGoogleApplicationId);
|
||||
var appId = AppLovinSettings.Instance.AdMobAndroidAppId;
|
||||
// Log error if the App ID is not set.
|
||||
if (string.IsNullOrEmpty(appId) || !appId.StartsWith("ca-app-pub-"))
|
||||
{
|
||||
MaxSdkLogger.UserError("Google App ID is not set. Please enter a valid app ID within the AppLovin Integration Manager window.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the Google App ID meta data already exists. Update if it already exists.
|
||||
if (googleApplicationIdMetaData != null)
|
||||
{
|
||||
googleApplicationIdMetaData.SetAttributeValue(AndroidNamespace + "value", appId);
|
||||
}
|
||||
// Meta data doesn't exist, add it.
|
||||
else
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleApplicationId, appId));
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddGoogleOptimizationFlagsIfNeeded(XElement elementApplication, IEnumerable<XElement> metaDataElements)
|
||||
{
|
||||
if (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.IsAdapterInstalled("GoogleAdManager")) return;
|
||||
|
||||
var googleOptimizeInitializationMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataGoogleOptimizeInitialization);
|
||||
// If meta data doesn't exist, add it
|
||||
if (googleOptimizeInitializationMetaData == null)
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleOptimizeInitialization, true));
|
||||
}
|
||||
|
||||
var googleOptimizeAdLoadingMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataGoogleOptimizeAdLoading);
|
||||
// If meta data doesn't exist, add it
|
||||
if (googleOptimizeAdLoadingMetaData == null)
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleOptimizeAdLoading, true));
|
||||
}
|
||||
}
|
||||
|
||||
private static void DisableAutoInitIfNeeded(XElement elementApplication, IEnumerable<XElement> metaDataElements)
|
||||
{
|
||||
if (AppLovinIntegrationManager.IsAdapterInstalled("MobileFuse"))
|
||||
{
|
||||
var mobileFuseMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataMobileFuseAutoInit);
|
||||
// If MobileFuse meta data doesn't exist, add it
|
||||
if (mobileFuseMetaData == null)
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataMobileFuseAutoInit, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (AppLovinIntegrationManager.IsAdapterInstalled("MyTarget"))
|
||||
{
|
||||
var myTargetMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataMyTargetAutoInit);
|
||||
// If MyTarget meta data doesn't exist, add it
|
||||
if (myTargetMetaData == null)
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataMyTargetAutoInit, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveSdkKeyIfNeeded(IEnumerable<XElement> metaDataElements)
|
||||
{
|
||||
var sdkKeyMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataAppLovinSdkKey);
|
||||
if (sdkKeyMetaData == null) return;
|
||||
|
||||
sdkKeyMetaData.Remove();
|
||||
}
|
||||
|
||||
private static void UpdateGradleVersionsIfNeeded(string gradleWrapperPropertiesPath, string rootGradleBuildFilePath)
|
||||
{
|
||||
var customGradleVersionUrl = AppLovinSettings.Instance.CustomGradleVersionUrl;
|
||||
var customGradleToolsVersion = AppLovinSettings.Instance.CustomGradleToolsVersion;
|
||||
|
||||
if (MaxSdkUtils.IsValidString(customGradleVersionUrl))
|
||||
{
|
||||
var newDistributionUrl = string.Format("distributionUrl={0}", customGradleVersionUrl);
|
||||
if (ReplaceStringInFile(gradleWrapperPropertiesPath, TokenDistributionUrl, newDistributionUrl))
|
||||
{
|
||||
MaxSdkLogger.D("Distribution url set to " + newDistributionUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set distribution URL");
|
||||
}
|
||||
}
|
||||
|
||||
if (MaxSdkUtils.IsValidString(customGradleToolsVersion))
|
||||
{
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
// Unity 2022.3+ requires Gradle Plugin version 7.1.2+.
|
||||
if (MaxSdkUtils.CompareVersions(customGradleToolsVersion, "7.1.2") == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle plugin version. Unity 2022.3+ requires gradle plugin version 7.1.2+");
|
||||
return;
|
||||
}
|
||||
|
||||
var newGradleVersionLibraryLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("id 'com.android.library' version '{0}' apply false", customGradleToolsVersion));
|
||||
if (ReplaceStringInFile(rootGradleBuildFilePath, TokenGradleVersionLibrary, newGradleVersionLibraryLine))
|
||||
{
|
||||
MaxSdkLogger.D("Gradle library version set to " + newGradleVersionLibraryLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle library version");
|
||||
}
|
||||
|
||||
var newGradleVersionLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("id 'com.android.application' version '{0}' apply false", customGradleToolsVersion));
|
||||
#else
|
||||
var newGradleVersionLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("classpath 'com.android.tools.build:gradle:{0}'", customGradleToolsVersion));
|
||||
#endif
|
||||
if (ReplaceStringInFile(rootGradleBuildFilePath, TokenGradleVersion, newGradleVersionLine))
|
||||
{
|
||||
MaxSdkLogger.D("Gradle version set to " + newGradleVersionLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle plugin version");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddSdkSettings(string path)
|
||||
{
|
||||
var appLovinSdkSettings = new Dictionary<string, object>();
|
||||
var rawResourceDirectory = Path.Combine(path, "src/main/res/raw");
|
||||
|
||||
// Add the SDK key to the SDK settings.
|
||||
appLovinSdkSettings[KeySdkKey] = AppLovinSettings.Instance.SdkKey;
|
||||
|
||||
// Add the Consent/Terms flow settings if needed.
|
||||
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled)
|
||||
{
|
||||
EnableConsentFlowIfNeeded(rawResourceDirectory, appLovinSdkSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableTermsFlowIfNeeded(rawResourceDirectory, appLovinSdkSettings);
|
||||
}
|
||||
|
||||
WriteAppLovinSettings(rawResourceDirectory, appLovinSdkSettings);
|
||||
}
|
||||
|
||||
private static void EnableConsentFlowIfNeeded(string rawResourceDirectory, Dictionary<string, object> applovinSdkSettings)
|
||||
{
|
||||
// Check if consent flow is enabled. No need to create the applovin_consent_flow_settings.json if consent flow is disabled.
|
||||
var consentFlowEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled;
|
||||
if (!consentFlowEnabled)
|
||||
{
|
||||
RemoveAppLovinSettingsRawResourceFileIfNeeded(rawResourceDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
var privacyPolicyUrl = AppLovinInternalSettings.Instance.ConsentFlowPrivacyPolicyUrl;
|
||||
if (string.IsNullOrEmpty(privacyPolicyUrl))
|
||||
{
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL in the AppLovin Integration Manager.");
|
||||
|
||||
// No need to update the applovin_consent_flow_settings.json here. Default consent flow state will be determined on the SDK side.
|
||||
return;
|
||||
}
|
||||
|
||||
var consentFlowSettings = new Dictionary<string, object>();
|
||||
consentFlowSettings[KeyConsentFlowEnabled] = consentFlowEnabled;
|
||||
consentFlowSettings[KeyConsentFlowPrivacyPolicy] = privacyPolicyUrl;
|
||||
|
||||
var termsOfServiceUrl = AppLovinInternalSettings.Instance.ConsentFlowTermsOfServiceUrl;
|
||||
if (MaxSdkUtils.IsValidString(termsOfServiceUrl))
|
||||
{
|
||||
consentFlowSettings[KeyConsentFlowTermsOfService] = termsOfServiceUrl;
|
||||
}
|
||||
|
||||
var debugUserGeography = AppLovinInternalSettings.Instance.DebugUserGeography;
|
||||
if (debugUserGeography == MaxSdkBase.ConsentFlowUserGeography.Gdpr)
|
||||
{
|
||||
consentFlowSettings[KeyConsentFlowDebugUserGeography] = "gdpr";
|
||||
}
|
||||
|
||||
applovinSdkSettings[KeyConsentFlowSettings] = consentFlowSettings;
|
||||
}
|
||||
|
||||
private static void EnableTermsFlowIfNeeded(string rawResourceDirectory, Dictionary<string, object> applovinSdkSettings)
|
||||
{
|
||||
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled) return;
|
||||
|
||||
// Check if terms flow is enabled for this format. No need to create the applovin_consent_flow_settings.json if consent flow is disabled.
|
||||
var consentFlowEnabled = AppLovinSettings.Instance.ConsentFlowEnabled;
|
||||
var consentFlowPlatform = AppLovinSettings.Instance.ConsentFlowPlatform;
|
||||
if (!consentFlowEnabled || (consentFlowPlatform != Platform.All && consentFlowPlatform != Platform.Android))
|
||||
{
|
||||
RemoveAppLovinSettingsRawResourceFileIfNeeded(rawResourceDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
var privacyPolicyUrl = AppLovinSettings.Instance.ConsentFlowPrivacyPolicyUrl;
|
||||
if (string.IsNullOrEmpty(privacyPolicyUrl))
|
||||
{
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL in the AppLovin Integration Manager.");
|
||||
|
||||
// No need to update the applovin_consent_flow_settings.json here. Default consent flow state will be determined on the SDK side.
|
||||
return;
|
||||
}
|
||||
|
||||
var consentFlowSettings = new Dictionary<string, object>();
|
||||
consentFlowSettings[KeyTermsFlowEnabled] = consentFlowEnabled;
|
||||
consentFlowSettings[KeyTermsFlowPrivacyPolicy] = privacyPolicyUrl;
|
||||
|
||||
var termsOfServiceUrl = AppLovinSettings.Instance.ConsentFlowTermsOfServiceUrl;
|
||||
if (MaxSdkUtils.IsValidString(termsOfServiceUrl))
|
||||
{
|
||||
consentFlowSettings[KeyTermsFlowTermsOfService] = termsOfServiceUrl;
|
||||
}
|
||||
|
||||
applovinSdkSettings[KeyTermsFlowSettings] = consentFlowSettings;
|
||||
}
|
||||
|
||||
private static void WriteAppLovinSettingsRawResourceFile(string applovinSdkSettingsJson, string rawResourceDirectory)
|
||||
{
|
||||
if (!Directory.Exists(rawResourceDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(rawResourceDirectory);
|
||||
}
|
||||
|
||||
var consentFlowSettingsFilePath = Path.Combine(rawResourceDirectory, AppLovinSettingsFileName);
|
||||
try
|
||||
{
|
||||
File.WriteAllText(consentFlowSettingsFilePath, applovinSdkSettingsJson + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("applovin_settings.json file write failed due to: " + exception.Message);
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the applovin_settings json file from the build if it exists.
|
||||
/// </summary>
|
||||
/// <param name="rawResourceDirectory">The raw resource directory that holds the json file</param>
|
||||
private static void RemoveAppLovinSettingsRawResourceFileIfNeeded(string rawResourceDirectory)
|
||||
{
|
||||
var consentFlowSettingsFilePath = Path.Combine(rawResourceDirectory, AppLovinSettingsFileName);
|
||||
if (!File.Exists(consentFlowSettingsFilePath)) return;
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(consentFlowSettingsFilePath);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Deleting applovin_settings.json failed due to: " + exception.Message);
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteAppLovinSettings(string rawResourceDirectory, Dictionary<string, object> applovinSdkSettings)
|
||||
{
|
||||
var applovinSdkSettingsJson = Json.Serialize(applovinSdkSettings);
|
||||
WriteAppLovinSettingsRawResourceFile(applovinSdkSettingsJson, rawResourceDirectory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and returns a <c>meta-data</c> element with the given name and value.
|
||||
/// </summary>
|
||||
private static XElement CreateMetaDataElement(string name, object value)
|
||||
{
|
||||
var metaData = new XElement("meta-data");
|
||||
metaData.Add(new XAttribute(AndroidNamespace + "name", name));
|
||||
metaData.Add(new XAttribute(AndroidNamespace + "value", value));
|
||||
|
||||
return metaData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks through all the given meta-data elements to check if the required one exists. Returns <c>null</c> if it doesn't exist.
|
||||
/// </summary>
|
||||
private static XElement GetMetaDataElement(IEnumerable<XElement> metaDataElements, string metaDataName)
|
||||
{
|
||||
foreach (var metaDataElement in metaDataElements)
|
||||
{
|
||||
var attributes = metaDataElement.Attributes();
|
||||
if (attributes.Any(attribute => attribute.Name.Namespace.Equals(AndroidNamespace)
|
||||
&& attribute.Name.LocalName.Equals("name")
|
||||
&& attribute.Value.Equals(metaDataName)))
|
||||
{
|
||||
return metaDataElement;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first line that contains regexToMatch and replaces the whole line with replacement
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file you want to replace a line in</param>
|
||||
/// <param name="regexToMatch">Regex to search for in the line you want to replace</param>
|
||||
/// <param name="replacement">String that you want as the new line</param>
|
||||
/// <returns>Returns whether the string was successfully replaced or not</returns>
|
||||
private static bool ReplaceStringInFile(string path, Regex regexToMatch, string replacement)
|
||||
{
|
||||
if (!File.Exists(path)) return false;
|
||||
|
||||
var lines = File.ReadAllLines(path);
|
||||
for (var i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (regexToMatch.IsMatch(lines[i]))
|
||||
{
|
||||
lines[i] = replacement;
|
||||
File.WriteAllLines(path, lines);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c01ea79d0cb2a43c093e2fd07201df9e
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessAndroid.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// AppLovinBuildPostProcessor.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 8/29/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_ANDROID
|
||||
|
||||
using System.IO;
|
||||
using UnityEditor.Android;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds Quality Service plugin to the Gradle project once the project has been exported. See <see cref="AppLovinProcessGradleBuildFile"/> for more details.
|
||||
/// </summary>
|
||||
public class AppLovinPostProcessGradleProject : AppLovinProcessGradleBuildFile, IPostGenerateGradleAndroidProject
|
||||
{
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
if (!AppLovinSettings.Instance.QualityServiceEnabled) return;
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
// On Unity 2019.3+, the path returned is the path to the unityLibrary's module.
|
||||
// The AppLovin Quality Service buildscript closure related lines need to be added to the root build.gradle file.
|
||||
var rootGradleBuildFilePath = Path.Combine(path, "../build.gradle");
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
if (!AddPluginToRootGradleBuildFile(rootGradleBuildFilePath)) return;
|
||||
|
||||
var rootSettingsGradleFilePath = Path.Combine(path, "../settings.gradle");
|
||||
if (!AddAppLovinRepository(rootSettingsGradleFilePath)) return;
|
||||
#else
|
||||
var buildScriptChangesAdded = AddQualityServiceBuildScriptLines(rootGradleBuildFilePath);
|
||||
if (!buildScriptChangesAdded) return;
|
||||
#endif
|
||||
|
||||
// The plugin needs to be added to the application module (named launcher)
|
||||
var applicationGradleBuildFilePath = Path.Combine(path, "../launcher/build.gradle");
|
||||
#else
|
||||
// If Gradle template is enabled, we would have already updated the plugin.
|
||||
if (AppLovinIntegrationManager.GradleTemplateEnabled) return;
|
||||
|
||||
var applicationGradleBuildFilePath = Path.Combine(path, "build.gradle");
|
||||
#endif
|
||||
|
||||
if (!File.Exists(applicationGradleBuildFilePath))
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Couldn't find build.gradle file. Failed to add AppLovin Quality Service plugin to the gradle project.");
|
||||
return;
|
||||
}
|
||||
|
||||
AddAppLovinQualityServicePlugin(applicationGradleBuildFilePath);
|
||||
}
|
||||
|
||||
public int callbackOrder
|
||||
{
|
||||
get { return int.MaxValue; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f75e54e2eb78f427ca8643c97684387b
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessAndroidGradle.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,782 @@
|
||||
//
|
||||
// MaxIntegrationManager.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 8/29/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_IOS || UNITY_IPHONE
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
using UnityEditor.iOS.Xcode.Extensions;
|
||||
#endif
|
||||
using UnityEditor.iOS.Xcode;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
using UnityEngine.Networking;
|
||||
using VersionComparisonResult = MaxSdkUtils.VersionComparisonResult;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class SkAdNetworkData
|
||||
{
|
||||
[SerializeField] public string[] SkAdNetworkIds;
|
||||
}
|
||||
|
||||
public class AppLovinPostProcessiOS
|
||||
{
|
||||
private const string OutputFileName = "AppLovinQualityServiceSetup.rb";
|
||||
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
private const string UnityMainTargetName = "Unity-iPhone";
|
||||
#endif
|
||||
|
||||
private const string TargetUnityIphonePodfileLine = "target 'Unity-iPhone' do";
|
||||
private const string UseFrameworksPodfileLine = "use_frameworks!";
|
||||
private const string UseFrameworksDynamicPodfileLine = "use_frameworks! :linkage => :dynamic";
|
||||
private const string UseFrameworksStaticPodfileLine = "use_frameworks! :linkage => :static";
|
||||
|
||||
private const string LegacyResourcesDirectoryName = "Resources";
|
||||
private const string AppLovinMaxResourcesDirectoryName = "AppLovinMAXResources";
|
||||
private const string AppLovinAdvertisingAttributionEndpoint = "https://postbacks-app.com";
|
||||
|
||||
private const string AppLovinSettingsPlistFileName = "AppLovin-Settings.plist";
|
||||
|
||||
private const string KeySdkKey = "SdkKey";
|
||||
|
||||
private const string AppLovinVerboseLoggingOnKey = "AppLovinVerboseLoggingOn";
|
||||
|
||||
private const string KeyConsentFlowInfo = "ConsentFlowInfo";
|
||||
private const string KeyConsentFlowEnabled = "ConsentFlowEnabled";
|
||||
private const string KeyConsentFlowTermsOfService = "ConsentFlowTermsOfService";
|
||||
private const string KeyConsentFlowPrivacyPolicy = "ConsentFlowPrivacyPolicy";
|
||||
private const string KeyConsentFlowDebugUserGeography = "ConsentFlowDebugUserGeography";
|
||||
|
||||
private const string KeyAppLovinSdkKeyToRemove = "AppLovinSdkKey";
|
||||
|
||||
private static readonly Regex PodfilePodLineRegex = new Regex("pod \'([^\']*)\'");
|
||||
|
||||
private static string PluginMediationDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
var pluginParentDir = AppLovinIntegrationManager.MediationSpecificPluginParentDirectory;
|
||||
return Path.Combine(pluginParentDir, "MaxSdk/Mediation/");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds AppLovin Quality Service to the iOS project once the project has been exported.
|
||||
///
|
||||
/// 1. Downloads the Quality Service ruby script.
|
||||
/// 2. Runs the script using Ruby which integrates AppLovin Quality Service to the project.
|
||||
/// </summary>
|
||||
[PostProcessBuild(int.MaxValue)] // We want to run Quality Service script last.
|
||||
public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath)
|
||||
{
|
||||
if (!AppLovinSettings.Instance.QualityServiceEnabled) return;
|
||||
|
||||
var sdkKey = AppLovinSettings.Instance.SdkKey;
|
||||
if (string.IsNullOrEmpty(sdkKey))
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. SDK Key is empty. Please enter the AppLovin SDK Key in the Integration Manager.");
|
||||
return;
|
||||
}
|
||||
|
||||
var outputFilePath = Path.Combine(buildPath, OutputFileName);
|
||||
|
||||
// Check if Quality Service is already installed.
|
||||
if (File.Exists(outputFilePath) && Directory.Exists(Path.Combine(buildPath, "AppLovinQualityService")))
|
||||
{
|
||||
// TODO: Check if there is a way to validate if the SDK key matches the script. Else the pub can't use append when/if they change the SDK Key.
|
||||
return;
|
||||
}
|
||||
|
||||
// Download the ruby script needed to install Quality Service
|
||||
var downloadHandler = new DownloadHandlerFile(outputFilePath);
|
||||
var postJson = string.Format("{{\"sdk_key\" : \"{0}\"}}", sdkKey);
|
||||
var bodyRaw = Encoding.UTF8.GetBytes(postJson);
|
||||
var uploadHandler = new UploadHandlerRaw(bodyRaw);
|
||||
uploadHandler.contentType = "application/json";
|
||||
|
||||
using (var unityWebRequest = new UnityWebRequest("https://api2.safedk.com/v1/build/ios_setup2"))
|
||||
{
|
||||
unityWebRequest.method = UnityWebRequest.kHttpVerbPOST;
|
||||
unityWebRequest.downloadHandler = downloadHandler;
|
||||
unityWebRequest.uploadHandler = uploadHandler;
|
||||
var operation = unityWebRequest.SendWebRequest();
|
||||
|
||||
// Wait for the download to complete or the request to timeout.
|
||||
while (!operation.isDone) { }
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (unityWebRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
|
||||
#endif
|
||||
{
|
||||
MaxSdkLogger.UserError("AppLovin Quality Service installation failed. Failed to download script with error: " + unityWebRequest.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if Ruby is installed
|
||||
var rubyVersion = AppLovinCommandLine.Run("ruby", "--version", buildPath);
|
||||
if (rubyVersion.ExitCode != 0)
|
||||
{
|
||||
MaxSdkLogger.UserError("AppLovin Quality Service installation requires Ruby. Please install Ruby, export it to your system PATH and re-export the project.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Ruby is installed, run `ruby AppLovinQualityServiceSetup.rb`
|
||||
var result = AppLovinCommandLine.Run("ruby", OutputFileName, buildPath);
|
||||
|
||||
// Check if we have an error.
|
||||
if (result.ExitCode != 0) MaxSdkLogger.UserError("Failed to set up AppLovin Quality Service");
|
||||
|
||||
MaxSdkLogger.UserDebug(result.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[PostProcessBuild(int.MaxValue)]
|
||||
public static void MaxPostProcessPbxProject(BuildTarget buildTarget, string buildPath)
|
||||
{
|
||||
var projectPath = PBXProject.GetPBXProjectPath(buildPath);
|
||||
var project = new PBXProject();
|
||||
project.ReadFromFile(projectPath);
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
var unityMainTargetGuid = project.GetUnityMainTargetGuid();
|
||||
var unityFrameworkTargetGuid = project.GetUnityFrameworkTargetGuid();
|
||||
#else
|
||||
var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName);
|
||||
var unityFrameworkTargetGuid = project.TargetGuidByName(UnityMainTargetName);
|
||||
#endif
|
||||
EmbedDynamicLibrariesIfNeeded(buildPath, project, unityMainTargetGuid);
|
||||
|
||||
var internalSettingsEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled;
|
||||
var userTrackingUsageDescriptionDe = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionDe : AppLovinSettings.Instance.UserTrackingUsageDescriptionDe;
|
||||
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionDe, "de", buildPath, project, unityMainTargetGuid);
|
||||
var userTrackingUsageDescriptionEn = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn : AppLovinSettings.Instance.UserTrackingUsageDescriptionEn;
|
||||
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionEn, "en", buildPath, project, unityMainTargetGuid);
|
||||
var userTrackingUsageDescriptionEs = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEs : AppLovinSettings.Instance.UserTrackingUsageDescriptionEs;
|
||||
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionEs, "es", buildPath, project, unityMainTargetGuid);
|
||||
var userTrackingUsageDescriptionFr = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionFr : AppLovinSettings.Instance.UserTrackingUsageDescriptionFr;
|
||||
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionFr, "fr", buildPath, project, unityMainTargetGuid);
|
||||
var userTrackingUsageDescriptionJa = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionJa : AppLovinSettings.Instance.UserTrackingUsageDescriptionJa;
|
||||
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionJa, "ja", buildPath, project, unityMainTargetGuid);
|
||||
var userTrackingUsageDescriptionKo = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionKo : AppLovinSettings.Instance.UserTrackingUsageDescriptionKo;
|
||||
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionKo, "ko", buildPath, project, unityMainTargetGuid);
|
||||
var userTrackingUsageDescriptionZhHans = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHans : AppLovinSettings.Instance.UserTrackingUsageDescriptionZhHans;
|
||||
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionZhHans, "zh-Hans", buildPath, project, unityMainTargetGuid);
|
||||
var userTrackingUsageDescriptionZhHant = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHant : AppLovinSettings.Instance.UserTrackingUsageDescriptionZhHant;
|
||||
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionZhHant, "zh-Hant", buildPath, project, unityMainTargetGuid);
|
||||
|
||||
AddSwiftSupport(buildPath, project, unityFrameworkTargetGuid, unityMainTargetGuid);
|
||||
AddYandexSettingsIfNeeded(project, unityMainTargetGuid);
|
||||
|
||||
project.WriteToFile(projectPath);
|
||||
}
|
||||
|
||||
private static void EmbedDynamicLibrariesIfNeeded(string buildPath, PBXProject project, string targetGuid)
|
||||
{
|
||||
// Check that the Pods directory exists (it might not if a publisher is building with Generate Podfile setting disabled in EDM).
|
||||
var podsDirectory = Path.Combine(buildPath, "Pods");
|
||||
if (!Directory.Exists(podsDirectory) || !ShouldEmbedDynamicLibraries(buildPath)) return;
|
||||
|
||||
var dynamicLibraryPathsToEmbed = GetDynamicLibraryPathsToEmbed(podsDirectory, buildPath);
|
||||
if (dynamicLibraryPathsToEmbed == null || dynamicLibraryPathsToEmbed.Count == 0) return;
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
foreach (var dynamicLibraryPath in dynamicLibraryPathsToEmbed)
|
||||
{
|
||||
var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath);
|
||||
project.AddFileToEmbedFrameworks(targetGuid, fileGuid);
|
||||
}
|
||||
#else
|
||||
string runpathSearchPaths;
|
||||
runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS");
|
||||
runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " ";
|
||||
|
||||
// Check if runtime search paths already contains the required search paths for dynamic libraries.
|
||||
if (runpathSearchPaths.Contains("@executable_path/Frameworks")) return;
|
||||
|
||||
runpathSearchPaths += "@executable_path/Frameworks";
|
||||
project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// |-----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
/// | embed | use_frameworks! (:linkage => :dynamic) | use_frameworks! :linkage => :static | `use_frameworks!` line not present |
|
||||
/// |---------------------------|------------------------------------------|---------------------------------------|--------------------------------------|
|
||||
/// | Unity-iPhone present | Do not embed dynamic libraries | Embed dynamic libraries | Do not embed dynamic libraries |
|
||||
/// | Unity-iPhone not present | Embed dynamic libraries | Embed dynamic libraries | Embed dynamic libraries |
|
||||
/// |-----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
/// </summary>
|
||||
/// <param name="buildPath">An iOS build path</param>
|
||||
/// <returns>Whether or not the dynamic libraries should be embedded.</returns>
|
||||
private static bool ShouldEmbedDynamicLibraries(string buildPath)
|
||||
{
|
||||
var podfilePath = Path.Combine(buildPath, "Podfile");
|
||||
if (!File.Exists(podfilePath)) return false;
|
||||
|
||||
// If the Podfile doesn't have a `Unity-iPhone` target, we should embed the dynamic libraries.
|
||||
var lines = File.ReadAllLines(podfilePath);
|
||||
var containsUnityIphoneTarget = lines.Any(line => line.Contains(TargetUnityIphonePodfileLine));
|
||||
if (!containsUnityIphoneTarget) return true;
|
||||
|
||||
// If the Podfile does not have a `use_frameworks! :linkage => static` line, we should not embed the dynamic libraries.
|
||||
var useFrameworksStaticLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksStaticPodfileLine));
|
||||
if (useFrameworksStaticLineIndex == -1) return false;
|
||||
|
||||
// If more than one of the `use_frameworks!` lines are present, CocoaPods will use the last one.
|
||||
var useFrameworksLineIndex = Array.FindIndex(lines, line => line.Trim() == UseFrameworksPodfileLine); // Check for exact line to avoid matching `use_frameworks! :linkage => static/dynamic`
|
||||
var useFrameworksDynamicLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksDynamicPodfileLine));
|
||||
|
||||
// Check if `use_frameworks! :linkage => :static` is the last line of the three. If it is, we should embed the dynamic libraries.
|
||||
return useFrameworksLineIndex < useFrameworksStaticLineIndex && useFrameworksDynamicLineIndex < useFrameworksStaticLineIndex;
|
||||
}
|
||||
|
||||
private static List<string> GetDynamicLibraryPathsToEmbed(string podsDirectory, string buildPath)
|
||||
{
|
||||
var podfilePath = Path.Combine(buildPath, "Podfile");
|
||||
var dynamicLibraryFrameworksToEmbed = GetDynamicLibraryFrameworksToEmbed(podfilePath);
|
||||
|
||||
return GetDynamicLibraryPathsInProjectToEmbed(podsDirectory, dynamicLibraryFrameworksToEmbed);
|
||||
}
|
||||
|
||||
private static List<string> GetDynamicLibraryFrameworksToEmbed(string podfilePath)
|
||||
{
|
||||
var dynamicLibrariesToEmbed = GetDynamicLibrariesToEmbed();
|
||||
|
||||
var podsInUnityIphoneTarget = GetPodNamesInUnityIphoneTarget(podfilePath);
|
||||
var dynamicLibrariesToIgnore = dynamicLibrariesToEmbed.Where(dynamicLibraryToEmbed => podsInUnityIphoneTarget.Contains(dynamicLibraryToEmbed.PodName)).ToList();
|
||||
|
||||
// Determine frameworks to embed based on the dynamic libraries to embed and ignore
|
||||
var dynamicLibraryFrameworksToIgnore = dynamicLibrariesToIgnore.SelectMany(library => library.FrameworkNames).Distinct().ToList();
|
||||
return dynamicLibrariesToEmbed.SelectMany(library => library.FrameworkNames).Except(dynamicLibraryFrameworksToIgnore).Distinct().ToList();
|
||||
}
|
||||
|
||||
private static List<DynamicLibraryToEmbed> GetDynamicLibrariesToEmbed()
|
||||
{
|
||||
var pluginData = AppLovinIntegrationManager.LoadPluginDataSync();
|
||||
if (pluginData == null)
|
||||
{
|
||||
MaxSdkLogger.E("Failed to load plugin data. Dynamic libraries will not be embedded.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the dynamic libraries to embed for each network
|
||||
var librariesToAdd = pluginData.MediatedNetworks
|
||||
.Where(network => network.DynamicLibrariesToEmbed != null)
|
||||
.SelectMany(network => network.DynamicLibrariesToEmbed
|
||||
.Where(libraryToEmbed => IsRequiredNetworkVersionInstalled(libraryToEmbed, network)))
|
||||
.ToList();
|
||||
|
||||
// Get the dynamic libraries to embed for AppLovin MAX
|
||||
if (pluginData.AppLovinMax.DynamicLibrariesToEmbed != null)
|
||||
{
|
||||
librariesToAdd.AddRange(pluginData.AppLovinMax.DynamicLibrariesToEmbed);
|
||||
}
|
||||
|
||||
// Get the dynamic libraries to embed for third parties
|
||||
if (pluginData.ThirdPartyDynamicLibrariesToEmbed != null)
|
||||
{
|
||||
// TODO: Add version check for third party dynamic libraries.
|
||||
librariesToAdd.AddRange(pluginData.ThirdPartyDynamicLibrariesToEmbed);
|
||||
}
|
||||
|
||||
return librariesToAdd;
|
||||
}
|
||||
|
||||
private static List<string> GetPodNamesInUnityIphoneTarget(string podfilePath)
|
||||
{
|
||||
var lines = File.ReadAllLines(podfilePath);
|
||||
var podNamesInUnityIphone = new List<string>();
|
||||
|
||||
var insideUnityIphoneTarget = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
// Loop until we find the `target 'Unity-iPhone'` line
|
||||
if (insideUnityIphoneTarget)
|
||||
{
|
||||
if (line.Trim() == "end") break;
|
||||
|
||||
if (PodfilePodLineRegex.IsMatch(line))
|
||||
{
|
||||
var podName = PodfilePodLineRegex.Match(line).Groups[1].Value;
|
||||
podNamesInUnityIphone.Add(podName);
|
||||
}
|
||||
}
|
||||
else if (line.Contains(TargetUnityIphonePodfileLine))
|
||||
{
|
||||
insideUnityIphoneTarget = true;
|
||||
}
|
||||
}
|
||||
|
||||
return podNamesInUnityIphone;
|
||||
}
|
||||
|
||||
private static bool IsRequiredNetworkVersionInstalled(DynamicLibraryToEmbed libraryToEmbed, Network network)
|
||||
{
|
||||
var currentIosVersion = network.CurrentVersions.Ios;
|
||||
if (string.IsNullOrEmpty(currentIosVersion)) return false;
|
||||
|
||||
var minIosVersion = libraryToEmbed.MinVersion;
|
||||
var maxIosVersion = libraryToEmbed.MaxVersion;
|
||||
|
||||
var greaterThanOrEqualToMinVersion = string.IsNullOrEmpty(minIosVersion) || MaxSdkUtils.CompareVersions(currentIosVersion, minIosVersion) != VersionComparisonResult.Lesser;
|
||||
var lessThanOrEqualToMaxVersion = string.IsNullOrEmpty(maxIosVersion) || MaxSdkUtils.CompareVersions(currentIosVersion, maxIosVersion) != VersionComparisonResult.Greater;
|
||||
|
||||
return greaterThanOrEqualToMinVersion && lessThanOrEqualToMaxVersion;
|
||||
}
|
||||
|
||||
private static List<string> GetDynamicLibraryPathsInProjectToEmbed(string podsDirectory, List<string> dynamicLibrariesToEmbed)
|
||||
{
|
||||
var dynamicLibraryPathsPresentInProject = new List<string>();
|
||||
foreach (var dynamicLibraryToSearch in dynamicLibrariesToEmbed)
|
||||
{
|
||||
// both .framework and .xcframework are directories, not files
|
||||
var directories = Directory.GetDirectories(podsDirectory, dynamicLibraryToSearch, SearchOption.AllDirectories);
|
||||
if (directories.Length <= 0) continue;
|
||||
|
||||
var dynamicLibraryAbsolutePath = directories[0];
|
||||
var relativePath = GetDynamicLibraryRelativePath(dynamicLibraryAbsolutePath);
|
||||
dynamicLibraryPathsPresentInProject.Add(relativePath);
|
||||
}
|
||||
|
||||
return dynamicLibraryPathsPresentInProject;
|
||||
}
|
||||
|
||||
private static string GetDynamicLibraryRelativePath(string dynamicLibraryAbsolutePath)
|
||||
{
|
||||
var index = dynamicLibraryAbsolutePath.LastIndexOf("Pods", StringComparison.Ordinal);
|
||||
return dynamicLibraryAbsolutePath.Substring(index);
|
||||
}
|
||||
|
||||
private static void LocalizeUserTrackingDescriptionIfNeeded(string localizedUserTrackingDescription, string localeCode, string buildPath, PBXProject project, string targetGuid)
|
||||
{
|
||||
// Use the legacy resources directory name if the build is being appended (the "Resources" directory already exists if it is an incremental build).
|
||||
var resourcesDirectoryName = Directory.Exists(Path.Combine(buildPath, LegacyResourcesDirectoryName)) ? LegacyResourcesDirectoryName : AppLovinMaxResourcesDirectoryName;
|
||||
var resourcesDirectoryPath = Path.Combine(buildPath, resourcesDirectoryName);
|
||||
var localeSpecificDirectoryName = localeCode + ".lproj";
|
||||
var localeSpecificDirectoryPath = Path.Combine(resourcesDirectoryPath, localeSpecificDirectoryName);
|
||||
var infoPlistStringsFilePath = Path.Combine(localeSpecificDirectoryPath, "InfoPlist.strings");
|
||||
|
||||
// Check if localization has been disabled between builds, and remove them as needed.
|
||||
if (ShouldRemoveLocalization(localizedUserTrackingDescription))
|
||||
{
|
||||
if (!File.Exists(infoPlistStringsFilePath)) return;
|
||||
|
||||
File.Delete(infoPlistStringsFilePath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create intermediate directories as needed.
|
||||
if (!Directory.Exists(resourcesDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(resourcesDirectoryPath);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(localeSpecificDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(localeSpecificDirectoryPath);
|
||||
}
|
||||
|
||||
var localizedDescriptionLine = "\"NSUserTrackingUsageDescription\" = \"" + localizedUserTrackingDescription + "\";\n";
|
||||
// File already exists, update it in case the value changed between builds.
|
||||
if (File.Exists(infoPlistStringsFilePath))
|
||||
{
|
||||
var output = new List<string>();
|
||||
var lines = File.ReadAllLines(infoPlistStringsFilePath);
|
||||
var keyUpdated = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line.Contains("NSUserTrackingUsageDescription"))
|
||||
{
|
||||
output.Add(localizedDescriptionLine);
|
||||
keyUpdated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
output.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (!keyUpdated)
|
||||
{
|
||||
output.Add(localizedDescriptionLine);
|
||||
}
|
||||
|
||||
File.WriteAllText(infoPlistStringsFilePath, string.Join("\n", output.ToArray()) + "\n");
|
||||
}
|
||||
// File doesn't exist, create one.
|
||||
else
|
||||
{
|
||||
File.WriteAllText(infoPlistStringsFilePath, "/* Localized versions of Info.plist keys - Generated by AL MAX plugin */\n" + localizedDescriptionLine);
|
||||
}
|
||||
|
||||
var localeSpecificDirectoryRelativePath = Path.Combine(resourcesDirectoryName, localeSpecificDirectoryName);
|
||||
var guid = project.AddFolderReference(localeSpecificDirectoryRelativePath, localeSpecificDirectoryRelativePath);
|
||||
project.AddFileToBuild(targetGuid, guid);
|
||||
}
|
||||
|
||||
private static bool ShouldRemoveLocalization(string localizedUserTrackingDescription)
|
||||
{
|
||||
if (string.IsNullOrEmpty(localizedUserTrackingDescription)) return true;
|
||||
|
||||
var settings = AppLovinSettings.Instance;
|
||||
var internalSettings = AppLovinInternalSettings.Instance;
|
||||
|
||||
return (!internalSettings.ConsentFlowEnabled || !internalSettings.UserTrackingUsageLocalizationEnabled)
|
||||
&& (!settings.ConsentFlowEnabled || !settings.UserTrackingUsageLocalizationEnabled);
|
||||
}
|
||||
|
||||
private static void AddSwiftSupport(string buildPath, PBXProject project, string unityFrameworkTargetGuid, string unityMainTargetGuid)
|
||||
{
|
||||
var swiftFileRelativePath = "Classes/MAXSwiftSupport.swift";
|
||||
var swiftFilePath = Path.Combine(buildPath, swiftFileRelativePath);
|
||||
|
||||
// Add Swift file
|
||||
CreateSwiftFile(swiftFilePath);
|
||||
var swiftFileGuid = project.AddFile(swiftFileRelativePath, swiftFileRelativePath);
|
||||
project.AddFileToBuild(unityFrameworkTargetGuid, swiftFileGuid);
|
||||
|
||||
// Add Swift version property if needed
|
||||
var swiftVersion = project.GetBuildPropertyForAnyConfig(unityFrameworkTargetGuid, "SWIFT_VERSION");
|
||||
if (string.IsNullOrEmpty(swiftVersion))
|
||||
{
|
||||
project.SetBuildProperty(unityFrameworkTargetGuid, "SWIFT_VERSION", "5.0");
|
||||
}
|
||||
|
||||
// Enable Swift modules
|
||||
project.AddBuildProperty(unityFrameworkTargetGuid, "CLANG_ENABLE_MODULES", "YES");
|
||||
project.AddBuildProperty(unityMainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
|
||||
}
|
||||
|
||||
private static void CreateSwiftFile(string swiftFilePath)
|
||||
{
|
||||
if (File.Exists(swiftFilePath)) return;
|
||||
|
||||
// Create a file to write to.
|
||||
using (var writer = File.CreateText(swiftFilePath))
|
||||
{
|
||||
writer.WriteLine("//\n// MAXSwiftSupport.swift\n//");
|
||||
writer.WriteLine("\nimport Foundation\n");
|
||||
writer.WriteLine("// This file ensures the project includes Swift support.");
|
||||
writer.WriteLine("// It is automatically generated by the MAX Unity Plugin.");
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[PostProcessBuild(int.MaxValue)]
|
||||
public static void MaxPostProcessPlist(BuildTarget buildTarget, string path)
|
||||
{
|
||||
var plistPath = Path.Combine(path, "Info.plist");
|
||||
var plist = new PlistDocument();
|
||||
plist.ReadFromFile(plistPath);
|
||||
|
||||
SetAttributionReportEndpointIfNeeded(plist);
|
||||
|
||||
EnableVerboseLoggingIfNeeded(plist);
|
||||
AddGoogleApplicationIdIfNeeded(plist);
|
||||
|
||||
AddSdkSettings(plist, path);
|
||||
EnableTermsFlowIfNeeded(plist);
|
||||
AddSkAdNetworksInfoIfNeeded(plist);
|
||||
RemoveSdkKeyIfNeeded(plist);
|
||||
|
||||
plist.WriteToFile(plistPath);
|
||||
}
|
||||
|
||||
private static void SetAttributionReportEndpointIfNeeded(PlistDocument plist)
|
||||
{
|
||||
if (AppLovinSettings.Instance.SetAttributionReportEndpoint)
|
||||
{
|
||||
plist.root.SetString("NSAdvertisingAttributionReportEndpoint", AppLovinAdvertisingAttributionEndpoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlistElement attributionReportEndPoint;
|
||||
plist.root.values.TryGetValue("NSAdvertisingAttributionReportEndpoint", out attributionReportEndPoint);
|
||||
|
||||
// Check if we had previously set the attribution endpoint and un-set it.
|
||||
if (attributionReportEndPoint != null && AppLovinAdvertisingAttributionEndpoint.Equals(attributionReportEndPoint.AsString()))
|
||||
{
|
||||
plist.root.values.Remove("NSAdvertisingAttributionReportEndpoint");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnableVerboseLoggingIfNeeded(PlistDocument plist)
|
||||
{
|
||||
if (!EditorPrefs.HasKey(MaxSdkLogger.KeyVerboseLoggingEnabled)) return;
|
||||
|
||||
var enabled = EditorPrefs.GetBool(MaxSdkLogger.KeyVerboseLoggingEnabled);
|
||||
if (enabled)
|
||||
{
|
||||
plist.root.SetBoolean(AppLovinVerboseLoggingOnKey, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
plist.root.values.Remove(AppLovinVerboseLoggingOnKey);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddGoogleApplicationIdIfNeeded(PlistDocument plist)
|
||||
{
|
||||
if (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.IsAdapterInstalled("GoogleAdManager")) return;
|
||||
|
||||
const string googleApplicationIdentifier = "GADApplicationIdentifier";
|
||||
var appId = AppLovinSettings.Instance.AdMobIosAppId;
|
||||
// Log error if the App ID is not set.
|
||||
if (string.IsNullOrEmpty(appId) || !appId.StartsWith("ca-app-pub-"))
|
||||
{
|
||||
MaxSdkLogger.UserError("[AppLovin MAX] Google App ID is not set. Please enter a valid app ID within the AppLovin Integration Manager window.");
|
||||
return;
|
||||
}
|
||||
|
||||
plist.root.SetString(googleApplicationIdentifier, appId);
|
||||
}
|
||||
|
||||
private static void AddYandexSettingsIfNeeded(PBXProject project, string unityMainTargetGuid)
|
||||
{
|
||||
if (!AppLovinIntegrationManager.IsAdapterInstalled("Yandex")) return;
|
||||
|
||||
if (MaxSdkUtils.CompareVersions(PlayerSettings.iOS.targetOSVersionString, "12.0") == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Your iOS target version is under the minimum required version by Yandex. Please update it to 12.0 or newer in your ProjectSettings and rebuild your project.");
|
||||
return;
|
||||
}
|
||||
|
||||
project.SetBuildProperty(unityMainTargetGuid, "GENERATE_INFOPLIST_FILE", "NO");
|
||||
}
|
||||
|
||||
private static void AddSdkSettings(PlistDocument infoPlist, string buildPath)
|
||||
{
|
||||
var sdkSettingsPlistPath = Path.Combine(buildPath, AppLovinSettingsPlistFileName);
|
||||
var sdkSettingsPlist = new PlistDocument();
|
||||
if (File.Exists(sdkSettingsPlistPath))
|
||||
{
|
||||
sdkSettingsPlist.ReadFromFile(sdkSettingsPlistPath);
|
||||
}
|
||||
|
||||
// Add the SDK key to the SDK settings plist.
|
||||
sdkSettingsPlist.root.SetString(KeySdkKey, AppLovinSettings.Instance.SdkKey);
|
||||
|
||||
// Add consent flow settings if needed.
|
||||
EnableConsentFlowIfNeeded(sdkSettingsPlist, infoPlist);
|
||||
|
||||
sdkSettingsPlist.WriteToFile(sdkSettingsPlistPath);
|
||||
|
||||
var projectPath = PBXProject.GetPBXProjectPath(buildPath);
|
||||
var project = new PBXProject();
|
||||
project.ReadFromFile(projectPath);
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
var unityMainTargetGuid = project.GetUnityMainTargetGuid();
|
||||
#else
|
||||
var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName);
|
||||
#endif
|
||||
|
||||
var guid = project.AddFile(AppLovinSettingsPlistFileName, AppLovinSettingsPlistFileName, PBXSourceTree.Source);
|
||||
project.AddFileToBuild(unityMainTargetGuid, guid);
|
||||
project.WriteToFile(projectPath);
|
||||
}
|
||||
|
||||
private static void EnableConsentFlowIfNeeded(PlistDocument applovinSettingsPlist, PlistDocument infoPlist)
|
||||
{
|
||||
var consentFlowEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled;
|
||||
if (!consentFlowEnabled) return;
|
||||
|
||||
var userTrackingUsageDescription = AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn;
|
||||
var privacyPolicyUrl = AppLovinInternalSettings.Instance.ConsentFlowPrivacyPolicyUrl;
|
||||
if (string.IsNullOrEmpty(userTrackingUsageDescription) || string.IsNullOrEmpty(privacyPolicyUrl))
|
||||
{
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL and the `User Tracking Usage Description` in the AppLovin Integration Manager. \n\n" +
|
||||
"Both values must be included to enable the SDK's consent flow.");
|
||||
|
||||
// No need to update the info.plist here. Default consent flow state will be determined on the SDK side.
|
||||
return;
|
||||
}
|
||||
|
||||
var consentFlowInfoRoot = applovinSettingsPlist.root.CreateDict(KeyConsentFlowInfo);
|
||||
consentFlowInfoRoot.SetBoolean(KeyConsentFlowEnabled, consentFlowEnabled);
|
||||
consentFlowInfoRoot.SetString(KeyConsentFlowPrivacyPolicy, privacyPolicyUrl);
|
||||
|
||||
var termsOfServiceUrl = AppLovinInternalSettings.Instance.ConsentFlowTermsOfServiceUrl;
|
||||
if (MaxSdkUtils.IsValidString(termsOfServiceUrl))
|
||||
{
|
||||
consentFlowInfoRoot.SetString(KeyConsentFlowTermsOfService, termsOfServiceUrl);
|
||||
}
|
||||
|
||||
var debugUserGeography = AppLovinInternalSettings.Instance.DebugUserGeography;
|
||||
if (debugUserGeography == MaxSdkBase.ConsentFlowUserGeography.Gdpr)
|
||||
{
|
||||
consentFlowInfoRoot.SetString(KeyConsentFlowDebugUserGeography, "gdpr");
|
||||
}
|
||||
|
||||
infoPlist.root.SetString("NSUserTrackingUsageDescription", userTrackingUsageDescription);
|
||||
}
|
||||
|
||||
private static void EnableTermsFlowIfNeeded(PlistDocument plist)
|
||||
{
|
||||
// Check if terms flow is enabled. No need to update info.plist if consent flow is disabled.
|
||||
var consentFlowEnabled = AppLovinSettings.Instance.ConsentFlowEnabled;
|
||||
if (!consentFlowEnabled) return;
|
||||
|
||||
// Check if terms flow is enabled for this format.
|
||||
var consentFlowPlatform = AppLovinSettings.Instance.ConsentFlowPlatform;
|
||||
if (consentFlowPlatform != Platform.All && consentFlowPlatform != Platform.iOS) return;
|
||||
|
||||
var userTrackingUsageDescription = AppLovinSettings.Instance.UserTrackingUsageDescriptionEn;
|
||||
var privacyPolicyUrl = AppLovinSettings.Instance.ConsentFlowPrivacyPolicyUrl;
|
||||
if (string.IsNullOrEmpty(userTrackingUsageDescription) || string.IsNullOrEmpty(privacyPolicyUrl))
|
||||
{
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL and the `User Tracking Usage Description` in the AppLovin Integration Manager. \n\n" +
|
||||
"Both values must be included to enable the SDK's consent flow.");
|
||||
|
||||
// No need to update the info.plist here. Default consent flow state will be determined on the SDK side.
|
||||
return;
|
||||
}
|
||||
|
||||
var consentFlowInfoRoot = plist.root.CreateDict("AppLovinConsentFlowInfo");
|
||||
consentFlowInfoRoot.SetBoolean("AppLovinConsentFlowEnabled", true);
|
||||
consentFlowInfoRoot.SetString("AppLovinConsentFlowPrivacyPolicy", privacyPolicyUrl);
|
||||
|
||||
var termsOfServiceUrl = AppLovinSettings.Instance.ConsentFlowTermsOfServiceUrl;
|
||||
if (!string.IsNullOrEmpty(termsOfServiceUrl))
|
||||
{
|
||||
consentFlowInfoRoot.SetString("AppLovinConsentFlowTermsOfService", termsOfServiceUrl);
|
||||
}
|
||||
|
||||
plist.root.SetString("NSUserTrackingUsageDescription", userTrackingUsageDescription);
|
||||
}
|
||||
|
||||
private static void AddSkAdNetworksInfoIfNeeded(PlistDocument plist)
|
||||
{
|
||||
var skAdNetworkData = GetSkAdNetworkData();
|
||||
var skAdNetworkIds = skAdNetworkData.SkAdNetworkIds;
|
||||
// Check if we have a valid list of SKAdNetworkIds that need to be added.
|
||||
if (skAdNetworkIds == null || skAdNetworkIds.Length < 1) return;
|
||||
|
||||
//
|
||||
// Add the SKAdNetworkItems to the plist. It should look like following:
|
||||
//
|
||||
// <key>SKAdNetworkItems</key>
|
||||
// <array>
|
||||
// <dict>
|
||||
// <key>SKAdNetworkIdentifier</key>
|
||||
// <string>ABC123XYZ.skadnetwork</string>
|
||||
// </dict>
|
||||
// <dict>
|
||||
// <key>SKAdNetworkIdentifier</key>
|
||||
// <string>123QWE456.skadnetwork</string>
|
||||
// </dict>
|
||||
// <dict>
|
||||
// <key>SKAdNetworkIdentifier</key>
|
||||
// <string>987XYZ123.skadnetwork</string>
|
||||
// </dict>
|
||||
// </array>
|
||||
//
|
||||
PlistElement skAdNetworkItems;
|
||||
plist.root.values.TryGetValue("SKAdNetworkItems", out skAdNetworkItems);
|
||||
var existingSkAdNetworkIds = new HashSet<string>();
|
||||
// Check if SKAdNetworkItems array is already in the Plist document and collect all the IDs that are already present.
|
||||
if (skAdNetworkItems != null && skAdNetworkItems.GetType() == typeof(PlistElementArray))
|
||||
{
|
||||
var plistElementDictionaries = skAdNetworkItems.AsArray().values.Where(plistElement => plistElement.GetType() == typeof(PlistElementDict));
|
||||
foreach (var plistElement in plistElementDictionaries)
|
||||
{
|
||||
PlistElement existingId;
|
||||
plistElement.AsDict().values.TryGetValue("SKAdNetworkIdentifier", out existingId);
|
||||
if (existingId == null || existingId.GetType() != typeof(PlistElementString) || string.IsNullOrEmpty(existingId.AsString())) continue;
|
||||
|
||||
existingSkAdNetworkIds.Add(existingId.AsString());
|
||||
}
|
||||
}
|
||||
// Else, create an array of SKAdNetworkItems into which we will add our IDs.
|
||||
else
|
||||
{
|
||||
skAdNetworkItems = plist.root.CreateArray("SKAdNetworkItems");
|
||||
}
|
||||
|
||||
foreach (var skAdNetworkId in skAdNetworkIds)
|
||||
{
|
||||
// Skip adding IDs that are already in the array.
|
||||
if (existingSkAdNetworkIds.Contains(skAdNetworkId)) continue;
|
||||
|
||||
var skAdNetworkItemDict = skAdNetworkItems.AsArray().AddDict();
|
||||
skAdNetworkItemDict.SetString("SKAdNetworkIdentifier", skAdNetworkId);
|
||||
}
|
||||
}
|
||||
|
||||
private static SkAdNetworkData GetSkAdNetworkData()
|
||||
{
|
||||
var uriBuilder = new UriBuilder("https://unity.applovin.com/max/1.0/skadnetwork_ids");
|
||||
|
||||
// Get the list of installed ad networks to be passed up
|
||||
var maxMediationDirectory = PluginMediationDirectory;
|
||||
if (Directory.Exists(maxMediationDirectory))
|
||||
{
|
||||
var mediationNetworkDirectories = Directory.GetDirectories(maxMediationDirectory);
|
||||
var installedNetworks = mediationNetworkDirectories.Select(Path.GetFileName).ToList();
|
||||
if (AppLovinSettings.Instance.AddApsSkAdNetworkIds)
|
||||
{
|
||||
installedNetworks.Add("AmazonAdMarketplace");
|
||||
}
|
||||
|
||||
var adNetworks = string.Join(",", installedNetworks.ToArray());
|
||||
if (!string.IsNullOrEmpty(adNetworks))
|
||||
{
|
||||
uriBuilder.Query += string.Format("ad_networks={0}", adNetworks);
|
||||
}
|
||||
}
|
||||
|
||||
using (var unityWebRequest = UnityWebRequest.Get(uriBuilder.ToString()))
|
||||
{
|
||||
var operation = unityWebRequest.SendWebRequest();
|
||||
// Wait for the download to complete or the request to timeout.
|
||||
while (!operation.isDone) { }
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (unityWebRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
|
||||
#endif
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to retrieve SKAdNetwork IDs with error: " + unityWebRequest.error);
|
||||
return new SkAdNetworkData();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return JsonUtility.FromJson<SkAdNetworkData>(unityWebRequest.downloadHandler.text);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to parse data '" + unityWebRequest.downloadHandler.text + "' with exception: " + exception);
|
||||
return new SkAdNetworkData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveSdkKeyIfNeeded(PlistDocument plist)
|
||||
{
|
||||
if (!plist.root.values.ContainsKey(KeyAppLovinSdkKeyToRemove)) return;
|
||||
|
||||
plist.root.values.Remove(KeyAppLovinSdkKeyToRemove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5d209f90444f4a90830b48b5f3f3ff4
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessiOS.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// AppLovinPreProcess.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Jonathan Liu on 10/19/2023.
|
||||
// Copyright © 2023 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public abstract class AppLovinPreProcess
|
||||
{
|
||||
private const string AppLovinDependenciesFileExportPath = "MaxSdk/AppLovin/Editor/Dependencies.xml";
|
||||
|
||||
private static readonly XmlWriterSettings DependenciesFileXmlWriterSettings = new XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
IndentChars = " ",
|
||||
NewLineChars = "\n",
|
||||
NewLineHandling = NewLineHandling.Replace
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Adds a string into AppLovin's Dependencies.xml file inside the containerElementString if it doesn't exist
|
||||
/// </summary>
|
||||
/// <param name="lineToAdd">The line you want to add into the xml file</param>
|
||||
/// <param name="containerElementString">The root XML element under which to add the line. For example, to add a new dependency to Android, pass in "androidPackages"</param>
|
||||
protected static void TryAddStringToDependencyFile(string lineToAdd, string containerElementString)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dependenciesFilePath = MaxSdkUtils.GetAssetPathForExportPath(AppLovinDependenciesFileExportPath);
|
||||
var dependencies = XDocument.Load(dependenciesFilePath);
|
||||
// Get the container where we are going to insert the line
|
||||
var containerElement = dependencies.Descendants(containerElementString).FirstOrDefault();
|
||||
|
||||
if (containerElement == null)
|
||||
{
|
||||
MaxSdkLogger.E(containerElementString + " not found in Dependencies.xml file");
|
||||
return;
|
||||
}
|
||||
|
||||
var elementToAdd = XElement.Parse(lineToAdd);
|
||||
|
||||
// Check if the xml file doesn't already contain the string.
|
||||
if (containerElement.Elements().Any(element => XNode.DeepEquals(element, elementToAdd))) return;
|
||||
|
||||
// Append the new element to the container element
|
||||
containerElement.Add(elementToAdd);
|
||||
|
||||
using (var xmlWriter = XmlWriter.Create(dependenciesFilePath, DependenciesFileXmlWriterSettings))
|
||||
{
|
||||
dependencies.Save(xmlWriter);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Google CMP will not function. Unable to add string to dependency file due to exception: " + exception.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a string from AppLovin's Dependencies.xml file inside the containerElementString if it exists
|
||||
/// </summary>
|
||||
/// <param name="lineToRemove">The line you want to remove from the xml file</param>
|
||||
/// <param name="containerElementString">The root XML element from which to remove the line. For example, to remove an Android dependency, pass in "androidPackages"</param>
|
||||
protected static void TryRemoveStringFromDependencyFile(string lineToRemove, string containerElementString)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dependenciesFilePath = MaxSdkUtils.GetAssetPathForExportPath(AppLovinDependenciesFileExportPath);
|
||||
var dependencies = XDocument.Load(dependenciesFilePath);
|
||||
var containerElement = dependencies.Descendants(containerElementString).FirstOrDefault();
|
||||
|
||||
if (containerElement == null)
|
||||
{
|
||||
MaxSdkLogger.E(containerElementString + " not found in Dependencies.xml file");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the dependency line exists.
|
||||
var elementToFind = XElement.Parse(lineToRemove);
|
||||
var existingElement = containerElement.Elements().FirstOrDefault(element => XNode.DeepEquals(element, elementToFind));
|
||||
if (existingElement == null) return;
|
||||
|
||||
existingElement.Remove();
|
||||
|
||||
using (var xmlWriter = XmlWriter.Create(dependenciesFilePath, DependenciesFileXmlWriterSettings))
|
||||
{
|
||||
dependencies.Save(xmlWriter);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Unable to remove string from dependency file due to exception: " + exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e6254f24e89548b3a7644fa7bf25f9d
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPreProcess.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// AppLovinBuildPreProcessor.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 8/27/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_ANDROID
|
||||
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the AppLovin Quality Service plugin to the gradle template file. See <see cref="AppLovinProcessGradleBuildFile"/> for more details.
|
||||
/// </summary>
|
||||
public class AppLovinPreProcessAndroid : AppLovinProcessGradleBuildFile, IPreprocessBuildWithReport
|
||||
{
|
||||
private const string UmpLegacyDependencyLine = "<androidPackage spec=\"com.google.android.ump:user-messaging-platform:2.1.0\" />";
|
||||
private const string UmpDependencyLine = "<androidPackage spec=\"com.google.android.ump:user-messaging-platform:2.+\" />";
|
||||
private const string AndroidPackagesContainerElementString = "androidPackages";
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
PreprocessAppLovinQualityServicePlugin();
|
||||
AddGoogleCmpDependencyIfNeeded();
|
||||
}
|
||||
|
||||
private static void PreprocessAppLovinQualityServicePlugin()
|
||||
{
|
||||
// We can only process gradle template file here. If it is not available, we will try again in post build on Unity IDEs newer than 2018_2 (see AppLovinPostProcessGradleProject).
|
||||
if (!AppLovinIntegrationManager.GradleTemplateEnabled) return;
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
// The publisher could be migrating from older Unity versions to 2019_3 or newer.
|
||||
// If so, we should delete the plugin from the template. The plugin will be added to the project's application module in the post processing script (AppLovinPostProcessGradleProject).
|
||||
RemoveAppLovinQualityServiceOrSafeDkPlugin(AppLovinIntegrationManager.GradleTemplatePath);
|
||||
#else
|
||||
AddAppLovinQualityServicePlugin(AppLovinIntegrationManager.GradleTemplatePath);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void AddGoogleCmpDependencyIfNeeded()
|
||||
{
|
||||
// Remove the legacy fixed UMP version if it exists, we'll add the dependency with a dynamic version below.
|
||||
TryRemoveStringFromDependencyFile(UmpLegacyDependencyLine, AndroidPackagesContainerElementString);
|
||||
|
||||
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled)
|
||||
{
|
||||
TryAddStringToDependencyFile(UmpDependencyLine, AndroidPackagesContainerElementString);
|
||||
}
|
||||
else
|
||||
{
|
||||
TryRemoveStringFromDependencyFile(UmpDependencyLine, AndroidPackagesContainerElementString);
|
||||
}
|
||||
}
|
||||
|
||||
public int callbackOrder
|
||||
{
|
||||
get { return int.MaxValue; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ccaf444d0d4f4cadb5debe7c41b20c4
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPreProcessAndroid.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// AppLovinBuildPreProcessiOS.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Jonathan Liu on 10/17/2023.
|
||||
// Copyright © 2023 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_IOS
|
||||
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public class AppLovinPreProcessiOS : AppLovinPreProcess, IPreprocessBuildWithReport
|
||||
{
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
AddGoogleCmpDependencyIfNeeded();
|
||||
}
|
||||
|
||||
private const string UmpLegacyDependencyLine = "<iosPod name=\"GoogleUserMessagingPlatform\" version=\"2.1.0\" />";
|
||||
private const string UmpDependencyLine = "<iosPod name=\"GoogleUserMessagingPlatform\" version=\"~> 2.1\" />";
|
||||
private const string IosPodsContainerElementString = "iosPods";
|
||||
|
||||
private static void AddGoogleCmpDependencyIfNeeded()
|
||||
{
|
||||
// Remove the legacy fixed UMP version if it exists, we'll add the dependency with a dynamic version below.
|
||||
TryRemoveStringFromDependencyFile(UmpLegacyDependencyLine, IosPodsContainerElementString);
|
||||
|
||||
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled)
|
||||
{
|
||||
TryAddStringToDependencyFile(UmpDependencyLine, IosPodsContainerElementString);
|
||||
}
|
||||
else
|
||||
{
|
||||
TryRemoveStringFromDependencyFile(UmpDependencyLine, IosPodsContainerElementString);
|
||||
}
|
||||
}
|
||||
|
||||
public int callbackOrder
|
||||
{
|
||||
get { return int.MaxValue; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee45537a5833240d7afcfac4a38df1b9
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPreProcessiOS.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,577 @@
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 9/3/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_ANDROID
|
||||
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class AppLovinQualityServiceData
|
||||
{
|
||||
public string api_key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or updates the AppLovin Quality Service plugin to the provided build.gradle file.
|
||||
/// If the gradle file already has the plugin, the API key is updated.
|
||||
/// </summary>
|
||||
public abstract class AppLovinProcessGradleBuildFile : AppLovinPreProcess
|
||||
{
|
||||
private static readonly Regex TokenBuildScriptRepositories = new Regex(".*repositories.*");
|
||||
private static readonly Regex TokenBuildScriptDependencies = new Regex(".*classpath \'com.android.tools.build:gradle.*");
|
||||
private static readonly Regex TokenApplicationPlugin = new Regex(".*apply plugin: \'com.android.application\'.*");
|
||||
private static readonly Regex TokenApiKey = new Regex(".*apiKey.*");
|
||||
private static readonly Regex TokenAppLovinPlugin = new Regex(".*apply plugin:.+?(?=applovin-quality-service).*");
|
||||
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
private const string PluginsMatcher = "plugins";
|
||||
private const string PluginManagementMatcher = "pluginManagement";
|
||||
private const string QualityServicePluginRoot = " id 'com.applovin.quality' version '+' apply false // NOTE: Requires version 4.8.3+ for Gradle version 7.2+";
|
||||
#endif
|
||||
|
||||
private const string BuildScriptMatcher = "buildscript";
|
||||
private const string QualityServiceMavenRepo = "maven { url 'https://artifacts.applovin.com/android'; content { includeGroupByRegex 'com.applovin.*' } }";
|
||||
private const string QualityServiceDependencyClassPath = "classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:+'";
|
||||
private const string QualityServiceApplyPlugin = "apply plugin: 'applovin-quality-service'";
|
||||
private const string QualityServicePlugin = "applovin {";
|
||||
private const string QualityServiceApiKey = " apiKey '{0}'";
|
||||
private const string QualityServiceBintrayMavenRepo = "https://applovin.bintray.com/Quality-Service";
|
||||
private const string QualityServiceNoRegexMavenRepo = "maven { url 'https://artifacts.applovin.com/android' }";
|
||||
|
||||
// Legacy plugin detection variables
|
||||
private const string QualityServiceDependencyClassPathV3 = "classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:3.+'";
|
||||
private static readonly Regex TokenSafeDkLegacyApplyPlugin = new Regex(".*apply plugin:.+?(?=safedk).*");
|
||||
private const string SafeDkLegacyPlugin = "safedk {";
|
||||
private const string SafeDkLegacyMavenRepo = "http://download.safedk.com";
|
||||
private const string SafeDkLegacyDependencyClassPath = "com.safedk:SafeDKGradlePlugin:";
|
||||
|
||||
/// <summary>
|
||||
/// Updates the provided Gradle script to add Quality Service plugin.
|
||||
/// </summary>
|
||||
/// <param name="applicationGradleBuildFilePath">The gradle file to update.</param>
|
||||
protected static void AddAppLovinQualityServicePlugin(string applicationGradleBuildFilePath)
|
||||
{
|
||||
if (!AppLovinSettings.Instance.QualityServiceEnabled) return;
|
||||
|
||||
var sdkKey = AppLovinSettings.Instance.SdkKey;
|
||||
if (string.IsNullOrEmpty(sdkKey))
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. SDK Key is empty. Please enter the AppLovin SDK Key in the Integration Manager.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the API Key using the SDK Key.
|
||||
var qualityServiceData = RetrieveQualityServiceData(sdkKey);
|
||||
var apiKey = qualityServiceData.api_key;
|
||||
if (string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. API Key is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate the updated Gradle file that needs to be written.
|
||||
var lines = File.ReadAllLines(applicationGradleBuildFilePath).ToList();
|
||||
var sanitizedLines = RemoveLegacySafeDkPlugin(lines);
|
||||
var outputLines = GenerateUpdatedBuildFileLines(
|
||||
sanitizedLines,
|
||||
apiKey,
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
false // On Unity 2019.3+, the buildscript closure related lines will to be added to the root build.gradle file.
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
);
|
||||
// outputLines can be null if we couldn't add the plugin.
|
||||
if (outputLines == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(applicationGradleBuildFilePath, string.Join("\n", outputLines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Gradle file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
/// <summary>
|
||||
/// Adds AppLovin Quality Service plugin DSL element to the project's root build.gradle file.
|
||||
/// </summary>
|
||||
/// <param name="rootGradleBuildFile">The path to project's root build.gradle file.</param>
|
||||
/// <returns><c>true</c> when the plugin was added successfully.</returns>
|
||||
protected bool AddPluginToRootGradleBuildFile(string rootGradleBuildFile)
|
||||
{
|
||||
var lines = File.ReadAllLines(rootGradleBuildFile).ToList();
|
||||
|
||||
// Check if the plugin is already added to the file.
|
||||
var pluginAdded = lines.Any(line => line.Contains(QualityServicePluginRoot));
|
||||
if (pluginAdded) return true;
|
||||
|
||||
var outputLines = new List<string>();
|
||||
var insidePluginsClosure = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line.Contains(PluginsMatcher))
|
||||
{
|
||||
insidePluginsClosure = true;
|
||||
}
|
||||
|
||||
if (!pluginAdded && insidePluginsClosure && line.Contains("}"))
|
||||
{
|
||||
outputLines.Add(QualityServicePluginRoot);
|
||||
pluginAdded = true;
|
||||
insidePluginsClosure = false;
|
||||
}
|
||||
|
||||
outputLines.Add(line);
|
||||
}
|
||||
|
||||
if (!pluginAdded)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin to root gradle file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(rootGradleBuildFile, string.Join("\n", outputLines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Root Gradle file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the AppLovin maven repository to the project's settings.gradle file.
|
||||
/// </summary>
|
||||
/// <param name="settingsGradleFile">The path to the project's settings.gradle file.</param>
|
||||
/// <returns><c>true</c> if the repository was added successfully.</returns>
|
||||
protected bool AddAppLovinRepository(string settingsGradleFile)
|
||||
{
|
||||
var lines = File.ReadLines(settingsGradleFile).ToList();
|
||||
var outputLines = new List<string>();
|
||||
var mavenRepoAdded = false;
|
||||
var pluginManagementClosureDepth = 0;
|
||||
var insidePluginManagementClosure = false;
|
||||
var pluginManagementMatched = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
outputLines.Add(line);
|
||||
|
||||
if (!pluginManagementMatched && line.Contains(PluginManagementMatcher))
|
||||
{
|
||||
pluginManagementMatched = true;
|
||||
insidePluginManagementClosure = true;
|
||||
}
|
||||
|
||||
if (insidePluginManagementClosure)
|
||||
{
|
||||
if (line.Contains("{"))
|
||||
{
|
||||
pluginManagementClosureDepth++;
|
||||
}
|
||||
|
||||
if (line.Contains("}"))
|
||||
{
|
||||
pluginManagementClosureDepth--;
|
||||
}
|
||||
|
||||
if (pluginManagementClosureDepth == 0)
|
||||
{
|
||||
insidePluginManagementClosure = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (insidePluginManagementClosure)
|
||||
{
|
||||
if (!mavenRepoAdded && TokenBuildScriptRepositories.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
|
||||
mavenRepoAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mavenRepoAdded)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin maven repo to settings gradle file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(settingsGradleFile, string.Join("\n", outputLines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Setting Gradle file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
/// <summary>
|
||||
/// Adds the necessary AppLovin Quality Service dependency and maven repo lines to the provided root build.gradle file.
|
||||
/// </summary>
|
||||
/// <param name="rootGradleBuildFile">The root build.gradle file path</param>
|
||||
/// <returns><c>true</c> if the build script lines were applied correctly.</returns>
|
||||
protected bool AddQualityServiceBuildScriptLines(string rootGradleBuildFile)
|
||||
{
|
||||
var lines = File.ReadAllLines(rootGradleBuildFile).ToList();
|
||||
var outputLines = GenerateUpdatedBuildFileLines(lines, null, true);
|
||||
|
||||
// outputLines will be null if we couldn't add the build script lines.
|
||||
if (outputLines == null) return false;
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(rootGradleBuildFile, string.Join("\n", outputLines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Root Gradle file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the AppLovin Quality Service Plugin or Legacy SafeDK plugin from the given gradle template file if either of them are present.
|
||||
/// </summary>
|
||||
/// <param name="gradleTemplateFile">The gradle template file from which to remove the plugin from</param>
|
||||
protected static void RemoveAppLovinQualityServiceOrSafeDkPlugin(string gradleTemplateFile)
|
||||
{
|
||||
var lines = File.ReadAllLines(gradleTemplateFile).ToList();
|
||||
lines = RemoveLegacySafeDkPlugin(lines);
|
||||
lines = RemoveAppLovinQualityServicePlugin(lines);
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(gradleTemplateFile, string.Join("\n", lines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to remove AppLovin Quality Service Plugin from mainTemplate.gradle. Please remove the Quality Service plugin from the mainTemplate.gradle manually.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private static AppLovinQualityServiceData RetrieveQualityServiceData(string sdkKey)
|
||||
{
|
||||
var postJson = string.Format("{{\"sdk_key\" : \"{0}\"}}", sdkKey);
|
||||
var bodyRaw = Encoding.UTF8.GetBytes(postJson);
|
||||
// Upload handler is automatically disposed when UnityWebRequest is disposed
|
||||
var uploadHandler = new UploadHandlerRaw(bodyRaw);
|
||||
uploadHandler.contentType = "application/json";
|
||||
|
||||
using (var unityWebRequest = new UnityWebRequest("https://api2.safedk.com/v1/build/cred"))
|
||||
{
|
||||
unityWebRequest.method = UnityWebRequest.kHttpVerbPOST;
|
||||
unityWebRequest.uploadHandler = uploadHandler;
|
||||
unityWebRequest.downloadHandler = new DownloadHandlerBuffer();
|
||||
|
||||
var operation = unityWebRequest.SendWebRequest();
|
||||
|
||||
// Wait for the download to complete or the request to timeout.
|
||||
while (!operation.isDone) { }
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (unityWebRequest.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
|
||||
#endif
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to retrieve API Key for SDK Key: " + sdkKey + "with error: " + unityWebRequest.error);
|
||||
return new AppLovinQualityServiceData();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return JsonUtility.FromJson<AppLovinQualityServiceData>(unityWebRequest.downloadHandler.text);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to parse API Key." + exception);
|
||||
return new AppLovinQualityServiceData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<string> RemoveLegacySafeDkPlugin(List<string> lines)
|
||||
{
|
||||
return RemovePlugin(lines, SafeDkLegacyPlugin, SafeDkLegacyMavenRepo, SafeDkLegacyDependencyClassPath, TokenSafeDkLegacyApplyPlugin);
|
||||
}
|
||||
|
||||
private static List<string> RemoveAppLovinQualityServicePlugin(List<string> lines)
|
||||
{
|
||||
return RemovePlugin(lines, QualityServicePlugin, QualityServiceMavenRepo, QualityServiceDependencyClassPath, TokenAppLovinPlugin);
|
||||
}
|
||||
|
||||
private static List<string> RemovePlugin(List<string> lines, string pluginLine, string mavenRepo, string dependencyClassPath, Regex applyPluginToken)
|
||||
{
|
||||
var sanitizedLines = new List<string>();
|
||||
var legacyRepoRemoved = false;
|
||||
var legacyDependencyClassPathRemoved = false;
|
||||
var legacyPluginRemoved = false;
|
||||
var legacyPluginMatched = false;
|
||||
var insideLegacySafeDkClosure = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (!legacyPluginMatched && line.Contains(pluginLine))
|
||||
{
|
||||
legacyPluginMatched = true;
|
||||
insideLegacySafeDkClosure = true;
|
||||
}
|
||||
|
||||
if (insideLegacySafeDkClosure && line.Contains("}"))
|
||||
{
|
||||
insideLegacySafeDkClosure = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (insideLegacySafeDkClosure)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!legacyRepoRemoved && line.Contains(mavenRepo))
|
||||
{
|
||||
legacyRepoRemoved = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!legacyDependencyClassPathRemoved && line.Contains(dependencyClassPath))
|
||||
{
|
||||
legacyDependencyClassPathRemoved = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!legacyPluginRemoved && applyPluginToken.IsMatch(line))
|
||||
{
|
||||
legacyPluginRemoved = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
sanitizedLines.Add(line);
|
||||
}
|
||||
|
||||
return sanitizedLines;
|
||||
}
|
||||
|
||||
private static List<string> GenerateUpdatedBuildFileLines(List<string> lines, string apiKey, bool addBuildScriptLines)
|
||||
{
|
||||
var addPlugin = !string.IsNullOrEmpty(apiKey);
|
||||
// A sample of the template file.
|
||||
// ...
|
||||
// allprojects {
|
||||
// repositories {**ARTIFACTORYREPOSITORY**
|
||||
// google()
|
||||
// jcenter()
|
||||
// flatDir {
|
||||
// dirs 'libs'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// apply plugin: 'com.android.application'
|
||||
// **APPLY_PLUGINS**
|
||||
//
|
||||
// dependencies {
|
||||
// implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
// **DEPS**}
|
||||
// ...
|
||||
var outputLines = new List<string>();
|
||||
// Check if the plugin exists, if so, update the SDK Key.
|
||||
var pluginExists = lines.Any(line => TokenAppLovinPlugin.IsMatch(line));
|
||||
if (pluginExists)
|
||||
{
|
||||
var pluginMatched = false;
|
||||
var insideAppLovinClosure = false;
|
||||
var updatedApiKey = false;
|
||||
var mavenRepoUpdated = false;
|
||||
var dependencyClassPathUpdated = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
// Bintray maven repo is no longer being used. Update to s3 maven repo with regex check
|
||||
if (!mavenRepoUpdated && (line.Contains(QualityServiceBintrayMavenRepo) || line.Contains(QualityServiceNoRegexMavenRepo)))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
|
||||
mavenRepoUpdated = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We no longer use version specific dependency class path. Just use + for version to always pull the latest.
|
||||
if (!dependencyClassPathUpdated && line.Contains(QualityServiceDependencyClassPathV3))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceDependencyClassPath));
|
||||
dependencyClassPathUpdated = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pluginMatched && line.Contains(QualityServicePlugin))
|
||||
{
|
||||
insideAppLovinClosure = true;
|
||||
pluginMatched = true;
|
||||
}
|
||||
|
||||
if (insideAppLovinClosure && line.Contains("}"))
|
||||
{
|
||||
insideAppLovinClosure = false;
|
||||
}
|
||||
|
||||
// Update the API key.
|
||||
if (insideAppLovinClosure && !updatedApiKey && TokenApiKey.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(string.Format(QualityServiceApiKey, apiKey));
|
||||
updatedApiKey = true;
|
||||
}
|
||||
// Keep adding the line until we find and update the plugin.
|
||||
else
|
||||
{
|
||||
outputLines.Add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Plugin hasn't been added yet, add it.
|
||||
else
|
||||
{
|
||||
var buildScriptClosureDepth = 0;
|
||||
var insideBuildScriptClosure = false;
|
||||
var buildScriptMatched = false;
|
||||
var qualityServiceRepositoryAdded = false;
|
||||
var qualityServiceDependencyClassPathAdded = false;
|
||||
var qualityServicePluginAdded = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
// Add the line to the output lines.
|
||||
outputLines.Add(line);
|
||||
|
||||
// Check if we need to add the build script lines and add them.
|
||||
if (addBuildScriptLines)
|
||||
{
|
||||
if (!buildScriptMatched && line.Contains(BuildScriptMatcher))
|
||||
{
|
||||
buildScriptMatched = true;
|
||||
insideBuildScriptClosure = true;
|
||||
}
|
||||
|
||||
// Match the parenthesis to track if we are still inside the buildscript closure.
|
||||
if (insideBuildScriptClosure)
|
||||
{
|
||||
if (line.Contains("{"))
|
||||
{
|
||||
buildScriptClosureDepth++;
|
||||
}
|
||||
|
||||
if (line.Contains("}"))
|
||||
{
|
||||
buildScriptClosureDepth--;
|
||||
}
|
||||
|
||||
if (buildScriptClosureDepth == 0)
|
||||
{
|
||||
insideBuildScriptClosure = false;
|
||||
|
||||
// There may be multiple buildscript closures and we need to keep looking until we added both the repository and classpath.
|
||||
buildScriptMatched = qualityServiceRepositoryAdded && qualityServiceDependencyClassPathAdded;
|
||||
}
|
||||
}
|
||||
|
||||
if (insideBuildScriptClosure)
|
||||
{
|
||||
// Add the build script dependency repositories.
|
||||
if (!qualityServiceRepositoryAdded && TokenBuildScriptRepositories.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
|
||||
qualityServiceRepositoryAdded = true;
|
||||
}
|
||||
// Add the build script dependencies.
|
||||
else if (!qualityServiceDependencyClassPathAdded && TokenBuildScriptDependencies.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceDependencyClassPath));
|
||||
qualityServiceDependencyClassPathAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we need to add the plugin and add it.
|
||||
if (addPlugin)
|
||||
{
|
||||
// Add the plugin.
|
||||
if (!qualityServicePluginAdded && TokenApplicationPlugin.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(QualityServiceApplyPlugin);
|
||||
outputLines.AddRange(GenerateAppLovinPluginClosure(apiKey));
|
||||
qualityServicePluginAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((addBuildScriptLines && (!qualityServiceRepositoryAdded || !qualityServiceDependencyClassPathAdded)) || (addPlugin && !qualityServicePluginAdded))
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin. Quality Service Plugin Added?: " + qualityServicePluginAdded + ", Quality Service Repo added?: " + qualityServiceRepositoryAdded + ", Quality Service dependency added?: " + qualityServiceDependencyClassPathAdded);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
public static string GetFormattedBuildScriptLine(string buildScriptLine)
|
||||
{
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
return " "
|
||||
#elif UNITY_2019_3_OR_NEWER
|
||||
return " "
|
||||
#else
|
||||
return " "
|
||||
#endif
|
||||
+ buildScriptLine;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GenerateAppLovinPluginClosure(string apiKey)
|
||||
{
|
||||
// applovin {
|
||||
// // NOTE: DO NOT CHANGE - this is NOT your AppLovin MAX SDK key - this is a derived key.
|
||||
// apiKey "456...a1b"
|
||||
// }
|
||||
var linesToInject = new List<string>(5);
|
||||
linesToInject.Add("");
|
||||
linesToInject.Add("applovin {");
|
||||
linesToInject.Add(" // NOTE: DO NOT CHANGE - this is NOT your AppLovin MAX SDK key - this is a derived key.");
|
||||
linesToInject.Add(string.Format(QualityServiceApiKey, apiKey));
|
||||
linesToInject.Add("}");
|
||||
|
||||
return linesToInject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 732b7510bc9c94aafb3fd3b8c0dc5d2d
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinProcessGradleBuildFile.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,425 @@
|
||||
//
|
||||
// AppLovinSettings.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 1/27/20.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using AppLovinMax.Scripts.IntegrationManager.Editor;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public enum Platform
|
||||
{
|
||||
All,
|
||||
Android,
|
||||
iOS
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="ScriptableObject"/> representing the AppLovin Settings that can be set in the Integration Manager Window.
|
||||
///
|
||||
/// The scriptable object asset is created with the name <c>AppLovinSettings.asset</c> and is placed under the directory <c>Assets/MaxSdk/Resources</c>.
|
||||
///
|
||||
/// NOTE: Not name spacing this class since it is reflected upon by the Google adapter and will break compatibility.
|
||||
/// </summary>
|
||||
public class AppLovinSettings : ScriptableObject
|
||||
{
|
||||
public const string SettingsExportPath = "MaxSdk/Resources/AppLovinSettings.asset";
|
||||
|
||||
public const string DefaultUserTrackingDescriptionEnV0 = "Pressing \\\"Allow\\\" uses device info for more relevant ad content";
|
||||
public const string DefaultUserTrackingDescriptionEnV1 = "This only uses device info for less annoying, more relevant ads";
|
||||
public const string DefaultUserTrackingDescriptionEnV2 = "This only uses device info for more interesting and relevant ads";
|
||||
public const string DefaultUserTrackingDescriptionEnV3 = "This uses device info for more personalized ads and content";
|
||||
|
||||
public const string DefaultUserTrackingDescriptionDe = "\\\"Erlauben\\\" drücken benutzt Gerätinformationen für relevantere Werbeinhalte";
|
||||
public const string DefaultUserTrackingDescriptionEs = "Presionando \\\"Permitir\\\", se usa la información del dispositivo para obtener contenido publicitario más relevante";
|
||||
public const string DefaultUserTrackingDescriptionFr = "\\\"Autoriser\\\" permet d'utiliser les infos du téléphone pour afficher des contenus publicitaires plus pertinents";
|
||||
public const string DefaultUserTrackingDescriptionJa = "\\\"許可\\\"をクリックすることで、デバイス情報を元により最適な広告を表示することができます";
|
||||
public const string DefaultUserTrackingDescriptionKo = "\\\"허용\\\"을 누르면 더 관련성 높은 광고 콘텐츠를 제공하기 위해 기기 정보가 사용됩니다";
|
||||
public const string DefaultUserTrackingDescriptionZhHans = "点击\\\"允许\\\"以使用设备信息获得更加相关的广告内容";
|
||||
public const string DefaultUserTrackingDescriptionZhHant = "點擊\\\"允許\\\"以使用設備信息獲得更加相關的廣告內容";
|
||||
|
||||
/// <summary>
|
||||
/// A placeholder constant to be replaced with the actual default localization or an empty string based on whether or not localization is enabled when when the getter is called.
|
||||
/// </summary>
|
||||
protected const string DefaultLocalization = "default_localization";
|
||||
|
||||
private static AppLovinSettings instance;
|
||||
|
||||
[SerializeField] private bool qualityServiceEnabled = true;
|
||||
[SerializeField] private string sdkKey;
|
||||
|
||||
[SerializeField] private bool setAttributionReportEndpoint;
|
||||
[SerializeField] private bool addApsSkAdNetworkIds;
|
||||
|
||||
[SerializeField] private string customGradleVersionUrl;
|
||||
[SerializeField] private string customGradleToolsVersion;
|
||||
|
||||
[SerializeField] private bool consentFlowEnabled;
|
||||
[SerializeField] private Platform consentFlowPlatform;
|
||||
[SerializeField] private string consentFlowPrivacyPolicyUrl = string.Empty;
|
||||
[SerializeField] private string consentFlowTermsOfServiceUrl = string.Empty;
|
||||
[FormerlySerializedAs("userTrackingUsageDescription")] [SerializeField] private string userTrackingUsageDescriptionEn = string.Empty;
|
||||
[SerializeField] private bool userTrackingUsageLocalizationEnabled;
|
||||
[SerializeField] private string userTrackingUsageDescriptionDe = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionEs = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionFr = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionJa = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionKo = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionZhHans = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionZhHant = DefaultLocalization;
|
||||
|
||||
[SerializeField] private string adMobAndroidAppId = string.Empty;
|
||||
[SerializeField] private string adMobIosAppId = string.Empty;
|
||||
|
||||
[SerializeField] private bool showInternalSettingsInIntegrationManager;
|
||||
|
||||
/// <summary>
|
||||
/// An instance of AppLovin Setting.
|
||||
/// </summary>
|
||||
public static AppLovinSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
// Check for an existing AppLovinSettings somewhere in the project
|
||||
var guids = AssetDatabase.FindAssets("AppLovinSettings t:ScriptableObject");
|
||||
if (guids.Length > 1)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Multiple AppLovinSettings found. This may cause unexpected results.");
|
||||
}
|
||||
|
||||
if (guids.Length != 0)
|
||||
{
|
||||
var path = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||
instance = AssetDatabase.LoadAssetAtPath<AppLovinSettings>(path);
|
||||
return instance;
|
||||
}
|
||||
|
||||
// If there is no existing AppLovinSettings asset, create one in the default location
|
||||
string settingsFilePath;
|
||||
// The settings file should be under the Assets/ folder so that it can be version controlled and cannot be overriden when updating.
|
||||
// If the plugin is outside the Assets folder, create the settings asset at the default location.
|
||||
if (AppLovinIntegrationManager.IsPluginOutsideAssetsDirectory)
|
||||
{
|
||||
// Note: Can't use absolute path when calling `CreateAsset`. Should use relative path to Assets/ directory.
|
||||
settingsFilePath = Path.Combine("Assets", SettingsExportPath);
|
||||
|
||||
var maxSdkDir = Path.Combine(Application.dataPath, "MaxSdk");
|
||||
if (!Directory.Exists(maxSdkDir))
|
||||
{
|
||||
Directory.CreateDirectory(maxSdkDir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
settingsFilePath = Path.Combine(AppLovinIntegrationManager.PluginParentDirectory, SettingsExportPath);
|
||||
}
|
||||
|
||||
var settingsDir = Path.GetDirectoryName(settingsFilePath);
|
||||
if (!Directory.Exists(settingsDir))
|
||||
{
|
||||
Directory.CreateDirectory(settingsDir);
|
||||
}
|
||||
|
||||
// On script reload AssetDatabase.FindAssets() can fail and will overwrite AppLovinSettings without this check
|
||||
if (!File.Exists(settingsFilePath))
|
||||
{
|
||||
instance = CreateInstance<AppLovinSettings>();
|
||||
AssetDatabase.CreateAsset(instance, settingsFilePath);
|
||||
MaxSdkLogger.D("Creating new AppLovinSettings asset at path: " + settingsFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to install Quality Service plugin.
|
||||
/// </summary>
|
||||
public bool QualityServiceEnabled
|
||||
{
|
||||
get { return Instance.qualityServiceEnabled; }
|
||||
set { Instance.qualityServiceEnabled = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AppLovin SDK Key.
|
||||
/// </summary>
|
||||
public string SdkKey
|
||||
{
|
||||
get { return Instance.sdkKey; }
|
||||
set { Instance.sdkKey = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to set `NSAdvertisingAttributionReportEndpoint` in Info.plist.
|
||||
/// </summary>
|
||||
public bool SetAttributionReportEndpoint
|
||||
{
|
||||
get { return Instance.setAttributionReportEndpoint; }
|
||||
set { Instance.setAttributionReportEndpoint = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to add Amazon Publisher Services SKAdNetworkID's.
|
||||
/// </summary>
|
||||
public bool AddApsSkAdNetworkIds
|
||||
{
|
||||
get { return Instance.addApsSkAdNetworkIds; }
|
||||
set { Instance.addApsSkAdNetworkIds = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A URL to set the distributionUrl in the gradle-wrapper.properties file (ex: https\://services.gradle.org/distributions/gradle-6.9.3-bin.zip)
|
||||
/// </summary>
|
||||
public string CustomGradleVersionUrl
|
||||
{
|
||||
get { return Instance.customGradleVersionUrl; }
|
||||
set { Instance.customGradleVersionUrl = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string to set the custom gradle tools version (ex: com.android.tools.build:gradle:4.2.0)
|
||||
/// </summary>
|
||||
public string CustomGradleToolsVersion
|
||||
{
|
||||
get { return Instance.customGradleToolsVersion; }
|
||||
set { Instance.customGradleToolsVersion = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not AppLovin Consent Flow is enabled.
|
||||
/// </summary>
|
||||
public bool ConsentFlowEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
// Update the default EN description if an old version of the description is still being used.
|
||||
if (DefaultUserTrackingDescriptionEnV0.Equals(Instance.UserTrackingUsageDescriptionEn)
|
||||
|| DefaultUserTrackingDescriptionEnV1.Equals(Instance.UserTrackingUsageDescriptionEn)
|
||||
|| DefaultUserTrackingDescriptionEnV2.Equals(Instance.UserTrackingUsageDescriptionEn))
|
||||
{
|
||||
Instance.UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEnV3;
|
||||
}
|
||||
|
||||
return Instance.consentFlowEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
var previousValue = Instance.consentFlowEnabled;
|
||||
Instance.consentFlowEnabled = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// If the value didn't change, we don't need to update anything.
|
||||
if (previousValue) return;
|
||||
|
||||
Instance.UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEnV3;
|
||||
Instance.UserTrackingUsageLocalizationEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance.ConsentFlowPlatform = Platform.All;
|
||||
Instance.ConsentFlowPrivacyPolicyUrl = string.Empty;
|
||||
Instance.ConsentFlowTermsOfServiceUrl = string.Empty;
|
||||
Instance.UserTrackingUsageDescriptionEn = string.Empty;
|
||||
Instance.UserTrackingUsageLocalizationEnabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Platform ConsentFlowPlatform
|
||||
{
|
||||
get { return Instance.consentFlowEnabled ? Instance.consentFlowPlatform : Platform.All; }
|
||||
set { Instance.consentFlowPlatform = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A URL pointing to the Privacy Policy for the app to be shown when prompting the user for consent.
|
||||
/// </summary>
|
||||
public string ConsentFlowPrivacyPolicyUrl
|
||||
{
|
||||
get { return Instance.consentFlowPrivacyPolicyUrl; }
|
||||
set { Instance.consentFlowPrivacyPolicyUrl = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional URL pointing to the Terms of Service for the app to be shown when prompting the user for consent.
|
||||
/// </summary>
|
||||
public string ConsentFlowTermsOfServiceUrl
|
||||
{
|
||||
get { return Instance.consentFlowTermsOfServiceUrl; }
|
||||
set { Instance.consentFlowTermsOfServiceUrl = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in English to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionEn
|
||||
{
|
||||
get { return Instance.userTrackingUsageDescriptionEn; }
|
||||
set { Instance.userTrackingUsageDescriptionEn = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to localize User Tracking Usage Description.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public bool UserTrackingUsageLocalizationEnabled
|
||||
{
|
||||
get { return Instance.userTrackingUsageLocalizationEnabled; }
|
||||
set
|
||||
{
|
||||
var previousValue = Instance.userTrackingUsageLocalizationEnabled;
|
||||
Instance.userTrackingUsageLocalizationEnabled = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// If the value didn't change or the english localization text is not the default one, we don't need to update anything.
|
||||
if (previousValue || !DefaultUserTrackingDescriptionEnV3.Equals(Instance.UserTrackingUsageDescriptionEn)) return;
|
||||
|
||||
Instance.UserTrackingUsageDescriptionDe = DefaultUserTrackingDescriptionDe;
|
||||
Instance.UserTrackingUsageDescriptionEs = DefaultUserTrackingDescriptionEs;
|
||||
Instance.UserTrackingUsageDescriptionFr = DefaultUserTrackingDescriptionFr;
|
||||
Instance.UserTrackingUsageDescriptionJa = DefaultUserTrackingDescriptionJa;
|
||||
Instance.UserTrackingUsageDescriptionKo = DefaultUserTrackingDescriptionKo;
|
||||
Instance.UserTrackingUsageDescriptionZhHans = DefaultUserTrackingDescriptionZhHans;
|
||||
Instance.UserTrackingUsageDescriptionZhHant = DefaultUserTrackingDescriptionZhHant;
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance.UserTrackingUsageDescriptionDe = string.Empty;
|
||||
Instance.UserTrackingUsageDescriptionEs = string.Empty;
|
||||
Instance.UserTrackingUsageDescriptionFr = string.Empty;
|
||||
Instance.UserTrackingUsageDescriptionJa = string.Empty;
|
||||
Instance.UserTrackingUsageDescriptionKo = string.Empty;
|
||||
Instance.UserTrackingUsageDescriptionZhHans = string.Empty;
|
||||
Instance.UserTrackingUsageDescriptionZhHant = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in German to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionDe
|
||||
{
|
||||
get { return Instance.userTrackingUsageDescriptionDe; }
|
||||
set { Instance.userTrackingUsageDescriptionDe = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Spanish to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionEs
|
||||
{
|
||||
get { return Instance.userTrackingUsageDescriptionEs; }
|
||||
set { Instance.userTrackingUsageDescriptionEs = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in French to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionFr
|
||||
{
|
||||
get { return Instance.userTrackingUsageDescriptionFr; }
|
||||
set { Instance.userTrackingUsageDescriptionFr = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Japanese to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionJa
|
||||
{
|
||||
get { return Instance.userTrackingUsageDescriptionJa; }
|
||||
set { Instance.userTrackingUsageDescriptionJa = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Korean to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionKo
|
||||
{
|
||||
get { return Instance.userTrackingUsageDescriptionKo; }
|
||||
set { Instance.userTrackingUsageDescriptionKo = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Chinese (Simplified) to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionZhHans
|
||||
{
|
||||
get { return Instance.userTrackingUsageDescriptionZhHans; }
|
||||
set { Instance.userTrackingUsageDescriptionZhHans = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Chinese (Traditional) to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionZhHant
|
||||
{
|
||||
get
|
||||
{
|
||||
// Since this localization has been added separate from the other localizations,
|
||||
// we use a placeholder constant to be replaced with the actual value or an empty string based on whether or not the localization was enabled by the publisher.
|
||||
if (DefaultLocalization.Equals(Instance.userTrackingUsageDescriptionZhHant))
|
||||
{
|
||||
Instance.userTrackingUsageDescriptionZhHant = Instance.UserTrackingUsageLocalizationEnabled ? DefaultUserTrackingDescriptionZhHant : string.Empty;
|
||||
}
|
||||
|
||||
return Instance.userTrackingUsageDescriptionZhHant;
|
||||
}
|
||||
set { Instance.userTrackingUsageDescriptionZhHant = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AdMob Android App ID.
|
||||
/// </summary>
|
||||
public string AdMobAndroidAppId
|
||||
{
|
||||
get { return Instance.adMobAndroidAppId; }
|
||||
set { Instance.adMobAndroidAppId = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AdMob iOS App ID.
|
||||
/// </summary>
|
||||
public string AdMobIosAppId
|
||||
{
|
||||
get { return Instance.adMobIosAppId; }
|
||||
set { Instance.adMobIosAppId = value; }
|
||||
}
|
||||
|
||||
public bool ShowInternalSettingsInIntegrationManager
|
||||
{
|
||||
get { return Instance.showInternalSettingsInIntegrationManager; }
|
||||
set { Instance.showInternalSettingsInIntegrationManager = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the instance of the settings.
|
||||
/// </summary>
|
||||
public void SaveAsync()
|
||||
{
|
||||
EditorUtility.SetDirty(instance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebc0ba1b5ef6b4a6b9dd53d7eadfea16
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinSettings.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "MaxSdk.Scripts.IntegrationManager.Editor",
|
||||
"references": [
|
||||
"MaxSdk.Scripts"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a10a05a8449c42519fd80f2b8b580de3
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/MaxSdk.IntegrationManager.Editor.asmdef
|
||||
timeCreated: 1591749873
|
||||
170
sdk-intergration/Assets/MaxSdk/Scripts/MaxCmpService.cs
Normal file
170
sdk-intergration/Assets/MaxSdk/Scripts/MaxCmpService.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// MaxCmpService.cs
|
||||
// AppLovin User Engagement Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 10/1/23.
|
||||
// Copyright © 2023 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
#elif UNITY_ANDROID
|
||||
using UnityEngine;
|
||||
#elif UNITY_IOS
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// This class provides direct APIs for interfacing with the Google-certified CMP installed, if any.
|
||||
/// </summary>
|
||||
public class MaxCmpService
|
||||
{
|
||||
private static readonly MaxCmpService _instance = new MaxCmpService();
|
||||
|
||||
private MaxCmpService() { }
|
||||
|
||||
private static Action<MaxCmpError> OnCompletedAction;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
#elif UNITY_ANDROID
|
||||
private static readonly AndroidJavaClass MaxUnityPluginClass = new AndroidJavaClass("com.applovin.mediation.unity.MaxUnityPlugin");
|
||||
#elif UNITY_IOS
|
||||
[DllImport("__Internal")]
|
||||
private static extern void _MaxShowCmpForExistingUser();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
private static extern bool _MaxHasSupportedCmp();
|
||||
#endif
|
||||
|
||||
internal static MaxCmpService Instance
|
||||
{
|
||||
get { return _instance; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the CMP flow to an existing user.
|
||||
/// Note that the user's current consent will be reset before the CMP alert is shown.
|
||||
/// </summary>
|
||||
/// <param name="onCompletedAction">Called when the CMP flow finishes showing.</param>
|
||||
public void ShowCmpForExistingUser(Action<MaxCmpError> onCompletedAction)
|
||||
{
|
||||
OnCompletedAction = onCompletedAction;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
var errorProps = new Dictionary<string, object>
|
||||
{
|
||||
{"code", (int) MaxCmpError.ErrorCode.FormUnavailable},
|
||||
{"message", "CMP is not supported in Unity editor"}
|
||||
};
|
||||
|
||||
NotifyCompletedIfNeeded(errorProps);
|
||||
#elif UNITY_ANDROID
|
||||
MaxUnityPluginClass.CallStatic("showCmpForExistingUser");
|
||||
#elif UNITY_IOS
|
||||
_MaxShowCmpForExistingUser();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <code>true</code> if a supported CMP SDK is detected.
|
||||
/// </summary>
|
||||
public bool HasSupportedCmp
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return false;
|
||||
#elif UNITY_ANDROID
|
||||
return MaxUnityPluginClass.CallStatic<bool>("hasSupportedCmp");
|
||||
#elif UNITY_IOS
|
||||
return _MaxHasSupportedCmp();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal static void NotifyCompletedIfNeeded(Dictionary<string, object> errorProps)
|
||||
{
|
||||
if (OnCompletedAction == null) return;
|
||||
|
||||
var error = (errorProps == null) ? null : MaxCmpError.Create(errorProps);
|
||||
OnCompletedAction(error);
|
||||
}
|
||||
}
|
||||
|
||||
public class MaxCmpError
|
||||
{
|
||||
public enum ErrorCode
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that an unspecified error has occurred.
|
||||
/// </summary>
|
||||
Unspecified = -1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the CMP has not been integrated correctly.
|
||||
/// </summary>
|
||||
IntegrationError = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the CMP form is unavailable.
|
||||
/// </summary>
|
||||
FormUnavailable = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the CMP form is not required.
|
||||
/// </summary>
|
||||
FormNotRequired = 3
|
||||
}
|
||||
|
||||
public static MaxCmpError Create(IDictionary<string, object> error)
|
||||
{
|
||||
return new MaxCmpError()
|
||||
{
|
||||
Code = GetCode(MaxSdkUtils.GetIntFromDictionary(error, "code")),
|
||||
Message = MaxSdkUtils.GetStringFromDictionary(error, "message"),
|
||||
CmpCode = MaxSdkUtils.GetIntFromDictionary(error, "cmpCode", -1),
|
||||
CmpMessage = MaxSdkUtils.GetStringFromDictionary(error, "cmpMessage")
|
||||
};
|
||||
}
|
||||
|
||||
private static ErrorCode GetCode(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 1:
|
||||
return ErrorCode.IntegrationError;
|
||||
case 2:
|
||||
return ErrorCode.FormUnavailable;
|
||||
case 3:
|
||||
return ErrorCode.FormNotRequired;
|
||||
default:
|
||||
return ErrorCode.Unspecified;
|
||||
}
|
||||
}
|
||||
|
||||
private MaxCmpError() { }
|
||||
|
||||
/// <summary>
|
||||
/// The error code for this error.
|
||||
/// </summary>
|
||||
public ErrorCode Code { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error message for this error.
|
||||
/// </summary>
|
||||
public string Message { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error code returned by the CMP.
|
||||
/// </summary>
|
||||
public int CmpCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error message returned by the CMP.
|
||||
/// </summary>
|
||||
public string CmpMessage { get; private set; }
|
||||
}
|
||||
14
sdk-intergration/Assets/MaxSdk/Scripts/MaxCmpService.cs.meta
Normal file
14
sdk-intergration/Assets/MaxSdk/Scripts/MaxCmpService.cs.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2e895983b04846af81b59189de0310c
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/MaxCmpService.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
108
sdk-intergration/Assets/MaxSdk/Scripts/MaxEventExecutor.cs
Normal file
108
sdk-intergration/Assets/MaxSdk/Scripts/MaxEventExecutor.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// MaxEventExecutor.cs
|
||||
// Max Unity Plugin
|
||||
//
|
||||
// Created by Jonathan Liu on 1/22/2024.
|
||||
// Copyright © 2024 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace AppLovinMax.Internal
|
||||
{
|
||||
public class MaxEventExecutor : MonoBehaviour
|
||||
{
|
||||
private static MaxEventExecutor instance;
|
||||
private static List<MaxAction> adEventsQueue = new List<MaxAction>();
|
||||
|
||||
private static volatile bool adEventsQueueEmpty = true;
|
||||
|
||||
struct MaxAction
|
||||
{
|
||||
public Action action;
|
||||
public string eventName;
|
||||
|
||||
public MaxAction(Action actionToExecute, string nameOfEvent)
|
||||
{
|
||||
action = actionToExecute;
|
||||
eventName = nameOfEvent;
|
||||
}
|
||||
}
|
||||
|
||||
public static void InitializeIfNeeded()
|
||||
{
|
||||
if (instance != null) return;
|
||||
|
||||
var executor = new GameObject("MaxEventExecutor");
|
||||
executor.hideFlags = HideFlags.HideAndDontSave;
|
||||
DontDestroyOnLoad(executor);
|
||||
instance = executor.AddComponent<MaxEventExecutor>();
|
||||
}
|
||||
|
||||
#region Public API
|
||||
|
||||
#if UNITY_EDITOR || !(UNITY_ANDROID || UNITY_IPHONE || UNITY_IOS)
|
||||
public static MaxEventExecutor Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void ExecuteOnMainThread(Action action, string eventName)
|
||||
{
|
||||
lock (adEventsQueue)
|
||||
{
|
||||
adEventsQueue.Add(new MaxAction(action, eventName));
|
||||
adEventsQueueEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void InvokeOnMainThread(UnityEvent unityEvent, string eventName)
|
||||
{
|
||||
ExecuteOnMainThread(() => unityEvent.Invoke(), eventName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (adEventsQueueEmpty) return;
|
||||
|
||||
var actionsToExecute = new List<MaxAction>();
|
||||
lock (adEventsQueue)
|
||||
{
|
||||
actionsToExecute.AddRange(adEventsQueue);
|
||||
adEventsQueue.Clear();
|
||||
adEventsQueueEmpty = true;
|
||||
}
|
||||
|
||||
foreach (var maxAction in actionsToExecute)
|
||||
{
|
||||
if (maxAction.action.Target != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
maxAction.action.Invoke();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Caught exception in publisher event: " + maxAction.eventName + ", exception: " + exception);
|
||||
Debug.LogException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4715dd62632564dc4810a4dc98243f4a
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/MaxEventExecutor.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user