Unity
How to integrate the Unity plugin.
You can use this plugin for Mobile Unity games - at the moment we support Android and iOS
To obtain the plugin please connect with us.
It's very easy to add our plugin to your Unity project - just drop our plugin folder into ./Assets/Plugins (don't forget to create Plugins folder if you don't have one yet). The only prerequisite is External Dependency Manager for Unity (EDM4U) - it should be installed for the plugin to work correctly, otherwise you will need to provide all the dependencies manually. Just use the latest version (1.2.176 at the moment). The configuration of the EDM4U is listed for each platform below.
Right after adding our plugin for the first time to your project, you will be greeted with welcome window like this (if you somehow miss it, you can open it using Window -> ESCS Plugin):

Escs welcome window
You can explore our API demo, filling the public key field with your public key generated at https://client.escs.io (or you can just click "Open ESCS Dashboard") and then clicking "Open example scene". Example will use public key that you entered in that field. Please install TMPro (Text Mesh Pro) Essentials beforehand (Window -> TextMesh Pro -> Import TMP Essential Resources).
Note: if you don't import TMPro before opening the scene, Unity will automatically ask you to do that, and you may encounter error (right after importing TMPro) like this:

You can safely ignore it and continue (press Play in editor and it will go away), it is due to opening scene before you have TMPro Essentials installed. To avoid this error install TMPro Essentials beforehand (Window -> TextMesh Pro -> Import TMP Essential Resources)
Exploring our demo scene, note that our code assumes that your game's score type (created in https://client.escs.io) is named "points", otherwise you won't get results sent from the demo.
Because Android build system heavily relies on package dependency management and Unity does't really support it out of the box, we need 3rd party dependency managements solution added. If you are working on a big project, chances are that you are already use it, otherwise please import following package:
This is officially supported by google package manager for Unity. Just download latest .unitypackage file from the repository and drag and drop it into your assets folder, it will automatically install itself. We recommend you to allow it to automatically resolve dependencies, otherwise you can do it manually from the Assets menu (after installing aforementioned package):

To support escs video chat and streaming on android platform, you need to define several properties in player settings in Scripting Define Symbols:

