상세 컨텐츠

본문 제목

0911 TIL - 하다가 막힘...

스파르타 코딩캠프/'24 Today I Learned

by lucar 2024. 9. 11. 22:49

본문

미니 프로젝트에 이스터에그로 슈팅게임을 심고있는 중이였는데...

 

벡터고 코사인이고 사인이고 나발이고...

 

으으윽...

 

우선 보스와 플레이어, 보스의 체력바는 구현을 완료했다.

크게 3가지 패턴을 만들려고 했다.

 

전방 45도 각도로 발사되는 5개의 탄환 3연발

 

플레이어를 향해 발사되는 총알 10연발

 

보스를 중심으로 전개되는 원 모양의 흩어지는 총알 30발

 

을 구현하려 했건만

 

실행하면 멈추고 총알 수를 줄여도 멈추고 Visual Studio에서는 빨간줄이 없고

Unity는 실행하면 에러코드 한 줄 안남기고 멈춰버린다..

 

아마도 Mathf 구문 실행 중에 에러가 발생한 것 같은데 어디가 문제인지 감이 안온다..

 

인터넷을 뒤져봤는데 아직 잘 모르겠다...

 

우선 오늘 배운 걸 정리해보자.

 

InputField 숨기는 법

public InputField hiddenKeyInput; //인풋 필드를 받아옴
public GameObject inputField; //인풋 필드를 게임오브젝트로 다시 받아옴
private string getKey; //받아올 문자열

void Update()
{
    
    if (Input.GetKeyDown(KeyCode.Tab)) //tab이 입력된다면
    {
        inputField.SetActive(true); //게임오브젝트형 인풋 필드 활성화
        Time.timeScale = 0.0f; //타이무 쓰토뿌
        getKey = hiddenKeyInput.text; //인풋필드형 인풋에 입력된 텍스트를 받아온다.
        inputField.SetActive(false); //게임오브젝트형 인풋 필드 비활성화
    }
    
}

그냥 두 번 받아오면 된다. 편하고 좋다.

 

이걸 통해서 약간의 이스터에그를 구현했다.

 

게임 플레이 중 tab키를 입력하면 인풋필드가 생겨나고 거기에 알맞는 키를 입력하면 숨겨놓은 게임이 실행되게 했다.

 

근데 지금 실행해보니까 이것도 안된다. 어디선가 코드가 꼬였나보다.

흑흑

 

방금 고쳤다.

 

Update내부에서 SetActive를 True및 false로 변경하게 했더니 TimeScale만 0이되고 진행이 안되는 거였다.

    public InputField hiddenKeyInput;
    public GameObject inputField;
    bool shown = false; //거짓으로 생성

    private string getKey;

    void Update()
    {
        
        if (Input.GetKeyDown(KeyCode.Tab))
        {
            inputField.SetActive(!shown); //누르면 바로 참으로 바뀜
            Time.timeScale = 0.0f;
            getKey = hiddenKeyInput.text;
            inputField.SetActive(!shown);
        }
        
    }

 

위에 부울 변수를 따로 만들고 이를 통해 조작하게 했다.

이러니까 된다.

왤까..

 

비활성화를 해놓긴 했는데 비활성화가 안된다.

나중에 버튼이라도 추가해서 꺼야겠다.

 

public void CancelHiddenConsole()
{
    Time.timeScale = 1.0f;
    inputField.SetActive(false);
}

버튼 추가해줬다

 

흑흑

 

대충 이런 감성

와! 이스터에그! 게임 내부를 살펴볼까?

게임이 시작하고 조금 있다가 잠깐 멈추는데

GIF파일이라서 품질문제가 아니고 걍 게임이 멈춘거다.

 

적이 공격 하는 순간 게임이 멈춘다

헉!

 

이걸 어떻게 하지....

 

참고로 게임이 멈추면

이 꼬라지가 되니 빨리 종료해주자.

 

아마도 리소스 관련한 문제인 것 같은데 

반복문도 아니고 총알 1발 1회 실행하면 멈춘다. 왜 그럴까

 

뭐가 문제인지 몰라서 실행도 안되고 수정도 어딜 해야될 지 모르겠다.

 

하루종일 저거 수정한다고 붙잡고 있다가 아무것도 못했다...

 

아 그리고 또 배운거

Coroutine을 통한 반복이 가능하다

여태 InvokeRepeating을 쓰다가 함수에 매개변수가 필요한 경우 어떻게 해결해야 할까

 

예를 들어

랜덤 숫자 생성 함수가 있다.

 

Int randomGen(int min, int max)

{
	int output = Random.Range(min, max);
	return output;
}

코드 보니까 굳이 함수로 만들어줄 필요는 없는 것 같지만 대충 넘어가자

 

이런 경우 InvokeRepeating을 사용하면 매개변수를 집어 넣을 수 없다는 단점이 생긴다.

InvokeRepeating의 경우 매개변수로 함수명만 필요로 하지 매개변수 자리를 만들어주지 않기 때문이다.

 

이런 경우를 위해 Coroutine이라는 시스템이 존재한다.

 

코루틴은 변수형부터가 심상치 않다.

 

무려  IEnumerator라는 변수형을 사용하는데

뭔 소린지 모르겠다. 구글 번역기는 IE분자라고 번역해줬다.

또 검색해보니 열거자 라고 부른단다.

 

아무튼 유니티에서 앞으로 자주 사용하게 될 구문인데

 

왜냐하면 이 친구를 통해 코루틴 이라는 기능을 사용 할 수 있기 때문이다.

 

void Update와 별도의 공간에서 반복을 선언할 수 있으며 매개변수도 받아줄 수 있기 때문이다.

 

예를 들어보자.

 

IEnumerator coroutine(float i, GameObject bullet, Vector3 _playerPos, Vector3 _bossPos)
{
        yield return new WaitForSeconds(i); //Unity내부 시간 기준 i초 후에 재실행
        ShotToPlayer(bullet, _playerPos, _bossPos); //메소드를 불러온다.
}

이건 오늘 내가 쓴 망한 코드이다.

흑흑

 

하지만 코루틴이 작동하는 건 디버그로그를 통해 확인했으니 계속해서 알아보도록 하자.

보시는 바와 같이 ShotToPlayer라는 메소드를 반복실행하려고 한다.

ShotToPlayer메소드는 3개의 매개변수를 필요로한다.

 

이걸 InvokeRepeating으로 실행하려면 아마 불가능할 것이다.

void Start()
{
    StartCoroutine(coroutine(5, fire, playerPos, bossPos));
}

스타트 메소드에 StartCoroutine메소드를 통해 IEnumerator 메소드를 불러온 후

뒤에 매개 변수를 넣어주면 놀랍게도 작동한다.

 

그 외의 오늘 모든 시간은 버그 픽스하느라 써버리는 바람에 딱히 적을 내용이 더 없다... 흑흑

오늘 TIL은 여기까지...

관련글 더보기