본문 바로가기

TIL

[TIL]2023-12-26 / 3일차 - 오디오 매니저 구현과 코드 최적

 

오늘은 사전캠프에서 배운 내용에서 벗어나 각종 자료를 이용해 공부하고 주변에 도움을 구해 다양한 코드를 공부했다.

 

오늘 주로 작업한 내용은 카드를 매칭하면 조원 이름을 띄우고 아닐 시에는 실패 문장 띄우기 / 난이도 스테이지 구현된 것에 오디오 매니저를 만들어 난이도별 배경음과 카드 효과음들, 시간이 조금 남을 시에 비상 배경음 틀기, 그리고 이러한 구현들 후에 렉을 줄이기 위한 코드 최적화를 진행하였다.

 

더보기

오디오 매니저 구현 과정

 

오디오 매니저는 초기 구현 당시에 난이도선택 코드와 게임매니저에서 조건문을 통해 GetComponent를 불러오는 방식이었다.

 

오디오 매니저

    {
        audioSource.clip = bgmusic;
        audioSource.Play();
        DontDestroyOnLoad(gameObject);
    }
    public void ChangeBGM(int num)
    {
        if (num == 1) 
        {
            gameObject.GetComponent<AudioSource>().clip = Resources.Load<AudioClip>("StageBGM/StageEasy");
            audioSource.Play();
        }
        else if (num == 2)
        {
            gameObject.GetComponent<AudioSource>().clip = Resources.Load<AudioClip>("StageBGM/StageNormal");
            audioSource.Play();
        }
        else if (num == 3)
        {
            gameObject.GetComponent<AudioSource>().clip = Resources.Load<AudioClip>("StageBGM/StageHard");
            audioSource.Play();
        }
        else if (num == 4)
        {
            gameObject.GetComponent<AudioSource>().clip = Resources.Load<AudioClip>("StageBGM/Emergency");
            audioSource.Play();
        }
        else if (num == 5)
        {
            gameObject.GetComponent<AudioSource>().clip = Resources.Load<AudioClip>("StageBGM/Menu");
            audioSource.Play();
        }
    }
}

 

난이도 선택 코드, 각 난이도 별 ChangeBGM을 불러오는 모습

    public Image EasyScoreImg;
    public Image NormalScoreImg;
    public Image HardScoreImg;
    public GameObject audiomanager;

    public float canNormal;
    public float canHard;

@@ -28,6 +29,7 @@ public class selectDifficulty : MonoBehaviour
    // Start is called before the first frame update
    void Start()
    {
        audiomanager = GameObject.Find("audioManager");
        // 각 난이도별 점수 불러오기
        easyScore = PlayerPrefs.GetFloat("EasyScore", 0f);
        normalScore = PlayerPrefs.GetFloat("NormalScore", 0f);


@@ -71,6 +73,7 @@ public class selectDifficulty : MonoBehaviour

    public void EasyClick()
    {
        audiomanager.GetComponent<audioManager>().ChangeBGM(1);
        // Easy 스테이지 진입
        NowDifficulty.GetComponent<nowDifficulty>().difficulty = "Easy";
        SceneManager.LoadScene("MainScene");

@@ -80,6 +83,7 @@ public class selectDifficulty : MonoBehaviour
        // Easy가 {CanNormal}점 이상일 경우 Normal 진입
        if(easyScore > canNormal)
        {
            audiomanager.GetComponent<audioManager>().ChangeBGM(2);
            NowDifficulty.GetComponent<nowDifficulty>().difficulty = "Normal";
            SceneManager.LoadScene("MainScene");
        }

@@ -90,6 +94,7 @@ public class selectDifficulty : MonoBehaviour
        // Normal이 {CanHard}점 이상일 경우 Hard 진입
        if(normalScore > canHard)
        {
            audiomanager.GetComponent<audioManager>().ChangeBGM(3);
            NowDifficulty.GetComponent<nowDifficulty>().difficulty = "Hard";
            SceneManager.LoadScene("MainScene");
        }

 

이런 식으로 불러오는 방식이었으나 오디오 불러오는 과정 중 생기는 약간의 렉을 확인하고 줄일 방법을 찾고자 오디오 파일을 더 압축하고 코드를 줄이기로 결정하였다.

 

이후 오디오 매니저

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class audioManager : MonoBehaviour
{
    public AudioSource audioSource;
    public AudioClip[] Bgmlist;
    
    private void Start()
    {
        audioSource.clip = Bgmlist[0];
        audioSource.Play();
        DontDestroyOnLoad(gameObject);
    }
    public void ChangeBGM(int num)
    {
        audioSource.clip = Bgmlist[num];
        audioSource.Play();
    }
}

 

이런 식으로 GetComponent와 조건문이 많아 무겁다고 생각되어 이들 없이 배열을 만들어 불러오는 방식으로 최적화 하였다.

 

또한 긴급한 상황 (시간이 20초 남은 상황)에 긴급한 배경음악을 틀어주고 남은 시간을 빨간색으로 표시하는 코드를 만들었다.

        public audioManager audiomanager;
       
       	isPlay = false;
        audiomanager = GameObject.Find("audioManager").GetComponent<audioManager>();
        
     void Update()
    {
        time -= Time.deltaTime;
        timeText.text = time.ToString("N2");

 		if (!isPlay && time < 20.0f)
        {
            isPlay= true;
            audiomanager.ChangeBGM(4);
            timeText.color = Color.red;
        }
     }

 

시간을 재는 업데이트 문에다가 추가한 내용이다보니 처음 ChangeBGM만 사용했을 때는 계속 업데이트를 반복하며 해당 코드가 무한 반복 재생되었다.

 

그래서 이를 해결하기 위해 isPlay 함수를 만들어 Boolean 체크를 하여 False일 때만 작동하게 하고 한번 배경음을 전환할 때 True로 바꿔지도록 코드를 수정하였다.

 

더보기

조원 이름 띄우기 과정

 

조원 이름을 띄우는 과정은 처음에는 편리하게 스프라이트 이름을 그대로 출력할 수 있도록 하고자 했다

그렇기 때문에 리소스에 이미지 이름들을 모두 한글명으로 바꾸고

      string imageName = "image" + images[i].ToString();
                newCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(imageName);

난이도마다 이런 식으로 불러오던 카드 이미지를

                string spriteName = sprites[images[i]].name;
                newCard.transform.Find("Front").GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(spriteName);

 스프라이트로 바꾸고 //("front")를 ("Front")로 바꿔쓴 점에 주목, 이 오타 문제를 찾지 못해 NullReference 문제를 해결하는데 3시간이 걸렸었다...

 

이런식으로 불러온 스프라이트 이름을 끝에 한글자(리소스 번호 = ex) 김준하1)만 지운 채로 출력하도록 하였다.

            nameText.text = firstCardImage.Substring(0, firstCardImage.Length - 1);

 

이외에도 여러 코드를 썼지만 결과적으로 조원이 다른 코드를 작성하는데 있어 리소스를 한글로 바꿔놓은 점이 문제를 일으키기 시작했고 이를 위해 다시 영어로 변경한 뒤 코드를 다시 쓰기로 하였다.

 

이를 if문을 이용하기로 결정하여 아래와 같이 작성하였다.

이미지에는 각각 조원 순서대로 3개씩 번호가 부여되어 있었고 ex = (image13~15는 이승배 조원님) 이를 앞에 이미지를 번호만 자른채 불러와 이 번호를 비교하여 이름을 띄우는 방식을 구현하였다. 

            if (int.Parse(firstCardImage.Substring(5)) >= 13)
            {
                nameText.text = "이승배";
            }
            else if (int.Parse(firstCardImage.Substring(5)) >= 10)
            {
                nameText.text = "이도현";
            }
            else if (int.Parse(firstCardImage.Substring(5)) >= 7)
            {
                nameText.text = "박소이";
            }
            else if (int.Parse(firstCardImage.Substring(5)) >= 4)
            {
                nameText.text = "김준하";
            }
            else if (int.Parse(firstCardImage.Substring(5)) >= 1)
            {
                nameText.text = "김성우";
            }

 

아래와 같이 완성되었다.

이를 통해 어제 한 것까지 포함하여 내가 맡은 파트는 끝이 나 추가적인 작업을 하며 다듬다가

 

조원들의 이미지가 일관성이 없는 모습이 아까워 그림 취미를 살려 내가 조원들의 아바타로 일관적인 카드로 만들기로 하였다.

 

아직 3개 덜 만들었으나 위와 같이 좀 더 아기자기하고 일관된 카드로 만들었다.

 

내일은 나머지 그림 금방 그리고 추가적으로 다듬는 작업을 한 후 발표 자료를 준비해 보고자 한다.