Jelajahi Sumber

登录广告sdk加入

lzx 1 bulan lalu
induk
melakukan
414cad95a1
100 mengubah file dengan 6029 tambahan dan 23 penghapusan
  1. 16 0
      Assets/Plugins/Android/AndroidManifest.xml
  2. 7 0
      Assets/Plugins/Android/AndroidManifest.xml.meta
  3. 8 0
      Assets/Plugins/Android/gradleTemplate.properties
  4. 7 0
      Assets/Plugins/Android/gradleTemplate.properties.meta
  5. 57 0
      Assets/Plugins/Android/mainTemplate.gradle
  6. 7 0
      Assets/Plugins/Android/mainTemplate.gradle.meta
  7. 30 0
      Assets/Plugins/Android/settingsTemplate.gradle
  8. 7 0
      Assets/Plugins/Android/settingsTemplate.gradle.meta
  9. 3 1
      Assets/Scripts/GameLogic/Fort23.GameLogic.asmdef
  10. 39 16
      Assets/Scripts/GameLogic/SDK/TakuSDKManager.cs
  11. 78 0
      Assets/Scripts/GameLogic/SDK/TapSDKManager.cs
  12. 11 0
      Assets/Scripts/GameLogic/SDK/TapSDKManager.cs.meta
  13. 5 3
      Assets/Scripts/GameLogic/Shop/ShopManger.cs
  14. 7 2
      Assets/Scripts/GameUI/GameApplction.cs
  15. 3 1
      Assets/Scripts/ThirdParty/Fort23.ThirdParty.asmdef
  16. 8 0
      Assets/TapSDK.meta
  17. 8 0
      Assets/TapSDK/Core.meta
  18. 8 0
      Assets/TapSDK/Core/Editor.meta
  19. 14 0
      Assets/TapSDK/Core/Editor/BuildTargetUtils.cs
  20. 11 0
      Assets/TapSDK/Core/Editor/BuildTargetUtils.cs.meta
  21. 70 0
      Assets/TapSDK/Core/Editor/LinkXMLGenerator.cs
  22. 11 0
      Assets/TapSDK/Core/Editor/LinkXMLGenerator.cs.meta
  23. 954 0
      Assets/TapSDK/Core/Editor/Plist.cs
  24. 3 0
      Assets/TapSDK/Core/Editor/Plist.cs.meta
  25. 119 0
      Assets/TapSDK/Core/Editor/SDKLinkProcessBuild.cs
  26. 11 0
      Assets/TapSDK/Core/Editor/SDKLinkProcessBuild.cs.meta
  27. 168 0
      Assets/TapSDK/Core/Editor/TapFileHelper.cs
  28. 3 0
      Assets/TapSDK/Core/Editor/TapFileHelper.cs.meta
  29. 15 0
      Assets/TapSDK/Core/Editor/TapSDK.Core.Editor.asmdef
  30. 7 0
      Assets/TapSDK/Core/Editor/TapSDK.Core.Editor.asmdef.meta
  31. 493 0
      Assets/TapSDK/Core/Editor/TapSDKCoreCompile.cs
  32. 3 0
      Assets/TapSDK/Core/Editor/TapSDKCoreCompile.cs.meta
  33. 102 0
      Assets/TapSDK/Core/Editor/TapSDKCoreIOSProcessor.cs
  34. 3 0
      Assets/TapSDK/Core/Editor/TapSDKCoreIOSProcessor.cs.meta
  35. 9 0
      Assets/TapSDK/Core/Editor/UI.meta
  36. 267 0
      Assets/TapSDK/Core/Editor/UI/ScrollViewEditor.cs
  37. 12 0
      Assets/TapSDK/Core/Editor/UI/ScrollViewEditor.cs.meta
  38. 34 0
      Assets/TapSDK/Core/Editor/UI/ScrollViewExEditor.cs
  39. 12 0
      Assets/TapSDK/Core/Editor/UI/ScrollViewExEditor.cs.meta
  40. 17 0
      Assets/TapSDK/Core/Editor/UI/TapSDK.UI.Editor.asmdef
  41. 7 0
      Assets/TapSDK/Core/Editor/UI/TapSDK.UI.Editor.asmdef.meta
  42. 8 0
      Assets/TapSDK/Core/Mobile.meta
  43. 8 0
      Assets/TapSDK/Core/Mobile/Editor.meta
  44. 15 0
      Assets/TapSDK/Core/Mobile/Editor/NativeDependencies.xml
  45. 7 0
      Assets/TapSDK/Core/Mobile/Editor/NativeDependencies.xml.meta
  46. 20 0
      Assets/TapSDK/Core/Mobile/Editor/TapCommonMobileProcessBuild.cs
  47. 11 0
      Assets/TapSDK/Core/Mobile/Editor/TapCommonMobileProcessBuild.cs.meta
  48. 17 0
      Assets/TapSDK/Core/Mobile/Editor/TapSDK.Core.Mobile.Editor.asmdef
  49. 7 0
      Assets/TapSDK/Core/Mobile/Editor/TapSDK.Core.Mobile.Editor.asmdef.meta
  50. 8 0
      Assets/TapSDK/Core/Mobile/Runtime.meta
  51. 51 0
      Assets/TapSDK/Core/Mobile/Runtime/AndroidNativeWrapper.cs
  52. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/AndroidNativeWrapper.cs.meta
  53. 84 0
      Assets/TapSDK/Core/Mobile/Runtime/Bridge.cs
  54. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/Bridge.cs.meta
  55. 74 0
      Assets/TapSDK/Core/Mobile/Runtime/BridgeAndroid.cs
  56. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/BridgeAndroid.cs.meta
  57. 35 0
      Assets/TapSDK/Core/Mobile/Runtime/BridgeCallback.cs
  58. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/BridgeCallback.cs.meta
  59. 112 0
      Assets/TapSDK/Core/Mobile/Runtime/BridgeIOS.cs
  60. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/BridgeIOS.cs.meta
  61. 119 0
      Assets/TapSDK/Core/Mobile/Runtime/Command.cs
  62. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/Command.cs.meta
  63. 9 0
      Assets/TapSDK/Core/Mobile/Runtime/Constants.cs
  64. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/Constants.cs.meta
  65. 34 0
      Assets/TapSDK/Core/Mobile/Runtime/EngineBridgeInitializer.cs
  66. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/EngineBridgeInitializer.cs.meta
  67. 15 0
      Assets/TapSDK/Core/Mobile/Runtime/IBridge.cs
  68. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/IBridge.cs.meta
  69. 50 0
      Assets/TapSDK/Core/Mobile/Runtime/IOSNativeWrapper.cs
  70. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/IOSNativeWrapper.cs.meta
  71. 37 0
      Assets/TapSDK/Core/Mobile/Runtime/Result.cs
  72. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/Result.cs.meta
  73. 77 0
      Assets/TapSDK/Core/Mobile/Runtime/TapCoreMobile.cs
  74. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/TapCoreMobile.cs.meta
  75. 291 0
      Assets/TapSDK/Core/Mobile/Runtime/TapEventMobile.cs
  76. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/TapEventMobile.cs.meta
  77. 18 0
      Assets/TapSDK/Core/Mobile/Runtime/TapSDK.Core.Mobile.Runtime.asmdef
  78. 7 0
      Assets/TapSDK/Core/Mobile/Runtime/TapSDK.Core.Mobile.Runtime.asmdef.meta
  79. 9 0
      Assets/TapSDK/Core/Mobile/Runtime/TapUUID.cs
  80. 11 0
      Assets/TapSDK/Core/Mobile/Runtime/TapUUID.cs.meta
  81. 8 0
      Assets/TapSDK/Core/Resources.meta
  82. 8 0
      Assets/TapSDK/Core/Resources/Fonts.meta
  83. TEMPAT SAMPAH
      Assets/TapSDK/Core/Resources/Fonts/taptap-sdk-bold.ttf
  84. 22 0
      Assets/TapSDK/Core/Resources/Fonts/taptap-sdk-bold.ttf.meta
  85. TEMPAT SAMPAH
      Assets/TapSDK/Core/Resources/Fonts/taptap-sdk.ttf
  86. 21 0
      Assets/TapSDK/Core/Resources/Fonts/taptap-sdk.ttf.meta
  87. 260 0
      Assets/TapSDK/Core/Resources/Loading.prefab
  88. 7 0
      Assets/TapSDK/Core/Resources/Loading.prefab.meta
  89. 194 0
      Assets/TapSDK/Core/Resources/TapCommonTip.prefab
  90. 7 0
      Assets/TapSDK/Core/Resources/TapCommonTip.prefab.meta
  91. 528 0
      Assets/TapSDK/Core/Resources/TapCommonToastBlack.prefab
  92. 7 0
      Assets/TapSDK/Core/Resources/TapCommonToastBlack.prefab.meta
  93. 411 0
      Assets/TapSDK/Core/Resources/TapCommonToastWhite.prefab
  94. 7 0
      Assets/TapSDK/Core/Resources/TapCommonToastWhite.prefab.meta
  95. 352 0
      Assets/TapSDK/Core/Resources/TapMessage.prefab
  96. 10 0
      Assets/TapSDK/Core/Resources/TapMessage.prefab.meta
  97. TEMPAT SAMPAH
      Assets/TapSDK/Core/Resources/TapSDKCommonTapIcon-v2.png
  98. 128 0
      Assets/TapSDK/Core/Resources/TapSDKCommonTapIcon-v2.png.meta
  99. TEMPAT SAMPAH
      Assets/TapSDK/Core/Resources/TapSDKCommonTapIcon.png
  100. 128 0
      Assets/TapSDK/Core/Resources/TapSDKCommonTapIcon.png.meta

+ 16 - 0
Assets/Plugins/Android/AndroidManifest.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.unity3d.player"
+    xmlns:tools="http://schemas.android.com/tools">
+    <application>
+        <activity android:name="com.unity3d.player.UnityPlayerActivity"
+                  android:theme="@style/TuanjieThemeSelector">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
+        </activity>
+    </application>
+</manifest>

+ 7 - 0
Assets/Plugins/Android/AndroidManifest.xml.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: DClNti+uUnMpIGGiBEk4WmN/J4WrWceualctSF9MsxpS9/7N6BA616pg0O9u
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Plugins/Android/gradleTemplate.properties

@@ -0,0 +1,8 @@
+org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M
+org.gradle.parallel=true
+tuanjieStreamingAssets=**STREAMING_ASSETS**
+# Android Resolver Properties Start
+android.useAndroidX=true
+android.enableJetifier=true
+# Android Resolver Properties End
+**ADDITIONAL_PROPERTIES**

+ 7 - 0
Assets/Plugins/Android/gradleTemplate.properties.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: W35NtH/4Wnx1598RPc1uax0g4p1+vHfz4Yx4mleofQZSv0twabPzRyYDK6B9
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 57 - 0
Assets/Plugins/Android/mainTemplate.gradle

@@ -0,0 +1,57 @@
+apply plugin: 'com.android.library'
+**APPLY_PLUGINS**
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+// Android Resolver Dependencies Start
+    implementation 'com.android.support:appcompat-v7:28.0.0' // Assets/Scripts/ThirdParty/AnyThinkAds/Plugins/Android/China/Editor/Dependencies.xml:3
+    implementation 'com.taptap.sdk:tap-core-unity:4.8.2' // Assets/TapSDK/Core/Mobile/Editor/NativeDependencies.xml:7
+    implementation 'com.taptap.sdk:tap-login-unity:4.8.2' // Assets/TapSDK/Login/Mobile/Editor/NativeDependencies.xml:7
+// Android Resolver Dependencies End
+**DEPS**}
+
+// Android Resolver Exclusions Start
+android {
+  packagingOptions {
+      exclude ('/lib/armeabi/*' + '*')
+      exclude ('/lib/mips/*' + '*')
+      exclude ('/lib/mips64/*' + '*')
+      exclude ('/lib/x86/*' + '*')
+      exclude ('/lib/x86_64/*' + '*')
+  }
+}
+// Android Resolver Exclusions End
+android {
+    namespace "com.unity3d.player"
+    ndkPath "**NDKPATH**"
+    compileSdkVersion **APIVERSION**
+    buildToolsVersion '**BUILDTOOLS**'
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
+    }
+
+    defaultConfig {
+        minSdkVersion **MINSDKVERSION**
+        targetSdkVersion **TARGETSDKVERSION**
+        ndk {
+            abiFilters **ABIFILTERS**
+        }
+        versionCode **VERSIONCODE**
+        versionName '**VERSIONNAME**'
+        consumerProguardFiles 'proguard-tuanjie.txt'**USER_PROGUARD**
+    }
+
+    lintOptions {
+        abortOnError false
+    }
+
+    aaptOptions {
+        noCompress = **BUILTIN_NOCOMPRESS** + tuanjieStreamingAssets.tokenize(', ')
+        ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~"
+    }**PACKAGING_OPTIONS**
+}
+**IL_CPP_BUILD_SETUP**
+**SOURCE_BUILD_SETUP**
+**EXTERNAL_SOURCES**

+ 7 - 0
Assets/Plugins/Android/mainTemplate.gradle.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: CX9LsyyoUy9Q6+4NOSjXPpqpME347258eV5Pcs6vl31pm2Yp8VtnDTwQzVSj
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 30 - 0
Assets/Plugins/Android/settingsTemplate.gradle

@@ -0,0 +1,30 @@
+pluginManagement {
+    repositories {
+        **ARTIFACTORYREPOSITORY**
+        gradlePluginPortal()
+        google()
+        mavenCentral()
+    }
+}
+
+include ':launcher', ':tuanjieLibrary'
+**INCLUDES**
+
+dependencyResolutionManagement {
+    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
+    repositories {
+        **ARTIFACTORYREPOSITORY**
+        google()
+        mavenCentral()
+// Android Resolver Repos Start
+        def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/")
+        maven {
+            url "https://repo.maven.apache.org/maven2" // Assets/TapSDK/Core/Mobile/Editor/NativeDependencies.xml:6, Assets/TapSDK/Login/Mobile/Editor/NativeDependencies.xml:6
+        }
+        mavenLocal()
+// Android Resolver Repos End
+        flatDir {
+            dirs "${project(':tuanjieLibrary').projectDir}/libs"
+        }
+    }
+}

+ 7 - 0
Assets/Plugins/Android/settingsTemplate.gradle.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: XHodtSytUH3BUTr3nm4dEc5M6RMUu/EUvyVwIYwL8q5y1pkxnMn4f5bFWcML
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 1
Assets/Scripts/GameLogic/Fort23.GameLogic.asmdef

@@ -11,7 +11,9 @@
         "GUID:5efd170ecd8084500bed5692932fe14e",
         "GUID:5efd170ecd8084500bed5692932fe14e",
         "GUID:8097be56b8f8a81458fa9b1971038cec",
         "GUID:8097be56b8f8a81458fa9b1971038cec",
         "GUID:9aacf4a871662084382dfb2f67105436",
         "GUID:9aacf4a871662084382dfb2f67105436",
-        "ThirdParty"
+        "ThirdParty",
+        "GUID:7d5ef2062f3704e1ab74aac0e4d5a1a7",
+        "GUID:e8754b6153389406c963cd52996cc80f"
     ],
     ],
     "includePlatforms": [],
     "includePlatforms": [],
     "excludePlatforms": [],
     "excludePlatforms": [],

+ 39 - 16
Assets/Scripts/GameLogic/SDK/TakuSDKManager.cs

@@ -9,21 +9,20 @@ public class TakuSDKManager : Singleton<TakuSDKManager>, ATSDKInitListener
 {
 {
     private bool isOK;
     private bool isOK;
     private CTask<bool> _cTask;
     private CTask<bool> _cTask;
-    private ATSDKInitListener _atsdkInitListener;
+    string[] jsonList = { "n67dd01ce07ec2" };
 
 
     public void CustomInit()
     public void CustomInit()
     {
     {
         //(可选配置)设置子渠道的信息,开发者可以通过该渠道信息在后台来区分看各个渠道的子渠道广告数据
         //(可选配置)设置子渠道的信息,开发者可以通过该渠道信息在后台来区分看各个渠道的子渠道广告数据
         //注意:如果有使用initCustomMap()方法,必须在initCustomMap()方法之后调用此方法
         //注意:如果有使用initCustomMap()方法,必须在initCustomMap()方法之后调用此方法
-        ATSDKAPI.setSubChannel("Google");
+        ATSDKAPI.setSubChannel("TapTap");
 
 
         //设置开启Debug日志(强烈建议测试阶段开启,方便排查问题)
         //设置开启Debug日志(强烈建议测试阶段开启,方便排查问题)
         ATSDKAPI.setLogDebug(true);
         ATSDKAPI.setLogDebug(true);
 
 
         //(必须配置)SDK的初始化
         //(必须配置)SDK的初始化
-        ATSDKAPI.initSDK("h67dd01a5e182e", "a3a3e17270711ba83fdc200d98cf67888", this); //Use your own app_id & app_key here
-
-     
+        ATSDKAPI.initSDK("a68d9eee94b6c5", "a73bcf09011c40e8dd1400d8e987a46b9",
+            this); //Use your own app_id & app_key here
     }
     }
 
 
     public void AddAutoLoadAdPlacementID()
     public void AddAutoLoadAdPlacementID()
@@ -45,14 +44,13 @@ public class TakuSDKManager : Singleton<TakuSDKManager>, ATSDKInitListener
         //广告被关闭
         //广告被关闭
         ATRewardedAutoVideo.Instance.client.onAdVideoCloseEvent += onAdVideoClosedEvent;
         ATRewardedAutoVideo.Instance.client.onAdVideoCloseEvent += onAdVideoClosedEvent;
 
 
-        string[] jsonList = { "n67dd01ce07ec2" };
 
 
         ATRewardedAutoVideo.Instance.addAutoLoadAdPlacementID(jsonList);
         ATRewardedAutoVideo.Instance.addAutoLoadAdPlacementID(jsonList);
     }
     }
 
 
     public bool IsReady()
     public bool IsReady()
     {
     {
-        return ATRewardedAutoVideo.Instance.autoLoadRewardedVideoReadyForPlacementID("n67dd01ce07ec2");
+        return ATRewardedAutoVideo.Instance.autoLoadRewardedVideoReadyForPlacementID(jsonList[0]);
     }
     }
 
 
     public async CTask<bool> ShowAutoAd()
     public async CTask<bool> ShowAutoAd()
@@ -81,7 +79,8 @@ public class TakuSDKManager : Singleton<TakuSDKManager>, ATSDKInitListener
     // 广告加载失败
     // 广告加载失败
     public void onAdLoadFail(object sender, ATAdErrorEventArgs erg)
     public void onAdLoadFail(object sender, ATAdErrorEventArgs erg)
     {
     {
-        LogTool.Error("开发者回调 广告加载失败 :" + erg.placementId + " erroCode:" + erg.errorCode + " eroMsg:" + erg.errorMessage);
+        LogTool.Error("开发者回调 广告加载失败 :" + erg.placementId + " erroCode:" + erg.errorCode + " eroMsg:" +
+                      erg.errorMessage);
     }
     }
 
 
     // 广告视频开始播放
     // 广告视频开始播放
@@ -124,17 +123,41 @@ public class TakuSDKManager : Singleton<TakuSDKManager>, ATSDKInitListener
         _cTask.SetResult(isOK);
         _cTask.SetResult(isOK);
     }
     }
 
 
