主题
Skip to content 
说明
该模块是调用广告的接口的说明,本 SDK 提供了以下几种广告形式
1. Banner(横幅)广告
2. 插屏广告
3. 激励视频广告
接口
Banner 广告
广告接口的核心代码在 ZMYSDKManager
,除了接口外,还有几种对应的回调。
可以参考示例中的内容,来集成广告模块
1. 展示 Banner 广告
C#
//展示位置 pos: 1-Bottom 2-Top
ZMYSDKManager.I.Sdk.ShowBannerStatic(pos);
C#
public void ShowBanner(ToggleGroup group)
{
Toggle active = group.ActiveToggles().FirstOrDefault();
int pos = 1;
switch (active.transform.name)
{
case "1":
pos = 1; break;
case "2":
pos = 2; break;
}
ZMYSDKManager.I.Sdk.ShowBannerStatic(pos);
}
2. 隐藏 Banenr 广告
C#
ZMYSDKManager.I.Sdk.HideBannerStatic();
C#
public void HideBanner()
{
ZMYSDKManager.I.Sdk.HideBannerStatic();
}
3. Banner 点击回调
C#
// 事件
ZMYSDKManager.I.Ads_BannerClick
C#
void Start()
{
ZMYSDKManager.I.Ads_BannerClick += ClickBanner;
}
void OnDestroy()
{
ZMYSDKManager.I.Ads_BannerClick -= ClickBanner;
}
void ClickBanner()
{
Debug.Log("Banner被点击");
}
广告接口的核心代码在 GameHelper.AdsModule
,除了接口外,还有几种对应的回调。
接口
1. 展示 banner
TypeScript
/**
* 显示Banner广告
* @param pos: 1-Bottom 2-Top
*/
public showBannerStatic(pos : number = 1, opts?: {clickCallback? : () => void}) {}
2. 隐藏 banner
TypeScript
/**
* 隐藏Banner广告
*/
public hideBannerStatic() {}
插屏 广告
1. 插屏是否准备好了
C#
/// <param name="InterstType">0 游戏结束页弹出插屏,1 游戏内弹出插屏</param>
ZMYSDKManager.I.IsInterstitialReadyStatic(InterstType)
C#
public bool ClickCheckInterstitialIsReady(string InterstType)
{
return ZMYSDKManager.I.IsInterstitialReadyStatic(InterstType) ? true : false;
}
2. 展示插屏
C#
/// <param name="insertName">插屏标记位,必填不可传空</param>
/// <param name="insertType">0 游戏结束页弹出插屏,1 游戏内弹出插屏</param>
ZMYSDKManager.I.ShowInterstitial(insertName, "0");
C#
public void ClickInterstitialShow()
{
string insertName = "Interstitial_01";
ZMYSDKManager.I.ShowInterstitial(insertName, "0");
}
3. 插屏展示回调和关闭回调
C#
// 监听
ZMYSDKManager.I.Ads_InterstitialShow
ZMYSDKManager.I.Ads_InterstitialClose
C#
void Start()
{
ZMYSDKManager.I.Ads_InterstitialShow += InterstitialShow;
ZMYSDKManager.I.Ads_InterstitialClose += InterstitialClose;
}
void OnDestroy()
{
ZMYSDKManager.I.Ads_InterstitialShow -= InterstitialShow;
ZMYSDKManager.I.Ads_InterstitialClose -= InterstitialClose;
}
// 插屏广告展示回调有两种状态:1展示成功,0展示失败
void InterstitialShow(int result)
{
Debug.Log("触发插屏展示回调");
}
void InterstitialClose()
{
Debug.Log("触发插屏关闭回调");
}
1、展示插屏广告
无需判断是否准备好,直接调用即可,在有填充的情况下会展示,无填充的情况则不展示,回调通过 show fail close返回
TypeScript
/**
* 调用插屏展示【静态方法,用于Jni调用】
* 插屏的fail close回调是百分百准确的 show不保证百分百准确
* @param name 游戏名 内部做统计用
* @param insertName 插屏名
* @param type 0游戏结束插屏,1游戏内插屏
*/
public showInterstitialStatic(obj? : {name? : string, insertName? : string, type? : string, show? : Function, fail? : Function ,close? : Function}) {}
激励视频
TIP
开始播放视频广告时,暂停游戏背景音乐
WARNING
💡 视频未填充时,提示文本为:视频未拉取到,请稍后再试
💡 视频中途退出 提示文本为:视频未完整播放
TIP
💡 最推荐的方式!
- 组件式激励视频
激励视频由于涉及到的功能比较多,所以单独封装了激励视频模块:VideoButton

