// CameraOrbit.ts import { _decorator, Component, Node, Vec3, EventTouch, input, Input, v3 } from 'cc'; const { ccclass, property } = _decorator; @ccclass('CameraOrbit') export class CameraOrbit extends Component { @property(Node) public targetNode: Node | null = null; @property(Vec3) private readonly FINISH_POINT = new Vec3(0, 0, -50); // 终点位置 private radius: number = 8; // 与角色的距离 private heightOffset: number = 3; // 高度偏移 private centerOffset = v3(0, 1.5, 0); // 瞄准点高度偏移 private isInitialized: boolean = false; private lastTouchX: number = 0; private readonly rotationSpeed: number = 0.3; private readonly resetSpeed: number = 0.15; // 增加回正速度 private isTouching: boolean = false; private currentRotation: number = 0; private isResetting: boolean = false; start() { this.tryInitialize(); } onEnable() { input.on(Input.EventType.TOUCH_START, this.onTouchStart, this); input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this); input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this); input.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this); } onDisable() { input.off(Input.EventType.TOUCH_START, this.onTouchStart, this); input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this); input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this); input.off(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this); } private onTouchStart(event: EventTouch) { this.isTouching = true; this.isResetting = false; this.lastTouchX = event.getLocationX(); } private onTouchMove(event: EventTouch) { if (!this.isTouching || !this.targetNode) return; const currentTouchX = event.getLocationX(); const deltaX = currentTouchX - this.lastTouchX; // 更新摄像机的旋转 this.currentRotation += deltaX * this.rotationSpeed; this.currentRotation = Math.max(-90, Math.min(90, this.currentRotation)); // 限制在±90度 // 更新摄像机位置和朝向 this.updateCameraPosition(); this.lastTouchX = currentTouchX; } private onTouchEnd() { this.isTouching = false; } lateUpdate(deltaTime: number) { if (!this.isInitialized || !this.targetNode) return; if (!this.isTouching && !this.isResetting) { this.resetRotation(deltaTime); } this.updateCameraPosition(); } private updateCameraPosition() { if (!this.targetNode) return; const targetPos = this.targetNode.worldPosition.clone().add(this.centerOffset); // 计算摄像机位置(始终在角色后方) const cameraPos = new Vec3( targetPos.x, // 与角色相同的X坐标 targetPos.y + this.heightOffset, // 高度偏移 targetPos.z + this.radius // 在角色后方 ); // 根据当前旋转角度调整摄像机位置 const angle = this.currentRotation * Math.PI / 180; const offsetX = this.radius * Math.sin(angle); const offsetZ = this.radius * Math.cos(angle); cameraPos.x = targetPos.x + offsetX; cameraPos.z = targetPos.z + offsetZ; // 设置摄像机位置和朝向 this.node.worldPosition = cameraPos; this.node.lookAt(targetPos); // 添加固定的俯视角度 const currentEuler = this.node.eulerAngles.clone(); this.node.eulerAngles = new Vec3(-15, currentEuler.y, 0); } private resetRotation(deltaTime: number) { const resetSpeed = 0.2; // 增加回正速度 this.currentRotation *= (1 - resetSpeed); if (Math.abs(this.currentRotation) < 0.1) { this.currentRotation = 0; } } private tryInitialize() { if (!this.targetNode || this.isInitialized) return; this.isInitialized = true; // 确保角色朝向-Z方向 this.targetNode.setRotationFromEuler(0, 180, 0); this.updateCameraPosition(); } }