8 개의 강의

목차

음악 지역 State 설정하기

게임에 상호작용 음악을 통합할 때 음악을 게임의 다양한 상황이나 동작에 연결하면 해당 상황이나 동작에 대한 플레이어의 마음을 음악을 통해 표현해낼 수 있습니다. 음악 시스템을 만드는 방법은 여러가지가 있습니다. 플레이어의 게임 진행 과정이나 위치에 따라 음악을 전환하거나, 플레이어가 음악을 선택해 들을 수 있도록 하거나, 혹은 두 방법을 모두 사용할 수 있습니다. 하지만 보통 소리풍경이 복잡해지는 것을 방지하기 위해서 보통 동시에 한 음악(혹은 리듬이나 조가 같은 음악 모음)만 활성화하게 됩니다. 이 경우에는 State를 사용해서 현재 음악 State를 제어하는 것이 좋습니다. 왜냐하면 State가 전역적(global)인 범위에서 작동되기 때문이죠 (게임 오브젝트 범위와 전역적 범위에 대한 더 자세한 설명은 제 5강을 참조하시기 바랍니다).

다음 단계에서는 플레이어가 Village 안으로 들어갈 때 음악 State를 변경해봅시다. 그러기 위해서는 Village 주변에 Trigger 볼륨을 추가하고 스크립트를 통해 Player의 위치에 따라 State를 설정해야 합니다.

  1. Unity 메뉴에서 Audiokinetic > Certification > 301 > Lesson 8로 가서 Setting a Music Region State를 선택하세요.

    먼저 Village 지역에 잘 맞는 Trigger 모양을 선택해야 합니다.

    Village를 위에서 바라보면 둥근 모양을 하고 있기 때문에 Sphere(구체) Trigger를 사용하는 것이 좋겠네요.

    [작은 정보]

    Sphere Trigger는 가장 높은 성능의 Trigger 타입 중 하나로 다른 모양보다 CPU를 적게 사용합니다.

  2. Village 영역을 내려다보도록 Scene View를 조절하세요.

    [참고]

    Hierarchy에서 아무 게임 오브젝트도 선택하지 않았는지 확인하세요. 잘 모르실 경우 게임 오브젝트 아래 빈 공간을 클릭하세요.

  3. Hierarchy에서 빈 공간을 우클릭하고 3D Object로 가서 Sphere를 선택하세요.

  4. Move 도구, Rotate 도구, Scale 도구를 사용해서 Sphere가 Village 영역을 감싸도록 만드세요.

    이제 Trigger 모양에 다른 메쉬를 설정해서 안을 들여다볼 수 있도록 만들고 Sphere Collider를 Trigger로 만들어서 Trigger 안으로 들어갈 수 있도록 만들어봅시다.

  5. Inspector의 Sphere Collider에서 Is Trigger를 활성화하세요.

    Sphere 모양을 보이지 않게 하려면 Mesh Renderer를 모두 비활성화할 수 있습니다. 하지만 테스트를 위해서 Sphere 모양을 안이 비치는 재질로 만들어 언제 트리거 안으로 들어가는지 알 수 있도록 해봅시다. Sphere를 그리기 위해서 제 3강에서 사용했던 Trigger_Red Material을 사용해봅시다.

  6. Project 뷰에서 Trigger_Red를 검색하고 Trigger_Red Material을 Sphere 게임 오브젝트로 드래그하세요.

    다음으로 Sphere Trigger에 상태를 설정할 스크립트를 추가해봅시다.

  7. Sphere에 SetMusicState라는 새로운 스크립트를 만들어서 여세요.

  8. 이제 제 4강에서 설명드린 것처럼, 이미 정의된 Start()와 Update()라는 기본적인 함수가 든 스크립트가 생겼습니다.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetMusicState : MonoBehaviour {
    
        // Use this for initialization.
        void Start () {
            
        }
        
        // Update is called once per frame.
        void Update () {
            
        }
    }

    이 함수를 사용하지 않을 것이기 때문에 SetMusicState 클래스 안에 있는 모든 내용을 제거하겠습니다.

  9. SetMusicState 중괄호 안에 있는 모든 줄을 선택하고 Backspace를 누르세요.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetMusicState : MonoBehaviour {
    
    }

    플레이어가 Trigger 안으로 들어가는 것을 감지하기 위해서는 가능할 경우 스크립트에서 Trigger에 의해 호출되는 OnTriggerEnter 함수를 사용합니다. 이 함수는 제 1강에서 설명해드린 AkEvent의 Trigger On 옵션 중 하나인 'AkTriggerEnter'와 이름과 작동 방식이 비슷합니다.

  10. 빈 자리에 void OnTriggerEnter를 입력하세요.

    Visual Studio에서 드롭다운 메뉴가 나타날 것입니다. 우리가 사용하고자 하는 OnTriggerEnter 함수를 추천하고 있네요. OnTriggerEnter 구성 요소를 클릭하면 Visual Studio가 자동으로 함수 입력을 완료합니다. Visual Studio가 함수 입력을 자동 완성할 때 접근 한정자 private로 함수를 선언하게 되는데, 이 경우 SetMusicState 클래스 안에서만 이 함수를 사용할 수 있습니다.

    [참고]

    코드 편집기에 드롭다운 메뉴가 나타나지 않을 경우 다음 단계에서 직접 입력하시면 됩니다.

  11. 드롭다운 메뉴에서 OnTriggerEnter 구성 요소를 클릭하거나 private void OnTriggerEnter(Collider other){}를 입력하세요.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetMusicState : MonoBehaviour {
        private void OnTriggerEnter(Collider other){
        
        }
    }
    

    OnTriggerEnter 괄호 안에 'other'라는 Collider 변수가 보이실 것입니다. Sphere 게임 오브젝트 Collider가 또 다른 Collider(Trigger 포함)를 감지하면 OnTriggerEnter 함수와 감지된 내용이 함께 호출됩니다. 다시 말해 'other' 변수는 방금 이 Trigger 안으로 들어간 Collider에 대한 참조가 되죠. 예를 들어 Player 게임 오브젝트가 방금 만든 Sphere Trigger 안으로 들어갈 경우 OnTriggerEnter와 Player에서 발견된 Collider 컴포넌트에 대한 참조를 담고 있는 'other' 변수가 호출됩니다.

    Player의 게임 오브젝트가 Trigger 안으로 들어갈 때만 State를 변경하고자 하기 때문에 Collider 안으로 들어가는 오브젝트가 "Player"라는 태그를 가지는지 확인해야 합니다. 그러기 위해서는 트리거 안으로 들어가는 Collider 오브젝트에 'if 문'과 CompareTag() 함수를 사용해야 합니다. 'if 조건문'을 더 자세히 살펴볼까요.

    if 문은 입력을 받으면 주어진 조건에 대해 평가하여 조건이 'true'로 평가될 경우 프로그래머가 심은 코드를 실행합니다. 만약 if 문이 'false'일 경우 해당 코드 세그먼트를 건너뜁니다. if 문을 작성하려면 먼저 'if'를 입력한 후 평가에 필요한 불리언(boolean) 연산식이 들어갈 괄호 '()'와 실행할 코드가 들어갈 중괄호 '{}'를 입력하면 됩니다. 아주 간단한 예시를 살펴봅시다.

        if (Number == 42){
            print("Number is 42.");
        }else {
            print("Number is not 42.");
        }
    

    실습으로 돌아가봅시다. if 문의 괄호 안에서 Collider 오브젝트 안으로 들어갈 때 CompareTag() 함수를 사용하여 '다른' 게임 오브젝트가 Player인지 확인해야 합니다. 그러기 위해서는 Player의 태그 이름(마찬가지로 'Player'임)을 CompareTag 함수의 괄호 안에 string으로 입력하여 CompareTag 함수가 'true' 비교가 'true'인지 'false'인지 응답하도록 해야 합니다.

    [참고]
    문자열을 나타내는 string은 텍스트를 저장하는 방법으로, 텍스트 양 옆에 큰 따옴표 ("")를 사용하면 문자열을 선언할 수 있습니다.

  12. OnTriggerEnter 함수 중괄호 안에 if(other.CompareTag("Player")){ }를 입력하세요.

    public class SetMusicState : MonoBehaviour {
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){ 
                
            }
        }
    }

    [참고]

    사용 중인 코드 편집기가 자동으로 중괄호를 추가해서 줄을 끝낼 수 있기 때문에 중괄호가 중복 입력되지 않도록 주의하세요.

    이 'if 문' 안에 State를 설정하면 플레이어가 Trigger 안으로 들어갔기 때문에 이 State가 설정되었음을 알 수 있습니다. 다음으로 Wwise-Type State 프로퍼티를 만들어봅시다.

  13. 클래스의 가장 윗 부분에 public AK.Wwise.State OnTriggerEnterState;를 입력해서 Wwise-Type State 프로퍼티를 선언하세요.

    public class SetMusicState : MonoBehaviour {    
        public AK.Wwise.State OnTriggerEnterState;
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){

    이제 OnTriggerEnter() 함수에 MusicState를 설정해봅시다.

  14. if 문 안에 OnTriggerEnterState.SetValue();를 입력하고 스크립트를 저장하세요.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SetMusicState : MonoBehaviour {
        public AK.Wwise.State OnTriggerEnterState;
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerEnterState.SetValue();
            }
        }
    }

  15. Unity Inspector의 SetMusicState 스크립트에서 OnTriggerEnterState 프로퍼티를 열고 MusicStates > Music_Regions를 펼친 후 Village를 선택하세요.

    다 됐습니다! 한 번 확인해볼까요?

  16. Play 모드를 시작하고 Sphere Trigger 안으로 들어가세요.

    먼저 Training Area에서 스폰하면 Ambient Music Playlist Container가 들리실 것입니다. 하지만 Sphere Trigger 안으로 들어가면 Village Music Playlist Container로 음악이 바뀝니다.

    지금까지 작업한 과정으로 인해 트리거 안으로 들어갈 때마다 State가 변합니다. 하지만 트리거 밖으로 나가면 State가 다시 Ambient Music Playlist Container로 바뀌지 않습니다. Wwise-Type State 클래스 프로퍼티를 추가해서 Trigger 밖으로 나갈 때 State를 설정하도록 해봅시다. 이제 Play 모드를 종료하셔도 됩니다.

  17. 다시 코드 편집기로 돌아가서 OnTriggerEnterState 를 선언한 줄 바로 아래 빈 줄을 추가하고 public AK.Wwise.State OnTriggerExitState;를 입력하세요.

    public class SetMusicState : MonoBehaviour {
        public AK.Wwise.State OnTriggerEnterState;
        public AK.Wwise.State OnTriggerExitState;    
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerEnterState.SetValue();
            }
        }
    }

    플레이어가 Trigger 밖으로 나가는 것을 감지하기 위해서는 OnTriggerExit() 함수를 사용해야 합니다. 코드 작성 시간을 절약하기 위해서 OnTriggerEnter() 함수를 복사한 후 OnTriggerExit() 함수로 바꿔봅시다.

  18. 중괄호를 포함한 OnTriggerEnter() 함수 전체를 선택한 후 우클릭하고 Copy를 선택하세요.

  19. OnTriggerEnter() 함수의 닫는 중괄호 아래 빈 줄을 추가하고 우클릭하고 Paste를 선택하세요.

    public class SetMusicState : MonoBehaviour {
        public AK.Wwise.State OnTriggerEnterState;
         public AK.Wwise.State OnTriggerExitState;
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerEnterState.SetValue();
            }
        }
        
        private void OnTriggerEnter(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerEnterState.SetValue();
            }    
        }
    }

  20. 이제 OnTrigger Enter를 OnTrigger Exit으로 바꾸고 OnTrigger EnterState를 OnTrigger ExitState로 바꾼 후 스크립트를 저장하세요.

        private void OnTriggerExit(Collider other){
            if(other.CompareTag("Player")){
                OnTriggerExitState.SetValue();
            }
        }

    마지막으로 OnTriggerExitState 프로퍼티를 지정하고 작업 결과를 시험해봅시다.

  21. Unity Inspector에서 On Trigger Exit State 프로퍼티를 열고 MusicStates > Music_Regions로 가서 Nowhere를 선택하세요.

  22. Play 모드를 시작하고 Sphere Trigger 안으로 들어가세요.

    이전과 마찬가지로 Village 음악이 들리기 시작할 것입니다.

  23. Sphere Trigger 밖으로 나가세요.

    스크립트를 변경함에 따라서 이제 Ambient 음악이 재생됩니다. 이제 Play 모드를 종료하셔도 됩니다.

이 방법은 작업 속도가 매우 빠르며 사용하기 쉽지만 State를 설정하는 데에 사용되는 Trigger가 서로 겹치지 않도록 해야 합니다. 만약 서로 겹치게 될 경우 State가 충돌하기 때문이죠. 이 부분에 대해서는 다음 섹션인 'State가 겹치는 영역의 시스템 만들기'에서 더 자세히 배우게 됩니다.


이 페이지가 도움이 되었나요?