[开发者心得] 【027】【性能教室】性能优化实战

[复制链接]
2584 |0
喵喵哭唧唧 发表于 2023-4-20 16:12:35 | 显示全部楼层 |阅读模式
本帖最后由 哭唧唧的细狗 于 2023-11-1 16:28 编辑
在A项目中拥有大量的随机怪物。怪物们会依次随机出生在场景中的某个点,然后找到玩家的位置并攻击玩家。程序小Z在经过一段时间的编码并完成了上述逻辑后,兴冲冲地打了个手机包准备在真机上看看效果。结果一上真机,小Z傻了眼,他发现随着怪物数量增多,帧率越来越低。。。
通过性能工具分析,小Z发现性能瓶颈主要在怪物生成和怪物移动上,在解决了怪物生成造成的性能瓶颈后,移动上的性能瓶颈仍然存在且无从下手。
可以先想想自己的解决方案喔~

👇下面是小Z最开始的伪代码和性能分析日志👇

这段代码实现了一个怪物的类和怪物AI逻辑的类。
怪物类有一个显示对象、移动速度和位置属性。
怪物AI逻辑类通过不断调用update方法来更新怪物的位置和攻击目标。
其中,攻击目标的判断是通过怪物和目标的位置距离来判断的,如果距离小于100就攻击目标。怪物的移动是通过方向向量乘以速度加上旧位置来得到新位置的方式来实现的。



const tempOffsetDir = Vector.zero;
@Component
export default class Monster extends Script {
    private moveSpeed: number = 30;

    public set location(value: Vector) {
        this.gameObject.worldTransform.position.set(value);
    }

    public get location() {
        return this.gameObject.worldTransform.position
    }

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {

        Event.addLocalListener("TickAble", this.updateTickAble)
        this.updateTickAble();
    }

    /**
     * 周期函数 每帧执行
     * 此函数执行需要将this.useUpdate赋值为true
     * @param dt 当前帧与上一帧的延迟 / 秒
     */
    protected onUpdate(dt: number): void {
        let target = Player.localPlayer.character.worldTransform.position

        if (Vector.squaredDistance(target, this.location) <= 100) {
            return;
        } else {
            // 求出距离目标的方向
            tempOffsetDir.set(target).subtract(this.location).normalize();
            // 方向向量乘以速度+旧位置 = 新位置
            tempOffsetDir.multiply(this.moveSpeed * dt).add(this.location);
            this.location = tempOffsetDir;
        }


    }

    private updateTickAble = () => {
        this.useUpdate = monsterIns.tickAble;
    }

    /** 脚本被销毁时最后一帧执行完调用此函数 */
    protected onDestroy(): void {

    }
}


image.png

(图1 优化前帧率图 平均耗时5ms)
👇性能分析日志
un_optimized_monster.rar (87.76 KB, 下载次数: 71)
回复

使用道具 举报

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