【重要|官方调研】关于引擎私有变量的访问

image

与其在这里搜集这些私有变量,还不如问问大家为啥要用这些变量,考虑下是不是接口没给够。大家不得已而为之

以后另外找list方案吧 :joy:


fgui里面也用了。。

对了。还有一堆插件

大家都不说,那我来说。

这种”优化“有面向汇报编程的嫌疑。

官方大佬们有空的话还是得捡些硬活来啃,游戏引擎毕竟是面向开发者的,最终得开发者投票,应该着力于解决开发者的痛点。ppt讲得好只是一时的,引擎做好才是永恒的。

5赞

我觉得官方对接口的态度更重要

  • 坚定维护公开接口的稳定性(稳定性包括最基本的函数签名不变,行为不变)
  • 私有接口坚决由调用者自己维护(同时多关注调用私有接口的潜在需求是什么)

让大家都遵循一定的使用规范,并且引擎的维护者自己也遵循这样的规范,才是合理的

4赞

比方scrollview这类不好用,但又不想改引擎代码,要不然升级引擎的时候一大堆merge,就只能通过继承或者hack的方式进行魔改,主要还是提供的满足不了需求,或者是体验,或者是性能,或者是特殊需求,这个也是js比较方便的地方,要不然就只剩下改引擎一条路了,不改引擎还能当扩展或者插件放商店卖一卖,改引擎的怎么放商店出售

spine._skeletonData._skeletonCache._animations
主要想获取指定的还未播放的动画的时长,用来做一些其他联动的逻辑处理。
assetManager._projectBundles
用来获取当前项目已设置的资源包名称,因为项目多人合作开发。会出现其他人新加了 bundle 代码还没上传,我这边拉取后台配置后去获取这个 bundle 报错。所以需要判断我当前已有的 bundle 再决定是否执行后面获取 bundle 的代码。



然后这里面好像用的会比较多,不知道有没有私有变量。

ScrollView的_setContentPosition,因为 ScrollView的setContentPosition方法已停用了,又不想用scrollToOffset

慎重啊!慎重啊!

// skeleton.ts
    /**
     * @en
     * The skeleton data contains the skeleton information (bind pose bones, slots, draw order,
     * attachments, skins, etc) and animations but does not hold any state.<br/>
     * Multiple skeletons can share the same skeleton data.
     * @zh
     * 骨骼数据包含了骨骼信息(绑定骨骼动作,slots,渲染顺序,
     * attachments,皮肤等等)和动画但不持有任何状态。<br/>
     * 多个 Skeleton 可以共用相同的骨骼数据。
     * @property {sp.SkeletonData} skeletonData
     */
    @editable
    @type(SkeletonData)
    @displayName('SkeletonData')
    get skeletonData (): SkeletonData | null {
        return this._skeletonData;
    }
// skeleton-data.ts
/**
     * @en Gets the included SkeletonData used in spine runtime.<br>
     * Returns a sp.spine.SkeletonData object.
     * @zh 获取 Spine Runtime 使用的 SkeletonData。<br>
     * 返回一个 p.spine.SkeletonData 对象。
     * @param quiet @en If vaulue is false, feedback information will be printed when an error occurs.
     *              @zh 值为 false 时,当发生错误时将打印出反馈信息。
     */
    public getRuntimeData (quiet?: boolean): spine.SkeletonData | null {
        if (this._skeletonCache) {
            return this._skeletonCache;
        }
// spine-core.d.ts
class SkeletonData {
        name: string;
        bones: BoneData[];
        slots: SlotData[];
        skins: Skin[];
        defaultSkin: Skin;
        events: EventData[];
        animations: Animation[];

这不都有共有接口吗?为什么非得用私有的?
spComp.skeletonData.getRuntimeData().animations 不能满足需求?

建议出个选项,可供选择是否进行对私有变量做压缩,可重新编译。

protected _clampDelta (out: Vec3): void {
protected _moveContent (deltaMove: Vec3, canStartBounceBack?: boolean): void {
protected _autoScrolling = false;
protected _getHowMuchOutOfBoundary (addition?: Vec3): Vec3 {
protected _dispatchEvent (event: string): void {
protected _autoScrolling = false;
    protected _scrolling = false;
    @serializable
    protected _content: Node | null = null;
    @serializable
    protected _horizontalScrollBar: ScrollBar | null = null;
    @serializable
    protected _verticalScrollBar: ScrollBar | null = null;

    protected _topBoundary = 0;
    protected _bottomBoundary = 0;
    protected _leftBoundary = 0;
    protected _rightBoundary = 0;

    protected _touchMoveDisplacements: Vec3[] = [];
    protected _touchMoveTimeDeltas: number[] = [];
    protected _touchMovePreviousTimestamp = 0;
    protected _touchMoved = false;
    protected _autoScrollAttenuate = false;
    protected _autoScrollStartPosition = new Vec3();
    protected _autoScrollTargetDelta = new Vec3();
    protected _autoScrollTotalTime = 0;
    protected _autoScrollAccumulatedTime = 0;
    protected _autoScrollCurrentlyOutOfBoundary = false;
    protected _autoScrollBraking = false;
    protected _autoScrollBrakingStartPosition = new Vec3();

    protected _outOfBoundaryAmount = new Vec3();
    protected _outOfBoundaryAmountDirty = true;
    protected _stopMouseWheel = false;
    protected _mouseWheelEventElapsedTime = 0.0;
    protected _isScrollEndedWithThresholdEventFired = false;
    // use bit wise operations to indicate the direction
    protected _scrollEventEmitMask = 0;
    protected _isBouncing = false;
    protected _contentPos = new Vec3();
    protected _deltaPos = new Vec3();
    protected _deltaAmount = new Vec3();

    protected _hoverIn: XrhoverType = XrhoverType.NONE;

注意看,这些 protected 修饰的属性不会做压缩处理的,你要 hack 可以继续 hack。Happy Hacking.

至于 private _getContentPosition ,你可以用 public 的接口替代:

public getContentPosition (): Vec3 {
        return this._getContentPosition();
    }

第二个社区版中会有这个选项。有需要的可以去设置。
但是私有变量还是以 $ 结尾,如果项目中有 hack 私有变量,需要做两件事:

  1. 构建选项中,不勾选“压缩 $ 后缀的属性”
  2. 为项目代码中用到的引擎私有变量字符串加上 $ 后缀。

这两个接口,之前有 issue,可以考虑在第二个社区版本中加上。

https://github.com/cocos/cocos-engine/issues/17123

// skeleton.ts
public _skeleton: spine.Skeleton = null!;

这个是公有接口,不会压缩。

虽然可供选择了,但依旧需要去修改代码,不是最佳方案。 能否在勾选不压缩的时候,去掉$这个尾巴?

嗯,既要又要还要。

那当我没说咯

虽然这个建议看似合理,但实现起来确实有点困难,大概率是没办法了。

1、所有用了私有变量的项目,加一个$尾巴,工作量应该不大。 总不至于整个项目全用的私有变量。
2、这个$是引擎代码里加的,动态改起来比较难,并且成本高。
3、当你访问的变量带有 $ 尾巴时,说明引擎并不推荐访问 ,后面的版本中有可能随时变,就得注意了。

我觉得要从两方面解决。
1、加上开关(这个内部版本已经有了,下一次社区版更新就会有)
2、大家把访问到的私有变量和需求都多说说,推进引擎接口的完善。这才是长久的路线。

恩,我也只是提出建议,其中难度并不清楚,如此的话,也只能翻阅代码进行修改了。