使用方法
将 VideoButton 挂载到任意对象上
设置按钮点击回调,触发
VideoButton.PlayVideo
设置对应的
BtnShowType
、VideFlag
、m_ReportLable
、m_Video_param1
、m_Video_param2
设置对应的回调接受方法:
m_btnOnClick
和m_videoPlayCallBack
完成以上设置即可使用激励视频功能,并且会自动进行激励视频相关上报
💡 以上步骤既可以在 Inspector 面板进行,也可以代码动态赋值
激励视频类型
C#
/// 视频显示类型
public enum BtnShowType
{
/// 条件视频按钮,只有当条件准备好了后 才显示视频按钮
Condition,
/// 单次视频按钮。视频按钮创建后,只能播放单次视频
SingleShow,
/// 多次视频按钮 视频按钮创建后,能够重复点击播放
MultipleShow,
}
激励视频标志位 Flag
C#
/// 激励视频标志位
public enum VideFlag
{
/// 视频送道具
Flag1 = 0,
/// 视频复活
Flag2 = 1,
/// 视频解释玩法/功能
Flag3 = 2,
}
可以自定义的 3 个上报参数
Video_name
:激励视频名称
Video_param1
:自定义参数 1
Video_param2
:自定义参数 2
激励视频回调
回调都为VideoButton中的公开事件
点击回调:m_btnOnClick
只要点击激励视频按钮就会触发,回调 bool 值表示当前激励视频能否播放
播放完成回调:m_videoPlayCallBack
激励视频播放完成后回调,回调 bool 值表示激励视频是否完成播放,
true:完成播放,可以发放奖励 flase:未正常完成播放,不给予奖励
WARNING
💡 用这种方式也可以
动态绑定 组件式激励视频
如果已经写了视频按钮组件,不方便替换成组件式视频按钮,也可以使用绑定的方式来实现
C#
public void ShowRewardVideo_ByComponent(GameObject btn_go,Action<bool> callBack)
{
VideoButton videoButton = btn_go.GetComponent<VideoButton>();
if (videoButton == null)
{
videoButton = btn_go.AddComponent<VideoButton>();
}
videoButton.Video_name = "test";
//添加视频的回调
videoButton.m_videoPlayCallBack = new UnityEngine.Events.UnityEvent<bool>();
videoButton.m_videoPlayCallBack.AddListener((bool success)=>
{
callBack(success);
});
bool IsReady = ZMYSDKManager.I.IsVideoReady();
videoButton.SetButtonState(IsReady ? BtnState.Active : BtnState.ActiveNotClick);
//播放视频
videoButton.PlayVideo();
}
调用
C#
GameObject btn_go = GetComponent<Button>().gameObject;
ShowRewardVideo_ByComponent(btn_go,VideoCallBack);
API 接入激励视频
DANGER
💡 如果上述两种方式都不方便接入,我们也提供了单独接入各个功能的接口,只不过这种方式需要手动进行广告状态的上报,很复杂
视频是否准备好
C#
/// 视频是否准备好了
ZMYSDKManager.I.IsVideoReady();
显示激励视频
C#
ZMYSDKManager.I.ShowVide(m_flag, VideoCallBack);
激励视频状态变化事件
status:0:不显示,1:显示,置灰,不可点 ,2:显示,点亮,可点击
C#
MsgDispatcher.AddEventListener(GlobalEventType.VideoButtonStatus, VideoButtonStatus);
// 事件记得在合适的时机移除
MsgDispatcher.RemoveEventListener(GlobalEventType.VideoButtonStatus, VideoButtonStatus);
TrackVideo 和点击上报
C#
///点击视频按钮时
ReportManager.I.TrackVideo(1);
ReportManager.I.NewReportVideoClick(string video_name, string video_param1, string video_param2)
播放上报
C#
ReportManager.I.NewReportVideoPlay(string video_name, string video_param1, string video_param2);
播放成功上报
C#
ReportManager.I.NewReportVideoSuccess(string video_name, string video_param1, string video_param2);
播放失败上报
C#
ReportManager.I.NewReportVideoFail(string video_name, string video_param1, string video_param2);
参考VideoButton代码逻辑
C#
using System.Collections;
using System.Collections.Generic;
using ZMYSDK;
using ZMYSDK.Report;
using ZMYSDK.Util.Event;
using ZMYSDK.Util.Lang;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
[DisallowMultipleComponent]
public class VideoButton : MonoBehaviour
{
[SerializeField]
private BtnShowType m_btnType = BtnShowType.SingleShow;
[SerializeField]
private VideFlag m_flag;
public UnityEvent<bool> m_videoPlayCallBack;
public UnityEvent<bool> m_btnOnClick;
/// <summary>按钮的三种状态</summary>
private BtnState btnstate { get; set; }
BtnReportState btnReportState = BtnReportState.None;
/*===========上报相关的三个参数=============*/
[SerializeField]
private string m_Video_name;
[SerializeField]
private string m_Video_param1;
[SerializeField]
private string m_Video_param2;
#region 对外属性
public BtnShowType BtnType
{
get { return m_btnType; }
set { m_btnType = value; }
}
public VideFlag Flag
{
get { return m_flag; }
set { m_flag = value; }
}
public string Video_name
{
get { return m_Video_name; }
set { m_Video_name = value; }
}
public string Video_param1
{
get { return m_Video_param1; }
set { m_Video_param1 = value; }
}
public string Video_param2
{
get { return m_Video_param2; }
set { m_Video_param2 = value; }
}
#endregion
/// 自动上报视频加载时上报 </summary>
public bool AutoCallBtnShow = true;
void Awake()
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlaying)
return;
#endif
if (m_btnType == BtnShowType.Condition)
{
gameObject.SetActive(false);
}
}
void Start()
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlaying)
return;
#endif
MsgDispatcher.AddEventListener(GlobalEventType.VideoButtonStatus, VideoButtonStatus);
//条件视频按钮不走这条逻辑
if (m_btnType == BtnShowType.Condition)
return;
bool IsReady = ZMYSDKManager.I.IsVideoReady();
SetButtonState(IsReady ? BtnState.Active : BtnState.ActiveNotClick);
}
/// <summary>
/// 由于打开UI默认隐藏,导致OnEnable会调用2次。所以对OnEnable进行0.5s的间隔判断
/// </summary>
private float OnEnableWeekTime;
void OnEnable()
{
if (Time.time < OnEnableWeekTime)
{
Debug.Log("激励视频多次激活,CD未好");
return;
}
OnEnableWeekTime = Time.time + 0.5f;
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlaying)
return;
#endif
//视频上报
if (AutoCallBtnShow)
VideoBtnShow(true);
if (m_btnType == BtnShowType.Condition)
return;
//过1S后上报创建
StartCoroutine(DelayReport(1));
}
private bool isDestroy = false;
protected void OnDestroy()
{
isDestroy = true;
m_videoPlayCallBack = null;
m_btnOnClick = null;
MsgDispatcher.RemoveEventListener(GlobalEventType.VideoButtonStatus, VideoButtonStatus);
}
private void Update()
{
CheckClickVideoBtnCD();
}
#region 基础的按钮点击事件
const int PLAYVIDEOCD = 5;
const int CLICKBTNCD = 1;
static bool m_isPlayVideo = false;
static float m_PlayVideoTimer;
bool m_isClickVideo = false;
float m_ClickVideoTimer;
void CheckClickVideoBtnCD()
{
if (m_isClickVideo)
{
//开始清空点击倒计时
if (Time.unscaledTime > m_ClickVideoTimer)
m_isClickVideo = false;
}
if (m_isPlayVideo)
{
//开始清视频播放倒计时
if (Time.unscaledTime > m_PlayVideoTimer)
m_isPlayVideo = false;
}
}
/// <summary>
/// 播放视频
/// </summary>
public void PlayVideo()
{
OnClcikVideoBtn();
}
[System.Obsolete("请使用PlayVideo替代,后续版本会删除")]
public void OnClcikVideoBtn()
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlaying)
return;
#endif
if (m_isPlayVideo)//视频播放内置CD
{
Debug.Log($"目前正处于视频播放CD中:{m_PlayVideoTimer - Time.unscaledTime}");
m_btnOnClick?.Invoke(false);
return;
}
if (m_isClickVideo)//视频点击内置CD
{
Debug.Log($"目前正处于视频点击CD中{m_ClickVideoTimer - Time.unscaledTime}");
m_btnOnClick?.Invoke(false);
return;
}
//CLog.Log("点击了视频按钮");
m_isClickVideo = true;
m_ClickVideoTimer = Time.unscaledTime + CLICKBTNCD;
VideoClickReport();
m_btnOnClick?.Invoke(btnstate == BtnState.Active);
if (btnstate == BtnState.Active)
{
// CLog.Log("播放视频");
m_isPlayVideo = true;
m_PlayVideoTimer = Time.unscaledTime + PLAYVIDEOCD;
ReportManager.I.NewReportVideoPlay(m_Video_name, m_Video_param1, m_Video_param2);
ZMYSDKManager.I.ShowVide(m_flag, VideoCallBack);
}
else
{
//广告没准备好
ZMYSDKManager.I.Sdk.ShowToast(SdkLang.I.Get("sdk_noadstips"));
}
}
/// <summary>
/// 视频播放回调
/// </summary>
/// <param name="i"></param>
void VideoCallBack(bool i)
{
if (m_btnType == BtnShowType.MultipleShow)
{
btnReportState = BtnReportState.None;
if (!isDestroy && gameObject.activeSelf)
{
//过1S后重新统计上报
StartCoroutine(DelayReport(1));
}
}
if (i)
ReportManager.I.NewReportVideoSuccess(m_Video_name, m_Video_param1, m_Video_param2);
else//上报失败
ReportManager.I.NewReportVideoFail(m_Video_name, m_Video_param1, m_Video_param2);
m_videoPlayCallBack?.Invoke(i);
}
#endregion
#region 按钮状态变更
void VideoButtonStatus(object[] Args)
{
if (null == this.gameObject || isDestroy)
{
MsgDispatcher.RemoveEventListener(GlobalEventType.VideoButtonStatus, VideoButtonStatus);
return;
}
if (Args == null || Args.Length <= 0)
return;
int status = (int)Args[0];
switch (status)
{
case 0:
SetButtonState(BtnState.Hide);
break;
case 1:
SetButtonState(BtnState.ActiveNotClick);
break;
case 2:
SetButtonState(BtnState.Active);
break;
}
}
public void SetButtonState(BtnState btnState)
{
this.btnstate = btnState;
switch (btnstate)
{
case BtnState.Hide:
gameObject.SetActive(false);
break;
case BtnState.ActiveNotClick:
break;
case BtnState.Active:
//视频准备好了,检查下是否需要上报请求成功
if (btnReportState == BtnReportState.Create)
VideoIsReadyReport();
break;
default:
break;
}
}
#endregion
#region 视频的上报
/// <summary>
/// 创建上报
/// </summary>
void CreateVideoReport()
{
ReportManager.I.TrackVideo(1); btnReportState = BtnReportState.Create;
}
/// <summary>
/// 请求成功上报
/// </summary>
void VideoIsReadyReport()
{
ReportManager.I.TrackVideo(2); btnReportState = BtnReportState.Ready;
}
/// <summary>
/// 视频点击上报
/// </summary>
void VideoClickReport()
{
ReportManager.I.TrackVideo(3);
ReportManager.I.NewReportVideoClick(m_Video_name, m_Video_param1, m_Video_param2);
}
IEnumerator DelayReport(int n)
{
yield return new WaitForSeconds(n);
CreateVideoReport();
//如果视频能够播放,那么就立刻上报请求成功
if (ZMYSDKManager.I.Sdk.IsVideoReadyStatic())
{
VideoIsReadyReport();
}
}
/// <summary>
/// 视频按钮显示到屏幕上了
/// </summary>
/// <param name="IsAvailable"></param>
public void VideoBtnShow(bool IsAvailable)
{
bool IsReady = ZMYSDKManager.I.Sdk.IsVideoReadyStatic();
if (IsAvailable)
{
if (IsReady)
{
ReportManager.I.NewReportVideoShow(m_Video_name, m_Video_param1, m_Video_param2);
}
else
{
ReportManager.I.NewReportVideoNoAds(m_Video_name);
}
}
else
{
ReportManager.I.NewReportVideoUnable(m_Video_name);
}
}
#endregion
}
方案一:AdsVideoManager 视频
使用 AdsVideoManager 播放视频 就不用再自己统计以下视频相关埋点
trackVideo
ShowVideo
UnableVideo
ClickVideo
StartPlayVideo
PlayedVideoOver
PlayedVideoFail
AdsVideoManager 是封装了视频相关统计的视频管理类 使用方法如下:
首先 addVideoNode 绑定一个视频节点,这个视频节点就是你的视频按钮。第一个参数即是这个节点,第二个参数 videoName 是这个节点的“唯一标识” 注意取名要“唯一”,不能和其他视频节点冲突,第三个参数是渲染这个节点的相机组件,是 Camera 组件,如果这个节点是 UI 节点可以不传。注意每个视频节点都要绑定 如果用的预制或复制创的视频节点 一定要记得重新设置 videoName 的名字 “videoName”一定要“唯一”
然后点击(点击事件自己处理)这个视频节点时 调用 AdsVideoManager.showVideo 播放视频,注意这个方法第一个参数 videoName 和 addVideoNode 的第二个参数 videoName 要“一致”
注意:addVideoNode 要先于 showVideo 绑定,最好在当前界面的初始化就绑定好
TypeScript
/**
* 增加视频互动节点
* @param node Node
* @param videoFlag 视频的唯一标识
* @param camera 相机 2D节点可以不传 如果此节点是3d节点 需要告知渲染他的相机组件是哪一个,如果不指定 会根据layer自动搜寻
*/
addVideoNode(node, videoFlag: string, camera? : any){}
/**
* 展示广告视频
* @param videoName 视频的唯一标识 用于统计
* @param statExt 业务额外扩展需要上报的参数,可以放到 statExt 里上报
* @returns 返回值可以认为是否播放成功 true播放成功
*/
showVideo(videoName: string, opts: {
param?: any, // 想要回传参数,根据业务自己定义 非必须
statExt? : object, // 统计相关的扩展属性参数
success?: (videoName: string, param: any) => void, // 视频播放成功,给奖励的回调
fail?: (videoName: string, param: any) => void, // 视频播放失败(中途退出)
error?: (videoName: string, err: any, param: any) => void, // 视频拉取失败
}) : boolean;
//存在某些情况,一个节点同时存在不同状态,有点击播放视频,或者点击分享 等其他情况,此时要主动告诉管理器当前是否是视频状态,
//如果点击非播放视频时请设置为false
//管理器内部会做相应的点击播放视频和统计操作,如果这个节点只有视频这一种情况,此方法则不用管,内部已经默认是视频状态
setVideoStatus(videoFlag: string, isVideo: boolean);
方案二:AdsFunc 视频
AdsFunc.showVideoStatic 不建议使用,后续 AdsFunc.showVideoStatic 会被删除
关于视频广告的一些说明
- 视频广告依赖上报模块的
EnterGame
,如果带视频广告,初始化完成进游戏后,优先调用GameHelper.GameStatistics.EnterGame("GameName")
,GameName
是游戏名称,需要具体传入 - 然后再调
showVideoStatic
- 视频广告的统计说明:只有视频按钮被点击就统计
GameHelper.GameStatistics.ClickVideo("videoName");
和GameHelper.GameStatistics.trackVideo(3)
这两个事件。videoName
是视频名称,需要具体传入
TypeScript
// success 播放完给奖励 fail 中途退出 error 不支持 或没有拉取到视频
// videoName 视频点名字 每个视频点保证名字唯一
public showVideoStatic(obj : {
videoName : string,
success : (videoFlag : number, rewardTime : number) => void,
fail? : (videoFlag : number) => void,
error? : () => void
}) : boolean {}
点我快速对接


