이번에는 원하는 GameObject에 붙어있는 한개 이상의 Script에 구현되어있는 메소드를 호출하는 방법에 대해 이야기 해보겠습니다. 이 방법을 사용하면 해당 GameObject에 실행하고자 하는 메소드를 가진 스크립트가 컴포넌트로 존재하는지 아닌지를 크게 신경쓰지 않고도 호출하는 것이 가능합니다.
public void SendMessage(string methodName, object value = null, SendMessageOptions options = SendMessageOptions.RequireReceiver);
SendMessage 함수는 현재 스크립트가 실행중인 GameObject에 붙어있는 모든 MonoBehaviour 스크립트의 원하는 함수를 호출해 줍니다.
1
2
3
4
5
6
7
voidStart(){
gameObject.SendMessage("ApplyDamage",5.0f);
}
voidApplyDamage(floatdamage){
Debug.Log("Damage: "+damage);
}
위의 코드가 실행되면 ApplyDamage() 함수에 파라미터 5.0f 가 넘어가며 실행되게 됩니다.
하나의 GameObject에 두개의 스크립트를 붙여보았습니다. 그리고 ExampleClass1에서는 SendMessage를 사용하여 ExampleClass2에 있는 메소드를 호출해 보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
publicclassExampleClass1:MonoBehaviour{
voidStart(){
gameObject.SendMessage("ApplyDamage",5.0f);
}
}
publicclassExampleClass2:MonoBehaviour{
voidStart(){
}
voidApplyDamage(floatdamage){
Debug.Log("ExampleClass2 Damage: "+damage);
}
}
위의 실행결과는 정상적으로 다음과 같이 출력이 됩니다.
1
ExampleClass2 Damage:5
여기서 알 수 있는 것은 SendMessage는 GameObject에 추가되어있는 모든 Script 컴포넌트들에 전달이 되게 됩니다. 그중에 같은 이름을 가지고 있는 메소드가 있다면 그것이 실행되게 됩니다. 해당 이름의 메소드가 호출하는 스크립트 내부에 선언되어 있다면 그것이 최우선 순위로 실행이 되고 이후에는 컴포넌트에 등록되어있는 순서대로 메시지가 전달됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
publicclassExampleClass1:MonoBehaviour{
voidStart(){
gameObject.SendMessage("ApplyDamage",5.0f);
}
voidApplyDamage(floatdamage){
Debug.Log("ExampleClass1 Damage: "+damage);
}
}
publicclassExampleClass2:MonoBehaviour{
voidStart(){
}
voidApplyDamage(floatdamage){
Debug.Log("ExampleClass2 Damage: "+damage);
}
}
//=>
ExampleClass1 Damage:5
ExampleClass2 Damage:5
SendMessage를 호출할때는 파라미터를 가지고 있더라도 수신하는 메소드는 파라미터를 받지 않음으로써 넘어올 파라미터를 무시할 수 있습니다. 다음의 코드는 문제 없이 ApplyDamage() 메소드가 호출됩니다.
1
2
3
4
5
6
7
voidStart(){
gameObject.SendMessage("ApplyDamage",5.0f);
}
voidApplyDamage(){
Debug.Log("Damage: Parameter Ignored");
}
SendMessage는 .Net 리플렉션을 통하여 구현됩니다. 때문에 처음 찾게 되는 같은 이름을 가진 메소드를 실행하게 되며 만약 메소드 오버로딩이 되어있는 상태라면 정상적으로 동작하지 않게 됩니다.
1
2
3
4
5
6
7
8
9
10
11
voidStart(){
gameObject.SendMessage("ApplyDamage",5.0f);
}
voidApplyDamage(){
Debug.Log("Damage: Ignored");
}
voidApplyDamage(floatdamage){
Debug.Log("Damage: "+damage);
}
위의 코드는 Damage: Ignored 를 출력하게 됩니다. 추가로 SetActive(false)와 같은 방법으로 비활성화 되어있는 GameObject는 메시지를 수신하지 않습니다.
public void SendMessageUpwards(string methodName, object value = null, SendMessageOptions options = SendMessageOptions.RequireReceiver);
이번에는 SendMessageUpwards 메소드에 대해 알아보겠습니다. 기본적으로 SendMessage 와 동일하게 동작하지만 자신(GameObject)를 포함하여 부모 GameObject까지 메시지를 전달합니다.
위의 스크린샷과 같이 두개의 GameObject를 부모 자식 형태로 배치를 해보았습니다. 스크립트는 다음과 같이 부여하였습니다.