+    public override void Dispose()
+    {
+        //广告加载成功
+        ATRewardedAutoVideo.Instance.client.onAdLoadEvent -= onAdLoad;
+        //广告加载失败
+        ATRewardedAutoVideo.Instance.client.onAdLoadFailureEvent -= onAdLoadFail;
+        //广告展示的回调(可依赖这个回调统计展示数据)
+        ATRewardedAutoVideo.Instance.client.onAdVideoStartEvent -= onAdVideoStartEvent;
+        //广告播放结束
+        ATRewardedAutoVideo.Instance.client.onAdVideoEndEvent -= onAdVideoEndEvent;
+        //广告视频播放失败
+        ATRewardedAutoVideo.Instance.client.onAdVideoFailureEvent -= onAdVideoPlayFail;
+        //广告点击
+        ATRewardedAutoVideo.Instance.client.onAdClickEvent -= onAdClick;
+        //广告激励回调(可依赖该监听下发游戏激励)
+        ATRewardedAutoVideo.Instance.client.onRewardEvent -= onReward;
+        //广告被关闭
+        ATRewardedAutoVideo.Instance.client.onAdVideoCloseEvent -= onAdVideoClosedEvent;
+
+        ATRewardedAutoVideo.Instance.removeAutoLoadAdPlacementID(jsonList);
+        base.Dispose();
+    }
+
     public void initSuccess()
     public void initSuccess()
     {
     {
-        // string[] deniedInfos = new string[] { "gaid" };
-        // foreach (var deniedInfo in deniedInfos)
-        // {
-        //     LogTool.Error("gdis:" + deniedInfo);
-        // }
+        AddAutoLoadAdPlacementID();
+        //  string[] deniedInfos = new string[] { "gaid" };
+        //  foreach (var deniedInfo in deniedInfos)
+        //  {
+        //      LogTool.Error("gdis:" + deniedInfo);
+        //  }
         //
         //
-        // ATSDKAPI.deniedUploadDeviceInfo(deniedInfos);
-
-        //ATSDKAPI.showDebuggerUI("417b0c4ec2dad1d3ebffbcbb43e5da28d2bfefed");
+        //  ATSDKAPI.deniedUploadDeviceInfo(deniedInfos);
+        //
+        // ATSDKAPI.showDebuggerUI("417b0c4ec2dad1d3ebffbcbb43e5da28d2bfefed");
     }
     }
 
 
     public void initFail(string message)
     public void initFail(string message)

+ 78 - 0
Assets/Scripts/GameLogic/SDK/TapSDKManager.cs

@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Fort23.Core;
+using TapSDK.Core;
+using TapSDK.Login;
+using UnityEngine;
+using Utility;
+
+namespace GameMono
+{
+    public class TapSDKManager : Singleton<TapSDKManager>
+    {
+        public string clientId = "ivhfbirxgb7i2zp5ww";
+        public string clientToken = "4indLCP7va53MrXXjj1iHWMy9BYsRV6vouIl16Zn";
+
+        public void CustomInit()
+        {
+            TapTapSdkOptions coreOptions = new TapTapSdkOptions
+            {
+                // 客户端 ID,开发者后台获取
+                clientId = clientId,
+                // 客户端令牌,开发者后台获取
+                clientToken = clientToken,
+                // 地区,CN 为国内,Overseas 为海外
+                region = TapTapRegionType.CN,
+                // 语言,默认为 Auto,默认情况下,国内为 zh_Hans,海外为 en
+                preferredLanguage = TapTapLanguageType.zh_Hans,
+                // 是否开启日志,Release 版本请设置为 false
+                enableLog = true
+            };
+            // TapSDK 初始化
+            TapTapSDK.Init(coreOptions);
+            // 当需要添加其他模块的初始化配置项,例如合规认证、成就等, 请使用如下 API
+            TapTapSdkBaseOptions[] otherOptions = new TapTapSdkBaseOptions[]
+            {
+                // 其他模块配置项
+            };
+            TapTapSDK.Init(coreOptions, otherOptions);
+        }
+
+        public async CTask<bool> Login()
+        {
+            CTask<bool> cTask = CTask<bool>.Create();
+            try
+            {
+                // 定义授权范围
+                List<string> scopes = new List<string>
+                {
+                    TapTapLogin.TAP_LOGIN_SCOPE_PUBLIC_PROFILE
+                };
+                // 发起 Tap 登录
+                var userInfo = await TapTapLogin.Instance.LoginWithScopes(scopes.ToArray());
+                cTask.SetResult(true);
+                // HudPanel.ShowTipsCom($"登录成功,当前用户 ID:{userInfo.unionId}");
+                Debug.Log($"登录成功,当前用户 ID:{userInfo.unionId}");
+            }
+            catch (TaskCanceledException)
+            {
+                cTask.SetResult(false);
+                // HudPanel.ShowTipsCom("用户取消登录");
+                Debug.Log("用户取消登录");
+            }
+            catch (Exception exception)
+            {
+                // HudPanel.ShowTipsCom($"登录失败,出现异常:{exception}");
+                Debug.Log($"登录失败,出现异常:{exception}");
+            }
+
+            return await cTask;
+        }
+
+        public void LogOut()
+        {
+            TapTapLogin.Instance.Logout();
+        }
+    }
+}

+ 11 - 0
Assets/Scripts/GameLogic/SDK/TapSDKManager.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: CnhJsin4UCqH2zNfRg6rFId3QAXtpWGChntqwu3nsk2GGf7JqSJOwnIT8pkY
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 3
Assets/Scripts/GameLogic/Shop/ShopManger.cs

@@ -294,7 +294,8 @@ public class ShopManger : Singleton<ShopManger>
         {
         {
             var dic = new Dictionary<string, string>();
             var dic = new Dictionary<string, string>();
             dic.Add("buyItem", shopItemConfig.ID.ToString());
             dic.Add("buyItem", shopItemConfig.ID.ToString());
-            isOk = true;
+            // isOk = true;
+            isOk = await TakuSDKManager.Instance.ShowAutoAd();
 
 
             if (isOk)
             if (isOk)
             {
             {
@@ -304,7 +305,8 @@ public class ShopManger : Singleton<ShopManger>
         }
         }
         else
         else
         {
         {
-            if (PlayerManager.Instance.BagController.DeductItem(shopItemConfig.costItemId, shopItemConfig.price * count))
+            if (PlayerManager.Instance.BagController.DeductItem(shopItemConfig.costItemId,
+                    shopItemConfig.price * count))
             {
             {
                 isOk = true;
                 isOk = true;
             }
             }
@@ -331,7 +333,7 @@ public class ShopManger : Singleton<ShopManger>
                 dic.Add("ShopItemId", shopItemConfig.ID.ToString());
                 dic.Add("ShopItemId", shopItemConfig.ID.ToString());
             }
             }
 
 
-        
+
             return itemList;
             return itemList;
         }
         }
         else
         else

+ 7 - 2
Assets/Scripts/GameUI/GameApplction.cs

@@ -13,6 +13,7 @@ using GameLogic.CombatScenesTool;
 using GameLogic.Hero;
 using GameLogic.Hero;
 using GameLogic.NetworkClient;
 using GameLogic.NetworkClient;
 using GameLogic.Player;
 using GameLogic.Player;
+using GameMono;
 using GameUI;
 using GameUI;
 using NetCore.Protocol.MemoryPack;
 using NetCore.Protocol.MemoryPack;
 #if UNITY_EDITOR
 #if UNITY_EDITOR
@@ -72,6 +73,9 @@ public class GameApplction : IGameStart
         AssetBundleLoadManager.Instance.BundleLoadType = BundleLoadType;
         AssetBundleLoadManager.Instance.BundleLoadType = BundleLoadType;
         AssetBundleLoadManager.Instance.h5Url = h5Url;
         AssetBundleLoadManager.Instance.h5Url = h5Url;
         await AssetBundleLoadManager.Instance.InitAssetsManager(null);
         await AssetBundleLoadManager.Instance.InitAssetsManager(null);
+
+        TakuSDKManager.Instance.CustomInit();
+        TapSDKManager.Instance.CustomInit();
 #if !UNITY_EDITOR
 #if !UNITY_EDITOR
         AssetBundleLoadManager.Instance.AddBundleTask("fb010shader", delegate(BundleLoadBasic basic, object o)
         AssetBundleLoadManager.Instance.AddBundleTask("fb010shader", delegate(BundleLoadBasic basic, object o)
         {
         {
@@ -116,6 +120,8 @@ public class GameApplction : IGameStart
         //     return;
         //     return;
         // }
         // }
 
 
+        await TapSDKManager.Instance.Login();
+
         EventSystemManager.Instance.CustomInit();
         EventSystemManager.Instance.CustomInit();
         PlayerManager.Instance.Init();
         PlayerManager.Instance.Init();
         await ShowItemMoveToTargetPanel.OpenShowItemMoveToTargetPanel();
         await ShowItemMoveToTargetPanel.OpenShowItemMoveToTargetPanel();
@@ -196,7 +202,7 @@ public class GameApplction : IGameStart
                     LogTool.Log("战斗完成" + isWin);
                     LogTool.Log("战斗完成" + isWin);
                     cTask.SetResult();
                     cTask.SetResult();
                 });
                 });
-            
+
             await cTask;
             await cTask;
 
 
             AccountFileInfo.EventList eventList1 = EventSystemManager.Instance.AddEvent(10000);
             AccountFileInfo.EventList eventList1 = EventSystemManager.Instance.AddEvent(10000);
@@ -206,7 +212,6 @@ public class GameApplction : IGameStart
             AccountFileInfo.Instance.SavePlayerData();
             AccountFileInfo.Instance.SavePlayerData();
 
 
             MainPanel mainPanel = await MainPanel.OpenPanel();
             MainPanel mainPanel = await MainPanel.OpenPanel();
-    
         }
         }
     }
     }
 }
 }

+ 3 - 1
Assets/Scripts/ThirdParty/Fort23.ThirdParty.asmdef

@@ -7,7 +7,9 @@
         "GUID:343deaaf83e0cee4ca978e7df0b80d21",
         "GUID:343deaaf83e0cee4ca978e7df0b80d21",
         "GUID:2bafac87e7f4b9b418d9448d219b01ab",
         "GUID:2bafac87e7f4b9b418d9448d219b01ab",
         "GUID:df380645f10b7bc4b97d4f5eb6303d95",
         "GUID:df380645f10b7bc4b97d4f5eb6303d95",
-        "GUID:15fc0a57446b3144c949da3e2b9737a9"
+        "GUID:15fc0a57446b3144c949da3e2b9737a9",
+        "GUID:7d5ef2062f3704e1ab74aac0e4d5a1a7",
+        "GUID:e8754b6153389406c963cd52996cc80f"
     ],
     ],
     "includePlatforms": [],
     "includePlatforms": [],
     "excludePlatforms": [],
     "excludePlatforms": [],

+ 8 - 0
Assets/TapSDK.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: WnxOsiP8U3vijjyyM5bwL9YUn1EHUj5sGzYc2V5o6iL5BZpxWsJ1UaG1vVGx
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/TapSDK/Core.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: Bi8c5y7+W39alchwKVtEFWOpWKGr3OsAk3Lj2a6er+C67o77zvS6wky+qdby
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/TapSDK/Core/Editor.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 829b7cb0b66da498b9d1cc859956fc7c
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 14 - 0
Assets/TapSDK/Core/Editor/BuildTargetUtils.cs

@@ -0,0 +1,14 @@
+using UnityEditor;
+
+namespace TapSDK.Core.Editor {
+    public static class BuildTargetUtils {
+        public static bool IsSupportMobile(BuildTarget platform) {
+            return platform == BuildTarget.iOS || platform == BuildTarget.Android;
+        }
+
+        public static bool IsSupportStandalone(BuildTarget platform) {
+            return platform == BuildTarget.StandaloneOSX ||
+                platform == BuildTarget.StandaloneWindows || platform == BuildTarget.StandaloneWindows64;
+        }
+}
+}

+ 11 - 0
Assets/TapSDK/Core/Editor/BuildTargetUtils.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9416fb163ae0c4cbb8d52caa63978b2a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 70 - 0
Assets/TapSDK/Core/Editor/LinkXMLGenerator.cs

