# 快速上手 `u-space`

`u-space` 是一个基于 Three.js 的 WebGPU 3D 引擎。本指南使用 React、TypeScript 和 Vite 搭建一个基础应用。

## 创建项目

### 1. 初始化 React + Vite

```bash
pnpm create vite u-space-demo --template react-ts
cd u-space-demo
pnpm install
```

### 2. 安装 `u-space`

```bash
pnpm add u-space three camera-controls
pnpm add -D @types/three
```

Vite 会直接解析 npm 包及 `three/webgpu`，不需要额外配置模块映射。

## 编写场景组件

### 1. 替换 `src/App.tsx`

下面的组件会初始化 `Viewer`、添加一个可交互的立方体，并在 React 组件卸载时释放资源。

```tsx
import { useEffect, useRef } from 'react';
import { BoxGeometry, Color, GridHelper, MeshBasicMaterial } from 'three/webgpu';
import { BaseMesh, Viewer } from 'u-space';

export default function App() {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    let viewer: Viewer | undefined;
    let cancelled = false;

    async function setup() {
      const nextViewer = new Viewer({
        el: container,
        rendererOptions: { forceWebGL: false },
      });
      await nextViewer.init();

      // 兼容 React StrictMode 在开发环境中的重复挂载检查
      if (cancelled) {
        nextViewer.dispose();
        return;
      }

      nextViewer.scene.background = new Color(0x666666);
      nextViewer.scene.add(new GridHelper(10, 10));

      const material = new MeshBasicMaterial({ color: 0xff0000 });
      const box = new BaseMesh(new BoxGeometry(1, 1, 1), material);
      box.position.set(0, 0.5, 0);
      nextViewer.scene.add(box);

      nextViewer.interactionManager.pointerMoveEventsEnabled = true;

      box.addEventListener('click', ({ event }) => {
        console.log('点击位置：', event.intersect?.point);
        material.color.set(Math.random() * 0xffffff);
        void nextViewer.render();
      });

      box.addEventListener('pointerenter', () => {
        document.body.style.cursor = 'pointer';
      });

      box.addEventListener('pointerleave', () => {
        document.body.style.cursor = 'default';
      });

      viewer = nextViewer;
      void viewer.render();
    }

    void setup();

    return () => {
      cancelled = true;
      document.body.style.cursor = 'default';
      viewer?.dispose();
    };
  }, []);

  return <div ref={containerRef} className="viewer" />;
}
```

`BaseMesh` 已包含 `u-space` 交互事件类型，因此可以直接监听 `click`、`pointerenter` 和 `pointerleave`。

### 2. 替换 `src/index.css`

```css
html,
body,
#root,
.viewer {
  width: 100%;
  height: 100%;
  margin: 0;
}

body {
  overflow: hidden;
}
```

### 3. 启动开发服务器

```bash
pnpm dev
```

打开 Vite 输出的本地地址，即可看到并操作 `u-space` 场景。

## 版本信息

`u-space` 导出了 `version` 常量，同时在 `window.__USPACE__` 上挂载了版本信息，方便调试和版本检查。

```typescript
import { version } from 'u-space';
console.log(version); // e.g. '0.0.32'

// 也可以通过全局变量访问
console.log(window.__USPACE__.version);
```

## 下一步

- 深入了解 [Viewer API](./api-viewer.md)
- 探索如何 [加载模型与使用对象](./api-objects.md)
- 理解 [交互系统](./api-interactions.md)
- 使用 [Managers API](./api-managers.md) 注册和检索对象
- 通过插件添加 [瓦片地图](./api-plugin-tiles.md)、[小地图](./api-plugin-minimap.md)、[键盘控制](./api-plugin-keyboard-controls.md) 等功能
- 使用 [Animations API](./api-animations.md) 为属性添加动画
- 使用 [Effects API](./api-effects.md) 应用视觉特效
- 浏览 [示例指南](./examples-guide.md)
