Open16

輪投げ Web VR コンテンツ作成の記録

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

このスクラップについて

このスクラップでは輪投げの Web VR コンテンツを React Three Fiber と Rapier を使って作っていく過程を記録していく。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ワークスペース作成

コマンド
npx create-next-app \
  --typescript \
  --tailwind \
  --eslint \
  --app \
  --src-dir \
  --import-alias "@/*" \
  --use-npm \
  wanage-web-vr
cd wanage-web-vr
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

はじめの一歩

src/app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
src/app/layout.tsx
import "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Ring Toss Web VR",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  );
}
src/app/page.tsx
"use client";

import { Torus } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { CuboidCollider, Physics, RigidBody } from "@react-three/rapier";

export default function Home() {
  return (
    <main className="container mx-auto">
      <h1 className="mt-4 mb-4 text-2xl">Ring Toss Web VR</h1>
      <Canvas className="aspect-video border">
        <Physics debug>
          <RigidBody colliders="trimesh">
            <Torus></Torus>
          </RigidBody>
          {/* 床 */}
          <CuboidCollider
            position={[0, -2.5, 0]}
            args={[10, 1, 10]}
          ></CuboidCollider>
        </Physics>
      </Canvas>
    </main>
  );
}


リングが落ちてきて床に立つ

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

OrbitControls の追加

マウスで拡大したりできるようにする。

src/app/page.tsx(抜粋)
      <Canvas className="aspect-video border">
        <OrbitControls></OrbitControls>
        <Physics debug>
          <RigidBody colliders="trimesh">
            <Torus args={[ringRadius, ringTube]}></Torus>
          </RigidBody>
          {/* 床 */}
          <CuboidCollider
            position={[0, -2.5, 0]}
            args={[10, 1, 10]}
          ></CuboidCollider>
        </Physics>
      </Canvas>


できればカメラの初期値を設定したいがどうやるんだっけ?

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

色々といじった

  • カメラの位置
  • リングの回転
  • 床に RigidBody を使用
src/app/page.tsx
"use client";

import { Box, OrbitControls, Torus } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { Physics, RigidBody } from "@react-three/rapier";

const ringRadius = 170e-3;
const ringTube = 20e-3;

export default function Home() {
  return (
    <main className="container mx-auto">
      <h1 className="mt-4 mb-4 text-2xl">Ring Toss Web VR</h1>
      <Canvas
        className="aspect-video border"
        camera={{ position: [0, 1.7, -3] }}
      >
        <OrbitControls></OrbitControls>
        <Physics debug>
          <RigidBody colliders="trimesh">
            <Torus
              args={[ringRadius, ringTube]}
              position={[0, 1, 0]}
              rotation={[Math.PI / 2, 0, 0]}
            ></Torus>
          </RigidBody>
          {/* 床 */}
          <RigidBody type="fixed">
            <Box args={[20, 1, 20]}></Box>
          </RigidBody>
        </Physics>
      </Canvas>
    </main>
  );
}
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

台を追加したけど

src/app/page.tsx
"use client";

import { Box, OrbitControls, Torus } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { Physics, RigidBody } from "@react-three/rapier";

const ringRadius = 170e-3;
const ringTube = 20e-3;

const tableWidth = 600e-3;
const tableDepth = 600e-3;
const tableHeight = 50e-3;

export default function Home() {
  return (
    <main className="container mx-auto">
      <h1 className="mt-4 mb-4 text-2xl">Ring Toss Web VR</h1>
      <Canvas
        className="aspect-video border"
        camera={{ position: [0, 1.7, -3] }}
      >
        <OrbitControls></OrbitControls>
        <Physics debug>
          <RigidBody colliders="trimesh">
            <Torus
              args={[ringRadius, ringTube]}
              position={[0, 1, 0]}
              rotation={[Math.PI / 2, 0, 0]}
            ></Torus>
          </RigidBody>
          {/* 床 */}
          <RigidBody type="fixed">
            <Box args={[20, 1, 20]}></Box>
          </RigidBody>
          {/* 輪投げの台 */}
          <Box args={[tableWidth, tableHeight, tableDepth]}></Box>
        </Physics>
      </Canvas>
    </main>
  );
}


台が小さく見える

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

内径とは直径のことだった

踏まえて変更してみる。

src/app/page.tsx(抜粋)
const ringRadius = 170e-3 / 2;


サイズは良い感じになったが太すぎる気がする。