接入ResLogin.otherPlayers
This commit is contained in:
@@ -1,21 +1,28 @@
|
||||
import { Camera, Component, Node, Vec3, _decorator } from 'cc';
|
||||
import { _decorator, Camera, Component, find, Node, Vec3 } from 'cc';
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* CameraController 摄像机控制器
|
||||
* 负责让摄像机跟随指定的目标物体
|
||||
* 负责让摄像机跟随指定的目标物体,并提供摄像机坐标转换功能
|
||||
* 支持世界摄像机和UI摄像机的概念
|
||||
*/
|
||||
@ccclass('CameraController')
|
||||
export class CameraController extends Component {
|
||||
/** 跟随目标 */
|
||||
private target: Node = null;
|
||||
|
||||
/** 摄像机节点 */
|
||||
private cameraNode: Node = null;
|
||||
/** 世界摄像机节点 (Main Camera) */
|
||||
private worldCameraNode: Node = null;
|
||||
|
||||
/** 摄像机组件 */
|
||||
private camera: Camera = null;
|
||||
/** 世界摄像机组件 */
|
||||
private worldCamera: Camera = null;
|
||||
|
||||
/** UI摄像机节点 (Canvas/Camera) */
|
||||
private uiCameraNode: Node = null;
|
||||
|
||||
/** UI摄像机组件 */
|
||||
private uiCamera: Camera = null;
|
||||
|
||||
/** 相对偏移量 */
|
||||
private offset: Vec3 = new Vec3(0, 10, 8);
|
||||
@@ -29,21 +36,49 @@ export class CameraController extends Component {
|
||||
public smoothFollow: boolean = true;
|
||||
|
||||
onLoad() {
|
||||
this.findMainCamera();
|
||||
this.findCameras();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找主摄像机
|
||||
* 查找所有摄像机
|
||||
*/
|
||||
private findMainCamera(): void {
|
||||
// 查找名为 "Main Camera" 的摄像机
|
||||
const mainCameraNode = this.node.scene.getChildByName('Main Camera');
|
||||
private findCameras(): void {
|
||||
this.findWorldCamera();
|
||||
this.findUICamera();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找世界摄像机 (Main Camera)
|
||||
*/
|
||||
private findWorldCamera(): void {
|
||||
// 查找名为 "Main Camera" 的世界摄像机
|
||||
const mainCameraNode = find('Main Camera', this.node.scene);
|
||||
if (mainCameraNode) {
|
||||
this.cameraNode = mainCameraNode;
|
||||
this.camera = mainCameraNode.getComponent(Camera);
|
||||
console.log('[CameraController] 找到主摄像机:', mainCameraNode.name);
|
||||
this.worldCameraNode = mainCameraNode;
|
||||
this.worldCamera = mainCameraNode.getComponent(Camera);
|
||||
console.log('[CameraController] 找到世界摄像机:', mainCameraNode.name);
|
||||
} else {
|
||||
console.error('[CameraController] 未找到主摄像机(Main Camera)');
|
||||
console.error('[CameraController] 未找到世界摄像机(Main Camera)');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找UI摄像机 (Canvas/Camera)
|
||||
*/
|
||||
private findUICamera(): void {
|
||||
// 查找Canvas下的Camera作为UI摄像机
|
||||
const canvasNode = find('Canvas', this.node.scene);
|
||||
if (canvasNode) {
|
||||
const uiCameraNode = canvasNode.getChildByName('Camera');
|
||||
if (uiCameraNode) {
|
||||
this.uiCameraNode = uiCameraNode;
|
||||
this.uiCamera = uiCameraNode.getComponent(Camera);
|
||||
console.log('[CameraController] 找到UI摄像机:', uiCameraNode.name);
|
||||
} else {
|
||||
console.error('[CameraController] 未找到Canvas下的Camera节点');
|
||||
}
|
||||
} else {
|
||||
console.error('[CameraController] 未找到Canvas节点');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +89,7 @@ export class CameraController extends Component {
|
||||
public setTarget(target: Node): void {
|
||||
this.target = target;
|
||||
|
||||
if (this.target && this.cameraNode) {
|
||||
if (this.target && this.worldCameraNode) {
|
||||
// 立即设置初始位置
|
||||
this.updateCameraPosition(false);
|
||||
console.log('[CameraController] 设置跟随目标:', target.name);
|
||||
@@ -77,14 +112,35 @@ export class CameraController extends Component {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取摄像机节点
|
||||
* 获取世界摄像机节点
|
||||
*/
|
||||
public getCameraNode(): Node {
|
||||
return this.cameraNode;
|
||||
public getWorldCameraNode(): Node {
|
||||
return this.worldCameraNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取世界摄像机组件
|
||||
*/
|
||||
public getWorldCamera(): Camera {
|
||||
return this.worldCamera;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取UI摄像机节点
|
||||
*/
|
||||
public getUICameraNode(): Node {
|
||||
return this.uiCameraNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取UI摄像机组件
|
||||
*/
|
||||
public getUICamera(): Camera {
|
||||
return this.uiCamera;
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
if (this.target && this.cameraNode) {
|
||||
if (this.target && this.worldCameraNode) {
|
||||
this.updateCameraPosition(this.smoothFollow, deltaTime);
|
||||
}
|
||||
}
|
||||
@@ -95,7 +151,7 @@ export class CameraController extends Component {
|
||||
* @param deltaTime 帧时间(smooth为true时需要)
|
||||
*/
|
||||
private updateCameraPosition(smooth: boolean = true, deltaTime: number = 0): void {
|
||||
if (!this.target || !this.cameraNode) {
|
||||
if (!this.target || !this.worldCameraNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -105,17 +161,17 @@ export class CameraController extends Component {
|
||||
|
||||
if (smooth && deltaTime > 0) {
|
||||
// 平滑跟随
|
||||
const currentPosition = this.cameraNode.worldPosition;
|
||||
const currentPosition = this.worldCameraNode.worldPosition;
|
||||
const newPosition = new Vec3();
|
||||
Vec3.lerp(newPosition, currentPosition, targetPosition, this.followSpeed * deltaTime);
|
||||
this.cameraNode.setWorldPosition(newPosition);
|
||||
this.worldCameraNode.setWorldPosition(newPosition);
|
||||
} else {
|
||||
// 立即跟随
|
||||
this.cameraNode.setWorldPosition(targetPosition);
|
||||
this.worldCameraNode.setWorldPosition(targetPosition);
|
||||
}
|
||||
|
||||
// 让摄像机看向目标
|
||||
this.cameraNode.lookAt(this.target.worldPosition);
|
||||
this.worldCameraNode.lookAt(this.target.worldPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,13 +182,83 @@ export class CameraController extends Component {
|
||||
console.log('[CameraController] 停止跟随');
|
||||
}
|
||||
|
||||
/**
|
||||
* 将世界坐标转换为指定摄像机的屏幕坐标
|
||||
* @param worldPosition 世界坐标(Vec3)
|
||||
* @param camera 目标摄像机
|
||||
* @returns 摄像机坐标系下的屏幕坐标(Vec3),z为深度
|
||||
*/
|
||||
public worldToCameraPosition(worldPosition: Vec3, camera: Camera): Vec3 {
|
||||
if (!camera) {
|
||||
console.warn('[CameraController] 摄像机参数为空,无法进行坐标转换');
|
||||
return new Vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
// 使用摄像机的worldToScreen方法将世界坐标转换为屏幕坐标
|
||||
const screenPos = new Vec3();
|
||||
camera.worldToScreen(worldPosition, screenPos);
|
||||
return screenPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将摄像机屏幕坐标转换为指定Node的本地坐标
|
||||
* 计算流程:摄像机坐标 -> 世界坐标 -> Node本地坐标
|
||||
* @param screenPosition 摄像机屏幕坐标
|
||||
* @param sourceCamera 源摄像机
|
||||
* @param targetNode 目标Node节点
|
||||
* @returns 目标Node的本地坐标
|
||||
*/
|
||||
public CameraToNode(screenPosition: Vec3, sourceCamera: Camera, targetNode: Node): Vec3 {
|
||||
if (!sourceCamera || !targetNode) {
|
||||
console.warn('[CameraController] 摄像机或目标节点参数为空,无法进行坐标转换');
|
||||
return new Vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
// 第一步:摄像机屏幕坐标转世界坐标
|
||||
const worldPosition = new Vec3();
|
||||
sourceCamera.screenToWorld(screenPosition, worldPosition);
|
||||
|
||||
// 第二步:世界坐标转Node本地坐标
|
||||
const localPosition = new Vec3();
|
||||
targetNode.inverseTransformPoint(localPosition, worldPosition);
|
||||
|
||||
return localPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将世界坐标转换为UI摄像机节点的本地坐标
|
||||
* @param worldPosition 世界坐标
|
||||
* @returns UI摄像机节点的本地坐标
|
||||
*/
|
||||
public worldToUICamera(worldPosition: Vec3, node: Node): Vec3 {
|
||||
if (!this.worldCamera || !this.uiCameraNode) {
|
||||
console.warn('[CameraController] 世界摄像机或UI摄像机节点未初始化');
|
||||
return new Vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
// 第一步:世界坐标转世界摄像机屏幕坐标
|
||||
const worldCameraPos = this.worldToCameraPosition(worldPosition, this.worldCamera);
|
||||
|
||||
// 第二步:世界摄像机屏幕坐标转UI摄像机节点本地坐标
|
||||
const uiCameraLocalPos = this.CameraToNode(worldCameraPos, this.uiCamera, node);
|
||||
return uiCameraLocalPos;
|
||||
|
||||
// // 世界坐标转Node本地坐标
|
||||
// const localPosition = new Vec3();
|
||||
// node.inverseTransformPoint(localPosition, worldPosition);
|
||||
|
||||
return worldPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁控制器
|
||||
*/
|
||||
onDestroy(): void {
|
||||
this.target = null;
|
||||
this.cameraNode = null;
|
||||
this.camera = null;
|
||||
this.worldCameraNode = null;
|
||||
this.worldCamera = null;
|
||||
this.uiCameraNode = null;
|
||||
this.uiCamera = null;
|
||||
console.log('[CameraController] 摄像机控制器已销毁');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user