CREATE YOUR WORLD
Interaction with Object
ZEPETO 캐릭터에 탈 것 적용하기
19분
zepeto 캐릭터에 물체를 부착하는 가이드를 적용하면 캐릭터가 자동차, 비행기, 애완동물 등과 같이 차량을 타는 것처럼 구현할 수 있습니다 📘 다음 가이드를 참조하십시오 \[ zepeto 캐릭터에 오브젝트 부착하기 docid\ vs9vfckvakshborxh3nz ] 애니메이터 설정하기 1\) 프로젝트 > 생성 > 애니메이터 컨트롤러로 이동하여 애니메이터 컨트롤러를 생성하고 이름을 vehiclezepetoanimator로 변경합니다 2\) 애니메이터 탭에서 상태 만들기 > 비어 있는 상태를 선택하여 비어 있는 상태를 생성합니다 3\) 검사기에서 적절하게 이름을 변경하고 모션에 애니메이션 클립을 할당합니다 원하는 애니메이션 클립 파일을 사용하려면 사용자 정의 애니메이션 가이드를 참조하십시오 📘 다음 가이드를 참조하십시오 \[ 커스텀 애니메이션 적용 방법 docid\ agaiesi0jlr83c2khm4ch ] 4\) vehiclezepetoanimator를 zepetoplayers에 드래그 앤 드롭하여 설정합니다 👍 팁 차량의 크기에 따라 카메라 높이를 변경해야 하는 경우, zepetoplayers에서 카메라 lookoffset 값을 미리 설정할 수 있습니다 예제 코드 1\) 프로젝트 > 생성 > zepeto > typescript로 이동하여 typescript를 생성하고 ridevehicle로 이름을 바꿉니다 2\) 아래와 같이 샘플 스크립트를 작성합니다 이 예제의 vehicle transform 값은 실제로 적용할 때 vehicle prefab에 맞게 조정해야 합니다 import { zepetoscriptbehaviour } from 'zepeto script'; import { zepetocharacter, zepetoplayers } from 'zepeto character controller'; import { transform, animator, gameobject, humanbodybones, object, vector3, quaternion } from 'unityengine'; export default class ridevehicle extends zepetoscriptbehaviour { public vehicleprefab gameobject; public bodybone humanbodybones; private localcharacter zepetocharacter; private vehicle gameobject; start() { zepetoplayers instance onaddedlocalplayer addlistener(() => { // find the local player and set it to localcharacter this localcharacter = zepetoplayers instance localplayer zepetoplayer character; // get the localcharacter's animator component const animator animator = this localcharacter zepetoanimator; // get the position of the bone to attach the object to const bone transform = animator getbonetransform(this bodybone); // create the vehicle prefab this vehicle = object instantiate(this vehicleprefab, bone) as gameobject; // set vehicle transform this vehicle transform localposition = new vector3(0 5, 0,0); this vehicle transform localrotation = quaternion euler(0, 0,90); }); } } 3\) 스크립트 작성을 완료한 후, 스크립트를 씬의 gameobject에 추가합니다 4\) 인스펙터에서 차량의 프리팹 리소스와 부착할 본을 지정합니다 5\) 재생 버튼을 클릭하면 zepeto 캐릭터가 차량에 탑승하는 것을 볼 수 있습니다 👍 팁 차량의 프리팹과 캐릭터의 애니메이션 클립을 변경하여 다양한 차량을 만들 수 있습니다 아이템 소비 시 크기 변화 예시 여기 캐릭터의 크기가 아이템을 소비할 때 변화하는 콘텐츠를 구현한 재미있는 예시가 있습니다 1\) 이 예시에서는 두 가지 유형의 프리팹을 준비하고 소비 시 크기가 증가하는 아이템의 태그를 "increase"로, 크기가 감소하는 아이템의 태그를 "decrease"로 설정했습니다 2\) 각 아이템에 콜라이더를 추가하고 istrigger를 체크합니다 3\) 프로젝트 > 생성 > zepeto > typescript로 이동하여 typescript를 생성하고 이름을 changeobjectsize로 변경합니다 4\) 아래와 같이 샘플 스크립트를 작성합니다 import { collider, gameobject, vector3 } from 'unityengine'; import { zepetoscriptbehaviour } from 'zepeto script'; export default class changeobjectsize extends zepetoscriptbehaviour { public vehicle gameobject; start() { } ontriggerenter(collider collider) { if (collider tag === "increase") { this gameobject transform localscale += new vector3(0 1, 0 1, 0 1); gameobject destroy(collider gameobject); } if (collider tag === "decrease") { const decreaseamount = new vector3(0 1, 0 1, 0 1); const newscale = this gameobject transform localscale decreaseamount; gameobject destroy(collider gameobject); // 예외 처리 스케일이 (1, 1, 1)보다 작아지지 않도록 보장합니다 if (newscale x >= 1 && newscale y >= 1 && newscale z >= 1) { this gameobject transform localscale = newscale; } } } } 코드의 핵심 부분은 각 항목에 닿을 때 zepeto 캐릭터의 크기를 변경하기 위해 localscale을 수정하는 것입니다 크기 변경을 위해 숫자를 자유롭게 조정하세요 하지만 스케일이 (1,1,1)보다 작아지지 않도록 예외를 처리해야 합니다 5\) 이 스크립트는 런타임에 생성된 zepeto 캐릭터에 추가되어야 합니다 따라서 차량을 부착하는 ridevehicle 스크립트를 다음과 같이 수정하세요 import { zepetoscriptbehaviour } from 'zepeto script'; import { zepetocharacter, zepetoplayers } from 'zepeto character controller'; import { transform, animator, gameobject, humanbodybones, object, vector3, quaternion } from 'unityengine'; import changeobjectsize from ' /changeobjectsize'; export default class ridevehicle extends zepetoscriptbehaviour { public vehicleprefab gameobject; public bodybone humanbodybones; private localcharacter zepetocharacter; private vehicle gameobject; start() { zepetoplayers instance onaddedlocalplayer addlistener(() => { // 로컬 플레이어를 찾아 localcharacter에 설정합니다 this localcharacter = zepetoplayers instance localplayer zepetoplayer character; // localcharacter의 애니메이터 컴포넌트를 가져옵니다 const animator animator = this localcharacter zepetoanimator; // 객체를 부착할 뼈의 위치를 가져옵니다 const bone transform = animator getbonetransform(this bodybone); // 차량 프리팹을 생성합니다 this vehicle = object instantiate(this vehicleprefab, bone) as gameobject; // 차량 변환 설정 this vehicle transform localposition = new vector3(0 5, 0,0); this vehicle transform localrotation = quaternion euler(0, 0,90); // charactercontroller에 스크립트를 추가합니다 const sizescript = this localcharacter gameobject addcomponent\<changeobjectsize>(); // 스크립트의 인스펙터에 차량을 추가합니다 sizescript vehicle = this vehicle; }); } } 런타임에 changeobjectsize 스크립트를 추가하는 코드가 추가되었습니다 6\) 재생 버튼을 클릭하면 아이템을 소비할 때마다 캐릭터의 크기가 변하는 것을 볼 수 있습니다 차량과 상호작용하기 상호작용 가이드를 적용하면 차량과 상호작용한 후 원하는 위치에서 탑승을 구현할 수 있습니다 📘 다음 가이드를 참조하십시오 \[ 오브젝트와 인터렉션하기 docid\ o9fgua39 m8njkslqq8ba ] 설정하기 1\) 상호작용 가이드와 같은 방식으로 차량 프리팹에 dockpoint 객체와 ui 프리팹을 설정하십시오 2\) unity 편집기에서 상단의 변환 기즈모 토글 버튼이 로컬로 설정되어 있는지 확인하고, z축(파란 화살표)이 객체에서 바깥쪽을 가리키도록 회전시킵니다 3\) collider 구성 요소를 추가하고 istrigger 옵션을 확인합니다 4\) 플레이어가 객체와 상호작용할 수 있는 범위 내에서 collider의 크기를 조정합니다 5\) 계층 구조에서 hierarchy > 빈 객체 만들기를 통해 dockpoint의 자식으로 빈 객체를 만들고, 이름을 iconpos로 변경합니다 6\) preficoncanvas를 객체 상호작용 가이드와 동일한 방식으로 설정한 후, 프리팹으로 만드세요 7\) 추가 단계 내리기 버튼 만들기 hierarchy > ui > button으로 가서 차량 객체의 자식으로 버튼을 만들고, 이름을 내리기 버튼으로 변경하세요 차량에 탑승 애니메이션 추가하기 캐릭터가 차량에 탑승하거나 하차할 때, 자연스러운 애니메이터 설정이 필요합니다 아래 가이드는 탑승 또는 하차에 필요한 애니메이터 설정을 도와줄 것입니다 사용자 정의 애니메이션을 적용하는 가이드를 참조하여 사용자 정의 애니메이터에 앉기 애니메이션 상태를 추가하세요 📘 다음 가이드를 참조하세요 \[ 커스텀 애니메이션 적용 방법 docid\ agaiesi0jlr83c2khm4ch ] 1\) 추가된 애니메이션 상태에서 마우스 오른쪽 버튼을 클릭하고 전환 만들기를 클릭하여 대기 상태에서 앉기 상태로, 그리고 앉기 상태에서 대기 상태로의 전환을 만듭니다 생성된 전환을 선택하고 종료 시간 옵션의 체크를 해제합니다 2\) 사용자 정의 애니메이터 → 매개변수 → \[ + ]에서 bool 조건을 추가하고 이름을 isriding으로 변경합니다 3\) 앉기 상태에서 대기 상태로의 전환을 위해 조건 클릭 → \[ + ]를 클릭하고 isriding 조건을 추가하며 옵션을 false로 설정합니다 4\) 대기 상태에서 앉기 상태로의 전환을 위해 조건 클릭 → \[ + ]를 클릭하고 isriding 조건을 추가하며 옵션을 true로 설정합니다 스크립트 interactionicon ts 스크립트를 작성합니다 이 스크립트는 차량 프리팹의 트리거 영역에 들어갈 때 상호작용 ui를 표시합니다 작성된 interactionicon zepetoscript를 dockpoint 객체에 추가하고, 검사기에서 pref icon canvas와 icon position을 할당합니다 ui와 상호작용한 후 차량에 탑승하는 방법에 대한 샘플 코드는 아래의 ridevehicleexample을 참조하세요 import { animator, gameobject, humanbodybones, physics, transform, vector3, waitforendofframe } from 'unityengine'; import { zepetoscriptbehaviour } from 'zepeto script'; import { zepetoplayers, zepetocharacter, characterstatemachine } from "zepeto character controller"; import { button } from 'unityengine ui'; import interactionicon from ' /interactionicon'; export default class ridevehicleexample extends zepetoscriptbehaviour { @serializefield() private bodybone humanbodybones; public isriding bool; public getoffbtn button; public vehicleobj gameobject; private interactionicon interactionicon; private localcharacter zepetocharacter; private playersittingposition vector3; private animator animator; private start() { zepetoplayers instance onaddedlocalplayer addlistener(() => { this localcharacter = zepetoplayers instance localplayer zepetoplayer character; this animator = this localcharacter zepetoanimator; }); this interactionicon = this transform getcomponent\<interactionicon>(); this interactionicon onclickevent addlistener(() => { // 상호작용 아이콘이 클릭되면 아이콘을 숨기고 상호작용을 수행합니다 this interactionicon hideicon(); this dointeraction(); }); // getoffbtn(차량에서 내리는 버튼)의 클릭 이벤트를 설정합니다 this getoffbtn onclick addlistener(() => { if(this isriding) { this stopinteraction(); this interactionicon showicon(); } }); this getoffbtn gameobject setactive(false); } // 탑승 로직을 수행하는 메서드 private dointeraction() { // animator의 전환 값을 설정하여 현재 애니메이션 상태를 앉기 상태로 전환합니다 this animator setbool("isriding", true); this startcoroutine(this snapbone()); // 현재 애니메이션을 고정하기 위해 animator를 비활성화합니다 this localcharacter statemachine constraintstateanimation = true; // 차량 객체의 부모를 로컬 캐릭터로 설정합니다 this vehicleobj transform parent = this localcharacter transform; // getoffbutton을 활성화합니다 this getoffbtn gameobject setactive(true); this isriding = true; } private stopinteraction() { // animator의 전환 값을 설정하여 애니메이션 상태를 대기 상태로 전환합니다 this animator setbool("isriding", false); // animator를 다시 활성화합니다 this localcharacter statemachine constraintstateanimation = false; this isriding = false; // 차량 객체의 부모를 null로 설정합니다 this vehicleobj transform parent = null; // getoffbutton을 비활성화합니다 this getoffbtn gameobject setactive(false); } // 차량에 뼈를 스냅하는 코루틴 private snapbone() { const animator animator = this localcharacter zepetoanimator; const bone transform = animator getbonetransform(this bodybone); let idx = 0; while (true) { // 뼈와 캐릭터 위치 간의 거리를 계산합니다 const distance = vector3 op subtraction(bone position, this localcharacter transform position); const newpos vector3 = vector3 op subtraction(this transform position, distance); // 플레이어 앉는 위치를 업데이트하고 캐릭터의 위치와 회전을 설정합니다 this playersittingposition = newpos; this localcharacter transform position = this playersittingposition; this localcharacter transform rotation = this transform rotation; yield new waitforendofframe(); idx++; // 애니메이션의 5 프레임 동안 위치를 보정합니다 if (idx > 5) { return; } } } } 스크립트의 흐름은 다음과 같습니다 시작() 아이콘이 클릭되면, this interactionicon이 비활성화되고, dointeraction() 함수가 호출됩니다 dointeraction() 애니메이터의 전환 값을 설정하여 앉기 애니메이션을 재생합니다 snap bone() 코루틴을 시작하여 zepeto 캐릭터의 bodybone을 targettransform에 연결합니다 this localcharacter statemachine constraintstateanimation = true; 함수를 사용하여 현재 애니메이터의 전환을 비활성화하고 현재 재생 중인 애니메이션을 고정합니다 차량 객체의 부모가 zepeto 캐릭터로 변경됩니다 오른쪽 상단의 get off 버튼이 활성화됩니다 stopinteraction() 애니메이터의 전환 값을 설정하여 대기 애니메이션을 재생합니다 상황에 따라 적절한 애니메이션이 재생되도록 애니메이터 전환을 다시 활성화합니다 차량 객체의 부모를 null로 설정합니다 get off 버튼을 비활성화합니다 this getoffbtn onclick stopinteraction() 함수가 호출됩니다 this interactionicon이 활성화됩니다 작성된 ridevehicleexample zepetoscript를 dockpoint에 추가하고, 검사기에서 get off 버튼과 차량 프리팹을 할당합니다 \[▶︎(재생)] 차량 탑승을 시도하려면 재생 버튼을 누르세요 결과 화면 👍 팁 위 샘플은 멀티플레이어 동기화에 고려되지 않은 콘텐츠의 예입니다 멀티플레이어 동기화를 구현하려면 각 플레이어가 탑승하고 있는 차량, 차량의 크기 및 위치와 같은 정보를 room state로 동기화해야 합니다