抖音开放平台Logo
开发者文档
控制台

直播玩法移动端适配提示

收藏
我的收藏
修改记录
时间
文档信息/修改点
2024.7.04
创建文档
2024.7.26
更新准入规则,明确移动端要求

为什么要适配移动端?

抖音直播生态下,移动端主播的数量数倍于伴侣主播的数量,移动端汇聚了更多样化的直播内容!
完成移动端适配有利于帮助玩法拓展当前的开播场景,获得更多主播的关注,助力玩法流水的提升!
平台建议已有玩法在线的开发者尽快完成适配,以便支持更多主播能够参与进来,同时,也期待大家开发更适合移动端的玩法,开拓新的直播内容,扩大收益规模🎉

开放时间

    2024年8月1日,正式对外开放移动端开播功能
    在正式对外开放之前,移动端会上线一款《顶哪个羊》的主播可匹配&操作的玩法,期望为各位开发者进行开播链路、移动端操作等平台体验向的功能进行试点打样,帮助开发者了解移动端情况,建立对移动端玩法的认知
限时周期:2024年7月11日-2024年7月28日

适配对象

    有移动端上线诉求的开发者,需要完成伴侣与移动端的双端适配

准入规则

    1.申请上架移动端
    在直播玩法后台开启【玩法云启动能力】;
    上传审核版本时,在【玩法是否上架移动端】中选择【是】,通过审核并发布上线后可上架移动端。
    2.玩法适配要求
需要完成移动端适配和改造,玩法操作要符合移动端操作习惯,推荐使用触控操作代替键盘操作。
    3.玩法可理解要求
    移动端玩法需相对简单好理解。
    2.2需要接入移动端新主播引导能力,对主播做好引导。
    3.3需要有贴纸介绍玩法操作和礼物对应功能。
    4.玩法性能要求
确保玩法在移动端实际体验中能够在8s内打开,画质不低于1080p,30帧

适配流程

核心目的:移动端主播能够正常开播和使用玩法
具体流程
    1.能力接入
    根据云启动接入指引接入并上传云包体,如不接入或不上传,移动端将不被下发
    开发者需要根据平台返回的接口,进行云启动包体在伴侣端/移动端开启的判断,并适配差异化的操作交互设计
    在原先伴侣端操作方式到基础上,额外增加移动端操作方式(包括但不限于镜头切换、镜头锁定、设置等)
    云端分辨率当前支持三种比例 ,在后续上传包体时可以选择包体展示比例,开发者可以以其中一个比例定制支持和验证(移动端+伴侣端通用)
    3:4(推荐使用 1080x1440)
    9:16(推荐使用 1080x1920)
    1:2(推荐使用 1080x2160)
    由于移动端不具备贴纸功能,玩法需将礼物&互动说明展示在玩法内,保证用户送礼、评论、点赞等行为正常生效
    2.包体测试
    完成适配后可在直播玩法后台 - 版本管理 - 调试版本进行测试,确保玩法能正常启动、流程可正常运行。

适配方式

