import {Camera, Component, EventTouch, find, Input, input, Mat4, Node, UITransform, v3, Vec2, Vec3} from 'cc';
/**
* 坐标转换
*/
export class CoordinateConversionView extends Component {
private canvasNode: Node = null;
private camera3D: Camera = null;
private cameraUI: Camera = null;
private cube: Node = null;
private cubeA: Node = null;
private cubeB: Node = null;
private button: Node = null;
private test1: Node = null;
private label1: Node = null;
private test2: Node = null;
protected start(): void {
this.cubeA = this.node.getChildByName("CubeA");
this.cubeB = this.node.getChildByName("CubeB");
this.canvasNode = this.node.getChildByName("Canvas");
this.cameraUI = find("Canvas/Camera", this.node).getComponent(Camera);
this.button = find("Canvas/Button", this.node);
this.test1 = find("Canvas/Test1", this.node);
this.label1 = this.test1.getChildByName("Label1");
this.test2 = find("Canvas/Test2", this.node);
}
public init(camera3D: Camera, cube: Node): void {
this.camera3D = camera3D;
this.cube = cube;
}
protected onEnable(): void {
this.listener(true);
}
protected onDisable(): void {
this.listener(false);
}
private listener(isAdd: boolean): void {
if (isAdd) {
input.on(Input.EventType.TOUCH_START, this.onTouchHandler, this);
} else {
input.on(Input.EventType.TOUCH_START, this.onTouchHandler, this);
}
}
private onTouchHandler(event: EventTouch): void {
//屏幕坐标的获取: 2D当中代表UI坐标,3D中代表屏幕坐标
let screenPos: Vec2 = event.getLocation();
//UI最表获取
let uiPos: Vec2 = event.getUILocation();
console.log(`%c screen x:${screenPos.x} ,y:${screenPos.y}`, "color:#F00");
console.log(`%c ui x: ${uiPos.x} , y: ${uiPos.y}`, "color:#F00");
// this.screen2Ui(screenPos, uiPos);
// this.ui2Screen(screenPos, uiPos);
// this.screenTo3D(screenPos, uiPos);
// this.threeD2Screen2UI(screenPos, uiPos);
// this.threeD2UI(screenPos, uiPos);
// this.ui2ui(screenPos, uiPos);
this.threeD(screenPos, uiPos);
}
/**
* <屏幕 => UI>: 点击屏幕让UI上的btnNode节点设置到点击位置上
*/
private screen2Ui(screenPos: Vec2, uiPos: Vec2): void {
//方法1: 坐标转换(不会出错)
let uiPoint: Vec3 = this.cameraUI.screenToWorld(v3(screenPos.x, screenPos.y, 0));
this.button.setWorldPosition(uiPoint);
//方法2: 直接使用UI坐标(若:parent的坐标不是(0,0)就会出错)
// this.btnNode.setWorldPosition(v3(uiPos.x, uiPos.y, 0));
}
/**
* UI坐标到屏幕坐标
*/
private ui2Screen(screenPos: Vec2, uiPos: Vec2): void {
let screenPoint: Vec3 = this.cameraUI.worldToScreen(v3(uiPos.x, uiPos.y, 0));
console.log(
`%c ui2Screen x: ${screenPoint.x}-${screenPos.x} , y: ${screenPoint.y}-${screenPos.y}`,
"color:#0F0"
);
}
//设置cube(3D)到屏幕位置
private screenTo3D(screenPos: Vec2, uiPos: Vec2): void {
let cZ: number = this.camera3D.node.worldPosition.z / 1000;
let worldPoint: Vec3 = this.camera3D.screenToWorld(v3(screenPos.x, screenPos.y, cZ));
this.cube.setWorldPosition(worldPoint);
}
/**
* 3D -> Screen -> UI
* 将button放在cube的上面
*/
private threeD2Screen2UI(screenPos: Vec2, uiPos: Vec2): void {
let screenPoint: Vec3 = this.camera3D.worldToScreen(this.cube.worldPosition);
let uiPoint: Vec3 = this.cameraUI.screenToWorld(screenPoint);
this.button.setWorldPosition(uiPoint);
}
//将button放在cube的上面
private threeD2UI(screenPos: Vec2, uiPos: Vec2): void {
let out: Vec3 = new Vec3();
this.camera3D.convertToUINode(this.cube.worldPosition, this.canvasNode, out);
this.button.parent = this.canvasNode;
this.button.position = out;
}
//UI内部坐标转换
private ui2ui(screenPos: Vec2, uiPos: Vec2): void {
let pos: Vec3 = new Vec3();
let test2UITransform: UITransform = this.test2.getComponent(UITransform);
// test2UITransform.convertToNodeSpaceAR(this.label1.worldPosition, pos);//这种也行
pos = test2UITransform.convertToNodeSpaceAR(this.label1.worldPosition);
this.label1.parent = this.test2;
this.label1.position = pos;
}
//将cubeB放在cubeA下
private threeD(screenPos: Vec2, uiPos: Vec2): void {
let tempPos: Vec3 = new Vec3();
let tempMat4: Mat4 = new Mat4();
Mat4.invert(tempMat4, this.cubeA.getWorldMatrix()); //得到A的逆矩阵
Vec3.transformMat4(tempPos, this.cubeB.worldPosition, tempMat4); //得到B在A中的坐标
this.cubeB.parent = this.cubeA;
this.cubeB.position = tempPos;
}
protected onDestroy(): void {
this.camera3D = null;
this.cubeA = null;
this.cubeB = null;
this.cameraUI = null;
this.button = null;
this.test1 = null;
this.label1 = null;
this.test2 = null;
this.cube = null;
this.canvasNode = null;
}
}
/**
* <屏幕 => UI>: 点击屏幕让UI上的btnNode节点设置到点击位置上
*/
private screen2Ui(screenPos: Vec2, uiPos: Vec2): void {
//方法1: 坐标转换(不会出错)
let uiPoint: Vec3 = this.cameraUI.screenToWorld(v3(screenPos.x, screenPos.y, 0));
this.button.setWorldPosition(uiPoint);
//方法2: 直接使用UI坐标(若:parent的坐标不是(0,0)就会出错)
// this.btnNode.setWorldPosition(v3(uiPos.x, uiPos.y, 0));
}
//将cubeB放在cubeA下
private threeD(screenPos: Vec2, uiPos: Vec2): void {
let tempPos: Vec3 = new Vec3();
let tempMat4: Mat4 = new Mat4();
Mat4.invert(tempMat4, this.cubeA.getWorldMatrix()); //得到A的逆矩阵
Vec3.transformMat4(tempPos, this.cubeB.worldPosition, tempMat4); //得到B在A中的坐标
this.cubeB.parent = this.cubeA;
this.cubeB.position = tempPos;
}