Contents

Unity Engine

Initial settings

Double click on the supplied unitypackage and import all files into your project. Once that import has been completed click on the Twitch Menu in the toolbar and then click on edit settings. The Inspector will then show a Twitch Client ID text box, you must enter a valid Client ID in that box for the plugins to function.

Unity Plugin Settings image

Authentication

Authentication requires you to maintain two GameTask objects of type AuthenticationInfo and AuthState, GameTask<AuthenticationInfo> and GameTask<AuthState>. GetAuthState() can be called at any time to ensure that your user’s auth state is up to date. Generally we suggest you do this in the start function of your management code. Once updateAuthState has been called at least once you can then check the status of the auth via the MaybeResult of the state. If the MaybeResult is not null you can check its Status such as curAuthState.MaybeResults.Status. Possible status states are AuthStatus.LoggedIn, AuthStatus.LoggedOut, AuthStatus.WaitingForCode. If the status is WaitingForCode, Then your user needs to complete the login flow. To do so create an UserAuthInfo object via the MaybeResult of Twitch.API.GetAuthenticationInfo(Scopes). If the MaybeResult is not null then you should be able to launch a browser window with the uri from the UserAuthInfo object. Application.OpenURL("{UserAuthInfo.uri}").

Example of a Authentication Manager Class

using TwitchSDK;
using TwitchSDK.interop;
public class AuthManager : MonoBehaviour
{
	private bool alreadyLoggedIn = false
	GameTask<AuthenticationInfo> AuthInfoTask;
	GameTask<AuthState> curAuthState;
	
	void start()
	{
		updateAuthState();
	}
	
	public void UpdateAuthState()
	{
		curAuthState = Twitch.API.GetAuthState();
		if(curAuthState.MaybeResult.Status == AuthStatus.LoggedIn)
		{
			//user is logged in
		}
		if (curAuthState.MaybeResult.Status == AuthStatus.LoggedOut)
		{
			//user is logged out, do something
			//In this example you could also call GetAuthInformation() to retrigger login
		}
		if (curAuthState.MaybeResult.Status == AuthStatus.WaitingForCode)
		{
			//Waiting for code
			var UserAuthInfo = Twitch.API.GetAuthenticationInfo(RequiredScopes).MaybeResult;
			if(UserAuthInfo == null)
			{
				//User is still loading
			}
			//We have reached the state where we can ask the user to login
			Application.OpenURL("{UserAuthInfo.Uri}{UserAuthInfo.UserCode}");
		}
	}

	//Triggered by something external, like a menu button
	public void GetAuthInformation()
	{
		if (AuthInfoTask == null)
		{
			//This example uses all scopes, we suggest you only request the scopes you actively need.
			var scopes = TwitchOAuthScope.Bits.Read.Scope + "+" + TwitchOAuthScope.Channel.ManageBroadcast.Scope + "+" + TwitchOAuthScope.Channel.ManagePolls.Scope + "+" + TwitchOAuthScope.Channel.ManagePredictions.Scope + "+" + TwitchOAuthScope.Channel.ManageRedemptions.Scope + "+" + TwitchOAuthScope.Channel.ReadHypeTrain.Scope + "+" + TwitchOAuthScope.Clips.Edit.Scope + "+" + TwitchOAuthScope.User.ReadSubscriptions.Scope;
			TwitchOAuthScope tscopes = new TwitchOAuthScope(scopes);
			AuthInfoTask = Twitch.API.GetAuthenticationInfo(tscopes);
		}
	}
}

Polls

When utilizing the poll functionality of the plugins you must maintain a GameTask of type poll, GameTask<Poll>. You can use that task to determine if a poll has started, is active, or has returned results. To create a new poll make a new object of type GameTask<Poll> then use the new poll function and pass in a PollDefinition for example:

OurPoll = Twitch.API.NewPoll(new PollDefinition { Title = "some title", Choices = {"a","b","c"}, Duration = someNumber})

Once that has been created you can use the MaybeResult to check the results. var PollResult = OurPoll?.MaybeResult; The resulting variable contains a Info object to check status and choice values. PollResult.Info.Status and PollResult.Info.Choices. More information can be found in our reference.

Example of a Poll Manager class

using TwitchSDK;
using TwitchSDK.Interop;
public class TwitchPollManager : MonoBehaviour
{
	GameTask<Poll> ActivePoll = null;
	private bool PollHasEnded = false;
	void Start()
	{
	}
	
	//Called by some external class
	void StartPoll(string pollTitle, string[] pollChoices)
	{
		// We already polled something, so we don't do anything.
		if (ActivePoll != null)
			return;
		var authStatus = Twitch.API?.GetAuthState().MaybeResult;
		//Not logged in
		if (authStatus?.Status != AuthStatus.LoggedIn)
			return;
		// If we don't have the "Manage Polls" permission, we also give up.
		if (!authStatus.Scopes.Any(a => a == Twitch.TwitchOAuthScope.Channel.ManagePolls.Scope))
			return;
		ActivePoll = Twitch.API.NewPoll(new PollDefinition
		{
			Title = pollTitle,
			Choices = pollChoices,
			Duration = 20, // in seconds
		});
	}
	void Update()
	{
		if (PollHasEnded)
			return;
		var poll = ActivePoll?.MaybeResult;
		if (poll == null)
			return;
		// This means we have an active poll, and are waiting for it to finish.
		if (poll.Info.Status == PollStatus.Active)
			return;
		// Now we know the poll is finished in some way.
		PollHasEnded = true;
		// This poll was cancelled by someone, so we don't take the results.
		if (poll.Info.Status != PollStatus.Completed)
			return;
		// Now we can tally results and do something
		var votesForChoice1= poll.Info.Choices.Where(a => a.Title == "Yes").Single();
		var votesForChoice2 = poll.Info.Choices.Where(a => a.Title == "No").Single();

		if(votesForChoice1 > votesForChoice2)
			//Do something
		if(votesForChoice2 > votesForChoice1)
			//Do something else
		else //encase they somehow tie
			//Do something else again
	}
}

Predictions

