mcpField
X
xrift-world

xrift-world

github.com/webxr-jp开发173 次安装5 天前更新
代码仓库

关于 xrift-world

xrift-world 是用于创建和修改 XRift WebXR 世界的开发指南,为 React Three Fiber 开发者提供平台实现规范、设备支持要求、配置说明和代码参考。

主要功能

  1. 01XRift API 与类型参考
  2. 02资源加载和目录规则
  3. 03PC 与移动设备支持指南
  4. 043D 交互与界面模式
  5. 05物理和摄像机配置

适用场景

  1. 01创建 XRift WebXR 世界
  2. 02调整移动端和 VR 交互
  3. 03配置世界物理与摄像机

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/webxr-jp/xrift-skills --skill xrift-world

安装后在 Claude Code 中输入/xrift-world确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api-reference.md
code-templates.md
type-definitions.md

详细介绍

XRift World 开发指南

用于创建和修改 XRift 平台 WebXR 世界的指南。

参考资料

  • API 参考 - @xrift/world-components 中所有 Hook、组件和常量的完整规范
  • 代码模板 - GLB 模型、纹理、Skybox、交互等的实现模式
  • 类型定义 - User、PlayerMovement、VRTrackingData、TeleportDestination、WorldInfo、InstanceInfo、ConfirmOptions、Tag、VideoState、LogEntry、PhysicsConfig、CameraConfig、VoiceVolumeOverrideContextValue 的类型定义

关键规则(必须遵守)

  1. 加载资源时,始终使用 useXRift() 中的 baseUrl
  2. 将资源文件放在 public/ 目录中
  3. baseUrl 末尾包含 /,因此请使用 ${baseUrl}path 拼接(${baseUrl}/path 是错误的)
// Correct
const { baseUrl } = useXRift()
const model = useGLTF(`${baseUrl}robot.glb`)

// Wrong
const model = useGLTF('/robot.glb')           // Absolute path - NG
const model = useGLTF(`${baseUrl}/robot.glb`) // Extra / - NG

设备支持(必须遵守)

访客可以通过 PC、移动设备(智能手机和平板电脑)和 VR 头显加入同一实例。世界必须至少同时支持 PC 和移动设备。 尽可能支持 VR。

设备支持要求控制方式
PC必须鼠标 + 键盘、中心准星 + 点击
移动设备必须触控、虚拟摇杆
VR尽力支持控制器、射线 + 扳机

开发服务器(npm run dev)只会测试 PC 控制,因此以下问题可能不会被发现:

  1. 不要使用自定义键盘快捷键构建功能(window.addEventListener('keydown'))。移动设备和 VR 没有键盘,因此这些功能将无法使用。W/A/S/D、Space、Q/E、G、H 和 Esc 等按键也已被平台占用。
    • 按钮和开关:使用 Interactable 包裹(PC 上点击、移动设备上触控、VR 中使用控制器)
    • 载具:在 Seat / Vehicle 上使用 onControlInput(键盘、虚拟摇杆和摇杆帽会以相同形式传入)
    • 文本输入:使用 TextInput。确认操作:使用 useConfirm
    • 只有在某个操作也能通过 Interactable 完成时,才可以将快捷键作为 PC 端的便捷方式
  2. 不要使用 DOM 元素构建 HUD 或 UI。 DOM 覆盖层在较小或旋转后的移动设备屏幕上会出现问题,还会与平台的虚拟摇杆和按钮重叠。在 VR 中只会渲染 3D 场景,因此完全不会显示 DOM UI。
    • 将 UI 作为对象放置在 3D 空间中:使用 @react-three/drei 中的 Text,并使用 @react-three/uikit 构建面板和菜单
    • 加载 useDefaultFont 以显示日语文本,使用 BillboardY 包裹以面向玩家,再使用 Interactable 包裹以使其可点击
  3. 不要让进度仅依赖 Grabbable。 目前抓取功能仅在 PC 上可用(指针锁定 + 准星)。

项目概览

  • 用途:适用于 XRift 平台的 WebXR 世界
  • 技术栈:React Three Fiber + Rapier 物理引擎 + Module Federation
  • 工作原理:上传至 CDN,再由前端动态加载

项目结构

xrift-world-template/
├── public/              # Asset files (place directly, no subdirectories needed)
│   ├── model.glb
│   ├── texture.jpg
│   └── skybox.jpg
├── src/
│   ├── components/      # 3D components
│   ├── World.tsx        # Main world component
│   ├── dev.tsx          # Development entry point
│   ├── index.tsx        # Production export
│   └── constants.ts     # Constants
├── .triplex/            # Triplex (3D editor) config
├── xrift.json           # XRift CLI config
├── vite.config.ts       # Build config (Module Federation)
└── package.json

