Article

Unity WebGL 小游戏实战 06:广告与商业化接入(激励视频、插屏与收益归因)

路线阶段:Unity WebGL 小游戏实战第 6 章。
本章目标:建立可控商业化系统,而不是“哪里能插广告就硬插”。

学习目标

完成本章后,你应该能做到:

  1. 划分激励广告与插屏广告的使用场景。
  2. 设计广告频控、冷却和保护规则,避免体验崩坏。
  3. 建立奖励发放幂等机制,防止重复领奖。
  4. 记录收益归因事件,支持后续优化决策。

商业化基础策略

建议先做两条线:

  1. 激励广告(Rewarded):玩家主动触发,获得明确收益。
  2. 插屏广告(Interstitial):关卡结束或返回菜单时触发,需低频。

首版禁用:

  1. 战斗进行中强插。
  2. 高频弹窗诱导观看。

广告接口抽象

public enum AdType
{
    Rewarded = 0,
    Interstitial = 1
}

public interface IAdService
{
    void Initialize();
    bool IsReady(AdType type);

    void ShowRewarded(string placement, Action<AdResult> onDone);
    void ShowInterstitial(string placement, Action<AdResult> onDone);
}

public struct AdResult
{
    public bool Success;
    public bool RewardGranted;
    public string Placement;
    public string Error;
}

触发策略

激励广告触发点

  1. 失败后“复活一次”。
  2. 结算页“双倍奖励”。
  3. 每日商店“免费一次刷新”。

插屏广告触发点

  1. 关卡结束返回菜单。
  2. 连续游玩多局后的自然间隙。

频控与冷却

public sealed class AdFrequencyGuard
{
    private float _lastInterstitialTime;
    private int _interstitialToday;

    public bool CanShowInterstitial(float now)
    {
        if (_interstitialToday >= 8) return false;
        if (now - _lastInterstitialTime < 90f) return false;
        return true;
    }

    public void MarkInterstitial(float now)
    {
        _lastInterstitialTime = now;
        _interstitialToday++;
    }
}

激励奖励幂等

关键:玩家观看成功后奖励只能发一次。

public sealed class RewardGrantService
{
    private readonly HashSet<string> _grantedTokens = new HashSet<string>();

    public bool TryGrant(string token, Action grantAction)
    {
        if (string.IsNullOrEmpty(token)) return false;
        if (_grantedTokens.Contains(token)) return false;

        _grantedTokens.Add(token);
        if (grantAction != null) grantAction();
        return true;
    }
}

Token 可由:sessionId + placement + adImpressionId 组成。

商业化控制器

public sealed class AdFlowController
{
    private readonly IAdService _ads;
    private readonly EconomyService _economy;
    private readonly RewardGrantService _grant;
    private readonly EventBus _eventBus;

    public AdFlowController(IAdService ads, EconomyService economy, RewardGrantService grant, EventBus eventBus)
    {
        _ads = ads;
        _economy = economy;
        _grant = grant;
        _eventBus = eventBus;
    }

    public void TryShowDoubleReward(int baseReward, string sessionId)
    {
        const string placement = "result_double";

        if (!_ads.IsReady(AdType.Rewarded))
        {
            _eventBus.Publish("AdUnavailable", placement);
            return;
        }

        _ads.ShowRewarded(placement, delegate(AdResult res)
        {
            _eventBus.Publish("AdFinished", res);

            if (!res.Success || !res.RewardGranted)
            {
                return;
            }

            var token = sessionId + "|" + placement;
            var ok = _grant.TryGrant(token, delegate
            {
                _economy.Add(CurrencyType.MetaCrystal, baseReward, "ad_double_reward");
            });

            if (ok)
            {
                FoundationLog.Info("Ad", "reward_granted placement=" + placement + " amount=" + baseReward);
            }
        });
    }
}

归因事件

至少记录:

  1. ad_impression
  2. ad_click
  3. ad_complete
  4. reward_granted
public struct AdTelemetryEvent
{
    public string Name;
    public string Placement;
    public string AdNetwork;
    public string SessionId;
    public int StageId;
    public long Ts;
}

AB 测试预留

示例实验:

  1. A组:失败后展示复活广告。
  2. B组:结算后展示双倍广告。

对比指标:

  1. 次日留存
  2. 平均局时长
  3. 广告完播率
  4. ARPDAU

WebGL 接入注意点

  1. 广告 SDK 回调可能从 JS 层异步回 Unity,需要主线程桥接。
  2. 页面失焦或弹窗拦截会影响回调时序。
  3. 广告失败要有兜底(直接关闭弹窗,不阻塞流程)。

与前面系统联动

  1. 流程状态机:广告播放期间进入 AdOverlay 输入门控。
  2. 经济系统:奖励发放统一走货币服务。
  3. 存档系统:记录当日广告次数与奖励领取状态。
  4. 回放系统:仅记录奖励发放结果,不回放广告播放本身。

验收清单

  1. 激励广告成功后奖励发放准确且不重复。
  2. 插屏广告遵守频控,不在战斗中弹出。
  3. 广告失败不会卡住流程。
  4. 关键归因事件可在日志中追踪。

常见坑

坑 1:把奖励发放放在“点击观看”时

应以“广告回调成功且完播”作为唯一条件。

坑 2:缺少频控

短期收益上升,长期留存下降。

坑 3:广告回调直接改 UI 与状态

应通过事件总线中转,避免并发时序问题。

本月作业

实现“失败复活激励广告”完整链路:

  1. 每局最多复活一次。
  2. 广告成功后玩家原地半血复活并短暂无敌。
  3. 回放与日志能区分自然通关与广告复活通关。

下一章进入 Unity WebGL 小游戏实战 07:运营活动系统(限时任务、签到与版本活动开关)。