About C# Scripting API

Strix Unity SDK provides a set of C# scripting API. This page includes some common ideas and tips to use it.

StrixBehaviour class

In Unity, when you create a script component, you make your class derive from MonoBehaviour class. In Strix Unity SDK, when you create a script component that uses Strix functions, you make your class derive from StrixBehaviour class instead.

StrixBehaviour is a derived class of MonoBehaviour, so, by deriving from StrixBehaviour, you can enjoy all features that MonoBehaviour provides (such as being eligible to be attached to a GameObject) plus StrixBehaviour’s own features.

When you attach your own script that derives from StrixBehaviour to a GameObject, you need to attach StrixReplicator component to it, too. StrixBehaviour has a property strixReplicator, that you can use to refer to the StrixReplicator component attached to the GameObject, just like you can use transform property to access to the Transform component. StrixBehaviour provides two more shortcut properties, isLocal and isSync, that refer to StrixReplicator‘s properties of the same names.

StrixNetwork singleton class

StrixNetwork singleton class provides the main entry point to the Strix’s scripting API. As usual, you can use its instance property to get its singleton instance then use it to access to other members of the class.

The class resides in the namespace SoftGear.Strix.Unity.Runtime

For example:

using SoftGear.Strix.Unity.Runtime;

        // In some method such as Start()

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

Asynchronous processing

Many methods in Strix’s scripting API are executed asynchronously because they involve network operation that may take some long time and because we should not block the Unity’s main thread.

Strix Unity SDK uses callback handlers to implement such asynchronous operations.

sequenceDiagram participant A as Script participant B as SDK library participant C as Server A ->> + B : Invoking a method B ->> + C : Request to a server B -->> - A : Method returns C ->> C : Server-side processing C -->> + B : Response from a server deactivate C B -->> - A : Callback

Note

In Strix Unity SDK, we often call those callbacks events, though they are just ordinary delegates. Don’t confuse them with event in C# grammar terminology or Unity’s UnityEvent.

Some Strix classes, by the way, have event members in the sense of C# grammar term.

A typical Strix method for a network operation has two delegates in its parameter list. The two delegates are called a success callback handler and failure callback handler in general. When you invoke such a method, the method returns before the completion of the network operation. Later, when the operation completes, one of the delegates is invoked. If the operation was successful, the success callback is invoked; otherwise the failure callback is invoked.

The delegate types of those callback handlers vary, but they usually receive a single parameter of a type whose name ends with EventArgs and return nothing (void). The object that a callback handler receives through its parameter usually (though not always) provides information that tells you the result of the network operation (something more than just success or failure.)

For example, The type of the failure callback handler of ConnectMasterServer method is StrixNetworkConnectFailedEventHandler, which is defined as:

public delegate void StrixNetworkConnectFailedEventHandler(
    StrixNetworkConnectFailedEventArgs args
);

where StrixNetworkConnectFailedEventArgs is a class with two properties cause (of type Exception) and session (of type AbstractSession).

Downcasting

One of the strengths of Strix server is its flexibility for customization. (Though, unfortunately, you can’t customize Strix servers running on Strix Cloud; you need to use STRIX ENGINE product to run customized Strix servers.) Utilizing the customized servers requires similar levels of flexibility on the client side.

Many parts of scripting API are defined in general way, often using generics, partly for the purpose. The types they use are often defined as interfaces or abstract classes. However, you can downcast such an object to a concrete class to access to more members than the declared type. You can sometimes downcast an object declared as a concrete class in the same way.

For example, a parameter passed to a failure callback often has a property of name cause defined as Exception type. Although its defined type is System.Exception, you can often downcast it to ErrorCodeException (a Strix’s exception type defined in namespace SoftGear.Strix.Unity.Runtime.Error), which has errorCode property to denote the cause of the error.

For example:

void OnConnectMasterFailedCallback(StrixNetworkConnectFailedEventArgs args)
{
    if (args.cause is ErrorCodeException
        && ((ErrorCodeException)args.cause).errorCode == StandardErrorCode.ConnectionError)
    {
        // A special handling of this particular error.
    }
    else
    {
        // Ordinary error processing.
    }
}

See Error Codes for details on error codes.

Interfaces

Please note that Strix Unity SDK uses a lot of its own interfaces, and some of their names don’t start with “I”. An example is SoftGear.Strix.Client.Core.UID interface which represents a unique identifier of various objects. (It is the type of RoomInfo.nodeUid property or the return type of IRoomMember.GetUid() method among other usages.) You should be careful to identify those interfaces whose names start with non-I letters.

Well, why being an interface matters? … Because there is a common pitfall.

Many classes override == and != operators, if instances of the class represent some comparable values, so that programmers can compare such objects in intuitive ways. However, interfaces can’t override equality (and inequality) operators due to the C# language limitation (regardless of its first letter).

So, when you compare two UID objects, for example, you can’t use == operator, because it compares equality of the references of the two objects, and it returns false for two separate UID objects even when they represent an identical ID. Instead, you need to use Equals method as in the second if statement in the example below:

private UID uid;

// A handler for StrixNetwork::GetRoomMembers.
void OnRoomMembersGot(RoomMemberGetEventArgs args)
{
    foreach (var member in args.roomMemberCollection)
    {
        UID memberUid = member.GetUid();

        // This comparison doesn't work as you expect,
        // because it compares equality of references.
        if (memberUid == uid)
        {
            // Do something.
        }

        // Do it this way, instead.
        if (memberUid.Equals(uid))
        {
            // Do something.
        }
    }
}