import { _decorator, Component, Node, Prefab, instantiate, Vec3 } from "cc"; const { ccclass, property } = _decorator; @ccclass("TrajectoryPreview") export class TrajectoryPreview extends Component { @property(Prefab) pointPrefab: Prefab = null!; @property maxPoints: number = 20; @property timeStep: number = 0.1; @property gravity: Vec3 = new Vec3(0, -9.8, 0); private points: Node[] = []; onLoad() { for (let i = 0; i < this.maxPoints; i++) { const p = instantiate(this.pointPrefab); p.active = false; this.node.addChild(p); // 确保挂在场景下的空节点 this.points.push(p); } } showTrajectory( startPos: Vec3, forward: Vec3, power: number, sideForce: number ) { const velocity = forward.multiplyScalar(power); velocity.x += sideForce; const ballRadius = 0.01; // ⚽ 球半径 const groundY = 0; // 🟩 地面高度 for (let i = 0; i < this.maxPoints; i++) { const t = i * this.timeStep; const pos = new Vec3( startPos.x + velocity.x * t, startPos.y + velocity.y * t + 0.5 * this.gravity.y * t * t, startPos.z + velocity.z * t ); // ⭐ 限制最低不低于地面 if (pos.y < groundY + ballRadius * 0.5) { pos.y = groundY + ballRadius * 0.5; } this.points[i].setWorldPosition(pos); this.points[i].active = true; } } hideTrajectory() { this.points.forEach((p) => (p.active = false)); } }