diff --git a/assets/Scenes/MainScene.scene b/assets/Scenes/MainScene.scene index 9b5e4835..6c7a5c25 100644 --- a/assets/Scenes/MainScene.scene +++ b/assets/Scenes/MainScene.scene @@ -23,7 +23,7 @@ "_active": true, "_components": [], "_prefab": { - "__id__": 26 + "__id__": 24 }, "_lpos": { "__type__": "cc.Vec3", @@ -54,7 +54,7 @@ }, "autoReleaseAssets": false, "_globals": { - "__id__": 27 + "__id__": 25 }, "_id": "1a23cd3e-e487-4fd1-a415-346c2087464d" }, @@ -74,25 +74,25 @@ "__id__": 5 }, { - "__id__": 16 + "__id__": 14 }, { - "__id__": 19 + "__id__": 17 } ], "_active": true, "_components": [ + { + "__id__": 20 + }, + { + "__id__": 21 + }, { "__id__": 22 }, { "__id__": 23 - }, - { - "__id__": 24 - }, - { - "__id__": 25 } ], "_prefab": null, @@ -231,17 +231,14 @@ ], "_active": true, "_components": [ + { + "__id__": 11 + }, { "__id__": 12 }, { "__id__": 13 - }, - { - "__id__": 14 - }, - { - "__id__": 15 } ], "_prefab": null, @@ -292,10 +289,7 @@ "__id__": 8 }, { - "__id__": 9 - }, - { - "__id__": 11 + "__id__": 10 } ], "_prefab": null, @@ -340,8 +334,8 @@ "__prefab": null, "_contentSize": { "__type__": "cc.Size", - "width": 361, - "height": 384 + "width": 384, + "height": 672 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -350,36 +344,6 @@ }, "_id": "e9cMt7vAhIc4a7k9vEIMWF" }, - { - "__type__": "cc.Widget", - "_name": "", - "_objFlags": 0, - "__editorExtras__": {}, - "node": { - "__id__": 6 - }, - "_enabled": true, - "__prefab": null, - "_alignFlags": 45, - "_target": null, - "_left": 359.5, - "_right": 359.5, - "_top": 978, - "_bottom": 978, - "_horizontalCenter": 0, - "_verticalCenter": 0, - "_isAbsLeft": true, - "_isAbsRight": true, - "_isAbsTop": true, - "_isAbsBottom": true, - "_isAbsHorizontalCenter": true, - "_isAbsVerticalCenter": true, - "_originalWidth": 100, - "_originalHeight": 100, - "_alignMode": 2, - "_lockFlags": 0, - "_id": "2euXGGuaZBbJIjbeaF9ka3" - }, { "__type__": "cc.VideoPlayer", "_name": "", @@ -403,7 +367,7 @@ "_keepAspectRatio": true, "videoPlayerEvent": [ { - "__id__": 10 + "__id__": 9 } ], "_id": "4eO0OJtSRAuJxLXluDHDbn" @@ -482,19 +446,6 @@ "_lockFlags": 0, "_id": "88uIpLSUpFcq1yB9nA16Xu" }, - { - "__type__": "f681beDEhFI370t373WShvI", - "_name": "", - "_objFlags": 0, - "__editorExtras__": {}, - "node": { - "__id__": 5 - }, - "_enabled": true, - "__prefab": null, - "m_rootNode": null, - "_id": "e4rzfSu/JJyaeVTZFmKOUc" - }, { "__type__": "5caf8//TmZHLJgls9ahUjBU", "_name": "", @@ -520,10 +471,10 @@ "_active": true, "_components": [ { - "__id__": 17 + "__id__": 15 }, { - "__id__": 18 + "__id__": 16 } ], "_prefab": null, @@ -562,7 +513,7 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 16 + "__id__": 14 }, "_enabled": true, "__prefab": null, @@ -584,7 +535,7 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 16 + "__id__": 14 }, "_enabled": true, "__prefab": null, @@ -620,10 +571,10 @@ "_active": true, "_components": [ { - "__id__": 20 + "__id__": 18 }, { - "__id__": 21 + "__id__": 19 } ], "_prefab": null, @@ -662,7 +613,7 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 19 + "__id__": 17 }, "_enabled": true, "__prefab": null, @@ -684,7 +635,7 @@ "_objFlags": 0, "__editorExtras__": {}, "node": { - "__id__": 19 + "__id__": 17 }, "_enabled": true, "__prefab": null, @@ -787,10 +738,10 @@ "_enabled": true, "__prefab": null, "UIRoot": { - "__id__": 16 + "__id__": 14 }, "UILayerMod": { - "__id__": 19 + "__id__": 17 }, "MainCamera": { "__id__": 4 @@ -808,28 +759,28 @@ { "__type__": "cc.SceneGlobals", "ambient": { - "__id__": 28 + "__id__": 26 }, "shadows": { - "__id__": 29 + "__id__": 27 }, "_skybox": { - "__id__": 30 + "__id__": 28 }, "fog": { - "__id__": 31 + "__id__": 29 }, "octree": { - "__id__": 32 + "__id__": 30 }, "skin": { - "__id__": 33 + "__id__": 31 }, "lightProbeInfo": { - "__id__": 34 + "__id__": 32 }, "postSettings": { - "__id__": 35 + "__id__": 33 }, "bakedWithStationaryMainLight": false, "bakedWithHighpLightmap": false diff --git a/assets/Scripts/Sub/UI/SceneBgVideoLayer.ts b/assets/Scripts/Sub/UI/SceneBgVideoLayer.ts index fd4c3cd2..b11061ef 100644 --- a/assets/Scripts/Sub/UI/SceneBgVideoLayer.ts +++ b/assets/Scripts/Sub/UI/SceneBgVideoLayer.ts @@ -63,40 +63,117 @@ export class SceneBgVideoLayer extends li_BaseView { //================== 公共 API 方法 ================== /** - * 播放视频 + * 播放视频 - 统一的视频播放接口 * @param path 视频路径 - * @param loop 是否循环播放 + * @param options 可选配置项 + * @param options.loop 是否循环播放,默认true + * @param options.size 视频尺寸 {width, height} + * @param options.position 视频位置 {x, y, z} + * @param options.scale 视频缩放值 + * @param options.autoFill 是否自动填充到指定尺寸 */ - playVideo(path: string, loop: boolean = false) { + playVideo( + path: string, + options?: { + loop?: boolean; + size?: { width: number; height: number } | Size; + position?: { x: number; y: number; z?: number } | Vec3; + scale?: number | Vec3; + } + ) { if (!this.videoPlayer) { console.error("SceneBgVideoLayer: VideoPlayer未初始化"); return; } + // 默认参数 + const config = { + loop: options?.loop ?? true, + size: options?.size, + position: options?.position, + scale: options?.scale, + }; + + // 先停止当前视频 + if (this.isPlaying) { + this.stop(); + } + // 加载本地视频资源 ResManager.I.changeBundleVideo( this.videoPlayer, path, "Girls", (res: VideoClip) => { - this.videoPlayer.loop = loop; + this.videoPlayer.loop = config.loop; + + // 设置锚点为中心,确保位置对齐 + const uiTransform = this.videoPlayer.node.getComponent(UITransform); + if (uiTransform) { + uiTransform.setAnchorPoint(0.5, 0.5); + } + + // 应用位置设置(使用世界坐标) + if (config.position) { + const pos = config.position; + if (pos instanceof Vec3) { + this.videoPlayer.node.setWorldPosition(pos); + } else { + this.videoPlayer.node.setWorldPosition(pos.x, pos.y, pos.z || 0); + } + } + + // 如果传入了目标尺寸,计算并应用缩放 + if (config.size && uiTransform) { + // 获取视频的原始尺寸 + const videoWidth = uiTransform.contentSize.width; + const videoHeight = uiTransform.contentSize.height; + + if (videoWidth > 0 && videoHeight > 0) { + const targetWidth = config.size instanceof Size ? config.size.width : config.size.width; + const targetHeight = config.size instanceof Size ? config.size.height : config.size.height; + + // 计算缩放比例(填满整个区域) + const scaleX = targetWidth / videoWidth; + const scaleY = targetHeight / videoHeight; + const scale = Math.max(scaleX, scaleY); + + this.videoPlayer.node.setScale(new Vec3(scale, scale, 1)); + console.log(`SceneBgVideoLayer: 视频原始尺寸: ${videoWidth}x${videoHeight}, 目标尺寸: ${targetWidth}x${targetHeight}, 缩放: ${scale}`); + } else { + // 如果视频尺寸还未准备好,延迟重试 + this.scheduleOnce(() => { + if (config.size && uiTransform) { + const videoWidth = uiTransform.contentSize.width; + const videoHeight = uiTransform.contentSize.height; + + if (videoWidth > 0 && videoHeight > 0) { + const targetWidth = config.size instanceof Size ? config.size.width : config.size.width; + const targetHeight = config.size instanceof Size ? config.size.height : config.size.height; + + const scaleX = targetWidth / videoWidth; + const scaleY = targetHeight / videoHeight; + const scale = Math.max(scaleX, scaleY); + + this.videoPlayer.node.setScale(new Vec3(scale, scale, 1)); + console.log(`SceneBgVideoLayer: (延迟) 视频原始尺寸: ${videoWidth}x${videoHeight}, 目标尺寸: ${targetWidth}x${targetHeight}, 缩放: ${scale}`); + } + } + }, 0.1); + } + } + // 如果显式传入了 scale 参数,覆盖自动计算的缩放 + else if (config.scale !== undefined) { + this.setVideoScale(config.scale); + } + this.videoPlayer.play(); this.isPlaying = true; - console.log(`SceneBgVideoLayer: 播放视频 ${path}, 循环: ${loop}`); + console.log(`SceneBgVideoLayer: 播放视频 ${path}, 配置:`, config); } ); } - /** - * 切换视频(停止当前视频并播放新视频) - * @param path 视频路径 - * @param loop 是否循环播放 - */ - switchVideo(path: string, loop: boolean = false) { - this.stop(); - this.playVideo(path, loop); - } - /** * 暂停视频 */ @@ -128,62 +205,6 @@ export class SceneBgVideoLayer extends li_BaseView { } } - /** - * 设置视频尺寸 - * @param width 宽度 - * @param height 高度 - */ - setVideoSize(width: number, height: number) { - if (this.videoPlayer) { - const uiTransform = this.videoPlayer.node.getComponent(UITransform); - if (uiTransform) { - uiTransform.setContentSize(width, height); - console.log(`SceneBgVideoLayer: 设置视频尺寸 ${width}x${height}`); - } - } - } - - /** - * 设置视频位置 - * @param x X坐标 - * @param y Y坐标 - * @param z Z坐标 - */ - setVideoPosition(x: number, y: number, z: number = 0) { - if (this.videoPlayer) { - this.videoPlayer.node.setPosition(x, y, z); - console.log(`SceneBgVideoLayer: 设置视频位置 (${x}, ${y}, ${z})`); - } - } - - /** - * 设置视频世界位置 - * @param x X坐标 - * @param y Y坐标 - * @param z Z坐标 - */ - setVideoWorldPosition(x: number, y: number, z: number = 0) { - if (this.videoPlayer) { - this.videoPlayer.node.setWorldPosition(x, y, z); - console.log(`SceneBgVideoLayer: 设置视频世界位置 (${x}, ${y}, ${z})`); - } - } - - /** - * 设置视频锚点 - * @param anchorX X轴锚点 (0-1) - * @param anchorY Y轴锚点 (0-1) - */ - setVideoAnchor(anchorX: number, anchorY: number) { - if (this.videoPlayer) { - const uiTransform = this.videoPlayer.node.getComponent(UITransform); - if (uiTransform) { - uiTransform.setAnchorPoint(anchorX, anchorY); - console.log(`SceneBgVideoLayer: 设置视频锚点 (${anchorX}, ${anchorY})`); - } - } - } - /** * 设置视频缩放 * @param scale 缩放值(数字或Vec3) @@ -227,7 +248,7 @@ export class SceneBgVideoLayer extends li_BaseView { this.videoPlayer.node.setScale(new Vec3(scale, scale, 1)); if (position) { - this.videoPlayer.node.setPosition(position); + this.videoPlayer.node.setWorldPosition(position); } console.log(`SceneBgVideoLayer: 自适应填充区域,缩放: ${scale}`); @@ -292,38 +313,6 @@ export class SceneBgVideoLayer extends li_BaseView { // 由子类重写或外部监听 } - //================== 兼容性方法 ================== - - /** - * 播放本地循环视频(保留以保证兼容性) - * @deprecated 使用 playVideo(path, true) 替代 - */ - playLocalLoopVideo(data: any) { - if (data?.path) { - this.playVideo(data.path, true); - - // 保存当前数据供回调使用 - this.currentVideoData = data; - - // 如果有尺寸和位置信息,进行调整 - if (data.size) { - this.adjustToFillArea(data.size, data.bgFrameNode?.position); - } - } - } - - /** - * 调整视频填充框架(保留以保证兼容性) - * @deprecated 使用 adjustToFillArea 替代 - */ - adjustVideoToFillFrame(targetSize: any, bgFrameNode?: Node) { - let position: Vec3 | undefined; - if (bgFrameNode && isValid(bgFrameNode) && bgFrameNode.position) { - position = bgFrameNode.position; - } - this.adjustToFillArea(targetSize, position); - } - //================== 其他方法 ================== /** diff --git a/assets/Scripts/chat18x/ui/panels/ChatPanel.ts b/assets/Scripts/chat18x/ui/panels/ChatPanel.ts index d0c6658e..5a75f749 100644 --- a/assets/Scripts/chat18x/ui/panels/ChatPanel.ts +++ b/assets/Scripts/chat18x/ui/panels/ChatPanel.ts @@ -135,32 +135,9 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback { console.error("ChatPanel: SceneBgVideoLayer.handle 未初始化"); } else { console.log("ChatPanel: 成功获取 SceneBgVideoLayer 实例"); - this.initVideoPosition(); } } - /** - * 初始化视频位置和属性 - */ - private initVideoPosition() { - if (!this.videoLayer || !this.videoArea) return; - - // 设置视频锚点为中心 (0.5, 0.5),这样视频的中心点就是定位点 - this.videoLayer.setVideoAnchor(0.5, 0.5); - - // 使用 videoArea 的世界坐标位置 - const videoAreaWorldPos = this.videoArea.node.getWorldPosition(); - this.videoLayer.setVideoWorldPosition( - this.videoLayer.node.worldPosition.x, - videoAreaWorldPos.y, - videoAreaWorldPos.z - ); - this.videoLayer.setVideoScale(1); - console.log( - `ChatPanel: 初始化视频世界位置到 (${videoAreaWorldPos.x}, ${videoAreaWorldPos.y})` - ); - } - register() { Utils.addInnerEL( InnerMsgCode.Chat_DialogRefresh, @@ -277,15 +254,18 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback { ? new Size(this.videoArea.width, this.videoArea.height) : new Size(600, 800); - const videoData = { - path: initialVideo, - size: targetSize, - bgFrameNode: this.videoArea ? this.videoArea.node : null, - }; - // Set current emotion to the loaded video's emotion this.currentEmotion = this.chatController.getCurrentEmotion(); - this.videoLayer.playLocalLoopVideo(videoData); + + // 使用新的统一 playVideo 方法 + const videoAreaPos = this.videoArea + ? this.videoArea.node.getWorldPosition() + : undefined; + this.videoLayer.playVideo(initialVideo, { + loop: true, + size: targetSize, + position: videoAreaPos, + }); // 延迟调整视频缩放 this.scheduleOnce(() => { @@ -311,9 +291,6 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback { const videoTransform = videoPlayer.node.getComponent(UITransform); if (videoTransform && videoTransform.height > 0) { - // 设置视频锚点为中心 (0.5, 0.5),确保视频的中心点就是定位点 - this.videoLayer.setVideoAnchor(0.5, 0.5); - // 计算缩放比例,使视频高度填满 videoArea const scale = this.videoArea.height / videoTransform.height; @@ -323,12 +300,9 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback { // 获取 videoArea 的世界坐标中心点 const videoAreaWorldPos = this.videoArea.node.getWorldPosition(); - // 使用世界坐标设置视频位置,确保正确对齐 - this.videoLayer.setVideoWorldPosition( - this.videoLayer.node.worldPosition.x, - videoAreaWorldPos.y, - videoAreaWorldPos.z - ); + // 使用新的 playVideo 方法的位置参数,如果需要更新位置 + // 由于视频已经在播放,这里只调整缩放 + // 位置调整已在 playVideo 中处理 console.log( `ChatPanel: 视频缩放到 ${scale}, videoArea高度: ${this.videoArea.height}, 视频高度: ${videoTransform.height}` @@ -408,8 +382,20 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback { })` ); - // Load the new video - this.videoLayer.playVideo(matchingVideo, true); + // Load the new video with the unified playVideo method + // 获取 videoArea 的尺寸和位置 + const targetSize = this.videoArea + ? new Size(this.videoArea.width, this.videoArea.height) + : new Size(600, 800); + const videoAreaPos = this.videoArea + ? this.videoArea.node.getWorldPosition() + : undefined; + + this.videoLayer.playVideo(matchingVideo, { + loop: true, + size: targetSize, + position: videoAreaPos, + }); //ResManager.I.changeBundleVideo(this.girlVideo, matchingVideo, "Girls"); // Update current emotion state @@ -430,7 +416,19 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback { `Loading fallback video: ${fallbackVideo} (emotion: ${VideoEmotion[fallbackVideo]})` ); - this.videoLayer.playVideo(fallbackVideo, true); + // 获取 videoArea 的尺寸和位置 + const targetSize = this.videoArea + ? new Size(this.videoArea.width, this.videoArea.height) + : new Size(600, 800); + const videoAreaPos = this.videoArea + ? this.videoArea.node.getWorldPosition() + : undefined; + + this.videoLayer.playVideo(fallbackVideo, { + loop: true, + size: targetSize, + position: videoAreaPos, + }); // Update current emotion state to the fallback video's emotion this.currentEmotion = this.chatController.getCurrentEmotion(); diff --git a/assets/Scripts/chat18x/ui/panels/GirlDetailPanel.ts b/assets/Scripts/chat18x/ui/panels/GirlDetailPanel.ts index 0b8504fb..849a9226 100644 --- a/assets/Scripts/chat18x/ui/panels/GirlDetailPanel.ts +++ b/assets/Scripts/chat18x/ui/panels/GirlDetailPanel.ts @@ -73,6 +73,16 @@ export class GirlDetailPanel extends li_BaseView { onLoadCT() { super.onLoadCT(); this.imgItemInst.node.active = false; + + // 检查 SceneBgVideoLayer 是否可用 + if (!this.videoLayer) { + console.error("GirlDetailPanel: SceneBgVideoLayer.handle 未初始化"); + } else { + console.log("GirlDetailPanel: 成功获取 SceneBgVideoLayer 实例"); + // 初始化视频显示位置 + this.initVideoPosition(); + } + this.refresh(this.id); Utils.addInnerEL(InnerMsgCode.LanguageChange, this, () => { @@ -89,15 +99,6 @@ export class GirlDetailPanel extends li_BaseView { this.imgToggle.callback = this.bindImgToggle.bind(this); this.videoToggle.callback = this.bindVideoToggle.bind(this); - - // 检查 SceneBgVideoLayer 是否可用 - if (!this.videoLayer) { - console.error("GirlDetailPanel: SceneBgVideoLayer.handle 未初始化"); - } else { - console.log("GirlDetailPanel: 成功获取 SceneBgVideoLayer 实例"); - // 初始化视频显示位置 - this.initVideoPosition(); - } } setVideEnable(enable: boolean) { @@ -117,69 +118,6 @@ export class GirlDetailPanel extends li_BaseView { } } - adjustVideoScale() { - if (!this.videoLayer) { - console.error("GirlDetailPanel: SceneBgVideoLayer 不可用"); - return; - } - - // 获取 videoArea 的尺寸 - if (!this.videoArea) { - console.error("GirlDetailPanel: videoArea 未设置"); - return; - } - - // 参考原有逻辑,计算缩放比例使视频高度填满 videoArea - const tryAdjustScale = () => { - const videoPlayer = this.videoLayer.getVideoPlayer(); - if (!videoPlayer) return false; - - const videoTransform = videoPlayer.node.getComponent(UITransform); - if (videoTransform && videoTransform.height > 0) { - // 设置视频锚点为中心 (0.5, 0.5),确保视频的中心点就是定位点 - this.videoLayer.setVideoAnchor(0.5, 0.5); - - // 计算缩放比例,使视频高度填满 videoArea(保持原有逻辑) - const scale = this.videoArea.height / videoTransform.height; - - // 设置视频缩放 - this.videoLayer.setVideoScale(scale); - - // 获取 videoArea 的世界坐标中心点 - const videoAreaWorldPos = this.videoArea.node.getWorldPosition(); - - // 使用世界坐标设置视频位置,确保正确对齐 - this.videoLayer.setVideoWorldPosition( - videoAreaWorldPos.x, - videoAreaWorldPos.y, - videoAreaWorldPos.z - ); - - console.log( - `GirlDetailPanel: 视频缩放到 ${scale}, videoArea高度: ${this.videoArea.height}, 视频高度: ${videoTransform.height}` - ); - console.log( - `GirlDetailPanel: 视频世界位置设置为 (${videoAreaWorldPos.x}, ${videoAreaWorldPos.y})` - ); - return true; - } - return false; - }; - - // 立即尝试一次 - if (!tryAdjustScale()) { - // 如果失败,延迟尝试(保持原有的重试机制) - this.scheduleOnce(() => { - if (!tryAdjustScale()) { - // 再次延迟尝试 - this.scheduleOnce(() => { - tryAdjustScale(); - }, 0.5); - } - }, 0.1); - } - } - /** * 获取目标视频尺寸 * 从 videoArea 获取实际需要填充的区域尺寸 @@ -244,25 +182,17 @@ export class GirlDetailPanel extends li_BaseView { ? new Size(this.videoArea.width, this.videoArea.height) : new Size(600, 800); - // 获取 videoArea 的中心位置作为参考节点 - const bgFrameNode = this.videoArea ? this.videoArea.node : null; + // 获取 videoArea 的中心位置作为参考节点(使用世界坐标) + const videoAreaPos = this.videoArea + ? this.videoArea.node.getWorldPosition() + : undefined; - // 使用 playLocalLoopVideo 方法,保证兼容性 - const videoData = { - path: firstPath, + // 使用新的统一 playVideo 方法 + this.videoLayer.playVideo(firstPath, { + loop: true, size: targetSize, - bgFrameNode: bgFrameNode, // 传递 videoArea 节点作为位置参考 - }; - this.videoLayer.playLocalLoopVideo(videoData); - - // 延迟调整视频缩放和位置,确保视频加载完成 - this.scheduleOnce(() => { - this.adjustVideoScale(); - }, 0.1); - } else if (!firstPath) { - console.warn( - `GirlDetailPanel: 未找到视频路径 category=${this.category}, id=${this.id}` - ); + position: videoAreaPos + }); } let resIds = girlData.getAllDisplayGrilPhotoId( @@ -333,16 +263,9 @@ export class GirlDetailPanel extends li_BaseView { private initVideoPosition() { if (!this.videoLayer || !this.videoArea) return; - // 设置视频锚点为中心 (0.5, 0.5),这样视频的中心点就是定位点 - this.videoLayer.setVideoAnchor(0.5, 0.5); - // 使用 videoArea 的世界坐标位置 const videoAreaWorldPos = this.videoArea.node.getWorldPosition(); - this.videoLayer.setVideoWorldPosition( - videoAreaWorldPos.x, - videoAreaWorldPos.y, - videoAreaWorldPos.z - ); + // 视频位置和缩放已在 playVideo 中处理 this.videoLayer.setVideoScale(1); console.log( `GirlDetailPanel: 初始化视频世界位置到 (${videoAreaWorldPos.x}, ${videoAreaWorldPos.y})` diff --git a/assets/Scripts/chat18x/ui/panels/ShowPanel.ts b/assets/Scripts/chat18x/ui/panels/ShowPanel.ts index 062c8399..1629ba2a 100644 --- a/assets/Scripts/chat18x/ui/panels/ShowPanel.ts +++ b/assets/Scripts/chat18x/ui/panels/ShowPanel.ts @@ -5,13 +5,17 @@ import { Sprite, UITransform, VideoPlayer, + VideoClip, view, + Size, + Vec3, } from "cc"; import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView"; import ResManager from "db://assets/Scripts/Main/Manager/ResManager"; import Utils from "db://assets/Scripts/Main/Common/Utils"; import { ViewManager } from "db://assets/Scripts/Main/Manager/ViewManager"; import { GButton } from "db://assets/Scripts/Main/Common/GButton"; +import { SceneBgVideoLayer } from "../../../Sub/UI/SceneBgVideoLayer"; const { ccclass, property } = _decorator; interface ShowPanelData { @@ -26,6 +30,8 @@ export class ShowPanel extends li_BaseView { image: Sprite; @property(Sprite) splash: Sprite; + @property(UITransform) + videoArea: UITransform; @property(VideoPlayer) videoPlayer: VideoPlayer; @@ -41,15 +47,6 @@ export class ShowPanel extends li_BaseView { onLoadCT() { this.show(this.url); - - // 添加视频加载完成回调 - this.videoPlayer.node.on( - VideoPlayer.EventType.READY_TO_PLAY, - () => { - this.adjustVideoScale(); - }, - this - ); } start() { @@ -58,6 +55,11 @@ export class ShowPanel extends li_BaseView { } protected onClose() { + // 停止视频播放 + if (this.videoPlayer) { + this.videoPlayer.stop(); + } + if (this.func) { this.func(); } @@ -70,42 +72,69 @@ export class ShowPanel extends li_BaseView { Utils.adjustBgPixelRatio(this.image.node, 3); }); } else { - ResManager.I.changeBundleVideo(this.videoPlayer, path, "Girls", () => { - this.adjustVideoScale(); - }); + // 使用自己的 videoPlayer 进行置顶显示 + if (this.videoPlayer) { + const targetSize = this.videoArea + ? new Size(this.videoArea.width, this.videoArea.height) + : new Size(600, 800); + + ResManager.I.changeBundleVideo( + this.videoPlayer, + path, + "Girls", + (res: VideoClip) => { + // 设置视频大小和位置 + const uiTransform = this.videoPlayer.node.getComponent(UITransform); + if (uiTransform && this.videoArea) { + uiTransform.setContentSize(targetSize.width, targetSize.height); + // 设置位置为 videoArea 的位置 + const pos = this.videoArea.node.getWorldPosition(); + this.videoPlayer.node.setWorldPosition(pos); + } + + this.videoPlayer.loop = true; + this.videoPlayer.play(); + + // 延迟调整缩放以填充区域 + this.scheduleOnce(() => { + this.adjustVideoScale(); + }, 0.1); + } + ); + } else { + // 如果没有配置 videoPlayer,使用 SceneBgVideoLayer 作为后备 + const targetSize = this.videoArea + ? new Size(this.videoArea.width, this.videoArea.height) + : new Size(600, 800); + const videoAreaPos = this.videoArea + ? this.videoArea.node.getWorldPosition() + : undefined; + + if (SceneBgVideoLayer.handle) { + SceneBgVideoLayer.handle.playVideo(path, { + loop: true, + size: targetSize, + position: videoAreaPos, + }); + } + } } } - adjustVideoScale() { - if (!this.videoPlayer) { - return; - } - - const tryAdjustScale = () => { - const screenSize = view.getVisibleSize(); - - const videoTransform = this.videoPlayer.node.getComponent(UITransform); - - if (videoTransform && videoTransform.height > 0) { - let scale = screenSize.width / videoTransform.width; - this.videoPlayer.node.setScale(scale, scale, 1); - - return true; - } - return false; - }; - - // 立即尝试一次 - if (!tryAdjustScale()) { - // 如果失败,延迟尝试 - this.scheduleOnce(() => { - if (!tryAdjustScale()) { - // 再次延迟尝试 - this.scheduleOnce(() => { - tryAdjustScale(); - }, 0.5); - } - }, 0.1); + /** + * 调整视频缩放以填满区域 + */ + private adjustVideoScale() { + if (!this.videoPlayer || !this.videoArea) return; + + const videoTransform = this.videoPlayer.node.getComponent(UITransform); + if (videoTransform && videoTransform.height > 0) { + const scaleX = this.videoArea.width / videoTransform.width; + const scaleY = this.videoArea.height / videoTransform.height; + const scale = Math.max(scaleX, scaleY); // 填满整个区域 + + this.videoPlayer.node.setScale(new Vec3(scale, scale, 1)); + console.log(`ShowPanel: 调整视频缩放到 ${scale}`); } } } diff --git a/assets/bundles/Chat18x/Image/Girls.meta b/assets/bundles/Chat18x/Image/Girls.meta new file mode 100644 index 00000000..1459180f --- /dev/null +++ b/assets/bundles/Chat18x/Image/Girls.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "f24940a7-d618-4ee2-a6b9-8ba05b2fe267", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/bundles/Chat18x/ShowPanel.prefab b/assets/bundles/Chat18x/ShowPanel.prefab index d0ed8996..922b7bf6 100644 --- a/assets/bundles/Chat18x/ShowPanel.prefab +++ b/assets/bundles/Chat18x/ShowPanel.prefab @@ -30,18 +30,18 @@ ], "_active": true, "_components": [ - { - "__id__": 24 - }, - { - "__id__": 26 - }, { "__id__": 28 + }, + { + "__id__": 30 + }, + { + "__id__": 32 } ], "_prefab": { - "__id__": 30 + "__id__": 34 }, "_lpos": { "__type__": "cc.Vec3", @@ -447,18 +447,19 @@ "_parent": { "__id__": 1 }, - "_children": [], + "_children": [ + { + "__id__": 19 + } + ], "_active": true, "_components": [ { - "__id__": 19 - }, - { - "__id__": 21 + "__id__": 25 } ], "_prefab": { - "__id__": 23 + "__id__": 27 }, "_lpos": { "__type__": "cc.Vec3", @@ -489,6 +490,127 @@ }, "_id": "" }, + { + "__type__": "cc.Node", + "_name": "VideoPlayer", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 18 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 20 + }, + { + "__id__": 22 + } + ], + "_prefab": { + "__id__": 24 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 19 + }, + "_enabled": true, + "__prefab": { + "__id__": 21 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 384, + "height": 672 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a4dlzYsPlE4J4+Ej16vdWP" + }, + { + "__type__": "cc.VideoPlayer", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 19 + }, + "_enabled": true, + "__prefab": { + "__id__": 23 + }, + "_resourceType": 1, + "_remoteURL": "", + "_clip": null, + "_playOnAwake": true, + "_volume": 1, + "_mute": false, + "_playbackRate": 1, + "_loop": false, + "_fullScreenOnAwake": false, + "_stayOnBottom": false, + "_keepAspectRatio": true, + "videoPlayerEvent": [], + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "104U4SIi9J9oUdCdMtQN8I" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "11zQc04etBLK2ie+tkWM3R", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, { "__type__": "cc.UITransform", "_name": "", @@ -499,12 +621,12 @@ }, "_enabled": true, "__prefab": { - "__id__": 20 + "__id__": 26 }, "_contentSize": { "__type__": "cc.Size", - "width": 1170, - "height": 2532 + "width": 450, + "height": 695.5 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -517,36 +639,6 @@ "__type__": "cc.CompPrefabInfo", "fileId": "adE8tlqHhN2YnsHttPJDRn" }, - { - "__type__": "cc.VideoPlayer", - "_name": "", - "_objFlags": 0, - "__editorExtras__": {}, - "node": { - "__id__": 18 - }, - "_enabled": true, - "__prefab": { - "__id__": 22 - }, - "_resourceType": 1, - "_remoteURL": "", - "_clip": null, - "_playOnAwake": true, - "_volume": 1, - "_mute": false, - "_playbackRate": 1, - "_loop": true, - "_fullScreenOnAwake": false, - "_stayOnBottom": false, - "_keepAspectRatio": true, - "videoPlayerEvent": [], - "_id": "" - }, - { - "__type__": "cc.CompPrefabInfo", - "fileId": "a9HSqpEXNFpojuCAxNvLUJ" - }, { "__type__": "cc.PrefabInfo", "root": { @@ -570,7 +662,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 25 + "__id__": 29 }, "_contentSize": { "__type__": "cc.Size", @@ -598,7 +690,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 27 + "__id__": 31 }, "_alignFlags": 45, "_target": null, @@ -634,7 +726,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 29 + "__id__": 33 }, "m_rootNode": null, "image": { @@ -643,8 +735,11 @@ "splash": { "__id__": 5 }, + "videoArea": { + "__id__": 25 + }, "videoPlayer": { - "__id__": 21 + "__id__": 22 }, "_id": "" },