Last active
January 18, 2021 15:35
-
-
Save YaserAlOsh/48d9e5b1785135df1d4d4264437c8d03 to your computer and use it in GitHub Desktop.
Handling Arabic Text In Unity Using the Arabic Support Plugin - Fixing The Plugin Issues
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//تمت كتابة الملف من قبل الموقع مراحل - لمطوري الألعاب | |
//http://www.devjourney.epizy.com/النصوص-باللغة-العربية-محرك-unity | |
//يمكن استخدامه في أي مشروع من دون ذكر المرجع | |
//ولكن لا يسمح بيعه على حدة | |
//فهو متوفر بشكل مجاني للجميع | |
public static class CustomTextFunctions { | |
public static string FixArabicUITextLines(this Text textUIItem, bool useTashkeel, bool hinduNumbers, string text) | |
{ | |
textUIItem.text = text; | |
TextGenerator textGenerator = GetTextGenerator(textUIItem,text); | |
string reversedText = ""; | |
string tempLine; | |
//حلقة تكرارية بعدد الأسطر الموجودة | |
for (int i = 0; i < textGenerator.lineCount; i++) | |
{ | |
//للأسف، لا يتم توفير نص كل سطر بشكل مباشر | |
//يجب علينا استخراجه بأنفسنا ^_^ | |
//سنحصل على موقع بداية ونهاية كل سطر، ثم نقصه من النص الأصلي | |
//موقع البداية للسطر هو بكل بساطة: | |
int startIndex = textGenerator.lines[i].startCharIdx; | |
//أما موقع النهاية: | |
//إذا لم نصل لآخر سطر بعد | |
int endIndex = i < textGenerator.lines.Count - 1 ? | |
//نحصل على موقع نهاية السطر من موقع بداية السطر اللاحق: | |
textGenerator.lines[i + 1].startCharIdx : | |
//ولكن في السطر الأخير، سنحصل عليه من طول النص كاملاً: | |
textUIItem.text.Length; | |
//نحصل على نص السطر الحالي، وهو معرف بموقعي البداية والنهاية | |
//دالة Substring تقتص جزء من نص | |
//استنادًا إلى موقع البداية والطول | |
tempLine = textUIItem.text.Substring(startIndex, endIndex - startIndex); | |
//نقوم بإصلاح هذا السطر ثم إضافته إلى النص المعكوس النهائي | |
reversedText += ArabicSupport.ArabicFixer.Fix(tempLine, useTashkeel, hinduNumbers).Trim('\n'); | |
reversedText += Environment.NewLine;//نفصل بين كل سطر بمسافة enter | |
} | |
return reversedText; | |
} | |
public static TextGenerator GetTextGenerator(Text textUI,string text) | |
{ | |
textUI.text = text; //تعيين النص للعنصر النصي | |
//تعريف كائن من النوع TextGenerator، الذي سيحتوي على المعلومات | |
TextGenerator textGenerator = new TextGenerator(); | |
//نعرف كائن آخر سيحتوي على أبعاد العنصر text في الواجهة | |
//السبب أن عدد الأسطر الجديدة المطلوبة يعتمد على المساحة المتوفرة | |
TextGenerationSettings generationSettings = textUI.GetGenerationSettings(textUI.rectTransform.rect.size); | |
//نقدم النص والإعدادات لل textGenerator ، | |
// ليقوم بحساب عدد الأسطر وما إلى ذلك، | |
// عن طريق دالة Populate | |
textGenerator.Populate(text, generationSettings); | |
//إرجاع الكائن الذي يحتوي على المعلومات المطلوبة | |
return textGenerator; | |
} | |
public static string FixArabicTMProUGUILines(this TextMeshProUGUI textMesh, bool useTashkeel, bool hinduNumbersوstring text) | |
{ | |
textMesh.text = text; | |
Canvas.ForceUpdateCanvases(); | |
textMesh.text = text; | |
TMP_TextInfo newTextInfo = textMesh.GetTextInfo(text); | |
string reversedText = ""; | |
string tempLine; | |
for (int i = 0; i < newTextInfo.lineCount; i++) | |
{ | |
int startIndex = newTextInfo.lineInfo[i].firstCharacterIndex; | |
tempLine = text.Substring(startIndex, newTextInfo.lineInfo[i].characterCount); | |
reversedText += ArabicSupport.ArabicFixer.Fix(tempLine, useTashkeel, hinduNumbers).Trim('\n'); | |
reversedText += Environment.NewLine; | |
} | |
return reversedText; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using TMPro; | |
using UnityEditor; | |
[RequireComponent(typeof(TextMeshProUGUI))] | |
[ExecuteInEditMode] | |
public class FixArabicTMProUGUI : MonoBehaviour | |
{ | |
[SerializeField] // السماح لتعديل النص من المحرر هنا؟ (أي من القيمة text في الأسقل) | |
bool editTextHere = false; | |
[Multiline(3)]//جعل النص يظهر بأكثر من سطر، يمكن تعديل القيمة لتغيير عدد الأسطر | |
[SerializeField] | |
string customText; | |
[Tooltip("عينها ك true إذا لم ترد التعديل على النص من الملف البرمجي مباشرة(من خاصية ال text في الملف) ")] | |
[SerializeField] | |
bool textAlreadySet = false; | |
[SerializeField] | |
bool updateInRealTime = true; | |
[Tooltip("تحديث نص العنصر فقط بعد أن تم التوقف عن تغيير الخصائص (أفضل للأداء، ولكن قد يجعل الحركات والتأثيرات أبطئ"] | |
[SerializeField] | |
bool updateOnlyOnChange = true; | |
TextMeshProUGUI textMeshPro; | |
[SerializeField] | |
bool useTashkeel = false; | |
[SerializeField] | |
bool useHinduNumbers = false; | |
RectTransform rectTransform; | |
float previousWorldRectWH; | |
string neededText; | |
bool previousFrameNeededEdit = false; | |
string editedText; | |
bool initialized; | |
void Awake(){ | |
rectTransform = GetComponent<RectTransform>(); | |
textMeshPro = GetComponent<TextMeshProUGUI>(); | |
neededText = textMeshPro.text; | |
initialized = true; | |
} | |
void Start() | |
{ | |
if (textAlreadySet) | |
{ | |
rectTransform.hasChanged = false; | |
prevCorrectText = textMeshPro.FixArabicTMProUGUILines(useTashkeel, useHinduNumbers, neededText); | |
textMeshPro.text = prevCorrectText; | |
}else if(editTextHere){ | |
UpdateText(customText); | |
} | |
} | |
void Update() | |
{ | |
if (!updateInRealTime) | |
return; | |
float currentRectArea = rectTransform.rect.height + rectTransform.rect.width; | |
if (previousFrameNeededEdit || (!updateOnlyOnChange)) | |
{ | |
editedText = textMeshPro.FixArabicTMProUGUILines(useTashkeel, useHinduNumbers, neededText); | |
textMeshPro.text = editedText; | |
previousFrameNeededEdit = false; | |
textMeshPro.havePropertiesChanged = false; | |
} | |
else if (updateOnlyOnChange && | |
(textMeshPro.havePropertiesChanged || currentRectArea != previousWorldRectWH)) | |
{ | |
previousFrameNeededEdit = true; | |
} | |
previousWorldRectWH = rectTransform.rect.width + rectTransform.rect.height; | |
} | |
//يجب استخدام هذه الدالة لتغيير النص عند الحاجة | |
public void UpdateText(string text) | |
{ | |
if (!initialized) | |
Awake(); | |
neededText = text; | |
textMeshPro.text = textMeshPro.FixArabicTMProUGUILines(useTashkeel, useHinduNumbers, text); | |
} | |
} | |
#if UNITY_EDITOR | |
[CustomEditor(typeof(FixArabicTMProUGUI))] | |
public class FixArabicTMProUGUIEditor : UnityEditor.Editor | |
{ | |
private string previousText; | |
public override void OnInspectorGUI() | |
{ | |
serializedObject.Update(); | |
DrawDefaultInspector(); | |
FixArabicTMProUGUI myScript = (FixArabicTMProUGUI)target; | |
string currentText = serializedObject.FindProperty("customText").stringValue; | |
if(currentText != previousText) | |
{ | |
myScript.UpdateText(currentText); | |
} | |
previousText = currentText; | |
serializedObject.ApplyModifiedProperties(); | |
} | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.UI; | |
using System; | |
[RequireComponent(typeof(Text))] | |
public class SetArabicFixedText : MonoBehaviour | |
{ | |
[SerializeField] | |
bool useTashkeel; | |
[SerializeField] | |
bool useHinduNumbers; | |
[SerializeField] | |
bool updateOnRealtime = true; | |
private bool hasChangedLastFrame; | |
private float previousWorldRectWH; | |
private string neededText; | |
private RectTransform rectTransform; | |
Text UIText; //نعرف متغير يحمل كائن/عنصر النص | |
void Start() | |
{ | |
UIText = GetComponent<Text>(); | |
rectTransform = GetComponent<RectTransform>(); | |
if (UIText.text != string.Empty) // إذا لم يكن النص فارغًا | |
{ | |
//نعرف متغير نصي، ونعين قيمته عن طريق استدعاء | |
// دالة من الإضافة | |
//هذه الدالة المستدعاة تأخذ النص العربي، | |
// تقوم بإعادة ضبطه ليصبح جاهزًا للعرض، | |
// ثم ترجعه كقيمة نصية | |
neededText = UIText.text; | |
UIText.text = UIText.FixArabicUITextLines(useTashkeel, useHinduNumbers, neededText); | |
} | |
//نجمع طول وعرض عنصر النص ونحفظهم في المتغير.. | |
//لنستطيع بعد ذلك ملاحظة التغيير في الأبعاد. | |
previousWorldRectWH = rectTransform.rect.width + rectTransform.rect.height; | |
} | |
void Update() | |
{ | |
if (!updateOnRealtime) | |
return; | |
//نحسب مجموع طول وعرض عنصر النص في كل إطار Frame | |
float currentRectWH = rectTransform.rect.width + rectTransform.rect.height; | |
//إذا حصل تغيير في الأبعاد في الإطار السابق، ولكن لم يحصل أي تغيير بين الإطار السابق والإطار الحالي: | |
if (hasChangedLastFrame && previousWorldRectWH == currentRectWH) { | |
//نقوم بإعادة ترتيب النص | |
UIText.text = UIText.FixArabicUITextLines(useTashkeel, useHinduNumbers, neededText); | |
} | |
hasChangedLastFrame = currentRectWH != previousWorldRectWH; | |
previousWorldRectWH = rectTransform.rect.width + rectTransform.rect.height; | |
} | |
//يجب استخدام هذه الدالة لتغيير النص عند الحاجة | |
public void UpdateText(string text) | |
{ | |
neededText = text; | |
UIText.text = UIText.FixArabicUITextLines(useTashkeel, useHinduNumbers, text); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment