设置页、弹窗逻辑、跳转逻辑
视频播放逻辑优化
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
Sprite,
|
||||
UITransform,
|
||||
VideoPlayer,
|
||||
Size,
|
||||
} from "cc";
|
||||
// 首先加载 polyfills 以确保兼容性
|
||||
import "../../utils/polyfills";
|
||||
@@ -27,6 +28,7 @@ import { VideoEmotion, purchase } from "../../../schema/schema";
|
||||
import { PayToTalkSubpanel } from "./PayToTalkSubpanel";
|
||||
import { DataId, DataManager } from "../../data/DataManager";
|
||||
import { GirlData } from "../../data/GirlData";
|
||||
import { SceneBgVideoLayer } from "../../../Sub/UI/SceneBgVideoLayer";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass("ChatPanel")
|
||||
@@ -46,8 +48,16 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
// @property(Sprite)
|
||||
// girlImg: Sprite = null;
|
||||
|
||||
@property(VideoPlayer)
|
||||
girlVideo: VideoPlayer = null;
|
||||
// 移除直接的 VideoPlayer 引用,改用 SceneBgVideoLayer 单例
|
||||
// @property(VideoPlayer)
|
||||
// girlVideo: VideoPlayer = null;
|
||||
@property(UITransform)
|
||||
videoArea: UITransform = null;
|
||||
|
||||
/** 获取 SceneBgVideoLayer 单例实例 */
|
||||
private get videoLayer(): SceneBgVideoLayer | null {
|
||||
return SceneBgVideoLayer.handle;
|
||||
}
|
||||
|
||||
@property(ChatContentsLayout)
|
||||
layout: ChatContentsLayout = null;
|
||||
@@ -119,17 +129,38 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
this.register();
|
||||
this.refresh();
|
||||
this.payToTalkPanel.node.active = false;
|
||||
// Add video loaded event callback
|
||||
if (this.girlVideo) {
|
||||
this.girlVideo.node.on(
|
||||
VideoPlayer.EventType.READY_TO_PLAY,
|
||||
() => {
|
||||
this.adjustVideoScale();
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
// 检查 SceneBgVideoLayer 是否可用
|
||||
if (!this.videoLayer) {
|
||||
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,
|
||||
@@ -179,8 +210,8 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
);
|
||||
|
||||
// Cleanup video event listeners
|
||||
if (this.girlVideo && this.girlVideo.node) {
|
||||
this.girlVideo.node.off(
|
||||
if (this.videoLayer && this.videoLayer.node) {
|
||||
this.videoLayer.node.off(
|
||||
VideoPlayer.EventType.READY_TO_PLAY,
|
||||
this.adjustVideoScale,
|
||||
this
|
||||
@@ -224,7 +255,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
const chatModel = this.chatController.getChatModel();
|
||||
|
||||
// Load initial video based on current emotion
|
||||
if (this.girlVideo) {
|
||||
if (this.videoLayer) {
|
||||
// Get current emotion from ChatController
|
||||
const currentEmotion = this.chatController.getCurrentEmotion();
|
||||
console.log(
|
||||
@@ -241,46 +272,81 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
`Loading initial video: ${initialVideo} (emotion: ${VideoEmotion[initialVideo]})`
|
||||
);
|
||||
|
||||
// 获取 videoArea 的尺寸
|
||||
const targetSize = this.videoArea
|
||||
? 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();
|
||||
ResManager.I.changeBundleVideo(this.girlVideo, initialVideo, "Girls");
|
||||
// Also immediately try to adjust scale (in case already loaded)
|
||||
this.adjustVideoScale();
|
||||
this.videoLayer.playLocalLoopVideo(videoData);
|
||||
|
||||
// 延迟调整视频缩放
|
||||
this.scheduleOnce(() => {
|
||||
this.adjustVideoScale();
|
||||
}, 0.1);
|
||||
}
|
||||
} else {
|
||||
this.commercialVideos = [];
|
||||
this.currentEmotion = null; // Reset current emotion when no videos available
|
||||
console.log("No commercialVideos data available for role", this.id);
|
||||
console.log("No SceneBgVideoLayer available for role", this.id);
|
||||
}
|
||||
}
|
||||
|
||||
adjustVideoScale() {
|
||||
if (!this.girlVideo || !this.girlVideo.node.parent) {
|
||||
if (!this.videoLayer || !this.videoArea) {
|
||||
console.error("ChatPanel: SceneBgVideoLayer 或 videoArea 不可用");
|
||||
return;
|
||||
}
|
||||
|
||||
const tryAdjustScale = () => {
|
||||
const parentTransform =
|
||||
this.girlVideo.node.parent.getComponent(UITransform);
|
||||
const videoTransform = this.girlVideo.node.getComponent(UITransform);
|
||||
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(
|
||||
this.videoLayer.node.worldPosition.x,
|
||||
videoAreaWorldPos.y,
|
||||
videoAreaWorldPos.z
|
||||
);
|
||||
|
||||
if (parentTransform && videoTransform && videoTransform.height > 0) {
|
||||
const scale = parentTransform.height / videoTransform.height;
|
||||
this.girlVideo.node.setScale(scale, scale, 1);
|
||||
console.log(
|
||||
`ChatPanel Video scaled to: ${scale}, parent height: ${parentTransform.height}, video height: ${videoTransform.height}`
|
||||
`ChatPanel: 视频缩放到 ${scale}, videoArea高度: ${this.videoArea.height}, 视频高度: ${videoTransform.height}`
|
||||
);
|
||||
console.log(
|
||||
`ChatPanel: 视频世界位置设置为 (${videoAreaWorldPos.x}, ${videoAreaWorldPos.y})`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Immediately try once
|
||||
// 立即尝试一次
|
||||
if (!tryAdjustScale()) {
|
||||
// If failed, delay and try again
|
||||
// 如果失败,延迟尝试
|
||||
this.scheduleOnce(() => {
|
||||
if (!tryAdjustScale()) {
|
||||
// Try again with longer delay
|
||||
// 再次延迟尝试
|
||||
this.scheduleOnce(() => {
|
||||
tryAdjustScale();
|
||||
}, 0.5);
|
||||
@@ -292,22 +358,28 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
||||
let triggerId = girlData.getTriggerGrilPhotoId(this.categoryId, this.id);
|
||||
|
||||
if (triggerId == 0) triggerId = 100040103;
|
||||
if (triggerId == 0) return;
|
||||
|
||||
this.popUpImage.refresh(this.categoryId, this.id, triggerId);
|
||||
}
|
||||
|
||||
setVideoEnable(enable: boolean) {
|
||||
if (!this.girlVideo) return;
|
||||
if (!this.videoLayer) {
|
||||
console.error("ChatPanel: SceneBgVideoLayer 不可用");
|
||||
return;
|
||||
}
|
||||
|
||||
this.girlVideo.enabled = enable;
|
||||
if (enable) {
|
||||
this.girlVideo.play();
|
||||
this.videoLayer.resume();
|
||||
console.log("ChatPanel: 恢复视频播放");
|
||||
} else {
|
||||
this.videoLayer.pause();
|
||||
console.log("ChatPanel: 暂停视频播放");
|
||||
}
|
||||
}
|
||||
|
||||
private switchVideoByEmotion(emotion: VideoEmotion): void {
|
||||
if (!this.girlVideo) {
|
||||
if (!this.videoLayer) {
|
||||
console.warn("Cannot switch video: missing video player");
|
||||
return;
|
||||
}
|
||||
@@ -337,7 +409,8 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
);
|
||||
|
||||
// Load the new video
|
||||
ResManager.I.changeBundleVideo(this.girlVideo, matchingVideo, "Girls");
|
||||
this.videoLayer.playVideo(matchingVideo, true);
|
||||
//ResManager.I.changeBundleVideo(this.girlVideo, matchingVideo, "Girls");
|
||||
|
||||
// Update current emotion state
|
||||
this.currentEmotion = emotion;
|
||||
@@ -357,11 +430,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
`Loading fallback video: ${fallbackVideo} (emotion: ${VideoEmotion[fallbackVideo]})`
|
||||
);
|
||||
|
||||
ResManager.I.changeBundleVideo(
|
||||
this.girlVideo,
|
||||
fallbackVideo,
|
||||
"Chat18x"
|
||||
);
|
||||
this.videoLayer.playVideo(fallbackVideo, true);
|
||||
|
||||
// Update current emotion state to the fallback video's emotion
|
||||
this.currentEmotion = this.chatController.getCurrentEmotion();
|
||||
|
||||
Reference in New Issue
Block a user