Commit b1931ecf authored by Abdulrahman Mohammed's avatar Abdulrahman Mohammed

Done with all tags system & score Incorrect & etc...

parent 32ad6014
fileFormatVersion: 2
guid: 8bdd24772367c4eab9095baa28f7f53d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 636b6cb26ff364cae97fed5c404063a5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace ALArcade.ArabicTMP
{
/// <summary>
/// Static class providing character sets for Arabic font creation
/// </summary>
public static class ArabicCharsets
{
/// <summary>
/// Returns the complete Arabic character set for font asset creation
/// </summary>
public static string GetCompleteArabicCharset()
{
return
"0600-06FF\n" + // Arabic Basic
"0750-077F\n" + // Arabic Supplement
"08A0-08FF\n" + // Arabic Extended-A
"FB50-FDFF\n" + // Arabic Presentation Forms-A
"FE70-FEFF\n" + // Arabic Presentation Forms-B
"0020-007F\n"; // Basic Latin for mixed text
}
/// <summary>
/// Returns the basic Arabic character set for font asset creation (less comprehensive)
/// </summary>
public static string GetBasicArabicCharset()
{
return
"0600-06FF\n" + // Arabic Basic
"FE70-FEFF\n" + // Arabic Presentation Forms-B
"0020-007F\n"; // Basic Latin for mixed text
}
/// <summary>
/// Returns the essential Persian characters (چ پ ژ گ) to add to an Arabic font
/// </summary>
public static string GetPersianCharset()
{
return "067E, 0686, 0698, 06AF\n"; // Persian letters پ چ ژ گ
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 33cf026253e634291b2071b76a8e3e63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
namespace ALArcade.ArabicTMP
{
/// <summary>
/// AL-Arcade Ultimate Arabic Support for Unity TextMeshPro
/// FINAL VERSION - All issues fixed
/// </summary>
public static class ArabicSupport
{
#region Unicode Ranges
// Arabic Unicode blocks
private const int ARABIC_BASIC_START = 0x0600;
private const int ARABIC_BASIC_END = 0x06FF;
private const int ARABIC_SUPPLEMENT_START = 0x0750;
private const int ARABIC_SUPPLEMENT_END = 0x077F;
private const int ARABIC_EXTENDED_A_START = 0x08A0;
private const int ARABIC_EXTENDED_A_END = 0x08FF;
private const int ARABIC_PRESENTATION_A_START = 0xFB50;
private const int ARABIC_PRESENTATION_A_END = 0xFDFF;
private const int ARABIC_PRESENTATION_B_START = 0xFE70;
private const int ARABIC_PRESENTATION_B_END = 0xFEFF;
// Special control characters
private const char ZWJ = (char)0x200D;
private const char ZWNJ = (char)0x200C;
private const char RLM = (char)0x200F;
private const char LRM = (char)0x200E;
private const char ALM = (char)0x061C;
#endregion
#region Enums
private enum LetterForm
{
Isolated = 0,
Initial = 1,
Medial = 2,
Final = 3
}
private enum ConnectionType
{
None,
Right,
Dual,
Transparent
}
private enum TextDirection
{
LTR,
RTL,
Neutral
}
#endregion
#region Character Mappings
private static readonly Dictionary<char, char[]> ArabicGlyphMap = new Dictionary<char, char[]>() {
// Basic Arabic Letters
{ 'ا', new char[] { 'ا', 'ا', '\uFE8E', '\uFE8E' } },
{ 'ب', new char[] { 'ب', '\uFE91', '\uFE92', '\uFE90' } },
{ 'ت', new char[] { 'ت', '\uFE97', '\uFE98', '\uFE96' } },
{ 'ث', new char[] { 'ث', '\uFE9B', '\uFE9C', '\uFE9A' } },
{ 'ج', new char[] { 'ج', '\uFE9F', '\uFEA0', '\uFE9E' } },
{ 'ح', new char[] { 'ح', '\uFEA3', '\uFEA4', '\uFEA2' } },
{ 'خ', new char[] { 'خ', '\uFEA7', '\uFEA8', '\uFEA6' } },
{ 'د', new char[] { 'د', 'د', '\uFEAA', '\uFEAA' } },
{ 'ذ', new char[] { 'ذ', 'ذ', '\uFEAC', '\uFEAC' } },
{ 'ر', new char[] { 'ر', 'ر', '\uFEAE', '\uFEAE' } },
{ 'ز', new char[] { 'ز', 'ز', '\uFEB0', '\uFEB0' } },
{ 'س', new char[] { 'س', '\uFEB3', '\uFEB4', '\uFEB2' } },
{ 'ش', new char[] { 'ش', '\uFEB7', '\uFEB8', '\uFEB6' } },
{ 'ص', new char[] { 'ص', '\uFEBB', '\uFEBC', '\uFEBA' } },
{ 'ض', new char[] { 'ض', '\uFEBF', '\uFEC0', '\uFEBE' } },
{ 'ط', new char[] { 'ط', '\uFEC3', '\uFEC4', '\uFEC2' } },
{ 'ظ', new char[] { 'ظ', '\uFEC7', '\uFEC8', '\uFEC6' } },
{ 'ع', new char[] { 'ع', '\uFECB', '\uFECC', '\uFECA' } },
{ 'غ', new char[] { 'غ', '\uFECF', '\uFED0', '\uFECE' } },
{ 'ف', new char[] { 'ف', '\uFED3', '\uFED4', '\uFED2' } },
{ 'ق', new char[] { 'ق', '\uFED7', '\uFED8', '\uFED6' } },
{ 'ك', new char[] { 'ك', '\uFEDB', '\uFEDC', '\uFEDA' } },
{ 'ل', new char[] { 'ل', '\uFEDF', '\uFEE0', '\uFEDE' } },
{ 'م', new char[] { 'م', '\uFEE3', '\uFEE4', '\uFEE2' } },
{ 'ن', new char[] { 'ن', '\uFEE7', '\uFEE8', '\uFEE6' } },
{ 'ه', new char[] { 'ه', '\uFEEB', '\uFEEC', '\uFEEA' } },
{ 'و', new char[] { 'و', 'و', '\uFEEE', '\uFEEE' } },
{ 'ي', new char[] { 'ي', '\uFEF3', '\uFEF4', '\uFEF2' } },
{ 'ى', new char[] { 'ى', 'ى', '\uFEF0', '\uFEF0' } },
{ 'ة', new char[] { 'ة', 'ة', '\uFE94', '\uFE94' } },
{ 'ء', new char[] { 'ء', 'ء', 'ء', 'ء' } },
// Alef variants
{ 'آ', new char[] { 'آ', 'آ', '\uFE82', '\uFE82' } },
{ 'أ', new char[] { 'أ', 'أ', '\uFE84', '\uFE84' } },
{ 'إ', new char[] { 'إ', 'إ', '\uFE88', '\uFE88' } },
{ 'ؤ', new char[] { 'ؤ', 'ؤ', '\uFE86', '\uFE86' } },
{ 'ئ', new char[] { 'ئ', '\uFE8B', '\uFE8C', '\uFE8A' } },
// Persian/Urdu letters
{ 'پ', new char[] { 'پ', '\uFB58', '\uFB59', '\uFB57' } },
{ 'چ', new char[] { 'چ', '\uFB7C', '\uFB7D', '\uFB7B' } },
{ 'ژ', new char[] { 'ژ', 'ژ', '\uFB8B', '\uFB8B' } },
{ 'گ', new char[] { 'گ', '\uFB94', '\uFB95', '\uFB93' } },
{ 'ک', new char[] { 'ک', '\uFB90', '\uFB91', '\uFB8F' } },
{ 'ی', new char[] { 'ی', '\uFBFE', '\uFBFF', '\uFBFD' } }
};
private static readonly Dictionary<string, char[]> LamAlefLigatures = new Dictionary<string, char[]>() {
{ "لا", new char[] { '\uFEFB', '\uFEFC' } },
{ "لأ", new char[] { '\uFEF7', '\uFEF8' } },
{ "لإ", new char[] { '\uFEF9', '\uFEFA' } },
{ "لآ", new char[] { '\uFEF5', '\uFEF6' } }
};
// FIXED: Lam-Alef ligatures also don't connect forward
private static readonly HashSet<char> RightConnectingOnly = new HashSet<char> {
'ا', 'آ', 'أ', 'إ', 'ى', // Alef family
'د', 'ذ', // Dal family
'ر', 'ز', 'ژ', // Reh family
'و', 'ؤ', // Waw family
'ة', // Teh Marbuta
'ء', // Hamza
// CRITICAL FIX: Add Lam-Alef ligatures
'\uFEFB', '\uFEFC', // لا ligatures
'\uFEF7', '\uFEF8', // لأ ligatures
'\uFEF9', '\uFEFA', // لإ ligatures
'\uFEF5', '\uFEF6' // لآ ligatures
};
private static readonly HashSet<char> Diacritics = new HashSet<char> {
'\u064B', '\u064C', '\u064D', '\u064E', '\u064F', '\u0650', '\u0651', '\u0652',
'\u0653', '\u0654', '\u0655', '\u0656', '\u0657', '\u0658', '\u0659', '\u065A',
'\u065B', '\u065C', '\u065D', '\u065E', '\u065F', '\u0670'
};
#endregion
#region Public API
public static string Fix(string originalText, bool showTashkeel = true, bool preserveNumbers = true,
bool fixTags = true, bool forceRTL = true)
{
if (string.IsNullOrEmpty(originalText))
{
return originalText;
}
try
{
List<TagInfo> tags = new List<TagInfo>();
string textWithoutTags = originalText;
if (fixTags)
{
textWithoutTags = ExtractTMPTags(originalText, tags);
}
bool containsArabic = ContainsArabicCharacters(textWithoutTags);
if (!containsArabic && !forceRTL)
{
return originalText;
}
string processedText = ProcessArabicText(textWithoutTags, showTashkeel, preserveNumbers, forceRTL);
if (fixTags && tags.Count > 0)
{
processedText = ReinsertTMPTags(processedText, tags);
}
return processedText;
}
catch (Exception ex)
{
Debug.LogError($"[AL-Arcade Arabic] Error processing text: {ex.Message}");
return originalText;
}
}
public static void LogFontRecommendations()
{
Debug.Log("[AL-Arcade Arabic] 🎯 RECOMMENDED ARABIC FONTS FOR UNITY:\n" +
"✅ Noto Sans Arabic (Google Fonts - Free & Excellent)\n" +
"✅ Amiri (Free - Perfect for traditional Arabic)\n" +
"✅ Cairo (Google Fonts - Modern & Clean)\n" +
"✅ Almarai (Google Fonts - Great for UI)\n" +
"Download from: fonts.google.com");
}
#endregion
#region Core Processing
private static string ProcessArabicText(string text, bool showTashkeel, bool preserveNumbers, bool forceRTL)
{
if (string.IsNullOrEmpty(text)) return text;
List<CharInfo> chars = AnalyzeCharacters(text);
if (!showTashkeel)
{
chars.RemoveAll(c => c.IsDiacritic);
}
if (!preserveNumbers)
{
ConvertToArabicNumerals(chars);
}
ProcessLamAlefLigatures(chars);
ApplyArabicShaping(chars);
string result = HandleBidirectionalText(chars, forceRTL);
return result;
}
private static List<CharInfo> AnalyzeCharacters(string text)
{
List<CharInfo> chars = new List<CharInfo>(text.Length);
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
CharInfo charInfo = new CharInfo
{
OriginalChar = c,
ProcessedChar = c,
IsArabic = IsArabicChar(c),
IsDiacritic = IsDiacritic(c),
IsLatin = IsLatinChar(c),
IsDigit = char.IsDigit(c),
IsWhitespace = char.IsWhiteSpace(c),
IsPunctuation = char.IsPunctuation(c),
ConnectionType = GetConnectionType(c),
Direction = GetCharDirection(c)
};
chars.Add(charInfo);
}
return chars;
}
private static void ProcessLamAlefLigatures(List<CharInfo> chars)
{
for (int i = 0; i < chars.Count - 1; i++)
{
if (chars[i].OriginalChar == 'ل')
{
int alefIndex = FindNextNonDiacriticIndex(chars, i);
if (alefIndex != -1)
{
char alefChar = chars[alefIndex].OriginalChar;
string lamAlefKey = "ل" + alefChar;
if (LamAlefLigatures.ContainsKey(lamAlefKey))
{
bool isConnectedToPrevious = CanConnectToPrevious(chars, i);
char ligature = LamAlefLigatures[lamAlefKey][isConnectedToPrevious ? 1 : 0];
chars[i].ProcessedChar = ligature;
chars[i].IsLigature = true;
// CRITICAL FIX: Mark ligature as right-connecting only
chars[i].ConnectionType = ConnectionType.Right;
chars[alefIndex].ShouldRemove = true;
}
}
}
}
chars.RemoveAll(c => c.ShouldRemove);
}
private static void ApplyArabicShaping(List<CharInfo> chars)
{
for (int i = 0; i < chars.Count; i++)
{
CharInfo charInfo = chars[i];
if (!charInfo.IsArabic || charInfo.IsDiacritic || charInfo.IsLigature)
{
continue;
}
char baseChar = charInfo.OriginalChar;
if (ArabicGlyphMap.ContainsKey(baseChar))
{
LetterForm form = DetermineLetterForm(chars, i);
charInfo.ProcessedChar = ArabicGlyphMap[baseChar][(int)form];
}
}
}
// COMPLETELY FIXED: Bidirectional text handling
private static string HandleBidirectionalText(List<CharInfo> chars, bool forceRTL)
{
if (chars.Count == 0) return "";
List<TextRun> runs = CreateDirectionalRuns(chars);
bool isOverallRTL = forceRTL || IsPrimarilyArabic(chars);
StringBuilder result = new StringBuilder();
if (isOverallRTL)
{
// RTL Context: Reverse run order, but NEVER reverse English internally
for (int i = runs.Count - 1; i >= 0; i--)
{
TextRun run = runs[i];
if (run.IsRTL)
{
// Arabic: Keep in logical order (already shaped correctly)
foreach (var charInfo in run.Characters)
{
result.Append(charInfo.ProcessedChar);
}
}
else
{
// CRITICAL FIX: English in RTL context - NEVER reverse
foreach (var charInfo in run.Characters)
{
result.Append(charInfo.ProcessedChar);
}
}
}
}
else
{
// LTR Context
foreach (var run in runs)
{
if (run.IsRTL)
{
// Arabic in LTR context - reverse
for (int i = run.Characters.Count - 1; i >= 0; i--)
{
result.Append(run.Characters[i].ProcessedChar);
}
}
else
{
// English in LTR context - keep normal
foreach (var charInfo in run.Characters)
{
result.Append(charInfo.ProcessedChar);
}
}
}
}
return result.ToString();
}
// IMPROVED: Better run creation
private static List<TextRun> CreateDirectionalRuns(List<CharInfo> chars)
{
List<TextRun> runs = new List<TextRun>();
if (chars.Count == 0) return runs;
TextRun currentRun = null;
for (int i = 0; i < chars.Count; i++)
{
CharInfo charInfo = chars[i];
bool isRTL = charInfo.Direction == TextDirection.RTL;
bool isLTR = charInfo.Direction == TextDirection.LTR;
bool isNeutral = charInfo.Direction == TextDirection.Neutral;
if (currentRun == null)
{
currentRun = new TextRun
{
IsRTL = isRTL,
Characters = new List<CharInfo> { charInfo }
};
}
else if (isNeutral)
{
// Neutral characters join current run
currentRun.Characters.Add(charInfo);
}
else if (isRTL == currentRun.IsRTL)
{
// Same direction
currentRun.Characters.Add(charInfo);
}
else
{
// Direction change
runs.Add(currentRun);
currentRun = new TextRun
{
IsRTL = isRTL,
Characters = new List<CharInfo> { charInfo }
};
}
}
if (currentRun != null)
{
runs.Add(currentRun);
}
return runs;
}
#endregion
#region Helper Methods
private static LetterForm DetermineLetterForm(List<CharInfo> chars, int index)
{
bool canConnectToPrevious = CanConnectToPrevious(chars, index);
bool canConnectToNext = CanConnectToNext(chars, index);
if (canConnectToPrevious && canConnectToNext)
{
return LetterForm.Medial;
}
else if (canConnectToPrevious)
{
return LetterForm.Final;
}
else if (canConnectToNext)
{
return LetterForm.Initial;
}
else
{
return LetterForm.Isolated;
}
}
private static bool CanConnectToPrevious(List<CharInfo> chars, int index)
{
if (index <= 0) return false;
for (int i = index - 1; i >= 0; i--)
{
if (chars[i].IsDiacritic) continue;
// Check original character AND processed character for right-connecting-only
bool isRightConnectingOnly = RightConnectingOnly.Contains(chars[i].OriginalChar) ||
RightConnectingOnly.Contains(chars[i].ProcessedChar);
return chars[i].IsArabic &&
chars[i].ConnectionType != ConnectionType.None &&
!isRightConnectingOnly;
}
return false;
}
private static bool CanConnectToNext(List<CharInfo> chars, int index)
{
if (index >= chars.Count - 1) return false;
// CRITICAL FIX: Check both original and processed character
bool isRightConnectingOnly = RightConnectingOnly.Contains(chars[index].OriginalChar) ||
RightConnectingOnly.Contains(chars[index].ProcessedChar);
if (isRightConnectingOnly)
{
return false;
}
for (int i = index + 1; i < chars.Count; i++)
{
if (chars[i].IsDiacritic) continue;
return chars[i].IsArabic && chars[i].ConnectionType != ConnectionType.None;
}
return false;
}
private static int FindNextNonDiacriticIndex(List<CharInfo> chars, int startIndex)
{
for (int i = startIndex + 1; i < chars.Count; i++)
{
if (!chars[i].IsDiacritic)
{
return i;
}
}
return -1;
}
private static ConnectionType GetConnectionType(char c)
{
if (IsDiacritic(c)) return ConnectionType.Transparent;
if (!IsArabicChar(c)) return ConnectionType.None;
if (c == 'ء') return ConnectionType.None;
if (RightConnectingOnly.Contains(c)) return ConnectionType.Right;
return ConnectionType.Dual;
}
private static TextDirection GetCharDirection(char c)
{
if (IsArabicChar(c)) return TextDirection.RTL;
if (IsLatinChar(c)) return TextDirection.LTR;
return TextDirection.Neutral;
}
private static bool IsPrimarilyArabic(List<CharInfo> chars)
{
int arabicCount = 0;
int totalCount = 0;
foreach (var c in chars)
{
if (!c.IsWhitespace && !c.IsDiacritic)
{
totalCount++;
if (c.IsArabic) arabicCount++;
}
}
return totalCount > 0 && (arabicCount * 2 > totalCount);
}
private static void ConvertToArabicNumerals(List<CharInfo> chars)
{
char[] westernNumerals = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
char[] arabicNumerals = { '٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩' };
for (int i = 0; i < chars.Count; i++)
{
if (chars[i].IsDigit)
{
for (int j = 0; j < westernNumerals.Length; j++)
{
if (chars[i].OriginalChar == westernNumerals[j])
{
chars[i].ProcessedChar = arabicNumerals[j];
break;
}
}
}
}
}
#endregion
#region Character Classification
private static bool ContainsArabicCharacters(string text)
{
foreach (char c in text)
{
if (IsArabicChar(c)) return true;
}
return false;
}
private static bool IsArabicChar(char c)
{
int code = (int)c;
return (code >= ARABIC_BASIC_START && code <= ARABIC_BASIC_END) ||
(code >= ARABIC_SUPPLEMENT_START && code <= ARABIC_SUPPLEMENT_END) ||
(code >= ARABIC_EXTENDED_A_START && code <= ARABIC_EXTENDED_A_END) ||
(code >= ARABIC_PRESENTATION_A_START && code <= ARABIC_PRESENTATION_A_END) ||
(code >= ARABIC_PRESENTATION_B_START && code <= ARABIC_PRESENTATION_B_END);
}
private static bool IsLatinChar(char c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
private static bool IsDiacritic(char c)
{
return Diacritics.Contains(c);
}
#endregion
#region TextMeshPro Tag Handling
private static string ExtractTMPTags(string text, List<TagInfo> tags)
{
StringBuilder result = new StringBuilder();
bool inTag = false;
StringBuilder tagBuilder = new StringBuilder();
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
if (c == '<' && !inTag)
{
inTag = true;
tagBuilder.Clear();
tagBuilder.Append(c);
continue;
}
if (inTag)
{
tagBuilder.Append(c);
if (c == '>')
{
inTag = false;
tags.Add(new TagInfo
{
Tag = tagBuilder.ToString(),
Position = result.Length
});
}
continue;
}
result.Append(c);
}
if (inTag)
{
result.Append(tagBuilder);
}
return result.ToString();
}
private static string ReinsertTMPTags(string text, List<TagInfo> tags)
{
if (tags.Count == 0) return text;
StringBuilder result = new StringBuilder(text);
for (int i = tags.Count - 1; i >= 0; i--)
{
int pos = Math.Min(tags[i].Position, result.Length);
result.Insert(pos, tags[i].Tag);
}
return result.ToString();
}
#endregion
#region Data Classes
private class CharInfo
{
public char OriginalChar;
public char ProcessedChar;
public bool IsArabic;
public bool IsDiacritic;
public bool IsLatin;
public bool IsDigit;
public bool IsWhitespace;
public bool IsPunctuation;
public bool IsLigature;
public bool ShouldRemove;
public ConnectionType ConnectionType;
public TextDirection Direction;
}
private class TextRun
{
public bool IsRTL;
public List<CharInfo> Characters = new List<CharInfo>();
}
private class TagInfo
{
public string Tag;
public int Position;
}
#endregion
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: c717d64c270b1469f9b32a6110e7eb26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
namespace ALArcade.ArabicTMP
{
[AddComponentMenu("UI/Arabic TextMeshPro - Input Field", 12)]
public class ArabicTMPInputField : TMP_InputField
{
[SerializeField] private bool m_ShowTashkeel = true;
[SerializeField] private bool m_PreserveNumbers = true;
[SerializeField] private bool m_FixTags = true;
[SerializeField] private bool m_ForceRTL = true; // FIXED: Default to true for better Arabic support
private string m_OriginalText = "";
private bool m_ProcessingInternalChange = false;
// Shadow the base .text property
public new string text
{
get => m_OriginalText;
set
{
if (m_OriginalText == value)
return;
m_OriginalText = value;
m_ProcessingInternalChange = true;
var processed = ArabicSupport.Fix(value, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
base.SetTextWithoutNotify(processed);
m_ProcessingInternalChange = false;
}
}
protected override void Awake()
{
base.Awake();
if (textComponent != null)
{
// FIXED: Ensure text component is properly set up for RTL
textComponent.isRightToLeftText = true;
textComponent.alignment = TextAlignmentOptions.Right;
}
// Ensure text viewport has correct layout for RTL
if (textViewport != null)
{
// Adjust padding to make sure text appears correctly aligned
textComponent.margin = new Vector4(0, 0, 5, 0); // Add right margin for RTL text
}
}
protected override void Start()
{
base.Start();
onValueChanged.AddListener(OnValueChangedHandler);
if (!string.IsNullOrEmpty(m_OriginalText))
text = m_OriginalText;
}
private void OnValueChangedHandler(string value)
{
// Only update our stored original if this wasn't triggered by our own setText
if (!m_ProcessingInternalChange)
{
m_OriginalText = value;
}
}
public override void OnSelect(BaseEventData eventData)
{
base.OnSelect(eventData);
// When selected, ensure caretPosition is at the proper end for RTL
if (caretPosition == 0 && m_OriginalText.Length > 0)
{
caretPosition = 0; // For RTL, visual position 0 is at the right side
}
}
public override void OnDeselect(BaseEventData eventData)
{
base.OnDeselect(eventData);
// Ensure text is properly formatted on deselection
text = m_OriginalText;
}
// Override LateUpdate to re-process text before each frame render
protected override void LateUpdate()
{
base.LateUpdate();
// Apply Arabic shaping if the text changed and we're not in the middle of our own change
if (!m_ProcessingInternalChange)
{
var processed = ArabicSupport.Fix(m_OriginalText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
if (base.text != processed)
{
m_ProcessingInternalChange = true;
base.SetTextWithoutNotify(processed);
m_ProcessingInternalChange = false;
}
}
}
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
if (!string.IsNullOrEmpty(m_OriginalText))
{
m_ProcessingInternalChange = true;
var processed = ArabicSupport.Fix(m_OriginalText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
base.SetTextWithoutNotify(processed);
m_ProcessingInternalChange = false;
}
if (textComponent != null)
{
textComponent.isRightToLeftText = true;
textComponent.alignment = TextAlignmentOptions.Right;
}
}
#endif
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 31f53d7c2368d4ca298130e8d6951abb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using TMPro;
using UnityEngine;
namespace ALArcade.ArabicTMP
{
/// <summary>
/// Arabic-enabled TextMeshPro component for 3D/World space
/// </summary>
[AddComponentMenu("Text/Arabic TextMeshPro - Text", 10)]
public class ArabicTextMeshPro : TextMeshPro
{
// Original (editable) Arabic text
[SerializeField] private string m_ArabicText;
// Plugin options
[Tooltip("Show Arabic diacritics (tashkeel)")]
[SerializeField] private bool m_ShowTashkeel = true;
[Tooltip("Keep Western digits (123) as-is instead of converting to Eastern Arabic")]
[SerializeField] private bool m_PreserveNumbers = true;
[Tooltip("Process rich text tags (color, bold, etc.)")]
[SerializeField] private bool m_FixTags = true;
[Tooltip("Force RTL even if text starts with Latin letters")]
[SerializeField] private bool m_ForceRTL = true; // FIXED: Default to true for better Arabic support
/// <summary>
/// The original Arabic text (not fixed for rendering)
/// </summary>
public string arabicText
{
get { return m_ArabicText; }
set
{
if (m_ArabicText == value)
return;
m_ArabicText = value;
// Apply Arabic text processing and update TMP text
text = ArabicSupport.Fix(m_ArabicText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
}
}
/// <summary>
/// Show or hide Arabic diacritics (tashkeel)
/// </summary>
public bool showTashkeel
{
get { return m_ShowTashkeel; }
set
{
if (m_ShowTashkeel == value)
return;
m_ShowTashkeel = value;
// Re-process text with new setting
if (!string.IsNullOrEmpty(m_ArabicText))
text = ArabicSupport.Fix(m_ArabicText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
}
}
/// <summary>
/// Preserve Western digits (123) as-is
/// </summary>
public bool preserveNumbers
{
get { return m_PreserveNumbers; }
set
{
if (m_PreserveNumbers == value)
return;
m_PreserveNumbers = value;
// Re-process text with new setting
if (!string.IsNullOrEmpty(m_ArabicText))
text = ArabicSupport.Fix(m_ArabicText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
}
}
/// <summary>
/// Process rich text tags (color, bold, etc.)
/// </summary>
public bool fixTags
{
get { return m_FixTags; }
set
{
if (m_FixTags == value)
return;
m_FixTags = value;
// Re-process text with new setting
if (!string.IsNullOrEmpty(m_ArabicText))
text = ArabicSupport.Fix(m_ArabicText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
}
}
/// <summary>
/// Force RTL even if text starts with Latin letters
/// </summary>
public bool forceRTL
{
get { return m_ForceRTL; }
set
{
if (m_ForceRTL == value)
return;
m_ForceRTL = value;
// Re-process text with new setting
if (!string.IsNullOrEmpty(m_ArabicText))
text = ArabicSupport.Fix(m_ArabicText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
}
}
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
// Update displayed text whenever properties change in the editor
if (!string.IsNullOrEmpty(m_ArabicText))
{
text = ArabicSupport.Fix(m_ArabicText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
}
// Set alignment to right by default for Arabic text
if (alignment == TextAlignmentOptions.TopLeft ||
alignment == TextAlignmentOptions.Left ||
alignment == TextAlignmentOptions.BottomLeft)
{
alignment = TextAlignmentOptions.Right;
}
}
#endif
protected override void Awake()
{
base.Awake();
// Initialize with proper alignment for RTL text
if (alignment == TextAlignmentOptions.TopLeft)
alignment = TextAlignmentOptions.TopRight;
else if (alignment == TextAlignmentOptions.Left)
alignment = TextAlignmentOptions.Right;
else if (alignment == TextAlignmentOptions.BottomLeft)
alignment = TextAlignmentOptions.BottomRight;
// Set RTL flag (for TMP's own RTL awareness)
isRightToLeftText = true;
// Initial text processing
if (!string.IsNullOrEmpty(m_ArabicText))
{
text = ArabicSupport.Fix(m_ArabicText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 6288886329a3741578473981df735c34
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using TMPro;
using UnityEngine;
namespace ALArcade.ArabicTMP
{
[AddComponentMenu("UI/Arabic TextMeshPro - Text (UI)", 11)]
public class ArabicTextMeshProUGUI : TextMeshProUGUI
{
[Header("Arabic Settings")]
[SerializeField] private string m_ArabicText = "";
[SerializeField] private bool m_ShowTashkeel = true;
[SerializeField] private bool m_PreserveNumbers = true;
[SerializeField] private bool m_FixTags = true;
[SerializeField] private bool m_ForceRTL = true;
public string arabicText
{
get => m_ArabicText;
set
{
if (m_ArabicText == value) return;
m_ArabicText = value;
UpdateDisplayText();
}
}
public bool showTashkeel
{
get => m_ShowTashkeel;
set
{
if (m_ShowTashkeel == value) return;
m_ShowTashkeel = value;
UpdateDisplayText();
}
}
public bool preserveNumbers
{
get => m_PreserveNumbers;
set
{
if (m_PreserveNumbers == value) return;
m_PreserveNumbers = value;
UpdateDisplayText();
}
}
public bool fixTags
{
get => m_FixTags;
set
{
if (m_FixTags == value) return;
m_FixTags = value;
UpdateDisplayText();
}
}
public bool forceRTL
{
get => m_ForceRTL;
set
{
if (m_ForceRTL == value) return;
m_ForceRTL = value;
UpdateDisplayText();
}
}
private void UpdateDisplayText()
{
if (!string.IsNullOrEmpty(m_ArabicText))
{
text = ArabicSupport.Fix(m_ArabicText, m_ShowTashkeel, m_PreserveNumbers, m_FixTags, m_ForceRTL);
}
}
protected override void Awake()
{
base.Awake();
// Set RTL properties
isRightToLeftText = true;
// Set default alignment for Arabic
if (alignment == TextAlignmentOptions.TopLeft)
alignment = TextAlignmentOptions.TopRight;
else if (alignment == TextAlignmentOptions.Left)
alignment = TextAlignmentOptions.Right;
else if (alignment == TextAlignmentOptions.BottomLeft)
alignment = TextAlignmentOptions.BottomRight;
UpdateDisplayText();
}
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
UpdateDisplayText();
}
#endif
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 0e20cc1eab1d04e7c9515c000ca5ba22
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: d384d57467e8841c89e614799f272161
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using TMPro;
using TMPro.EditorUtilities;
using System.IO;
using System.Text;
namespace ALArcade.ArabicTMP.Editor
{
public class ArabicFontAssetCreator : EditorWindow
{
private Font sourceFont;
private string savePath = "Assets/";
private string saveFileName = "New Arabic Font Asset";
private int samplingPointSize = 90;
private int atlasPadding = 9;
private int atlasWidth = 1024;
private int atlasHeight = 1024;
private bool includeArabicBasic = true;
private bool includeArabicSupplement = true;
private bool includeArabicExtendedA = true;
private bool includeArabicPresentationA = true;
private bool includeArabicPresentationB = true;
private bool includePersian = true;
private TMP_FontAsset createdFontAsset;
private readonly string[] arabicRanges = new string[] {
// Basic Arabic
"0600-06FF",
// Arabic Supplement
"0750-077F",
// Arabic Extended-A
"08A0-08FF",
// Arabic Presentation Forms-A
"FB50-FDFF",
// Arabic Presentation Forms-B
"FE70-FEFF",
// Persian Characters
"067E, 0686, 0698, 06AF"
};
[MenuItem("Window/AL-Arcade/Arabic TMP/Font Asset Creator")]
public static void ShowWindow()
{
EditorWindow.GetWindow<ArabicFontAssetCreator>("Arabic Font Asset Creator");
}
private void OnGUI()
{
GUILayout.Label("Create Arabic TextMeshPro Font Asset", EditorStyles.boldLabel);
EditorGUILayout.Space();
// Source font selection
sourceFont = (Font)EditorGUILayout.ObjectField("Source Font File", sourceFont, typeof(Font), false);
// Atlas settings
EditorGUILayout.Space();
EditorGUILayout.LabelField("Atlas Settings", EditorStyles.boldLabel);
samplingPointSize = EditorGUILayout.IntField("Sampling Point Size", samplingPointSize);
atlasPadding = EditorGUILayout.IntField("Atlas Padding", atlasPadding);
atlasWidth = EditorGUILayout.IntField("Atlas Width", atlasWidth);
atlasHeight = EditorGUILayout.IntField("Atlas Height", atlasHeight);
// Character sets
EditorGUILayout.Space();
EditorGUILayout.LabelField("Character Sets to Include", EditorStyles.boldLabel);
includeArabicBasic = EditorGUILayout.Toggle("Arabic Basic (0600-06FF)", includeArabicBasic);
includeArabicSupplement = EditorGUILayout.Toggle("Arabic Supplement (0750-077F)", includeArabicSupplement);
includeArabicExtendedA = EditorGUILayout.Toggle("Arabic Extended-A (08A0-08FF)", includeArabicExtendedA);
includeArabicPresentationA = EditorGUILayout.Toggle("Arabic Presentation Forms-A (FB50-FDFF)", includeArabicPresentationA);
includeArabicPresentationB = EditorGUILayout.Toggle("Arabic Presentation Forms-B (FE70-FEFF)", includeArabicPresentationB);
includePersian = EditorGUILayout.Toggle("Persian Letters (پ چ ژ گ)", includePersian);
// Save settings
EditorGUILayout.Space();
EditorGUILayout.LabelField("Save Settings", EditorStyles.boldLabel);
savePath = EditorGUILayout.TextField("Save Path", savePath);
saveFileName = EditorGUILayout.TextField("Asset Name", saveFileName);
// Create button
EditorGUILayout.Space();
if (sourceFont == null)
{
EditorGUILayout.HelpBox("A Source Font File is required to create a font asset.", MessageType.Error);
}
EditorGUI.BeginDisabledGroup(sourceFont == null);
if (GUILayout.Button("Create Font Asset"))
{
GenerateFontAsset();
}
EditorGUI.EndDisabledGroup();
// Show the created font asset
EditorGUILayout.Space();
if (createdFontAsset != null)
{
EditorGUILayout.ObjectField("Created Font Asset", createdFontAsset, typeof(TMP_FontAsset), false);
}
// Help box
EditorGUILayout.Space();
EditorGUILayout.HelpBox(
"This utility creates a TextMeshPro Font Asset with all necessary Arabic Unicode ranges.\n\n" +
"1. Select a source font that contains Arabic glyphs.\n" +
"2. Choose which character sets to include.\n" +
"3. Set the save location and asset name.\n" +
"4. Click 'Create Font Asset'.\n\n" +
"The created asset will be ready for use with the Arabic TMP components.",
MessageType.Info);
}
private void GenerateFontAsset()
{
if (sourceFont == null)
{
EditorUtility.DisplayDialog("Error", "A Source Font File is required to create a font asset.", "OK");
return;
}
// Generate the character set string for TMP Font Asset Creator
StringBuilder charSetBuilder = new StringBuilder();
// Add selected character ranges
if (includeArabicBasic) charSetBuilder.Append(arabicRanges[0] + "\n");
if (includeArabicSupplement) charSetBuilder.Append(arabicRanges[1] + "\n");
if (includeArabicExtendedA) charSetBuilder.Append(arabicRanges[2] + "\n");
if (includeArabicPresentationA) charSetBuilder.Append(arabicRanges[3] + "\n");
if (includeArabicPresentationB) charSetBuilder.Append(arabicRanges[4] + "\n");
if (includePersian) charSetBuilder.Append(arabicRanges[5] + "\n");
// Add basic Latin range for mixed text
charSetBuilder.Append("0020-007F\n"); // Basic Latin
string characterSet = charSetBuilder.ToString();
// Create temp file with character set
string tempFilePath = Path.Combine(Path.GetTempPath(), "ArabicCharSet.txt");
File.WriteAllText(tempFilePath, characterSet);
// Ensure the save path exists
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
// Generate the font asset using TMP_FontAsset.CreateFontAsset
string fullPath = Path.Combine(savePath, saveFileName + ".asset");
// Create the font asset
TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(
sourceFont,
samplingPointSize,
atlasPadding,
UnityEngine.TextCore.LowLevel.GlyphRenderMode.SDFAA,
atlasWidth,
atlasHeight,
TMPro.AtlasPopulationMode.Dynamic,
true);
// Initialize character table with our character set
fontAsset.ReadFontAssetDefinition();
// Save the created font asset
AssetDatabase.CreateAsset(fontAsset, fullPath);
// Save the material as a sub-asset
fontAsset.material.name = saveFileName + " Material";
AssetDatabase.AddObjectToAsset(fontAsset.material, fontAsset);
// Update atlas texture and add it as sub-asset
if (fontAsset.atlasTexture != null)
{
fontAsset.atlasTexture.name = saveFileName + " Atlas";
AssetDatabase.AddObjectToAsset(fontAsset.atlasTexture, fontAsset);
}
// The following is a workaround to "load" character set into the font
// In practice, this will set these characters to be loaded when needed
string sampleText = "السلام عليكم مرحبا بكم في يونيتي";
fontAsset.TryAddCharacters(sampleText);
// Save all assets
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
// Store the created font asset reference
createdFontAsset = fontAsset;
EditorUtility.DisplayDialog("Success", "Arabic font asset created successfully at:\n" + fullPath, "OK");
// Clean up temp file
try
{
File.Delete(tempFilePath);
}
catch
{
// Ignore cleanup errors
}
// Select the created asset
EditorGUIUtility.PingObject(fontAsset);
}
}
}
#endif
\ No newline at end of file
fileFormatVersion: 2
guid: c0cd9abaf612f42b39a5bdafbba6d610
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using TMPro;
using ALArcade.ArabicTMP;
namespace ALArcade.ArabicTMP.Editor {
[CustomEditor(typeof(ArabicTMPInputField)), CanEditMultipleObjects]
public class ArabicTMPInputFieldEditor : TMPro.EditorUtilities.TMP_InputFieldEditor {
// SerializedProperties for Arabic input field options
SerializedProperty m_ShowTashkeelProp;
SerializedProperty m_PreserveNumbersProp;
SerializedProperty m_FixTagsProp;
SerializedProperty m_ForceRTLProp;
protected override void OnEnable() {
base.OnEnable();
// Get references to serialized properties
m_ShowTashkeelProp = serializedObject.FindProperty("m_ShowTashkeel");
m_PreserveNumbersProp = serializedObject.FindProperty("m_PreserveNumbers");
m_FixTagsProp = serializedObject.FindProperty("m_FixTags");
m_ForceRTLProp = serializedObject.FindProperty("m_ForceRTL");
}
public override void OnInspectorGUI() {
serializedObject.Update();
// Draw the Arabic options before the base inspector
EditorGUILayout.LabelField("Arabic Input Options", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_ShowTashkeelProp, new GUIContent("Show Diacritics (Tashkeel)", "Display Arabic diacritic marks"));
EditorGUILayout.PropertyField(m_PreserveNumbersProp, new GUIContent("Preserve Numbers", "Keep Western numerals (123) as-is"));
EditorGUILayout.PropertyField(m_FixTagsProp, new GUIContent("Fix Rich Text Tags", "Process rich text tags like <color> properly"));
EditorGUILayout.PropertyField(m_ForceRTLProp, new GUIContent("Force RTL", "Force right-to-left rendering even if text starts with Latin characters"));
EditorGUILayout.Space();
// Call the base class's OnInspectorGUI
base.OnInspectorGUI();
serializedObject.ApplyModifiedProperties();
// Show helpful notes for first-time users
EditorGUILayout.Space();
EditorGUILayout.HelpBox("This component works best with an ArabicTextMeshProUGUI as the text component.", MessageType.Info);
}
}
}
#endif
\ No newline at end of file
fileFormatVersion: 2
guid: 3f229dce16e154883bb9eca9f8c5ef0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using TMPro;
using UnityEngine.UI;
using UnityEngine.EventSystems;
namespace ALArcade.ArabicTMP.Editor
{
public static class ArabicTMPMenu
{
[MenuItem("GameObject/UI/Arabic Text - TextMeshPro", false, 2001)]
static void CreateArabicTextUGUI(MenuCommand menuCommand)
{
// Create a new GameObject with ArabicTextMeshProUGUI
GameObject go = new GameObject("Arabic Text (TMP)");
go.AddComponent<RectTransform>();
go.AddComponent<ArabicTextMeshProUGUI>().text = "أهلا بالعالم"; // Hello World in Arabic
// Set alignment to Right
go.GetComponent<ArabicTextMeshProUGUI>().alignment = TextAlignmentOptions.Right;
// Assign font asset if default Arabic font exists
TMP_FontAsset arabicFont = GetDefaultArabicFont();
if (arabicFont != null)
{
go.GetComponent<ArabicTextMeshProUGUI>().font = arabicFont;
}
// Register the creation in the Undo system
Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
// Set parent
PlaceUIElementRoot(go, menuCommand);
// Select the newly created object
Selection.activeObject = go;
}
[MenuItem("GameObject/3D Object/Arabic Text - TextMeshPro", false, 2001)]
static void CreateArabicTextWorld(MenuCommand menuCommand)
{
// Create a new GameObject with ArabicTextMeshPro
GameObject go = new GameObject("Arabic Text (TMP)");
go.AddComponent<ArabicTextMeshPro>().text = "أهلا بالعالم"; // Hello World in Arabic
// Set alignment to Right
go.GetComponent<ArabicTextMeshPro>().alignment = TextAlignmentOptions.Right;
// Set default size for 3D text
go.GetComponent<ArabicTextMeshPro>().fontSize = 36;
// Assign font asset if default Arabic font exists
TMP_FontAsset arabicFont = GetDefaultArabicFont();
if (arabicFont != null)
{
go.GetComponent<ArabicTextMeshPro>().font = arabicFont;
}
// Register the creation in the Undo system
Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
// Set parent
PlaceGameObjectInScene(go, menuCommand);
// Select the newly created object
Selection.activeObject = go;
}
[MenuItem("GameObject/UI/Arabic Input Field - TextMeshPro", false, 2051)]
static void CreateArabicInputField(MenuCommand menuCommand)
{
// Create a GameObject with InputField with built-in UI components
GameObject go = CreateInputFieldWithRTL();
// Register the creation in the Undo system
Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
// Set parent
PlaceUIElementRoot(go, menuCommand);
// Select the newly created object
Selection.activeObject = go;
}
private static GameObject CreateInputFieldWithRTL()
{
// Create a new GameObject with ArabicTMPInputField
GameObject go = new GameObject("Arabic Input Field (TMP)");
RectTransform rt = go.AddComponent<RectTransform>();
rt.sizeDelta = new Vector2(160, 30);
// Add the Input field component which in turn adds the needed sub components
ArabicTMPInputField inputField = go.AddComponent<ArabicTMPInputField>();
// Get reference to the TMP_InputField.textComponent
GameObject textArea = new GameObject("Text Area");
RectTransform textAreaRectTransform = textArea.AddComponent<RectTransform>();
textAreaRectTransform.anchorMin = Vector2.zero;
textAreaRectTransform.anchorMax = Vector2.one;
textAreaRectTransform.sizeDelta = Vector2.zero;
textAreaRectTransform.offsetMin = new Vector2(10, 6);
textAreaRectTransform.offsetMax = new Vector2(-10, -7);
textArea.transform.SetParent(go.transform, false);
// Create text component
GameObject textComponent = new GameObject("Text");
RectTransform textRectTransform = textComponent.AddComponent<RectTransform>();
textRectTransform.anchorMin = new Vector2(0, 0);
textRectTransform.anchorMax = new Vector2(1, 1);
textRectTransform.sizeDelta = Vector2.zero;
textRectTransform.offsetMin = new Vector2(0, 0);
textRectTransform.offsetMax = new Vector2(0, 0);
textComponent.transform.SetParent(textArea.transform, false);
// Instead of regular TMP_Text, use our ArabicTextMeshProUGUI
ArabicTextMeshProUGUI text = textComponent.AddComponent<ArabicTextMeshProUGUI>();
text.alignment = TextAlignmentOptions.Right;
text.color = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f);
text.text = "";
// Create placeholder for the text input
GameObject placeholder = new GameObject("Placeholder");
RectTransform placeholderRectTransform = placeholder.AddComponent<RectTransform>();
placeholderRectTransform.anchorMin = Vector2.zero;
placeholderRectTransform.anchorMax = Vector2.one;
placeholderRectTransform.sizeDelta = Vector2.zero;
placeholderRectTransform.offsetMin = Vector2.zero;
placeholderRectTransform.offsetMax = Vector2.zero;
placeholder.transform.SetParent(textArea.transform, false);
// Again use ArabicTextMeshProUGUI for the placeholder
ArabicTextMeshProUGUI placeholderText = placeholder.AddComponent<ArabicTextMeshProUGUI>();
placeholderText.alignment = TextAlignmentOptions.Right;
placeholderText.text = "أدخل النص..."; // "Enter text..." in Arabic
placeholderText.enableWordWrapping = false;
placeholderText.extraPadding = true;
Color placeholderColor = new Color(0f, 0f, 0f, 0.5f);
placeholderText.color = placeholderColor;
// Make the placeholder text slightly smaller
placeholderText.fontSize = text.fontSize - 0.75f;
// Set references on the InputField
inputField.textComponent = text;
inputField.placeholder = placeholderText;
inputField.fontAsset = text.font;
// Assign Arabic font if available
TMP_FontAsset arabicFont = GetDefaultArabicFont();
if (arabicFont != null)
{
text.font = arabicFont;
placeholderText.font = arabicFont;
inputField.fontAsset = arabicFont;
}
return go;
}
// Helper function to get default Arabic font, if available
private static TMP_FontAsset GetDefaultArabicFont()
{
// Look for common Arabic fonts in project
string[] guids = AssetDatabase.FindAssets("t:TMP_FontAsset");
foreach (string guid in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
TMP_FontAsset font = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(assetPath);
// Look for fonts with common Arabic font names
if (font != null)
{
string fontName = font.name.ToLowerInvariant();
if (fontName.Contains("arabic") || fontName.Contains("amiri") ||
fontName.Contains("cairo") || fontName.Contains("scheherazade") ||
fontName.Contains("dubai") || fontName.Contains("noto") && fontName.Contains("arabic"))
{
return font;
}
}
}
return null;
}
// Common code for placing UI elements in hierarchy
private static void PlaceUIElementRoot(GameObject element, MenuCommand menuCommand)
{
GameObject parent = menuCommand.context as GameObject;
if (parent == null || parent.GetComponentInParent<Canvas>() == null)
{
parent = GetOrCreateCanvasGameObject();
}
string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent.transform, element.name);
element.name = uniqueName;
Undo.RegisterCreatedObjectUndo(element, "Create " + element.name);
Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name);
GameObjectUtility.SetParentAndAlign(element, parent);
Selection.activeGameObject = element;
}
// Get or create canvas for UI elements
private static GameObject GetOrCreateCanvasGameObject()
{
GameObject selectedGo = Selection.activeGameObject;
// Try to find canvas in selected hierarchy
Canvas canvas = (selectedGo != null) ? selectedGo.GetComponentInParent<Canvas>() : null;
if (canvas != null && canvas.gameObject.activeInHierarchy)
{
return canvas.gameObject;
}
// No canvas in hierarchy, try to find any canvas
canvas = Object.FindObjectOfType<Canvas>();
if (canvas != null && canvas.gameObject.activeInHierarchy)
{
return canvas.gameObject;
}
// No canvas exists, create one
return CreateNewUI();
}
// Create a new UI with EventSystem
private static GameObject CreateNewUI()
{
// Root canvas
GameObject root = new GameObject("Canvas");
root.layer = LayerMask.NameToLayer("UI");
Canvas canvas = root.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
root.AddComponent<CanvasScaler>();
root.AddComponent<GraphicRaycaster>();
// Create EventSystem if needed
CreateEventSystemIfNeeded();
return root;
}
// Create EventSystem if none exists
private static void CreateEventSystemIfNeeded()
{
if (Object.FindObjectOfType<EventSystem>() == null)
{
GameObject eventSystem = new GameObject("EventSystem");
eventSystem.AddComponent<EventSystem>();
eventSystem.AddComponent<StandaloneInputModule>();
Undo.RegisterCreatedObjectUndo(eventSystem, "Create EventSystem");
}
}
// Place 3D objects in the scene
private static void PlaceGameObjectInScene(GameObject element, MenuCommand menuCommand)
{
GameObject parent = menuCommand.context as GameObject;
if (parent == null)
{
// No context, place at scene root
parent = null;
}
string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent != null ? parent.transform : null, element.name);
element.name = uniqueName;
// Register undo
Undo.RegisterCreatedObjectUndo(element, "Create " + element.name);
// Set parent
if (parent != null)
{
Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name);
GameObjectUtility.SetParentAndAlign(element, parent);
}
// Set selection to new object
Selection.activeGameObject = element;
}
}
}
#endif
\ No newline at end of file
fileFormatVersion: 2
guid: 4d5aca6a679854ad287e5f80e22df0e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using TMPro;
using ALArcade.ArabicTMP;
namespace ALArcade.ArabicTMP.Editor {
[CustomEditor(typeof(ArabicTextMeshPro)), CanEditMultipleObjects]
public class ArabicTextMeshProEditor : TMPro.EditorUtilities.TMP_EditorPanelUI {
// SerializedProperties for Arabic text component
SerializedProperty m_ArabicTextProp;
SerializedProperty m_ShowTashkeelProp;
SerializedProperty m_PreserveNumbersProp;
SerializedProperty m_FixTagsProp;
SerializedProperty m_ForceRTLProp;
protected override void OnEnable() {
base.OnEnable();
// Get references to serialized properties
m_ArabicTextProp = serializedObject.FindProperty("m_ArabicText");
m_ShowTashkeelProp = serializedObject.FindProperty("m_ShowTashkeel");
m_PreserveNumbersProp = serializedObject.FindProperty("m_PreserveNumbers");
m_FixTagsProp = serializedObject.FindProperty("m_FixTags");
m_ForceRTLProp = serializedObject.FindProperty("m_ForceRTL");
}
public override void OnInspectorGUI() {
if (target == null)
return;
serializedObject.Update();
// Draw Arabic text input field
EditorGUILayout.LabelField("Arabic Text", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
string newText = EditorGUILayout.TextArea(m_ArabicTextProp.stringValue, GUILayout.MinHeight(80));
if (EditorGUI.EndChangeCheck()) {
m_ArabicTextProp.stringValue = newText;
// Ensure immediate update in editor
foreach (var obj in targets) {
if (obj is ArabicTextMeshPro arabicText) {
arabicText.arabicText = newText;
}
}
}
// Draw options section
EditorGUILayout.Space();
EditorGUILayout.LabelField("Arabic Options", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_ShowTashkeelProp, new GUIContent("Show Diacritics (Tashkeel)", "Display Arabic diacritic marks"));
EditorGUILayout.PropertyField(m_PreserveNumbersProp, new GUIContent("Preserve Numbers", "Keep Western numerals (123) as-is"));
EditorGUILayout.PropertyField(m_FixTagsProp, new GUIContent("Fix Rich Text Tags", "Process rich text tags like <color> properly"));
EditorGUILayout.PropertyField(m_ForceRTLProp, new GUIContent("Force RTL", "Force right-to-left rendering even if text starts with Latin characters"));
EditorGUILayout.Space();
// Draw default TMP properties
EditorGUILayout.LabelField("TextMeshPro Settings", EditorStyles.boldLabel);
// Hide the original text property since we're using our custom one
SerializedProperty prop = serializedObject.FindProperty("m_text");
if (prop != null) {
// Make the TMP text field read-only to prevent editing it directly
GUI.enabled = false;
EditorGUILayout.PropertyField(prop, new GUIContent("Processed Text (Read Only)"));
GUI.enabled = true;
}
DrawMainSettings();
DrawExtraSettings();
serializedObject.ApplyModifiedProperties();
// Show helpful notes for first-time users
EditorGUILayout.Space();
EditorGUILayout.HelpBox("Enter Arabic text in the 'Arabic Text' field above. It will be automatically shaped and displayed correctly.", MessageType.Info);
}
}
}
#endif
\ No newline at end of file
fileFormatVersion: 2
guid: 870f69856c80f48a59fe7ebc1f74dde8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using TMPro;
using ALArcade.ArabicTMP;
namespace ALArcade.ArabicTMP.Editor {
[CustomEditor(typeof(ArabicTextMeshProUGUI)), CanEditMultipleObjects]
public class ArabicTextMeshProUGUIEditor : TMPro.EditorUtilities.TMP_EditorPanelUI {
// SerializedProperties for Arabic text component
SerializedProperty m_ArabicTextProp;
SerializedProperty m_ShowTashkeelProp;
SerializedProperty m_PreserveNumbersProp;
SerializedProperty m_FixTagsProp;
SerializedProperty m_ForceRTLProp;
protected override void OnEnable() {
base.OnEnable();
// Get references to serialized properties
m_ArabicTextProp = serializedObject.FindProperty("m_ArabicText");
m_ShowTashkeelProp = serializedObject.FindProperty("m_ShowTashkeel");
m_PreserveNumbersProp = serializedObject.FindProperty("m_PreserveNumbers");
m_FixTagsProp = serializedObject.FindProperty("m_FixTags");
m_ForceRTLProp = serializedObject.FindProperty("m_ForceRTL");
}
public override void OnInspectorGUI() {
if (target == null)
return;
serializedObject.Update();
// Draw Arabic text input field
EditorGUILayout.LabelField("Arabic Text", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
string newText = EditorGUILayout.TextArea(m_ArabicTextProp.stringValue, GUILayout.MinHeight(80));
if (EditorGUI.EndChangeCheck()) {
m_ArabicTextProp.stringValue = newText;
// Ensure immediate update in editor
foreach (var obj in targets) {
if (obj is ArabicTextMeshProUGUI arabicText) {
arabicText.arabicText = newText;
}
}
}
// Draw options section
EditorGUILayout.Space();
EditorGUILayout.LabelField("Arabic Options", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_ShowTashkeelProp, new GUIContent("Show Diacritics (Tashkeel)", "Display Arabic diacritic marks"));
EditorGUILayout.PropertyField(m_PreserveNumbersProp, new GUIContent("Preserve Numbers", "Keep Western numerals (123) as-is"));
EditorGUILayout.PropertyField(m_FixTagsProp, new GUIContent("Fix Rich Text Tags", "Process rich text tags like <color> properly"));
EditorGUILayout.PropertyField(m_ForceRTLProp, new GUIContent("Force RTL", "Force right-to-left rendering even if text starts with Latin characters"));
EditorGUILayout.Space();
// Draw default TMP properties
EditorGUILayout.LabelField("TextMeshPro Settings", EditorStyles.boldLabel);
// Hide the original text property since we're using our custom one
SerializedProperty prop = serializedObject.FindProperty("m_text");
if (prop != null) {
// Make the TMP text field read-only to prevent editing it directly
GUI.enabled = false;
EditorGUILayout.PropertyField(prop, new GUIContent("Processed Text (Read Only)"));
GUI.enabled = true;
}
DrawMainSettings();
DrawExtraSettings();
serializedObject.ApplyModifiedProperties();
// Show helpful notes for first-time users
EditorGUILayout.Space();
EditorGUILayout.HelpBox("Enter Arabic text in the 'Arabic Text' field above. It will be automatically shaped and displayed correctly.", MessageType.Info);
}
}
}
#endif
\ No newline at end of file
fileFormatVersion: 2
guid: a0c1457171b094e90af03f669b460a4d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
This source diff could not be displayed because it is too large. You can view the blob instead.
fileFormatVersion: 2
guid: 978f208d0ffc7d24b925e17faf828775
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
This source diff could not be displayed because it is too large. You can view the blob instead.
fileFormatVersion: 2
guid: 4b1038618804cf140a96475a05e3c66c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
...@@ -550,6 +550,7 @@ MonoBehaviour: ...@@ -550,6 +550,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: Assembly-CSharp::AnimalDetails m_EditorClassIdentifier: Assembly-CSharp::AnimalDetails
<animalProperties>k__BackingField: {fileID: 11400000, guid: 9c4c9c8f3b059674d8ea903f0baa73f1, type: 2} <animalProperties>k__BackingField: {fileID: 11400000, guid: 9c4c9c8f3b059674d8ea903f0baa73f1, type: 2}
<isCorrect>k__BackingField: 0
--- !u!65 &3134386485418195282 --- !u!65 &3134386485418195282
BoxCollider: BoxCollider:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -569,8 +570,8 @@ BoxCollider: ...@@ -569,8 +570,8 @@ BoxCollider:
m_ProvidesContacts: 0 m_ProvidesContacts: 0
m_Enabled: 1 m_Enabled: 1
serializedVersion: 3 serializedVersion: 3
m_Size: {x: 3.7020752, y: 7.6251206, z: 9.196465} m_Size: {x: 52429.523, y: 7.6251206, z: 9.196465}
m_Center: {x: 0, y: 3.9071233, z: 1.1254215} m_Center: {x: -26212.887, y: 3.9071233, z: 1.1254215}
--- !u!1 &821623542764607179 --- !u!1 &821623542764607179
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -1614,6 +1615,7 @@ MonoBehaviour: ...@@ -1614,6 +1615,7 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::BodyPart m_EditorClassIdentifier: Assembly-CSharp::BodyPart
<AnimalPart>k__BackingField: 1 <AnimalPart>k__BackingField: 1
healthScript: {fileID: 4577948788861265325} healthScript: {fileID: 4577948788861265325}
animalDetails: {fileID: 7439170055329331585}
--- !u!1 &4814410725735562131 --- !u!1 &4814410725735562131
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -1984,8 +1986,8 @@ CapsuleCollider: ...@@ -1984,8 +1986,8 @@ CapsuleCollider:
m_ProvidesContacts: 0 m_ProvidesContacts: 0
m_Enabled: 1 m_Enabled: 1
serializedVersion: 2 serializedVersion: 2
m_Radius: 1.96 m_Radius: 2.41
m_Height: 7.300329 m_Height: 7.79
m_Direction: 2 m_Direction: 2
m_Center: {x: 0, y: 0, z: -0.48516464} m_Center: {x: 0, y: 0, z: -0.48516464}
--- !u!114 &3160737932670797696 --- !u!114 &3160737932670797696
...@@ -2002,6 +2004,7 @@ MonoBehaviour: ...@@ -2002,6 +2004,7 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::BodyPart m_EditorClassIdentifier: Assembly-CSharp::BodyPart
<AnimalPart>k__BackingField: 0 <AnimalPart>k__BackingField: 0
healthScript: {fileID: 4577948788861265325} healthScript: {fileID: 4577948788861265325}
animalDetails: {fileID: 7439170055329331585}
--- !u!1 &5648405520980593439 --- !u!1 &5648405520980593439
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
......
...@@ -326,7 +326,7 @@ MonoBehaviour: ...@@ -326,7 +326,7 @@ MonoBehaviour:
reloadTime: 1.5 reloadTime: 1.5
bodyPartLayer: bodyPartLayer:
serializedVersion: 2 serializedVersion: 2
m_Bits: 64 m_Bits: 192
MuzzleFlashEffect: {fileID: 1784640390} MuzzleFlashEffect: {fileID: 1784640390}
HeadDamage: 2 HeadDamage: 2
BodyDamage: 1 BodyDamage: 1
...@@ -1155,143 +1155,6 @@ Transform: ...@@ -1155,143 +1155,6 @@ Transform:
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &564941260
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 564941261}
- component: {fileID: 564941263}
- component: {fileID: 564941262}
m_Layer: 5
m_Name: Question
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &564941261
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 564941260}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 3.25, y: 3.25, z: 3.25}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 653799946}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 30.53003, y: 43.5}
m_SizeDelta: {x: 269.4476, y: 50}
m_Pivot: {x: 0, y: 0}
--- !u!114 &564941262
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 564941260}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: Which animal lives in the forest, eats plants, and can run
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4279435519
m_fontColor: {r: 1, g: 0, b: 0.07646704, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 16.02
m_fontSizeBase: 16.02
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 1
m_HorizontalAlignment: 1
m_VerticalAlignment: 1024
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &564941263
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 564941260}
m_CullTransparentMesh: 1
--- !u!1 &578846265 --- !u!1 &578846265
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -1303,7 +1166,7 @@ GameObject: ...@@ -1303,7 +1166,7 @@ GameObject:
- component: {fileID: 578846266} - component: {fileID: 578846266}
- component: {fileID: 578846267} - component: {fileID: 578846267}
m_Layer: 0 m_Layer: 0
m_Name: QuestionGenerator m_Name: AnimalsQuestionGenerator
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
...@@ -1336,8 +1199,7 @@ MonoBehaviour: ...@@ -1336,8 +1199,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: eed983e626aa84642aca502efe530d72, type: 3} m_Script: {fileID: 11500000, guid: eed983e626aa84642aca502efe530d72, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: Assembly-CSharp::TagGeneration m_EditorClassIdentifier: Assembly-CSharp::TagGeneration
QuestionText: {fileID: 564941262} QuestionText: {fileID: 1182284588}
MaxQuestion: 2
--- !u!1 &590320134 --- !u!1 &590320134
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -1432,7 +1294,7 @@ RectTransform: ...@@ -1432,7 +1294,7 @@ RectTransform:
m_Children: m_Children:
- {fileID: 1298293215} - {fileID: 1298293215}
- {fileID: 383998553} - {fileID: 383998553}
- {fileID: 564941261} - {fileID: 1182284587}
m_Father: {fileID: 1156373102} m_Father: {fileID: 1156373102}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
...@@ -1988,6 +1850,10 @@ PrefabInstance: ...@@ -1988,6 +1850,10 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z propertyPath: m_LocalEulerAnglesHint.z
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 9070904445842527667, guid: 9642121dd9340f748a05158b8437cb00, type: 3}
propertyPath: m_LocalPosition.z
value: 0.39
objectReference: {fileID: 0}
m_RemovedComponents: [] m_RemovedComponents: []
m_RemovedGameObjects: [] m_RemovedGameObjects: []
m_AddedGameObjects: [] m_AddedGameObjects: []
...@@ -2471,6 +2337,152 @@ Transform: ...@@ -2471,6 +2337,152 @@ Transform:
- {fileID: 1699401339} - {fileID: 1699401339}
m_Father: {fileID: 1613193636} m_Father: {fileID: 1613193636}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1182284586
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1182284587}
- component: {fileID: 1182284589}
- component: {fileID: 1182284588}
m_Layer: 0
m_Name: QuestionText
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1182284587
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1182284586}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 653799946}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 969.9172, y: 113.9566}
m_Pivot: {x: 0, y: 0}
--- !u!114 &1182284588
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1182284586}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0e20cc1eab1d04e7c9515c000ca5ba22, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::ALArcade.ArabicTMP.ArabicTextMeshProUGUI
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: '
'
m_isRightToLeft: 1
m_fontAsset: {fileID: 11400000, guid: 978f208d0ffc7d24b925e17faf828775, type: 2}
m_sharedMaterial: {fileID: -1068976181254587461, guid: 978f208d0ffc7d24b925e17faf828775, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4278190335
m_fontColor: {r: 1, g: 0, b: 0, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 36
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 4
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
m_ArabicText: '
'
m_ShowTashkeel: 1
m_PreserveNumbers: 1
m_FixTags: 1
m_ForceRTL: 1
--- !u!222 &1182284589
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1182284586}
m_CullTransparentMesh: 1
--- !u!1 &1241827882 --- !u!1 &1241827882
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -2543,11 +2555,6 @@ MonoBehaviour: ...@@ -2543,11 +2555,6 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
m_Bits: 64 m_Bits: 64
debugMode: 0 debugMode: 0
animalsCollider:
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
_currentTarget: {fileID: 0}
--- !u!114 &1241827886 --- !u!114 &1241827886
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -3854,7 +3861,8 @@ MonoBehaviour: ...@@ -3854,7 +3861,8 @@ MonoBehaviour:
roundTimerText: {fileID: 383998554} roundTimerText: {fileID: 383998554}
matchRoundText: {fileID: 1298293216} matchRoundText: {fileID: 1298293216}
maxMatchRound: 5 maxMatchRound: 5
maxRoundTimer: 60 maxRoundTimer: 10
animalsQuestionGenerator: {fileID: 578846267}
animalsSpawner: {fileID: 1360605812} animalsSpawner: {fileID: 1360605812}
--- !u!1 &1613193635 --- !u!1 &1613193635
GameObject: GameObject:
......
public enum AnimalName public enum AnimalName
{ {
// Ice // Ice
Penguin, بطريق,
PolarBear, دب_قطبي,
Seal, كلب_البحر,
Walrus, أسد_البحر,
// Forest // Forest
Deer, غزال,
Monkey, قرد,
Bear, دب,
Elephant, فيل,
GorillaBlack, غوريلا,
// Desert // Desert
SnakeRed, ثعبان,
Ostrich, نعامة,
ثعلب ثعلب
} }
public enum AnimalType public enum AnimalType
{ {
Bird, طائر,
Mammal, ثديي,
Reptile زاحف
} }
public enum FoodType public enum FoodType
{ {
Carnivore, يأكل_اللحم,
Herbivore, يأكل_العشب,
Omnivore يأكل_كل_شيء
} }
public enum Environment public enum Environment
{ {
Ice, يعيش_في_الجليد,
Desert, يعيش_في_الصحراء,
Forest يعيش_في_الغابة
} }
public enum SpecialAbilities public enum SpecialAbilities
{ {
CanSwim, يستطيع_السباحة,
CanRun, يستطيع_الجري,
CanClimb, يستطيع_التسلق,
NightVision, رؤية_ليل,
Venomous سام
} }
public enum Reproduction public enum Reproduction
{ {
LaysEggs, يضع_البيض,
LiveBirth, يولد,
} }
public enum AnimalPart public enum AnimalPart
......
...@@ -13,8 +13,9 @@ public class MatchManager : MonoBehaviour ...@@ -13,8 +13,9 @@ public class MatchManager : MonoBehaviour
[SerializeField] TextMeshProUGUI matchRoundText; [SerializeField] TextMeshProUGUI matchRoundText;
[SerializeField] int maxMatchRound; [SerializeField] int maxMatchRound;
[SerializeField] int maxRoundTimer; [SerializeField] int maxRoundTimer;
[SerializeField] AnimalsQuestionGenerator animalsQuestionGenerator;
[SerializeField] AnimalsSpawner animalsSpawner; [SerializeField] AnimalsSpawner animalsSpawner;
TransitionManager _transitionManager; TransitionManager _transitionManager;
int currentMatch; int currentMatch;
...@@ -53,6 +54,7 @@ public class MatchManager : MonoBehaviour ...@@ -53,6 +54,7 @@ public class MatchManager : MonoBehaviour
} }
void ChangeRound() void ChangeRound()
{ {
animalsQuestionGenerator.GengenerateNewQuestions(currentMatch);
animalsSpawner.SpawnAnimals(); animalsSpawner.SpawnAnimals();
StopNPC(false); StopNPC(false);
matchRoundText.text = $"Round: {currentMatch}/{maxMatchRound}"; matchRoundText.text = $"Round: {currentMatch}/{maxMatchRound}";
......
...@@ -6,15 +6,16 @@ public class AnimalDetails : MonoBehaviour ...@@ -6,15 +6,16 @@ public class AnimalDetails : MonoBehaviour
{ {
[field: SerializeField] public AnimalProperties animalProperties { get; private set; } [field: SerializeField] public AnimalProperties animalProperties { get; private set; }
[SerializeField] List<Enum> animalTag = new List<Enum>(); [SerializeField] List<Enum> animalTag = new List<Enum>();
[SerializeField] bool isCorrect; [field: SerializeField] public bool isCorrect { get; private set; }
private void Start() private void Start()
{ {
AddAnimalTagsToList(); AddAnimalTagsToList();
Invoke("CheckIfAnimalIsCorrect", .1f); Invoke("CheckIfAnimalIsCorrect", .05f);
} }
void AddAnimalTagsToList() void AddAnimalTagsToList()
{ {
animalTag.Add(animalProperties.AnimalType); animalTag.Add(animalProperties.AnimalType);
......
...@@ -5,7 +5,16 @@ public class BodyPart : MonoBehaviour,IDamageable ...@@ -5,7 +5,16 @@ public class BodyPart : MonoBehaviour,IDamageable
[field: SerializeField] public AnimalPart AnimalPart { get; private set; } [field: SerializeField] public AnimalPart AnimalPart { get; private set; }
[SerializeField] Health healthScript; [SerializeField] Health healthScript;
[SerializeField] AnimalDetails animalDetails;
private void Start()
{
Invoke("CheckIfCorrectAnimal", .1f);
}
void CheckIfCorrectAnimal()
{
if (!animalDetails.isCorrect) gameObject.layer = LayerMask.NameToLayer("IncorrectAnimal");
}
public void TakeDamage(int amount, RaycastWeapon player) public void TakeDamage(int amount, RaycastWeapon player)
{ {
healthScript.TakeDamage(amount, player); healthScript.TakeDamage(amount, player);
......
...@@ -36,10 +36,14 @@ public class Health : MonoBehaviour ...@@ -36,10 +36,14 @@ public class Health : MonoBehaviour
if (isDie) return; if (isDie) return;
isDie = true; isDie = true;
int score = (int)healthSlider.maxValue;
score = animalDetails.isCorrect ? score : -score / 2;
if (firstPlayer == lastPlayer) if (firstPlayer == lastPlayer)
firstPlayer.AddScore((int)healthSlider.maxValue); firstPlayer.AddScore(score);
else else
lastPlayer.AddScore((int)healthSlider.maxValue / 2); lastPlayer.AddScore(score / 2);
// onDie?.Invoke(); // onDie?.Invoke();
......
...@@ -12,8 +12,8 @@ public class NPCsMovement : MonoBehaviour ...@@ -12,8 +12,8 @@ public class NPCsMovement : MonoBehaviour
NavMeshAgent _agent; NavMeshAgent _agent;
Vector3 _direction; Vector3 _direction;
[SerializeField] Collider[] animalsCollider = new Collider[3]; Collider[] animalsCollider = new Collider[2];
[SerializeField] Collider _currentTarget; Collider _currentTarget;
void Start() void Start()
{ {
_agent = GetComponent<NavMeshAgent>(); _agent = GetComponent<NavMeshAgent>();
......
...@@ -16,6 +16,8 @@ public class Score : MonoBehaviour ...@@ -16,6 +16,8 @@ public class Score : MonoBehaviour
private void AnimalDie(int score) private void AnimalDie(int score)
{ {
this.score += score; this.score += score;
this.score = Mathf.Max(0, this.score);
if (scoreText != null) if (scoreText != null)
scoreText.text = "Score: " + this.score.ToString(); scoreText.text = "Score: " + this.score.ToString();
} }
......
using System; using ALArcade.ArabicTMP;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
...@@ -10,77 +11,98 @@ public class AnimalsQuestionGenerator : MonoBehaviour ...@@ -10,77 +11,98 @@ public class AnimalsQuestionGenerator : MonoBehaviour
public static AnimalsQuestionGenerator Instance { get; private set; } public static AnimalsQuestionGenerator Instance { get; private set; }
public List<Enum> randomTags { get; private set; } = new List<Enum>(); public List<Enum> randomTags { get; private set; } = new List<Enum>();
[SerializeField] TextMeshProUGUI QuestionText; [SerializeField] ArabicTextMeshProUGUI QuestionText;
[SerializeField] StringBuilder text = new StringBuilder(); [SerializeField] StringBuilder textBuilder = new StringBuilder();
private void Awake() private void Awake()
{ {
if (Instance == null) if (Instance == null)
Instance = this; Instance = this;
else else
Destroy(this); Destroy(this);
}
private void Start()
{
GengenerateNewQuestions();
}
public void GengenerateNewQuestions() GengenerateNewQuestions(1);
}
string prevQuestion;
public void GengenerateNewQuestions(int numberOfTags)
{ {
string currentQuestionText = "";
do do
{ {
AddRandomTagToList(); AddRandomTagToList(numberOfTags);
currentQuestionText = BuildQuestionString();
} }
while (CheckIfTagsIsCorrect() == false); while (!CheckIfTagsIsCorrect() || currentQuestionText == prevQuestion);
text.Clear(); prevQuestion = currentQuestionText;
QuestionText.arabicText = currentQuestionText;
}
private string BuildQuestionString()
{
textBuilder.Clear();
for (int i = 0; i < randomTags.Count; i++) for (int i = 0; i < randomTags.Count; i++)
{ {
text.Append(randomTags[i].ToString()); textBuilder.Append(randomTags[i].ToString());
if (i != randomTags.Count - 1) if (i != randomTags.Count - 1)
text.Append(" And "); textBuilder.Append(" و ");
} }
Debug.Log(text); return textBuilder.ToString();
} }
private void AddRandomTagToList() private void AddRandomTagToList(int numberOfTag)
{ {
randomTags.Clear(); randomTags.Clear();
var AnimalType = (AnimalType[])Enum.GetValues(typeof(AnimalType)); if (numberOfTag >= 1)
randomTags.Add(AnimalType[UnityEngine.Random.Range(0, AnimalType.Length)]); {
var animalTypes = (AnimalType[])Enum.GetValues(typeof(AnimalType));
randomTags.Add(animalTypes[UnityEngine.Random.Range(0, animalTypes.Length)]);
}
var FoodType = (FoodType[])Enum.GetValues(typeof(FoodType)); if (numberOfTag >= 2)
randomTags.Add(FoodType[UnityEngine.Random.Range(0, FoodType.Length)]); {
var foodTypes = (FoodType[])Enum.GetValues(typeof(FoodType));
randomTags.Add(foodTypes[UnityEngine.Random.Range(0, foodTypes.Length)]);
}
//var Environment = (Environment[])Enum.GetValues(typeof(Environment)); if (numberOfTag >= 3)
//randomTags.Add(Environment[UnityEngine.Random.Range(0, Environment.Length)]); {
var environments = (Environment[])Enum.GetValues(typeof(Environment));
randomTags.Add(environments[UnityEngine.Random.Range(0, environments.Length)]);
}
//var SpecialAbilities = (SpecialAbilities[])Enum.GetValues(typeof(SpecialAbilities)); if (numberOfTag >= 4)
//randomTags.Add(SpecialAbilities[UnityEngine.Random.Range(0, SpecialAbilities.Length)]); {
var abilities = (SpecialAbilities[])Enum.GetValues(typeof(SpecialAbilities));
randomTags.Add(abilities[UnityEngine.Random.Range(0, abilities.Length)]);
}
//var Reproduction = (Reproduction[])Enum.GetValues(typeof(Reproduction)); if (numberOfTag >= 5)
//randomTags.Add(Reproduction[UnityEngine.Random.Range(0, Reproduction.Length)]); {
var reproductions = (Reproduction[])Enum.GetValues(typeof(Reproduction));
randomTags.Add(reproductions[UnityEngine.Random.Range(0, reproductions.Length)]);
}
} }
bool CheckIfTagsIsCorrect() bool CheckIfTagsIsCorrect()
{ {
if (randomTags.Contains(AnimalType.Bird) && randomTags.Contains(Reproduction.LiveBirth)) if (randomTags.Contains(AnimalType.طائر) && randomTags.Contains(Reproduction.يولد))
return false; return false;
if (randomTags.Contains(AnimalType.Mammal) && randomTags.Contains(Reproduction.LaysEggs)) if (randomTags.Contains(AnimalType.زاحف) && randomTags.Contains(Reproduction.يضع_البيض))
return false; return false;
if (randomTags.Contains(AnimalType.Mammal) && randomTags.Contains(SpecialAbilities.Venomous)) if (randomTags.Contains(AnimalType.زاحف) && randomTags.Contains(SpecialAbilities.سام))
return false; return false;
if (randomTags.Contains(Environment.Desert) && randomTags.Contains(SpecialAbilities.CanSwim)) if (randomTags.Contains(Environment.يعيش_في_الصحراء) && randomTags.Contains(SpecialAbilities.يستطيع_السباحة))
return false; return false;
if (randomTags.Contains(Environment.Ice) && !randomTags.Contains(SpecialAbilities.CanSwim)) if (randomTags.Contains(Environment.يعيش_في_الجليد) && !randomTags.Contains(SpecialAbilities.يستطيع_السباحة))
return false; return false;
if (randomTags.Contains(Environment.Ice) && !randomTags.Contains(SpecialAbilities.CanRun)) if (randomTags.Contains(Environment.يعيش_في_الجليد) && !randomTags.Contains(SpecialAbilities.يستطيع_الجري))
return false; return false;
if (randomTags.Contains(Environment.Ice) && randomTags.Contains(SpecialAbilities.Venomous)) if (randomTags.Contains(Environment.يعيش_في_الجليد) && randomTags.Contains(SpecialAbilities.سام))
return false; return false;
return true; return true;
......
...@@ -58,7 +58,7 @@ public class RaycastWeapon : MonoBehaviour ...@@ -58,7 +58,7 @@ public class RaycastWeapon : MonoBehaviour
if (Physics.Raycast(origin, direction, out RaycastHit hit, range, bodyPartLayer)) if (Physics.Raycast(origin, direction, out RaycastHit hit, range, bodyPartLayer))
{ {
if (hit.collider.TryGetComponent<IDamageable>(out IDamageable damageable)) if (hit.collider.TryGetComponent<IDamageable>(out IDamageable damageable))
{ {
if (damageable.AnimalPart == AnimalPart.Body) if (damageable.AnimalPart == AnimalPart.Body)
damageable.TakeDamage(BodyDamage,this); damageable.TakeDamage(BodyDamage,this);
else if (damageable.AnimalPart == AnimalPart.Head) else if (damageable.AnimalPart == AnimalPart.Head)
......
...@@ -63,7 +63,7 @@ Material: ...@@ -63,7 +63,7 @@ Material:
m_Scale: {x: 1, y: 1} m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0} m_Offset: {x: 0, y: 0}
- _MainTex: - _MainTex:
m_Texture: {fileID: 0} m_Texture: {fileID: 2800000, guid: f35f1725252dc4fd8a502e1a4d07a04c, type: 3}
m_Scale: {x: 1, y: 1} m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0} m_Offset: {x: 0, y: 0}
- _MetallicGlossMap: - _MetallicGlossMap:
......
...@@ -120,7 +120,7 @@ Material: ...@@ -120,7 +120,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 0.8039216, g: 0.60784316, b: 0.37647057, a: 1} - _BaseColor: {r: 0.8039216, g: 0.60784316, b: 0.37647057, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 0.8039216, g: 0.60784316, b: 0.3764705, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
...@@ -133,7 +133,7 @@ Material: ...@@ -133,7 +133,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 0.8627451, g: 0.7490196, b: 0.6039216, a: 1} - _BaseColor: {r: 0.8627451, g: 0.7490196, b: 0.6039216, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 0.8627451, g: 0.7490196, b: 0.6039216, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
...@@ -120,7 +120,7 @@ Material: ...@@ -120,7 +120,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 0.654902, g: 0.6313726, b: 0.61960775, a: 1} - _BaseColor: {r: 0.654902, g: 0.6313726, b: 0.61960775, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 0.654902, g: 0.6313726, b: 0.61960775, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
...@@ -133,7 +133,7 @@ Material: ...@@ -133,7 +133,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 1, g: 0.9019608, b: 0.43921566, a: 1} - _BaseColor: {r: 1, g: 0.9019608, b: 0.43921566, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 1, g: 0.9019608, b: 0.43921563, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
...@@ -120,7 +120,7 @@ Material: ...@@ -120,7 +120,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 0.4470588, g: 0.6627451, b: 0.23921564, a: 1} - _BaseColor: {r: 0.4470588, g: 0.6627451, b: 0.23921564, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 0.4470588, g: 0.6627451, b: 0.23921561, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
...@@ -120,7 +120,7 @@ Material: ...@@ -120,7 +120,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 0.8862745, g: 0.96078426, b: 0.2588235, a: 1} - _BaseColor: {r: 0.8862745, g: 0.96078426, b: 0.2588235, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 0.8862745, g: 0.96078426, b: 0.25882348, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
...@@ -133,7 +133,7 @@ Material: ...@@ -133,7 +133,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 0.7411765, g: 0.47843128, b: 0.35294116, a: 1} - _BaseColor: {r: 0.7411765, g: 0.47843128, b: 0.35294116, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 0.7411765, g: 0.47843128, b: 0.35294113, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
...@@ -133,7 +133,7 @@ Material: ...@@ -133,7 +133,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 0.9921568, g: 0.68627447, b: 0.7137255, a: 1} - _BaseColor: {r: 0.9921568, g: 0.68627447, b: 0.7137255, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 0.9921568, g: 0.6862744, b: 0.7137255, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
...@@ -133,7 +133,7 @@ Material: ...@@ -133,7 +133,7 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BaseColor: {r: 0.93333334, g: 0.654902, b: 0.43921566, a: 1} - _BaseColor: {r: 0.93333334, g: 0.654902, b: 0.43921566, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 0.93333334, g: 0.654902, b: 0.43921563, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1} - _SpecColor: {r: 0.07352942, g: 0.07352942, b: 0.07352942, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -12,7 +12,7 @@ TagManager: ...@@ -12,7 +12,7 @@ TagManager:
- Water - Water
- UI - UI
- AnimalParts - AnimalParts
- - IncorrectAnimal
- -
- -
- -
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment