getLocation 与 getUILocation

傻傻分不清,只好自己去看清!

游戏开发中少不了触摸操作,在 Cocos Creator 3.x 中触摸事件中有 getLocationgetUILocation 这两个方法,刚开始看到会有些困惑,所以就简单整理一下其中的奥妙。

da8930b0bdd622eebfcd64e0a5eb9f52.png
getLocation getUILocation

白玉无冰决定在 Creator 3.4 探讨 EventTouch 中的 getLocationgetUILocation 的区别。

先看一眼声明文件,好像不是很明白。

b3a1279aa7a39b5624c68f7be7cab629.png
声明文件中的注释

再搜一搜官方文档,看来关键点是在 UI窗口

5438773515e32449acbcb61a801765ac.png
官方文档

再翻源码瞧瞧,看看这两口子有什么区别!

aa6ec9ff7d3841a20ac1337e9a44eb24.png
touch.ts 源码

盲生发现华点了!区别在 view._convertToUISpace,继续前进看看!

f0fed6bdec5e9c79adfe816f313616d3.png
_convertToUISpace

看来 getUILocation 获得的坐标是 getLocation 的基础上偏移一个位置,再放大一个系数。

接着再跟进 viewportRectscale 是如何变化的。

894b0b4036b29edae68544bb5245dc0b.png
setDesignResolutionSize

viewportRectscale 是在设置设计分辨率和匹配模式来进行游戏画面的屏幕适配时变化的。

原来 getUILocation 是设计分辨率与匹配模式相关的!

既然涉及到匹配模式,这里把所有匹配策略的代码抠出来。dc473af19502969b8668653af4922f5f.png

ContentStrategy

scale 就是根据这些适配策略的算出来的,详细的说明就不细细展开了,可以参考代码或者官方文档。https://docs.cocos.com/creator/manual/zh/ui-system/components/engine/multi-resolution.html

c630bbc0cc76e2cfc9239a000e854c88.png
官方文档-多分辨率适配方案

viewportRect  是根据不同策略的容器大小关系算出的。

ea1c43679f3186e62dc960ccc73a813e.png
_buildResult

接下来验证一下吧!随便写一个测试代码。

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);
    }
}

根据代码推论,当设计分辨率与屏幕分辨率一致时,getLocationgetUILocation 得到结果是相同的。

0261081826c84b0ba2410ca06311dbd6.png


分辨率一致

当分辨率不一致时,根据适配策略会有些许不同:

  • ExactFit 有不同缩放系数 scaleX,scaleY

  • ShowAll 有位置偏移和相同的缩放系数。

  • NoBorder 有位置偏移和相同的缩放系数。

  • FixedHeight 有相同的缩放系数。

  • FixedWidth 有相同的缩放系数。b1f34cf923864a1d121839e7115fb587.png

 分辨率不一致

那么为何有时需要位置偏移呢?关于这一点,白玉无冰没有悟出来。等一个有缘人来化解这个坎。

23df4646769933360640fe757d1e3a9d.png
为何 contentH 有不同的处理

最后,结合放空老师的一文搞懂 Cocos Creator 3.0 坐标转换原理可以得出结论:

  • 设计分辨率、实际分辨率以及适配策略决定了 getUILocationgetLocation 的变化函数关系。

  • getUILocation 可以用来直接设置 UI 元素的世界坐标

  • getLocation 用于射线检测等坐标转换。

本次探索之旅已结束,以上是白玉无冰根据 Cocos Creator 3.4 源码对getLocationgetUILocation 的分析。

快过年了,祝大伙万事如意!随手画了一个微信红包皮!送给大伙!

2b2e3ade6cb924b32b0222dad571671a.png


更多精彩欢迎关注微信公众号

4e4b7a68d83543fabe7b9b2aa5a426be.png

➡️【2021年原创精选】

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值