getLocation 与 getUILocation
共 2448字,需浏览 5分钟
·
2022-02-20 10:16
傻傻分不清,只好自己去看清!
游戏开发中少不了触摸操作,在 Cocos Creator 3.x
中触摸事件中有 getLocation
和 getUILocation
这两个方法,刚开始看到会有些困惑,所以就简单整理一下其中的奥妙。
![e83e5e8846c5e034aa629a41087aaf37.webp](https://filescdn.proginn.com/5a0bb19a09ab6208736fe02cff1de616/e83e5e8846c5e034aa629a41087aaf37.webp)
白玉无冰决定在 Creator 3.4
探讨 EventTouch
中的 getLocation
与 getUILocation
的区别。
先看一眼声明文件,好像不是很明白。
![404976a72327e2104d3c48bd3d1bf0c4.webp](https://filescdn.proginn.com/bfcb375f34278d841be25795d7e3ad46/404976a72327e2104d3c48bd3d1bf0c4.webp)
再搜一搜官方文档,看来关键点是在 UI窗口
。
![66541c0af1d7f7559203b1de4d398374.webp](https://filescdn.proginn.com/4878b4cb90dfbfe56a277cda10277371/66541c0af1d7f7559203b1de4d398374.webp)
再翻源码瞧瞧,看看这两口子有什么区别!
![2566766ea7094c945b797a54abdf6500.webp](https://filescdn.proginn.com/46926aabf808aa21fb151e92d9832257/2566766ea7094c945b797a54abdf6500.webp)
盲生发现华点了!区别在 view._convertToUISpace
,继续前进看看!
![0e7258d136ed10ff4f5996bae9a2b65b.webp](https://filescdn.proginn.com/2bdf0ece577e26ae78a1c6ed437f72c7/0e7258d136ed10ff4f5996bae9a2b65b.webp)
看来 getUILocation
获得的坐标是 getLocation
的基础上偏移一个位置,再放大一个系数。
接着再跟进 viewportRect
和 scale
是如何变化的。
![b0958472c77f30e195b873907ba0d1d4.webp](https://filescdn.proginn.com/e2ed26f84d637c81e561ce267e17c1db/b0958472c77f30e195b873907ba0d1d4.webp)
viewportRect
和 scale
是在设置设计分辨率和匹配模式来进行游戏画面的屏幕适配时变化的。
原来 getUILocation
是设计分辨率与匹配模式相关的!
既然涉及到匹配模式,这里把所有匹配策略的代码抠出来。
scale
就是根据这些适配策略的算出来的,详细的说明就不细细展开了,可以参考代码或者官方文档。https://docs.cocos.com/creator/manual/zh/ui-system/components/engine/multi-resolution.html
![72f73cf0d009f60c3bad54aad6ba59b9.webp](https://filescdn.proginn.com/726875e7ae80ce8cd9c1be23da94c502/72f73cf0d009f60c3bad54aad6ba59b9.webp)
而 viewportRect
是根据不同策略的容器大小关系算出的。
![3d7a8876948ac3b4d7b835c98a3ab755.webp](https://filescdn.proginn.com/d8c801f96873c3e7adb8efbaedff9f32/3d7a8876948ac3b4d7b835c98a3ab755.webp)
接下来验证一下吧!随便写一个测试代码。
import { _decorator, Component, Node, Label, input, Input, EventTouch, view, screen } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('NewComponent')
export class NewComponent extends Component {
@property(Label)
lb: Label = null!;
@property(Node)
click: Node = null!;
start() {
input.on(Input.EventType.TOUCH_START, this.onTouch, this);
input.on(Input.EventType.TOUCH_MOVE, this.onTouch, this);
}
onTouch(evt: EventTouch) {
const UILocation = evt.getUILocation();
this.lb.string =
`
getLocation:${evt.getLocation().toString()}
getUILocation:${UILocation.toString()}
getLocationInView:${evt.getLocationInView().toString()}
view scale:(${view.getScaleX().toFixed(3)},${view.getScaleY().toFixed(3)})
ViewportRect:${view.getViewportRect()}
DesignResolutionSize:${view.getDesignResolutionSize().toString()}
screen.windowSize:${screen.windowSize.toString()}
ResolutionPolicy:${view.getResolutionPolicy()._contentStrategy.name}
`;
this.click.setWorldPosition(UILocation.x, UILocation.y, 0);
}
}
根据代码推论,当设计分辨率与屏幕分辨率一致时,getLocation
和 getUILocation
得到结果是相同的。
分辨率一致
当分辨率不一致时,根据适配策略会有些许不同:
ExactFit
有不同缩放系数scaleX
,scaleY
ShowAll
有位置偏移和相同的缩放系数。NoBorder
有位置偏移和相同的缩放系数。FixedHeight
有相同的缩放系数。FixedWidth
有相同的缩放系数。
那么为何有时需要位置偏移呢?关于这一点,白玉无冰没有悟出来。等一个有缘人来化解这个坎。
![a82e994ac88e5f1e0aeab97dcbfb151a.webp](https://filescdn.proginn.com/08d762269e125d4235fdab7261f7b795/a82e994ac88e5f1e0aeab97dcbfb151a.webp)
最后,结合放空老师的一文搞懂 Cocos Creator 3.0 坐标转换原理可以得出结论:
- 设计分辨率、实际分辨率以及适配策略决定了
getUILocation
与getLocation
的变化函数关系。 getUILocation
可以用来直接设置 UI 元素的世界坐标getLocation
用于射线检测等坐标转换。
本次探索之旅已结束,以上是白玉无冰根据 Cocos Creator 3.4
源码对getLocation
和 getUILocation
的分析。
快过年了,祝大伙万事如意!随手画了一个微信红包皮!送给大伙!
更多精彩欢迎关注微信公众号