리액트 나티브로 오징어 게임!

(1) 시작
평소 사회복지사로서 장애가 있는 사람을 지원한다.Advent Calendar에 맞춰 버전을 업그레이드한 React Native의 3D 표현과 관련해 이번에 완성된 기고가 됐다.지난번에 React Native로 Socket 커뮤니케이션 하세요. 소켓 통신을 통해 3D 캐릭터에 대한 멀티플레이를 할 수 있는 코드를 소개했다.이번에는 오징어 게임에 나오는 오뚝이 넘어지는 요소를 추가해 완성하고 싶습니다.
큰 적 캐릭터가 돌아설 때 자신의 캐릭터가 움직이면 아웃되고 초기 위치로 돌아간다.github에 공개됐기 때문에 관심 있는 분들은 보세요.
gl.pixelStorei() doesn't support this parameter yet! from TextureLoader가 나오니까 node.modules에서.js16527줄에서 아래 3줄을 평론해 주세요.
※ github expo-three의 issue #196 참조
// _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
// _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
// _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE);

(2) 소켓으로 통신하는 서버에 추가 기능
우선 지난번 nodejs 코드에 일정한 간격으로ture를 보내는 코드를 추가합니다.Math.flor 함수와 Math.random 함수를 사용하여 5~8(0~3+5)의 정수를 되돌려주고 1000밀리초를 곱하여 setTimeout 함수의 간격을 설정합니다.이렇게 하면 5초에서 8초 간격으로 프로그램에 무작위로 팩스를 보낼 수 있다.프로그램이 이 사실을 받아들일 때 적의 역할은 되돌아온다.
function enemy() {
  io.emit("Enemy", true);
}

(function loop() {
  let random = (Math.floor(Math.random() * 3) + 5) * 1000;
  setTimeout(() => {
    enemy();
    loop();
  }, random);
})();
Expo에서 nodejs 응용 프로그램 (상기github의 서버 폴더 내) 에 접근하는 방법은 윈도우즈라면 '네트워크와 인터넷' 에서 와이파이 속성까지의 IPv4 주소를 설정해서 로컬에서 만든 서버에 접근할 수 있습니다.
const socket = io("http://<IPv4アドレス>:3000");
(3) 사용하는 기술
사용할 라이브러리는 지난번과 같습니다.
・react-native
・expo 42.0.1
・expo-gl 10.4.2
・expo-three6.0.1
・gsap 3.6.0
・the 0.132.0← ※ 버전에 따라 오류 발생
・expo-asset8.3.3
・socket.io-client 4.4.0
사이트 축소판 그림
Three.본격
Expo 공식
정부측
Socket.공식.
blender 공식
(4) 3D 모델 디스플레이
추가된 코드의 설명을 기술하다.적 역할은 특허를 사용하지 않는 믹사모가 만들었다.fbx 형식으로 회고 동작을 다운로드하고 Blender로 비율을 확대하여 gbl 형식으로 저장(testC.gbl)합니다.애니메이션 변수 walkC는 Mixamo가 설정한 애니메이션입니다.

아직 일부 기능만 사용했지만 블렌더가 아주 좋아요!
 // 敵のキャラクターを設置
    let mixerC;
    let clockC = new Clock();
      const assetC = Asset.fromModule(require("./assets/testC.glb"));
      await assetC.downloadAsync();
      loader.load(
        assetC.uri || "",
        (gltf) => {
          const modelC = gltf.scene;
          modelC.position.set(0, 0, -40); // 配置される座標 (x,y,z)
          modelC.rotation.y = Math.PI - 0.7;
          const animations = gltf.animations;
          //Animation Mixerインスタンスを生成
          mixerC = new AnimationMixer(modelC);
          // 設定した一つ目のアニメーションを設定
          let animation = animations[0];
          // アニメーションを変数walkにセット
          setWalkC(mixerC.clipAction(animation));
          // test.glbを3D空間に追加;
          scene.add(modelC);
          setModelsC(modelC);
        },
        (xhr) => {
          console.log("ロード中");
        },
        (error) => {
          console.error("読み込めませんでした");
        }
     ;
적 캐릭터가 돌아올 시기에 대해 socket.온으로 받다.
// App.js
  const [daruma, setDaruma] = useState(false); // サーバーから受信したかどうかをセットする変数 
  const [stare, setStare] = useState(false); // 自身のキャラクターが動いたらアウトになるタイミングの変数

  useEffect(() => {
    // サーバーのアドレス
    const socket = io("http://<IPv4アドレス>:3000");
    // サーバーからランダムな値を受け取り変数darumaにセット
    socket.on("Enemy", (data) => {
      // 敵キャラクターを読み込む前にtrueとなっているためfalseにセットしなおす
      setDaruma(false);
      // サーバーから受け取ったtrueをセット
      setDaruma(data);
    });
    return () => socket.disconnect();
  }, [modelsC]);
변수 stare를 실제 위치로 되돌려주는 함수walk를 캐릭터 행동을 수행하는 함수walk에 추가합니다.
const move = (props) => {
    walkA.paused = false; // キャラクターのポーズを解除
    walkA.play(); // // アニメーションである変数walkを再生
    setAction({ z: props.y, x: props.x }); // Position.jsから受け取った座標を変数actionにセット
    walk(); // walk関数を実行
    // 関数moveが実行されているときにdarumaがtrueなら初期座標に戻る
    if (stare) {
      TweenMax.set(modelsA.position, {
        x: 0,
        y: 0,
        z: 25, // 中心より手前に初期座標を設定
      });
      TweenMax.set(cameras.position, {
        x: 0,
        y: 2,
        z: 32,
      });
      walkA.paused = true;
      send({
        x: modelsA.position.x,
        y: modelsA.rotation.y,
        z: modelsA.position.z,
        w: walkA.paused,
      });
    }
  };
마지막으로 변수daruma가 변할 때마다useEffect로 반응한다.적 캐릭터를 읽지 않으면 오류가 발생하기 때문에 조건식if(modelsc 오류:=null)를 설정합니다.settime를 사용하여 되돌아오는 애니메이션을 실행합니다. 2500밀리초 간격으로 멈추고, 애니메이션을 실행한 후 500밀리초 동안 변수 stare를 진짜로 변경합니다. 자신의 캐릭터가 이동하면 아웃되는 시간이 지연됩니다.
useEffect(() => {
//darumaがtrueであれば下記を実行する
    if (daruma) {
      if (modelsC !== null) {
       // アニメーション開始
        walkC.play();
        setTimeout(() => {
          setStare(true);
        }, 500);
      }
      setTimeout(() => {
        // 2500ミリ秒後にリセット
        if (modelsC !== null) {
          setDaruma(false);
          setStare(false);
          // アニメーション停止
          walkC.stop();
        }
      }, 2500);
    }
  //変数darumaが変化する度に反応する
  }, [daruma]);
(5) 끝
React Native의 3D 디스플레이에 대해 Advent Calendar와 함께 2주 동안 업그레이드했습니다.귀중한 기회를 이용해 주셔서 감사합니다.리액트 네이티브 커뮤니티에 조금이나마 기여할 수 있다면 좋겠네요.React Native Advent Calendar의 여러분의 기사를 배울 만한 가치가 있습니다

좋은 웹페이지 즐겨찾기