Unity

How to integrate the Unity plugin.

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

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

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.

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

Due to known issue (https://github.com/googlesamples/unity-jar-resolver/issues/591) 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:

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

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

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

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

  • 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 double

  • 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 integrate more deeply with escs. Read optional steps to know more.

Last updated