Predictions function much in the same way as polls, only with a limit of two choices for outcomes. To interact with predictions you must maintain a GameTask of type Prediction, GameTask<Prediction>. You can use that task to determine if a prediction has been started, is active, or has returned results. To create a new prediction make a new object of type GameTask<Prediction> then use the new prediction function and pass in a PredictionDefinition for example OurPrediction = Twitch.API.NewPoll(new PollDefinition { Title = "some prediction", Outcomes = {"a","b"}, Duration = someNumber). Once that has been created you can use the MaybeResult to check the results. var PredictionResult = OurPrediction?.MaybeResult; The resulting variable contains a Info object, You can use this to check status, outcomes, and the winning outcome. PredictionResult.Info.Status, PredictionResult.Info.WinningOutcomeId, PredictionResult.Info.Outcomes. PredictionResult.Info.Outcomes is a vector containing information about a given outcome, such as number of users and channel points spent. More information can be found in our reference.

Example of a predictions manager class

using TwitchSDK;
using TwitchSDK.Interop;
public class TwitchPredictionManager : MonoBehaviour
{
	GameTask<Prediction> ActivePrediction = null;
	private bool PredictionHasEnded = false;

	public void createPrediction(string predictionTitle, string[] predictionChoices)
	{
		// We already polled something, so we don't do anything.
		if (ActivePrediction != null)
			return;
		var authStatus = Twitch.API?.GetAuthState().MaybeResult;
		//Not Logged in
		if (authStatus?.Status != AuthStatus.LoggedIn)
			return;
		// If we don't have the "Manage Predictions" permission, we also give up.
		if (!authStatus.Scopes.Any(a => a == R66.TwitchOAuthScope.Channel.ManagePredictions.Scope))
			return;
		ActivePrediction = Twitch.API.NewPrediction(new PredictionDefinition
		{
			Title = predictionTitle,
			Outcomes = predictionChoices,
			Duration = 20, // in seconds
		});
		//Sets it back to false incase a previous prediction has already ended
		PredictionHasEnded = false;
	}

	void Update()
	{
		if (PredictionHasEnded)
			return;
		var prediction = ActivePrediction?.MaybeResult;
		if (prediction == null)
			return;
		// This means we have an active poll, and are waiting for it to finish.
		if (prediction.Info.Status == PollStatus.Active)
			return;
		// Now we know the prediction is finished.
		PredictionHasEnded = true;
		// This prediction was cancelled by someone, so we don't take the results.
		if (prediction.Info.Status != PredictionStatus.Completed)
			return;
		// Now we get the winning outcome
		var winningOutcome = prediction.Info.Outcomes.Where(a => a.Id == prediction.Info.WinningOutcomeId);
		//Do something with that			
	}
}

Channel Point Rewards

Channel point rewards allow you to create dynamic ingame events based on “purchases” made by users on a given stream. This is the most open-ended of all supported functions and as such, any functionality implemented will be highly dependent on your game’s design.

This requires the user to be logged in and the appropriate manage:redemptions scope.

The example below uses channel points to provide a list of colors which could be used in various ways in-game.

using TwitchSDK;
using TwitchSDK.Interop;
public class TwitchChannelPointManager : MonoBehaviour
{
	public void SetSampleRewards()
	{
		CustomRewardDefinition ColorRed = new CustomRewardDefinition();
		ColorRed.Title = "Red!";
		ColorRed.Cost = 10;
		CustomRewardDefinition ColorBlue = new CustomRewardDefinition();
		ColorBlue.Title = "Blue!";
		ColorBlue.Cost = 25;
		CustomRewardDefinition ColorOctarine = new CustomRewardDefinition();
		ColorOctarine.Title = "Octarine!";
		ColorOctarine.Cost = 750;

		List<CustomRewardDefinition> cDefinitionList = new List<CustomRewardDefinition>();
		cDefinitionList.Add(ColorRed);
		cDefinitionList.Add(ColorBlue);
		cDefinitionList.Add(ColorOctarine);

		Twitch.API.ReplaceCustomRewards(cDefinitionList.ToArray());
	}

	public void ClearRewards()
	{
		CustomRewardDefinition Cleared = new CustomRewardDefinition();
		Cleared.Title = "";
		Cleared.Cost = 0;
		Cleared.IsEnabled = false;
		Twitch.API.ReplaceCustomRewards(Cleared);
	}
}

Once you have created custom channel point rewards you must subscribe to the associated event, this is covered below.

User Info

To pull user information, such as Displayname, Viewcount or UserType, you must maintain a GameTask of type UserInfo, GameTask<UserInfo>. If you wish to pull email information you must request the appropriate scope at authentication.

Example of how to use:

GameTask<UserInfo> UserInfoTask;
string LoginName;
string BroacasterType;
string DisplayName;
string UserType;
string ViewCount;
	
public void GetUserInformation()
{
    if(UserInfoTask == null)
    {
        UserInfoTask = Twitch.API.GetMyUserInfo();
        if(UserInfoTask?.IsCompleted == true)
        {
            if(UserInfoTask.MaybeResult != null)
            {
                LoginName = "Login Name: " + UserInfoTask.MaybeResult.DisplayName;
                BroacasterType = "Broadcaster Type: " + UserInfoTask.MaybeResult.BroadcasterType;
                DisplayName = "Display Name: " + UserInfoTask.MaybeResult.DisplayName;
                UserType = "User Type: " + UserInfoTask.MaybeResult.UserType;
                ViewCount = "View Count: " + UserInfoTask.MaybeResult.ViewCount;
            }
        }
    }
}

Stream Info

To pull stream information, such as ViewerCount, Language, GameName, etc. You must maintain a GameTask of type UserInfo, GameTask<StreamInfo>. If you wish to pull email information you must request the appropriate scope at authentication.

Example of how to use:

GameTask<StreamInfo> StreamInfoTask;
string GameName;
bool isMature;
string Language;
string Title;
long ViewerCount;
	
public void GetStreamInformation()
{
    if(StreamInfoTask == null)
    {
        StreamInfoTask = Twitch.API.GetMyStreamInfo();
        if(StreamInfoTask?.IsCompleted == true)
        {
            if(StreamInfoTask.MaybeResult != null)
            {
                GameName = "Game Name: " + StreamInfoTask.MaybeResult.GameName;
                isMature = StreamInfoTask.MaybeResult.IsMature;
                DisplayName = "Language: " + StreamInfoTask.MaybeResult.Language;
                Title = "Title: " + StreamInfoTask.MaybeResult.Title;
                ViewerCount = StreamInfoTask.MaybeResult.ViewerCount;
            }
        }
    }
}

Subscribe to Events

Events such as new followers, subscribers, raids, hypetrain etc use a special type of GameTask<EventStream<>>. EventStreams are special in that they also have multiple types.

When working with Events you have a choice to either use WaitForEvent or TryGetNextEvent. We recommend that you only use one at a time. If you plan on calling this at regular intervals such as in Update we suggest using TryGetNextEvent. If the event has been completed, TryGetNextEvent will return the task via the out parameter.

Channel Point Rewards

GameTask<EventStream<CustomRewardEvent>> CustomRewardEvents;

start()
{
  CustomRewardEvents = SubscribeToCustomRewardEvents();
}

update()
{
  var CurRewardEvent; 
  CustomRewardEvents.TryGetNextEvent(out CurRewardEvent);
  if(CurRewardEvent != null)
  {
    //Do something
    Debug.Log("{CurRewardEvent.RedeemerName} has brought {CurRewardEvent.CustomRewardTitle} for {CurRewardEvent.CustomRewardCost}!");
  }
}

Follows

GameTask<EventStream<ChannelFollowEvent>> FollowEvents;

start()
{
  FollowEvents = SubscribeToChannelFollowEvents();
}

update()
{
  var CurFollowEvent; 
  FollowEvents.TryGetNextEvent(out CurFollowEvent);
  if(CurFollowEvent != null)
  {
    //Do something
    Debug.Log("{CurFollowEvent.UserDisplayName} is now following!");
  }
}

Subscribers

GameTask<EventStream<ChannelSubscribeEvent>> ChannelSubscribeEvents;

start
{
  ChannelSubscribeEvents = SubscribeToChannelSubscribeEvents();
}

update()
{
  var CurSubscriberEvent; 
  ChannelSubscribeEvents.TryGetNextEvent(out CurSubscriberEvent);
  if(CurSubscriberEvent != null)
  {
    //Do something
    Debug.Log("{CurSubscriberEvent.UserDisplayName} has Subscribed!");
  }
}

HypeTrain

GameTask<EventStream<HypeTrainEvent>> HypeTrainEvents;

start
{
  HypeTrainEvents = SubscribeToHypeTrainsEvents();
}

update()
{
  var CurHypeTrainEvent; 
  HypeTrainEvents.TryGetNextEvent(out CurHypeTrainEvent);
  if(CurHypeTrainEvent != null)
  {
    //Do something
    Debug.Log("The Hypetrain level is {CurHypeTrainEvent.Level}!");
  }
}

Raids

GameTask<EventStream<ChannelRaidEvent>> RaidEvents;

start
{
  RaidEvents = SubscribeToChannelRaidEvent();
}

update()
{
  var CurRaidEvent; 
  RaidEvents.TryGetNextEvent(out CurRaidEvent);
  if(CurRaidEvent != null)
  {
    //Do something
    Debug.Log("{CurRaidEvent.FromBroadcasterName} has raided with {CurRaidEvent.Viewers} people!");
  }
}