Lingara Lingara 說明文件 學習指南 API 程式庫 App 建立 嵌入 網頁版
語言: 粵語

Unity

呢頁係由英文翻譯過嚟嘅。如果兩個版本有出入,以英文頁為準。 睇英文頁

Lingara.Embed 係一個建基於 Lingara 玩家核心嘅 NuGet 套件。佢為玩家套件支援嘅五個平台分別附帶原生程式庫:Windows、macOS、Linux、Android 同 iOS。

安裝 NuGet 套件

Unity 本身唔會讀取 NuGet 套件,所以要先安裝 NuGetForUnity。然後照下面咁,將 Lingara.Embed 加入 Assets/packages.config。NuGetForUnity 會還原嗰個套件,並將每個平台嘅原生程式庫放喺 Unity 預期嘅位置。

下面嘅範例元件 LingaraEmbedBehaviour 唔屬於嗰個套件:將佢嘅原始碼放入你個專案,掛喺一個 GameObject 上面,然後監聽佢嘅 C# 事件。佢喺喚醒嗰陣建立用戶端,喺被銷毀嗰陣、遊戲結束嗰陣,同埋編輯器重新載入你嘅指令碼之前釋放用戶端。

由你部伺服器攞權杖

呢個套件永遠唔會持有密鑰。用戶端需要權杖嗰陣,會用一個 TokenNeeded 事件話你知。元件用一個協同程式回應佢,呢個協同程式會向你自己部伺服器嘅權杖路由傳送 POST 請求,伺服器用伺服器套件簽發權杖,再回覆權杖同佢嘅到期時間。如果你部伺服器回應唔到,就呼叫 TokenUnavailable,等緊權杖嘅呼叫就會即刻失敗,而唔係等到逾時。

喺 Update 入面清空事件

核心喺佢自己嘅執行緒上面做網絡 I/O。喺 Update 入面,元件會清空由上一個畫格到而家送到嘅嘢,每個畫格最多 256 個事件,然後逐個分派:權杖請求、串流嘅 NPC 回覆(睇 NPC 對話)、練習更新(睇練習結果)、關於玩家嘅事件,或者失敗。

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;
        }
    }
}