본문 바로가기
가상세계 산사VR

산사VR, 오브젝트간 통신

산사에서는 오브젝트들끼리도 이야기를 할 수 있습니다.
이른바 오브젝트들끼리의 통신인데요.

우리 사람들 몰래 오브젝트들끼리 이야기한다고 하니,
무슨 이야기를 할지 궁금해지는군요? :)

오브젝트간 통신에는 보내는 오브젝트, 송신에는 다음 명령이 사용됩니다.

ScenePrivate.Chat.MessageScript(message, ScriptId.AllScripts, 1);

여기서 message 는 실제 통신할 내용을,
그리고  ScriptUd.AllScripts 는 모든 스크립트가 들어있는 오브젝트에 해당하고,
마지막 1은 채널 번호를 의미합니다.
채널은 마치 주파수와 같아서 각각 용도마다 그 값을 다르게 주어서 통신이 혼선되지 않게 하는 것이지요.

그리고 오브젝트의 받는 오브젝트, 수신에는 다음 명령이 사용됩니다. 이 명령어로 메시지를 수신하는데요.

ScenePrivate.Chat.Subscribe(1, null, ChatMessage_1);

앞의 1은 채널번호입니다. 지난번 사용자가 채팅을 할 때는 0번을 사용하나, 오브젝트간 통신에는 1이상의 다른 채널 번호를 사용합니다. 그래야 채팅창에 보이지 않거든요.

다음으로 나오는 null 은 특정 스크립트에서만 메시지를 받는 것으로 추정되나 그냥 null 을 주면 모든 오브젝트로부터 메시지를 받습니다.
그 다음의 ChatMessage_1 은 콜백 함수라고 해서 메시지를 받으면 실행할 함수의 이름을 파라미터로 주어줍니다.

이 2개의 함수로 메시지를 주고 받고 하는데요.

우선 아래 2개의 소스를 준비하였습니다.

1번소스.  chat2_sender.cs - 메시지를 보내는 쪽

using Sansar.Script;
using Sansar.Simulation;
using System.Runtime.Serialization;


public class Chat2SenderScript : SceneObjectScript
{
    [DisplayName("메시지")]
    [DefaultValue("학교종이 땡땡땡")]
    public string message;

    public override void Init()
    {
        ObjectPrivate.AddInteractionData addData =
            (ObjectPrivate.AddInteractionData)WaitFor(
                ObjectPrivate.AddInteraction, "", true);
        
        // 터치 이벤트
        addData.Interaction.Subscribe((InteractionData data) =>
        {
            ScenePrivate.Chat.MessageScript(message, ScriptId.AllScripts, 1);
        });

    }
}

2번소스. chat2.cs - 메시지를 받는 쪽

using Sansar.Script;
using Sansar.Simulation;
using System.Runtime.Serialization;


public class Chat2Script : SceneObjectScript
{
    public override void Init()
    {
        // 채팅 채널 0번으로부터 메시지 송신을 대기하고 메시지가 송신되면 
        // ChatMessage 콜백함수를 실행합니다.
        ScenePrivate.Chat.Subscribe(1, null, ChatMessage_1);
    }

    // ChatMessage 콜백 함수
    private void ChatMessage_1(int Channel, string Source, SessionId SourceId, ScriptId SourceScriptId, string Message)
    {
        ScenePrivate.Chat.MessageAllUsers("채널" + Channel.ToString() + " => " + Message);
    }
}

 

이 2개의 소스를 산사에 업로드하고, 오브젝트 5개를 배치하여 각각 아래와 같이 스크립트를 넣어줍니다.
윗 줄의 4개의 오브젝트는 chat2_sender 스크립트를 넣고,
아랫줄 1개의 오브젝트를  chat2 스크립트를 넣는 것이지요.

그리고 윗줄 첫번째 오브젝트의 속성(Property) 을 한번 살펴볼까요?
CHAT2_SENDER 패널의 메시지 속성이 "학교종이 땡땡땡"이라고 적혀 있을텐데요.
이 메시지가 통신을 보낼 메시지 전문에 해당합니다.

사실 첫번쨰 오브젝트를 그대로 두고 2, 3, 4번째 오브젝트를 각각 선택해서 메시지 속성을 각각 다음과 같이 바꿔 주세요.

"어서 모이자"
"선생님이 우리를"
"기다리신다"

 

자 이제 월드를 빌드해 봅시다. 5개의 오브젝트가 보이실 겁니다.
참, 채팅창을 열어놔주세요. 채팅창으로 메시를 출력할 예정이거든요.

윗 줄의 첫번째 오브젝트를 클릭합니다.
그러자 채팅창에 "채널1=>학교종이 땡땡땡" 문구가 표시됩니다.,

두번째, 세번째, 네번째 오브젝트를 클릭하면 연이어 입력했었던 문구가 노출됩니다.,

사실 이 스크립트에서 채팅창에 출력해주는 오브젝트는 1개밖에 없습니다.

하지만 위에 4개의오브젝트가 1개의 오브젝트에 메시지를 전송했기 때문에 이를 받아서 출력하는 것이지요.
메시지를 받아서 출력하는 소스가 바로 이 부분에 해당하는 것이지요.
참고로 ScenePrivate.Chat.MessageAllUsers 함수는 월드 내 모든 사용자에게 텍스트 채팅을 보내는 것입니다

// ChatMessage 콜백 함수
private void ChatMessage_1(int Channel, string Source, SessionId SourceId, ScriptId SourceScriptId, string Message)
{
    ScenePrivate.Chat.MessageAllUsers("채널" + Channel.ToString() + " => " + Message);
}

이를 이용하면, 별도의 버튼 오브젝트를 터치하면 문을 열거나 빛을 밝히는 등의 액션이 가능하겠지요.

이런 통신 방식이 생소하신분도 계시겠지만
세컨드라이프 스크립트를 해보셨던 분이라면
그 개념을 그대로 이어받은 부분이라 좀 수월하게 느껴지셨을 겁니다.

단 세컨드라이프처럼 특정 채널에 강제로 메시지를 보내기 위해 채팅창에 "/1 안녕" 과 같이 타이핑해도 채널 1로 메시지를 보내진 않습니다. 보안 문제상 막은게 아닐까 생각됩니다.

산사에서의 스크립트 시스템이 비록 언어는 다르지만 일부 세컨드라이프를 전수받은 부분이 있습니다.
즐거운 스크립트 스터디(?) 되시길 바라며 이만 글을 맺습니다.

오늘도 여기까지 읽어주셔서 감사합니다 :)


하나님의 말씀을 마음에 담아두면 환난날에 도움이 됩니다.
예수님께서 강림하실 날을 소망합니다. :)

주께서 호령과 천사장의 소리와 하나님의 나팔로
친히 하늘로 좇아 강림하시리니
그리스도안에서 죽은 자들이 먼저 일어나고
그 후에 우리 살아 남은 자도 저희와 함께 구름 속으로 끌어 올려
공중에서 주를 영접하게 하시리니
그리하여 우리가 항상 주와 함께 있으리라.
- 데살로니가 전서 4장 16, 17절 말씀 -