Unity
هذه الصفحة مترجمة من الإنجليزية. إذا اختلفت النسختان، فالصفحة الإنجليزية هي الصحيحة. اقرأ الصفحة الإنجليزية
Lingara.Embed حزمة NuGet مبنية فوق نواة اللاعب في Lingara. تحمل المكتبة الأصلية لكل منصة من المنصات الخمس التي تدعمها حِزم اللاعب: Windows وmacOS وLinux وAndroid وiOS.
ثبّت الحزمة
لا يقرأ Unity حِزم NuGet بمفرده، لذا ثبّت NuGetForUnity أولًا. ثم أضِف Lingara.Embed إلى Assets/packages.config، كما هو موضّح أدناه. يستعيد NuGetForUnity الحزمة ويضع المكتبة الأصلية لكل منصة حيث يتوقعها Unity.
المكوّن النموذجي أدناه، LingaraEmbedBehaviour، ليس جزءًا من الحزمة: ضع شيفرته المصدرية في مشروعك، وضعه على GameObject، واستمع إلى أحداث C# الخاصة به. ينشئ العميل عندما يستيقظ، ويتخلّص منه عند تدميره، وعند خروج اللعبة، وقبل أن يعيد المحرّر تحميل سكربتاتك.
احصل على الرموز من خادمك
لا تحتفظ الحزمة بأي سرّ أبدًا. عندما يحتاج العميل إلى رمز، يعلن ذلك بحدث TokenNeeded. يجيب المكوّن عنه بروتين مشترك (coroutine) يرسل طلبًا إلى مسار الرموز في خادمك، الذي يُصدر الرمز باستخدام حزمة خادم ويجيب بالرمز وموعد انتهاء صلاحيته. إذا لم يستطع خادمك الإجابة، فاستدعِ TokenUnavailable حتى تفشل الاستدعاءات المنتظرة لرمز فورًا بدلًا من أن تنتهي مهلتها.
أفرغ الأحداث في Update
تشغّل النواة عمليات الإدخال والإخراج الشبكية على خيطها الخاص. في 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;
}
}
}