xrift.json 配置

physics(物理设置)
字段类型默认值说明
gravitynumber9.81重力强度(正值;地球 = 9.81、月球 = 1.62、木星 = 24.79)
allowInfiniteJumpbooleantrue是否允许无限跳跃
{
  "physics": {
    "gravity": 9.81,
    "allowInfiniteJump": true
  }
}

示例:

  • 障碍赛世界:设置 "allowInfiniteJump": false 以增加坠落风险
  • 低重力世界:设置 "gravity": 1.62(月球重力),实现轻飘飘的移动
  • 高重力世界:设置 "gravity": 24.79(木星重力),实现沉重的移动
camera(相机设置)
字段类型说明
nearnumber近裁剪距离(隐藏距离小于此值的物体)
farnumber远裁剪距离(隐藏距离大于此值的物体)
{
  "camera": {
    "near": 0.1,
    "far": 1000
  }
}

示例:

  • 广阔世界:设置 "far": 5000 以渲染远处物体
  • 精细世界:设置 "near": 0.01 以提高近距离渲染精度
outputBufferType(输出缓冲区类型)

指定 WebGLRenderer 的输出缓冲区类型。会影响后期处理和 HDR 渲染精度。

值描述
UnsignedByteType8 位整数(默认,标准渲染)
HalfFloatType16 位浮点数(HDR 和后期处理)
FloatType32 位浮点数(最高精度,但 GPU 开销更高)
{
  "outputBufferType": "HalfFloatType"
}
items(从开始时放置的物品)

使用 <Item itemId> 放置在世界中的用户创建物品的 ID。生产环境中只会加载此处列出的 ID(进入时预加载;访客会根据此列表解析资源包 URL)。你只能声明自己创建的物品,或已添加到个人库中的物品(从市场获取)。最多 50 个。

{
  "items": [
    "2a69ded4-d913-4359-8c1f-eac83a982b0c"
  ]
}

本地开发:在 vite.config.ts 中从 @xrift/sdk/vite 添加 xriftDev(),并运行 xrift login;随后,DevEnvironment 会通过开发服务器代理(/__xrift)加载与生产环境相同的资源包。若要同时开发物品和世界,请通过 <DevEnvironment items={{ [itemId]: Component }}> 传入本地组件。

permissions(权限设置)

声明世界所需的权限。进入实例时,声明的权限会以审批界面的形式展示给用户。

字段类型描述
allowedDomainsstring[]世界通信所需的外部域名
allowedCodeRulesstring[]要放宽限制的代码安全规则
{
  "permissions": {
    "allowedDomains": ["api.example.com", "cdn.example.com"],
    "allowedCodeRules": ["no-storage-access", "no-network-without-permission"]
  }
}
allowedCodeRules

由 @xrift/code-security 分析器定义的规则。默认情况下会阻止不安全操作,但在需要时可以放宽限制。

类别规则描述
动态代码no-eval允许使用 eval()
动态代码no-new-function允许使用 Function 构造函数
动态代码no-string-timeout允许使用字符串参数调用 setTimeout/setInterval
动态代码no-javascript-blob允许创建 JavaScript Blob
混淆no-obfuscation允许使用混淆代码模式
网络no-network-without-permission允许使用 fetch、WebSocket 等
网络no-unauthorized-domain允许连接 allowedDomains 以外的域名
网络no-rtc-connection允许建立 WebRTC 对等连接
网络no-external-import允许导入外部 JS 模块
存储no-storage-access允许访问 localStorage/sessionStorage
存储no-cookie-access允许读取/写入 Cookie
存储no-indexeddb-access允许访问 IndexedDB
存储no-storage-event允许监听存储事件
DOMno-dangerous-dom允许使用 innerHTML 和注入脚本
浏览器 APIno-navigator-access允许使用地理位置、摄像头、麦克风和剪贴板
全局no-sensitive-api-override允许覆盖 fetch 等对象
全局no-global-override允许覆盖 window、document
全局no-prototype-pollution允许修改原型

命令参考

# Development
npm run dev        # Start dev server (http://localhost:5173)
npm run build      # Production build
npm run typecheck  # Type checking

# XRift CLI
xrift login        # Authenticate
xrift create world # Create new world project
xrift upload       # Upload (auto-detect from xrift.json)
xrift whoami       # Check logged-in user
xrift logout       # Log out

开发环境

