Files
Commercialization.tapadn/GLOBAL_DESIGN.md
2026-06-12 16:17:36 +08:00

8.5 KiB
Raw Permalink Blame History

Commercialization.tapadn 全局设计

目标

本模块把 TapADN / Dirichlet 聚合广告 SDK 接到 CC-Framework.Commercialization 抽象层后面,让业务项目继续只关心 ADManagerADConfig

当前实现对齐 Commercialization.topon 的分层:

  • CC-Framework.Commercialization: ADManagerIAdControllerADPlayer 抽象。
  • Commercialization.tapadn: 平台 controller、广告播放器、构建自动化。
  • DirichletMediation: 官方 SDK 和平台桥。

目录

  • Assets/DirichletMediation: 官方聚合 Unity SDK 4.2.5.0,已删除官方 Sample。
  • Assets/Plugins/Android: 官方 Android AAR、Manifest、ProGuard、本地微信 OpenSDK AAR。
  • Assets/Plugins/iOS: iOS Objective-C++ bridge。
  • Assets/Tapadn_Adapter/Runtime/Scripts: 商业化抽象层适配。
  • Assets/Tapadn_Adapter/Editor: Android 构建后处理和依赖声明。
  • Assets/DirichletMediation/Editor: Android Gradle 后处理与 iOS Xcode/CocoaPods 后处理。
  • Assets/Samples~: 可选调试样例预留,不随主包自动进入业务项目。

Runtime 设计

TapadnAdController 实现 IAdController

  • ADConfig 和可选 args 解析 TapadnControllerOptions
  • 构造 DirichletAdConfig 并调用 DirichletSdk.Init
  • 根据 AD_Type 创建 TapadnAwardVideoPlayerTapadnInteractionPlayerTapadnSplashPlayer

TapadnCommercialization 是便捷入口:

  • CreateController() 隐藏 controller 创建细节。
  • InitADManager(...) 由模块负责创建 controller 并交给 ADManager
  • CreateConfig(...) 用代码生成临时 ADConfig,适合游戏项目不想维护 TapADN SDK 细节时使用。

广告播放器

默认方案:优先手动 load/show避免把 ADManager.AsyncAdPlayer 的时序语义与 TapADN auto 语义混用。

原因:

  • TapADN auto-ad 是官方 Android 场景下的“加载 + 展示合并”调用,不等价于完整场景分发与实时 readiness 能力。
  • ADManager.AsyncAdPlayer 先做 IsReadly 决策,未 ready 则调用 LoadADready 后再 ShowAD,所以手动模式下生命周期和失败收口更稳定。

备选方案:手动 load/show。

  • 已通过 tapadn.rewarded_auto_load=false 等 key 保留。
  • 手动模式保存 SDK 返回的 ad handle并在 Closed 时销毁。

不确定点:

  • 官方文档说明 auto-ad 目前主要是 Android 能力。本模块在 iOS 对激励、插屏、开屏 auto API 做 load-then-show 兼容 fallback但不承诺 Android native auto 缓存语义;真正 iOS 出包前需要用 TapADN iOS 账号和广告位做真机验证。
  • AD_Type 抽象层没有 Banner 类型,所以本轮没有将 TapADN Banner 暴露到 ADManager。如果抽象层后续新增 Banner可以直接复用官方 ShowBannerAutoAd

配置设计

基础字段复用 ADConfig

  • Id: MediaId。
  • Key: MediaKey。
  • Key2: MediaName。
  • BaseAwardAdKeyValue.value: 激励视频 SpaceId。
  • BaseInteractionAdKeyValue.value: 插屏 SpaceId。
  • BaseSplashAdKeyValue.value: 开屏 SpaceId。

高级配置通过 CommonKeyValues 或字典传入,使用 tapadn.* 前缀,避免和 TopOn 现有 key 冲突。

Android 构建设计

保留官方 DirichletGradlePostProcessor,它负责 Dirichlet AAR 和 Maven 依赖注入。

新增 TapadnBuildAndroidProcess,只负责本模块集成层额外需求:

  • TapADN Manifest 权限补齐。
  • com.tapsdk.tapad.internal.TapADFileProvider@xml/tapad_ad_file_path
  • 微信 OpenSDK 的 com.tencent.mm queries 与 .wxapi.WXEntryActivity
  • AndroidX / Jetifier 开关。

方案选择记录:

  • 方案 A只放 WXDependencies.xml,依赖宿主 EDM4U 下载微信 SDK。风险是业务项目没有 EDM4U 或未 resolve 时构建失败。
  • 方案 B只放本地微信 AAR。风险是宿主 EDM4U 依赖图不可见。
  • 当前选择:本地 AAR + WXDependencies.xml 同时保留。这样最接近 TopOn 当前工程,也能覆盖无 EDM4U 的构建场景。

iOS 构建设计

