컨트롤

0

Three.js

목록 보기
7/14

개요

Three.js에는 미리 만들어져있는 다양한 컨트롤들이 존재하는데 이들에 대해서 소개를 좀 하고자 한다.

미리 만들어져있어서 쓰기는 편하지만 새로운 기능을 추가할때는 까다로울 수 있기 때문에 새로 카메라 컨트롤을 직접 만들지 기존 컨트롤을 수정할지는 상황에 따라 진행하면 된다.

OrbitControls

궤도 컨트롤이라고 부르며 사용 방법은 다음과 같다.

  import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";  

  const geometry = new THREE.BoxGeometry(1, 1, 1);
  let mesh;
  let material;

  const controls = new OrbitControls(camera, renderer.domElement);

  for (let i = 0; i < 20; i++) {
    // 배경이 0에 가까워지면 안보일 수 있기 때문에 이를 방지하기 위해 초기 50값을 줌
    material = new THREE.MeshStandardMaterial({
      color: `rgb(
				${50 + Math.floor(Math.random() * 205)},
				${50 + Math.floor(Math.random() * 205)},
				${50 + Math.floor(Math.random() * 205)}
			)`,
    });
    mesh = new THREE.Mesh(geometry, material);
    mesh.position.x = (Math.random() - 0.5) * 5;
    mesh.position.y = (Math.random() - 0.5) * 5;
    mesh.position.z = (Math.random() - 0.5) * 5;
    scene.add(mesh);
  }

결과

옵션

그리고 다양한 옵션이 존재한다 예로 enableDamping의 옵션을 활성화 해주면 화면의 움직임이 부드럽게 처리가 된다.


  const geometry = new THREE.BoxGeometry(1, 1, 1);
  let mesh;
  let material;

  const controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;

  for (let i = 0; i < 20; i++) {
    // 배경이 0에 가까워지면 안보일 수 있기 때문에 이를 방지하기 위해 초기 50값을 줌
    material = new THREE.MeshStandardMaterial({
      color: `rgb(
				${50 + Math.floor(Math.random() * 205)},
				${50 + Math.floor(Math.random() * 205)},
				${50 + Math.floor(Math.random() * 205)}
			)`,
    });
    mesh = new THREE.Mesh(geometry, material);
    mesh.position.x = (Math.random() - 0.5) * 5;
    mesh.position.y = (Math.random() - 0.5) * 5;
    mesh.position.z = (Math.random() - 0.5) * 5;
    scene.add(mesh);
  }

  function draw() {
    const delta = clock.getDelta();
    // enableDamping은 update()함수를 호출해주어야 한다.
    controls.update();

    renderer.render(scene, camera);
    renderer.setAnimationLoop(draw);
  }

적용 전

적용 후

옵션설명
enableDamping화면 회전에 부드러움 적용
enableZoom마우스 줌이 불가능하게 막는다.
minDistance, maxDistance마우스 줌의 거리를 조절할 수 있다.
minPolarAngle, maxPolarAngle수직으로 돌아가는 각도를 막을 수 있다.
autoRotate자동으로 화면이 돌아가도록 한다.
autoRotateSpeed자동으로 화면이 돌아가는 속도를 조절한다.
enableZoom줌이 불가능하게 막을 수 있다.

TrackballControls

OrbitControls와 동일하지만 트랙볼 방향으로 컨트롤 할 수 있다는 점과 update메서드를 호출을 해주어야 사용이 가능하다.

트랙볼 마우스를 생각하면 될듯하다.

FlyControls

다른 컨트롤과는 다르게 update 메서드 매개변수에 delta값을 넣어주어야 동작한다. autoForward속성을 true로 하면 controls이 앞으로 계속 움직이도록 할수있다.

  const controls = new FlyControls(camera, renderer.domElement);
  function draw() {
    const delta = clock.getDelta();
    controls.update(delta);

    renderer.render(scene, camera);
    renderer.setAnimationLoop(draw);
  }

마우스 컨트롤 조정

키보드 컨트롤 조정

FirstPersonControls

FlyControls의 대체구현으로 FlyControls와 동일하게 동작하며 activeLook 옵션을 false로 지정하면 좌우 주변을 둘러볼 수 없다.

PointerLockControls

다른 Controls과는 다르게 update메서드가 존재하지 않는다. 이 컨트롤을 실행하려면 lock 메서드를 실행해야 하는데 이것은 사용자의 특정 동작에 의해서 메서드를 실행해야한다.

이 컨트롤러를 실행하면 화면 상단에 커서를 표시하려면 ESC를 누르세요.라는 문구가 나타나게 된다.

  // 캔버스 메서드
  controls.domElement.addEventListener("click", () => {
    controls.lock();
  });

DragControls

각 오브젝트를 이동시킬때 사용하는 컨트롤러이다. 드래그가 시작될때나 완료가 되었을때 이벤트를 처리해할수있다.

마인크래프트 스타일 컨트롤

PointerLockControls에 키보드의 움직임을 추가하면 마인크래프트 스타일의 컨트롤이 완성된다.

  • keyController.js
export class KeyController {
  constructor() {
    this.keys = [];
    window.addEventListener("keydown", (e) => {
      this.keys[e.code] = true;
    });

    window.addEventListener("keyup", (e) => {
      delete this.keys[e.code];
    });
  }
}

PointerLock에는 moveFoward 메서드와 moveRight 메서드밖에 없기때문에 뒤로 이동 혹은 왼쪽으로 이동은 -값을 넣어주면 된다

  
  // Controls
  const controls = new PointerLockControls(camera, renderer.domElement);

  // 캔버스 메서드
  controls.domElement.addEventListener("click", () => {
    controls.lock();
  });
  const keyController = new KeyController();
  const walk = () => {
    if (keyController.keys["KeyW"]) {
      controls.moveForward(0.05);
    } else if (keyController.keys["KeyD"]) {
      controls.moveRight(0.05);
    } else if (keyController.keys["KeyA"]) {
      controls.moveRight(-0.05);
    } else if (keyController.keys["KeyS"]) {
      controls.moveForward(-0.05);
    }
  };
  
  function draw() {
    walk();
    renderer.render(scene, camera);
    renderer.setAnimationLoop(draw);
  }

profile
업무하면서 쌓인 노하우를 정리하는 블로그🚀 풀스택 개발자를 지향하고 있습니다👻

0개의 댓글