Skip to main content
Version: 5.7.0

brainCloud + Unity + Steam Integration

Steam does not offer native support for the Unity Game Engine. A third party git library was used to integrate Steam features into Unity.

Required Materials

Download Steamworks SDK from Steam

https://partner.steamgames.com/doc/sdk

Steamworks.Net version 12.0.0 was used.
https://github.com/rlabrecque/Steamworks.NET/releases

brainCloud version 3.11 was used.
https://github.com/getbraincloud/braincloud-csharp

Unity 2018.2.5f1 was used

https://unity3d.com/get-unity/download/archive

Configure Steam Platform with brainCloud Design Portal

Enter in the Steam App Id and Steam Publisher Key into the brainCloud Design Portal via Design -> Core App Info -> Application IDs.

Steam App Id - Retrievable via Steam’s partner network.

Steam Publisher Key - Also referred to as WEB API key within Steam.  From the Steam partner network, Users & Permissions.  Select the correct group, and select “Create WepAPI Key” from the right panel.

Configure Steamworks.Net

Update Plugins\Steamworks.NET\redist\steam_appid.txt with the appropriate steam app Id.

Update SteamManager.cs,

if (SteamAPI.RestartAppIfNecessary(AppId_t.Invalid))

To

if (SteamAPI.RestartAppIfNecessary((AppId_t)<yoursteamappid>) 

Setup Steamworks.Net

using Steamworks;

public void SetupSteamManager()
{
if (SteamManager.Initialized)
{
m_bSteamInitialized = true;
// required callback for authenticating, view Steamworks.Net + brainCloud Authentication
m_getAuthSessionTicketResponse = Callback<GetAuthSessionTicketResponse_t>.Create(OnGetAuthSessionTicketResponse);
// required callback for In-App Purchases, Steamworks.Net + brainCloud Microtransactions
m_transactionCallback = Callback<MicroTxnAuthorizationResponse_t>.Create(OnTransactionResponse);
}
}

Steamworks.Net + brainCloud Authentication

using BrainCloud;

private bool m_bAttachSteam = false; // used for after we receive the auth response
private uint m_ticketSize; // cache ticket size
private byte[] m_ticket; // cache auth ticket

// requests an auth ticket from Steam for use later
public void AttachSteamAccount(bool in_bAttach = false, SuccessCallback in_success = null, FailureCallback in_fail = null)
{
if (SteamManager.Initialized)
{
m_bAttachSteam = in_bAttach;
m_steamAuthSuccess = in_success;
m_steamFailure = in_fail;

m_ticket = new byte[1024];
SteamUser.GetAuthSessionTicket(m_ticket, 1024, out m_ticketSize);
}
}

public void MergeSteamAccount(SuccessCallback in_success = null, FailureCallback in_fail = null, object in_obj = null)
{
if (m_steamIdStr != "" && m_authToken != "")
{
BCWrapper.IdentityService.MergeSteamIdentity(m_steamIdStr, m_authToken, in_success, in_fail, in_obj);
m_steamIdStr = "";
m_authToken = "";
}
}

private string m_authToken = ""; // will cache this, if we need it for a merge
private string m_steamIdStr = ""; // will cache this, if we need it for a merge
private void OnGetAuthSessionTicketResponse(GetAuthSessionTicketResponse_t pCallback)
{
CSteamID steamId = SteamUser.GetSteamID();
if (pCallback.m_hAuthTicket != HAuthTicket.Invalid && m_ticketSize != 0)
{
m_steamIdStr = steamId.ToString();
// IMPORTANT!!! CONVERT TO HEX STRING
m_authToken = BitConverter.ToString(m_ticket, 0, (int)m_ticketSize).Replace("-", string.Empty);

if (!m_bAttachSteam)
{
BCWrapper.AuthenticateSteam(m_steamIdStr, m_authToken, false, m_steamAuthSuccess, m_steamFailure, m_steamObj);
}
else
{
BCWrapper.IdentityService.AttachSteamIdentity(m_steamIdStr, m_authToken, m_steamAuthSuccess, m_steamFailure, m_steamObj);
}
}
}

Steamworks.Net + brainCloud Microtransactions / In-App Purchases

 // steam is a two-step process, where you start a purchase, and then finalize it

private SuccessCallback m_successCallback;
private FailureCallback m_failureCallback;
private string m_delayedTransactionId = "";

public void StartPurchase(string in_languageCode, string in_storeProductId, SuccessCallback in_success = null, FailureCallback in_fail = null)
{
m_successCallback = in_success;
m_failureCallback = in_failure;
m_delayedTransactionId = "";

Dictionary<string, object> purchaseData = new Dictionary<string, object>();
purchaseData["language"] = in_languageCode;
purchaseData["itemId"] = in_storeProductId;

BCWrapper.Client.AppStoreService.StartPurchase("steam", JsonWriter.Serialize(purchaseData), onSteamStartPurchaseSuccess, m_failureCallback);
}

private void onSteamStartPurchaseSuccess(string in_json, object obj)
{
Dictionary<string, object> jsonMessage = (Dictionary<string, object>)JsonReader.Deserialize(in_json);
Dictionary<string, object> jsonData = (Dictionary<string, object>)jsonMessage["data"];

// brainCloud has given a transaction ID for this interaction, the STEAM overlay will popup
// to finalize the purchase for the user
m_delayedTransactionId = (string)jsonData["transactionId"];
}
// callback was created during Steam Setup
private void OnTransactionResponse(MicroTxnAuthorizationResponse_t pCallback)
{
Dictionary<string, object> transactionData = new Dictionary<string, object>();
transactionData["transId"] = m_delayedTransactionId;
BCWrapper.AppStoreService.FinalizePurchase("steam", m_delayedTransactionId, JsonWriter.Serialize(transactionData), m_successCallback, m_failureCallback);

m_delayedTransactionId = "";
}

More Info

  • Often times the Steam Overlay does not render/show up during editor or developer standalone builds.  You will need to upload a build using the steam SDK content uploader, to ensure the overlay is properly rendered over Unity’s engine.
  • All Steam purchases by default are in sandbox mode, to help initial integration and testing, prior to release.  Visit the brainCloud design portal Navigate to Design -> Core App Info -> Advanced Settings.  At the bottom is a check mark to distinguish if Steam Store purchases should be in sandbox mode or not.  Ensure this is unselected before going to the marketplace.