멤버 전체가 준비 완료될 때까지 기다리는 방법

방장이 게임 시작 시점을 선택할 수 있으려면 방장을 포함하여 멤버 모두가 준비를 마칠 때까지 기다려야 합니다.

방 멤버의 상태는 Room Member 개체에 저장할 수 있습니다(로비 만드는 방법 참조).

멤버 전체의 상태를 보고 싶다면 다음 코드를 이용하면 됩니다.

public static bool CheckAllRoomMembersState(int desiredState) {
    foreach (var roomMember in StrixNetwork.instance.roomMembers) {
        if (!roomMember.Value.GetProperties().TryGetValue("state",
            out object value)) {
            return false;
        }

        if ((int) value != desiredState) {
            return false;
        }
    }

    Debug.Log("CheckAllRoomMembersState OK");
    return true;
}

여기서 StrixNetwork.instance.roomMembers는 방에 있는 멤버 전체의 인스턴스가 저장되어 있는 컨테이너입니다. 이 함수는 멤버 전체의 상태가 desiredState 인수와 같은지 확인합니다.

CheckAllRoomMembersState()는 두 가지 방법으로 호출할 수 있습니다.

하나는 WaitUntil 클래스를 이용하여 코루틴(coroutine) 안에서 호출하는 것입니다. 아래 코드가 이 방식을 보여줍니다.

// 멤버 전체를 기다리고 게임 시작
void Start() {
    StartCoroutine(WaitStartGame());
}

private IEnumerator WaitStartGame() {
    yield return new WaitUntil(() => CheckAllRoomMembersState(1));
}

다른 한 가지 방법은 RoomSetMemberNotification을 이용하는 것입니다. 이를 위해서는 RoomSetMemberNotified 이벤트 핸들러를 등록해야 합니다. 아래 코드가 이 방식을 보여줍니다.

public static void AddRoomSetMemberHandler() {
    StrixNetwork.instance.roomSession.roomClient.RoomSetMemberNotified +=
        RoomSetMemberNotifiedHandler;
}

private static void RoomSetMemberNotifiedHandler(
    NotificationEventArgs<RoomSetMemberNotification<CustomizableMatchRoomMember>> notification) {
    if (CheckAllRoomMembersState(1) {
        // 전체 멤버가 준비 완료, 게임 시작
        StartGame();
    }
}

참고

StrixNetwork.instance.roomMembers의 콘텐츠가 업데이트되어 다른 클라이언트에서 요청한 변경사항을 반영합니다. 신규 멤버를 추가하고 퇴장한 멤버를 삭제할 수 있을 뿐만 아니라 기저의 네트워크 운영이 진행됨에 따라 같은 멤버의 CustomizableMatchRoomMember 개체도 다시 만들 수 있습니다.

즉, 향후 프레임에 사용하기 위해 rooMembers에서 가져온 개체는 캐싱할 수 없으며, 위의 CheckAllRoomMembersState와 같이 프레임마다(또는 새 알람이 도착할 때마다) roomMembers에서 새로 프레임을 가져와야 합니다.