@@ -0,0 +1,70 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using UnityEngine;
+using UnityEditor;
+
+namespace TapSDK.Core.Editor {
+    public class LinkedAssembly {
+        public string Fullname { get; set; }
+        public string[] Types { get; set; }
+    }
+
+    public class LinkXMLGenerator {
+        public static void Generate(string path, IEnumerable<LinkedAssembly> assemblies) {
+            DirectoryInfo parent = Directory.GetParent(path);
+            if (!parent.Exists) {
+                Directory.CreateDirectory(parent.FullName);
+            }
+
+            XmlDocument doc = new XmlDocument();
+
+            XmlNode rootNode = doc.CreateElement("linker");
+            doc.AppendChild(rootNode);
+
+            foreach (LinkedAssembly assembly in assemblies) {
+                XmlNode assemblyNode = doc.CreateElement("assembly");
+
+                XmlAttribute fullnameAttr = doc.CreateAttribute("fullname");
+                fullnameAttr.Value = assembly.Fullname;
+                assemblyNode.Attributes.Append(fullnameAttr);
+
+                if (assembly.Types?.Length > 0) {
+                    foreach (string type in assembly.Types) {
+                        XmlNode typeNode = doc.CreateElement("type");
+                        XmlAttribute typeFullnameAttr = doc.CreateAttribute("fullname");
+                        typeFullnameAttr.Value = type;
+                        typeNode.Attributes.Append(typeFullnameAttr);
+
+                        XmlAttribute typePreserveAttr = doc.CreateAttribute("preserve");
+                        typePreserveAttr.Value = "all";
+                        typeNode.Attributes.Append(typePreserveAttr);
+
+                        assemblyNode.AppendChild(typeNode);
+                    }
+                } else {
+                    XmlAttribute preserveAttr = doc.CreateAttribute("preserve");
+                    preserveAttr.Value = "all";
+                    assemblyNode.Attributes.Append(preserveAttr);
+                }
+
+                rootNode.AppendChild(assemblyNode);
+            }
+
+            doc.Save(path);
+            AssetDatabase.Refresh();
+
+            Debug.Log($"Generate {path} done.");
+            Debug.Log(doc.OuterXml);
+        }
+
+        public static void Delete(string path) {
+            if (File.Exists(path)) {
+                File.Delete(path);
+                AssetDatabase.Refresh();
+            }
+
+            Debug.Log($"Delete {path} done.");
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Editor/LinkXMLGenerator.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ded83e14866c44fe0912befabd966846
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 954 - 0
Assets/TapSDK/Core/Editor/Plist.cs

@@ -0,0 +1,954 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+namespace TapSDK.Core.Editor
+{
+    public static class Plist
+    {
+        private static List<int> offsetTable = new List<int>();
+        private static List<byte> objectTable = new List<byte>();
+        private static int refCount;
+        private static int objRefSize;
+        private static int offsetByteSize;
+        private static long offsetTableOffset;
+        
+        #region Public Functions
+
+        public static object readPlist(string path)
+        {
+            using (FileStream f = new FileStream(path, FileMode.Open, FileAccess.Read))
+            {
+                return readPlist(f, plistType.Auto);
+            }
+        }
+
+        public static object readPlistSource(string source)
+        {
+            return readPlist(System.Text.Encoding.UTF8.GetBytes(source));
+        }
+
+        public static object readPlist(byte[] data)
+        {
+            return readPlist(new MemoryStream(data), plistType.Auto);
+        }
+
+        public static plistType getPlistType(Stream stream)
+        {
+            byte[] magicHeader = new byte[8];
+            stream.Read(magicHeader, 0, 8);
+
+            if (BitConverter.ToInt64(magicHeader, 0) == 3472403351741427810)
+            {
+                return plistType.Binary;
+            }
+            else
+            {
+                return plistType.Xml;
+            }
+        }
+
+        public static object readPlist(Stream stream, plistType type)
+        {
+            if (type == plistType.Auto)
+            {
+                type = getPlistType(stream);
+                stream.Seek(0, SeekOrigin.Begin);
+            }
+
+            if (type == plistType.Binary)
+            {
+                using (BinaryReader reader = new BinaryReader(stream))
+                {
+                    byte[] data = reader.ReadBytes((int) reader.BaseStream.Length);
+                    return readBinary(data);
+                }
+            }
+            else
+            {
+                XmlDocument xml = new XmlDocument();
+                xml.XmlResolver = null;
+                xml.Load(stream);
+                return readXml(xml);
+            }
+        }
+
+        public static void writeXml(object value, string path)
+        {
+            using (StreamWriter writer = new StreamWriter(path))
+            {
+                writer.Write(writeXml(value));
+            }
+        }
+
+        public static void writeXml(object value, Stream stream)
+        {
+            using (StreamWriter writer = new StreamWriter(stream))
+            {
+                writer.Write(writeXml(value));
+            }
+        }
+
+        public static string writeXml(object value)
+        {
+            using (MemoryStream ms = new MemoryStream())
+            {
+                XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
+                xmlWriterSettings.Encoding = new System.Text.UTF8Encoding(false);
+                xmlWriterSettings.ConformanceLevel = ConformanceLevel.Document;
+                xmlWriterSettings.Indent = true;
+
+                using (XmlWriter xmlWriter = XmlWriter.Create(ms, xmlWriterSettings))
+                {
+                    xmlWriter.WriteStartDocument();
+                    //xmlWriter.WriteComment("DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " + "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
+                    xmlWriter.WriteDocType("plist", "-//Apple Computer//DTD PLIST 1.0//EN",
+                        "http://www.apple.com/DTDs/PropertyList-1.0.dtd", null);
+                    xmlWriter.WriteStartElement("plist");
+                    xmlWriter.WriteAttributeString("version", "1.0");
+                    compose(value, xmlWriter);
+                    xmlWriter.WriteEndElement();
+                    xmlWriter.WriteEndDocument();
+                    xmlWriter.Flush();
+                    xmlWriter.Close();
+                    return System.Text.Encoding.UTF8.GetString(ms.ToArray());
+                }
+            }
+        }
+
+        public static void writeBinary(object value, string path)
+        {
+            using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create)))
+            {
+                writer.Write(writeBinary(value));
+            }
+        }
+
+        public static void writeBinary(object value, Stream stream)
+        {
+            using (BinaryWriter writer = new BinaryWriter(stream))
+            {
+                writer.Write(writeBinary(value));
+            }
+        }
+
+        public static byte[] writeBinary(object value)
+        {
+            offsetTable.Clear();
+            objectTable.Clear();
+            refCount = 0;
+            objRefSize = 0;
+            offsetByteSize = 0;
+            offsetTableOffset = 0;
+
+            //Do not count the root node, subtract by 1
+            int totalRefs = countObject(value) - 1;
+
+            refCount = totalRefs;
+
+            objRefSize = RegulateNullBytes(BitConverter.GetBytes(refCount)).Length;
+
+            composeBinary(value);
+
+            writeBinaryString("bplist00", false);
+
+            offsetTableOffset = (long) objectTable.Count;
+
+            offsetTable.Add(objectTable.Count - 8);
+
+            offsetByteSize = RegulateNullBytes(BitConverter.GetBytes(offsetTable[offsetTable.Count - 1])).Length;
+
+            List<byte> offsetBytes = new List<byte>();
+
+            offsetTable.Reverse();
+
+            for (int i = 0; i < offsetTable.Count; i++)
+            {
+                offsetTable[i] = objectTable.Count - offsetTable[i];
+                byte[] buffer = RegulateNullBytes(BitConverter.GetBytes(offsetTable[i]), offsetByteSize);
+                Array.Reverse(buffer);
+                offsetBytes.AddRange(buffer);
+            }
+
+            objectTable.AddRange(offsetBytes);
+
+            objectTable.AddRange(new byte[6]);
+            objectTable.Add(Convert.ToByte(offsetByteSize));
+            objectTable.Add(Convert.ToByte(objRefSize));
+
+            var a = BitConverter.GetBytes((long) totalRefs + 1);
+            Array.Reverse(a);
+            objectTable.AddRange(a);
+
+            objectTable.AddRange(BitConverter.GetBytes((long) 0));
+            a = BitConverter.GetBytes(offsetTableOffset);
+            Array.Reverse(a);
+            objectTable.AddRange(a);
+
+            return objectTable.ToArray();
+        }
+
+        #endregion
+
+        #region Private Functions
+
+        private static object readXml(XmlDocument xml)
+        {
+            XmlNode rootNode = xml.DocumentElement.ChildNodes[0];
+            return parse(rootNode);
+        }
+
+        private static object readBinary(byte[] data)
+        {
+            offsetTable.Clear();
+            List<byte> offsetTableBytes = new List<byte>();
+            objectTable.Clear();
+            refCount = 0;
+            objRefSize = 0;
+            offsetByteSize = 0;
+            offsetTableOffset = 0;
+
+            List<byte> bList = new List<byte>(data);
+
+            List<byte> trailer = bList.GetRange(bList.Count - 32, 32);
+
+            parseTrailer(trailer);
+
+            objectTable = bList.GetRange(0, (int) offsetTableOffset);
+
+            offsetTableBytes = bList.GetRange((int) offsetTableOffset, bList.Count - (int) offsetTableOffset - 32);
+
+            parseOffsetTable(offsetTableBytes);
+
+            return parseBinary(0);
+        }
+
+        private static Dictionary<string, object> parseDictionary(XmlNode node)
+        {
+            XmlNodeList children = node.ChildNodes;
+            if (children.Count % 2 != 0)
+            {
+                throw new DataMisalignedException("Dictionary elements must have an even number of child nodes");
+            }
+
+            Dictionary<string, object> dict = new Dictionary<string, object>();
+
+            for (int i = 0; i < children.Count; i += 2)
+            {
+                XmlNode keynode = children[i];
+                XmlNode valnode = children[i + 1];
+
+                if (keynode.Name != "key")
+                {
+                    throw new ApplicationException("expected a key node");
+                }
+
+                object result = parse(valnode);
+
+                if (result != null)
+                {
+                    dict.Add(keynode.InnerText, result);
+                }
+            }
+
+            return dict;
+        }
+
+        private static List<object> parseArray(XmlNode node)
+        {
+            List<object> array = new List<object>();
+
+            foreach (XmlNode child in node.ChildNodes)
+            {
+                object result = parse(child);
+                if (result != null)
+                {
+                    array.Add(result);
+                }
+            }
+
+            return array;
+        }
+
+        private static void composeArray(List<object> value, XmlWriter writer)
+        {
+            writer.WriteStartElement("array");
+            foreach (object obj in value)
+            {
+                compose(obj, writer);
+            }
+
+            writer.WriteEndElement();
+        }
+
+        private static object parse(XmlNode node)
+        {
+            switch (node.Name)
+            {
+                case "dict":
+                    return parseDictionary(node);
+                case "array":
+                    return parseArray(node);
+                case "string":
+                    return node.InnerText;
+                case "integer":
+                    //  int result;
+                    //int.TryParse(node.InnerText, System.Globalization.NumberFormatInfo.InvariantInfo, out result);
+                    return Convert.ToInt32(node.InnerText, System.Globalization.NumberFormatInfo.InvariantInfo);
+                case "real":
+                    return Convert.ToDouble(node.InnerText, System.Globalization.NumberFormatInfo.InvariantInfo);
+                case "false":
+                    return false;
+                case "true":
+                    return true;
+                case "null":
+                    return null;
+                case "date":
+                    return XmlConvert.ToDateTime(node.InnerText, XmlDateTimeSerializationMode.Utc);
+                case "data":
+                    return Convert.FromBase64String(node.InnerText);
+            }
+
+            throw new ApplicationException(String.Format("Plist Node `{0}' is not supported", node.Name));
+        }
+
+        private static void compose(object value, XmlWriter writer)
+        {
+            if (value == null || value is string)
+            {
+                writer.WriteElementString("string", value as string);
+            }
+            else if (value is int || value is long)
+            {
+                writer.WriteElementString("integer",
+                    ((int) value).ToString(System.Globalization.NumberFormatInfo.InvariantInfo));
+            }
+            else if (value is System.Collections.Generic.Dictionary<string, object> ||
+                     value.GetType().ToString().StartsWith("System.Collections.Generic.Dictionary`2[System.String"))
+            {
+                //Convert to Dictionary<string, object>
+                Dictionary<string, object> dic = value as Dictionary<string, object>;
+                if (dic == null)
+                {
+                    dic = new Dictionary<string, object>();
+                    IDictionary idic = (IDictionary) value;
+                    foreach (var key in idic.Keys)
+                    {
+                        dic.Add(key.ToString(), idic[key]);
+                    }
+                }
+
+                writeDictionaryValues(dic, writer);
+            }
+            else if (value is List<object>)
+            {
+                composeArray((List<object>) value, writer);
+            }
+            else if (value is byte[])
+            {
+                writer.WriteElementString("data", Convert.ToBase64String((Byte[]) value));
+            }
+            else if (value is float || value is double)
+            {
+                writer.WriteElementString("real",
+                    ((double) value).ToString(System.Globalization.NumberFormatInfo.InvariantInfo));
+            }
+            else if (value is DateTime)
+            {
+                DateTime time = (DateTime) value;
+                string theString = XmlConvert.ToString(time, XmlDateTimeSerializationMode.Utc);
+                writer.WriteElementString("date", theString); //, "yyyy-MM-ddTHH:mm:ssZ"));
+            }
+            else if (value is bool)
+            {
+                writer.WriteElementString(value.ToString().ToLower(), "");
+            }
+            else
+            {
+                throw new Exception(String.Format("Value type '{0}' is unhandled", value.GetType().ToString()));
+            }
+        }
+
+        private static void writeDictionaryValues(Dictionary<string, object> dictionary, XmlWriter writer)
+        {
+            writer.WriteStartElement("dict");
+            foreach (string key in dictionary.Keys)
+            {
+                object value = dictionary[key];
+                writer.WriteElementString("key", key);
+                compose(value, writer);
+            }
+
+            writer.WriteEndElement();
+        }
+
+        private static int countObject(object value)
+        {
+            int count = 0;
+            switch (value.GetType().ToString())
+            {
+                case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
+                    Dictionary<string, object> dict = (Dictionary<string, object>) value;
+                    foreach (string key in dict.Keys)
+                    {
+                        count += countObject(dict[key]);
+                    }
+
+                    count += dict.Keys.Count;
+                    count++;
+                    break;
+                case "System.Collections.Generic.List`1[System.Object]":
+                    List<object> list = (List<object>) value;
+                    foreach (object obj in list)
+                    {
+                        count += countObject(obj);
+                    }
+
+                    count++;
+                    break;
+                default:
+                    count++;
+                    break;
+            }
+
+            return count;
+        }
+
+        private static byte[] writeBinaryDictionary(Dictionary<string, object> dictionary)
+        {
+            List<byte> buffer = new List<byte>();
+            List<byte> header = new List<byte>();
+            List<int> refs = new List<int>();
+            for (int i = dictionary.Count - 1; i >= 0; i--)
+            {
+                var o = new object[dictionary.Count];
+                dictionary.Values.CopyTo(o, 0);
+                composeBinary(o[i]);
+                offsetTable.Add(objectTable.Count);
+                refs.Add(refCount);
+                refCount--;
+            }
+
+            for (int i = dictionary.Count - 1; i >= 0; i--)
+            {
+                var o = new string[dictionary.Count];
+                dictionary.Keys.CopyTo(o, 0);
+                composeBinary(o[i]); //);
+                offsetTable.Add(objectTable.Count);
+                refs.Add(refCount);
+                refCount--;
+            }
+
+            if (dictionary.Count < 15)
+            {
+                header.Add(Convert.ToByte(0xD0 | Convert.ToByte(dictionary.Count)));
+            }
+            else
+            {
+                header.Add(0xD0 | 0xf);
+                header.AddRange(writeBinaryInteger(dictionary.Count, false));
+            }
+
+
+            foreach (int val in refs)
+            {
+                byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize);
+                Array.Reverse(refBuffer);
+                buffer.InsertRange(0, refBuffer);
+            }
+
+            buffer.InsertRange(0, header);
+
+
+            objectTable.InsertRange(0, buffer);
+
+            return buffer.ToArray();
+        }
+
+        private static byte[] composeBinaryArray(List<object> objects)
+        {
+            List<byte> buffer = new List<byte>();
+            List<byte> header = new List<byte>();
+            List<int> refs = new List<int>();
+
+            for (int i = objects.Count - 1; i >= 0; i--)
+            {
+                composeBinary(objects[i]);
+                offsetTable.Add(objectTable.Count);
+                refs.Add(refCount);
+                refCount--;
+            }
+
+            if (objects.Count < 15)
+            {
+                header.Add(Convert.ToByte(0xA0 | Convert.ToByte(objects.Count)));
+            }
+            else
+            {
+                header.Add(0xA0 | 0xf);
+                header.AddRange(writeBinaryInteger(objects.Count, false));
+            }
+
+            foreach (int val in refs)
+            {
+                byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize);
+                Array.Reverse(refBuffer);
+                buffer.InsertRange(0, refBuffer);
+            }
+
+            buffer.InsertRange(0, header);
+
+            objectTable.InsertRange(0, buffer);
+
+            return buffer.ToArray();
+        }
+
+        private static byte[] composeBinary(object obj)
+        {
+            byte[] value;
+            switch (obj.GetType().ToString())
+            {
+                case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
+                    value = writeBinaryDictionary((Dictionary<string, object>) obj);
+                    return value;
+
+                case "System.Collections.Generic.List`1[System.Object]":
+                    value = composeBinaryArray((List<object>) obj);
+                    return value;
+
+                case "System.Byte[]":
+                    value = writeBinaryByteArray((byte[]) obj);
+                    return value;
+
+                case "System.Double":
+                    value = writeBinaryDouble((double) obj);
+                    return value;
+
+                case "System.Int32":
+                    value = writeBinaryInteger((int) obj, true);
+                    return value;
+
+                case "System.String":
+                    value = writeBinaryString((string) obj, true);
+                    return value;
+
+                case "System.DateTime":
+                    value = writeBinaryDate((DateTime) obj);
+                    return value;
+
+                case "System.Boolean":
+                    value = writeBinaryBool((bool) obj);
+                    return value;
+
+                default:
+                    return new byte[0];
+            }
+        }
+
+        public static byte[] writeBinaryDate(DateTime obj)
+        {
+            List<byte> buffer =
+                new List<byte>(RegulateNullBytes(BitConverter.GetBytes(PlistDateConverter.ConvertToAppleTimeStamp(obj)),
+                    8));
+            buffer.Reverse();
+            buffer.Insert(0, 0x33);
+            objectTable.InsertRange(0, buffer);
+            return buffer.ToArray();
+        }
+
+        public static byte[] writeBinaryBool(bool obj)
+        {
+            List<byte> buffer = new List<byte>(new byte[1] {(bool) obj ? (byte) 9 : (byte) 8});
+            objectTable.InsertRange(0, buffer);
+            return buffer.ToArray();
+        }
+
+        private static byte[] writeBinaryInteger(int value, bool write)
+        {
+            List<byte> buffer = new List<byte>(BitConverter.GetBytes((long) value));
+            buffer = new List<byte>(RegulateNullBytes(buffer.ToArray()));
+            while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count) / Math.Log(2)))
+                buffer.Add(0);
+            int header = 0x10 | (int) (Math.Log(buffer.Count) / Math.Log(2));
+
+            buffer.Reverse();
+
+            buffer.Insert(0, Convert.ToByte(header));
+
+            if (write)
+                objectTable.InsertRange(0, buffer);
+
+            return buffer.ToArray();
+        }
+
+        private static byte[] writeBinaryDouble(double value)
+        {
+            List<byte> buffer = new List<byte>(RegulateNullBytes(BitConverter.GetBytes(value), 4));
+            while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count) / Math.Log(2)))
+                buffer.Add(0);
+            int header = 0x20 | (int) (Math.Log(buffer.Count) / Math.Log(2));
+
+            buffer.Reverse();
+
+            buffer.Insert(0, Convert.ToByte(header));
+
+            objectTable.InsertRange(0, buffer);
+
+            return buffer.ToArray();
+        }
+
+        private static byte[] writeBinaryByteArray(byte[] value)
+        {
+            List<byte> buffer = new List<byte>(value);
+            List<byte> header = new List<byte>();
+            if (value.Length < 15)
+            {
+                header.Add(Convert.ToByte(0x40 | Convert.ToByte(value.Length)));
+            }
+            else
+            {
+                header.Add(0x40 | 0xf);
+                header.AddRange(writeBinaryInteger(buffer.Count, false));
+            }
+
+            buffer.InsertRange(0, header);
+
+            objectTable.InsertRange(0, buffer);
+
+            return buffer.ToArray();
+        }
+
+        private static byte[] writeBinaryString(string value, bool head)
+        {
+            List<byte> buffer = new List<byte>();
+            List<byte> header = new List<byte>();
+            foreach (char chr in value.ToCharArray())
+                buffer.Add(Convert.ToByte(chr));
+
+            if (head)
+            {
+                if (value.Length < 15)
+                {
+                    header.Add(Convert.ToByte(0x50 | Convert.ToByte(value.Length)));
+                }
+                else
+                {
+                    header.Add(0x50 | 0xf);
+                    header.AddRange(writeBinaryInteger(buffer.Count, false));
+                }
+            }
+
+            buffer.InsertRange(0, header);
+
+            objectTable.InsertRange(0, buffer);
+
+            return buffer.ToArray();
+        }
+
+        private static byte[] RegulateNullBytes(byte[] value)
+        {
+            return RegulateNullBytes(value, 1);
+        }
+
+        private static byte[] RegulateNullBytes(byte[] value, int minBytes)
+        {
+            Array.Reverse(value);
+            List<byte> bytes = new List<byte>(value);
+            for (int i = 0; i < bytes.Count; i++)
+            {
+                if (bytes[i] == 0 && bytes.Count > minBytes)
+                {
+                    bytes.Remove(bytes[i]);
+                    i--;
+                }
+                else
+                    break;
+            }
+
+            if (bytes.Count < minBytes)
+            {
+                int dist = minBytes - bytes.Count;
+                for (int i = 0; i < dist; i++)
+                    bytes.Insert(0, 0);
+            }
+
+            value = bytes.ToArray();
+            Array.Reverse(value);
+            return value;
+        }
+
+        private static void parseTrailer(List<byte> trailer)
+        {
+            offsetByteSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(6, 1).ToArray(), 4), 0);
+            objRefSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(7, 1).ToArray(), 4), 0);
+            byte[] refCountBytes = trailer.GetRange(12, 4).ToArray();
+            Array.Reverse(refCountBytes);
+            refCount = BitConverter.ToInt32(refCountBytes, 0);
+            byte[] offsetTableOffsetBytes = trailer.GetRange(24, 8).ToArray();
+            Array.Reverse(offsetTableOffsetBytes);
+            offsetTableOffset = BitConverter.ToInt64(offsetTableOffsetBytes, 0);
+        }
+
+        private static void parseOffsetTable(List<byte> offsetTableBytes)
+        {
+            for (int i = 0; i < offsetTableBytes.Count; i += offsetByteSize)
+            {
+                byte[] buffer = offsetTableBytes.GetRange(i, offsetByteSize).ToArray();
+                Array.Reverse(buffer);
+                offsetTable.Add(BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0));
+            }
+        }
+
+        private static object parseBinaryDictionary(int objRef)
+        {
+            Dictionary<string, object> buffer = new Dictionary<string, object>();
+            List<int> refs = new List<int>();
+            int refCount = 0;
+
+            int refStartPosition;
+            refCount = getCount(offsetTable[objRef], out refStartPosition);
+
+
+            if (refCount < 15)
+                refStartPosition = offsetTable[objRef] + 1;
+            else
+                refStartPosition = offsetTable[objRef] + 2 +
+                                   RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length;
+
+            for (int i = refStartPosition; i < refStartPosition + refCount * 2 * objRefSize; i += objRefSize)
+            {
+                byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray();
+                Array.Reverse(refBuffer);
+                refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0));
+            }
+
+            for (int i = 0; i < refCount; i++)
+            {
+                buffer.Add((string) parseBinary(refs[i]), parseBinary(refs[i + refCount]));
+            }
+
+            return buffer;
+        }
+
+        private static object parseBinaryArray(int objRef)
+        {
+            List<object> buffer = new List<object>();
+            List<int> refs = new List<int>();
+            int refCount = 0;
+
+            int refStartPosition;
+            refCount = getCount(offsetTable[objRef], out refStartPosition);
+
+
+            if (refCount < 15)
+                refStartPosition = offsetTable[objRef] + 1;
+            else
+                //The following integer has a header aswell so we increase the refStartPosition by two to account for that.
+                refStartPosition = offsetTable[objRef] + 2 +
+                                   RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length;
+
+            for (int i = refStartPosition; i < refStartPosition + refCount * objRefSize; i += objRefSize)
+            {
+                byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray();
+                Array.Reverse(refBuffer);
+                refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0));
+            }
+
+            for (int i = 0; i < refCount; i++)
+            {
+                buffer.Add(parseBinary(refs[i]));
+            }
+
+            return buffer;
+        }
+
+        private static int getCount(int bytePosition, out int newBytePosition)
+        {
+            byte headerByte = objectTable[bytePosition];
+            byte headerByteTrail = Convert.ToByte(headerByte & 0xf);
+            int count;
+            if (headerByteTrail < 15)
+            {
+                count = headerByteTrail;
+                newBytePosition = bytePosition + 1;
+            }
+            else
+                count = (int) parseBinaryInt(bytePosition + 1, out newBytePosition);
+
+            return count;
+        }
+
+        private static object parseBinary(int objRef)
+        {
+            byte header = objectTable[offsetTable[objRef]];
+            switch (header & 0xF0)
+            {
+                case 0:
+                {
+                    //If the byte is
+                    //0 return null
+                    //9 return true
+                    //8 return false
+                    return (objectTable[offsetTable[objRef]] == 0)
+                        ? (object) null
+                        : ((objectTable[offsetTable[objRef]] == 9) ? true : false);
+                }
+                case 0x10:
+                {
+                    return parseBinaryInt(offsetTable[objRef]);
+                }
+                case 0x20:
+                {
+                    return parseBinaryReal(offsetTable[objRef]);
+                }
+                case 0x30:
+                {
+                    return parseBinaryDate(offsetTable[objRef]);
+                }
+                case 0x40:
+                {
+                    return parseBinaryByteArray(offsetTable[objRef]);
+                }
+                case 0x50: //String ASCII
+                {
+                    return parseBinaryAsciiString(offsetTable[objRef]);
+                }
+                case 0x60: //String Unicode
+                {
+                    return parseBinaryUnicodeString(offsetTable[objRef]);
+                }
+                case 0xD0:
+                {
+                    return parseBinaryDictionary(objRef);
+                }
+                case 0xA0:
+                {
+                    return parseBinaryArray(objRef);
+                }
+            }
+
+            throw new Exception("This type is not supported");
+        }
+
+        public static object parseBinaryDate(int headerPosition)
+        {
+            byte[] buffer = objectTable.GetRange(headerPosition + 1, 8).ToArray();
+            Array.Reverse(buffer);
+            double appleTime = BitConverter.ToDouble(buffer, 0);
+            DateTime result = PlistDateConverter.ConvertFromAppleTimeStamp(appleTime);
+            return result;
+        }
+
+        private static object parseBinaryInt(int headerPosition)
+        {
+            int output;
+            return parseBinaryInt(headerPosition, out output);
+        }
+
+        private static object parseBinaryInt(int headerPosition, out int newHeaderPosition)
+        {
+            byte header = objectTable[headerPosition];
+            int byteCount = (int) Math.Pow(2, header & 0xf);
+            byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray();
+            Array.Reverse(buffer);
+            //Add one to account for the header byte
+            newHeaderPosition = headerPosition + byteCount + 1;
+            return BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0);
+        }
+
+        private static object parseBinaryReal(int headerPosition)
+        {
+            byte header = objectTable[headerPosition];
+            int byteCount = (int) Math.Pow(2, header & 0xf);
+            byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray();
+            Array.Reverse(buffer);
+
+            return BitConverter.ToDouble(RegulateNullBytes(buffer, 8), 0);
+        }
+
+        private static object parseBinaryAsciiString(int headerPosition)
+        {
+            int charStartPosition;
+            int charCount = getCount(headerPosition, out charStartPosition);
+
+            var buffer = objectTable.GetRange(charStartPosition, charCount);
+            return buffer.Count > 0 ? Encoding.ASCII.GetString(buffer.ToArray()) : string.Empty;
+        }
+
+        private static object parseBinaryUnicodeString(int headerPosition)
+        {
+            int charStartPosition;
+            int charCount = getCount(headerPosition, out charStartPosition);
+            charCount = charCount * 2;
+
+            byte[] buffer = new byte[charCount];
+            byte one, two;
+
+            for (int i = 0; i < charCount; i += 2)
+            {
+                one = objectTable.GetRange(charStartPosition + i, 1)[0];
+                two = objectTable.GetRange(charStartPosition + i + 1, 1)[0];
+
+                if (BitConverter.IsLittleEndian)
+                {
+                    buffer[i] = two;
+                    buffer[i + 1] = one;
+                }
+                else
+                {
+                    buffer[i] = one;
+                    buffer[i + 1] = two;
+                }
+            }
+
+            return Encoding.Unicode.GetString(buffer);
+        }
+
+        private static object parseBinaryByteArray(int headerPosition)
+        {
+            int byteStartPosition;
+            int byteCount = getCount(headerPosition, out byteStartPosition);
+            return objectTable.GetRange(byteStartPosition, byteCount).ToArray();
+        }
+
+        #endregion
+    }
+
+    public enum plistType
+    {
+        Auto,
+        Binary,
+        Xml
+    }
+
+    public static class PlistDateConverter
+    {
+        public static long timeDifference = 978307200;
+
+        public static long GetAppleTime(long unixTime)
+        {
+            return unixTime - timeDifference;
+        }
+
+        public static long GetUnixTime(long appleTime)
+        {
+            return appleTime + timeDifference;
+        }
+
+        public static DateTime ConvertFromAppleTimeStamp(double timestamp)
+        {
+            DateTime origin = new DateTime(2001, 1, 1, 0, 0, 0, 0);
+            return origin.AddSeconds(timestamp);
+        }
+
+        public static double ConvertToAppleTimeStamp(DateTime date)
+        {
+            DateTime begin = new DateTime(2001, 1, 1, 0, 0, 0, 0);
+            TimeSpan diff = date - begin;
+            return Math.Floor(diff.TotalSeconds);
+        }
+    }
+}

