[开发者心得] 【027】【性能教室】俯视角游戏逻辑剔除优化

[复制链接]
1046 |0
喵喵哭唧唧 发表于 2023-4-18 19:01:37 | 显示全部楼层 |阅读模式
本帖最后由 哭唧唧的细狗 于 2023-10-31 17:35 编辑

                                                                                          所使用编辑器版本:Online_v0.27.0.0



什么是逻辑剔除
在一个3D游戏中,常见的优化手段,我们能想到的有:
1.摄像机朝向的方向,既我们看到的屏幕区域内的内容,才会被渲染
2.怪物,其他玩家之类的,离当前用户一定距离外,不渲染,也不更新他们的逻辑,甚至不在客户端创建该对象,这就是逻辑优化

当有了以上的优化手段,无论是渲染的压力,还是处理逻辑的压力,都会有减少

目前编辑器里渲染方面的优化是已有的了,逻辑优化正在路上

对俯视角游戏的优化
Q:那么我一个俯视角游戏,是不是编辑器提供的优化可能也无法完全满足需求呢?

A:这是有可能的

我们游戏场景较大,怪物不是一下子出现在玩家屏幕内,而是分批次的进入玩家视野。
所以我们可以让玩家视野外的怪物不参与部分逻辑计算。
这样除了必须的同屏怪物,我们还可以承载更多的离屏怪物数量。能更好的表现怪物源源不断的这个效果,造成怪物数量很多的错觉。
(我们游戏是伪2d。考虑实现难度和性能直接建了一个以玩家为中心,长宽配置的AABB碰撞盒)

image.png

(图1)233上的高品质游戏皇家猎人范围演示截图

最小Demo运行起来实际的效果

场景中原本放置了4个对象,如图2绿色框中的情况
image.png
(图2)

最小Demo演示视频:红框会随着角色移动,但是超出红框范围的对象会被裁剪掉


Demo中的一些细节
image.png
(场景里添加了NewScript脚本作为入口初始化以及4个用来显影的对象)



/**
     * 周期函数 每帧执行
     * 此函数执行需要将this.useUpdate赋值为true
     * @param dt 当前帧与上一帧的延迟 / 秒
     */
    protected onUpdate(dt: number): void {
        if (this.playerViewport && this.cha) {
            // 随时更新红色视口的范围,设置范围的值
            this.playerViewport.min.set(this.cha.worldTransform.position).subtract(PLAYER_VIEWPORT_SIZE);
            this.playerViewport.max.set(this.cha.worldTransform.position).add(PLAYER_VIEWPORT_SIZE);

            if (this.Debug) {
                for (const transform of this.arrayGo) {
                    // 当对象在范围内
                    if (this.playerViewport.in(transform.worldTransform.position)) {
                        // 则显示它
                        transform.setVisibility(mw.PropertyStatus.On)
                    } else {
                        // 否则不显示它
                        transform.setVisibility(mw.PropertyStatus.Off)
                    }
                }
            }

            // 绘制这个范围
            this.playerViewport.draw();
        }

    }


在上述判断显示逻辑的代码里:
1.不显示对象的逻辑里,加上对象逻辑剔除的代码
2.或者只在显示的逻辑里,加上更新对象逻辑的代码
都能达到优化性能的目的




/**
     * 判断指定坐标是否在区域内
     * @param location
     * @returns
     */
    in(location: Type.Vector) {
        if (location.x <= this.min.x || location.y <= this.min.y || location.x >= this.max.x || location.y >= this.max.y) {
            return false;
        }
        return true;
    }


最小Demo
RectangleTest.rar (130.56 KB, 下载次数: 33)
回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表