escs
  • Introduction
  • Integration - step 1
  • Integration - step 2
  • Plugins
    • Unity
      • Optional steps
    • JS
    • React Native
    • Android native
      • Basic multiplayer with OAuth
    • iOS native
    • JS WatchThis
    • Pragma.gg
    • Unreal
  • Tournament series
    • Your first tournament series
    • Game mode and scores.
    • Matches, Sets, Points
    • Tournament structures
  • Anti-Cheat services
  • Using escs OAuth for sign in
  • How to integrate your business with the ESCS
  • Support
Powered by GitBook
On this page
  • Connecting plugin to your project.
  • Integrating plugin into your game.
  • Step 1, which enables all the socialization features
  • Step 2, which enables eSports

Was this helpful?

  1. Plugins

Unity

How to integrate the Unity plugin.

PreviousIntegration - step 2NextOptional steps

Last updated 7 months ago

Was this helpful?

You can use this plugin for Mobile Unity games - at the moment we support Android and iOS

Get it on the Unity !

Connecting plugin to your project.

To obtain the plugin please connect with us.

Unity plugin is currently for native devices only - it means that you won't be able to see plugin working in Unity Editor "Play" mode. However you can use device emulators to run the game and see plugin in action there. We are planning to add Editor functionality and Windows plugin as well in the future.

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 (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.179 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):

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)

Android

Unfortunately, we provide out-of-the-box integration only for Unity 2022 and higher. If you are still using Unity 2021, you have to manually update your gradle scripts to support android's compileSdk 33 / targetSdk 33 (you have to do that anyway since it is now a requirement for Google Play Store). This restriction is due to new Android permissions model for capturing device screen, introduced in Android SDK 33. The code required to support this change, will not compile using older versions of sdk, gradle and android gradle plugin.

To use Android Unity plugin you need to use compileSdk 33 or higher in your gradle build. For Unity 2022 the change is trivial - you can update the version manually in your custom gradle template or using Target API Level = 33 in your unity project settings.

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):

They are enabled by default, but make sure that you haven't unchecked them.

Note, that for these settings to work you have to enable custom main gradle template and gradle settings template in Unity Player Settings, as shown below:

Supporting video chat and streaming on Android

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 defineESCS_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

If you have highly customized Android Manifest and/or UnityPlayerActivity, then auto-generation may fail and you have to add following code manually to support notifications and streaming:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    EscsAndroidUnityPlugin.onActivityResult(requestCode, resultCode, data);
}

@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    EscsAndroidUnityPlugin.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

iOS

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

Integrating plugin into your game.

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.

Step 1, which enables all the socialization features

First you need to initialize your plugin.

Initialization

To start using your plugin you need first initialize it:

using EscsUnity.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 is https://api.escs.io for production environment

  • player_base_url - url for the player's ESCS service. It is https://player.escs.io for production environment

  • OnEscsInit- 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 string

  • gameId - gameId of configured game or empty string

  • tournamentId - tournamentId of current active tournament or empty string

That's it! Now your players can chat, video chat or stream. Awesome, right?

Step 2, which enables eSports

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

Registering in-game player id and metadata:

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)

Start Game

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 for

  • status- round status. "active" for just created round

  • playerId- escs playerId

Progress Game (Optional)

During gameplay, you can send progress of the players, this will allow advanced insights into your gameplay and ability to see their scores and score graphs in streaming view. Call ProgressGame() with score parameter:

[Serializable]
public class GameScoreExample {
    public double points;
    public double points_extra;
}
...
public void OnProgressGame(string progressId, string roundId) {
    Debug.Log(roundId);
    Debug.Log(progressId);
}
...
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.ProgressGame(score, OnProgressGame);

where

  • OnProgressGame - callback delegate when progressGame has obtained round info (you can omit it) with following signature:

public delegate void ProgressGameDelegate(string progressId, string roundId);

where:

  • roundId - roundId of just progressed game round

  • progressId- id of just sent progress object

End Game

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

  • OnEndGame - 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 round

  • tournamentId- tournamentId of active tournament for which the round was ended

  • status- round status. "ended" for just ended round

  • playerId- 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.

You can explore our API demo, filling the public key field with your public key generated at (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).

Exploring our demo scene, note that our code assumes that your game's score type (created in ) is named "points", otherwise you won't get results sent from the demo.

Due to known issue () in dependency resolver, the standard download artifacts phase may fail or resolve incorrect versions of libraries. We advise to use these settings for Android resolving:

For iOS you need to use the same 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 () which in turn uses SDWebImage, so you need to manually link those libraries if you don't want to use pods and dependency resolver.

score - game score parameter - accepts an object with Serializable annotation; the names of properties should be defined in game dashboard at , the type of each is double

score - game score parameter - accepts an object with Serializable annotation; the names of properties should be defined in game dashboard at , the type of each is double

You can integrate more deeply with escs. Read to know more.

https://client.escs.io
https://client.escs.io
https://github.com/googlesamples/unity-jar-resolver/issues/591
External Dependency Manager for Unity
https://github.com/SDWebImage/SDWebImageWebPCoder
client.escs.io
client.escs.io
optional steps
Asset Store
External Dependency Manager for Unity
GitHub - googlesamples/unity-jar-resolver: Unity plugin which resolves Android & iOS dependencies and performs version managementGitHub
ESCS welcome window
Importing errors that you can safely ignore
Resolving dependencies for Android
Advised android resolver settings
Android define symbols required for video chat and streaming
Logo