getLocation 与 getUILocation

白玉无冰

共 2448字,需浏览 5分钟

 ·

2022-02-20 10:16

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

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

e83e5e8846c5e034aa629a41087aaf37.webpgetLocation getUILocation

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

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

404976a72327e2104d3c48bd3d1bf0c4.webp声明文件中的注释

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

66541c0af1d7f7559203b1de4d398374.webp官方文档

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

2566766ea7094c945b797a54abdf6500.webptouch.ts 源码

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

0e7258d136ed10ff4f5996bae9a2b65b.webp_convertToUISpace

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

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

b0958472c77f30e195b873907ba0d1d4.webpsetDesignResolutionSize

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

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

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

ContentStrategy

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

72f73cf0d009f60c3bad54aad6ba59b9.webp官方文档-多分辨率适配方案

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

3d7a8876948ac3b4d7b835c98a3ab755.webp_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 得到结果是相同的。

b64634167bf997333516d16d512dde63.webp


分辨率一致

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

  • ExactFit 有不同缩放系数 scaleX,scaleY
  • ShowAll 有位置偏移和相同的缩放系数。
  • NoBorder 有位置偏移和相同的缩放系数。
  • FixedHeight 有相同的缩放系数。
  • FixedWidth 有相同的缩放系数。19058ea3e0f8a9f2ef12c2854eaff873.webp
 分辨率不一致

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

a82e994ac88e5f1e0aeab97dcbfb151a.webp为何 contentH 有不同的处理

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

  • 设计分辨率、实际分辨率以及适配策略决定了 getUILocationgetLocation 的变化函数关系。
  • getUILocation 可以用来直接设置 UI 元素的世界坐标
  • getLocation 用于射线检测等坐标转换。

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

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

e3104c6b1dc0549f931e60e534d50e1d.webp



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


➡️【2021年原创精选】


浏览 194
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报