inflearn logo
강의

講義

知識共有

React Three Fiber(R3F)で学ぶインタラクティブ3Dウェブ開発

靴をクリックして各パーツごとに色を変更する

primitive에 onClick 이벤트가 안되는 경우

30

justjh30

投稿した質問数 1

0

아래와 같이 코드를 작성했습니다. 렌더링은 잘되며, 에러코드도 안 뜨는데 클릭 이벤트에 응답이 없습니다.

import { useLoader, useThree } from '@react-three/fiber';
// import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/Addons.js';

export default function ShowRoom() {
  const gltf = useLoader(GLTFLoader, './models/custom.glb');
  const { raycaster } = useThree();
  // console.log(gltf);
  console.log(raycaster);
  const handleClick = () => {
    console.log('click');
    const intersects = raycaster.intersectObjects(gltf.scene.children, true);
    console.log(intersects);
  };
  return (
    <primitive object={gltf.scene} onClick={handleClick} />
    // <mesh
    //   rotation={[THREE.MathUtils.degToRad(45), THREE.MathUtils.degToRad(45), 0]}
    // >
    //   <boxGeometry />
    //   <meshStandardMaterial />
    // </mesh>
  );
}

javascript react typescript 인터랙티브-웹 three.js webgl react-three-fiber

回答 3

1

taejaehan

안녕하세요. 이지현님 질문 감사드립니다.

병원에 입원해 있느라 답변이 늦었습니다.


코드를 테스트해보니 click이벤트와 intersects도 잘 찍히는 것으로 보아

코드상에는 문제가 없어 보입니다.

custom.glb도 수업에서 사용했던 glb라면 문제없이 동작을 할것 같습니다.


신발 렌더링은 잘 되는데, 'click' 이라는것도 안찍히나요?

찍힌다면 intersects도 어떤게 나오는지 알려주시면 디버깅해보겠습니다.


만약에 click도 안찍힌다면, canvas위에 다른 DOM요소(div 등..)을 올려놓으신건 아닌지 canvas의 css를 pointer-events: none으로 해놓으신건 아닌지 등등 점검해보시는게 좋을것 같습니다. CameraControls를 달아서 회전등 컨트롤이 잘되는지 확인해보시고, 된다면 회전/이동하면서 click 이벤트가 동작하는지 테스트하는 순서로 디버깅하시면 좋을 것 같네요.

모두 안된다면 강의에 사용한 three.js / r3f 등 버젼인지 다른 버젼인지도 알려주시면 좋을것 같습니다.

시도해보시고 해결/미해결시 다시 알려주시면 같이 고민해보겠습니다.

감사합니다!




scene

0

eggmun

primitive에도 onClick은 사용할 수 있습니다.
현재 코드에는 이미 onClick이 연결되어 있기 때문에, 우선 handleClick 안의 console.log('click') 자체가 찍히는지 확인해보세요.
만약 이것도 찍히지 않는다면 수동 raycaster.intersectObjects() 문제가 아니라 R3F 이벤트가 해당 모델에 전달되지 않는 상태입니다.

0

communityai8509

안녕하세요, 인프런 AI 인턴입니다. 이지현님.

React Three Fiber(R3F)를 사용할 때 primitive 태그에 onClick 이벤트가 작동하지 않는 이유와 해결책에 대해 설명드리겠습니다.

문제 설명과 원인

primitive 컴포넌트는 매우 유연하게 다양한 Three.js 오브젝트를 React 내에서 사용할 수 있게 해주지만, 때때로 이벤트 바인딩이 올바르게 작동하지 않을 수 있습니다. 특히, GLTFLoader로 로드된 gltf.scene과 같은 Three.js 장면(scene)을 primitive 컴포넌트로 사용할 때는 이벤트 핸들러가 직접적으로 작동하지 않을 수 있습니다.

이는 주로 다음과 같은 이유 때문에 발생합니다:
- GLTF로 로드된 모델 내부의 메쉬나 그룹이 복잡하게 구성되어 있어 이벤트를 처리할 노드가 올바르게 선택되지 않을 수 있습니다.
- R3F에서 useLoader로 가져온 오브젝트 같은 경우, 생성된 객체가 이벤트 처리가 자동으로 되지 않는 경우도 있습니다.

해결 방법

  1. useThree의 레이캐스터를 사용하는 대신, Canvas의 모든 장면에 이벤트를 적용해보기:
    useThree의 행위에 의존하는 대신, Canvas 요소에 이벤트 핸들러를 설정해보실 수 있습니다.

  2. group을 사용하여 이벤트 처리:
    primitive 대신 group 태그로 처리해보는 방법입니다. group를 사용하면 더 명확하게 이벤트를 분리할 수 있습니다.

  3. 라이브러리 문서 확인 및 다른 이벤트 적용 방식 시도:
    만약 primitive에 꼭 onClick을 사용해야 한다면 R3F의 최신 문서나 FAQ를 참조하여, 이벤트 처리에 관련된 최신 정보를 확인하시기 바랍니다.

  4. 직접 raycaster 사용하여 수동으로 교차 확인:
    이미 시도하신 방식처럼 raycaster를 직접 사용하여, 손수 교차를 확인하는 방법도 여전히 유용할 수 있습니다. 이 경우, 버튼이나 다른 요소를 통해 호출되는 이벤트에서 구현해보실 수 있습니다.

관련하여 도움이 될 만한 자료로는 다음 링크를 참고하실 수 있습니다:
- onClick 이벤트함수로 raycaster 방향이 자동으로 set되나요?

위 설명들이 도움이 되었길 바랍니다. 추가적으로 궁금한 점이 있으시면 언제든지 질문해 주세요. 저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.

현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

ThemeProvider를 이용해서 NextThemeProvider를 따로 생성하여 Layout.tsx에 적용하는 이유는 뭘까요?

0

2

0

인덱스드 엑세스타입 실무질문

0

8

2

mission 09-01 을 수행할 수 없어요

0

14

1

outputStyle 설정하는데 어디서 문제일까요?

0

10

2

test.txt파일 삭제시 rm명령어이니 클로드의 질문이 있어야 한다고 하셨는데

0

7

1

검은화면

0

14

2

강의교환링크안열려요.....

0

14

1

영상재생에러 [확인부탁드려요!!!]

0

14

1

클로드 채팅에서 코드로 넘어가기

0

16

1

Context API vs Zustand 그리고 Auth

0

20

2

110강부터 따라가기가 힘듭니다...

0

39

1

ai 도구 질문

0

97

1

오브젝트에의 이벤트 감지 vs 레이캐스팅

0

101

2

섹션 10을 들었을때 궁금증

0

127

2

material 파트까지 들은 후 생긴 궁금증

0

190

1

zoom과 fov의 차이점이 잘 이해가 안됩니다.

1

359

2

1강 관련하여 의견을 여쭙고 싶은 게 있습니다.

0

167

1

'JSX.IntrinsicElements' 유형에 'mesh' 속성이 없습니다. 경고 해결법

1

384

2

onClick 이벤트함수로 raycaster 방향이 자동으로 set되나요?

0

221

2

화면에 렌더링은 되는데 코드에서 빨간줄이 떠요

0

432

2

문제 해결했습니다.

0

210

1

문제 있어요! alias Path @ 문제

0

513

2

dom / svg / canvas

0

258

1

물질을 클릭했을 때 이벤트

0

437

1