由于目前移动端不具备键盘鼠标,玩法侧在接入云启动后,需要调整启动UI和手势支持来适配移动端,手势适配可参考以下内容
API
在 PC 上操作时,接口的表现
通过移动端接入时,接口的表现
Input.touchSupported
返回 false
返回 true
Input.touchCount
返回 0
返回 按下手指的数量
Input.touches
空数组
返回 按下手指对应的 Touch 结构体数组
Input.mousePosition
返回鼠标位置,屏幕空间
返回手指位置,屏幕空间
多指触控情况下,返回中心位置
Input.GetMouseButtonDown(0)
鼠标左键按下时返回 true
手指按下时返回 true
Input.GetMouseButtonUp(0)
鼠标左键抬起时返回 true
手指抬起时返回 true
Input.GetMouseButton(0)
鼠标左键持续按下时返回 true
手指持续按下时返回 true
Input.GetAxis("Mouse X")
返回鼠标移动距离
返回值与手指移动距离不匹配
点击拖拽能力
代码参考:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; //安卓 PC都好用 点击物体移动 /// <summary> /// 物体上要有collider /// 场景中要存在EventSystem /// </summary> [RequireComponent(typeof(RectTransform))] public class EventClick : MonoBehaviour, IPointerClickHandler { public Text text; private bool isDrag = false; //偏移量 private Vector3 offset = Vector3.zero; public void OnPointerClick(PointerEventData eventData) { text.text="点到我啦!!!"; } IEnumerator OnMouseDown() { //将物体由世界坐标系转化为屏幕坐标系,由vector3 结构体变量ScreenSpace存储,以用来明确屏幕坐标系Z轴的位置 Vector3 ScreenSpace = Camera.main.WorldToScreenPoint(transform.position); //完成了两个步骤,1由于鼠标的坐标系是2维的,需要转化成3维的世界坐标系,2只有三维的情况下才能来计算鼠标位置与物体的距离,offset即是距离 Vector3 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, ScreenSpace.z)); Debug.Log("down"); //当鼠标左键按下时 while (Input.GetMouseButton(0)) { //得到现在鼠标的2维坐标系位置 Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, ScreenSpace.z); //将当前鼠标的2维位置转化成三维的位置,再加上鼠标的移动量 Vector3 CurPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset; //CurPosition就是物体应该的移动向量赋给transform的position属性 transform.position = CurPosition; yield return new WaitForFixedUpdate(); } } }
双指放大缩放旋转物体
代码参考:
using System.Collections; using System.Collections.Generic; using UnityEngine; public enum FingerIE { zero, OneFinger, TwoFinger, } public class Demo : MonoBehaviour { public Vector3 initialRot; public Vector3 initialSca; public static Demo instance; IEnumerator ie; FingerIE finger_num = FingerIE.zero; void Awake() { instance = this; } // Update is called once per frame void Update() { if (Input.touchCount == 0) { if (finger_num != FingerIE.zero) { StopCoroutine(ie); ie = null; finger_num = FingerIE.zero; } } else if (Input.touchCount == 1) { if (finger_num != FingerIE.OneFinger) { if (ie != null) { StopCoroutine(ie); } ie = IMonitorMouseOneFinger(); StartCoroutine(ie); finger_num = FingerIE.OneFinger; } } else if (Input.touchCount == 2) { if (finger_num != FingerIE.TwoFinger) { if (ie != null) { StopCoroutine(ie); } ie = IIMonitorMouseTwoFinger(); StartCoroutine(ie); finger_num = FingerIE.TwoFinger; } } } /// <summary> /// 一根手指控制转动 /// </summary> /// <returns></returns> IEnumerator IMonitorMouseOneFinger() { //单手操作 Touch oneFingerTouch; while (true) { oneFingerTouch = Input.GetTouch(0); if (oneFingerTouch.phase == TouchPhase.Moved) { Vector2 deltaPos = oneFingerTouch.deltaPosition; transform.Rotate(-Vector3.up * deltaPos.x * 0.2f, Space.World); transform.Rotate(-Vector3.left * deltaPos.y * 0.2f, Space.World); } yield return 0; } } /// <summary> /// 两个手指控制缩放 /// </summary> /// <returns></returns> IEnumerator IIMonitorMouseTwoFinger() { Touch firstOldTouch; Touch secondOldTouch; Touch firstNewTouch; Touch secondNewTouch; float oldDistance; float newDistance; while (true) { firstOldTouch = Input.GetTouch(0); secondOldTouch = Input.GetTouch(1); oldDistance = Vector2.Distance(firstOldTouch.position, secondOldTouch.position); yield return 0; firstNewTouch = Input.GetTouch(0); secondNewTouch = Input.GetTouch(1); newDistance = Vector2.Distance(firstNewTouch.position, secondNewTouch.position); if (oldDistance > newDistance && this.transform.localScale.x > 0.25f) { this.transform.localScale -= Vector3.one * 0.1f; } else if (oldDistance < newDistance && this.transform.localScale.x < 2f) { this.transform.localScale += Vector3.one * 0.1f; } } } /// <summary> /// 复位 /// </summary> public void ResetRot() { this.transform.localEulerAngles = initialRot; this.transform.localScale = initialSca; } }

其他优化建议

    1.建议玩法加载时间优化至8s内可进入,避免包体存在加载时间长/黑屏等问题,导致主播开启失败或等待中途退出
    2.做好移动端性能优化,尽量避免出现卡顿问题,影响主播直播体验,最低设备可参考:
    a.IOS:12pro 起
    b.安卓:近两年新购价格>2500元