保留 iOS Objective-C++ bridge并通过 DirichletMediationIOSPostProcessor 自动生成 Xcode 集成:

  • Pod 默认版本为官方 iOS 聚合 SDK 4.2.0.1,可用 DIRICHLET_IOS_SDK_VERSIONEditorPrefs("Dirichlet.iOS.SDKVersion") 覆盖。
  • 所有 Dirichlet iOS Pods 放到 Unity Framework target保持 bridge、SDK、adapter 在同一二进制上下文。
  • 自动补 SKAdNetworkItemsNSUserTrackingUsageDescriptionAppTrackingTransparency.frameworkAdSupport.framework
  • 构建后执行 pod install,缺失 CocoaPods 或 Pod 源异常时让 Unity 构建失败,避免产出半配置 Xcode 工程。
  • GDT 动态 framework 在 pod install 后嵌入 App target。

iOS runtime 桥接负责:

  • 初始化时传入 MediaIdMediaKeyMediaNamegameChannelshakeEnabledallowIDFAAccessaTags
  • RequestPermissionIfNecessary() 在 iOS 14+ 请求 ATT。
  • 加载/展示激励、插屏、开屏;展示前检查 root view controller 和 isReady,失败时回传 show_error

编辑器可见性

本模块不提供默认可见面板。构建自动化通过 IPostGenerateGradleAndroidProject 静默执行;调试能力放入 Samples~,由业务项目显式导入。

若后续需要可视化配置面板,应使用宏包裹菜单入口,例如 COMMERCIALIZATION_TAPADN_DEBUG_MENU,默认不在业务项目菜单里出现。

UPM 与本机验证约定

发布包入口是 Assets/package.json,其中 com.foldcc.cc-framework.commercialization 依赖保持为远程 Git URL

"com.foldcc.cc-framework.commercialization": "http://private.lightyears.ltd:18650/foldcc/CC-Framework.Commercialization.git#1.0.15"

当前仓库自身作为 Unity 验证工程时,可以在 Packages/manifest.json 使用本地 file: 引用:

"com.foldcc.cc-framework.commercialization": "file:CC-Framework.Commercialization/Assets"

该路径以 Packages/manifest.json 所在目录为基准,符合 Unity 本地 UPM package 规则;Packages/CC-Framework.Commercialization 只是本机验证副本,已被 .gitignore 排除,不进入发布包。

如果 batchmode 出现 Failed to resolve packages: The "path" argument must be of type string. Received undefined,不把它直接归因为 manifest 路径错误,也不使用 -noUpm 绕过。处理顺序是保存 Unity Editor log 和 %LOCALAPPDATA%\Unity\Editor\upm.log,确认没有并发 Unity/UPM 进程,再用官方 Unity.exe -batchmode -quit -projectPath <project> -logFile <log> 做一次只解析 package 的验证;若仍复现,则用 Unity Hub/已打开 Editor 作为 GUI 对照入口继续看 Console 编译错误。

策略验收与可视化

模块内置智能预加载策略评估脚本已接入,默认次留验收目标为 35%,用于验证 PreloadThresholdCooldownSeconds 在不同留存下的策略敏感度。

验收输出位于:

  • Tools/SmartLoadSensitivity/output/TapADN_智能预加载_敏感度验收报告.md
  • Tools/SmartLoadSensitivity/output/smartload_sensitivity_summary.csv
  • Tools/SmartLoadSensitivity/output/smartload_retention_rank.csv
  • Tools/SmartLoadSensitivity/output/*.png

推荐复现命令:

python Tools/SmartLoadSensitivity/smartload_sensitivity_simulation.py --users 5000 --out-dir Tools/SmartLoadSensitivity/output

核心对比维度(含 35%次留):

  • threshold 的下调会提升 Immediate,但会抬高 Waste
  • cooldown 拉长可压低 waste、降低重复预加载频次但也会把 show 等待时延上抬。
  • 默认策略建议先用 threshold=0.20~0.40 做高即时性验证,再通过 waste 上限(如 8%~12%)回退到 0.35~0.55 区间。

全局缓存归因

CC-Framework.Commercialization 当前是一类广告一个全局 ADPlayer,场景只是播放与策略标签,不是缓存隔离单位。因此 TapADN 智能预加载按两层口径统计:

  • 策略触发层:哪个场景触发了真实 SDK load记录 preload_request/preload_success/preload_fail
  • 播放消费层:哪个场景实际发起 AsyncPlayAD 并展示,记录 immediate_hit/show_start/smart_cache_hit

如果 A 场景触发的全局缓存最终在 B 场景展示A 会记录 smart_preload_consumed_other_sceneB 会记录 smart_cache_cross_scene_hit。这不会改变玩家实际体验,只用于避免把“全局缓存命中”误读成“同场景完全自消费”。

验收产物建议每周回放:用最近 7 天留存分布与 fill 成功率替换脚本默认参数,再做一次敏感度重算并对比排名变化。