Lingara Lingara Docs Guides API Libraries Apps Build Embed Web app
Language: English

Unity

Lingara.Embed is a NuGet package over Lingara’s player core. It carries the native library for each of the five platforms the player kits support: Windows, macOS, Linux, Android and iOS.

Install the package

Unity does not read NuGet packages on its own, so install NuGetForUnity first. Then add Lingara.Embed to Assets/packages.config, as below. NuGetForUnity restores the package and places each platform’s native library where Unity expects it.

The sample component below, LingaraEmbedBehaviour, is not part of the package: drop its source into your project, put it on a GameObject, and listen to its C# events. It creates the client when it wakes and disposes of it when it is destroyed, when the game quits, and before the editor reloads your scripts.

Get tokens from your server

The package never holds a secret. When the client needs a token, it says so with a TokenNeeded event. The component answers it with a coroutine that posts to your own server’s token route, which mints with a server kit and answers with the token and its expiry. If your server cannot answer, call TokenUnavailable so the calls waiting on a token fail at once instead of timing out.

Drain events in Update

The core runs its network I/O on its own thread. In Update, the component drains what arrived since the last frame, at most 256 events a frame, and dispatches each one: a token request, a streamed NPC reply (see NPC dialogue), a practice update (see practice results), an event about the player, or a failure.

Unity

<?xml version="1.0" encoding="utf-8"?>
<!-- Assets/packages.config, after installing NuGetForUnity: it restores Lingara.Embed and places each platform's native library. -->
<packages>
  <package id="Lingara.Embed" version="0.1.0-alpha.6" manuallyInstalled="true" />
</packages>

Unity

[Serializable]
private struct Handoff { public string token; public string expires_at; }

// Your own server mints the token: never put a client secret in a game.
private IEnumerator FetchToken()
{
    using (var request = UnityWebRequest.PostWwwForm(tokenUrl, string.Empty))
    {
        yield return request.SendWebRequest();
        if (Client == null) yield break;
        if (request.result != UnityWebRequest.Result.Success)
        {
            Client.TokenUnavailable(request.error); // fail the waiting calls now
            yield break;
        }
        var handoff = JsonUtility.FromJson<Handoff>(request.downloadHandler.text);
        Client.ProvideToken(handoff.token, handoff.expires_at);
    }
}

Unity

private void Update()
{
    if (Client == null) return;
    events.Clear();
    Client.Drain(events); // at most 256 a frame; the rest wait for the next
    foreach (var e in events)
    {
        switch (e)
        {
            case EmbedEvent.TokenNeeded _: StartCoroutine(FetchToken()); break;
            case EmbedEvent.NpcTurn turn: NpcTurn?.Invoke(turn); break;
            case EmbedEvent.Practice practice: Practice?.Invoke(practice); break;
            case EmbedEvent.LingaraReceived received: LingaraReceived?.Invoke(received); break;
            case EmbedEvent.Failed failed: Failed?.Invoke(failed); break;
            case EmbedEvent.Log log: Debug.Log($"[lingara] {log.Level} {log.Target}: {log.Message}"); break;
        }
    }
}