getLocation 与 getUILocation

Posted by lamyoung on January 23, 2022

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

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

getLocation getUILocation

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

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

声明文件中的注释

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

官方文档

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

touch.ts 源码

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

_convertToUISpace

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

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

setDesignResolutionSize

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

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

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

ContentStrategy

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

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

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

_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 得到结果是相同的。

分辨率一致

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

  • ExactFit 有不同缩放系数 scaleX,scaleY
  • ShowAll 有位置偏移和相同的缩放系数。
  • NoBorder 有位置偏移和相同的缩放系数。
  • FixedHeight 有相同的缩放系数。
  • FixedWidth 有相同的缩放系数。

分辨率不一致

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

为何 contentH 有不同的处理

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

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

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

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


➡️【2021年原创精选】