ReactJSでAFrameを動かすときはこれ。
aframe-react
NextJSは一部SSR(サーバサイドレンダリング)が走るので、クライアントで動作する状態になってからロードする必要がある。
参考: aframe-next-static
windowというグローバル変数が使えるようになればクライアント側で動作する状態なので、レンダリング完了フラグで管理する。
if (typeof window !== "undefined") {
require("aframe");
setRendered(true);
}
aframeは配置するものが多いと意外とソースが長くなるので、
1個のLockerを構成する単位でコンポーネント化しました。
選手の情報をAPIから取得して、奇数と偶数の場合で振り分けています。
if (!rendered || !teamMembers) {
return <></>;
}
return (
<Scene
//device-orientation-permission-ui="enabled: true"
>
{teamMembers.map((member,idx)=>(
<>
{idx%2 === 0
?<RightLocker member={member} x={3 - idx*0.35} y={0} z={1.7+idx*0.35} rot_x={0} rot_y={0} rot_z={0}/>
:<LeftLocker member={member} x={-idx*0.35} y={0} z={idx*0.35} rot_x={0} rot_y={0} rot_z={0}/>
}
</>
))}
<Entity primitive="a-sky" material="color: #555" />
<Entity camera look-controls wasd-controls position="3 1 2"/>
</Scene>
);
a-sky
は背景、camera
はカメラの初期位置を定義しています。
これがRightLockerのソースです。
プログラム的に難しいことはないのですが、
座標や光源の調整などが結構面倒でした。
(..planeって光透過すんの?)
import { Entity } from "aframe-react";
import { Player } from "../../model/typedef";
type diff={
x:number,
y:number,
z:number,
rot_x:number,
rot_y:number,
rot_z:number,
member:Player
}
const RightLocker:React.FC<diff> = ({x,y,z,rot_x,rot_y,rot_z,member}) => {
return (
<>
<Entity
geometry={{ primitive: "plane", width:1, height:2}}
material={{ src: "/images/wood.jpg",alphaTest:0.1 }}
position={{ x: x+0.7, y: y, z: z-4.3}}
rotation={{ x: rot_x, y: -135+rot_y, z: rot_z }}
/>
<Entity
primitive="a-image"
height="2"
//geometry={{ primitive: "plane", width:1, height:2}}
material={{ src: "/images/wood.jpg", transparent:false}}
position={{ x: x+0.7, y: y, z: z-5 }}
rotation={{ x: rot_x, y: rot_y-45, z: rot_z }}
/>
<Entity
primitive="a-image"
height="2"
//geometry={{ primitive: "plane", width:1, height:2}}
material={{ src: "/images/wood.jpg"}}
position={{ x: x, y: y, z: z-4.3 }}
rotation={{ x: rot_x, y: rot_y-45, z: rot_z }}
/>
<Entity
geometry={{ primitive: "box", width:0.5, height:0.3}}
material={{ color:'gray' }}
position={{ x: x+0.5, y: y-1, z: z-4.5 }}
rotation={{ x: rot_x, y: rot_y-45, z: rot_z }}
/>
<Entity
primitive="a-image"
height="1.5"
width="0.8"
//geometry={{ primitive: "plane", width:1, height:2}}
material={{ src: member.ogp_image}}
position={{ x: x+0.7, y: y, z: z-4.3}}
rotation={{ x: rot_x, y: -135+rot_y, z: rot_z }}
/>
<Entity
primitive="a-light"
light={{type:"spot"}}
material={{color:'yellow'}}
position={{ x: x+0.3, y: y+1.3, z: z-4.5 }}
rotation={{ x: rot_x-90, y: rot_y-10, z: rot_z-10 }}
/>
</>
);
};
export default RightLocker;
まだ本サイトにはデプロイしていませんが、team/[チームID]/vr_locker
で各チームのVRロッカーを見ることができます。
- キャップ野球情報局・VRロッカー
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント