This commit is contained in:
2025-09-11 10:54:06 +08:00
parent 53f2037c49
commit a590433a91
7 changed files with 413 additions and 419 deletions
+40 -42
View File
@@ -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();
@@ -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})`
+71 -42
View File
@@ -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}`);
}
}
}