C# 스크립팅 API 소개

Strix Unity SDK에는 C# 스크립팅 API가 있습니다. 이 페이지에는 많이 사용되는 아이디어와 정보가 들어 있습니다.

StrixBehaviour 클래스

Unity에서 스크립트 요소를 만들 때는 클래스가 MonoBehaviour에서 도출됩니다. Strix Unity SDK에서 Strix 함수를 이용하는 스크립트 요소를 만들 때는 클래스가 StrixBehaviour 클래스에서 도출됩니다.

StrixBehaviour는 도출된 MonoBehaviour 클래스 이므로, StrixBehaviour에서 도출하면 MonoBehaviour에서 제공하는 기능(예컨대 GameObject에 연결할 수 있는 자격) 외에 StrixBehaviour의 자체 기능도 이용할 수 있습니다.

StrixBehaviour에서 파생되는 자체 스크립트를 GameObject에 연결할 때는 StrixReplicator 요소도 연결해야 합니다. StrixBehaviour에는 strixReplicator 속성이 있어 GameObject에 연결된 StrixReplicator를 참조할 때 이용할 수 있습니다. 이것은 Transform 요소에 액세스할 때 transform 속성을 이용하는 것과 같습니다. StrixBehaviour에는 isLocalisSync라는 바로가기 속성이 두 개 더 있으며, 이것은 같은 이름의 StrixReplicator속성을 참조합니다.

StrixNetwork 싱글톤 클래스

StrixNetwork 싱글톤 클래스는 Strix의 스크립팅 API로 들어가는 주요 지점입니다. 평소처럼 instance 속성을 이용하여 싱글톤 인스턴스를 확보한 후 클래스의 다른 멤버에 액세스할 수 있습니다.

이것은 네임스페이스 SoftGear.Strix.Unity.Runtime 안에 있습니다.

예시

using SoftGear.Strix.Unity.Runtime;

        // Start()와 같은 메서드에서

        StrixNetwork.instance.applicationId = "00000000-0000-0000-0000-000000000000";
        StrixNetwork.instance.ConnectMasterServer(
            "000000000000000000000000.game.strixcloud.net",
            OnConnectMasterCallback,
            OnConnectMasterFailedCallback
        );

비동기 프로세싱

Strix의 스크립팅 API에 있는 메서드 중에는 비동기로 실행되는 것도 많습니다. 네트워크 동작에 시간이 많이 걸릴 뿐더러, Unity의 메인 쓰레드를 차단하면 안 되기 때문입니다.

Strix Unity SDK는 콜백 핸들러를 이용하여 이 같은 비동기 동작을 처리합니다.

sequenceDiagram participant A as 스크립트 participant B as SDK 라이브러리 participant C as 서버 A ->> + B : 메서드 호출 B ->> + C : 서버에 요청 B -->> - A : 메서드가 반환 C ->> C : 서버 측 처리 C -->> + B : 서버로부터의 응답 deactivate C B -->> - A : 콜백

참고

Strix Unity SDK에서는 이 콜백을 이벤트라고 부르기도 하지만, 보통 델리게이트일 뿐입니다. C# 문법 용어의 이벤트나 Unity의 UnityEvent와 혼동하면 안 됩니다.

한편 Strix 클래스 중에는 C# 문법 용어에서 말하는 이벤트 멤버가 있는 것도 있습니다.

일반적인 Strix 메서드에는 매개변수 목록에 델리게이트가 두 개 있습니다. 이 두 델리게이트는 보통 성공 호출 핸들러실패 호출 핸드러라고 부릅니다. 이 메서드를 호출하면 네트워크 동작 완료 전에 메서드가 리턴합니다. 나중에 동작이 완료되면 델리게이트 중 하나가 호출됩니다. 동작이 성공했다면 성공 콜백이 호출되고 성공하지 못했다면 실패 콜백이 호출됩니다.

이 콜백 핸들러의 델리게이트 타입은 여러 가지지만, 일반적으로 이름이 EventArgs로 끝나고 아무것도(void) 리턴하지 않는 타입의 한 매개변수만 수신합니다. 콜백 핸들러가 매개변수를 통해 받는 개체에는 (항상 그런 것은 아니지만) 보통 네트워크 동작의 결과를 알려주는 정보(단순한 성공 또는 실패 여부 이상의 정보)가 들어 있습니다.

