next.js 使用Unity webgl时出现OnWheel和getBoundingClientRect错误

vdzxcuhz  于 2022-11-05  发布在  其他
关注(0)|答案(2)|浏览(161)

我有以下错误时,使用webgl的React,我已经改变了两次尝试之间没有什么,显然错误的变化太.错误发生时,交换页面有人知道这个错误会是什么引起的吗?
OnWheel error
getBoundingClientRect error

oknwwptz

oknwwptz1#

当在next.js中呈现页面时,窗口不可用。要解决这个问题,您可以使用一个名为dynamic import的特性,并将ssr选项设置为false。这将禁用组件的服务器端呈现,您不必面对与SSR相关的问题。
请看下面使用动态导入的示例:
第一个
此外,请记住,不建议使用next.js进行3d工作和游戏制作。只需使用CRA或Vite创建SPA。

goqiplq2

goqiplq22#

我遇到了同样的错误。基本上,当你试图访问/执行一个在你的dom中没有引用的进程时,就会发生这种错误。所以你必须等待await unload函数()。一旦unity退出了它的instatance,你就会导航到其他路径。你必须等待unity退出函数。
如果你在模态中渲染unity示例,那么你需要从父组件传递unitycontext和它的函数。所以你可以暂停你的其他进程,直到await unload函数成功完成。
比如说
simModal.tsx(父组件)

const DynamicComponent = dynamic(() => import('../sim/index'), {
    ssr: false,
})

const SimModal: FC<any> = ({ simModalOpen, setSimModalOpen, raceId }) => {
    const unityProviders = useUnityContext({
        loaderUrl: '/Build/myunityapp.loader.js',
        dataUrl: '/Build/myunityapp.data.unityweb',
        frameworkUrl: '/Build/myunityapp.framework.js.unityweb',
        codeUrl: '/Build/myunityapp.wasm.unityweb',
        companyName: 'Nitro',
    })

    const handleUnityUnmounting = async () => {

        await unityProviders
            .unload()
            .then((res) => {
                console.log('res===>', res);
                setSimModalOpen(false)
            })
            .catch((err) => console.log('err===>', err))

    }
    return (
        <CustomModal
            isOpen={simModalOpen}
            setModalOpen={setSimModalOpen}
            styleclass={styles.simModal}
            onHide={
                unityProviders?.isLoaded
                    ? handleUnityUnmounting
                    : console.log('wait')
            }
        >
            {/* <ModalHeader closeButton></ModalHeader> */}
            <ModalBody>
                {/* <Sim  /> */}
                {simModalOpen && (
                    <div>
                        <DynamicComponent
                            unityProviders={unityProviders}
                            setSimModalOpen={setSimModalOpen}
                            simModalOpen={simModalOpen}
                            raceId={raceId}
                            handleUnityUnmounting={handleUnityUnmounting}
                        />
                    </div>
                )}
            </ModalBody>
        </CustomModal>

sim.tsx(加载Unity示例的子组件)

const Sim: FC<any> = ({ raceId, unityProviders }) => {
    const [isGameStarted, setIsGameStarted] = useState(false)
    const [gameFinish, setGameFinish] = useState<boolean>(false)

const images = [loading1, loading2, loading3, loading4, loading5]
const NUMBER_OF_PICTURES = 4
const [index, setIndex] = useState(0)

useEffect(() => {
    const timer = setInterval(() => {
        setIndex((prevIndex) =>
            prevIndex == NUMBER_OF_PICTURES ? 0 : prevIndex + 1
        )
    }, 3000)
    return () => {
        clearInterval(timer)
    }
}, [])

const {
    unityProvider,
    sendMessage,
    addEventListener,
    removeEventListener,
    isLoaded,
    loadingProgression,
} = unityProviders
const {
    data: raceLeaderBoardData,
    isFetching: raceLeaderBoardLoading,
    refetch: fetchRaceLeaderBoard,
} = raceLeaderBoard
    .list()
    .useRaceLeaderBoardlistQuery({ extendedPath: `/races/${raceId}` })

const [PopulateRaceParticipants, populateRaceParticipantsData] =
    raceParticipants.form().useRaceParticipantscreateMutation()

useEffect(() => {
    if (raceId) {
        PopulateRaceParticipants({
            body: {
                raceId: raceId,
            },
        })
    }
}, [raceId])

const handleGameOver = useCallback(async (result: unknown) => {
    console.log('name in handlegameover func===>', result)

    setGameFinish(true)
    // setTimeout(() => {
    //     unityProviders.unload().then((res: any) => {
    //     })
    // }, 7000)
}, [])

useEffect(() => {
    addEventListener('GameOver', handleGameOver)
    addEventListener('GameStart', handleGameStart)

    // addEventListener('QuitApp', handleQuitGame)
    return () => {
        if (unityProvider && isLoaded) {
            removeEventListener('GameOver', handleGameOver)
        }
    }
}, [addEventListener, removeEventListener, handleGameOver, isLoaded])

useEffect(() => {
    if (isLoaded) {
        sendMessage(
            '_SimController',
            'PopulateEventLeaderBoardData',
            JSON.stringify(raceLeaderBoardData?.responseData)
        )
        sendMessage(
            '_SimController',
            'PopulateRaceParticipantsData',
            JSON.stringify(populateRaceParticipantsData?.data)
        )
    }
}, [isLoaded])

const handleGameStart = async () => {
    setIsGameStarted(true)
}

return (
    <>
        {!isGameStarted && loadingProgression < 1 && !gameFinish && (
            <div
                style={{
                    height: '600px',
                    width: '1080px',
                    display: !isGameStarted ? 'block' : 'none',
                }}
                className={styles.loadingImg}
            >
                <Image
                    src={images[index]}
                    height={'100%'}
                    width={'100%'}
                    unoptimized={true}
                />
            </div>
        )}
        {gameFinish && (
            <div
                style={{
                    height: '600px',
                    width: '1080px',
                    display: gameFinish ? 'block' : 'none',
                }}
                className={styles.loadingImg}
            >
                <h5 style={{ zIndex: '99', color: 'white', }} className=' py-3'>Race Results</h5>
                <RaceResults raceId={raceId} />
            </div>
        )}

        <>

            <Unity
                style={{
                    height: '600px',
                    width: '1080px',
                    display: isGameStarted && !gameFinish ? 'block' : 'none',
                }}
                unityProvider={unityProvider}
            />

            {Math.round(loadingProgression * 100) < 100 && (
                <div className={styles.loadingWrap}>
                    <div className={styles.percentWrap}>
                        <span>Loading...</span>
                        <span>
                            {Math.round(loadingProgression * 100 + 10)}%
                        </span>
                    </div>

                    <div className={styles.progress}>
                        <div
                            className={styles.color}
                            style={{ width: loadingProgression * 1080 + 50 }}
                        ></div>
                    </div>
                </div>
            )}
        </>
    </>
)

}
导出默认模拟

相关问题