Game Development 24 min read

Build a Web 3D Endless Runner with Oasis Editor: Design, Code & Optimization

This article walks through creating a Web‑based 3D endless‑runner game using Oasis Editor, covering scene design, asset preparation, scripting, shader development, performance tuning, and the migration from Oasis 3D V2 to V3, with practical code examples and visual illustrations.

Alibaba Terminal Technology
Alibaba Terminal Technology
Alibaba Terminal Technology
Build a Web 3D Endless Runner with Oasis Editor: Design, Code & Optimization

Overview

The article uses the "Yuèbào 3D Runner" as a case study to demonstrate how front‑end developers can quickly start building Web 3D games with Oasis Editor, a cloud‑based 3D content platform built on the Ant‑developed Oasis 3D engine.

Game Design

The 3D scene is divided into three modules: the track, coins (and other items), and the player character.

Track design : Two copies of a building model are placed side by side and rotated counter‑clockwise. When the rotation reaches –θ, the building’s angle is reset to 0, creating a looping effect. The ground is a static circular‑arc mesh whose texture UV coordinates are shifted each frame to simulate scrolling.

Track structure diagram
Track structure diagram

Coin layout : The total number of coin rows is calculated from game duration, arc rotation time, and rows per arc. Formulas derive the interval between rows and the appearance time for each row. A JSON‑like queue describes each coin’s index, position (left, center, right), type, and spawn time.

[
  {
    "index": 0,
    "item": {"position": "center", "type": "coin"},
    "time": 0
  },
  {
    "index": 1,
    "item": {"position": "left", "type": "coin"},
    "time": 0.25
  }
  // ...
]

The queue is mapped to the 3D scene by selecting the appropriate slice of rows for the current arc index.

Development Workflow

Asset upload : Models (FBX or GLTF) and textures (WebP) are uploaded via the resource panel. Textures are often unbound from models to allow independent replacement.

Asset upload UI
Asset upload UI

Scene assembly : Create a scene tree, bind GLTF models, edit PBR materials, adjust the editor camera, and copy the view to the runtime camera.

Create scene tree

Bind GLTF model

Edit PBR material and bind textures

Adjust editor camera and copy view

Fine‑tune camera parameters

Final scene view
Final scene view

Logic Development

Scripts are attached to nodes to control behavior. Example: a coin‑rotation script updates the node’s rotation each frame.

onUpdate() {
  const { node } = this;
  TWEEN.update();
  if (this._isRotate && node.parentNode.isActive) {
    node.setRotationAngles(0, globalVal.coinAngle % 360, 0);
  }
}

Collision Detection

Sphere colliders are added to the player and coins. The engine checks intersections each frame. Collision events are listened to via:

let cd = node.createAbility(o3.ACollisionDetection);
cd.addEventListener('collision', e => {
  const colliderNode = e.data.collider.node;
  const name = colliderNode.name;
  // handle collision
});

Shader Development

Custom shaders are created to achieve visual effects such as track scrolling and light waves. A shader material definition includes vertex and fragment GLSL code, render states, uniforms, and attributes.

export const ShaderMaterial = {
  vertexShader: `
    uniform mat4 matModelViewProjection;
    uniform float utime;
    attribute vec3 a_position;
    attribute vec2 a_uv;
    varying vec2 v_uv;
    varying vec2 v_uv_run;
    void main() {
      gl_Position = matModelViewProjection * vec4(a_position, 1.0);
      v_uv = a_uv;
      v_uv_run = vec2(v_uv.s, v_uv.t + utime);
    }
  `,
  fragmentShader: `
    varying vec2 v_uv;
    varying vec2 v_uv_run;
    uniform sampler2D texturePrimary;
    uniform sampler2D textureLight;
    void main() {
      vec4 texSample = texture2D(texturePrimary, v_uv_run);
      vec4 texLightSample = texture2D(textureLight, v_uv);
      gl_FragColor = vec4(texSample.rgb * texSample.a + texLightSample.rgb * texLightSample.a, texSample.a);
    }
  `,
  states: {},
  uniforms: {},
  attributes: {}
};

The vertex shader updates UV coordinates to scroll the ground texture; the fragment shader blends a base texture with a light map.

Performance Optimization

Tools such as Chrome’s Performance panel and Spector.js are used to locate bottlenecks. Optimizations include reducing triangle count (from >200k to ~60k), merging static meshes, simplifying coin models, and using object pools to avoid frequent allocations.

Performance panel
Performance panel

Object‑pool example:

class CoinPool {
  private _originNode = null;
  private _pool = [];
  init(originNode, capacity = 5) {
    this._originNode = originNode;
    this._genNode(capacity);
  }
  getNode() {
    if (this._pool.length === 0) this._genNode();
    return this._pool.shift();
  }
  putNode(node) { if (this._pool.indexOf(node) === -1) this._pool.push(node); }
  _genNode(num = 1) {
    for (let i = 0; i < num; ++i) {
      let node = this._originNode.clone();
      changeParent(node);
      purifyNode(node);
      this._pool.push(node);
    }
  }
}

Business Integration

A glue layer (GameController) mediates between the React business layer and the Oasis game layer, exposing APIs such as gameInit and forwarding collision events back to the business side.

export default class GameController extends o3.EventDispatcher {
  constructor(rootNode, dispatch) { /* ... */ }
  getMessage(rootNode) { /* register collision listeners */ }
  gameInit(iconList, gameData) {
    const gameInit = new o3.Event('gameInit');
    gameInit.data = { iconList, gameData };
    this._oasis && this._oasis.resume();
    this._buildNNode1.trigger(gameInit);
    this._buildNNode2.trigger(gameInit);
    this._streetNode.trigger(gameInit);
  }
}

Oasis 3D V3 Migration

V3 introduces a streamlined resource manager, a class‑based math library, and online coding capabilities. Loading a GLTF model in V3 is reduced to a single async call:

const { defaultSceneRoot, animations } = await engine.resourceManager.load('xxx.gltf');
rootEntity.addChild(defaultSceneRoot);
const animator = root.getComponent(Animation);
animator.playAnimationClip('Take 001');

The new math library replaces array‑based vectors with class instances for better readability and performance.

Online Coding & Publishing

Developers can create, edit, and publish 3D projects directly in the browser. The interface includes a coding panel, an event panel for simulating business interactions, and a one‑click publish workflow.

Online coding UI
Online coding UI

Conclusion

The guide demonstrates end‑to‑end development of a Web 3D endless‑runner game, from asset preparation and scene construction to shader programming, performance tuning, and integration with a React business layer, while highlighting the benefits of the new Oasis 3D V3 architecture.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Performance OptimizationShaderWeb 3DOasis Editor
Alibaba Terminal Technology
Written by

Alibaba Terminal Technology

Official public account of Alibaba Terminal

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.