import { _decorator, BlockInputEvents, Button, director, Label, Node, UITransform, Vec3 } from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { IGuideStep, GuideStepType } from "../common/config/Guide"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; const { ccclass, property } = _decorator; /** 引导步骤UI组件 - 完整的引导UI容器 */ @ccclass('GuideSetpComp') @ecs.register('GuideSetp', false) export class GuideSetpComp extends CCComp { @property(Label) private tipLabel: Label = null!; @property(Node) private tipNode: Node = null!; @property(Node) private handNode: Node = null!; @property(Button) private skipButton: Button = null!; /** 当前引导步骤数据 */ private currentStep: IGuideStep | null = null; /** 当前步骤索引 */ private currentStepIndex: number = 0; /** 总步骤数 */ private totalSteps: number = 0; /** 目标节点 */ private _targetNode: Node | null = null; /** 提示父节点 */ private _tipParent: Node | null = null; private _showTip: boolean = false; private _showHand: boolean = false; private _callback: any = null; private _noInput: any = null; /** 触摸监听器标志位 */ private _hasTouchListener: boolean = false; /** 添加触摸监听器 */ private addTouchListener() { // 如果已经有监听器,不要重复添加 if (this._hasTouchListener) { console.log("[GuideSetpComp] 触摸监听器已存在,跳过添加"); return; } // 直接监听当前节点的触摸事件 this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this); this._hasTouchListener = true; console.log("[GuideSetpComp] 已添加触摸监听器到当前节点,等待用户点击"); } /** 触摸开始事件处理 */ private onTouchStart(event: any) { // 检查是否当前有等待引导在运行 if (!this.currentStep || this.currentStep.type !== GuideStepType.WAIT) { return; // 如果没有等待引导,不处理触摸事件 } console.log("[GuideSetpComp] 检测到触摸事件,完成等待引导"); // 移除触摸监听器 this.removeTouchListener(); // 完成当前引导 if (this._callback && this._callback.onStepComplete) { this._callback.onStepComplete(this.currentStep); } } /** 移除触摸监听器 */ private removeTouchListener() { // 如果没有监听器,直接返回 if (!this._hasTouchListener) { return; } // 直接从当前节点移除触摸事件监听 this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this); this._hasTouchListener = false; console.log("[GuideSetpComp] 已移除触摸监听器"); } /** 组件初始化 */ start() { console.log("[GuideSetpComp] start", this.node); } onAdded(args: any) { console.log("[GuideSetpComp] onAdded", this.node); this.initUI(); this._noInput=this.node.getComponent(BlockInputEvents); this._noInput.enabled=false; // 如有传入的参数,直接处理 if (args && args.step) { this.handleStepInfo(args); } } protected onEnable(): void { console.log("[GuideSetpComp] onEnable", this.node); } /** 处理步骤信息 */ private handleStepInfo(data: any) { const { step, stepIndex, totalSteps,callbacks } = data; const targetNode=this.findTargetNode(step.targetPath); this._noInput.enabled=step.noInput??false; this._callback=callbacks; if(targetNode){ this._targetNode=targetNode; this._showTip=true; this._showHand=true; }else{ this._targetNode=this.node; this._showTip=true; this._showHand=false; } if(step.tipParent){ this._tipParent=this.findTargetNode(step.tipParent); }else{ this._tipParent=this._targetNode; } console.log("[GuideSetpComp] 处理步骤信息:", step); // 显示步骤 this.showStep(step, stepIndex, totalSteps,targetNode,this._tipParent); // 如果有手指位置,直接设置 // this.setHandPosition(this._targetNode); } /** 初始化UI */ private initUI() { // 设置初始状态 this.node.active = false; this.node.setSiblingIndex(1000); this.tipNode.active = false; this.handNode.active = false; } /** 显示引导步骤 */ showStep(step: IGuideStep, stepIndex: number, totalSteps: number,targetNode: Node,tipParent: Node) { this.currentStep = step; this.currentStepIndex = stepIndex; this.totalSteps = totalSteps; // 将handNode和tipNode从当前父节点移除 this.handNode.parent=this._targetNode; // if(this._tipParent){ // this.tipNode.parent=this._tipParent; // }else{ // this.tipNode.parent=this._targetNode; // } this.handNode.setPosition(this.currentStep?.handOffset?.x || 0, this.currentStep?.handOffset?.y || 0); // this.tipNode.setPosition(this.currentStep?.tipOffset?.x || 0, this.currentStep?.tipOffset?.y || 0); // 设置setSiblingIndex最大 this.handNode.setSiblingIndex(this._targetNode.children.length - 1); // this.tipNode.setSiblingIndex(this._targetNode.children.length - 1); // 更新UI内容 this.updateStepContent() // 显示组件 this.show(); // 如果是等待引导,添加触摸监听器 if (step.type === GuideStepType.WAIT) { this.addTouchListener(); } } /** 更新步骤内容 */ private updateStepContent() { if (!this.currentStep || !this._targetNode) return; // 根据目标节点调整tipNode的位置 // 假设tipNode相对于目标节点是固定的偏移 // 更新提示文本 if (this.tipLabel) { this.tipLabel.string = this.currentStep.tipText ||""; } // 控制跳过按钮显示 } /** 显示组件 */ private show() { this.node.active = true; if (this.tipLabel.string!="") { this.tipNode.active = true; } if (this.handNode) { this.handNode.active = true; } } /** 查找目标节点 */ private findTargetNode(path: string): Node | null { console.log(`[GuideCon] 开始查找目标节点: ${path}`); const pathParts = path.split('/'); let currentNode: any = director.getScene(); for (const part of pathParts) { if (!currentNode || !currentNode.getChildByName) { console.error(`[GuideCon] 节点 ${part} 不存在或没有getChildByName方法`); break; } const childNode = currentNode.getChildByName(part); if (!childNode) { console.error(`[GuideCon] 找不到子节点: ${part}`); console.log(`[GuideCon] 当前节点 ${currentNode.name} 的子节点:`, currentNode.children.map(c => c.name)); break; } currentNode = childNode; console.log("[GuideCon] 当前节点:", currentNode) } if (currentNode) { console.log(`[GuideCon] 目标节点查找成功:`, currentNode.position, currentNode.getWorldPosition()); return currentNode as Node; } else { console.error(`[GuideCon] 目标节点查找失败: ${path}`); return null; } } /** 跳过按钮点击事件 */ private onSkipButtonClick() { console.log("[GuideSetpComp] 跳过按钮点击事件"); this.tipNode.destroy(); this.handNode.destroy(); // oops.gui.removeByNode(this.node); this._callback.onComplete(); } /** 清理资源 */ private cleanup() { // 移除触摸监听器 this.removeTouchListener(); this.currentStep = null; this.currentStepIndex = 0; this.totalSteps = 0; } /** 组件销毁时清理 */ reset() { this.cleanup(); this.node.active = false; } /** 组件销毁时清理 */ onDestroy() { // 清理资源 this.removeTouchListener(); this.tipNode.destroy(); this.handNode.destroy(); console.log("[GuideSetpComp] 监听onDestroy", this.node); } }