+ 3 - 0
Assets/TapSDK/Core/Editor/Plist.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 96acb9ea8a9264ea6a175b32e605bfab
+timeCreated: 1617120740

+ 119 - 0
Assets/TapSDK/Core/Editor/SDKLinkProcessBuild.cs

@@ -0,0 +1,119 @@
+using System;
+using System.IO;
+using UnityEngine;
+using UnityEditor;
+using UnityEditor.Build;
+using UnityEditor.Build.Reporting;
+
+namespace TapSDK.Core.Editor {
+    /// <summary>
+    /// 模块 SDK 生成 link.xml 构建过程
+    /// </summary>
+    public abstract class SDKLinkProcessBuild : IPreprocessBuildWithReport, IPostprocessBuildWithReport {
+        /// <summary>
+        /// 执行顺序
+        /// </summary>
+        public abstract int callbackOrder { get; }
+
+        /// <summary>
+        /// 生成 link.xml 路径
+        /// </summary>
+        public abstract string LinkPath { get; }
+
+        /// <summary>
+        /// 防止被裁剪的 Assembly
+        /// </summary>
+        public abstract LinkedAssembly[] LinkedAssemblies { get; }
+
+        /// <summary>
+        /// 执行平台委托
+        /// </summary>
+        public abstract Func<BuildReport, bool> IsTargetPlatform { get; }
+
+        /// <summary>
+        /// 构建时忽略目录,目前主要是 PC 内置浏览器 Vuplex
+        /// </summary>
+        public virtual string[] BuildingIgnorePaths => null;
+
+        /// <summary>
+        /// 构建前处理
+        /// </summary>
+        /// <param name="report"></param>
+        public void OnPreprocessBuild(BuildReport report) {
+            if (!IsTargetPlatform.Invoke(report)) {
+                return;
+            }
+
+            Application.logMessageReceived += OnBuildError;
+            IgnorePaths();
+
+            string linkPath = Path.Combine(Application.dataPath, LinkPath);
+            LinkXMLGenerator.Generate(linkPath, LinkedAssemblies);
+        }
+
+        /// <summary>
+        /// 构建后处理
+        /// </summary>
+        /// <param name="report"></param>
+        public void OnPostprocessBuild(BuildReport report) {
+            if (!IsTargetPlatform.Invoke(report)) {
+                return;
+            }
+
+            Application.logMessageReceived -= OnBuildError;
+            RecoverIgnoredPaths();
+
+            string linkPath = Path.Combine(Application.dataPath, LinkPath);
+            LinkXMLGenerator.Delete(linkPath);
+        }
+
+        /// <summary>
+        /// 错误日志回调
+        /// </summary>
+        /// <param name="condition"></param>
+        /// <param name="stacktrace"></param>
+        /// <param name="logType"></param>
+        private void OnBuildError(string condition, string stacktrace, LogType logType) {
+            // TRICK: 通过捕获错误日志来监听打包错误事件
+            if (logType == LogType.Error) {
+                Application.logMessageReceived -= OnBuildError;
+                RecoverIgnoredPaths();
+            }
+        }
+
+        /// <summary>
+        /// 忽略目录
+        /// </summary>
+        private void IgnorePaths() {
+            if (BuildingIgnorePaths == null) {
+                return;
+            }
+
+            foreach (string ignorePath in BuildingIgnorePaths) {
+                if (!Directory.Exists(Path.Combine(Application.dataPath, ignorePath))) {
+                    continue;
+                }
+                string ignoreName = Path.GetFileName(ignorePath);
+                AssetDatabase.RenameAsset(Path.Combine("Assets", ignorePath), $"{ignoreName}~");
+            }
+        }
+
+        /// <summary>
+        /// 恢复目录
+        /// </summary>
+        private void RecoverIgnoredPaths() {
+            if (BuildingIgnorePaths == null) {
+                return;
+            }
+
+            foreach (string ignorePath in BuildingIgnorePaths) {
+                if (!Directory.Exists(Path.Combine(Application.dataPath, $"{ignorePath}~"))) {
+                    continue;
+                }
+                Directory.Move(Path.Combine(Application.dataPath, $"{ignorePath}~"),
+                    Path.Combine(Application.dataPath, $"{ignorePath}"));
+                AssetDatabase.ImportAsset(Path.Combine("Assets", ignorePath));
+            }
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Editor/SDKLinkProcessBuild.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c724204483e1a47f8a4fe400a1353a56
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 168 - 0
Assets/TapSDK/Core/Editor/TapFileHelper.cs

@@ -0,0 +1,168 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using UnityEngine;
+
+namespace TapSDK.Core.Editor
+{
+    public class TapFileHelper : System.IDisposable
+    {
+        private string filePath;
+
+        public TapFileHelper(string fPath)
+        {
+            filePath = fPath;
+            if (!System.IO.File.Exists(filePath))
+            {
+                Debug.LogError(filePath + "路径下文件不存在");
+                return;
+            }
+        }
+
+        public void WriteBelow(string below, string text)
+        {
+            StreamReader streamReader = new StreamReader(filePath);
+            string all = streamReader.ReadToEnd();
+            streamReader.Close();
+            int beginIndex = all.IndexOf(below, StringComparison.Ordinal);
+            if (beginIndex == -1)
+            {
+                Debug.LogError(filePath + "中没有找到字符串" + below);
+                return;
+            }
+
+            int endIndex = all.LastIndexOf("\n", beginIndex + below.Length, StringComparison.Ordinal);
+            all = all.Substring(0, endIndex) + "\n" + text + "\n" + all.Substring(endIndex);
+            StreamWriter streamWriter = new StreamWriter(filePath);
+            streamWriter.Write(all);
+            streamWriter.Close();
+        }
+
+        public void Replace(string below, string newText)
+        {
+            StreamReader streamReader = new StreamReader(filePath);
+            string all = streamReader.ReadToEnd();
+            streamReader.Close();
+            int beginIndex = all.IndexOf(below, StringComparison.Ordinal);
+            if (beginIndex == -1)
+            {
+                Debug.LogError(filePath + "中没有找到字符串" + below);
+                return;
+            }
+
+            all = all.Replace(below, newText);
+            StreamWriter streamWriter = new StreamWriter(filePath);
+            streamWriter.Write(all);
+            streamWriter.Close();
+        }
+
+        public void Dispose()
+        {
+        }
+
+        public static void CopyAndReplaceDirectory(string srcPath, string dstPath)
+        {
+            if (Directory.Exists(dstPath))
+                Directory.Delete(dstPath, true);
+            if (File.Exists(dstPath))
+                File.Delete(dstPath);
+
+            Directory.CreateDirectory(dstPath);
+
+            foreach (var file in Directory.GetFiles(srcPath))
+                File.Copy(file, Path.Combine(dstPath, Path.GetFileName(file)));
+
+            foreach (var dir in Directory.GetDirectories(srcPath))
+                CopyAndReplaceDirectory(dir, Path.Combine(dstPath, Path.GetFileName(dir)));
+        }
+
+
+        public static void DeleteFileBySuffix(string dir, string[] suffix)
+        {
+            if (!Directory.Exists(dir))
+            {
+                return;
+            }
+
+            foreach (var file in Directory.GetFiles(dir))
+            {
+                foreach (var suffixName in suffix)
+                {
+                    if (file.Contains(suffixName))
+                    {
+                        File.Delete(file);
+                    }
+                }
+            }
+        }
+
+        public static string FilterFileByPrefix(string srcPath, string filterName)
+        {
+            if (!Directory.Exists(srcPath))
+            {
+                return null;
+            }
+
+            foreach (var dir in Directory.GetDirectories(srcPath))
+            {
+                string fileName = Path.GetFileName(dir);
+                if (fileName.StartsWith(filterName))
+                {
+                    return Path.Combine(srcPath, Path.GetFileName(dir));
+                }
+            }
+
+            return null;
+        }
+
+        public static string FilterFileBySuffix(string srcPath, string suffix)
+        {
+            if (!Directory.Exists(srcPath))
+            {
+                return null;
+            }
+
+            foreach (var dir in Directory.GetDirectories(srcPath))
+            {
+                string fileName = Path.GetFileName(dir);
+                if (fileName.StartsWith(suffix))
+                {
+                    return Path.Combine(srcPath, Path.GetFileName(dir));
+                }
+            }
+
+            return null;
+        }
+
+        public static FileInfo RecursionFilterFile(string dir, string fileName)
+        {
+            List<FileInfo> fileInfoList = new List<FileInfo>();
+            Director(dir, fileInfoList);
+            foreach (FileInfo item in fileInfoList)
+            {
+                if (fileName.Equals(item.Name))
+                {
+                    return item;
+                }
+            }
+
+            return null;
+        }
+
+        public static void Director(string dir, List<FileInfo> list)
+        {
+            DirectoryInfo d = new DirectoryInfo(dir);
+            FileInfo[] files = d.GetFiles();
+            DirectoryInfo[] directs = d.GetDirectories();
+            foreach (FileInfo f in files)
+            {
+                list.Add(f);
+            }
+
+            foreach (DirectoryInfo dd in directs)
+            {
+                Director(dd.FullName, list);
+            }
+        }
+    }
+}

+ 3 - 0
Assets/TapSDK/Core/Editor/TapFileHelper.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: ba6aa94e0d93a4706a7d274735817de5
+timeCreated: 1617120740

+ 15 - 0
Assets/TapSDK/Core/Editor/TapSDK.Core.Editor.asmdef

@@ -0,0 +1,15 @@
+{
+    "name": "TapSDK.Core.Editor",
+    "references": [],
+    "includePlatforms": [
+        "Editor"
+    ],
+    "excludePlatforms": [],
+    "allowUnsafeCode": false,
+    "overrideReferences": false,
+    "precompiledReferences": [],
+    "autoReferenced": true,
+    "defineConstraints": [],
+    "versionDefines": [],
+    "noEngineReferences": false
+}

+ 7 - 0
Assets/TapSDK/Core/Editor/TapSDK.Core.Editor.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 56f3da7a178484843974054bafe77e73
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 493 - 0
Assets/TapSDK/Core/Editor/TapSDKCoreCompile.cs

@@ -0,0 +1,493 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using UnityEditor;
+using UnityEditor.PackageManager;
+using UnityEngine;
+using System.Diagnostics;
+using System.Text.RegularExpressions;
+
+
+
+#if UNITY_IOS
+using System;
+using Google;
+using UnityEditor.iOS.Xcode;
+
+#endif
+
+namespace TapSDK.Core.Editor
+{
+    public static class TapSDKCoreCompile
+    {
+#if UNITY_IOS
+        public static string GetProjPath(string path)
+        {
+            UnityEngine.Debug.Log($"SDX , GetProjPath path:{path}");
+            return PBXProject.GetPBXProjectPath(path);
+        }
+
+        public static PBXProject ParseProjPath(string path)
+        {
+            UnityEngine.Debug.Log($"SDX , ParseProjPath path:{path}");
+            var proj = new PBXProject();
+            proj.ReadFromString(File.ReadAllText(path));
+            return proj;
+        }
+
+        public static string GetUnityFrameworkTarget(PBXProject proj)
+        {
+#if UNITY_2019_3_OR_NEWER
+            UnityEngine.Debug.Log("SDX , GetUnityFrameworkTarget UNITY_2019_3_OR_NEWER");
+            string target = proj.GetUnityFrameworkTargetGuid();
+            return target;
+#endif
+            UnityEngine.Debug.Log("SDX , GetUnityFrameworkTarget");
+            var unityPhoneTarget = proj.TargetGuidByName("Unity-iPhone");
+            return unityPhoneTarget;
+        }
+
+        public static string GetUnityTarget(PBXProject proj)
+        {
+#if UNITY_2019_3_OR_NEWER
+            UnityEngine.Debug.Log("SDX , GetUnityTarget UNITY_2019_3_OR_NEWER");
+            string target = proj.GetUnityMainTargetGuid();
+            return target;
+#endif
+            UnityEngine.Debug.Log("SDX , GetUnityTarget");
+            var unityPhoneTarget = proj.TargetGuidByName("Unity-iPhone");
+            return unityPhoneTarget;
+        }
+
+
+        public static bool CheckTarget(string target)
+        {
+            return string.IsNullOrEmpty(target);
+        }
+
+        public static string GetUnityPackagePath(string parentFolder, string unityPackageName)
+        {
+            var request = Client.List(true);
+            while (request.IsCompleted == false)
+            {
+                System.Threading.Thread.Sleep(100);
+            }
+            var pkgs = request.Result;
+            if (pkgs == null)
+                return "";
+            foreach (var pkg in pkgs)
+            {
+                if (pkg.name == unityPackageName)
+                {
+                    if (pkg.source == PackageSource.Local)
+                        return pkg.resolvedPath;
+                    else if (pkg.source == PackageSource.Embedded)
+                        return pkg.resolvedPath;
+                    else
+                    {
+                        return pkg.resolvedPath;
+                    }
+                }
+            }
+
+            return "";
+        }
+
+        public static bool HandlerIOSSetting(string path, string appDataPath, string resourceName,
+            string modulePackageName,
+            string moduleName, string[] bundleNames, string target, string projPath, PBXProject proj, string podSpecName = "")
+        {
+
+            var resourcePath = Path.Combine(path, resourceName);
+
+            var parentFolder = Directory.GetParent(appDataPath).FullName;
+
+            UnityEngine.Debug.Log($"ProjectFolder path:{parentFolder}" + " resourcePath: " + resourcePath + " parentFolder: " + parentFolder);
+
+            if (Directory.Exists(resourcePath))
+            {
+                Directory.Delete(resourcePath, true);
+            }
+
+            var podSpecPath = Path.Combine(path + "/Pods", podSpecName);
+            //使用 cocospod 远程依赖
+            if (podSpecName != null && podSpecName.Length > 0 && Directory.Exists(podSpecPath))
+            {
+                resourcePath = Path.Combine(path + "/Pods", podSpecName + "/Frameworks");
+                UnityEngine.Debug.Log($"Find {moduleName} use pods resourcePath:{resourcePath}");
+            }
+            else
+            {
+                Directory.CreateDirectory(resourcePath);
+                var remotePackagePath = GetUnityPackagePath(parentFolder, modulePackageName);
+
+                var assetLocalPackagePath = TapFileHelper.FilterFileByPrefix(parentFolder + "/Assets/TapSDK/", moduleName);
+
+                var localPackagePath = TapFileHelper.FilterFileByPrefix(parentFolder, moduleName);
+
+                UnityEngine.Debug.Log($"Find {moduleName} path: remote = {remotePackagePath} asset = {assetLocalPackagePath} local = {localPackagePath}");
+                var tdsResourcePath = "";
+
+                if (!string.IsNullOrEmpty(remotePackagePath))
+                {
+                    tdsResourcePath = remotePackagePath;
+                }
+                else if (!string.IsNullOrEmpty(assetLocalPackagePath))
+                {
+                    tdsResourcePath = assetLocalPackagePath;
+                }
+                else if (!string.IsNullOrEmpty(localPackagePath))
+                {
+                    tdsResourcePath = localPackagePath;
+                }
+
+                if (string.IsNullOrEmpty(tdsResourcePath))
+                {
+                    throw new Exception(string.Format("Can't find tdsResourcePath with module of : {0}", modulePackageName));
+                }
+
+                tdsResourcePath = $"{tdsResourcePath}/Plugins/iOS/Resource";
+
+                UnityEngine.Debug.Log($"Find {moduleName} path:{tdsResourcePath}");
+
+                if (!Directory.Exists(tdsResourcePath))
+                {
+                    throw new Exception(string.Format("Can't Find {0}", tdsResourcePath));
+                }
+
+                TapFileHelper.CopyAndReplaceDirectory(tdsResourcePath, resourcePath);
+            }
+            foreach (var name in bundleNames)
+            {
+                var relativePath = GetRelativePath(Path.Combine(resourcePath, name), path);
+                if (!proj.ContainsFileByRealPath(relativePath))
+                {
+                    var fileGuid = proj.AddFile(relativePath, relativePath, PBXSourceTree.Source);
+                    proj.AddFileToBuild(target, fileGuid);
+                }
+            }
+
+            File.WriteAllText(projPath, proj.WriteToString());
+            return true;
+        }
+
+        private static string GetRelativePath(string absolutePath, string rootPath)
+        {
+            if (Directory.Exists(rootPath) && !rootPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
+            {
+                rootPath += Path.AltDirectorySeparatorChar;
+            }
+            Uri aboslutePathUri = new Uri(absolutePath);
+            Uri rootPathUri = new Uri(rootPath);
+            var relateivePath = rootPathUri.MakeRelativeUri(aboslutePathUri).ToString();
+            UnityEngine.Debug.LogFormat($"[TapSDKCoreCompile] GetRelativePath absolutePath:{absolutePath} rootPath:{rootPath} relateivePath:{relateivePath} ");
+            return relateivePath;
+        }
+
+        public static bool HandlerPlist(string pathToBuildProject, string infoPlistPath, bool macos = false)
+        {
+            // #if UNITY_2020_1_OR_NEWER
+            //             var macosXCodePlistPath =
+            //                 $"{pathToBuildProject}/{PlayerSettings.productName}/Info.plist";
+            // #elif UNITY_2019_1_OR_NEWER
+            //             var macosXCodePlistPath =
+            //                 $"{Path.GetDirectoryName(pathToBuildProject)}/{PlayerSettings.productName}/Info.plist";
+            // #endif
+
+            string plistPath;
+
+            if (pathToBuildProject.EndsWith(".app"))
+            {
+                plistPath = $"{pathToBuildProject}/Contents/Info.plist";
+            }
+            else
+            {
+                var macosXCodePlistPath =
+                    $"{Path.GetDirectoryName(pathToBuildProject)}/{PlayerSettings.productName}/Info.plist";
+                if (!File.Exists(macosXCodePlistPath))
+                {
+                    macosXCodePlistPath = $"{pathToBuildProject}/{PlayerSettings.productName}/Info.plist";
+                }
+
+                plistPath = !macos
+                    ? pathToBuildProject + "/Info.plist"
+                    : macosXCodePlistPath;
+            }
+
+            UnityEngine.Debug.Log($"plist path:{plistPath}");
+
+            var plist = new PlistDocument();
+            plist.ReadFromString(File.ReadAllText(plistPath));
+            var rootDic = plist.root;
+
+            var items = new List<string>
+            {
+                "tapsdk",
+                "tapiosdk",
+                "taptap"
+            };
+
+            if (!(rootDic["LSApplicationQueriesSchemes"] is PlistElementArray plistElementList))
+            {
+                plistElementList = rootDic.CreateArray("LSApplicationQueriesSchemes");
+            }
+
+            string listData = "";
+            foreach (var item in plistElementList.values)
+            {
+                if (item is PlistElementString)
+                {
+                    listData += item.AsString() + ";";
+                }
+            }
+            foreach (var t in items)
+            {
+                if (!listData.Contains(t + ";"))
+                {
+                    plistElementList.AddString(t);
+                }
+            }
+
+            if (string.IsNullOrEmpty(infoPlistPath)) return false;
+            var dic = (Dictionary<string, object>)Plist.readPlist(infoPlistPath);
+            var taptapId = "";
+
+            foreach (var item in dic)
+            {
+                if (item.Key.Equals("taptap"))
+                {
+                    var taptapDic = (Dictionary<string, object>)item.Value;
+                    foreach (var taptapItem in taptapDic.Where(taptapItem => taptapItem.Key.Equals("client_id")))
+                    {
+                        taptapId = (string)taptapItem.Value;
+                    }
+                }
+                else
+                {
+                    rootDic.SetString(item.Key, item.Value.ToString());
+                }
+            }
+
+            //添加url
+            var dict = plist.root.AsDict();
+            if (!(dict["CFBundleURLTypes"] is PlistElementArray array))
+            {
+                array = dict.CreateArray("CFBundleURLTypes");
+            }
+
+            if (!macos)
+            {
+                var dict2 = array.AddDict();
+                dict2.SetString("CFBundleURLName", "TapTap");
+                var array2 = dict2.CreateArray("CFBundleURLSchemes");
+                array2.AddString($"tt{taptapId}");
+            }
+            else
+            {
+                var dict2 = array.AddDict();
+                dict2.SetString("CFBundleURLName", "TapWeb");
+                var array2 = dict2.CreateArray("CFBundleURLSchemes");
+                array2.AddString($"open-taptap-{taptapId}");
+            }
+
+            UnityEngine.Debug.Log("TapSDK change plist Success");
+            File.WriteAllText(plistPath, plist.WriteToString());
+            return true;
+        }
+
+        public static string GetValueFromPlist(string infoPlistPath, string key)
+        {
+            if (infoPlistPath == null)
+            {
+                return null;
+            }
+
+            var dic = (Dictionary<string, object>)Plist.readPlist(infoPlistPath);
+            return (from item in dic where item.Key.Equals(key) select (string)item.Value).FirstOrDefault();
+        }
+
+        public static void ExecutePodCommand(string command, string workingDirectory)
+        {
+            string podPath = FindPodPath();
+            if (string.IsNullOrEmpty(podPath))
+            {
+                UnityEngine.Debug.LogError("[CocoaPods] search pod install path failed");
+                return;
+            }
+            UnityEngine.Debug.Log("[CocoaPods] search pod install path :" + podPath);
+            command = command.Replace("pod", podPath);
+            command = "export LANG=en_US.UTF-8 && " + command;
+            var process = new Process
+            {
+                StartInfo = new ProcessStartInfo
+                {
+                    FileName = "/bin/bash",
+                    Arguments = $"-c \"{command}\"",
+                    WorkingDirectory = workingDirectory,
+                    RedirectStandardOutput = true,
+                    RedirectStandardError = true,
+                    UseShellExecute = false,
+                    CreateNoWindow = true
+                }
+            };
+
+            process.Start();
+            process.WaitForExit();
+
+            string output = process.StandardOutput.ReadToEnd();
+            string error = process.StandardError.ReadToEnd();
+
+            if (!string.IsNullOrEmpty(output))
+                UnityEngine.Debug.Log($"[CocoaPods] Output: {output}");
+
+            if (!string.IsNullOrEmpty(error))
+                UnityEngine.Debug.LogError($"[CocoaPods] Error: {error}");
+
+            if (process.ExitCode == 0)
+                UnityEngine.Debug.Log($"[CocoaPods] Success: {command}");
+            else
+                UnityEngine.Debug.LogError($"[CocoaPods] Failed: {command} (Exit code: {process.ExitCode})");
+        }
+
+        private static string FindPodPath()
+        {
+            string whichResult = RunBashCommand("-l -c \"which pod\"");
+            whichResult = whichResult.Replace("\n", "");
+            if (!string.IsNullOrEmpty(whichResult) && File.Exists(whichResult))
+            {
+                UnityEngine.Debug.Log($"[PodFinder] Found pod at which result: {whichResult}");
+                return whichResult;
+            }
+
+            string[] CommonPaths = new string[]
+            {
+                "/usr/local/bin",
+                "/usr/bin",
+                "/opt/homebrew/bin"
+            };
+            // 1. 先在常见路径查找 pod
+            foreach (var path in CommonPaths)
+            {
+                string podPath = Path.Combine(path, "pod");
+                if (File.Exists(podPath))
+                {
+                    UnityEngine.Debug.Log($"[PodFinder] Found pod at common path: {podPath}");
+                    return podPath;
+                }
+            }
+            // 2. 如果没找到,执行 gem environment 查找
+            string gemEnvOutput = RunBashCommand("-l -c \"gem environment\"");
+
+            if (string.IsNullOrEmpty(gemEnvOutput))
+            {
+                UnityEngine.Debug.LogWarning("[PodFinder] gem environment output is empty.");
+                return null;
+            }
+
+            // 3. 解析 EXECUTABLE DIRECTORY
+            string execDir = ParseGemEnvironment(gemEnvOutput, @"EXECUTABLE DIRECTORY:\s*(.+)");
+            if (!string.IsNullOrEmpty(execDir))
+            {
+                string podPath = Path.Combine(execDir.Trim(), "pod");
+                if (File.Exists(podPath))
+                {
+                    UnityEngine.Debug.Log($"[PodFinder] Found pod via EXECUTABLE DIRECTORY: {podPath}");
+                    return podPath;
+                }
+            }
+
+            // 4. 解析 GEM PATHS,尝试从每个路径下的 bin 文件夹查找 pod
+            var gemPaths = ParseGemEnvironmentMultiple(gemEnvOutput, @"GEM PATHS:\s*((?:- .+\n)+)");
+            if (gemPaths != null)
+            {
+                foreach (var gemPath in gemPaths)
+                {
+                    // 一般 pod 会在 bin 文件夹或同级目录中
+                    string podPath1 = Path.Combine(gemPath.Trim(), "bin", "pod");
+                    string podPath2 = Path.Combine(gemPath.Trim(), "pod"); // 备选路径
+
+                    if (File.Exists(podPath1))
+                    {
+                        UnityEngine.Debug.Log($"[PodFinder] Found pod via GEM PATHS (bin): {podPath1}");
+                        return podPath1;
+                    }
+
+                    if (File.Exists(podPath2))
+                    {
+                        UnityEngine.Debug.Log($"[PodFinder] Found pod via GEM PATHS: {podPath2}");
+                        return podPath2;
+                    }
+                }
+            }
+
+            UnityEngine.Debug.LogWarning("[PodFinder] pod executable not found.");
+            return null;
+        }
+    
+        private static string RunBashCommand(string arguments)
+        {
+            try
+            {
+                using (var process = new Process())
+                {
+                    process.StartInfo.FileName = "/bin/bash";
+                    process.StartInfo.Arguments = arguments;
+                    process.StartInfo.RedirectStandardOutput = true;
+                    process.StartInfo.RedirectStandardError = true;
+                    process.StartInfo.UseShellExecute = false;
+                    process.StartInfo.CreateNoWindow = true;
+
+                    process.Start();
+                    string output = process.StandardOutput.ReadToEnd();
+                    string err = process.StandardError.ReadToEnd();
+                    process.WaitForExit();
+
+                    if (!string.IsNullOrEmpty(err))
+                    {
+                        UnityEngine.Debug.LogWarning($"[PodFinder] bash error: {err}");
+                    }
+
+                    return output;
+                }
+            }
+            catch (Exception e)
+            {
+                UnityEngine.Debug.LogError($"[PodFinder] Exception running bash command: {e}");
+                return null;
+            }
+        }
+
+        private static string ParseGemEnvironment(string input, string pattern)
+        {
+            var match = Regex.Match(input, pattern);
+            if (match.Success && match.Groups.Count > 1)
+            {
+                return match.Groups[1].Value.Trim();
+            }
+            return null;
+        }
+
+        private static string[] ParseGemEnvironmentMultiple(string input, string pattern)
+        {
+            var match = Regex.Match(input, pattern, RegexOptions.Multiline);
+            if (!match.Success || match.Groups.Count < 2) return null;
+
+            string block = match.Groups[1].Value;
+
+            // 每行格式是类似 "- /path/to/gem"
+            var lines = block.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
+            var paths = new System.Collections.Generic.List<string>();
+            foreach (var line in lines)
+            {
+                string trimmed = line.Trim();
+                if (trimmed.StartsWith("- "))
+                {
+                    paths.Add(trimmed.Substring(2).Trim());
+                }
+            }
+
+            return paths.ToArray();
+        }
+#endif
+    }
+}

+ 3 - 0
Assets/TapSDK/Core/Editor/TapSDKCoreCompile.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: ec6f5ced361da4c9ba6c09d4e2dba5fd
+timeCreated: 1617120740

+ 102 - 0
Assets/TapSDK/Core/Editor/TapSDKCoreIOSProcessor.cs

@@ -0,0 +1,102 @@
+using System.IO;
+using System.Linq;
+using UnityEditor;
+# if UNITY_IOS
+using UnityEditor.Callbacks;
+using UnityEditor.iOS.Xcode;
+#endif
+using UnityEngine;
+
+namespace TapSDK.Core.Editor
+{
+# if UNITY_IOS
+    public static class TapCommonIOSProcessor
+    {
+        // 添加标签,unity导出工程后自动执行该函数
+        [PostProcessBuild(99)]
+        public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
+        {
+            if (buildTarget != BuildTarget.iOS) return;
+
+            // 获得工程路径
+            var projPath = TapSDKCoreCompile.GetProjPath(path);
+            var proj = TapSDKCoreCompile.ParseProjPath(projPath);
+            var target = TapSDKCoreCompile.GetUnityTarget(proj);
+            var unityFrameworkTarget = TapSDKCoreCompile.GetUnityFrameworkTarget(proj);
+
+            if (TapSDKCoreCompile.CheckTarget(target))
+            {
+                Debug.LogError("Unity-iPhone is NUll");
+                return;
+            }
+
+            // proj.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC");
+            // proj.AddBuildProperty(unityFrameworkTarget, "OTHER_LDFLAGS", "-ObjC");
+
+            proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
+            // proj.SetBuildProperty(target, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
+            proj.SetBuildProperty(target, "SWIFT_VERSION", "5.0");
+            proj.SetBuildProperty(target, "CLANG_ENABLE_MODULES", "YES");
+
+            proj.SetBuildProperty(unityFrameworkTarget, "ENABLE_BITCODE", "NO");
+            // proj.SetBuildProperty(unityFrameworkTarget, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
+            proj.SetBuildProperty(unityFrameworkTarget, "BUILD_LIBRARY_FOR_DISTRIBUTION", "YES");
+
+            proj.SetBuildProperty(unityFrameworkTarget, "SWIFT_VERSION", "5.0");
+            proj.SetBuildProperty(unityFrameworkTarget, "CLANG_ENABLE_MODULES", "YES");
+
+            proj.AddFrameworkToProject(unityFrameworkTarget, "MobileCoreServices.framework", false);
+            proj.AddFrameworkToProject(unityFrameworkTarget, "WebKit.framework", false);
+            proj.AddFrameworkToProject(unityFrameworkTarget, "Security.framework", false);
+            proj.AddFrameworkToProject(unityFrameworkTarget, "SystemConfiguration.framework", false);
+            proj.AddFrameworkToProject(unityFrameworkTarget, "CoreTelephony.framework", false);
+            proj.AddFrameworkToProject(unityFrameworkTarget, "SystemConfiguration.framework", false);
+
+            proj.AddFileToBuild(unityFrameworkTarget,
+                proj.AddFile("usr/lib/libc++.tbd", "libc++.tbd", PBXSourceTree.Sdk));
+
+            proj.AddFileToBuild(unityFrameworkTarget,
+                proj.AddFile("usr/lib/libsqlite3.tbd", "libsqlite3.tbd", PBXSourceTree.Sdk));
+
+            proj.WriteToFile(projPath);
+            // PodFile 使用动态库
+            string podfilePath = Path.Combine(path, "Podfile");
+            if (!File.Exists(podfilePath))
+            {
+                Debug.LogWarning("Podfile not found.");
+                return;
+            }
+
+            string podfileContent = File.ReadAllText(podfilePath);
+
+            // // 替换 use_frameworks! 的设置(默认是 static)
+            // if (podfileContent.Contains("use_frameworks! :linkage => :static"))
+            // {
+            //     podfileContent = podfileContent.Replace("use_frameworks! :linkage => :static", "use_frameworks! :linkage => :dynamic");
+            // }
+            // else if (!podfileContent.Contains("use_frameworks!"))
+            // {
+            //     // 插入 use_frameworks! 如果没有
+            //     podfileContent = podfileContent.Replace("platform :ios, '13.0'", "platform :ios, '13.0'\nuse_frameworks!");
+            // }
+            podfileContent += "\ninstall! 'cocoapods', :warn_for_unused_master_specs_repo => false";
+
+            File.WriteAllText(podfilePath, podfileContent);
+            Debug.Log("Podfile modified to use dynamic frameworks.");
+            // if (TapSDKCoreCompile.HandlerIOSSetting(path,
+            //     Application.dataPath,
+            //     "TapCommonResource",
+            //     "com.taptap.sdk.core",
+            //     "TapSDKCore",
+            //     new[] {"TapCommonResource.bundle"},
+            //     target, projPath, proj))
+            // {
+            //     Debug.Log("TapCommon add Bundle Success!");
+            //     return;
+            // }
+
+            // Debug.LogError("TapCommon add Bundle Failed!");
+        }
+    }
+#endif
+}

+ 3 - 0
Assets/TapSDK/Core/Editor/TapSDKCoreIOSProcessor.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: b61d97b2d6da94511a1e92afb1519d42
+timeCreated: 1617120740

+ 9 - 0
Assets/TapSDK/Core/Editor/UI.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6301720de19974c94b52839ed842dc3f
+folderAsset: yes
+timeCreated: 1533042733
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 267 - 0
Assets/TapSDK/Core/Editor/UI/ScrollViewEditor.cs

@@ -0,0 +1,267 @@
+// -----------------------------------------------------------------------
+// <copyright file="ScrollViewEditor.cs" company="AillieoTech">
+// Copyright (c) AillieoTech. All rights reserved.
+// </copyright>
+// -----------------------------------------------------------------------
+
+namespace TapSDK.UI.AillieoTech
+{
+    using System;
+    using System.Linq;
+    using System.Reflection;
+    using UnityEditor;
+    using UnityEditor.UI;
+    using UnityEngine;
+    using UnityEngine.UI;
+
+    [CustomEditor(typeof(ScrollView))]
+    public class ScrollViewEditor : ScrollRectEditor
+    {
+        private const string bgPath = "UI/Skin/Background.psd";
+        private const string spritePath = "UI/Skin/UISprite.psd";
+        private const string maskPath = "UI/Skin/UIMask.psd";
+        private static Color panelColor = new Color(1f, 1f, 1f, 0.392f);
+        private static Color defaultSelectableColor = new Color(1f, 1f, 1f, 1f);
+        private static Vector2 thinElementSize = new Vector2(160f, 20f);
+        private static Action<GameObject, MenuCommand> PlaceUIElementRoot;
+
+        private SerializedProperty itemTemplate;
+        private SerializedProperty poolSize;
+        private SerializedProperty defaultItemSize;
+        private SerializedProperty layoutType;
+
+        private GUIStyle cachedCaption;
+
+        private GUIStyle caption
+        {
+            get
+            {
+                if (this.cachedCaption == null)
+                {
+                    this.cachedCaption = new GUIStyle { richText = true, alignment = TextAnchor.MiddleCenter };
+                }
+
+                return this.cachedCaption;
+            }
+        }
+
+        public override void OnInspectorGUI()
+        {
+            this.serializedObject.Update();
+
+            EditorGUILayout.BeginVertical("box");
+            EditorGUILayout.LabelField("<b>Additional configs</b>", this.caption);
+            EditorGUILayout.Space();
+            this.DrawConfigInfo();
+            this.serializedObject.ApplyModifiedProperties();
+            EditorGUILayout.EndVertical();
+
+            EditorGUILayout.BeginVertical("box");
+            EditorGUILayout.LabelField("<b>For original ScrollRect</b>", this.caption);
+            EditorGUILayout.Space();
+            base.OnInspectorGUI();
+            EditorGUILayout.EndVertical();
+        }
+
+        protected static void InternalAddScrollView<T>(MenuCommand menuCommand)
+            where T : ScrollView
+        {
+            GetPrivateMethodByReflection();
+
+            GameObject root = CreateUIElementRoot(typeof(T).Name, new Vector2(200, 200));
+            PlaceUIElementRoot?.Invoke(root, menuCommand);
+
+            GameObject viewport = CreateUIObject("Viewport", root);
+            GameObject content = CreateUIObject("Content", viewport);
+
+            var parent = menuCommand.context as GameObject;
+            if (parent != null)
+            {
+                root.transform.SetParent(parent.transform, false);
+            }
+
+            Selection.activeGameObject = root;
+
+            GameObject hScrollbar = CreateScrollbar();
+            hScrollbar.name = "Scrollbar Horizontal";
+            hScrollbar.transform.SetParent(root.transform, false);
+            RectTransform hScrollbarRT = hScrollbar.GetComponent<RectTransform>();
+            hScrollbarRT.anchorMin = Vector2.zero;
+            hScrollbarRT.anchorMax = Vector2.right;
+            hScrollbarRT.pivot = Vector2.zero;
+            hScrollbarRT.sizeDelta = new Vector2(0, hScrollbarRT.sizeDelta.y);
+
+            GameObject vScrollbar = CreateScrollbar();
+            vScrollbar.name = "Scrollbar Vertical";
+            vScrollbar.transform.SetParent(root.transform, false);
+            vScrollbar.GetComponent<Scrollbar>().SetDirection(Scrollbar.Direction.BottomToTop, true);
+            RectTransform vScrollbarRT = vScrollbar.GetComponent<RectTransform>();
+            vScrollbarRT.anchorMin = Vector2.right;
+            vScrollbarRT.anchorMax = Vector2.one;
+            vScrollbarRT.pivot = Vector2.one;
+            vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0);
+
+            RectTransform viewportRect = viewport.GetComponent<RectTransform>();
+            viewportRect.anchorMin = Vector2.zero;
+            viewportRect.anchorMax = Vector2.one;
+            viewportRect.sizeDelta = Vector2.zero;
+            viewportRect.pivot = Vector2.up;
+
+            RectTransform contentRect = content.GetComponent<RectTransform>();
+            contentRect.anchorMin = Vector2.up;
+            contentRect.anchorMax = Vector2.one;
+            contentRect.sizeDelta = new Vector2(0, 300);
+            contentRect.pivot = Vector2.up;
+
+            ScrollView scrollRect = root.AddComponent<T>();
+            scrollRect.content = contentRect;
+            scrollRect.viewport = viewportRect;
+            scrollRect.horizontalScrollbar = hScrollbar.GetComponent<Scrollbar>();
+            scrollRect.verticalScrollbar = vScrollbar.GetComponent<Scrollbar>();
+            scrollRect.horizontalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
+            scrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
+            scrollRect.horizontalScrollbarSpacing = -3;
+            scrollRect.verticalScrollbarSpacing = -3;
+
+            Image rootImage = root.AddComponent<Image>();
+            rootImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(bgPath);
+            rootImage.type = Image.Type.Sliced;
+            rootImage.color = panelColor;
+
+            Mask viewportMask = viewport.AddComponent<Mask>();
+            viewportMask.showMaskGraphic = false;
+
+            Image viewportImage = viewport.AddComponent<Image>();
+            viewportImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(maskPath);
+            viewportImage.type = Image.Type.Sliced;
+        }
+
+        protected override void OnEnable()
+        {
+            base.OnEnable();
+
+            this.itemTemplate = this.serializedObject.FindProperty("itemTemplate");
+            this.poolSize = this.serializedObject.FindProperty("poolSize");
+            this.defaultItemSize = this.serializedObject.FindProperty("defaultItemSize");
+            this.layoutType = this.serializedObject.FindProperty("layoutType");
+        }
+
+        protected virtual void DrawConfigInfo()
+        {
+            EditorGUILayout.PropertyField(this.itemTemplate);
+            EditorGUILayout.PropertyField(this.poolSize);
+            EditorGUILayout.PropertyField(this.defaultItemSize);
+            this.layoutType.intValue = (int)(ScrollView.ItemLayoutType)EditorGUILayout.EnumPopup("layoutType", (ScrollView.ItemLayoutType)this.layoutType.intValue);
+        }
+
+        [MenuItem("GameObject/UI/DynamicScrollView", false, 90)]
+        private static void AddScrollView(MenuCommand menuCommand)
+        {
+            InternalAddScrollView<ScrollView>(menuCommand);
+        }
+
+        private static GameObject CreateScrollbar()
+        {
+            // Create GOs Hierarchy
+            GameObject scrollbarRoot = CreateUIElementRoot("Scrollbar", thinElementSize);
+            GameObject sliderArea = CreateUIObject("Sliding Area", scrollbarRoot);
+            GameObject handle = CreateUIObject("Handle", sliderArea);
+
+            Image bgImage = scrollbarRoot.AddComponent<Image>();
+            bgImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(bgPath);
+            bgImage.type = Image.Type.Sliced;
+            bgImage.color = defaultSelectableColor;
+
+            Image handleImage = handle.AddComponent<Image>();
+            handleImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(spritePath);
+            handleImage.type = Image.Type.Sliced;
+            handleImage.color = defaultSelectableColor;
+
+            RectTransform sliderAreaRect = sliderArea.GetComponent<RectTransform>();
+            sliderAreaRect.sizeDelta = new Vector2(-20, -20);
+            sliderAreaRect.anchorMin = Vector2.zero;
+            sliderAreaRect.anchorMax = Vector2.one;
+
+            RectTransform handleRect = handle.GetComponent<RectTransform>();
+            handleRect.sizeDelta = new Vector2(20, 20);
+
+            Scrollbar scrollbar = scrollbarRoot.AddComponent<Scrollbar>();
+            scrollbar.handleRect = handleRect;
+            scrollbar.targetGraphic = handleImage;
+            SetDefaultColorTransitionValues(scrollbar);
+
+            return scrollbarRoot;
+        }
+
+        private static GameObject CreateUIElementRoot(string name, Vector2 size)
+        {
+            var child = new GameObject(name);
+            RectTransform rectTransform = child.AddComponent<RectTransform>();
+            rectTransform.sizeDelta = size;
+            return child;
+        }
+
+        private static GameObject CreateUIObject(string name, GameObject parent)
+        {
+            var go = new GameObject(name);
+            go.AddComponent<RectTransform>();
+            SetParentAndAlign(go, parent);
+            return go;
+        }
+
+        private static void SetParentAndAlign(GameObject child, GameObject parent)
+        {
+            if (parent == null)
+            {
+                return;
+            }
+
+            child.transform.SetParent(parent.transform, false);
+            SetLayerRecursively(child, parent.layer);
+        }
+
+        private static void SetLayerRecursively(GameObject go, int layer)
+        {
+            go.layer = layer;
+            Transform t = go.transform;
+            for (var i = 0; i < t.childCount; i++)
+            {
+                SetLayerRecursively(t.GetChild(i).gameObject, layer);
+            }
+        }
+
+        private static void SetDefaultColorTransitionValues(Selectable slider)
+        {
+            ColorBlock colors = slider.colors;
+            colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f);
+            colors.pressedColor = new Color(0.698f, 0.698f, 0.698f);
+            colors.disabledColor = new Color(0.521f, 0.521f, 0.521f);
+        }
+
+        private static void GetPrivateMethodByReflection()
+        {
+            if (PlaceUIElementRoot == null)
+            {
+                Assembly uiEditorAssembly = AppDomain.CurrentDomain.GetAssemblies()
+                    .FirstOrDefault(asm => asm.GetName().Name == "UnityEditor.UI");
+                if (uiEditorAssembly != null)
+                {
+                    Type menuOptionType = uiEditorAssembly.GetType("UnityEditor.UI.MenuOptions");
+                    if (menuOptionType != null)
+                    {
+                        MethodInfo miPlaceUIElementRoot = menuOptionType.GetMethod(
+                            "PlaceUIElementRoot",
+                            BindingFlags.NonPublic | BindingFlags.Static);
+                        if (miPlaceUIElementRoot != null)
+                        {
+                            PlaceUIElementRoot = Delegate.CreateDelegate(
+                                    typeof(Action<GameObject, MenuCommand>),
+                                    miPlaceUIElementRoot)
+                                as Action<GameObject, MenuCommand>;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 12 - 0
Assets/TapSDK/Core/Editor/UI/ScrollViewEditor.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c20879c71b49a4b32b4170efe40af02c
+timeCreated: 1533042733
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 34 - 0
Assets/TapSDK/Core/Editor/UI/ScrollViewExEditor.cs

@@ -0,0 +1,34 @@
+// -----------------------------------------------------------------------
+// <copyright file="ScrollViewExEditor.cs" company="AillieoTech">
+// Copyright (c) AillieoTech. All rights reserved.
+// </copyright>
+// -----------------------------------------------------------------------
+
+namespace TapSDK.UI.AillieoTech
+{
+    using UnityEditor;
+
+    [CustomEditor(typeof(ScrollViewEx))]
+    public class ScrollViewExEditor : ScrollViewEditor
+    {
+        private SerializedProperty pageSize;
+
+        protected override void OnEnable()
+        {
+            base.OnEnable();
+            this.pageSize = this.serializedObject.FindProperty("pageSize");
+        }
+
+        protected override void DrawConfigInfo()
+        {
+            base.DrawConfigInfo();
+            EditorGUILayout.PropertyField(this.pageSize);
+        }
+
+        [MenuItem("GameObject/UI/DynamicScrollViewEx", false, 90)]
+        private static void AddScrollViewEx(MenuCommand menuCommand)
+        {
+            InternalAddScrollView<ScrollViewEx>(menuCommand);
+        }
+    }
+}

+ 12 - 0
Assets/TapSDK/Core/Editor/UI/ScrollViewExEditor.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0d7c4e920d9c4441a83c3d500596fb75
+timeCreated: 1533042733
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 17 - 0
Assets/TapSDK/Core/Editor/UI/TapSDK.UI.Editor.asmdef

@@ -0,0 +1,17 @@
+{
+    "name": "TapSDK.UI.Editor",
+    "references": [
+        "GUID:7d5ef2062f3704e1ab74aac0e4d5a1a7"
+    ],
+    "includePlatforms": [
+        "Editor"
+    ],
+    "excludePlatforms": [],
+    "allowUnsafeCode": false,
+    "overrideReferences": false,
+    "precompiledReferences": [],
+    "autoReferenced": true,
+    "defineConstraints": [],
+    "versionDefines": [],
+    "noEngineReferences": false
+}

+ 7 - 0
Assets/TapSDK/Core/Editor/UI/TapSDK.UI.Editor.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: d9925423e828d479c9063ea882f31e06
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/TapSDK/Core/Mobile.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6838d5bad18c0416688fd347e4b283d9
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/TapSDK/Core/Mobile/Editor.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 17753ed93cd314b168087b8f75b02b00
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
Assets/TapSDK/Core/Mobile/Editor/NativeDependencies.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<dependencies>
+  <androidPackages>
+    <repositories>
+      <repository>https://repo.maven.apache.org/maven2</repository>
+    </repositories>
+    <androidPackage spec="com.taptap.sdk:tap-core-unity:4.8.2"/>
+  </androidPackages>
+  <iosPods>
+    <sources>
+      <source>https://github.com/CocoaPods/Specs.git</source>
+    </sources>
+    <iosPod addToAllTargets="false" bitcodeEnabled="false" name="TapTapCoreSDK" version="4.8.2"/>
+  </iosPods>
+</dependencies>

+ 7 - 0
Assets/TapSDK/Core/Mobile/Editor/NativeDependencies.xml.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: b969d6e811d804faca9742abe7c51db0
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 20 - 0
Assets/TapSDK/Core/Mobile/Editor/TapCommonMobileProcessBuild.cs

@@ -0,0 +1,20 @@
+using System;
+using UnityEditor.Build.Reporting;
+using TapSDK.Core.Editor;
+
+namespace TapSDK.Core.Mobile.Editor {
+    public class TapCommonMobileProcessBuild : SDKLinkProcessBuild {
+        public override int callbackOrder => 0;
+
+        public override string LinkPath => "TapSDK/Core/link.xml";
+
+        public override LinkedAssembly[] LinkedAssemblies => new LinkedAssembly[] {
+                    new LinkedAssembly { Fullname = "TapSDK.Core.Runtime" },
+                    new LinkedAssembly { Fullname = "TapSDK.Core.Mobile.Runtime" }
+                };
+
+        public override Func<BuildReport, bool> IsTargetPlatform => (report) => {
+            return BuildTargetUtils.IsSupportMobile(report.summary.platform);
+        };
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Editor/TapCommonMobileProcessBuild.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e8e298a37fded43bb96e28c921c396d5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 17 - 0
Assets/TapSDK/Core/Mobile/Editor/TapSDK.Core.Mobile.Editor.asmdef

@@ -0,0 +1,17 @@
+{
+    "name": "TapSDK.Core.Mobile.Editor",
+    "references": [
+        "GUID:56f3da7a178484843974054bafe77e73"
+    ],
+    "includePlatforms": [
+        "Editor"
+    ],
+    "excludePlatforms": [],
+    "allowUnsafeCode": false,
+    "overrideReferences": false,
+    "precompiledReferences": [],
+    "autoReferenced": true,
+    "defineConstraints": [],
+    "versionDefines": [],
+    "noEngineReferences": false
+}

+ 7 - 0
Assets/TapSDK/Core/Mobile/Editor/TapSDK.Core.Mobile.Editor.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 4f379049292174fb88b6a19b4c7fc83b
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/TapSDK/Core/Mobile/Runtime.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 401790f14411442e6b4d30acc9ec31c6
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 51 - 0
Assets/TapSDK/Core/Mobile/Runtime/AndroidNativeWrapper.cs

@@ -0,0 +1,51 @@
+using System;
+using System.Runtime.InteropServices;
+using UnityEngine;
+using System.Collections;
+using TapSDK.Core;
+using TapSDK.Core.Internal;
+using System.Collections.Generic;
+using TapSDK.Core.Internal.Log;
+
+namespace TapSDK.Core.Mobile{
+    internal class AndroidNativeWrapper
+    {
+        private static AndroidJavaClass tapTapEventClass;
+        
+        public static void RegisterDynamicProperties(Func<string> callback)
+        {
+            tapTapEventClass = new AndroidJavaClass("com.taptap.sdk.core.TapTapEvent");
+            AndroidJavaProxy dynamicPropertiesProxy = new TapEventDynamicPropertiesProxy(callback);
+            tapTapEventClass.CallStatic("registerDynamicProperties", dynamicPropertiesProxy);
+        }
+
+        private class TapEventDynamicPropertiesProxy : AndroidJavaProxy
+        {
+            private Func<string> callback;
+
+            public TapEventDynamicPropertiesProxy(Func<string> callback)
+                : base("com.taptap.sdk.core.TapTapEvent$TapEventDynamicProperties")
+            {
+                this.callback = callback;
+            }
+
+            public AndroidJavaObject getDynamicProperties()
+            {
+                try
+                {
+                    string json = callback();
+                    if (!string.IsNullOrEmpty(json))
+                    {
+                        return new AndroidJavaObject("org.json.JSONObject", json);
+                    }
+                }
+                catch (Exception e)
+                {
+                    TapLog.Error("Failed to get dynamic properties: " + e.Message);
+                }
+                return null;
+            }
+        }
+
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/AndroidNativeWrapper.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: da60c9deeb9b14586a7e4a0eec603fbb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 84 - 0
Assets/TapSDK/Core/Mobile/Runtime/Bridge.cs

@@ -0,0 +1,84 @@
+using System;
+using System.Threading.Tasks;
+
+namespace TapSDK.Core
+{
+    public class EngineBridge
+    {
+        private static volatile EngineBridge _sInstance;
+
+        private readonly IBridge _bridge;
+
+        private static readonly object Locker = new object();
+
+        public static EngineBridge GetInstance()
+        {
+            lock (Locker)
+            {
+                if (_sInstance == null)
+                {
+                    _sInstance = new EngineBridge();
+                }
+            }
+
+            return _sInstance;
+        }
+
+        private EngineBridge()
+        {
+            if (Platform.IsAndroid())
+            {
+                _bridge = BridgeAndroid.GetInstance();
+            }
+            else if (Platform.IsIOS())
+            {
+                _bridge = BridgeIOS.GetInstance();
+            }
+        }
+
+        public void Register(string serviceClzName, string serviceImplName)
+        {
+            _bridge?.Register(serviceClzName, serviceImplName);
+        }
+
+        public void CallHandler(Command command)
+        {
+            _bridge?.Call(command);
+        }
+
+        public string CallWithReturnValue(Command command, Action<Result> action = null)
+        {
+            return _bridge?.CallWithReturnValue(command, action);
+        }
+
+        public void CallHandler(Command command, Action<Result> action)
+        {
+            _bridge?.Call(command, action);
+        }
+
+        public Task<Result> Emit(Command command)
+        {
+            var tcs = new TaskCompletionSource<Result>();
+            CallHandler(command, result =>
+            {
+                tcs.TrySetResult(result);
+            });
+            return tcs.Task;
+        }
+
+        public static bool CheckResult(Result result)
+        {
+            if (result == null)
+            {
+                return false;
+            }
+
+            if (result.code != Result.RESULT_SUCCESS)
+            {
+                return false;
+            }
+
+            return !string.IsNullOrEmpty(result.content);
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/Bridge.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 168155d160dc0448bb9f57e609c284af
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 74 - 0
Assets/TapSDK/Core/Mobile/Runtime/BridgeAndroid.cs

@@ -0,0 +1,74 @@
+using System;
+using UnityEngine;
+using TapSDK.Core.Internal.Log;
+
+namespace TapSDK.Core
+{
+    public class BridgeAndroid : IBridge
+    {
+        private string bridgeJavaClz = "com.taptap.sdk.kit.internal.enginebridge.EngineBridge";
+
+        private string instanceField = "INSTANCE";
+
+        private string registerHandlerMethod = "registerHandler";
+
+        private string callHandlerMethod = "execCommand";
+
+        private string callHandlerAsyncMethod = "execCommandAsync";
+
+        private string initMethod = "init";
+
+        private string registerMethod = "registerService";
+
+        private readonly AndroidJavaObject _mAndroidBridge;
+
+        private static readonly BridgeAndroid SInstance = new BridgeAndroid();
+
+        public static BridgeAndroid GetInstance()
+        {
+            return SInstance;
+        }
+
+        private BridgeAndroid()
+        {
+            var mCurrentActivity =
+                new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
+            _mAndroidBridge = new AndroidJavaClass(bridgeJavaClz).GetStatic<AndroidJavaObject>(instanceField);
+            _mAndroidBridge.Call(initMethod, mCurrentActivity);
+        }
+
+        public void Register(string serviceClzName, string serviceImplName)
+        {
+            if (_mAndroidBridge == null)
+            {
+                return;
+            }
+
+            try
+            {
+                var serviceClass = new AndroidJavaClass(serviceClzName);
+                var serviceImpl = new AndroidJavaObject(serviceImplName);
+                _mAndroidBridge.Call(registerMethod, serviceClass, serviceImpl);
+            }
+            catch (Exception e)
+            {
+                TapLog.Log("register Failed:" + e);
+                //
+            }
+        }
+
+        public void Call(Command command, Action<Result> action)
+        {
+            _mAndroidBridge?.Call(callHandlerMethod, command.ToJSON(), new BridgeCallback(action));
+        }
+
+        public void Call(Command command)
+        {
+            _mAndroidBridge?.Call(callHandlerMethod, command.ToJSON(), null);
+        }
+        public string CallWithReturnValue(Command command, Action<Result> action)
+        {
+            return _mAndroidBridge?.Call<string>(callHandlerAsyncMethod, command.ToJSON());
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/BridgeAndroid.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8f691a68724f14b63b7c60ac2f967488
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 35 - 0
Assets/TapSDK/Core/Mobile/Runtime/BridgeCallback.cs

@@ -0,0 +1,35 @@
+using System;
+using UnityEngine;
+using System.Threading;
+using TapSDK.Core.Internal.Utils;
+
+namespace TapSDK.Core
+{
+
+    public class BridgeCallback : AndroidJavaProxy
+    {
+        Action<Result> callback;
+
+        public BridgeCallback(Action<Result> action) :
+            base(new AndroidJavaClass("com.taptap.sdk.kit.internal.enginebridge.EngineBridgeCallback"))
+        {
+            this.callback = action;
+        }
+
+        public override AndroidJavaObject Invoke(string method, object[] args)
+        {
+            if (method.Equals("onResult"))
+            {
+                if (args[0] is string)
+                {
+                    string result = (string)(args[0]);
+                    TapLoom.QueueOnMainThread(() =>
+                    {
+                        callback(new Result(result));
+                    });
+                }
+            }
+            return null;
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/BridgeCallback.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b5ce170f9f3e64033909f7513e067032
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 112 - 0
Assets/TapSDK/Core/Mobile/Runtime/BridgeIOS.cs

@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Concurrent;
+using System.Runtime.InteropServices;
+using UnityEngine;
+using TapSDK.Core.Internal.Log;
+
+namespace TapSDK.Core
+{
+    public class BridgeIOS : IBridge
+    {
+        private static readonly BridgeIOS SInstance = new BridgeIOS();
+
+        private readonly ConcurrentDictionary<string, Action<Result>> dic;
+
+        public static BridgeIOS GetInstance()
+        {
+            return SInstance;
+        }
+
+        private BridgeIOS()
+        {
+            dic = new ConcurrentDictionary<string, Action<Result>>();
+        }
+
+        private ConcurrentDictionary<string, Action<Result>> GetConcurrentDictionary()
+        {
+            return dic;
+        }
+
+        private delegate void EngineBridgeDelegate(string result);
+
+        [AOT.MonoPInvokeCallbackAttribute(typeof(EngineBridgeDelegate))]
+        static void engineBridgeDelegate(string resultJson)
+        {
+            var result = new Result(resultJson);
+
+            var actionDic = GetInstance().GetConcurrentDictionary();
+
+            Action<Result> action = null;
+
+            if (actionDic != null && actionDic.ContainsKey(result.callbackId))
+            {
+                action = actionDic[result.callbackId];
+            }
+
+            if (action != null)
+            {
+                action(result);
+                if (result.onceTime && BridgeIOS.GetInstance().GetConcurrentDictionary()
+                    .TryRemove(result.callbackId, out Action<Result> outAction))
+                {
+                    TapLog.Log($"TapSDK resolved current Action:{result.callbackId}");
+                }
+            }
+        }
+        
+        
+
+        public void Register(string serviceClz, string serviceImp)
+        {
+            //IOS无需注册
+        }
+
+        public void Call(Command command)
+        {
+#if UNITY_IOS
+            callHandler(command.ToJSON());
+#endif
+        }
+
+        public void Call(Command command, Action<Result> action)
+        {
+            if (!command.withCallback || string.IsNullOrEmpty(command.callbackId)) return;
+            if (!dic.ContainsKey(command.callbackId))
+            {
+                dic.GetOrAdd(command.callbackId, action);
+            }
+#if UNITY_IOS
+            registerHandler(command.ToJSON(), engineBridgeDelegate);
+#endif
+        }
+
+        public string CallWithReturnValue(Command command, Action<Result> action)
+        {
+            if (command.callbackId != null && !dic.ContainsKey(command.callbackId))
+            {
+                dic.GetOrAdd(command.callbackId, action);
+            }
+#if UNITY_IOS
+            if (action == null)
+            {
+                return callWithReturnValue(command.ToJSON(), null);
+            } else {
+                return callWithReturnValue(command.ToJSON(), engineBridgeDelegate);
+            }
+#else
+            return null;
+#endif
+        }
+
+#if UNITY_IOS
+        [DllImport("__Internal")]
+        private static extern string callWithReturnValue(string command, EngineBridgeDelegate engineBridgeDelegate);
+
+        [DllImport("__Internal")]
+        private static extern void callHandler(string command);
+
+        [DllImport("__Internal")]
+        private static extern void registerHandler(string command, EngineBridgeDelegate engineBridgeDelegate);
+#endif
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/BridgeIOS.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a02205ed9346141f29e5729b12bae65a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 119 - 0
Assets/TapSDK/Core/Mobile/Runtime/Command.cs

@@ -0,0 +1,119 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace TapSDK.Core
+{
+    public class Command
+    {
+        [SerializeField] public string service;
+        [SerializeField] public string method;
+        [SerializeField] public string args;
+        [SerializeField] public bool withCallback;
+        [SerializeField] public string callbackId;
+        [SerializeField] public bool disposable;
+        
+        public Command()
+        {
+
+        }
+
+        public Command(string json)
+        {
+            JsonUtility.FromJsonOverwrite(json, this);
+        }
+
+        public string ToJSON()
+        {
+            return JsonUtility.ToJson(this);
+        }
+
+        public Command(string service, string method, bool callback, Dictionary<string, object> dic)
+        {
+            this.args = dic == null ? null : Json.Serialize(dic);
+            this.service = service;
+            this.method = method;
+            this.withCallback = callback;
+            this.callbackId = this.withCallback ? TapUUID.UUID() : null;
+        }
+
+        public Command(string service, string method, bool callback, bool onceTime, Dictionary<string, object> dic)
+        {
+            this.args = dic == null ? null : Json.Serialize(dic);
+            this.service = service;
+            this.method = method;
+            this.withCallback = callback;
+            this.callbackId = this.withCallback ? TapUUID.UUID() : null;
+            this.disposable = onceTime;
+        }
+
+        public class Builder
+        {
+            private string service;
+
+            private string method;
+
+            private bool withCallback;
+
+            private string callbackId;
+
+            private bool disposable;
+
+            private Dictionary<string, object> args;
+
+            public Builder()
+            {
+
+            }
+
+            public Builder Service(string service)
+            {
+                this.service = service;
+                return this;
+            }
+
+            public Builder Method(string method)
+            {
+                this.method = method;
+                return this;
+            }
+
+            public Builder OnceTime(bool onceTime)
+            {
+                this.disposable = onceTime;
+                return this;
+            }
+
+            public Builder Args(Dictionary<string, object> dic)
+            {
+                this.args = dic;
+                return this;
+            }
+
+            public Builder Args(string key, object value)
+            {
+                if (this.args == null)
+                {
+                    this.args = new Dictionary<string, object>();
+                }
+                if(value is Dictionary<string,object>)
+                {
+                    value = Json.Serialize(value);
+                }
+                this.args.Add(key, value);
+                return this;
+            }
+
+            public Builder Callback(bool callback)
+            {
+                this.withCallback = callback;
+                this.callbackId = this.withCallback ? TapUUID.UUID() : null;
+                return this;
+            }
+
+            public Command CommandBuilder()
+            {
+                return new Command(this.service, this.method, this.withCallback, this.disposable, this.args);
+            }
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/Command.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bf7276ae3f7ff45f9b1f35d69ede7afa
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/TapSDK/Core/Mobile/Runtime/Constants.cs

@@ -0,0 +1,9 @@
+namespace TapSDK.Core
+{
+    public static class Constants
+    {
+        public const string VersionKey = "Engine-Version";
+
+        public const string PlatformKey = "Engine-Platform";
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/Constants.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 93d344834789c4be3973b920f2f3db9b
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 34 - 0
Assets/TapSDK/Core/Mobile/Runtime/EngineBridgeInitializer.cs

@@ -0,0 +1,34 @@
+using UnityEngine;
+using TapSDK.Core.Internal;
+using TapSDK.Core.Internal.Log;
+
+namespace TapSDK.Core.Mobile
+{
+    public static class EngineBridgeInitializer
+    {
+        private static bool isInitialized = false;
+        private const string SERVICE_NAME = "BridgeCoreService";
+
+        public static void Initialize()
+        {
+            if (!isInitialized)
+            {
+                TapLog.Log("Initializing EngineBridge");
+
+                // TODO: android 注册桥接
+                // #if UNITY_ANDROID
+                EngineBridge.GetInstance().Register(
+                    "com.taptap.sdk.core.unity.BridgeCoreService",
+                    "com.taptap.sdk.core.unity.BridgeCoreServiceImpl");
+                // #endif
+
+                isInitialized = true;
+            }
+        }
+
+        public static Command.Builder GetBridgeServer()
+        {
+            return new Command.Builder().Service(SERVICE_NAME);
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/EngineBridgeInitializer.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 75ce492acd08b47a589d97f2eb9373ac
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
Assets/TapSDK/Core/Mobile/Runtime/IBridge.cs

@@ -0,0 +1,15 @@
+using System;
+
+namespace TapSDK.Core
+{
+    public interface IBridge
+    {
+        void Register(string serviceClzName, string serviceImplName);
+
+        void Call(Command command);
+
+        void Call(Command command, Action<Result> action);
+        string CallWithReturnValue(Command command, Action<Result> action);
+        
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/IBridge.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 756215630f6ce4667b60a1deaff8543a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 50 - 0
Assets/TapSDK/Core/Mobile/Runtime/IOSNativeWrapper.cs

@@ -0,0 +1,50 @@
+using System;
+using System.Runtime.InteropServices;
+using UnityEngine;
+using System.Collections;
+using TapSDK.Core.Internal;
+using TapSDK.Core;
+
+namespace TapSDK.Core.Mobile {
+    public class IOSNativeWrapper
+    {
+
+#if UNITY_IOS
+    // 导入 C 函数
+        
+        // 定义一个委托类型,匹配 Objective-C 中的 block 参数
+        public delegate string DynamicPropertiesCalculatorDelegate();
+
+        // 注意:这个方法的封装比较特殊,因为它需要一个返回 NSDictionary 的回调。
+        [DllImport("__Internal")]
+        private static extern void _TapTapEventRegisterDynamicProperties(DynamicPropertiesCalculatorDelegate callback);
+
+        [DllImport("__Internal")]
+        private static extern void _TapTapSDKCoreSwitchToRND();
+
+        public static void SetRND(){
+            _TapTapSDKCoreSwitchToRND();
+        }
+        // 定义一个 Func<string> 委托,用于从 Unity 使用者那里获取动态属性
+        private static Func<string> dynamicPropertiesCallback;
+        public static void RegisterDynamicProperties(Func<string> callback)
+        {
+            dynamicPropertiesCallback = callback;
+            _TapTapEventRegisterDynamicProperties(DynamicPropertiesCalculator);
+        }
+
+        // Unity 端的回调方法,返回一个 JSON 字符串
+        [AOT.MonoPInvokeCallback(typeof(DynamicPropertiesCalculatorDelegate))]
+        private static string DynamicPropertiesCalculator()
+        {
+            if (dynamicPropertiesCallback != null)
+            {
+                string properties = dynamicPropertiesCallback();
+                return properties;
+            }
+            return null;
+        }
+
+#endif
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/IOSNativeWrapper.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7a625254200cf4a85a707809c2ad07e6
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 37 - 0
Assets/TapSDK/Core/Mobile/Runtime/Result.cs

@@ -0,0 +1,37 @@
+using System;
+using UnityEngine;
+
+namespace TapSDK.Core
+{
+    [Serializable]
+    public class Result
+    {
+        public static int RESULT_SUCCESS = 0;
+
+        public static int RESULT_ERROR = -1;
+
+        [SerializeField] public int code;
+
+        [SerializeField] public string message;
+
+        [SerializeField] public string content;
+
+        [SerializeField] public string callbackId;
+
+        [SerializeField] public bool onceTime;
+
+        public Result()
+        {
+        }
+
+        public Result(string json)
+        {
+            JsonUtility.FromJsonOverwrite(json, this);
+        }
+
+        public string ToJSON()
+        {
+            return JsonUtility.ToJson(this);
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/Result.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1bed21977dc864ab3873055bfef79966
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 77 - 0
Assets/TapSDK/Core/Mobile/Runtime/TapCoreMobile.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Threading.Tasks;
+using System.Linq;
+using System.Runtime.InteropServices;
+using TapSDK.Core.Internal;
+using TapSDK.Core.Internal.Utils;
+using System.Collections.Generic;
+using UnityEngine;
+using Newtonsoft.Json;
+using TapSDK.Core.Internal.Log;
+
+namespace TapSDK.Core.Mobile
+{
+    public class TapCoreMobile : ITapCorePlatform
+    {
+        private EngineBridge Bridge = EngineBridge.GetInstance();
+
+        public TapCoreMobile()
+        {
+            TapLog.Log("TapCoreMobile constructor");
+            TapLoom.Initialize();
+            EngineBridgeInitializer.Initialize();
+        }
+
+        public void Init(TapTapSdkOptions coreOption, TapTapSdkBaseOptions[] otherOptions)
+        {
+            TapLog.Log("TapCoreMobile SDK inited");
+            SetPlatformAndVersion(TapTapSDK.SDKPlatform, TapTapSDK.Version);
+            string coreOptionsJson = JsonUtility.ToJson(coreOption);
+            string[] otherOptionsJson = otherOptions.Select(option => JsonConvert.SerializeObject(option)).ToArray();
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("init")
+                .Args("coreOption", coreOptionsJson)
+                .Args("otherOptions", otherOptionsJson)
+                .CommandBuilder());
+        }
+
+        private void SetPlatformAndVersion(string platform, string version)
+        {
+            TapLog.Log("TapCoreMobile SetPlatformAndVersion called with platform: " + platform + " and version: " + version);
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("setPlatformAndVersion")
+                .Args("platform", TapTapSDK.SDKPlatform)
+                .Args("version", TapTapSDK.Version)
+                .CommandBuilder());
+            SetSDKArtifact("Unity");
+        }
+
+        private void SetSDKArtifact(string value)
+        {
+            TapLog.Log("TapCoreMobile SetSDKArtifact called with value: " + value);
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("setSDKArtifact")
+                .Args("artifact", "Unity")
+                .CommandBuilder());
+        }
+
+        public void Init(TapTapSdkOptions coreOption)
+        {
+            Init(coreOption, new TapTapSdkBaseOptions[0]);
+        }
+
+        public void UpdateLanguage(TapTapLanguageType language)
+        {
+            TapLog.Log("TapCoreMobile UpdateLanguage language: " + language);
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("updateLanguage")
+                .Args("language", (int)language)
+                .CommandBuilder());
+        }
+
+        public Task<bool> IsLaunchedFromTapTapPC()
+        {
+            return Task.FromResult(false);
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/TapCoreMobile.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 058fcddd11e6f483c92c09963365f0ee
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 291 - 0
Assets/TapSDK/Core/Mobile/Runtime/TapEventMobile.cs

@@ -0,0 +1,291 @@
+using System;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using TapSDK.Core.Internal;
+using System.Collections.Generic;
+using TapSDK.Core.Internal.Log;
+using UnityEngine;
+
+namespace TapSDK.Core.Mobile
+{
+    public class TapEventMobile : ITapEventPlatform
+    {
+        private EngineBridge Bridge = EngineBridge.GetInstance();
+
+        public TapEventMobile()
+        {
+            TapLog.Log("TapEventMobile constructor");
+            EngineBridgeInitializer.Initialize();
+        }
+
+        public void Init(TapTapEventOptions eventOptions)
+        {
+            
+        }
+
+        public void SetUserID(string userID)
+        {
+            TapLog.Log("TapEventMobile SetUserID = " + userID);
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("setUserID")
+                .Args("userID", userID)
+                .CommandBuilder());
+        }
+
+        public void SetUserID(string userID, string properties)
+        {
+            TapLog.Log("TapEventMobile SetUserID" + userID + properties);
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("setUserID")
+                .Args("userID", userID)
+                .Args("properties", properties)
+                .CommandBuilder());
+        }
+
+        public void ClearUser()
+        {
+            TapLog.Log("TapEventMobile ClearUser");
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("clearUser")
+                .CommandBuilder());
+        }
+
+        public string GetDeviceId()
+        {
+            string deviceId = Bridge.CallWithReturnValue(EngineBridgeInitializer.GetBridgeServer()
+                .Method("getDeviceId")
+                .CommandBuilder());
+            TapLog.Log("TapEventMobile GetDeviceId = " + deviceId);
+            return deviceId;
+        }
+
+        public void LogEvent(string name, string properties)
+        {
+            TapLog.Log("TapEventMobile LogEvent" + name + properties);
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("logEvent")
+                .Args("name", name)
+                .Args("properties", properties)
+                .CommandBuilder());
+        }
+
+        public void DeviceInitialize(string properties)
+        {
+            TapLog.Log("TapEventMobile DeviceInitialize" + properties);
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("deviceInitialize")
+                .Args("deviceInitialize", properties)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("deviceInitialize")
+                .Args("properties", properties)
+                .CommandBuilder());
+#endif
+        }
+
+        public void DeviceUpdate(string properties)
+        {
+            TapLog.Log("TapEventMobile DeviceUpdate" + properties);
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("deviceUpdate")
+                .Args("deviceUpdate", properties)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("deviceUpdate")
+                .Args("properties", properties)
+                .CommandBuilder());
+#endif
+        }
+
+        public void DeviceAdd(string properties)
+        {
+            TapLog.Log("TapEventMobile DeviceAdd" + properties);
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("deviceAdd")
+                .Args("deviceAdd", properties)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("deviceAdd")
+                .Args("properties", properties)
+                .CommandBuilder());
+#endif
+        }
+
+        public void UserInitialize(string properties)
+        {
+            TapLog.Log("TapEventMobile UserInitialize" + properties);
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("userInitialize")
+                .Args("userInitialize", properties)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("userInitialize")
+                .Args("properties", properties)
+                .CommandBuilder());
+#endif
+        }
+
+        public void UserUpdate(string properties)
+        {
+            TapLog.Log("TapEventMobile UserUpdate" + properties);
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("userUpdate")
+                .Args("userUpdate", properties)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("userUpdate")
+                .Args("properties", properties)
+                .CommandBuilder());
+#endif
+        }
+
+        public void UserAdd(string properties)
+        {
+            TapLog.Log("TapEventMobile UserAdd" + properties);
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("userAdd")
+                .Args("userAdd", properties)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("userAdd")
+                .Args("properties", properties)
+                .CommandBuilder());
+#endif
+        }
+
+        public void AddCommonProperty(string key, string value)
+        {
+            TapLog.Log("TapEventMobile AddCommonProperty" + key + value);
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("addCommonProperty")
+                .Args("addCommonProperty", key)
+                .Args("value", value)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("addCommonProperty")
+                .Args("key", key)
+                .Args("value", value)
+                .CommandBuilder());
+#endif
+        }
+
+        public void AddCommon(string properties)
+        {
+            TapLog.Log("TapEventMobile AddCommon" + properties);
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("addCommon")
+                .Args("addCommon", properties)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("addCommonProperties")
+                .Args("properties", properties)
+                .CommandBuilder());
+#endif
+        }
+
+        public void ClearCommonProperty(string key)
+        {
+            TapLog.Log("TapEventMobile ClearCommonProperty");
+
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("clearCommonProperty")
+                .Args("clearCommonProperty", key)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("clearCommonProperty")
+                .Args("key", key)
+                .CommandBuilder());
+#endif
+        }
+
+        public void ClearCommonProperties(string[] keys)
+        {
+            TapLog.Log("TapEventMobile ClearCommonProperties");
+
+#if UNITY_IOS
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("clearCommonProperties")
+                .Args("clearCommonProperties", keys)
+                .CommandBuilder());
+#else
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("clearCommonProperties")
+                .Args("keys", keys)
+                .CommandBuilder());
+#endif
+        }
+
+        public void ClearAllCommonProperties()
+        {
+            TapLog.Log("TapEventMobile ClearAllCommonProperties");
+
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("clearAllCommonProperties")
+                .CommandBuilder());
+        }
+
+        public void LogChargeEvent(string orderID, string productName, long amount, string currencyType, string paymentMethod, string properties)
+        {
+            TapLog.Log("TapEventMobile LogChargeEvent" + orderID);
+
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("logPurchasedEvent")
+                .Args("orderID", orderID)
+                .Args("productName", productName)
+                .Args("amount", amount)
+                .Args("currencyType", currencyType)
+                .Args("paymentMethod", paymentMethod)
+                .Args("properties", properties)
+                .CommandBuilder());
+        }
+
+        public void RegisterDynamicProperties(Func<string> callback)
+        {
+            TapLog.Log("RegisterDynamicProperties called" + callback);
+#if UNITY_IOS
+            IOSNativeWrapper.RegisterDynamicProperties(callback);
+#else
+            AndroidNativeWrapper.RegisterDynamicProperties(callback);
+#endif
+        }
+
+        public void SetOAID(string value)
+        {
+            TapLog.Log("TapEventMobile SetOAID" + value);
+#if UNITY_ANDROID
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("setOAID")
+                .Args("oaid", value)
+                .CommandBuilder());            
+#endif
+        }
+
+        public void LogDeviceLoginEvent()
+        {
+            TapLog.Log("TapEventMobile LogDeviceLoginEvent");
+#if UNITY_ANDROID
+            Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
+                .Method("logDeviceLoginEvent")
+                .CommandBuilder());            
+#endif
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/TapEventMobile.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4afff3e4af4824f50b0b4a91897cc20a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 18 - 0
Assets/TapSDK/Core/Mobile/Runtime/TapSDK.Core.Mobile.Runtime.asmdef

@@ -0,0 +1,18 @@
+{
+    "name": "TapSDK.Core.Mobile.Runtime",
+    "references": [
+        "GUID:7d5ef2062f3704e1ab74aac0e4d5a1a7"
+    ],
+    "includePlatforms": [
+        "Android",
+        "iOS"
+    ],
+    "excludePlatforms": [],
+    "allowUnsafeCode": false,
+    "overrideReferences": false,
+    "precompiledReferences": [],
+    "autoReferenced": true,
+    "defineConstraints": [],
+    "versionDefines": [],
+    "noEngineReferences": false
+}

+ 7 - 0
Assets/TapSDK/Core/Mobile/Runtime/TapSDK.Core.Mobile.Runtime.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 10560023d8780423cb943c7a324b69f2
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
Assets/TapSDK/Core/Mobile/Runtime/TapUUID.cs

@@ -0,0 +1,9 @@
+namespace TapSDK.Core
+{
+    public class TapUUID
+    {
+        public static string UUID(){
+            return System.Guid.NewGuid().ToString();
+        }
+    }
+}

+ 11 - 0
Assets/TapSDK/Core/Mobile/Runtime/TapUUID.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e61d5874559a448db9aa22254d05fe7a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/TapSDK/Core/Resources.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 85e6f39839e6d4c69ae3b8d6b4928cdd
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/TapSDK/Core/Resources/Fonts.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5884ad20cef2e4e5b82f45e69b0de123
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

TEMPAT SAMPAH
Assets/TapSDK/Core/Resources/Fonts/taptap-sdk-bold.ttf


+ 22 - 0
Assets/TapSDK/Core/Resources/Fonts/taptap-sdk-bold.ttf.meta

@@ -0,0 +1,22 @@
+fileFormatVersion: 2
+guid: 5b92beb2e4ac04c1681719225dc6d5fc
+TrueTypeFontImporter:
+  externalObjects: {}
+  serializedVersion: 4
+  fontSize: 16
+  forceTextureCase: -2
+  characterSpacing: 0
+  characterPadding: 1
+  includeFontData: 1
+  fontName: icomoon
+  fontNames:
+  - taptap-sdk-bold
+  fallbackFontReferences:
+  - {fileID: 12800000, guid: 922f25809659d41b4b23147484bd150d, type: 3}
+  customCharacters: 
+  fontRenderingMode: 0
+  ascentCalculationMode: 1
+  useLegacyBoundsCalculation: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

TEMPAT SAMPAH
Assets/TapSDK/Core/Resources/Fonts/taptap-sdk.ttf


+ 21 - 0
Assets/TapSDK/Core/Resources/Fonts/taptap-sdk.ttf.meta

@@ -0,0 +1,21 @@
+fileFormatVersion: 2
+guid: c76570f7b9a4942ae84d6491f2669330
+TrueTypeFontImporter:
+  externalObjects: {}
+  serializedVersion: 4
+  fontSize: 16
+  forceTextureCase: -2
+  characterSpacing: 0
+  characterPadding: 1
+  includeFontData: 1
+  fontName: icomoon
+  fontNames:
+  - taptap-sdk
+  fallbackFontReferences: []
+  customCharacters: 
+  fontRenderingMode: 0
+  ascentCalculationMode: 1
+  useLegacyBoundsCalculation: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 260 - 0
Assets/TapSDK/Core/Resources/Loading.prefab

@@ -0,0 +1,260 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1138495173445114285
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 9127102694935652778}
+  - component: {fileID: 3062185400663604511}
+  - component: {fileID: 6853361318577022366}
+  - component: {fileID: 7333425585439521949}
+  - component: {fileID: 216553251484504045}
+  m_Layer: 5
+  m_Name: Loading
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &9127102694935652778
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  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: 7053660334341111769}
+  - {fileID: 6725243170288973124}
+  m_Father: {fileID: 0}
+  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!223 &3062185400663604511
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  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: 0
+  m_TargetDisplay: 0
+--- !u!114 &6853361318577022366
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!225 &7333425585439521949
+CanvasGroup:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_Alpha: 1
+  m_Interactable: 1
+  m_BlocksRaycasts: 1
+  m_IgnoreParentGroups: 0
+--- !u!114 &216553251484504045
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 270dfb0d584134275afb9640c5abde2d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  canvas: {fileID: 0}
+  canvasGroup: {fileID: 0}
+  panelConfig:
+    animationType: 0
+  toppedOrder: 10
+  rotater: {fileID: 6725243170288973124}
+  speed: 500
+--- !u!1 &1726325218397980974
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 6725243170288973124}
+  - component: {fileID: 3451134979655710801}
+  - component: {fileID: 6740354880857316333}
+  m_Layer: 5
+  m_Name: Image
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &6725243170288973124
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  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: 9127102694935652778}
+  m_RootOrder: 1
+  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: 0}
+  m_SizeDelta: {x: 100, y: 100}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &3451134979655710801
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  m_CullTransparentMesh: 0
+--- !u!114 &6740354880857316333
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 0
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: 5afbaa34df10d44c1989b6aa0c25524a, type: 3}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!1 &7843842294332592314
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 7053660334341111769}
+  - component: {fileID: 8764964144715973437}
+  - component: {fileID: 1611728940112126731}
+  m_Layer: 5
+  m_Name: Bgm
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &7053660334341111769
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7843842294332592314}
+  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: 9127102694935652778}
+  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 &8764964144715973437
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7843842294332592314}
+  m_CullTransparentMesh: 0
+--- !u!114 &1611728940112126731
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7843842294332592314}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0, g: 0, b: 0, a: 0.34901962}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 0}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1

+ 7 - 0
Assets/TapSDK/Core/Resources/Loading.prefab.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: c7324adbd46ba49df96a39da673743a9
+PrefabImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 194 - 0
Assets/TapSDK/Core/Resources/TapCommonTip.prefab

@@ -0,0 +1,194 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1138495173445114285
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 9127102694935652778}
+  - component: {fileID: 3062185400663604511}
+  - component: {fileID: 6853361318577022366}
+  - component: {fileID: 7333425585439521949}
+  - component: {fileID: 594910176992853236}
+  m_Layer: 5
+  m_Name: TapCommonTip
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &9127102694935652778
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  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: 9114159179718277540}
+  m_Father: {fileID: 0}
+  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!223 &3062185400663604511
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  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: 0
+  m_TargetDisplay: 0
+--- !u!114 &6853361318577022366
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!225 &7333425585439521949
+CanvasGroup:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_Alpha: 1
+  m_Interactable: 1
+  m_BlocksRaycasts: 1
+  m_IgnoreParentGroups: 0
+--- !u!114 &594910176992853236
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: cfadb0c2f9cbd4e26821f6acbffb6dac, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  canvas: {fileID: 0}
+  canvasGroup: {fileID: 0}
+  panelConfig:
+    animationType: 0
+  toppedOrder: 0
+  text: {fileID: 0}
+  background: {fileID: 0}
+  layout: {fileID: 0}
+  iconImage: {fileID: 0}
+  fixVal: 0
+  animationTime: 0
+  sizeDeltaX: 50
+--- !u!1 &2834967756811503227
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 9114159179718277540}
+  - component: {fileID: 3789258745879994999}
+  - component: {fileID: 7465180183063499933}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &9114159179718277540
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  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: 9127102694935652778}
+  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 &3789258745879994999
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  m_CullTransparentMesh: 0
+--- !u!114 &7465180183063499933
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 0
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 36
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 3
+    m_MaxSize: 36
+    m_Alignment: 2
+    m_AlignByGeometry: 1
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 

+ 7 - 0
Assets/TapSDK/Core/Resources/TapCommonTip.prefab.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: df6c1ff9c578d44a694382e270522415
+PrefabImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 528 - 0
Assets/TapSDK/Core/Resources/TapCommonToastBlack.prefab

@@ -0,0 +1,528 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &784908744357270256
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1362374463538379500}
+  m_Layer: 5
+  m_Name: Root
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1362374463538379500
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 784908744357270256}
+  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: 6725243170288973124}
+  m_Father: {fileID: 9127102694935652778}
+  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: -150}
+  m_SizeDelta: {x: 0, y: 50}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1138495173445114285
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 9127102694935652778}
+  - component: {fileID: 3062185400663604511}
+  - component: {fileID: 6853361318577022366}
+  - component: {fileID: 7333425585439521949}
+  - component: {fileID: 594910176992853236}
+  m_Layer: 5
+  m_Name: TapCommonToastBlack
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &9127102694935652778
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  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: 1362374463538379500}
+  m_Father: {fileID: 0}
+  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!223 &3062185400663604511
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  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: 0
+  m_TargetDisplay: 0
+--- !u!114 &6853361318577022366
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!225 &7333425585439521949
+CanvasGroup:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_Alpha: 1
+  m_Interactable: 1
+  m_BlocksRaycasts: 1
+  m_IgnoreParentGroups: 0
+--- !u!114 &594910176992853236
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: cfadb0c2f9cbd4e26821f6acbffb6dac, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  canvas: {fileID: 0}
+  canvasGroup: {fileID: 0}
+  panelConfig:
+    animationType: 0
+  toppedOrder: 0
+  text: {fileID: 0}
+  background: {fileID: 0}
+  layout: {fileID: 0}
+  iconImage: {fileID: 0}
+  fixVal: 0
+  animationTime: 0
+  sizeDeltaX: 50
+--- !u!1 &1726325218397980974
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 6725243170288973124}
+  - component: {fileID: 3451134979655710801}
+  - component: {fileID: 6740354880857316333}
+  m_Layer: 5
+  m_Name: BGM
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &6725243170288973124
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  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: 5482986322874465450}
+  m_Father: {fileID: 1362374463538379500}
+  m_RootOrder: 0
+  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.26, y: 52.53}
+  m_SizeDelta: {x: 210, y: 42}
+  m_Pivot: {x: 0.5, y: 1}
+--- !u!222 &3451134979655710801
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  m_CullTransparentMesh: 0
+--- !u!114 &6740354880857316333
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0, g: 0, b: 0, a: 0.8509804}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: 121fadaa5f515439bb5fa46c7f9d2c2c, type: 3}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!1 &1760182246072008436
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 5482986322874465450}
+  - component: {fileID: 4664850341719020502}
+  m_Layer: 5
+  m_Name: Container
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &5482986322874465450
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1760182246072008436}
+  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: 4095916428595266728}
+  - {fileID: 9114159179718277540}
+  m_Father: {fileID: 6725243170288973124}
+  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!114 &4664850341719020502
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1760182246072008436}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Padding:
+    m_Left: 8
+    m_Right: 0
+    m_Top: 9
+    m_Bottom: 0
+  m_ChildAlignment: 0
+  m_Spacing: 8
+  m_ChildForceExpandWidth: 1
+  m_ChildForceExpandHeight: 1
+  m_ChildControlWidth: 0
+  m_ChildControlHeight: 0
+  m_ChildScaleWidth: 0
+  m_ChildScaleHeight: 0
+--- !u!1 &2834967756811503227
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 9114159179718277540}
+  - component: {fileID: 3789258745879994999}
+  - component: {fileID: 7465180183063499933}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &9114159179718277540
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  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: 5482986322874465450}
+  m_RootOrder: 1
+  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: -42}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &3789258745879994999
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  m_CullTransparentMesh: 0
+--- !u!114 &7465180183063499933
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 1
+    m_MaxSize: 36
+    m_Alignment: 4
+    m_AlignByGeometry: 1
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: "\u5DF2\u767B\u5F55"
+--- !u!1 &7763401120556589406
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 8123150922358459483}
+  - component: {fileID: 4759975136191292132}
+  - component: {fileID: 1556038907289308440}
+  m_Layer: 5
+  m_Name: Icon
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &8123150922358459483
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7763401120556589406}
+  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: 4095916428595266728}
+  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 &4759975136191292132
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7763401120556589406}
+  m_CullTransparentMesh: 0
+--- !u!114 &1556038907289308440
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7763401120556589406}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Texture: {fileID: 0}
+  m_UVRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+--- !u!1 &7837080653710102900
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4095916428595266728}
+  - component: {fileID: 1700168474539684878}
+  - component: {fileID: 4314615989886940530}
+  - component: {fileID: 6742359035200427369}
+  m_Layer: 5
+  m_Name: Mask
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &4095916428595266728
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7837080653710102900}
+  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: 8123150922358459483}
+  m_Father: {fileID: 5482986322874465450}
+  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: 24, y: 24}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &1700168474539684878
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7837080653710102900}
+  m_CullTransparentMesh: 0
+--- !u!114 &4314615989886940530
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7837080653710102900}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0, g: 0, b: 0, a: 0.003921569}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: def1d4bba5fa6450b92e6a98dd48cb6e, type: 3}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!114 &6742359035200427369
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7837080653710102900}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_ShowMaskGraphic: 1