运行 npm run dev 启动开发服务器。你可以在第一人称视角中浏览并测试世界。

操作按键
环顾四周点击以锁定鼠标,然后移动鼠标
移动W / A / S / D
上升 / 下降E 或 Space / Q
交互瞄准准星并点击
释放鼠标锁定ESC

也可以在开发环境中测试 Interactable 组件的点击行为(中心的 Raycaster 会检测 LAYERS.INTERACTABLE 层)。Grabbable 也可用——按 G 抓取和放置,滚动鼠标滚轮调整距离,点击确认。

Seat 和 Vehicle 只会在开发环境中注册;坐下需要化身、摄像机和物理系统,因此在世界运行于 XRift 之前不会执行任何操作。

dev.tsx 结构

src/dev.tsx 是仅用于开发的入口点,不会包含在生产构建中。

注意:生产环境不需要 XRiftProvider(前端会自动将其包装起来)。

依赖项

必需项(peerDependencies)
  • react / react-dom ^19.0.0
  • three ^0.182.0
  • @react-three/fiber ^9.3.0
  • @react-three/drei ^10.7.3
  • @react-three/rapier ^2.1.0
XRift 专用
  • @xrift/world-components - XRift hooks 和组件
Module Federation 共享包

与宿主(xrift.net)共享的包。在世界的 vite.config.ts 中将包声明为 shared 后,它们不会打包进世界的 chunk,而是由宿主提供。

包版本要求
react^19.0.0
react-dom^19.0.0
react-dom/client-
react/jsx-runtime^19.0.0
three^0.176.0
three/addons/loaders/GLTFLoader.js-
three/addons/loaders/DRACOLoader.js-
three/addons/loaders/KTX2Loader.js-
@react-three/fiber^9.0.0
@react-three/rapier^2.0.0
@react-three/drei^10.0.0
@react-three/uikit^1.0.0
@pmndrs/uikit^1.0.0
@xrift/world-components^0.1.0
关于 three/addons 的注意事项
  • 如果将 three/addons barrel 声明为 shared,打包内容会包含源自 Lottie 的 eval,因此按子路径声明为 shared
  • 世界端也应按子路径导入并声明为 shared,例如 three/addons/loaders/DRACOLoader.js
// vite.config.ts — shared の設定例(xrift-world-template 準拠)
federation({
  name: 'xrift_world_template',
  filename: 'remoteEntry.js',
  exposes: {
    './World': './src/index.tsx',
  },
  shared: {
    react: { singleton: true, requiredVersion: '^19.0.0' },
    'react-dom': { singleton: true, requiredVersion: '^19.0.0' },
    'react-dom/client': { singleton: true },
    'react/jsx-runtime': { singleton: true },
    three: { singleton: true, requiredVersion: '^0.176.0' },
    // three/addons はバレルではなくサブパス単位で宣言する
    'three/addons/loaders/DRACOLoader.js': { singleton: true },
    '@react-three/fiber': { singleton: true, requiredVersion: '^9.3.0' },
    '@react-three/rapier': { singleton: true, requiredVersion: '^2.1.0' },
    '@react-three/drei': { singleton: true, requiredVersion: '^10.7.3' },
    '@xrift/world-components': { singleton: true, requiredVersion: '^0.1.0' },
  },
}),

故障排除

“useXRift must be used within XRiftProvider”

原因:未使用 XRiftProvider 包装

解决方案:

  • 检查 src/dev.tsx 是否使用了 XRiftProvider
  • 使用 Triplex 时:检查 .triplex/provider.tsx
资源加载失败

原因:未使用 baseUrl,或路径拼接错误

解决方案:

// Correct
const { baseUrl } = useXRift()
const model = useGLTF(`${baseUrl}robot.glb`)

// Wrong
const model = useGLTF('/robot.glb')
const model = useGLTF(`${baseUrl}/robot.glb`)
物理效果不起作用

原因:未使用 Physics 组件包装,或缺少 RigidBody

解决方案:

<Physics>
  <RigidBody type="fixed">  {/* or "dynamic" */}
    <mesh>...</mesh>
  </RigidBody>
</Physics>

链接

示例实现

  • GLB 模型:src/components/Duck/index.tsx
  • 天空盒:src/components/Skybox/index.tsx
  • 动画:src/components/RotatingObject/index.tsx
  • 交互:src/components/InteractableButton/index.tsx
  • 用户追踪:src/components/RemoteUserHUDs/index.tsx
  • 传送:src/components/TeleportPortal/index.tsx
  • 主世界:src/World.tsx

评论

支持 Markdown