Code

Allow players to create groups and interact in real-time

Overview

Here is everything needed to use the Groups feature in the "Beamable SDK for Unity".

The purpose of this feature is to allow players to play together in-game.

Groups may be short-term "parties" which are joined/left around a particular game event or longer-term "guilds" or "clans" which persist between game sessions.

📘

Use Cases

This functionality has various use cases for game makers and players. Here are just a few ideas...

Collaboration - Group members may share resources to progress on common goals (e.g. quests)
Competition - All groups in the game community compete directly and indirectly for rewards
Communication - Groups functionality integrates with text chat. See Chat for more info

Players can create groups and interact in real-time. Interactions include donating currency between group members for spending on in-game items. Depending on the game design, group members may have shared goals where interaction and collaboration are a key part of success.

Create Group

var groupCreateRequest= new GroupCreateRequest ("MyGroupName", "MyGroupTag", "open", 0, 50);
await _beamableAPI.GroupsService.CreateGroup (groupCreateRequest);

Request Group Donation

_beamableAPI.GroupsService.MakeDonationRequest (groupId, currency);

Make Group Donation

_beamableAPI.GroupsService.Donate (groupId, memberId, 10);

Glossary

Here is the glossary of chat-related terms.

Name

Detail

Group

A collection of game players (e.g. a guild)

Group Member

A game player within the group

Group Member Role

Players within a group may have distinct roles to dictate gameplay limits and responbilities

API

Unlike many Beamable FeatureFeature - An individual aspect of the Beamable product used to create a great user experiences, Chat does not require a specific Beamable Feature PrefabFeature Prefab - The drag-and-drop template for a specific Beamable product feature to be used. The main entry point to this feature is C# programming.

📘

Learning Fundamentals

Game makers who are new to Unity and C# can review the fundamentals here.

• See Beamable: Asynchronous Programming for more info

Here are API highlights for beamableAPI.GroupService.

Method Name

Detail

Subscribe

Callback to observe changes

CreateGroup

Create a new group

GetCurrent

Get list of all current groups

JoinGroup

Join a group

LeaveGroup

Leave the current group

MakeDonationRequest

Request a currency donation from group

Donate

Send a currency donation to group member

SetGroupProps

Sets the GroupUpdateProperties including...
Name - Group name
Slogan - External-facing group slogan
Motd - Internal-facing message for members
Tag - Optional 3 letter shorthand for group
EnrollmentType - restricted / open / closed

  • Restricted - By invitation or application only
  • Closed - By invitation only
  • Open - Anybody can join

Examples

Here are examples which cover common programming needs.

📘

Beamable SDK Examples

This and all examples are available for download at GitHub.com/Beamable_SDK_Examples

In this example, the player can create a group and interact.

using System.Collections.Generic;
using System.Threading.Tasks;
using Beamable.Common.Api;
using Beamable.Common.Api.Groups;
using UnityEngine;
using Beamable.Experimental.Api.Chat;
using UnityEngine.Events;

namespace Beamable.Examples.Services.GroupsService
{
    /// <summary>
    /// Holds data for use in the <see cref="GroupsServiceExampleUI"/>.
    /// </summary>
    [System.Serializable]
    public class GroupsServiceExampleData
    {
        public List<string> GroupNames = new List<string>();
        public List<string> RoomNames = new List<string>();
        public List<string> RoomUsernames = new List<string>();
        public List<string> RoomMessages = new List<string>();
        public string GroupToCreateName = "";
        public string GroupToLeaveName = "";
        public bool IsInGroup = false;
        public string MessageToSend = "";
    }
   
    [System.Serializable]
    public class RefreshedUnityEvent : UnityEvent<GroupsServiceExampleData> { }
    
    /// <summary>
    /// Demonstrates <see cref="GroupsService"/>.
    /// </summary>
    public class GroupsServiceExample : MonoBehaviour
    {
        //  Events  ---------------------------------------
        [HideInInspector]
        public RefreshedUnityEvent OnRefreshed = new RefreshedUnityEvent();
        
        //  Fields  ---------------------------------------
        private ChatView _chatView = null;
        private GroupsView _groupsView = null;
        private IBeamableAPI _beamableAPI = null;
        private GroupsServiceExampleData _data = new GroupsServiceExampleData();
    
        //  Unity Methods  --------------------------------
        protected void Start()
        {
            Debug.Log("Start()");

            SetupBeamable();
        }
        