+ 7 - 0
Assets/TapSDK/Core/Resources/TapCommonToastBlack.prefab.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: cf37b42d4d2434a15b3dcce12ac09f0d
+PrefabImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 411 - 0
Assets/TapSDK/Core/Resources/TapCommonToastWhite.prefab

@@ -0,0 +1,411 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &784908744357270256
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1362374463538379500}
+  m_Layer: 5
+  m_Name: Root
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1362374463538379500
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 784908744357270256}
+  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: 6725243170288973124}
+  m_Father: {fileID: 9127102694935652778}
+  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: -150}
+  m_SizeDelta: {x: 0, y: 50}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1138495173445114285
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 9127102694935652778}
+  - component: {fileID: 3062185400663604511}
+  - component: {fileID: 6853361318577022366}
+  - component: {fileID: 7333425585439521949}
+  - component: {fileID: 6070856196811468902}
+  m_Layer: 5
+  m_Name: TapCommonToastWhite
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &9127102694935652778
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  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: 1362374463538379500}
+  m_Father: {fileID: 0}
+  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!223 &3062185400663604511
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  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: 0
+  m_TargetDisplay: 0
+--- !u!114 &6853361318577022366
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!225 &7333425585439521949
+CanvasGroup:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_Alpha: 1
+  m_Interactable: 1
+  m_BlocksRaycasts: 1
+  m_IgnoreParentGroups: 0
+--- !u!114 &6070856196811468902
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1138495173445114285}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5e2bbf05d8861431bb645d167b1ab76c, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  canvas: {fileID: 0}
+  canvasGroup: {fileID: 0}
+  panelConfig:
+    animationType: 0
+  toppedOrder: 0
+  text: {fileID: 0}
+  background: {fileID: 0}
+  iconImage: {fileID: 0}
+  fixVal: 0
+  animationTime: 0
+--- !u!1 &1726325218397980974
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 6725243170288973124}
+  - component: {fileID: 3451134979655710801}
+  - component: {fileID: 6740354880857316333}
+  m_Layer: 5
+  m_Name: BGM
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &6725243170288973124
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  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: 5482986322874465450}
+  m_Father: {fileID: 1362374463538379500}
+  m_RootOrder: 0
+  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.26, y: 52.53}
+  m_SizeDelta: {x: 210, y: 42}
+  m_Pivot: {x: 0.5, y: 1}
+--- !u!222 &3451134979655710801
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  m_CullTransparentMesh: 0
+--- !u!114 &6740354880857316333
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1726325218397980974}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: f299b35e3cd69409c84ec21da0f6d880, type: 3}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!1 &1760182246072008436
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 5482986322874465450}
+  m_Layer: 5
+  m_Name: Container
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &5482986322874465450
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1760182246072008436}
+  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: 9114159179718277540}
+  - {fileID: 8123150922358459483}
+  m_Father: {fileID: 6725243170288973124}
+  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!1 &2834967756811503227
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 9114159179718277540}
+  - component: {fileID: 3789258745879994999}
+  - component: {fileID: 7465180183063499933}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &9114159179718277540
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  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: 5482986322874465450}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0.5}
+  m_AnchorMax: {x: 0, y: 0.5}
+  m_AnchoredPosition: {x: 40, y: 0.22}
+  m_SizeDelta: {x: 150, y: 37.5672}
+  m_Pivot: {x: 0, y: 0.5}
+--- !u!222 &3789258745879994999
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  m_CullTransparentMesh: 0
+--- !u!114 &7465180183063499933
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2834967756811503227}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0, g: 0, b: 0, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 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: 36
+    m_Alignment: 4
+    m_AlignByGeometry: 1
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: "\u63D0\u4EA4\u6210\u529F"
+--- !u!1 &7763401120556589406
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 8123150922358459483}
+  - component: {fileID: 4759975136191292132}
+  - component: {fileID: 1556038907289308440}
+  m_Layer: 5
+  m_Name: Image
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &8123150922358459483
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7763401120556589406}
+  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: 5482986322874465450}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 0, y: 1}
+  m_AnchoredPosition: {x: 8, y: -21}
+  m_SizeDelta: {x: 24, y: 24}
+  m_Pivot: {x: 0, y: 0.5}
+--- !u!222 &4759975136191292132
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7763401120556589406}
+  m_CullTransparentMesh: 0
+--- !u!114 &1556038907289308440
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7763401120556589406}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Texture: {fileID: 2800000, guid: 2d5e20c49ced14858807cec65b2e9a84, type: 3}
+  m_UVRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1

