"use client"; import Image from "next/image"; import { useSearchParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; import { Unity, UnityConfig, useUnityContext } from "react-unity-webgl"; import { ObjectType } from "../types"; const unityConfigBuilder: (path: string) => UnityConfig = (path) => ({ loaderUrl: `${path}.loader.js`, dataUrl: `${path}.data`, frameworkUrl: `${path}.framework.js`, codeUrl: `${path}.wasm`, streamingAssetsUrl: "StreamingAssets", companyName: "DTOL", productName: "3d-test", productVersion: "0.1", }); export default function UnityComponent({ option = [], ohg = [], frame = [], }: { option: { value: string; name: string; description: string; }[]; ohg: ObjectType[]; frame: ObjectType[]; }) { const params = useSearchParams(); const p = params.get("p"); const [selectedIndex, setSelectedIndex] = useState({ ohg: 0, frame: 0 }); const [match, setMatch] = useState(100); if (!p || isNaN(Number(p))) location.href = "/unity?p=0"; const { unityProvider, isLoaded, loadingProgression, UNSAFE__unityInstance } = useUnityContext(unityConfigBuilder(option[Number(p)].value)); const loadingPercentage = Math.round(loadingProgression * 100); const handleSelectIndex = useCallback( // objectName: ohg | frame, newValue: "0", "1", ... (objectName: keyof typeof selectedIndex, newValue: string) => { const newIndex = Number(newValue); // 화면상의 select 컴포넌트 업데이트 setSelectedIndex((prev) => { if (objectName === "ohg") { return { ...prev, ohg: newIndex, }; } else { return { ...prev, frame: newIndex, }; } }); // 유니티 스크립트 호출 - objectName 및 함수 이름은 유니티의 것과 동일해야 함 UNSAFE__unityInstance?.SendMessage(objectName, "HandleSelect", newIndex); }, [UNSAFE__unityInstance], ); useEffect(() => { (async () => { const res = await fetch( `/fit?o=${selectedIndex.ohg}&f=${selectedIndex.frame}`, { method: "GET", }, ); console.log(res); const json = (await res.json()) as { match: number }; if (isNaN(Number(json.match)) === false) setMatch(json.match); })(); }, [selectedIndex.frame, selectedIndex.ohg]); return ( <>
새 Unity 프로젝트를 생성하고, WebGL로 빌드 후 빌드 산출물을 react-unity-webgl 라이브러리를 통해 실행했다.
{option?.[Number(p)] && (
{option[Number(p)].description}
)}
{isLoaded === false && (

Loading... ({loadingPercentage}%)

)}
{Number(p) == 0 && ( <>
매치율: {`${match?.toFixed?.(2) ?? 100}`}%
)} 전체 화면 버튼 UNSAFE__unityInstance?.SetFullscreen(1)} />
); }