ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TIL] 5주차 1일 개인 과제 진행 ( Animater Override Controller)
    개발일지/스파르타 코딩클럽 부트캠프 2024. 5. 13. 21:01

     

    오늘 공부한 내용


    • Animator Override Controller
    • PlayerPrefs
    • 유니티 생명주기에 대해서 조금씩 더 알아가는중
    • 클래스간의 허용

    오늘 발생한 문제


    메인화면에서 캐릭터를 선택했을 때 인게임에서 적용시키기

     

    메인 화면에서 캐릭터를 선택하고 그에 맞는 스프라이트의 캐릭터로 인게임에서 적용해야 하는데

    mainSprite.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("angel_idle_anim_f0 1");

    나는 말 그대로 스프라이트를 바꾸려고 했다. 근데 바뀌지않았다.

    곰곰히 생각해보니 스프라이트를 아무리 바꿔도 그 위에 애니메이터가 있다는걸 까먹고 있었다.

    그래서 리소스 폴더에 애니메이터 오버라이드 컨트롤러들을 만들고

     public void PlayerCharacterChoice()
     {
         playerCharacter = PlayerPrefs.GetInt("character");
         var resourceName = "Animator Override Controller/Player0" + playerCharacter.ToString();
         var animator = mainSprite.GetComponent<Animator>();
    
         switch (playerCharacter)
         {
             case 1:
                 //mainSprite.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("angel_idle_anim_f0 1");
                 // 여러 시도 결과 애니메이터를 바꿔주면 스프라이트를 굳이 바꿀 필요가없어서 비활성화
                 animator.runtimeAnimatorController = (RuntimeAnimatorController)Resources.Load(resourceName);
                 //Debug.Log(resourceName);
                 break;
             case 2:
                 animator.runtimeAnimatorController = (RuntimeAnimatorController)Resources.Load(resourceName);
                 break;
             case 3:
                 animator.runtimeAnimatorController = (RuntimeAnimatorController)Resources.Load(resourceName);
                 break;
         }
     }

    메인 스프라이트가 아닌 각 캐릭터마다 고유값을 Playerprefs로 값을 받아서 스위치문으로

    애니메이터를 바꿔줘서 캐릭터를 변경했다.

     

    인게임에서 이름 바꾸기

     

    인게임에서 이름을 변경하는 법도 꽤나 고역이었는데

    코드 자체는 간단했지만 과정이 오래걸렸다.

     public TMP_Text name;
     
     void Start()
    {
        // 메인화면에서 입력한 이름을 가져와서 게임에 넣기
        playerName = PlayerPrefs.GetString(userName);
        name.text = playerName; 
    }

    코드자체는 메인화면에서 이름 정할때 쓴 걸 그대로 썼다.

    왜냐면 데이터값이야 그 위에 얹으면 된다고 생각했기 때문에.. 

    근데 생각처럼 이름이 바뀌질 않았다. 여기서 문제를 해결할 수 있었던 단서는

    게임을 실행시키고 인게임에서 바꿀 이름을 입력하면 바뀌지않는데, 게임을 종료했다가 실행하면

    바꾸려고 했던 그 이름으로 바뀌어 있었다.

    그말인즉슨 데이터는 잘 덮어졌는데 이름이 바꿔지는 과정에서 순서가 잘못되었다고 느껴서

    원래는 Update에 있었는데

    public void Rename()
    {
        // 원래 PlayerName 클래스에 Update 메서드 안에서 진행했는데 그렇게 하니 적용이 안됐다.
        // 근데 게임을 종료했다가 다시 키면 전에 썼던 이름이 이제서야 바뀌는걸 보고 업데이트에 있으면 안된다고 판단.
        // 버튼을 누르는 시점에 변경되도록 GameManager로 옮김
        playerName = inputField_ReName.GetComponent<TMP_InputField>().text;
        PlayerPrefs.SetString(userName, playerName);
    
        bool click = true;
    
        while (click)
        {
            //플레이어 이름이 2~10글자가 아닐경우 경고메시지 출력
            if (playerName.Length > 10 || playerName.Length < 2)
            {
                errorMessage.SetActive(true);
                click = false;
                Invoke("DownError", 3);
            }
            else
            {
                playerName = PlayerPrefs.GetString(userName);
                name.text = playerName;
    
                renamePanal.SetActive(false);
                click = false;
                break;
            }
    
        }

    버튼을 누를때만 바뀌는걸로 그냥 버튼 메서드 안에 넣었더니 해결됐다.

     

    인게임에서 캐릭터 바꾸기

     

    이거야말로 진짜 오래 고민하고 해결하는건 순식간이었는데

    그냥 메인화면에 있던 캐릭터 변경 패널 그대로 가져와서 조금 손 본 뒤

     public void Update()
     {
         PlayerCharacterChoice();
     }
     public void PlayerCharacterChoice()
     {
         playerCharacter = PlayerPrefs.GetInt("character");
         var resourceName = "Animator Override Controller/Player0" + playerCharacter.ToString();
         var animator = mainSprite.GetComponent<Animator>();
    
         switch (playerCharacter)
         {
             case 1:
                 //mainSprite.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("angel_idle_anim_f0 1");
                 // 여러 시도 결과 애니메이터를 바꿔주면 스프라이트를 굳이 바꿀 필요가없어서 비활성화
                 animator.runtimeAnimatorController = (RuntimeAnimatorController)Resources.Load(resourceName);
                 //Debug.Log(resourceName);
                 break;
             case 2:
                 animator.runtimeAnimatorController = (RuntimeAnimatorController)Resources.Load(resourceName);
                 break;
             case 3:
                 animator.runtimeAnimatorController = (RuntimeAnimatorController)Resources.Load(resourceName);
                 break;
         }
     }

    생각해보니 업데이트에 넣어도 버튼이라서 누를 때만 실행되잖아? 생각해서 업데이트에 넣었더니 해결 됐다.

     

    이동 시 애니메이션을 따로 구현하기

     

    이 부분은 처음 내가 썼던 코드는 오브젝트의 움직임에 맞춰서 애니메이션이 변경하게끔 썼었다.

    private void PlayerMoveCheck()
    {
        bool PlayerSpeed = Mathf.Abs(movementRigidbody.velocity.magnitude) > Mathf.Epsilon;
        animator.SetBool("isRun", PlayerSpeed);
    }

    그래서 Player오브젝트에 움직임이 있으면 isRun이 true값이 되도록 했는데

    생각해보니 Rigidbody2D는 Player오브젝트에 있고 Animator는 MainSprite에 있어서...

    키 입력에 따라서 바뀌는 식으로 해야할 거 같은데 아직 완성 못했다.

     

     

Designed by Tistory.