https://github.com/oculus-samples/Unity-TheWorldBeyond 유니티에서 공식적으로 제공해주는 프로젝트 기반으로 작성된 글입니다. 사용한 유니티 버전 : 2020.3.18f 사용한 VR 기기 : meta quest 3 |
먼저 위에서 제공되는 링크에서 Unity-TheWorldBeyond 프로젝트를 받아줍니다. oculus 및 유니티 버전 별 제공하는 패키지가 다를 수 있기 때문에 사용한 유니티 버전 및 해당 프로젝트를 받아서 수정하는 식으로 진행하는 것을 추천 드립니다. 추가적으로 기존 “현실 벽 파괴하고 3D 공간 등장 시키기” 프로젝트에 이어서 제작하는 프로젝트입니다.
먼저 해당 프로젝트 손 오브젝트가 제공되지 않기 때문에 다른 곳에서 얻은 손 오브젝트를 import 해줍니다. 이때 스크립트는 빼고 import 해줍니다. 안 그러면 오류가 납니다.
참고로 improt 후 shader 가 깨져 있다면 위에 처럼 standard 로 바꿔줍니다.
아래 손 prefab을 각 손 위치에 배치 시켜줍니다.
animator에 들어 가보면 아래처럼 뜨고 이 중에서 grip 과 trigger 값을 조정해보면 손 모양이 어떻게 변하는지 확인할 수 있습니다.
기본 제공하는 스크립트는 아래와 같습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class AnimateHandOnInput : MonoBehaviour
{
public InputActionProperty pinchAnimationAction;
public InputActionProperty gripAnimationAction;
public Animator handAnimator;
// Update is called once per frame
void Update()
{
float triggerValue = pinchAnimationAction.action.ReadValue<float>();
handAnimator.SetFloat("Trigger", triggerValue);
float gripValue = gripAnimationAction.action.ReadValue<float>();
handAnimator.SetFloat("Grip", gripValue);
}
}
저 같은 경우는 참고만 하고 아래와 같이 스크립트를 만들어줬습니다.
각 현재 손 상태에 따라 애니메이션이 변할 수 있도록 해주었습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SettingHandAnimation : MonoBehaviour
{
public Animator handAnimator;
public bool isGrap = false;
public bool isTrigger = false;
public bool isNot = false;
// Update is called once per frame
void Update()
{
if(isGrap){
handAnimator.SetFloat("Trigger", 1);
isGrap = false;
}
if(isTrigger){
handAnimator.SetFloat("Grip", 1);
isTrigger = false;
}
if(isNot){
handAnimator.SetFloat("Trigger", 0);
handAnimator.SetFloat("Grip", 0);
isNot = false;
}
}
}
설정은 다음과 같이 각 손 위치에 맞는 animator를 넣어주었습니다.
그 다음으로는 애니메이션 변화 상태를 넘겨주기 위한 스크립트 만들어주었습니다.
기존 프로젝트에서 썼던 SampleShooter를 변형했습니다.
참고로 grab 이라는 동작을 감지하기 위해, 여러 테스트를 위해 왼손 오른쪽 다른 방식으로 적용시켜보았습니다.
using UnityEngine;
public class SampleShooter : MonoBehaviour
{
public GameObject _gunPrefab;
public GameObject _bulletPrefab;
public Transform _leftHandAnchor;
public Transform _rightHandAnchor;
public SettingHandAnimation settingHandAnimation_L;
public SettingHandAnimation settingHandAnimation_R;
public CanvasController canvasController;
public OVRGrabber grabberL;
GameObject _leftGun;
GameObject _rightGun;
void Start()
{
_leftGun = Instantiate(_gunPrefab);
_leftGun.transform.SetParent(_leftHandAnchor, false);
_rightGun = Instantiate(_gunPrefab);
_rightGun.transform.SetParent(_rightHandAnchor, false);
}
// Update is called once per frame
void Update()
{
// 왼손
if (OVRInput.GetDown(OVRInput.RawButton.LIndexTrigger))
{
Vector3 ballPos = _leftGun.transform.position + _leftGun.transform.forward * 0.1f;
Instantiate(_bulletPrefab, ballPos, Quaternion.identity);
//settingHandAnimation_R.isTrigger = true;
canvasController.ChangeText1("L Trigger");
}
// 오른손
if (OVRInput.GetDown(OVRInput.RawButton.RIndexTrigger))
{
Vector3 ballPos = _rightGun.transform.position + _rightGun.transform.forward * 0.1f;
Instantiate(_bulletPrefab, ballPos, Quaternion.identity);
//settingHandAnimation_L.isTrigger = true;
canvasController.ChangeText2("R Trigger");
}
// 오른손
if (OVRInput.GetDown(OVRInput.Button.SecondaryHandTrigger))
{
settingHandAnimation_R.isTrigger = true;
canvasController.ChangeText2("R Grap");
}
// 왼손
// OVRInput.GetDown(OVRInput.Button.PrimaryHandTrigger) 원래는 이 코드인데 안 먹음
// if(grabberL.grabbedObject.gameObject != null) grab 은 인식하나 그 뒤 공을 놓았을 때 grabberL.grabbedObject.gameObject== null 인식 안됨
if (grabberL.grabbedObject != null)
{
settingHandAnimation_L.isTrigger = true;
canvasController.ChangeText1("L Grap");
}
// 오른쪽
if(OVRInput.GetUp(OVRInput.Button.SecondaryHandTrigger) || OVRInput.GetUp(OVRInput.RawButton.RIndexTrigger)){
settingHandAnimation_R.isNot = true;
canvasController.ChangeText2("R Not");
}
// 왼손
if(grabberL.grabbedObject == null){
settingHandAnimation_L.isNot = true;
canvasController.ChangeText1("L Not");
}
}
}
다음과 스크립트가 부착된 오브젝트 설정입니다.
여기까지 하면 끝납니다 다만 더 직관적인 확인을 위해서는 다음과 같이 canvas 를 손 옆에 부착해서 현재 동작을 표시해주는 텍스트를 띄워주면 좋습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CanvasController : MonoBehaviour
{
public GameObject spherePrefab;
public Transform pose;
static public CanvasController Instance = null;
public Text text1;
public Text text2;
private void Awake()
{
if (!Instance)
{
Instance = this;
}
}
public void ChangeText1(string text){
text1.text = text;
}
public void ChangeText2(string text){
text2.text = text;
}
public void ClickButton(){
Instantiate(spherePrefab, pose);
}
}
결과 영상 :
읽어주셔서 감사합니다.
'Project' 카테고리의 다른 글
[Even-I] 이븐아이 6기 게임톤 신청 및 결과 후기 (0) | 2024.03.17 |
---|---|
[유니티/MR] 현실 벽 파괴하고 3D 공간 등장 시키기 (0) | 2024.03.10 |
[회사 프로젝트][제페토 개발] Zepeto Gucci Ancora Project (0) | 2023.12.11 |
[회사 프로젝트][제페토 개발] Zepeto 진격의 거인(Attack On Titan) 게임 (0) | 2023.12.11 |
[해커톤] Junction Asia 2023 Project “My Chef Friend” App (0) | 2023.09.05 |
댓글