云适配能力收藏我的收藏
收藏
我的收藏云适配能力是一组独立的工具类集合,用于帮助开发者适配云启动环境。
API清单
API 入口 | 接入API | 返回 或 回调 | 功能 | 必须接入 | 建议 |
云游戏适配: | |||||
ILiveCloudGameAPI 云启动云游戏 (接口的实例通过 LiveOpenSdk.CloudGameApi 属性获取) | IsCloudGame() | bool | 是否是云启动 | ×否 | 不需要做任何手动执行。平台上发布exe玩法包版本,已自动支持云启动、自动适配。 仅用于可针对云启动做差异实现。 |
IsStartFromMobile() | bool | 是否是从手机端启动 | ×否 | ||
TryInitFullScreen() | 平台已支持云启动、自动适配。 最新版本已不需要手动调用。 | ||||
CloudGameInput 兼容适配云游戏输入。 对齐PC端Input风格 | IsTouchMode | bool | 否处于触摸模式 | 可选 | |
| Input.GetMouseButtonDown Input.GetMouseButtonUp Input.mousePosition | bool bool Vector3 | 兼容支持云游戏的:
详见Sample目录中 Camera3DObjectClick.cs - Sample演示3D物体点击
* CameraDragMove.cs - Sample演示镜头操作:拖拽移动 | 可选 | 替换开发者原有的Input后,开发者可以保持原Mouse输入代码,无需另写Touch输入代码) |
| Input.GetAxis("Mouse ScrollWheel") Input.mouseScrollDelta Input.mouseScrollDelta.y | float Vector2 float | 兼容支持云游戏的:
* CameraZoomInOut.cs - Sample演示镜头操作:缩放 | 可选 | 同上 |
| Input.touches Input.GetFingerTouch | Touch[] Touch | 兼容了手指触摸信息 | 可选 | 仅当"IsTouchMode"为true、表示是触摸模式时有有效返回 |
CloudGameEventSystem 兼容适配云游戏EventSystem | EventSystem.current | CloudGameEventSystem | 兼容了current EventSystem | 可选 | |
| IsPointerOverGameObject() | bool | 是否点击在UI上 | 可选 | 通常配合Input的点击、拖拽,判断输入信息一起使用 |
云启动云游戏
提示:
- •不需要做任何手动执行。平台上发布 exe 玩法包版本,已自动支持云启动、自动适配。
- •仅用于可针对云启动做差异实现。
相关接口、仅用于可针对云启动做差异实现:ILiveCloudGameAPI (Runtime/API/ILiveCloudGameAPI.cs)
/// <summary> /// 云启动云游戏API /// </summary> /// <remarks>会自动读取解析云启动参数。参考 https://developer.open-douyin.com/docs/resource/zh-CN/interaction/jierushuoming/pingtaijichu/cloud#0bf5266e</remarks> public interface ILiveCloudGameAPI { /// <summary> /// 是否是云启动。 /// </summary> /// <remarks>会读取云启动参数,参考 https://developer.open-douyin.com/docs/resource/zh-CN/interaction/jierushuoming/pingtaijichu/cloud#0bf5266e</remarks> bool IsCloudGame(); /// <summary> /// 是否是从手机端启动(手机抖音开播小玩法)。如果是PC伴侣开播,返回`false` /// </summary> /// <remarks>会读取云启动参数,参考 https://developer.open-douyin.com/docs/resource/zh-CN/interaction/jierushuoming/pingtaijichu/cloud#0bf5266e</remarks> bool IsStartFromMobile(); /// <summary> /// 尝试初始化全屏,自动适配云游戏设备的分辨率。 如果不是云启动云开播,不会产生影响。 /// </summary> void TryInitFullScreen(); }
兼容适配云游戏输入
- •按上文“接入方式”,替换开发者原有的Input后,开发者可以保持原Mouse输入代码,无需另写Touch输入代码。
- •实现以下sample功能。
接入方式
- •接入方式1:在使用到Input的相关代码顶部,添加:
using Input = Douyin.LivePlay.SDK.CloudGameInput; using EventSystem = Douyin.LivePlay.SDK.CloudGameEventSystem;
- •接入方式2:使用到 UnityEngine.Input 的相关代码的
Input.xxx
、EventSystem
,手动替换为CloudGameInput.xxx
、CloudGameEventSystem
1. Input 把: if (Input.GetMouseButtonDown(0)) =>替换为: if (CloudGameInput.GetMouseButtonDown(0)) 2. EventSystem 把: EventSystem.current; EventSystem.current.IsPointerOverGameObject() =>替换为: CloudGameEventSystem.current; CloudGameEventSystem.current.IsPointerOverGameObject()
示例Sample代码
参见:
- •com.bytedance.liveopensdk/Samples/SampleInputControl/Camera3DObjectClick.cs - Sample演示3D物体点击
- •com.bytedance.liveopensdk/Samples/SampleInputControl/CameraDragMove.cs - Sample演示镜头操作:拖拽移动
- •com.bytedance.liveopensdk/Samples/SampleInputControl/CameraZoomInOut.cs - Sample演示镜头操作:缩放
💡注:这些Sample中的MonoBehaviour,都可直接用于挂载添加到你自己工程中的GameObject上
手指点击适配
- •💡手指触摸点击,适配到Mouse点击
详见Sample目录中
Camera3DObjectClick.cs
- Sample演示3D物体点击public class Camera3DObjectClick : MonoBehaviour; private void UpdateMouseButton() { // Check for button down if (Input.GetMouseButtonDown(0)) { // Skip if it is on GUI var eventSystem = EventSystem.current; if (eventSystem != null && eventSystem.IsPointerOverGameObject()) { ShowToast("点击了: UI"); return; } _isClicked = true; _clickedObject = GetClickedObject(Camera); var go = _clickedObject; if (go != null) ShowToast($"点击到了: {go.name}"); else ShowToast("点击了: 场景"); } // Check for button up if (_isClicked && Input.GetMouseButtonUp(0)) { _isClicked = false; var go = _clickedObject; if (go != null) ShowToast($"点击松开了: {go.name}"); else ShowToast("松开了: 场景"); } }
拖拽移动适配
- •💡单指拖拽,适配到Mouse左键拖拽
详见Sample目录中
CameraDragMove.cs
- Sample演示镜头操作:拖拽移动/// <summary> /// Sample演示镜头操作:拖拽移动 /// </summary> public class CameraDragMove : MonoBehaviour; void Update() { // Check for button down if (Input.GetMouseButtonDown(0)) { // Skip if it is on GUI var eventSystem = EventSystem.current; if (eventSystem != null && eventSystem.IsPointerOverGameObject()) { return; } var mousePosition = Input.mousePosition; if (IsPositionZero(mousePosition)) // 部分设备会在点击开始或结束一刻、偶现坐标0,0异常信息,需要排除 { Debug.Log("拖拽 Down 排除: 坐标0,0异常信息"); return; } _isDragging = true; _dragFromPosition = mousePosition; Debug.Log("拖拽 Down 开始"); } // Deactivate dragging when button up if (_isDragging && Input.GetMouseButtonUp(0)) { _isDragging = false; if (_isMoved) { _isMoved = false; ShowToast("拖拽移动结束"); } else { ShowToast("拖拽结束: 移动距离不足"); } } var targetTransform = CameraTransform; if (targetTransform == null) return; // Move the camera while the left mouse button is held down var held = Input.GetMouseButton(0); if (_isDragging && held) { var mousePosition = Input.mousePosition; if (IsPositionZero(mousePosition)) // 部分设备会在点击开始或结束一刻、偶现坐标0,0异常信息,需要排除 { Debug.Log("拖拽 held 排除: 坐标0,0异常信息"); return; } Vector3 screenDelta = mousePosition - _dragFromPosition; var delta = screenDelta.magnitude; var threshold = MoveDeltaThreshold; if (delta < threshold) return; if (!_isMoved) { threshold = MoveStartThreshold; if (delta < threshold) return; _isMoved = true; ShowToast($"拖拽开始: from {{ {_dragFromPosition.x:F1}, {_dragFromPosition.y:F1} }} (move: {delta:F2})"); } // apply transform position var speed = CameraSpeedFactor * _screenToCameraInternalFactor; speed = Mathf.Clamp(speed, 0.0001f, 100f); var positionOffset = new Vector3( -screenDelta.x * speed, 0, -screenDelta.y * speed ); targetTransform.position += positionOffset; _dragFromPosition = mousePosition; ShowToast($"拖拽移动了: {{ {screenDelta.x:F1}, {screenDelta.y:F1} }} (move: {delta:F2})"); } }
双指缩放适配
- •💡双指缩放,适配到PC滚轮
详见Sample目录中
CameraZoomInOut.cs
- Sample演示镜头操作:缩放/// <summary> /// Sample演示镜头操作:缩放 /// </summary> public class CameraZoomInOut : MonoBehaviour; public float GetMouseScrollDelta() { if (IsMouseScrollAxisMode) return Input.GetAxis("Mouse ScrollWheel") * _axisToScrollInternalFactor; else return Input.mouseScrollDelta.y; } void Update() { var scrollValueInput = GetMouseScrollDelta(); if (Mathf.Abs(scrollValueInput) > _scrollStepMaxValue) scrollValueInput = Mathf.Clamp(scrollValueInput, -_scrollStepMaxValue, _scrollStepMaxValue); _scrollValueAccumulate += scrollValueInput; // avoid problem if the wheel input values are frequent but very small LogDebugTouchInfo(); LogDebugScrollInfo(); if (IsFloatEqual(_scrollValueAccumulate, 0)) return; var scrollValue = _scrollValueAccumulate; // reset accumulated _scrollValueAccumulate = 0; // Skip if it is on GUI var eventSystem = EventSystem.current; if (eventSystem != null && eventSystem.IsPointerOverGameObject()) return; var targetTransform = CameraTransform; if (targetTransform == null) return; // Zoom the camera based on mouse scroll input var speed = ZoomSpeedFactor * _internalFactor; Vector3 offsetPosition; switch (zoomType) { case ZoomType.AxisY: offsetPosition = Vector3.down * scrollValue * speed; break; case ZoomType.AxisZ: offsetPosition = Vector3.forward * scrollValue * speed; break; default: case ZoomType.Forward: offsetPosition = targetTransform.forward * scrollValue * speed; break; } var prevPosition = targetTransform.position; var position = prevPosition + offsetPosition; if (position.y < ZoomCameraMinY) { var y0 = prevPosition.y; var y1 = position.y; var yt = ZoomCameraMinY; var ratio = Mathf.Abs(yt - y0) / Mathf.Abs(y1 - y0); position = Vector3.Lerp(prevPosition, position, ratio); if (y0 < yt) { // reset back ratio = (yt - y0) / (y1 - y0); position = Vector3.LerpUnclamped(prevPosition, position, ratio); } } targetTransform.position = position; ShowToast($"缩放滚动了: {scrollValue:F3}"); }