+ 7 - 0
Assets/TapSDK/Core/Resources/TapCommonToastWhite.prefab.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 4b1d2ce1ea3fe4f9ba9aa15db7223c65
+PrefabImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 352 - 0
Assets/TapSDK/Core/Resources/TapMessage.prefab

@@ -0,0 +1,352 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1863032913385268
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 224735441970951518}
+  - component: {fileID: 223962106893064856}
+  - component: {fileID: 114668005265195872}
+  - component: {fileID: 114350312650004060}
+  m_Layer: 5
+  m_Name: TapMessage
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &224735441970951518
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1863032913385268}
+  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: 3020249884784984160}
+  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 &223962106893064856
+Canvas:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1863032913385268}
+  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: 32767
+  m_TargetDisplay: 0
+--- !u!114 &114668005265195872
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1863032913385268}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_UiScaleMode: 1
+  m_ReferencePixelsPerUnit: 100
+  m_ScaleFactor: 1
+  m_ReferenceResolution: {x: 600, y: 600}
+  m_ScreenMatchMode: 1
+  m_MatchWidthOrHeight: 0
+  m_PhysicalUnit: 3
+  m_FallbackScreenDPI: 96
+  m_DefaultSpriteDPI: 96
+  m_DynamicPixelsPerUnit: 1
+--- !u!114 &114350312650004060
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1863032913385268}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!1 &2683931837221227688
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 3020249884784984160}
+  m_Layer: 5
+  m_Name: container
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &3020249884784984160
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2683931837221227688}
+  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: 7445445916596797054}
+  m_Father: {fileID: 224735441970951518}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0}
+  m_AnchorMax: {x: 0.5, y: 0}
+  m_AnchoredPosition: {x: 0.5, y: 100}
+  m_SizeDelta: {x: 200, y: 40}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &6224477040733538127
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 7445445916596797054}
+  - component: {fileID: 6150942826548885810}
+  - component: {fileID: 1822422428467713874}
+  - component: {fileID: 3902093695152135445}
+  - component: {fileID: 8025106749851834532}
+  m_Layer: 5
+  m_Name: text_background
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &7445445916596797054
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6224477040733538127}
+  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: 5268490143839252188}
+  m_Father: {fileID: 3020249884784984160}
+  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: -20}
+  m_SizeDelta: {x: 200, y: 40}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &6150942826548885810
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6224477040733538127}
+  m_CullTransparentMesh: 0
+--- !u!114 &1822422428467713874
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6224477040733538127}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: 121fadaa5f515439bb5fa46c7f9d2c2c, type: 3}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!114 &3902093695152135445
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6224477040733538127}
+  m_Enabled: 0
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Padding:
+    m_Left: 25
+    m_Right: 25
+    m_Top: 10
+    m_Bottom: 10
+  m_ChildAlignment: 4
+  m_Spacing: 0
+  m_ChildForceExpandWidth: 0
+  m_ChildForceExpandHeight: 0
+  m_ChildControlWidth: 0
+  m_ChildControlHeight: 0
+  m_ChildScaleWidth: 0
+  m_ChildScaleHeight: 0
+--- !u!114 &8025106749851834532
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6224477040733538127}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_HorizontalFit: 0
+  m_VerticalFit: 0
+--- !u!1 &7966388593320536563
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 5268490143839252188}
+  - component: {fileID: 6511217540227465427}
+  - component: {fileID: 9100911774364350353}
+  - component: {fileID: 4527992897410718175}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &5268490143839252188
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7966388593320536563}
+  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: 7445445916596797054}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 1}
+  m_AnchorMax: {x: 0, y: 1}
+  m_AnchoredPosition: {x: 100, y: -20}
+  m_SizeDelta: {x: 180, y: 35}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &6511217540227465427
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7966388593320536563}
+  m_CullTransparentMesh: 0
+--- !u!114 &9100911774364350353
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7966388593320536563}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 12800000, guid: c76570f7b9a4942ae84d6491f2669330, type: 3}
+    m_FontSize: 11
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 0
+    m_MaxSize: 180
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: bottombottombotttombottombotttombottombotttombottombotttombottombotttombottombottombottombottombottombottombottombottombottombottombottomb
+--- !u!114 &4527992897410718175
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7966388593320536563}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreLayout: 0
+  m_MinWidth: -1
+  m_MinHeight: 60
+  m_PreferredWidth: -1
+  m_PreferredHeight: 60
+  m_FlexibleWidth: -1
+  m_FlexibleHeight: -1
+  m_LayoutPriority: 1

