안 쓰던 블로그

Button Prefab에 Onclick() 추가하기!!!! 본문

유니티/개발

Button Prefab에 Onclick() 추가하기!!!!

proqk 2021. 8. 3. 16:28
반응형

드디어!!!! 해내서!!!! 동작해서!!! 글로 기록합니다

 

원하는 것:

Prefab로 만든 Button을 Instantiate로 생성한 뒤, 생성한 오브젝트에 OnClick 이벤트를 할당하고 싶다

Button Prefab는 현재 이런 상태

Box Manager 스크립트에 Gm5에는 OnClickbox5() 라는 함수가 있다

각 Box Manager에 Me에는 이후에 Clone 오브젝트로 생성된 Prefab들의 번호가 들어갈 것이다

 

이 Prefab을 게임 실행 중 생성하고, On Click()에는 OnClickbox5() 함수를 넣어서, 클릭했을 때 이 함수가 실행되었으면 한다

 

실패:

            Button newText = Instantiate(probText, Vector3.zero, Quaternion.identity, null).GetComponent<Button>();
            newText.transform.SetParent(answerAllBox_text.transform); //부모 세팅
            newText.transform.GetComponent<Button>().onClick.AddListener(delegate { Boxmanager.OnClickbox5(); }); //text에 버튼 이벤트 부여

            newText.GetComponent<BoxManager>().me = i; //각 Text의 번호 1부터 시작함

Prefab을 생성하는 부분은 GameManager라는 다른 스크립트에서 한다

GameManager에서 위에서 처럼 Instantiate로 Button Prefab을 생성한 뒤, 부모를 연결해 주고 onClick.AddListener로 함수를 할당했다

 

참고)

https://stackoverflow.com/questions/39616824/is-there-a-way-to-set-a-button-onclick-function-to-a-function-on-a-prefab-that-i

 

Is there a way to set a button onClick function to a function on a prefab that is not in a Scene in Unity?

I have a prefab that instantiate on running the program. The prefab is not already in the scene. On this prefab there is a script with a function that should be called when a button is clicked.The ...

stackoverflow.com

 

그런데 이러면 에러없이 잘 실행되기는 한데, OnClick() 이벤트가 Null인 상태로 (Prefab 상태 그대로) 나온다

다시 말해 함수가 할당되지 않은 것이다

혹시 이 글(https://foxtrotin.tistory.com/509)에서랑 비슷하게 Prefab이 생성되기도 전에 OnClick을 붙이려고 해서 그런가?

 

GridLayoutGroup에 소속된 오브젝트의 position 가져오기

LayoutGroup을 적용한 부모 오브젝트 아래로, Text Prefab를 Instantiate로 생성해서 자식 오브젝트로 넣는 방식으로 정렬시켰다 이 상황에서 자식으로 생성된 Clone들의 Position을 가져오고 싶은 상태 (위

foxtrotin.tistory.com

 

이제까지는 Start()문에서 진행했는데 아래처럼 Update() 안에다가 클론으로 생성된 Prefab의 이름을 찾고, 있다면 AddListener를 붙이고 없다면 없다고 출력하는 코드를 넣었다

(Update에서 Find를 하는 것은 효율성 측면에서 빵점이다 지금은 테스트니까 이렇게 진행한다)

    void Update()
    {
        GameObject obj = GameObject.Find("Stage5_Text(Clone)");
        if (obj != null)
        {
            Debug.Log("있음");
            obj.transform.GetComponent<Button>().onClick.AddListener(Boxmanager.OnClickbox5); //text에 버튼 이벤트 부여
        }
        else Debug.Log("없음");
    }

 

결과는 너무 잘 있었다

사실 Instantiate아래 생성된 Button 크기를 변경하는 코드가 있었다

            RectTransform rectTran3 = newText.GetComponent<RectTransform>(); //사이즈 조절
            rectTran3.sizeDelta = new Vector2(150, 150);
            rectTran3.localScale = new Vector3(1.0f, 1.0f, 1.0f);

이 코드는 잘 동작하는 것으로 보면, 실제로 오브젝트는 잘 생성됐다

또한 코드의 실행 순서 관련한 문제도 아니다. 실행 순서가 문제였다면 저 사이즈 조절하는 코드도 실행되지 않을 거니까

 

참고)

만약 진짜 실행 순서 문제라면, 실행 순서를 임의로 정할 수 있다

Project Settings에서 +를 눌러서 원하는 코드를 먼저 실행하게 할 수 있다

 

그럼 Prefab만의 문제일까? 미리 생성해 둔 Object라면 onClick.AddListener로 함수가 잘 들어갈까?

테스트를 위한 Button 오브젝트를 생성했다. 이 오브젝트는 Hierarchy에 있다

OnClick()은 비워두고, GameManager에서 Button을 찾아서 onClick.AddListener를 해 보았다

 

결과는.. 실패

아예 OnClick()이 들어가지 않았다

Prefab만의 문제는 아니었다

 

성공:

하지만 불가능은 없다!!!!

Prefab 버튼은 유니티 개발자 한두명이 쓰는 기능이 아닐텐데 방법이 무조건 있을 거라고 생각했다

삽질한 시간에 비해 해결방법은 엄청 간단했다

 

1. Prefab에 스크립트를 붙인다

2. 붙인 스크립트 자체를 On Click() 이벤트에 끌어넣는다

3. 스크립트에서 함수를 선택한다

 

Prefab은 먼저 생성되므로 나중에 실행되는 오브젝트들은 붙일 수 없다

하지만 Prefab에 붙어있는 스크립트는 같이 생성되므로 자기 자신의 스크립트를 이벤트로 사용할 수 있다!!

대박!!

 

대박!!

실행 중 생성된 Clone 오브젝트에 OnClick()이벤트가 잘 들어가있다

클릭하면 OnClickBox5()라는 함수가 잘 실행된다

 

참고)

https://answers.unity.com/questions/794720/on-click-paramaters-disappear-from-button-prefab.html

 

On Click paramaters disappear from button prefab? - Unity Answers

 

answers.unity.com

 

반응형
Comments