squidGame/tgx-games-client/assets/module_arean/level1/Script/CameraOrbitRole.ts

127 lines
4.2 KiB
TypeScript

// 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();
}
}