These symbols will allow build post-process script to add specific code in Android Manifest and main activity to support video chat and streaming.
For video chat you need 2 following define symbols:
ESCS_ANDROID_ENABLE_CAMERA;ESCS_ANDROID_ENABLE_MICROPHONE
separated by semicolon. If you are targeting Android API 29 or higher, then you also need to define
ESCS_ANDROID_API29_STREAMING
symbol, otherwise the app will crash upon receiving user's permission to record screen when streaming is starting, so in total you will need to define 3 symbols:ESCS_ANDROID_ENABLE_CAMERA;ESCS_ANDROID_ENABLE_MICROPHONE;ESCS_ANDROID_API29_STREAMING
For iOS you need to use the same External Dependency Manager for Unity as for Android, it will generate pods project. Be aware that we use
use_frameworks!
param in resulting pod file. However you can live without the resolver if you put required dependency manually. Internally the Escs Plugin uses SDWebImageWebPCoder
(https://github.com/SDWebImage/SDWebImageWebPCoder) which in turn uses SDWebImage
, so you need to manually link those libraries if you don't want to use pods and dependency resolver.Important! We do not currently support static linking because of Google WebRTC is shipped only as dynamically linked pod, so be sure that you uncheck "Link frameworks statically" in External Dependency Manager configuration, otherwise you might encounter errors when starting your game, saying that WebRTC framework is not found.

Be advised that you will not be able to use bitcode (because we have dependency on Google WebRTC which does not come with bitcode support). Also our framework is FAT framework, so it comes with both x86_64 and arm64 architectures. We provide built-in script for removing unused architectures when exporting build to iOS targets, so you don't need to worry about that, unless you already have one present in your build config. Then you just have to delete extra one.
When building for iOS you might encounter an error saying something like this:
Undefined symbols for architecture arm64: "_CallRegisterIngamePlayerId", referenced from: _EscsIosUnityPlugin_CallRegisterIngamePlayerId_m3865D0F13C4088A49DC16A615D13760E27353033 in Bulk_Assembly-CSharp-firstpass_0.o (maybe you meant: _EscsIosUnityPlugin_CallRegisterIngamePlayerId_m3865D0F13C4088A49DC16A615D13760E27353033) ld: symbol(s) not found for architecture arm64
In that case you might need to supply additional parameters to your linker. Go to your build target > Build Settings > Linking > Other Linker Flags and add the following line:
-Wl,-undefined,dynamic_lookup
It is very easy to integrate ESCS plugin into your game code.
We splitted these instructions into steps to make it easier to follower. Please complete each step before running your code.
First you need to initialize your plugin.
To start using your plugin you need first initialize it:
using EscsUnityPlugin.Core;
EscsUnityPlugin.Invoke(
string public_key,
string base_url,
string player_base_url,
InvokeDelegate OnEscsInit);
where:
public_key
- a key that you've obtained in the step 1 of the integration guide, like"fee91a27-2b87-45f8-8ca4-0b317707806q"
base_url
- url for the core ESCS service. It ishttps://api.escs.io
for production environmentplayer_base_url
- url for the player's ESCS service. It ishttps://player.escs.io
for production environmentOnEscsInit
- callback delegate when init is completed; you can omit it.
IMPORTANT! Although you can call Invoke several times, you should do it only once, otherwise behaviour is undefined.
Delegate method signature is following:
public delegate void InvokeDelegate (string status, string gameId, string tournamentId);
where:
status
- string "initialized" for fully initialized escs, or some error message, or empty stringgameId
- gameId of configured game or empty stringtournamentId
- tournamentId of current active tournament or empty string
That's it!
Now your players can chat, video chat or stream. Awesome, right?
escs takes care of the organization of competitions. For this to work, escs just need to let you know when to start a game and in return you need to let escs know player's score after the end of the game. Additionally, if your game is a true multiplayer game, you should let escs know your in-game player ids for the proper matchmaking
Call this right after you initialize the escs service and before player interacts with escs:
EscsUnityPlugin.RegisterIngamePlayerId(playerId, ingameMetadata);
where:
- playerId - your ingame player id (string). It will be passed along with OnGameSetStart callback when the game set will start
- ingameMetadata - your ingame metadata for this player (string, can be empty)
Now let's start the game.
Whenever escs starts a tournament and therefore initiates a game for the player, escs let's you know that you need to start the game. For this purpose escs provides OnGameSetStart callback.
When it is called - this is the moment when you should start your game or create lobby and await for players to join it.
Here is how you can register it.
EscsUnityPlugin.SetGameSetStartCallback(onSetStart);
//...
public void OnSetStart(EscsSetStartPayload p) {
Debug.Log("set started - players: ");
foreach(EscsTeam team in p.teams) {
Debug.Log("team: ");
foreach(EscsParticipant particip in team.members) {
Debug.Log(particip.username);
}
}
}
where EscsSetStartPayload contains:
- setId - setId of started set (string)
- tournamentId - tournamentId of the set (string)
- matchId - matchId of the set (string)
- roundId - roundId of the set (this is in fact id of the set "results") (string)
- globalMetadata - metadata string that can be set in the game dashboard (string)
- setEndTimeUnix - game's set latest end time in unix time (int)
- teams - array of EscsTeam objects. Each EscsTeam has array of EscsParticipant, which in turn contains:
- playerId - escs player id (string)
- ingamePlayerId - registered in-game player id via registerInGamePlayerId (string)
- username - user's escs username (string)
- firstName - user's escs first name (string)
- lastName - user's escs last name (string)
- avatar - user's escs avatar image url (string)
- ingameMetadata - in-game metadata that was registered via RegisterInGamePlayerId (string)
From all this parameters the most important one for you is the roundId, which you will be using to send the score of the game back to the escs.
You should use ingamePlayerIds to start the game for the right players (relevant only if your game is a multiplayer game).
Additionally, you might find it useful to send scores of some of the games to the escs, that are not part of the tournament, for example for the World Top Today or ELO calculations.
In this case you may call the
StartGame()
method to let the escs know of the start of the game (call it only for the games where you are not using OnGameSetStart callback to start the game) :EscsUnityPlugin.StartGame(StartGameDelegate OnStartGame);
where
OnStartGame
- callback delegate when startGame has obtained round info (you can omit it) with following signature:
public delegate void StartGameDelegate (string roundId, string tournamentId, string status, string playerId);
where:
roundId
- roundId of just started game round in the escs.tournamentId
- tournamentId of active tournament for which the round was created forstatus
- round status. "active" for just created roundplayerId
- escs playerId
When the round of your game has ended, just call
EndGame()
with score parameter:[Serializable]
public class GameScoreExample {
public double points;
public double points_extra;
}
...
public void OnEndGame(string roundId, string tournamentId, string status, string playerId) {
Debug.Log(roundId);
Debug.Log(status);
}
...
GameScoreExample score = new GameScoreExample();
score.points = Mathf.Ceil(UnityEngine.Random.Range(0.1f, 100.0f));
score.points_extra = Mathf.Ceil(UnityEngine.Random.Range(0.1f, 100.0f));
EscsUnityPlugin.EndGame(score, onEndGame);
where
score
- game score parameter - accepts an object with Serializable annotation; the names of properties should be defined in game dashboard at client.escs.io, the type of each is doubleOnEndGame
- callback delegate when startGame has obtained round info (you can omit it) with following signature:
public delegate void EndGameDelegate (string roundId, string tournamentId, string status, string playerId);
where:
roundId
- roundId of just ended game roundtournamentId
- tournamentId of active tournament for which the round was endedstatus
- round status. "ended" for just ended roundplayerId
- escs playerId
Now you are done! Your game is now a competition platform.
Go and create tournaments in the dashboard, your players can create tournaments inside the game and 3rd party organizers like ESL or influencers/streamers can create tournaments and drive players into your game.
Last modified 3mo ago