XUnity.AutoTranslator لا يترجم
XUnity.AutoTranslator هو أفضل مترجم أثناء التشغيل لدى Unity، وحين يصمت يكون السبب في الغالب واحدًا من خمسة أمور بعينها: اللعبة نسخة IL2CPP، أو النص يُضبط عبر مسار لا يعترضه الخطّاف، أو إطار الواجهة الذي يرسمه غير مفعّل، أو السطر أطول من حدّ الأحرف، أو نقطة النهاية أوقفت نفسها. إليك كيف تعرف أيّها لديك.
XUnity.AutoTranslator مجاني، برخصة MIT، ومصان بنشاط، وهو أفضل أداة ترجمة أثناء التشغيل لدى Unity على الإطلاق. يعمل بربط اللحظة التي تسلّم فيها اللعبة نصًا إلى مكوّن عرض، فيستبدل به ترجمةً قبل رسمه. وهذا التصميم هو سبب استغنائه تمامًا عن أي معرفة بصيغ ملفات اللعبة — وهو أيضًا سبب فشله بصمت حين يفشل. لا شيء ينهار. اللعبة ببساطة تعمل باليابانية.
الأمور الخمسة أدناه تفسّر تقريبًا كل بلاغ من نوع "لا يترجم". راجعها بالترتيب؛ لكل واحد منها إصلاح مختلف، والتخمين بينها يضيّع أمسيات كثيرة.
أولًا: اقرأ السجل، لا الشاشة
الإضافة صريحة جدًا فيما تفعله، والسجل هو المكان الوحيد الذي تقوله فيه. مع تثبيت BepInEx، انظر في BepInEx/LogOutput.log. ويجلس سجل Unity نفسه بجواره في <Game>_Data/output_log.txt على النسخ الأقدم، أو %APPDATA%/../LocalLow/<Company>/<Game>/Player.log على الأحدث.
- هل يذكر السجل تحميل XUnity.AutoTranslator أصلًا؟ إن لم يذكره، فالمشكلة في المُحمِّل لا في المترجم — وأنت عند سبب الفشل الأول.
- هل يذكر تهيئة نقطة نهاية، ثم يسمّي لاحقًا واحدة أُوقفت بعد أخطاء متكرّرة؟ هذا سبب الفشل الخامس.
- هل تُكتب الترجمات في
BepInEx/Translation/<lang>/Text/_AutoGeneratedTranslations.txt؟ إن كان هذا الملف يمتلئ بترجمات صحيحة لا تظهر على الشاشة أبدًا، فالجانب الشبكي سليم وجانب العرض ليس كذلك. - اضغط ALT+1 داخل اللعبة لفتح نافذة تجميع الترجمات. إن أظهرت الأسطر التي تنظر إليها، فالخطّاف يراها. وإن بقيت فارغة، فالخطّاف لا يراها أصلًا.
هذا الفصل الأخير — "مترجَم لكن غير معروض" مقابل "لم يُرَ أصلًا" — هو مفترق الطريق. وكل ما يلي يتفرّع منه.
1. اللعبة نسخة IL2CPP
تشحن Unity الألعاب بزمني تشغيل مختلفين تمامًا. يُبقي Mono شيفرة C# الخاصة باللعبة تجميعات .NET عادية في <Game>_Data/Managed/، ومنها Assembly-CSharp.dll، بأسماء أنواع وتوابع كاملة. أما IL2CPP فيحوّل تلك الشيفرة إلى C++ مسبقًا ويصرّفها في ملف GameAssembly.dll أصلي؛ وما يبقى من نظام الأنواع يُحزَم في <Game>_Data/il2cpp_data/Metadata/global-metadata.dat.
الخطّاف أثناء التشغيل يحتاج إلى إيجاد تابع واستبداله. على Mono هذه مسألة انعكاس عادية. وعلى IL2CPP لا يوجد تابع مُدار لينعكس عليه — الشيفرة أصلية، والطريق الوحيد للعودة إلى الأسماء والحقول وعناوين التوابع هو تحليل global-metadata.dat وإعادة بناء التخطيط. وهذا محمّل مختلف كليًا، لا إعداد.
- كيف تعرف في خمس ثوانٍ: وجود
GameAssembly.dllبجوار ملف اللعبة التنفيذي، مع مجلدil2cpp_data، يعني IL2CPP. ومجلدManaged/مليء بملفات DLL يعني Mono. - يحتاج IL2CPP إلى نسخة BepInEx الخاصة بـ IL2CPP، وإلى إصدار XUnity.AutoTranslator المبني عليها. ونسخة Mono لن تُحمَّل — ببساطة لن تظهر في السجل، وهو ما يبدو تمامًا كأن "الإضافة معطوبة".
- عرض البِت مهم أيضًا. اللعبة ذات 64 بت تحتاج محمّلًا بـ64 بت. والاقتران غير المتطابق يفشل بالصمت نفسه.
- بعض الألعاب تشحن ملف بيانات وصفية غير قابل للتحليل. تشفّر طبقات التغليف ومكافحة العبث ملف
global-metadata.datأو تعيد هيكلته، وكل أداة تعتمد على قراءته — بما فيها الخطّاف — تتوقّف عند هذا الحد.
2. الإضافة تُحمَّل، والنص لا يظهر أبدًا
الإضافة في السجل، ونقطة النهاية مهيّأة، وملف _AutoGeneratedTranslations.txt ينمو — والشاشة كما هي. إمّا أن الخطّاف يترجم نصًا تتخلّص منه اللعبة بعدها، وإمّا أن اللعبة تضبط النص عبر مسار لا يعترضه الخطّاف.
TextGetterCompatibilityMode
كثير من الألعاب تقرأ من جديد النص الذي ضبطته للتوّ — لقياسه، أو للإضافة إليه، أو لمقارنته بشيء ما. وبمجرد أن يحمل المكوّن نصًا مترجمًا، تعيد تلك القراءة الترجمة، فيعمل منطق اللعبة نفسه على نص لم يكتبه، وتتراوح النتيجة بين سطر يعود إلى أصله وتخطيط ينهار. ويجعل TextGetterCompatibilityMode في AutoTranslatorConfig.ini القارئ يعيد إلى اللعبة نصّها الأصلي بينما يظل اللاعب يرى المترجَم. وهو مُطفأ افتراضيًا لأنه يكلّف عملًا عند كل قراءة، وهو أول مفتاح تجرّبه حين يرتجف النص أو يعود إلى أصله أو يرفض الثبات.
والنصف الآخر من هذه الفئة نص لا يُضبط أصلًا عبر واجهة مربوطة: لعبة تعرض عبر محرك نصوص خاص بها، أو تدفع الأحرف مباشرةً داخل مجسّم، أو تخبز الحوار في صورة. ولا يوجد إعداد لذلك — نقطة الاعتراض غير موجودة. أما النص المخبوز داخل الرسومات فمشكلة منفصلة تمامًا، وتحتاج ترجمة الصور لا أي خطّاف.
3. جزء من النص فقط يُترجَم
القوائم تُترجَم والحوار لا. أو الحوار يُترجَم وكل زر يبقى يابانيًا. وهذا في الغالب إطار واجهة غير مفعّل، لأن الإضافة تربط كل إطار على حدة وليست كلها مفعّلة افتراضيًا.
- مفعّل افتراضيًا: UGUI (واجهة Unity المدمجة)، وNGUI، وTextMeshPro، وUIElements (
EnableUGUI،EnableNGUI،EnableTextMeshPro،EnableUIElements). وهي تغطي بينها معظم الألعاب الحديثة، بما فيها أطر الروايات المرئية مثل Utage، إذ ترسم من خلالها بدل أن يكون لها مفتاح خاص بها. - مُطفأ افتراضيًا: IMGUI ومكوّن
TextMeshالقديم. وIMGUI هي واجهة Unity الفورية — تُعاد رسمها في كل إطار، فربطها يعني الترجمة في كل إطار، وهي معطّلة لأجل الأداء لا لأنها لا تعمل. - الأعلام موجودة في `AutoTranslatorConfig.ini` بأسماء
EnableIMGUIوEnableTextMeshوأخواتها. اضبط ما تستخدمه لعبتك علىTrueوأعد التشغيل. - ألعاب Unity الأقدم واليابانية المستقلة هي حالات IMGUI المعتادة. واللعبة التي تبدو قوائمها صناديق رمادية عادية بتنسيق افتراضي إشارة قوية.
وإن لم يغيّر تفعيل كل شيء شيئًا، فالنص لا يمرّ عبر مكوّن نص Unity أصلًا — عد إلى سبب الفشل الثاني.
4. الأسطر الطويلة تُتخطّى، لا تُترجَم
قيمة MaxCharactersPerTranslation الافتراضية 200. وأي سطر أطول يُتخطّى. لا يُقتطع، ولا يُعاد، ولا يُسجَّل بطريقة تلاحظها وأنت تلعب — يُتخطّى، فيُعرض السطر بلغته الأصلية ولا يبدو شيء معطوبًا.
وهذا سبب الفشل الذي يطارده الناس أطول مدة، لأن الدليل عليه ضعيف جدًا: معظم اللعبة يُترجَم، ثم فقرة واحدة لا. والروايات المرئية هي الضحية المعتادة — كتلة سرد طويلة أو مونولوج بلا فاصل أسطر يتجاوز 200 حرف بسهولة، وهو بالضبط النص الذي أردت ترجمته أكثر من غيره.
ارفع القيمة في AutoTranslatorConfig.ini وأعد التشغيل. وتذكّر أنك ترفع أيضًا كلفة كل طلب: لنقاط النهاية المجانية سقوفها الخاصة لطول الطلب الواحد وستبدأ برفض الطلبات التي تتجاوزها منفردة، فالقيمة الكبيرة جدًا تستبدل بالتخطّي الصامت خطأً ظاهرًا في نقطة النهاية. وما بين 500 و1000 يغطّي نثر الروايات المرئية المعتاد.
5. نقطة النهاية فشلت أو حدّت من معدلك
نقاط نهاية XUnity الافتراضية خدمات ترجمة عامة مجانية يُوصَل إليها بالطريقة التي يصل بها المتصفح. وهي ليست تعاقدية، وهي تتغيّر. وحين تفشل سلسلة من الطلبات على التوالي، توقف الإضافة نقطة النهاية لبقية الجلسة بدل الاستمرار في طرقها — وهو قرار متعمّد وصائب، ويعني أيضًا أن كل ما بعد تلك اللحظة يبقى غير مترجم بصمت حتى تعيد تشغيل اللعبة.
- افحص السجل بحثًا عن سطر الإيقاف. إن وجدته، فالإصلاح إعادة تشغيل مع تغيير شيء ما — لا مزيد من الانتظار.
- أبطئ الطابور. وُجد
MaxTranslationsQueuedPerSecondوإعدادات التأخير لأن الدفقات هي ما يُشعل حدود المعدل. والتقديم السريع في رواية مرئية يرسل مئات الطلبات في ثوانٍ. - بدّل نقطة النهاية. إن كانت خدمة مجانية تمرّ بيوم سيئ، فغالبًا الأخرى ليست كذلك.
- استخدم نقطة نهاية بمفتاح. مفتاح DeepL حقيقي أو أي مفتاح واجهة مدفوع يزيل هذه الفئة من المشاكل كلها، بكلفة أنه مفتاح مدفوع.
- حدّث الإضافة. حين يتغيّر بروتوكول خدمة مجانية، يأتي الإصلاح في صورة إصدار جديد. وتشغيل نسخة عمرها سنتان مقابل خدمة تحرّكت سبب شائع لـ"كان يعمل من قبل".
إضافةً إلى ذلك: النص يُترجَم ويُعرض مربّعات
هذه ليست عطلًا في الترجمة أصلًا. شحنت اللعبة أطلس خط يحتوي بالضبط رسوم الحروف التي تحتاجها لغتها الأصلية، ولغتك الهدف تحتاج رسومًا ليست فيه، فيُرسم كل حرف مفقود مربّعًا أو فراغًا. ولدى XUnity الإعدادان OverrideFont وOverrideFontTextMeshPro لهذا تحديدًا. ولاحظ البصمة: المربّعات تعني رسم حرف مفقودًا؛ وعلامات `?` الحرفية تعني مشكلة ترميز في مكان أسبق من السلسلة. إنهما عطلان مختلفان، وإعداد الخط يصلح الأول فقط.
ترتيب المعالجة
- تأكّد من Mono مقابل IL2CPP بالبحث عن
GameAssembly.dll، وتأكّد أنك ثبّت المحمّل المطابق. - افتح
BepInEx/LogOutput.logوتأكّد أن الإضافة حُمِّلت وأن نقطة نهاية هُيّئت. - اضغط ALT+0 داخل اللعبة لفتح نافذة الإضافة نفسها — فإن لم يظهر شيء فالإضافة غير محمّلة. وALT+1 يفتح Translation Aggregator: الفارغ يعني أن الخطّاف لا يرى النص، والممتلئ يعني أنه يراه.
- إن كان الخطّاف يراه ولا تتغيّر الشاشة، فعّل
TextGetterCompatibilityMode. - إن كان جزء من اللعبة فقط يُترجَم، فعّل IMGUI وTextMesh القديم.
- إن بقيت أسطر طويلة بعينها غير مترجمة، ارفع
MaxCharactersPerTranslationعن قيمته الافتراضية 200. - إن توقّف كل شيء في منتصف الجلسة، ابحث عن سطر إيقاف نقطة النهاية، ثم أعد التشغيل بطابور أبطأ أو نقطة نهاية أخرى.
حين يكون الخطّاف الشكل الخطأ للمهمة
كل عطل مما سبق يعود إلى الجذر نفسه: الخطّاف أثناء التشغيل لا يترجم إلا نصًا يكون حاضرًا ليعترضه. فإن لم تضبط اللعبة النص عبر واجهة تعرفها الإضافة، أو رُسم النص قبل تحميل الإضافة، أو لم يُظهر زمن التشغيل التابع القابل للربط، فلا شيء هناك ليُضبط. الأداة تؤدي عملها بشكل صحيح، والنص ببساطة خارج متناولها.
والبديل البنيوي هو العمل على الملفات بدل الإطار. الأداة على مستوى الملفات تفتح أصول اللعبة نفسها، وتسحب النصوص منها، وتترجمها، وتكتب نسخة مترجمة من اللعبة — فيكون النص باللغة الهدف قبل أن يحمّله المحرك أصلًا. لا خطّاف، ولا نقطة اعتراض، ولا علم لكل إطار واجهة، وحدّ الأحرف هو ما تحتمله الصيغة. وهذا ما يفعله RuneTranslate، على Unity و16 محرّكًا وصيغة أخرى.
والمقايضات حقيقية وتسير في الاتجاه الآخر. الأداة على مستوى الملفات لا تصل إلا إلى النص الموجود في الملفات — وفي Unity يعني ذلك TextAssets، وحقول نصوص MonoBehaviour، وسكربتات StreamingAssets، وجداول التوطين وحزم الأصول، بما فيها حزم Addressable المشفّرة بـ AES. وهي تحتاج خطوة تصدير قبل أن تلعب، بدل الترجمة أثناء اللعب. ولا تستطيع فعل شيء حيال نص تولّده لعبتك أثناء التشغيل من أجزاء. وUnity محرك بأفضل جهد ممكن لهذا السبب بالضبط: ما تُخرجه لعبة بعينها يتفاوت كثيرًا، وفتح المشروع هو ما يخبرك بما لديك.
- النص المُصرَّف داخل شيفرة C# هو الحد الصعب. على نسخ Mono يقرأ RuneTranslate النصوص الحرفية من تجميعة اللعبة بمكوّن مرافق مضمّن، محكومًا بما يفعله موضع الاستدعاء بها حتى لا يترجم أبدًا اسم مشهد أو معامل محرّك حركة. أما على نسخ IL2CPP فتبقى الشيفرة المصرَّفة خارج النطاق.
- أما نص أصول IL2CPP فبخير. تُقرأ حقول نصوص المكوّنات على IL2CPP بإعادة بناء معلومات الأنواع من بيانات اللعبة الوصفية — وهو
global-metadata.datنفسه الذي يحتاجه الخطّاف، مستخدَمًا لغرض مختلف. - ويقرأ مخرجات XUnity نفسها. إن كان لديك ملف
_AutoGeneratedTranslations.txtممتلئ بالفعل، فإن RuneTranslate يحلّله ويستطيع ترجمة القيم فيه دون المساس بالمفاتيح. والعمل الذي أنجزته لا يُرمى. - وتُعالَج الخطوط عند التصدير، بحقن أصل خط احتياطي في اللعبة حتى تُعرض لغة هدف لم يغطّها الخط الأصلي قط.
تسعة مزوّدين، ثلاثة منهم لا يحتاجون مفتاح واجهة إطلاقًا — Google، وDeepL المجاني، ونموذجا DeepL الكلاسيكي والجيل التالي — إضافةً إلى واجهة DeepL، وOpenAI، وAnthropic، وDeepSeek، وأي نقطة نهاية متوافقة مع OpenAI، ونموذج محلي عبر Ollama أو LM Studio. وتفتح الفئة المجانية كل محرّك وكل مزوّد؛ وهي تحدّ من الإنتاجية وتحتفظ بمشروع واحد في المرة. تعمل على Windows 10/11، أو على Linux وSteam Deck عبر Wine أو Proton. ويلزم تسجيل دخول مجاني عبر Patreon عند أول تشغيل. والناتج نسخة مترجمة قابلة للعب تحتفظ بها.
ولا أحد النهجين صحيح على الإطلاق. اللعبة التي يجلس سكربتها كله في جدول JSON واحد مضمّن هي مهمة على مستوى الملفات وكانت كذلك دائمًا. واللعبة التي تركّب حوارها في الشيفرة أثناء التشغيل هي مهمة خطّاف وستبقى كذلك. ومعرفة أيّهما بين يديك هي معظم العمل.
إلى أين بعد ذلك
- كيفية ترجمة ألعاب Unity — الشرح الكامل، بما في ذلك ما تُخرجه Unity وما لا تُخرجه.
- صفحة محرك Unity — الصيغ المدعومة والحدود الحالية في مكان واحد.
- RuneTranslate مقابل XUnity.AutoTranslator — النهجان جنبًا إلى جنب، مع الحالات التي يفوز فيها كل منهما.
- اختيار مزوّد ترجمة — أيّ المزوّدين يتعامل جيدًا مع النثر الياباني، وأيّهم بلا كلفة.
- أساسيات المسرد — الحفاظ على اتساق أسماء الشخصيات والمصطلحات عبر سكربت كامل.
- كل المحرّكات المدعومة — إن تبيّن أن اللعبة ليست Unity بعد كل هذا.
مستعد لتجربة RuneTranslate؟
تفتح الباقة المجانية كل محرك + كل مزود ترجمة. باقة Supporter ($3/mo) تفتح السرعة الكاملة.
التنزيل لنظام Windows
