跳转到内容

世界流式加载

@esengine/world-streaming 提供基于区块的世界流式加载与管理,适用于开放世界游戏。根据玩家位置动态加载/卸载世界区块。

Terminal window
npm install @esengine/world-streaming
import {
ChunkManager,
ChunkStreamingSystem,
StreamingAnchorComponent,
ChunkLoaderComponent
} from '@esengine/world-streaming';
// 创建区块管理器 (512单位区块)
const chunkManager = new ChunkManager(512);
chunkManager.setScene(scene);
// 添加流式加载系统
const streamingSystem = new ChunkStreamingSystem();
streamingSystem.setChunkManager(chunkManager);
scene.addSystem(streamingSystem);
// 创建加载器实体
const loaderEntity = scene.createEntity('ChunkLoader');
const loader = loaderEntity.addComponent(new ChunkLoaderComponent());
loader.chunkSize = 512;
loader.loadRadius = 2;
loader.unloadRadius = 4;
// 创建玩家作为流式锚点
const playerEntity = scene.createEntity('Player');
const anchor = playerEntity.addComponent(new StreamingAnchorComponent());
// 每帧更新锚点位置
function update() {
anchor.x = player.position.x;
anchor.y = player.position.y;
}
import type { IChunkDataProvider, IChunkCoord, IChunkData } from '@esengine/world-streaming';
class ProceduralChunkProvider implements IChunkDataProvider {
private seed: number;
constructor(seed: number) {
this.seed = seed;
}
async loadChunkData(coord: IChunkCoord): Promise<IChunkData | null> {
// 使用种子+坐标生成确定性随机数
const chunkSeed = this.hashCoord(coord);
const rng = this.createRNG(chunkSeed);
// 生成区块内容
const entities = this.generateEntities(coord, rng);
return {
coord,
entities,
version: 1
};
}
async saveChunkData(data: IChunkData): Promise<void> {
// 可选:持久化已修改的区块
}
private hashCoord(coord: IChunkCoord): number {
return this.seed ^ (coord.x * 73856093) ^ (coord.y * 19349663);
}
private createRNG(seed: number) {
// 简单的种子随机数生成器
return () => {
seed = (seed * 1103515245 + 12345) & 0x7fffffff;
return seed / 0x7fffffff;
};
}
private generateEntities(coord: IChunkCoord, rng: () => number) {
// 生成资源、树木等
return [];
}
}
// 使用数据提供器
chunkManager.setDataProvider(new ProceduralChunkProvider(12345));
未加载 → 加载中 → 已加载 → 卸载中 → 未加载
↓ ↓
失败 (发生错误时)

StreamingAnchorComponent 用于标记作为区块加载锚点的实体。系统会在所有锚点周围加载区块,在超出范围时卸载区块。

// StreamingAnchorComponent 实现 IPositionable 接口
interface IPositionable {
readonly position: { x: number; y: number };
}
属性默认值说明
chunkSize512区块大小(世界单位)
loadRadius2锚点周围加载的区块半径
unloadRadius4超过此半径的区块会被卸载
maxLoadsPerFrame2每帧最大异步加载数
unloadDelay3000卸载前的延迟(毫秒)
bEnablePrefetchtrue沿移动方向预加载

使用模块辅助函数快速配置:

import { worldStreamingModule } from '@esengine/world-streaming';
const chunkManager = worldStreamingModule.setup(
scene,
services,
componentRegistry,
{ chunkSize: 256, bEnableCulling: true }
);