[Unity] VR 회전 스크립트

힐링힐링·2024년 11월 8일
0

UNITY

목록 보기
32/35

원하는 상황

  1. 시상 카드를 잡는다
  2. 시상 카드가 사라진다.
  3. bgm이 시작된다
  4. 후보자 카드가 5초에 한번씩 나오며 회전한다.
  5. 상장을 잡으면, BGM과 후보자 카드가 사라진다.

스크립트

  1. 시상 카드를 잡는다 => 시상카드 parentsObject
  2. 시상 카드가 사라진다. => OnSelectEntered 메소드
  3. bgm이 시작된다 => OnSelectEntered 메소드
  4. 후보자 카드가 5초에 한번씩 나오며 회전한다. => Update 메소드
  5. 상장을 잡으면, BGM과 후보자 카드가 사라진다. => OnGrabbed 메소드
using Oculus.Interaction;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using static Meta.WitAi.Data.AudioEncoding;

public class TouchNominate : MonoBehaviour
{
    public GameObject parentsObject;
    public GameObject awardObject;
    public GameObject[] objects; // 움직일 GameObject 배열
    public GameObject newBGM;
    private AudioSource previousAudio; // 이전에 재생된 오디오 소스를 저장할 변수


    public float radius = 1f; // 원의 반지름
    public float speed = 4f; // 회전 속도

    private float angle = 0f;

    private XRSimpleInteractable interactable;
    private XRGrabInteractable grabInteractable;

    //오브젝트 생성 조절
    public float spawnInterval = 5f; // 오브젝트 생성 간격 (초)
    private int currentObjectIndex = 0; // 현재 생성된 오브젝트 인덱스
    private bool isSpawning = false; // 오브젝트 생성 중인지 여부

    private void Start()

    {
        // XRSimpleInteractable 컴포넌트를 가져옵니다.
        interactable = parentsObject.GetComponent<XRSimpleInteractable>();
        // XRGrabInteractable 컴포넌트를 가져옵니다.
        grabInteractable = awardObject.GetComponent<XRGrabInteractable>();

        // interactable이 null이 아니면,
        if (interactable != null)
        {
            // selectEntered 이벤트에 핸들러를 등록합니다.
            interactable.selectEntered.AddListener(OnSelectEntered);
        }
        else
        {
            Debug.LogError("XRSimpleInteractable 컴포넌트를 찾을 수 없습니다.");
        }


        // grabInteractable null이 아니면,
        if (grabInteractable != null)
        {
            // selectEntered 이벤트에 핸들러를 등록합니다.
            grabInteractable.selectEntered.AddListener(OnGrabbed);
        }
        else
        {
            Debug.LogError("XRGrabInteractable 컴포넌트를 찾을 수 없습니다.");
        }


        // objects 배열의 모든 오브젝트를 비활성화합니다.
        foreach (GameObject obj in objects)
        {
            obj.SetActive(false);
        }

        for (int i = 0; i < objects.Length; i++)
        {
            // 위치를 업데이트합니다.
            objects[i].transform.position = new Vector3(parentsObject.transform.position.x, parentsObject.transform.position.y - 0.5f, parentsObject.transform.position.z );
        }


    }

    // 손으로 터치했을 때 호출되는 함수입니다.
    private void OnSelectEntered(SelectEnterEventArgs args)
    {
        // 기존 오디오 끄기
        if (previousAudio != null)
        {
            previousAudio.Stop();
        }

        newBGM.SetActive(true);

        AudioSource newAudio = newBGM.GetComponent<AudioSource>();

        // 새로운 오디오 재생
        if (newAudio != null)
        {
            
            newAudio.Play();
            previousAudio = newAudio; // 현재 재생 중인 오디오 소스 저장
        }
        else
        {
            Debug.LogError("오디오 소스를 찾을 수 없습니다.");
        }

        parentsObject.GetComponent<MeshRenderer>().enabled = false;

        // parentsObject 내에서 Title과 Contents GameObject 찾기
        Transform titleTransform = parentsObject.transform.Find("Title");
        Transform contentTransform = parentsObject.transform.Find("Contents");

        // 찾은 GameObject 비활성화
        if (titleTransform != null)
        {
            titleTransform.gameObject.SetActive(false);
        }
        else
        {
            Debug.LogError("Title GameObject를 찾을 수 없습니다.");
        }

        if (contentTransform != null)
        {
            contentTransform.gameObject.SetActive(false);
        }
        else
        {
            Debug.LogError("Contents GameObject를 찾을 수 없습니다.");
        }

        // 오브젝트 생성 코루틴 시작
        if (!isSpawning)
        {
            StartCoroutine(SpawnObjects());
        }
    }

    // 오브젝트를 순차적으로 생성하는 코루틴 함수
    private IEnumerator SpawnObjects()
    {
        isSpawning = true;

        while (currentObjectIndex < objects.Length)
        {
            // 현재 인덱스에 해당하는 오브젝트를 활성화합니다.
            objects[currentObjectIndex].SetActive(true);

            // 다음 오브젝트 생성까지 기다립니다.
            yield return new WaitForSeconds(spawnInterval);

            currentObjectIndex++;
        }

        isSpawning = false;
    }

    // awardObject를 Grab했을 때 호출될 함수
    private void OnGrabbed(SelectEnterEventArgs args)
    {
        if (newBGM != null)
        {
            newBGM.GetComponent<AudioSource>().Stop();
        }
        // parentsObject를 비활성화
        parentsObject.SetActive(false);

    }
    void Update()
    {
        // 각도를 시간에 따라 증가
        angle += speed * Time.deltaTime;

        // 각도를 라디안으로 변환
        float radian = angle * Mathf.Deg2Rad;

        // 각 GameObject의 위치를 계산하고 업데이트
        for (int i = 0; i < currentObjectIndex; i++)
        {
            // 각 GameObject offset계산
            float offset = i * 1.5f * Mathf.PI / objects.Length;

            // 새로운 위치를 계산
            float x = Mathf.Cos(radian + offset) * radius + parentsObject.transform.position.x;
            float z = Mathf.Sin(radian + offset) * radius + parentsObject.transform.position.z;

            // 위치 업데이트
            objects[i].transform.position = new Vector3(x - 1.8f, parentsObject.transform.position.y + 0.8f, z);
        }
    }


}
profile
재밌겠네 ? 해봐야지 ~

0개의 댓글