예를 들어, ConnectMasterServer 메서드의 실패 콜백 핸들러 타입은 StrixNetworkConnectFailedEventHandler이며 다음과 같이 정의됩니다.

public delegate void StrixNetworkConnectFailedEventHandler(
    StrixNetworkConnectFailedEventArgs args
);

여기서 StrixNetworkConnectFailedEventArgs는 cause (Exception 타입)와 session (AbstractSession 타입) 두 속성이 있는 클래스입니다.

다운캐스팅

Strix 서버의 장점 중 하나는 커스터마이징 유연성입니다. (단, Strix Cloud에서 실행되는 Strix 서버는 커스터마이징을 할 수 없습니다. 커스터마이징된 Strix 서버를 실행하기 위해서는 STRIX ENGINE 제품을 사용해야 합니다.) 커스터마이징된 서버를 이용하기 위해서는 클라이언트 측도 비슷한 수준으로 유연해야 합니다.

API 스크립팅은 많은 부분이 일반적인 방법으로 정의되며, 일부는 그 목적으로 제네릭을 이용하기도 합니다. 이때 사용되는 타입을 인터페이스 또는 추상 클래스로 정의하기도 합니다. 단, 선언된 타입보다 더 많은 멤버에 액세스하고 싶다면 개체를 구상 클래스로 다운캐스트해도 됩니다. 때로는 같은 방법으로 구상 클래스로 선언된 개체를 다운캐스트해도 됩니다.

예를 들어, 실패 콜백으로 전달된 매개변수에는 Exception 타입으로 정의된 cause라는 이름의 속성이 있을 때가 자주 있습니다. 이것의 정의된 타입은 System.Exception이지만 ErrorCodeException (네임스페이스 SoftGear.Strix.Unity.Runtime.Error에 정의된 Strix의 예외 타입)으로 다운캐스트해도 됩니다. 여기에는 오류의 원인을 나타내는 errorCode 속성이 있습니다.

예시

void OnConnectMasterFailedCallback(StrixNetworkConnectFailedEventArgs args)
{
    if (args.cause is ErrorCodeException
        && ((ErrorCodeException)args.cause).errorCode == StandardErrorCode.ConnectionError)
    {
        // 이 오류는 특별히 취급.
    }
    else
    {
        // 일반적인 오류 처리.
    }
}

오류 코드에 관해 자세한 사항은 오류 코드를 참조해 주십시오.

인터페이스

Strix Unity SDK는 자체 인터페이스를 많이 이용하며, 그중에는 이름이 "I"로 시작하지 않는 것도 있습니다. 여러 개체의 식별자로 사용되는 SoftGear.Strix.Client.Core.UID가 그 예입니다. (이것은 RoomInfo.nodeUid 속성의 타입이거나 IRoomMember.GetUid() 메서드의 리턴 타입입니다.) 이름이 “I”로 시작하지 않는 인터페이스를 구별할 때 주의해야 합니다.

그렇다면 인터페이스가 중요한 이유는 무엇일까요? 흔한 함정이 있기 때문입니다.

클래스 중에는 그 인스턴스가 비슷한 값을 표시할 경우 프로그래머가 직관적으로 개체를 비교할 수 있도록 ==!= 연산자를 덮어쓰는 것이 많습니다. 그러나 인터페이스는 (첫 글자와 상관 없이) C# 언어 제한 때문에 동일성 (또는 부동일성) 연산자를 덮어쓰지 못합니다.

그러므로 두 UID 개체를 비교할 때는 예컨대 == 연산자를 사용하지 못합니다. 두 개체 참조의 동등성을 비교하는 것이기 때문입니다. 두 UID 개체가 동일한 ID를 표시한다면 거짓이 리턴됩니다. 대신에 아래 예에서 두 번째 if 문과 같이 Equals 메서드를 사용해야 합니다.

private UID uid;

// StrixNetwork::GetRoomMembers 처리기.
void OnRoomMembersGot(RoomMemberGetEventArgs args)
{
    foreach (var member in args.roomMemberCollection)
    {
        UID memberUid = member.GetUid();

        // 이 비교는 예상대로 되지 않음,
        // 이유는 참조의 동일성을 비교하기 때문.
        if (memberUid == uid)
        {
            // 뭐라도 할 것.
        }

        // 대신 이렇게 할 것.
        if (memberUid.Equals(uid))
        {
            // 뭐라도 할 것.
        }
    }
}