2025-08-25 20:15:42 +08:00
|
|
|
import {
|
|
|
|
|
_decorator,
|
|
|
|
|
Component,
|
|
|
|
|
Sprite,
|
|
|
|
|
UITransform,
|
|
|
|
|
Size,
|
|
|
|
|
isValid,
|
|
|
|
|
Node,
|
|
|
|
|
} from "cc";
|
2025-09-21 20:36:19 +08:00
|
|
|
import { logger } from "db://assets/Scripts/Main/Common/Logger";
|
2025-08-25 20:15:42 +08:00
|
|
|
|
|
|
|
|
const { ccclass } = _decorator;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 父物体自适应调整组件
|
|
|
|
|
* 功能:使精灵保持原始宽高比并覆盖整个父物体区域
|
|
|
|
|
* 触发时机:GameObject 激活时、父物体尺寸变化时
|
|
|
|
|
*/
|
|
|
|
|
@ccclass("ParentResize")
|
|
|
|
|
export class ParentResize extends Component {
|
|
|
|
|
private sprite: Sprite = null;
|
|
|
|
|
private uiTransform: UITransform = null;
|
|
|
|
|
private parentTransform: UITransform = null;
|
|
|
|
|
private lastParentSize: Size = new Size();
|
|
|
|
|
|
|
|
|
|
onLoad() {
|
|
|
|
|
// 获取必要组件
|
|
|
|
|
this.sprite = this.getComponent(Sprite);
|
|
|
|
|
this.uiTransform = this.getComponent(UITransform);
|
|
|
|
|
|
|
|
|
|
if (!this.sprite) {
|
2025-09-21 20:36:19 +08:00
|
|
|
logger.warn("ParentResize: 未找到 Sprite 组件");
|
2025-08-25 20:15:42 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!this.uiTransform) {
|
2025-09-21 20:36:19 +08:00
|
|
|
logger.warn("ParentResize: 未找到 UITransform 组件");
|
2025-08-25 20:15:42 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取父物体的 UITransform
|
|
|
|
|
if (this.node.parent) {
|
|
|
|
|
this.parentTransform = this.node.parent.getComponent(UITransform);
|
|
|
|
|
if (!this.parentTransform) {
|
2025-09-21 20:36:19 +08:00
|
|
|
logger.warn("ParentResize: 父物体未找到 UITransform 组件");
|
2025-08-25 20:15:42 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2025-09-21 20:36:19 +08:00
|
|
|
logger.warn("ParentResize: 未找到父物体");
|
2025-08-25 20:15:42 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onEnable() {
|
|
|
|
|
// 激活时立即调整尺寸
|
|
|
|
|
this.adjustToParent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 调整精灵尺寸以覆盖整个父物体区域
|
|
|
|
|
* 保持原始宽高比,使用 cover 策略
|
|
|
|
|
*/
|
|
|
|
|
private adjustToParent() {
|
|
|
|
|
if (
|
|
|
|
|
!isValid(this.sprite) ||
|
|
|
|
|
!isValid(this.uiTransform) ||
|
|
|
|
|
!isValid(this.parentTransform)
|
|
|
|
|
) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const spriteFrame = this.sprite.spriteFrame;
|
|
|
|
|
if (!spriteFrame) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取父物体尺寸
|
|
|
|
|
const parentSize = this.parentTransform.contentSize;
|
|
|
|
|
|
|
|
|
|
// 获取精灵原始尺寸
|
|
|
|
|
const originalSize = spriteFrame.originalSize;
|
|
|
|
|
if (!originalSize || originalSize.width <= 0 || originalSize.height <= 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果父物体尺寸无效,则不进行调整
|
|
|
|
|
if (parentSize.width <= 0 || parentSize.height <= 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算缩放比例(使用较大值以确保覆盖整个父物体区域)
|
|
|
|
|
const scaleX = parentSize.width / originalSize.width;
|
|
|
|
|
const scaleY = parentSize.height / originalSize.height;
|
|
|
|
|
const scale = Math.max(scaleX, scaleY);
|
|
|
|
|
|
|
|
|
|
// 计算新的尺寸
|
|
|
|
|
const newWidth = originalSize.width * scale;
|
|
|
|
|
const newHeight = originalSize.height * scale;
|
|
|
|
|
|
|
|
|
|
// 应用新尺寸
|
|
|
|
|
this.uiTransform.setContentSize(newWidth, newHeight);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 手动触发尺寸调整
|
|
|
|
|
* 可在外部调用,例如当 SpriteFrame 改变时或父物体尺寸手动改变时
|
|
|
|
|
*/
|
|
|
|
|
public forceResize() {
|
|
|
|
|
this.adjustToParent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 设置新的父物体
|
|
|
|
|
* 当需要动态改变参考父物体时调用
|
|
|
|
|
*/
|
|
|
|
|
public setParent(parentNode: Node) {
|
|
|
|
|
if (parentNode) {
|
|
|
|
|
this.parentTransform = parentNode.getComponent(UITransform);
|
|
|
|
|
if (this.parentTransform) {
|
|
|
|
|
this.lastParentSize.set(0, 0); // 重置上次记录的尺寸
|
|
|
|
|
this.adjustToParent();
|
|
|
|
|
} else {
|
2025-09-21 20:36:19 +08:00
|
|
|
logger.warn("ParentResize: 新父物体未找到 UITransform 组件");
|
2025-08-25 20:15:42 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|