유니티 프로그램

[유니티] UNITY 게임오브젝트 여러개를 동시에 안보이게 하려면 어떻게 해야 할까요?

비도르 2022. 8. 23. 12:15

[유니티] UNITY 게임오브젝트 여러개를 동시에 안보이게 하려면 어떻게 해야 할까요?

 

안녕하세요. 오늘도 평화로운 구름들이 모여들어 여름의 끝자락을 즐기고 있는 8월의 어느 날입니다.

 

게임을 진행할 때 여러 개의 배경음악이나 게임오브젝트를 동시에 동작하지 못하게 하거나, 위치를 옮기면서 색깔도 바꾸며, 길이도 동시에 제어할 필요가 있습니다. 하지만 그때마다 하나씩 비활성화 시키거나 속성을 하나씩 바꾸는 것보다 하나로 묶어서 진행할 필요가 있습니다. 이때 묶어서 쓸 수 있는 함수를 만드는 것도 하나의 방법이지만, 보다 간결하게 쓸 수 있습니다.

 

이때 사용하면 편리한 것이 Delegate(델리게이트) 선언 입니다.

 

Deleagte라는 말 그대로 대리자로써의 역할을 한다고 보면 됩니다. 함수나 메서드를 넣어서 사용할 수 있는 변수로 봐도 될 듯 하다고 생각합니다. 물론 그렇게 하기 위해서는 return 하는 값의 타입이나 전달하는 매개변수의 타입이 일치해야 하는 제약은 있지만, 잘 쓰면 유용한 것 같습니다.


How??? 어떻게 사용하는지 알아보겠습니다.

 

1. Delegate 를 선언하는 방법의 예는 아래와 같습니다.

 

// 리턴값이 없고 전달 매개변수가 없을 때

delegate void tstDgate(); 

 

// 리턴값이 없고 string 타입으로 매개변수를 전달할 때

delegate void tstDgate(string tstSend); 

 

// float타입으로 리턴값을 받고, float 타입으로 매개변수 2개를 전달할 때

delegate float tstDgate(float x, float y); 

 

; 이 처럼 넣고자 하는 함수나 메서드의 형태에 따라서 적절히 변형해서 사용하면됩니다. 아래에서 예를 들어서 사용해 보겠습니다.

 

2. 함수나 메서드를 넣는 방법의 예는 아래와 같습니다.


/////////////////// 리턴값이 없고 전달 매개변수가 없을 때

 

delegate void tstDgate(); 

tstDgate tstD;

 

void Start()

{

       tstD = Hamsu;

       tstD();

}

void Hamsu()

