커뮤니티
포인트
쿠폰
내 강의실
국비 신청 내역
증명서
계정
로그아웃
학습 질문
개발 일지
나의 활동
답변 완료
동물들이 안나와요
[스킬업] 프론트엔드 개발자를 위한 인터랙티브 3D 웹 개발 실전 v0
5주차
북마크
박*규
댓글
3
추천
0
조회수
13
조회수
13
답변 완료

* 겪고 있는 문제 상황을 최대한 자세하게 작성해주세요.

* 문제 해결을 위해 어떤 시도를 해보았는지 구체적으로 함께 알려주세요.


동물원 만들기 하고 있는데

강의랑 강의자료보고 다 따라했는데 동물들이 안나와요

그 전까지는 동물잘나왔는데 4주차 변경모드 듣고 부터 안나오는데 어떻게 고쳐야할지 알려주시면 감사하겠습니다



스파르타 즉문즉답



animal.jsx

import { useAnimations, useGLTF } from "@react-three/drei";
import { useContext, useEffect, useMemo, useRef } from "react";
import { SkeletonUtils } from "three-stdlib";
import { EditContext } from "../context/EditContext";
import { RigidBody } from "@react-three/rapier";


export const Animal = ({ name, objectId, onClick, position, ...props }) => {
    const group = useRef();
    const { scene, animations } = useGLTF(`/models/animals/${name}.glb`);
    const clone = useMemo(() => SkeletonUtils.clone(scene), [scene])
    const { actions } = useAnimations(animations, group);


    const { isEditMode, selectedId, draggedPos } = useContext(EditContext);
    const isSelected = objectId === selectedId;


    useEffect(() => {
        actions["Idle"].reset().play();
    }, [])
    return (
        <>
          {isEditMode ? (
            <group
              scale={[2.5, 2.5, 2.5]}
              onClick={onClick(objectId)}
              position={isSelected ? draggedPos : position}
              {...props}
              ref={group}
            >
              <mesh>
                <boxGeometry args={[3, 1, 4]} />
                <meshBasicMaterial transparent opacity={0.7} color={"green"} />
              </mesh>
              <primitive object={clone}></primitive>;
            </group>
          ) : (
              <RigidBody position={position}
                {...props}
                colliders={"hull"}
                enabledRotations={[false, false, false]}
              >
                <group ref={group} >
                  <primitive object={clone}></primitive>
                </group>
              </RigidBody>
          )}
        </>
      );
    };


dino.jsx

import { useAnimations, useGLTF } from "@react-three/drei";
import { useContext, useEffect, useMemo, useRef } from "react";
import { SkeletonUtils } from "three-stdlib";
import { RigidBody } from "@react-three/rapier";
import { EditContext } from "../context/EditContext";


export const Dino = ({ name, objectId, onClick, position, ...props }) => {
    const group = useRef();
    const { scene, animations } = useGLTF(`/models/dinos/${name}.glb`);
    const clone = useMemo(() => SkeletonUtils.clone(scene), [scene])
    const { actions } = useAnimations(animations, group);


    const { isEditMode, selectedId, draggedPos } = useContext(EditContext);
    const isSelected = objectId === selectedId;


    useEffect(() => {
        actions[`Armature|${name}_Idle`].reset().play();
    }, [])
    return (
        <>
          {isEditMode ? (
            <group
              scale={[1.5, 1.5, 1.5]}
              onClick={onClick(objectId)}
              position={isSelected ? draggedPos : position}
              {...props}
              ref={group}
            >
              <mesh>
                <boxGeometry args={[6, 1, 8]} />
                <meshBasicMaterial transparent opacity={0.7} color={"blue"} />
              </mesh>
              <primitive object={clone}></primitive>;
            </group>
          ) : (
              <RigidBody position={position}
                {...props}
                colliders={"hull"}
                enabledRotations={[false, false, false]}
              >
                <group ref={group}>
                  <primitive object={clone}></primitive>
                </group>
              </RigidBody>
          )}
        </>
      );
    }

environments.jsx

import { OrbitControls } from "@react-three/drei";
import { Animal } from "./Animal";
import { ZooMap } from "./ZooMap";
import { Dino } from "./Dino";


import { Fragment, Suspense, useContext } from "react";
import { Physics, RigidBody } from "@react-three/rapier";
import { EditContext } from "../context/EditContext";
import { useFrame, useThree } from "@react-three/fiber";
import { Rtanny } from "./Rtanny";


const START_Y = 20;