        //  Methods  --------------------------------------
        private async void SetupBeamable()
        {
            _beamableAPI = await Beamable.API.Instance;

            Debug.Log($"beamableAPI.User.id = {_beamableAPI.User.id}");

            // Observe GroupsService Changes
            _beamableAPI.GroupsService.Subscribe(async groupsView =>
            {
                _groupsView = groupsView;
                _data.GroupNames.Clear();
                
                _data.IsInGroup = groupsView.Groups.Count > 0;
                
                foreach(var groupView in groupsView.Groups)
                {
                    string groupName = $"Name = {groupView.Group.name}, Members = {groupView.Group.members.Count}";
                    _data.GroupNames.Add(groupName);

                    // Create a new chat room for the group
                    string roomName = $"Room For Group {groupView.Group.name}";
                    await _beamableAPI.Experimental.ChatService.CreateRoom(groupName, false,
                        new List<long> {_beamableAPI.User.id});
                    
                    // Store, so user can leave if/when desired
                    _data.GroupToLeaveName = groupView.Group.name;
                }
                
                Refresh();
            });
            
            // Observe ChatService Changes
            _beamableAPI.Experimental.ChatService.Subscribe(chatView =>
            {
                _chatView = chatView;
                _data.RoomNames.Clear();
                
                foreach(RoomHandle room in chatView.roomHandles)
                {
                    // Optional: Only setup non-empty rooms
                    if (room.Players.Count > 0)
                    {
                        string roomName = $"Name = {room.Name}, Players = {room.Players.Count}";
                        _data.RoomNames.Add(roomName);

                        room.Subscribe().Then(_ =>
                        {
                            _data.RoomMessages.Clear();
                            foreach (var message in room.Messages)
                            {
                                string roomMessage = $"{message.gamerTag}: {message.content}";
                                _data.RoomMessages.Add(roomMessage);
                            }

                            room.OnMessageReceived += RoomHandle_OnMessageReceived;
                            Refresh();
                        });
                    }
                }
                Refresh();
            });
        }
        
        public async Task<EmptyResponse> SendGroupMessage()
        {
            foreach(RoomHandle room in _chatView.roomHandles)
            {
                await room.SendMessage(_data.MessageToSend);
            }
            return new EmptyResponse();
        }
        
        public async Task<EmptyResponse> CreateGroup ()
        {
            // Leave any existing group
            await LeaveGroup();
            
            string groupName = _data.GroupToCreateName;
            string groupTag = "t01";
            string enrollmentType = "open";

            // Search existing group
            var groupSearchResponse = await _beamableAPI.GroupsService.Search(groupName, 
                new List<string> {enrollmentType});
            
            // Join or Create new group
            if (groupSearchResponse.groups.Count > 0)
            {
                foreach (var group in groupSearchResponse.groups)
                {
                    var groupMembershipResponse = await _beamableAPI.GroupsService.JoinGroup(group.id);
                }
            }
            else
            {
                var groupCreateRequest = new GroupCreateRequest(groupName, groupTag, enrollmentType, 0, 50);
                var groupCreateResponse = await _beamableAPI.GroupsService.CreateGroup(groupCreateRequest);
                var createdGroup = groupCreateResponse.group;

                // Join new group
                await _beamableAPI.GroupsService.JoinGroup(createdGroup.id);
    
            }
   
            Refresh();

            return new EmptyResponse();
        }
        
        public async Task<EmptyResponse> LeaveGroup()
        {
            foreach(var group in _groupsView.Groups)
            {
                var result = await _beamableAPI.GroupsService.LeaveGroup(group.Group.id);
            }
            
            Refresh();
            
            return new EmptyResponse();
        }
        
        public void Refresh()
        {
            // Create new mock message 
            int messageIndex = _data.RoomMessages.Count;
            _data.MessageToSend = $"Hello World {messageIndex:000}!";
            
            // Create new mock group name
            int groupIndex = _data.GroupNames.Count;
            _data.GroupToCreateName = $"Group{groupIndex:000}";

            // Create temp name for pretty UI
            if (string.IsNullOrEmpty(_data.GroupToLeaveName))
            {
                _data.GroupToLeaveName = _data.GroupToCreateName;
            }
         
            Debug.Log($"Refresh()");
            Debug.Log($"\tGroupNames.Count = {_data.GroupNames.Count}");
            Debug.Log($"\tRoomNames.Count = {_data.RoomNames.Count}");
            Debug.Log($"\tUserNames.Count = {_data.RoomUsernames.Count}");
            Debug.Log($"\tIsInGroup = {_data.IsInGroup}");
            
            // Send relevant data to the UI for rendering
            OnRefreshed?.Invoke(_data);
        }
        
        //  Event Handlers  -------------------------------
        private void RoomHandle_OnMessageReceived(Message message)
        {
            string roomMessage = $"{message.gamerTag}: {message.content}";
            _data.RoomMessages.Add(roomMessage);
            Refresh();
        }
    }
}

Advanced

This section contains any advanced configuration options and workflows.

Adding Group Chat

The chat feature includes full functionality for groups. Players can send chat messages within their group. Players can also send chat messages globally, within rooms, and directly to a specific player.

See Chat for more info.

Adding Group Events

The events feature includes full functionality for groups. Players can collaborate with group members and get group rewards.

See Events for more info.


Did this page help you?