본문 바로가기

[내배캠] 본 캠프 개발 학습/Basic class

10월 24일 목요일 Basic class Q&A

📌

 2주차 개인 과제가 끝난 기념으로 실습 진행을 하면서 알게 된 부분을 간단하게 정리해보려고 한다. 대부분 튜터님께 찾아가서 드린 질문일 듯!


✅  GetComponent를 사용했는데 해당 스크립트의 필드 변수를 받아올 수 없어요! 

 다시 보니 저 질문 자체가 정말 바보 같다는 생각이 든다. 일단 GetComponent를 그저 어떤 스크립트의 생성(초기화)이라고 생각했기 때문에 범한 실수였다. 
GetComponent는 말 그대로 Component를 가져오는 함수로, 해당 스크립트가 붙어있는 오브젝트의 Component만 찾아서 가져올 수 있다. 예시로 살펴보자. 

[1] GetComponent를 사용하지 않은 경우 

using UnityEngine;
using UnityEngine.UI;

public class ScoreButton : MonoBehaviour
{
    public Button scoreButton;
    public int score = 0;

    void Awake()
    {
        
    }

 

 만약 이 스크립트를 "Button" 오브젝트에 붙여줬다면 인스펙터에 scoreButton 변수가 생길 것이고, 수동으로 연결해줄 수 있다. 

[2]  GetComponent를 사용한 경우 

using UnityEngine;
using UnityEngine.UI;

public class ScoreButton : MonoBehaviour
{
    public Button scoreButton;
    public int score = 0;

    void Awake()
    {
        scoreButton = GetComponent<Button>();
    }


 위와 똑같이 인스펙터에 scoreButton 변수가 생기겠지만 Awake에서 Button 컴포넌트를 찾아서 scoreButton에 할당해줬기 때문에 수동으로 연결해서는 안 된다. 만약 수동으로 연결한다면 실행 직후 Awake가
작동하면서 이미 할당된 Button 컴포넌트를 찾지 못 하기 때문에  none이 뜨는 오류가 발생한다. 

코드에 문제가 없는데 null 값이 떠요!

using UnityEngine;
using UnityEngine.UI;

public class ScoreButton : MonoBehaviour
{
    public Button scoreButton;
    public int score = 0;

    void Awake()
    {
        scoreButton = GetComponent<Button>();
       scoreButton.onClick.AddListener(PointUp); 
  	}
    
	void PointUp()
	{
       score++;
    }

public class ScoreText : MonoBehaviour
{
    public ScoreButton scoreButton;
    public TextMeshProUGUI scoreText;

    void Awake()
    {
		scoreText = GetComponent<TextMeshProUGUI>();
        scoreButton.onClick.AddListener(RefreshUI);
    }

    void RefreshUI()
    {
        score++;
        scoreText.text = $"Score: {score}";
    }

 

 과제 요구사항에 따라 Button 컴포넌트는 수동으로 연결해뒀고, 실행했을 때에도 모든 컴포넌트가 할당되어 있는 상태인데
scoreTxt가 작동되지 않으며  scoreButton을 찾을 수 없다는 null 값이 떴다.

 

 이유는 ScoreButton 스크립트에서 컴포넌트를 할당하는 코드와 ScoreText 스크립트에서 scoreButton의 click 이벤트를 받아오는 코드 중 무엇이 먼저 실행될지 모르기 때문이었다. 코드를 보면 둘 다 Awake에서 실행되고 있는데, 만약  scoreButton의 click 이벤트를 받아오는 코드가 먼저 실행되고, ScoreButton 스크립트에서 컴포넌트를 할당하게 되면 당연히 scoreButton 을 찾을 수 없게 된다. 

private void Start()
    {
      scoreButton.onClick.AddListener(RefreshUI);
    }

 

start 로 바꾸니까 바로 해결되었다! 

 

✅ 이 외에도 

1) event 함수는 public으로 선언해야 다른 스크립트에서 구독할 수 있다. 그렇다면 event 함수는 외부 접근으로부터 보호되지 못 하는 걸까? 아니다! public 'event' Action 처럼 event를 넣는다면 private처럼 사용 가능하다.  
2) Action 은 변수에 함수를 할당해 사용할 수 있지만, 필드에서 선언할 때 바로 함수를 정의하지 않고 Action이 사용될 때 함수를 할당해도 된다.  


📝 

 

 꾸준 실습 과제 제출 완료! 신난다~!