export const Environments = () => {
    const { isEditMode, objects, onObjectClicked, onPointMove} = useContext(EditContext);


    const { camera } = useThree();


    useFrame(() => {
        if (isEditMode) {
            camera.position.x = 0;
            camera.position.y = 400;
            camera.position.z = 0;
        }
    });


    return (
        <>
            {isEditMode ? (
                <gridHelper 
                onPointerMove={onPointMove}
                args={[500, 100]} position={[0, START_Y, 0]} />
            ) : null}
            <ambientLight intensity={4} />
            <directionalLight intensity={4} position={[3, 3, 3]} />
            <OrbitControls />


            <Suspense>
                <Physics>
                    <RigidBody type="fixed" colliders={"trimesh"}>
                        <ZooMap />
                    </RigidBody>
                    {objects.map(({ id, ...object }) => {
                        <Fragment key={id}>
                            {object.type === "animal" ? (
                                <Animal objectId={id} onClick={onObjectClicked} {...object} />
                            ) : (
                            <Dino objectId={id} onClick={onObjectClicked} {...object} />
                        )}
                        </Fragment>
                    })}
                    <Rtanny />
                </Physics>
            </Suspense>
        </>
    );
};

editcontext.jsx

import { createContext, useState } from "react";


export const EditContext = createContext();



export const EditProvider = ({ children }) => {
    const [isEditMode, setEditMode] = useState(false);
    const initData = localStorage.getItem("objects");
    const [objects, setObject] = useState(
        initData? JSON.parse(initData): data);


    const [selectedId, setselectedId] = useState();
    const [draggedPos, setDraggedPos] = useState();
    const setObj =(objects) =>{
        setObject(objects);
        localStorage.setItem('objects', JSON.stringify(objects));
    };


    const transform = () => {
        setObj(objects.map((object) => object.id === selectedId ? { ...object, position: draggedPos } : object))
    }


    const rotate = (type) => {
        if (type === "left") {
          setObj(
            objects.map((obj) => {
              return obj.id === selectedId
                ? {
                    ...obj,
                    rotation: [
                      obj.rotation[0],
                      obj.rotation[1] - Math.PI / 12,
                      obj.rotation[2],
                    ],
                  }
                : obj;
            })
          );
        }
    
        if (type === "right") {
          setObj(
            objects.map((obj) => {
              return obj.id === selectedId
                ? {
                    ...obj,
                    rotation: [
                      obj.rotation[0],
                      obj.rotation[1] + Math.PI / 12,
                      obj.rotation[2],
                    ],
                  }
                : obj;
            })
          );
        }
      };


    
    const onObjectClicked = (id) => (e) => {
        e.stopPropagation();


        if (id && id === selectedId) {
            transform();
            setselectedId(null);
            return;
        }


        setselectedId(id);
    };


    const onPointMove = (e) => {
        setDraggedPos(Object.values(e.point)); // x:y:z
    }


    const value = { rotate, onPointMove, onObjectClicked, draggedPos, setDraggedPos, selectedId, setselectedId, isEditMode, setEditMode, objects, setObj };


    return <EditContext.Provider value={value}>{children}</EditContext.Provider>;
};


const START_Y = 20;
const data = [
    {
        id: crypto.randomUUID(),
        name: "Alpaca",
        type: "animal",
        position: [17, START_Y, 0],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Bull",
        type: "animal",
        position: [23, START_Y, 0],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Cow",
        type: "animal",
        position: [24, START_Y, 0],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Deer",
        type: "animal",
        position: [29, START_Y, 0],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Donkey",
        type: "animal",
        position: [14, START_Y, 10],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Fox",
        type: "animal",
        position: [13, START_Y, 22],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Horse",
        type: "animal",
        position: [15, START_Y, 1],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Husky",
        type: "animal",
        position: [67, START_Y, 10],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "ShibaInu",
        type: "animal",
        position: [40, START_Y, 22],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Stag",
        type: "animal",
        position: [22, START_Y, 40],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "WhiteHorse",
        type: "animal",
        position: [10, START_Y, 10],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Wolf",
        type: "animal",
        position: [4, START_Y, 50],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Apatosaurus",
        type: "dino",
        position: [34, START_Y, 16],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Parasaurolophus",
        type: "dino",
        position: [-15, START_Y, 20],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Stegosaurus",
        type: "dino",
        position: [11, START_Y, 23],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "TRex",
        type: "dino",
        position: [-20, START_Y, 18],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Triceratops",
        type: "dino",
        position: [9, START_Y, 44],
        rotation: [0, 0, 0],
    },
    {
        id: crypto.randomUUID(),
        name: "Velociraptor",
        type: "dino",
        position: [34, START_Y, 7],
        rotation: [0, 0, 0],
    },
];
취소
 공유
취소
댓글 0
댓글 알림
나의얼굴