{

      Debug.Log("대리자 테스트");


///////////////////// 리턴값이 없고 string 타입으로 매개변수를 전달할 때

 

delegate void tstDgate(string tstSend);

tstDgate tstD;


    void Start()
    {
        tstD = Hamsu;
        tstD("대리자 테스트");
    }

    void Hamsu(string tstString)
    {
        Debug.Log(tstString);
    }


///////////////////// float타입으로 리턴값을 받고, float 타입으로 매개변수 2개를 전달할 때

 

delegate float tstDgate(float x, float y); 

tstDgate tstD = Hamsu;

 

void Start()

{

       Debug.Log(tstD(2.2f,3.3f));

}

 

float Hamsu(float x,float y)

{

      return(x+y);

 

 


 

[예제]  게임오브젝트를 동시에 3개 비활성화 하기

-. 먼저 아래와 같이 큐브와 원기둥, 구 이렇게 3개의 오브젝트를 배치하겠습니다. 그리고 , ' Delete Btn ' 이라는 이름으로 버튼도 생성하겠습니다.

delegate 설명 메인화면

 

 

' Delete Btn ' 버튼을 누르면 3개의 오브젝트가 사라졌다가 다시 누르면 나타나는 스크립터를 만들어 보겠습니다.

먼저, 다른 함수들을 동시에 처리할 수 있게 모을 함수를 생성해서 처리하도록 스크립터를 아래와 같이 생성하겠습니다. 

 

 

using UnityEngine;
using UnityEngine.UI;

public class TstDgate : MonoBehaviour
{
    public GameObject tstObj1; // 구 게임오브젝트 넣을 변수
    public GameObject tstObj2; // 큐브 게임오브젝트 넣을 변수
    public GameObject tstObj3; // 원기둥 게임오브젝트 넣을 변수
    public Text tstBtn; // 버튼의 텍스트를 넣을 변수

    bool tstBool = true; // 버튼의 동작 반전용 bool 변수
    
    public void ObjDelNliv() // 한번에 처리하기 위한 함수
    {

        if (tstBool) //버튼의 동작 반전용 bool 변수가 참 일 경우
        {
            tstGu(false); // 구 게임오브젝트를 비활성화
            tstCube(false); // 큐브 게임오브젝트를 비활성화
            tstCylinder(false); // 원기둥 게임오브젝트를 비활성화
            tstBool = false; // 버튼의 동작 반전용 bool 변수를 거짓으로 변경
            tstBtn.text = "Active Btn"; // 버튼의 텍스트를 변경
        }
        else
        {
            tstGu(true); // 구 게임오브젝트를 비활성화
            tstCube(true); // 큐브 게임오브젝트를 비활성화
            tstCylinder(true); // 원기둥 게임오브젝트를 비활성화
            tstBool = true; // 버튼의 동작 반전용 bool 변수를 참으로 변경
            tstBtn.text = "Delete Btn"; // 버튼의 텍스트를 변경
        }
    }

    void tstGu(bool boolObj)
    {
        tstObj1.SetActive(boolObj);
    }

    void tstCube(bool boolObj)
    {
        tstObj2.SetActive(boolObj);
    }

    void tstCylinder(bool boolObj)
    {
        tstObj3.SetActive(boolObj);
    }
    
}

 

 

 

'GameMgr' 이라는 이름으로 빈오브젝트를 만들어서 스크립터를 넣겠습니다. 그리고 버튼에 Onclick 이벤트를 추가해서 클릭시에 ObjDelNliv() 함수를 실행하겠습니다.

Onclick 이벤트 추가

 

이제 실행하고 버턴을 클릭할 때마다 3개의 오브젝트가 사라졌다가 나타나는 것을 확인 할 수 있습니다.

.

delegate 예시

 


-. 이제 위의 스크립트를 delegate 를 사용해서 아래와 같이 변경해 보았습니다. 이때 멀티캐스트(Multicast) 형태로 해서 여러개의 함수를 넣는 방식을 이용했습니다. 

 

※ 참고

멀티캐스트(Multicast) 형태로 할 때는 return 값이 Void형이어야 하는건 아시죠? 즉, return 값이 없어야 합니다. 이유는 return 값이 여러개가 되면 처리할 방법이 없으니깐 오류가 발생하기 때문입니다.

 

 

using UnityEngine;
using UnityEngine.UI;

public class TstDgate : MonoBehaviour
{
    public delegate void tstDelegate(bool btn); //delegate를 선언
    tstDelegate tstD; //delegate 변수를 생성합니다.

    public GameObject tstObj1; // 구 게임오브젝트 넣을 변수
    public GameObject tstObj2; // 큐브 게임오브젝트 넣을 변수
    public GameObject tstObj3; // 원기둥 게임오브젝트 넣을 변수
    public Text tstBtn; // 버튼의 텍스트를 넣을 변수

    bool tstBool = true; // 버튼의 동작 반전용 bool 변수


    private void Start() 
    {
        tstD = tstGu; //delegate 변수에 tstGu함수 넣기
        tstD += tstCube; // delegate 변수에 tstCube함수 추가
        tstD += tstCylinder; // delegate 변수에 TstCylinder함수 추가
    }

    public void ObjDelNliv()
    {        

        if (tstBool) //버튼의 동작 반전용 bool 변수가 참 일 경우
        {
            tstD(false);
            tstBool = false; // 버튼의 동작 반전용 bool 변수를 거짓으로 변경
            tstBtn.text = "Active Btn"; // 버튼의 텍스트를 변경
        }
        else
        {
            tstD(true);
            tstBool = true; // 버튼의 동작 반전용 bool 변수를 참으로 변경
            tstBtn.text = "Delete Btn"; // 버튼의 텍스트를 변경
        }
    }

    void tstGu(bool boolObj)
    {
        tstObj1.SetActive(boolObj);
    }

    void tstCube(bool boolObj)
    {
        tstObj2.SetActive(boolObj);
    }

    void tstCylinder(bool boolObj)
    {
        tstObj3.SetActive(boolObj);
    }
}

 

 

 

이렇게 해서 실행했을 때 동일한 결과를 확인 할 수 있습니다.

 

 

 참고

아래와 같이 객체를 선언하는 방식으로 변수에 넣어도 되지만 유니티 콤파일러가 알아서 잘 처리하니깐 굳이 이렇게 하지 않아도 됩니다. ^^

 

private void Start() 
    {
        tstD = new tstDelegate(tstGu); //delegate 변수에 tstGu함수 넣기
        tstD += new tstDelegate(tstCube); // delegate 변수에 tstCube함수 추가
        tstD += new tstDelegate(tstCylinder); // delegate 변수에 TstCylinder함수 추가
    }

 


Delegate는 다양하게 이용이 가능합니다. 함수를 통째로 넘겨주는 콜백(CallBack)의 방법이나 Event용으로 사용이 가능하죠~

 

그럼 오늘도 즐유!(즐거운 유니티) ^^