feat: 支持更新相机高度
This commit is contained in:
@@ -4,115 +4,117 @@ const { ccclass, property } = _decorator;
|
||||
@ccclass('CameraFollow')
|
||||
export class CameraFollow extends Component {
|
||||
|
||||
@property(Node)
|
||||
target: Node | null = null; // 要跟随的目标(玩家)
|
||||
@property(Node)
|
||||
target: Node | null = null; // 要跟随的目标(玩家)
|
||||
|
||||
@property({ range: [0.1, 10] })
|
||||
followSpeed: number = 5.0; // 跟随速度
|
||||
@property({ range: [0.1, 10] })
|
||||
followSpeed: number = 5.0; // 跟随速度
|
||||
|
||||
@property(Vec3)
|
||||
offset: Vec3 = new Vec3(0, 0, 10); // 相机相对目标的偏移
|
||||
@property(Vec3)
|
||||
offset: Vec3 = new Vec3(0, 0, 10); // 相机相对目标的偏移
|
||||
|
||||
@property({ range: [0, 1] })
|
||||
smoothness: number = 0.1; // 平滑度,0为瞬间跟随,1为最慢跟随
|
||||
@property({ range: [0, 1] })
|
||||
smoothness: number = 0.1; // 平滑度,0为瞬间跟随,1为最慢跟随
|
||||
|
||||
@property
|
||||
mapWidth: number = 1080; // 地图宽度
|
||||
@property
|
||||
mapWidth: number = 1080; // 地图宽度
|
||||
|
||||
@property
|
||||
mapHeight: number = 2560; // 地图高度
|
||||
@property
|
||||
mapHeight: number = 2560; // 地图高度
|
||||
|
||||
private camera: Camera | null = null;
|
||||
private camera: Camera | null = null;
|
||||
|
||||
onLoad() {
|
||||
// 获取相机组件
|
||||
this.camera = this.getComponent(Camera);
|
||||
if (!this.camera) {
|
||||
console.error('CameraFollow: 未找到Camera组件');
|
||||
}
|
||||
onLoad() {
|
||||
// 获取相机组件
|
||||
this.camera = this.getComponent(Camera);
|
||||
|
||||
this.camera.orthoHeight = 500
|
||||
if (!this.camera) {
|
||||
console.error('CameraFollow: 未找到Camera组件');
|
||||
}
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.target) {
|
||||
// 初始化相机位置
|
||||
const initialPos = this.target.position.clone();
|
||||
initialPos.add(this.offset);
|
||||
this.node.position = initialPos;
|
||||
}
|
||||
start() {
|
||||
if (this.target) {
|
||||
// 初始化相机位置
|
||||
const initialPos = this.target.position.clone();
|
||||
initialPos.add(this.offset);
|
||||
this.node.position = initialPos;
|
||||
}
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
if (!this.target) return;
|
||||
update(deltaTime: number) {
|
||||
if (!this.target) return;
|
||||
|
||||
// 计算目标位置
|
||||
const targetPosition = this.target.position.clone();
|
||||
targetPosition.add(this.offset);
|
||||
// 计算目标位置
|
||||
const targetPosition = this.target.position.clone();
|
||||
targetPosition.add(this.offset);
|
||||
|
||||
// 应用地图边界限制
|
||||
const clampedPosition = this.clampCameraPosition(targetPosition);
|
||||
// 应用地图边界限制
|
||||
const clampedPosition = this.clampCameraPosition(targetPosition);
|
||||
|
||||
// 使用插值实现平滑跟随
|
||||
const currentPosition = this.node.position;
|
||||
const newPosition = new Vec3();
|
||||
// 使用插值实现平滑跟随
|
||||
const currentPosition = this.node.position;
|
||||
const newPosition = new Vec3();
|
||||
|
||||
// 根据平滑度设置插值速度
|
||||
const lerpFactor = Math.min(1.0, this.followSpeed * deltaTime * (1 - this.smoothness + 0.1));
|
||||
// 根据平滑度设置插值速度
|
||||
const lerpFactor = Math.min(1.0, this.followSpeed * deltaTime * (1 - this.smoothness + 0.1));
|
||||
|
||||
Vec3.lerp(newPosition, currentPosition, clampedPosition, lerpFactor);
|
||||
this.node.position = newPosition;
|
||||
Vec3.lerp(newPosition, currentPosition, clampedPosition, lerpFactor);
|
||||
this.node.position = newPosition;
|
||||
}
|
||||
|
||||
// 限制相机位置在地图边界内
|
||||
private clampCameraPosition(position: Vec3): Vec3 {
|
||||
if (!this.camera) return position;
|
||||
|
||||
// 获取屏幕可见区域大小
|
||||
const visibleSize = view.getVisibleSize();
|
||||
|
||||
// 计算相机能看到的世界区域的一半
|
||||
const halfCameraWidth = visibleSize.width * 0.5;
|
||||
const halfCameraHeight = visibleSize.height * 0.5;
|
||||
|
||||
// 计算地图边界(地图锚点为0.5,0.5,所以范围是-mapWidth/2到+mapWidth/2)
|
||||
const mapHalfWidth = this.mapWidth * 0.5;
|
||||
const mapHalfHeight = this.mapHeight * 0.5;
|
||||
|
||||
// 计算相机位置的边界(确保相机边缘不超出地图边界)
|
||||
const minX = -mapHalfWidth + halfCameraWidth;
|
||||
const maxX = mapHalfWidth - halfCameraWidth;
|
||||
const minY = -mapHalfHeight + halfCameraHeight;
|
||||
const maxY = mapHalfHeight - halfCameraHeight;
|
||||
|
||||
// 限制相机位置
|
||||
const clampedPosition = position.clone();
|
||||
clampedPosition.x = Math.max(minX, Math.min(maxX, position.x));
|
||||
clampedPosition.y = Math.max(minY, Math.min(maxY, position.y));
|
||||
|
||||
return clampedPosition;
|
||||
}
|
||||
|
||||
// 设置跟随目标
|
||||
setTarget(target: Node) {
|
||||
this.target = target;
|
||||
if (target) {
|
||||
const initialPos = target.position.clone();
|
||||
initialPos.add(this.offset);
|
||||
this.node.position = initialPos;
|
||||
}
|
||||
}
|
||||
|
||||
// 限制相机位置在地图边界内
|
||||
private clampCameraPosition(position: Vec3): Vec3 {
|
||||
if (!this.camera) return position;
|
||||
// 设置偏移量
|
||||
setOffset(offset: Vec3) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
// 获取屏幕可见区域大小
|
||||
const visibleSize = view.getVisibleSize();
|
||||
// 瞬间移动到目标位置
|
||||
snapToTarget() {
|
||||
if (!this.target) return;
|
||||
|
||||
// 计算相机能看到的世界区域的一半
|
||||
const halfCameraWidth = visibleSize.width * 0.5;
|
||||
const halfCameraHeight = visibleSize.height * 0.5;
|
||||
|
||||
// 计算地图边界(地图锚点为0.5,0.5,所以范围是-mapWidth/2到+mapWidth/2)
|
||||
const mapHalfWidth = this.mapWidth * 0.5;
|
||||
const mapHalfHeight = this.mapHeight * 0.5;
|
||||
|
||||
// 计算相机位置的边界(确保相机边缘不超出地图边界)
|
||||
const minX = -mapHalfWidth + halfCameraWidth;
|
||||
const maxX = mapHalfWidth - halfCameraWidth;
|
||||
const minY = -mapHalfHeight + halfCameraHeight;
|
||||
const maxY = mapHalfHeight - halfCameraHeight;
|
||||
|
||||
// 限制相机位置
|
||||
const clampedPosition = position.clone();
|
||||
clampedPosition.x = Math.max(minX, Math.min(maxX, position.x));
|
||||
clampedPosition.y = Math.max(minY, Math.min(maxY, position.y));
|
||||
|
||||
return clampedPosition;
|
||||
}
|
||||
|
||||
// 设置跟随目标
|
||||
setTarget(target: Node) {
|
||||
this.target = target;
|
||||
if (target) {
|
||||
const initialPos = target.position.clone();
|
||||
initialPos.add(this.offset);
|
||||
this.node.position = initialPos;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置偏移量
|
||||
setOffset(offset: Vec3) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
// 瞬间移动到目标位置
|
||||
snapToTarget() {
|
||||
if (!this.target) return;
|
||||
|
||||
const targetPosition = this.target.position.clone();
|
||||
targetPosition.add(this.offset);
|
||||
const clampedPosition = this.clampCameraPosition(targetPosition);
|
||||
this.node.position = clampedPosition;
|
||||
}
|
||||
const targetPosition = this.target.position.clone();
|
||||
targetPosition.add(this.offset);
|
||||
const clampedPosition = this.clampCameraPosition(targetPosition);
|
||||
this.node.position = clampedPosition;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user