+ 10 - 0
Assets/TapSDK/Core/Resources/TapMessage.prefab.meta

@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: aadf0d7dac0d30144be3c5cefa0d81cf
+timeCreated: 1532764749
+licenseType: Free
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 100100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

TEMPAT SAMPAH
Assets/TapSDK/Core/Resources/TapSDKCommonTapIcon-v2.png


+ 128 - 0
Assets/TapSDK/Core/Resources/TapSDKCommonTapIcon-v2.png.meta

@@ -0,0 +1,128 @@
+fileFormatVersion: 2
+guid: 8a4f1e6b80f4f461dabbcce5a599ba3a
+TextureImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 11
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    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: 0
+    wrapU: 1
+    wrapV: 1
+    wrapW: 0
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 1
+  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: 1
+  spriteTessellationDetail: -1
+  textureType: 8
+  textureShape: 1
+  singleChannelComponent: 0
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  applyGammaDecoding: 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
+  - serializedVersion: 3
+    buildTarget: Standalone
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: iPhone
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: Android
+    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: 5e97eb03825dee720800000000000000
+    internalID: 0
+    vertices: []
+    indices: 
+    edges: []
+    weights: []
+    secondaryTextures: []
+  spritePackingTag: 
+  pSDRemoveMatte: 0
+  pSDShowRemoveMatteOption: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

TEMPAT SAMPAH
Assets/TapSDK/Core/Resources/TapSDKCommonTapIcon.png


+ 128 - 0
Assets/TapSDK/Core/Resources/TapSDKCommonTapIcon.png.meta

@@ -0,0 +1,128 @@
+fileFormatVersion: 2
+guid: def1d4bba5fa6450b92e6a98dd48cb6e
+TextureImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 11
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    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: 0
+    wrapU: 1
+    wrapV: 1
+    wrapW: 0
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 1
+  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: 1
+  spriteTessellationDetail: -1
+  textureType: 8
+  textureShape: 1
+  singleChannelComponent: 0
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  applyGammaDecoding: 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
+  - serializedVersion: 3
+    buildTarget: Standalone
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: iPhone
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  - serializedVersion: 3
+    buildTarget: Android
+    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: 5e97eb03825dee720800000000000000
+    internalID: 0
+    vertices: []
+    indices: 
+    edges: []
+    weights: []
+    secondaryTextures: []
+  spritePackingTag: 
+  pSDRemoveMatte: 0
+  pSDShowRemoveMatteOption: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini