[{"data":1,"prerenderedAt":4585},["ShallowReactive",2],{"post-/kwd-qabl-liaadh-alastkhdam-wqabl-lltwsa-fy-unity-ar":3,"author-رائد-البحري-ar":4567},{"id":4,"title":5,"author":6,"body":7,"category":4543,"description":4544,"extension":4545,"image":4546,"isDraft":4547,"isFeatured":4547,"locale":4548,"meta":4549,"navigation":157,"path":4554,"publishedAt":4555,"readingTime":384,"seo":4556,"stem":4557,"tags":4558,"updatedAt":4565,"__hash__":4566},"articles_ar/كود-قابل-لإعادة-الاستخدام-وقابل-للتوسع-في-unity.md","بناء كود قابل لإعادة الاستخدام وقابل للتوسع في Unity: دليل كامل لعام 2025","رائد-البحري",{"type":8,"value":9,"toc":4517},"minimark",[10,14,19,24,30,43,48,62,67,81,87,91,123,127,130,134,272,276,281,409,413,417,645,649,938,942,946,951,1026,1031,1209,1213,1218,1392,1396,1791,1795,2382,2386,2835,2839,3181,3185,3575,3579,4045,4049,4467,4471,4474,4480,4486,4492,4498,4504,4507,4513],[11,12,13],"p",{},"إنشاء كود معياري وقابل لإعادة الاستخدام في Unity هو مفهوم مهم لتطوير الألعاب بكفاءة. في 2025، مع استمرار تطور Unity وزيادة تعقيد مشاريع الألعاب، أصبح إتقان الهندسة المعمارية القابلة للتوسع أكثر أهمية من أي وقت مضى. يغطي هذا الدليل الشامل كل شيء من الأنماط الأساسية إلى المفاهيم المعمارية المتقدمة التي ستساعدك على بناء ألعاب يمكن أن تنمو من نماذج indie إلى عناوين AAA.",[15,16,18],"h2",{"id":17},"لماذا-يهم-الكود-القابل-للتوسع-في-unity","لماذا يهم الكود القابل للتوسع في Unity",[20,21,23],"h3",{"id":22},"تكلفة-الهندسة-المعمارية-السيئة","تكلفة الهندسة المعمارية السيئة",[11,25,26],{},[27,28,29],"strong",{},"تطوير اللعبة المبكر (الأشهر 1-3):",[31,32,33,37,40],"ul",{},[34,35,36],"li",{},"كل شيء يعمل بشكل مثالي",[34,38,39],{},"الكود بسيط ومباشر",[34,41,42],{},"التغييرات سهلة الإجراء",[11,44,45],{},[27,46,47],{},"تطوير اللعبة المتوسط (الأشهر 4-12):",[31,49,50,53,56,59],{},[34,51,52],{},"قاعدة الكود تنمو إلى 10,000+ سطر",[34,54,55],{},"الميزات تصبح مترابطة",[34,57,58],{},"التغييرات البسيطة تكسر أنظمة متعددة",[34,60,61],{},"سرعة التطوير تبطئ إلى سحب",[11,63,64],{},[27,65,66],{},"تطوير اللعبة المتأخر (الأشهر 13+):",[31,68,69,72,75,78],{},[34,70,71],{},"حجم الفريق ينمو إلى 5-20+ شخص",[34,73,74],{},"ميزات متعددة في التطوير المتوازي",[34,76,77],{},"الديون التقنية تسبب أخطاء مستمرة",[34,79,80],{},"الإصدارات تتأخر بسبب قضايا معمارية",[11,82,83,86],{},[27,84,85],{},"الواقع:"," 70% من مشاريع تطوير الألعاب تفشل بسبب قضايا تقنية، مع كون الهندسة المعمارية السيئة سبباً رئيسياً.",[20,88,90],{"id":89},"فوائد-الهندسة-المعمارية-القابلة-للتوسع","فوائد الهندسة المعمارية القابلة للتوسع",[31,92,93,99,105,111,117],{},[34,94,95,98],{},[27,96,97],{},"تطوير أسرع:"," الميزات الجديدة تأخذ أياماً، لا أسابيع",[34,100,101,104],{},[27,102,103],{},"صيانة أسهل:"," الأخطاء معزولة وقابلة للإصلاح",[34,106,107,110],{},[27,108,109],{},"تعاون الفريق:"," مطورون متعددون يمكنهم العمل بدون تعارضات",[34,112,113,116],{},[27,114,115],{},"مستقبل آمن:"," سهل إضافة ميزات ومنصات جديدة",[34,118,119,122],{},[27,120,121],{},"أداء:"," تحسين وإدارة ذاكرة أفضل",[15,124,126],{"id":125},"_1-scriptableobjects-تصميم-اللعبة-المدفوع-بالبيانات","1. ScriptableObjects: تصميم اللعبة المدفوع بالبيانات",[11,128,129],{},"ScriptableObjects هي أقوى ميزة Unity وأقل استخداماً. تفصل البيانات عن المنطق، مما يتيح تصميم لعبة مدفوع بالبيانات حقيقي.",[20,131,133],{"id":132},"إعداد-scriptableobject-الأساسي","إعداد ScriptableObject الأساسي",[135,136,141],"pre",{"className":137,"code":138,"language":139,"meta":140,"style":140},"language-csharp shiki shiki-themes github-light dark-plus dark-plus","using UnityEngine;\n\n[CreateAssetMenu(fileName = \"NewWeaponData\", menuName = \"Game/Weapon Data\")]\npublic class WeaponData : ScriptableObject\n{\n    [Header(\"Basic Info\")]\n    public string weaponName;\n    public Sprite icon;\n    public GameObject prefab;\n    \n    [Header(\"Stats\")]\n    public float damage = 10f;\n    public float fireRate = 1f;\n    public int maxAmmo = 30;\n    public float range = 50f;\n    \n    [Header(\"Visual Effects\")]\n    public ParticleSystem muzzleFlash;\n    public AudioClip fireSound;\n    public TrailRenderer bulletTrail;\n}\n","csharp","",[142,143,144,152,159,165,171,177,183,189,195,201,207,213,219,225,231,237,242,248,254,260,266],"code",{"__ignoreMap":140},[145,146,149],"span",{"class":147,"line":148},"line",1,[145,150,151],{},"using UnityEngine;\n",[145,153,155],{"class":147,"line":154},2,[145,156,158],{"emptyLinePlaceholder":157},true,"\n",[145,160,162],{"class":147,"line":161},3,[145,163,164],{},"[CreateAssetMenu(fileName = \"NewWeaponData\", menuName = \"Game/Weapon Data\")]\n",[145,166,168],{"class":147,"line":167},4,[145,169,170],{},"public class WeaponData : ScriptableObject\n",[145,172,174],{"class":147,"line":173},5,[145,175,176],{},"{\n",[145,178,180],{"class":147,"line":179},6,[145,181,182],{},"    [Header(\"Basic Info\")]\n",[145,184,186],{"class":147,"line":185},7,[145,187,188],{},"    public string weaponName;\n",[145,190,192],{"class":147,"line":191},8,[145,193,194],{},"    public Sprite icon;\n",[145,196,198],{"class":147,"line":197},9,[145,199,200],{},"    public GameObject prefab;\n",[145,202,204],{"class":147,"line":203},10,[145,205,206],{},"    \n",[145,208,210],{"class":147,"line":209},11,[145,211,212],{},"    [Header(\"Stats\")]\n",[145,214,216],{"class":147,"line":215},12,[145,217,218],{},"    public float damage = 10f;\n",[145,220,222],{"class":147,"line":221},13,[145,223,224],{},"    public float fireRate = 1f;\n",[145,226,228],{"class":147,"line":227},14,[145,229,230],{},"    public int maxAmmo = 30;\n",[145,232,234],{"class":147,"line":233},15,[145,235,236],{},"    public float range = 50f;\n",[145,238,240],{"class":147,"line":239},16,[145,241,206],{},[145,243,245],{"class":147,"line":244},17,[145,246,247],{},"    [Header(\"Visual Effects\")]\n",[145,249,251],{"class":147,"line":250},18,[145,252,253],{},"    public ParticleSystem muzzleFlash;\n",[145,255,257],{"class":147,"line":256},19,[145,258,259],{},"    public AudioClip fireSound;\n",[145,261,263],{"class":147,"line":262},20,[145,264,265],{},"    public TrailRenderer bulletTrail;\n",[145,267,269],{"class":147,"line":268},21,[145,270,271],{},"}\n",[20,273,275],{"id":274},"scriptableobjects-المدفوعة-بالأحداث","ScriptableObjects المدفوعة بالأحداث",[11,277,278],{},[27,279,280],{},"نظام GameEvent:",[135,282,284],{"className":137,"code":283,"language":139,"meta":140,"style":140},"using UnityEngine;\nusing UnityEngine.Events;\n\n[CreateAssetMenu(fileName = \"NewGameEvent\", menuName = \"Game/Game Event\")]\npublic class GameEvent : ScriptableObject\n{\n    [TextArea(3, 10)]\n    public string description;\n    \n    private UnityEvent onRaised = new UnityEvent();\n    \n    public void Raise()\n    {\n        onRaised.Invoke();\n    }\n    \n    public void RegisterListener(UnityAction listener)\n    {\n        onRaised.AddListener(listener);\n    }\n    \n    public void UnregisterListener(UnityAction listener)\n    {\n        onRaised.RemoveListener(listener);\n    }\n}\n",[142,285,286,290,295,299,304,309,313,318,323,327,332,336,341,346,351,356,360,365,369,374,378,382,388,393,399,404],{"__ignoreMap":140},[145,287,288],{"class":147,"line":148},[145,289,151],{},[145,291,292],{"class":147,"line":154},[145,293,294],{},"using UnityEngine.Events;\n",[145,296,297],{"class":147,"line":161},[145,298,158],{"emptyLinePlaceholder":157},[145,300,301],{"class":147,"line":167},[145,302,303],{},"[CreateAssetMenu(fileName = \"NewGameEvent\", menuName = \"Game/Game Event\")]\n",[145,305,306],{"class":147,"line":173},[145,307,308],{},"public class GameEvent : ScriptableObject\n",[145,310,311],{"class":147,"line":179},[145,312,176],{},[145,314,315],{"class":147,"line":185},[145,316,317],{},"    [TextArea(3, 10)]\n",[145,319,320],{"class":147,"line":191},[145,321,322],{},"    public string description;\n",[145,324,325],{"class":147,"line":197},[145,326,206],{},[145,328,329],{"class":147,"line":203},[145,330,331],{},"    private UnityEvent onRaised = new UnityEvent();\n",[145,333,334],{"class":147,"line":209},[145,335,206],{},[145,337,338],{"class":147,"line":215},[145,339,340],{},"    public void Raise()\n",[145,342,343],{"class":147,"line":221},[145,344,345],{},"    {\n",[145,347,348],{"class":147,"line":227},[145,349,350],{},"        onRaised.Invoke();\n",[145,352,353],{"class":147,"line":233},[145,354,355],{},"    }\n",[145,357,358],{"class":147,"line":239},[145,359,206],{},[145,361,362],{"class":147,"line":244},[145,363,364],{},"    public void RegisterListener(UnityAction listener)\n",[145,366,367],{"class":147,"line":250},[145,368,345],{},[145,370,371],{"class":147,"line":256},[145,372,373],{},"        onRaised.AddListener(listener);\n",[145,375,376],{"class":147,"line":262},[145,377,355],{},[145,379,380],{"class":147,"line":268},[145,381,206],{},[145,383,385],{"class":147,"line":384},22,[145,386,387],{},"    public void UnregisterListener(UnityAction listener)\n",[145,389,391],{"class":147,"line":390},23,[145,392,345],{},[145,394,396],{"class":147,"line":395},24,[145,397,398],{},"        onRaised.RemoveListener(listener);\n",[145,400,402],{"class":147,"line":401},25,[145,403,355],{},[145,405,407],{"class":147,"line":406},26,[145,408,271],{},[15,410,412],{"id":411},"_2-أنماط-التصميم-الأساسية-للألعاب","2. أنماط التصميم الأساسية للألعاب",[20,414,416],{"id":415},"نمط-singleton-للمديرين-العامين","نمط Singleton للمديرين العامين",[135,418,420],{"className":137,"code":419,"language":139,"meta":140,"style":140},"using UnityEngine;\n\npublic class GameManager : MonoBehaviour\n{\n    private static GameManager instance;\n    public static GameManager Instance\n    {\n        get\n        {\n            if (instance == null)\n            {\n                instance = FindObjectOfType\u003CGameManager>();\n                if (instance == null)\n                {\n                    GameObject obj = new GameObject(\"GameManager\");\n                    instance = obj.AddComponent\u003CGameManager>();\n                }\n            }\n            return instance;\n        }\n    }\n    \n    private void Awake()\n    {\n        if (instance != null && instance != this)\n        {\n            Destroy(gameObject);\n            return;\n        }\n        \n        instance = this;\n        DontDestroyOnLoad(gameObject);\n    }\n    \n    // Game state management\n    public int score = 0;\n    public bool isPaused = false;\n    \n    public void AddScore(int points)\n    {\n        score += points;\n        // Trigger score update events\n    }\n}\n",[142,421,422,426,430,435,439,444,449,453,458,463,468,473,478,483,488,493,498,503,508,513,518,522,526,531,535,540,544,550,556,561,567,573,579,584,589,595,601,607,612,618,623,629,635,640],{"__ignoreMap":140},[145,423,424],{"class":147,"line":148},[145,425,151],{},[145,427,428],{"class":147,"line":154},[145,429,158],{"emptyLinePlaceholder":157},[145,431,432],{"class":147,"line":161},[145,433,434],{},"public class GameManager : MonoBehaviour\n",[145,436,437],{"class":147,"line":167},[145,438,176],{},[145,440,441],{"class":147,"line":173},[145,442,443],{},"    private static GameManager instance;\n",[145,445,446],{"class":147,"line":179},[145,447,448],{},"    public static GameManager Instance\n",[145,450,451],{"class":147,"line":185},[145,452,345],{},[145,454,455],{"class":147,"line":191},[145,456,457],{},"        get\n",[145,459,460],{"class":147,"line":197},[145,461,462],{},"        {\n",[145,464,465],{"class":147,"line":203},[145,466,467],{},"            if (instance == null)\n",[145,469,470],{"class":147,"line":209},[145,471,472],{},"            {\n",[145,474,475],{"class":147,"line":215},[145,476,477],{},"                instance = FindObjectOfType\u003CGameManager>();\n",[145,479,480],{"class":147,"line":221},[145,481,482],{},"                if (instance == null)\n",[145,484,485],{"class":147,"line":227},[145,486,487],{},"                {\n",[145,489,490],{"class":147,"line":233},[145,491,492],{},"                    GameObject obj = new GameObject(\"GameManager\");\n",[145,494,495],{"class":147,"line":239},[145,496,497],{},"                    instance = obj.AddComponent\u003CGameManager>();\n",[145,499,500],{"class":147,"line":244},[145,501,502],{},"                }\n",[145,504,505],{"class":147,"line":250},[145,506,507],{},"            }\n",[145,509,510],{"class":147,"line":256},[145,511,512],{},"            return instance;\n",[145,514,515],{"class":147,"line":262},[145,516,517],{},"        }\n",[145,519,520],{"class":147,"line":268},[145,521,355],{},[145,523,524],{"class":147,"line":384},[145,525,206],{},[145,527,528],{"class":147,"line":390},[145,529,530],{},"    private void Awake()\n",[145,532,533],{"class":147,"line":395},[145,534,345],{},[145,536,537],{"class":147,"line":401},[145,538,539],{},"        if (instance != null && instance != this)\n",[145,541,542],{"class":147,"line":406},[145,543,462],{},[145,545,547],{"class":147,"line":546},27,[145,548,549],{},"            Destroy(gameObject);\n",[145,551,553],{"class":147,"line":552},28,[145,554,555],{},"            return;\n",[145,557,559],{"class":147,"line":558},29,[145,560,517],{},[145,562,564],{"class":147,"line":563},30,[145,565,566],{},"        \n",[145,568,570],{"class":147,"line":569},31,[145,571,572],{},"        instance = this;\n",[145,574,576],{"class":147,"line":575},32,[145,577,578],{},"        DontDestroyOnLoad(gameObject);\n",[145,580,582],{"class":147,"line":581},33,[145,583,355],{},[145,585,587],{"class":147,"line":586},34,[145,588,206],{},[145,590,592],{"class":147,"line":591},35,[145,593,594],{},"    // Game state management\n",[145,596,598],{"class":147,"line":597},36,[145,599,600],{},"    public int score = 0;\n",[145,602,604],{"class":147,"line":603},37,[145,605,606],{},"    public bool isPaused = false;\n",[145,608,610],{"class":147,"line":609},38,[145,611,206],{},[145,613,615],{"class":147,"line":614},39,[145,616,617],{},"    public void AddScore(int points)\n",[145,619,621],{"class":147,"line":620},40,[145,622,345],{},[145,624,626],{"class":147,"line":625},41,[145,627,628],{},"        score += points;\n",[145,630,632],{"class":147,"line":631},42,[145,633,634],{},"        // Trigger score update events\n",[145,636,638],{"class":147,"line":637},43,[145,639,355],{},[145,641,643],{"class":147,"line":642},44,[145,644,271],{},[20,646,648],{"id":647},"نمط-object-pool-لتحسين-الأداء","نمط Object Pool لتحسين الأداء",[135,650,652],{"className":137,"code":651,"language":139,"meta":140,"style":140},"using System.Collections.Generic;\nusing UnityEngine;\n\npublic class ObjectPool\u003CT> : MonoBehaviour where T : Component\n{\n    [SerializeField] private T prefab;\n    [SerializeField] private int initialSize = 10;\n    \n    private Queue\u003CT> pool = new Queue\u003CT>();\n    private List\u003CT> activeObjects = new List\u003CT>();\n    \n    private void Awake()\n    {\n        InitializePool();\n    }\n    \n    private void InitializePool()\n    {\n        for (int i = 0; i \u003C initialSize; i++)\n        {\n            CreateNewObject();\n        }\n    }\n    \n    private T CreateNewObject()\n    {\n        T newObj = Instantiate(prefab, transform);\n        newObj.gameObject.SetActive(false);\n        pool.Enqueue(newObj);\n        return newObj;\n    }\n    \n    public T GetObject()\n    {\n        if (pool.Count == 0)\n        {\n            CreateNewObject();\n        }\n        \n        T obj = pool.Dequeue();\n        obj.gameObject.SetActive(true);\n        activeObjects.Add(obj);\n        return obj;\n    }\n    \n    public void ReturnObject(T obj)\n    {\n        obj.gameObject.SetActive(false);\n        activeObjects.Remove(obj);\n        pool.Enqueue(obj);\n    }\n    \n    public void ReturnAllObjects()\n    {\n        foreach (T obj in activeObjects.ToArray())\n        {\n            ReturnObject(obj);\n        }\n    }\n}\n",[142,653,654,659,663,667,672,676,681,686,690,695,700,704,708,712,717,721,725,730,734,739,743,748,752,756,760,765,769,774,779,784,789,793,797,802,806,811,815,819,823,827,832,837,842,847,851,856,862,867,873,879,885,890,895,901,906,912,917,923,928,933],{"__ignoreMap":140},[145,655,656],{"class":147,"line":148},[145,657,658],{},"using System.Collections.Generic;\n",[145,660,661],{"class":147,"line":154},[145,662,151],{},[145,664,665],{"class":147,"line":161},[145,666,158],{"emptyLinePlaceholder":157},[145,668,669],{"class":147,"line":167},[145,670,671],{},"public class ObjectPool\u003CT> : MonoBehaviour where T : Component\n",[145,673,674],{"class":147,"line":173},[145,675,176],{},[145,677,678],{"class":147,"line":179},[145,679,680],{},"    [SerializeField] private T prefab;\n",[145,682,683],{"class":147,"line":185},[145,684,685],{},"    [SerializeField] private int initialSize = 10;\n",[145,687,688],{"class":147,"line":191},[145,689,206],{},[145,691,692],{"class":147,"line":197},[145,693,694],{},"    private Queue\u003CT> pool = new Queue\u003CT>();\n",[145,696,697],{"class":147,"line":203},[145,698,699],{},"    private List\u003CT> activeObjects = new List\u003CT>();\n",[145,701,702],{"class":147,"line":209},[145,703,206],{},[145,705,706],{"class":147,"line":215},[145,707,530],{},[145,709,710],{"class":147,"line":221},[145,711,345],{},[145,713,714],{"class":147,"line":227},[145,715,716],{},"        InitializePool();\n",[145,718,719],{"class":147,"line":233},[145,720,355],{},[145,722,723],{"class":147,"line":239},[145,724,206],{},[145,726,727],{"class":147,"line":244},[145,728,729],{},"    private void InitializePool()\n",[145,731,732],{"class":147,"line":250},[145,733,345],{},[145,735,736],{"class":147,"line":256},[145,737,738],{},"        for (int i = 0; i \u003C initialSize; i++)\n",[145,740,741],{"class":147,"line":262},[145,742,462],{},[145,744,745],{"class":147,"line":268},[145,746,747],{},"            CreateNewObject();\n",[145,749,750],{"class":147,"line":384},[145,751,517],{},[145,753,754],{"class":147,"line":390},[145,755,355],{},[145,757,758],{"class":147,"line":395},[145,759,206],{},[145,761,762],{"class":147,"line":401},[145,763,764],{},"    private T CreateNewObject()\n",[145,766,767],{"class":147,"line":406},[145,768,345],{},[145,770,771],{"class":147,"line":546},[145,772,773],{},"        T newObj = Instantiate(prefab, transform);\n",[145,775,776],{"class":147,"line":552},[145,777,778],{},"        newObj.gameObject.SetActive(false);\n",[145,780,781],{"class":147,"line":558},[145,782,783],{},"        pool.Enqueue(newObj);\n",[145,785,786],{"class":147,"line":563},[145,787,788],{},"        return newObj;\n",[145,790,791],{"class":147,"line":569},[145,792,355],{},[145,794,795],{"class":147,"line":575},[145,796,206],{},[145,798,799],{"class":147,"line":581},[145,800,801],{},"    public T GetObject()\n",[145,803,804],{"class":147,"line":586},[145,805,345],{},[145,807,808],{"class":147,"line":591},[145,809,810],{},"        if (pool.Count == 0)\n",[145,812,813],{"class":147,"line":597},[145,814,462],{},[145,816,817],{"class":147,"line":603},[145,818,747],{},[145,820,821],{"class":147,"line":609},[145,822,517],{},[145,824,825],{"class":147,"line":614},[145,826,566],{},[145,828,829],{"class":147,"line":620},[145,830,831],{},"        T obj = pool.Dequeue();\n",[145,833,834],{"class":147,"line":625},[145,835,836],{},"        obj.gameObject.SetActive(true);\n",[145,838,839],{"class":147,"line":631},[145,840,841],{},"        activeObjects.Add(obj);\n",[145,843,844],{"class":147,"line":637},[145,845,846],{},"        return obj;\n",[145,848,849],{"class":147,"line":642},[145,850,355],{},[145,852,854],{"class":147,"line":853},45,[145,855,206],{},[145,857,859],{"class":147,"line":858},46,[145,860,861],{},"    public void ReturnObject(T obj)\n",[145,863,865],{"class":147,"line":864},47,[145,866,345],{},[145,868,870],{"class":147,"line":869},48,[145,871,872],{},"        obj.gameObject.SetActive(false);\n",[145,874,876],{"class":147,"line":875},49,[145,877,878],{},"        activeObjects.Remove(obj);\n",[145,880,882],{"class":147,"line":881},50,[145,883,884],{},"        pool.Enqueue(obj);\n",[145,886,888],{"class":147,"line":887},51,[145,889,355],{},[145,891,893],{"class":147,"line":892},52,[145,894,206],{},[145,896,898],{"class":147,"line":897},53,[145,899,900],{},"    public void ReturnAllObjects()\n",[145,902,904],{"class":147,"line":903},54,[145,905,345],{},[145,907,909],{"class":147,"line":908},55,[145,910,911],{},"        foreach (T obj in activeObjects.ToArray())\n",[145,913,915],{"class":147,"line":914},56,[145,916,462],{},[145,918,920],{"class":147,"line":919},57,[145,921,922],{},"            ReturnObject(obj);\n",[145,924,926],{"class":147,"line":925},58,[145,927,517],{},[145,929,931],{"class":147,"line":930},59,[145,932,355],{},[145,934,936],{"class":147,"line":935},60,[145,937,271],{},[15,939,941],{"id":940},"_3-مبادئ-solid-في-unity","3. مبادئ SOLID في Unity",[20,943,945],{"id":944},"single-responsibility-principle-srp","Single Responsibility Principle (SRP)",[11,947,948],{},[27,949,950],{},"سيء - فئة تفعل الكثير:",[135,952,954],{"className":137,"code":953,"language":139,"meta":140,"style":140},"public class Player : MonoBehaviour\n{\n    // Movement\n    public float speed = 5f;\n    private Rigidbody rb;\n    \n    // Health\n    public int maxHealth = 100;\n    private int currentHealth;\n    \n    // Animation\n    private Animator animator;\n    \n    // Input handling, collision detection, UI updates...\n}\n",[142,955,956,961,965,970,975,980,984,989,994,999,1003,1008,1013,1017,1022],{"__ignoreMap":140},[145,957,958],{"class":147,"line":148},[145,959,960],{},"public class Player : MonoBehaviour\n",[145,962,963],{"class":147,"line":154},[145,964,176],{},[145,966,967],{"class":147,"line":161},[145,968,969],{},"    // Movement\n",[145,971,972],{"class":147,"line":167},[145,973,974],{},"    public float speed = 5f;\n",[145,976,977],{"class":147,"line":173},[145,978,979],{},"    private Rigidbody rb;\n",[145,981,982],{"class":147,"line":179},[145,983,206],{},[145,985,986],{"class":147,"line":185},[145,987,988],{},"    // Health\n",[145,990,991],{"class":147,"line":191},[145,992,993],{},"    public int maxHealth = 100;\n",[145,995,996],{"class":147,"line":197},[145,997,998],{},"    private int currentHealth;\n",[145,1000,1001],{"class":147,"line":203},[145,1002,206],{},[145,1004,1005],{"class":147,"line":209},[145,1006,1007],{},"    // Animation\n",[145,1009,1010],{"class":147,"line":215},[145,1011,1012],{},"    private Animator animator;\n",[145,1014,1015],{"class":147,"line":221},[145,1016,206],{},[145,1018,1019],{"class":147,"line":227},[145,1020,1021],{},"    // Input handling, collision detection, UI updates...\n",[145,1023,1024],{"class":147,"line":233},[145,1025,271],{},[11,1027,1028],{},[27,1029,1030],{},"جيد - فصل المسؤوليات:",[135,1032,1034],{"className":137,"code":1033,"language":139,"meta":140,"style":140},"public class PlayerMovement : MonoBehaviour\n{\n    [SerializeField] private float speed = 5f;\n    private Rigidbody rb;\n    \n    private void FixedUpdate()\n    {\n        float horizontal = Input.GetAxis(\"Horizontal\");\n        float vertical = Input.GetAxis(\"Vertical\");\n        \n        Vector3 movement = new Vector3(horizontal, 0f, vertical) * speed;\n        rb.AddForce(movement);\n    }\n}\n\npublic class PlayerHealth : MonoBehaviour\n{\n    [SerializeField] private int maxHealth = 100;\n    private int currentHealth;\n    \n    public event Action\u003Cint> OnHealthChanged;\n    public event Action OnDeath;\n    \n    private void Awake()\n    {\n        currentHealth = maxHealth;\n    }\n    \n    public void TakeDamage(int damage)\n    {\n        currentHealth -= damage;\n        OnHealthChanged?.Invoke(currentHealth);\n        \n        if (currentHealth \u003C= 0)\n        {\n            OnDeath?.Invoke();\n        }\n    }\n}\n",[142,1035,1036,1041,1045,1050,1054,1058,1063,1067,1072,1077,1081,1086,1091,1095,1099,1103,1108,1112,1117,1121,1125,1130,1135,1139,1143,1147,1152,1156,1160,1165,1169,1174,1179,1183,1188,1192,1197,1201,1205],{"__ignoreMap":140},[145,1037,1038],{"class":147,"line":148},[145,1039,1040],{},"public class PlayerMovement : MonoBehaviour\n",[145,1042,1043],{"class":147,"line":154},[145,1044,176],{},[145,1046,1047],{"class":147,"line":161},[145,1048,1049],{},"    [SerializeField] private float speed = 5f;\n",[145,1051,1052],{"class":147,"line":167},[145,1053,979],{},[145,1055,1056],{"class":147,"line":173},[145,1057,206],{},[145,1059,1060],{"class":147,"line":179},[145,1061,1062],{},"    private void FixedUpdate()\n",[145,1064,1065],{"class":147,"line":185},[145,1066,345],{},[145,1068,1069],{"class":147,"line":191},[145,1070,1071],{},"        float horizontal = Input.GetAxis(\"Horizontal\");\n",[145,1073,1074],{"class":147,"line":197},[145,1075,1076],{},"        float vertical = Input.GetAxis(\"Vertical\");\n",[145,1078,1079],{"class":147,"line":203},[145,1080,566],{},[145,1082,1083],{"class":147,"line":209},[145,1084,1085],{},"        Vector3 movement = new Vector3(horizontal, 0f, vertical) * speed;\n",[145,1087,1088],{"class":147,"line":215},[145,1089,1090],{},"        rb.AddForce(movement);\n",[145,1092,1093],{"class":147,"line":221},[145,1094,355],{},[145,1096,1097],{"class":147,"line":227},[145,1098,271],{},[145,1100,1101],{"class":147,"line":233},[145,1102,158],{"emptyLinePlaceholder":157},[145,1104,1105],{"class":147,"line":239},[145,1106,1107],{},"public class PlayerHealth : MonoBehaviour\n",[145,1109,1110],{"class":147,"line":244},[145,1111,176],{},[145,1113,1114],{"class":147,"line":250},[145,1115,1116],{},"    [SerializeField] private int maxHealth = 100;\n",[145,1118,1119],{"class":147,"line":256},[145,1120,998],{},[145,1122,1123],{"class":147,"line":262},[145,1124,206],{},[145,1126,1127],{"class":147,"line":268},[145,1128,1129],{},"    public event Action\u003Cint> OnHealthChanged;\n",[145,1131,1132],{"class":147,"line":384},[145,1133,1134],{},"    public event Action OnDeath;\n",[145,1136,1137],{"class":147,"line":390},[145,1138,206],{},[145,1140,1141],{"class":147,"line":395},[145,1142,530],{},[145,1144,1145],{"class":147,"line":401},[145,1146,345],{},[145,1148,1149],{"class":147,"line":406},[145,1150,1151],{},"        currentHealth = maxHealth;\n",[145,1153,1154],{"class":147,"line":546},[145,1155,355],{},[145,1157,1158],{"class":147,"line":552},[145,1159,206],{},[145,1161,1162],{"class":147,"line":558},[145,1163,1164],{},"    public void TakeDamage(int damage)\n",[145,1166,1167],{"class":147,"line":563},[145,1168,345],{},[145,1170,1171],{"class":147,"line":569},[145,1172,1173],{},"        currentHealth -= damage;\n",[145,1175,1176],{"class":147,"line":575},[145,1177,1178],{},"        OnHealthChanged?.Invoke(currentHealth);\n",[145,1180,1181],{"class":147,"line":581},[145,1182,566],{},[145,1184,1185],{"class":147,"line":586},[145,1186,1187],{},"        if (currentHealth \u003C= 0)\n",[145,1189,1190],{"class":147,"line":591},[145,1191,462],{},[145,1193,1194],{"class":147,"line":597},[145,1195,1196],{},"            OnDeath?.Invoke();\n",[145,1198,1199],{"class":147,"line":603},[145,1200,517],{},[145,1202,1203],{"class":147,"line":609},[145,1204,355],{},[145,1206,1207],{"class":147,"line":614},[145,1208,271],{},[20,1210,1212],{"id":1211},"dependency-inversion-principle-dip","Dependency Inversion Principle (DIP)",[11,1214,1215],{},[27,1216,1217],{},"استخدم الواجهات للتبعيات:",[135,1219,1221],{"className":137,"code":1220,"language":139,"meta":140,"style":140},"public interface IDamageable\n{\n    void TakeDamage(int damage);\n    bool IsAlive { get; }\n}\n\npublic interface IInteractable\n{\n    void Interact(GameObject interactor);\n    string InteractionPrompt { get; }\n}\n\npublic class Enemy : MonoBehaviour, IDamageable\n{\n    [SerializeField] private int maxHealth = 50;\n    private int currentHealth;\n    \n    public bool IsAlive => currentHealth > 0;\n    \n    private void Awake()\n    {\n        currentHealth = maxHealth;\n    }\n    \n    public void TakeDamage(int damage)\n    {\n        currentHealth -= damage;\n        if (currentHealth \u003C= 0)\n        {\n            Die();\n        }\n    }\n    \n    private void Die()\n    {\n        // Death logic\n        Destroy(gameObject);\n    }\n}\n",[142,1222,1223,1228,1232,1237,1242,1246,1250,1255,1259,1264,1269,1273,1277,1282,1286,1291,1295,1299,1304,1308,1312,1316,1320,1324,1328,1332,1336,1340,1344,1348,1353,1357,1361,1365,1370,1374,1379,1384,1388],{"__ignoreMap":140},[145,1224,1225],{"class":147,"line":148},[145,1226,1227],{},"public interface IDamageable\n",[145,1229,1230],{"class":147,"line":154},[145,1231,176],{},[145,1233,1234],{"class":147,"line":161},[145,1235,1236],{},"    void TakeDamage(int damage);\n",[145,1238,1239],{"class":147,"line":167},[145,1240,1241],{},"    bool IsAlive { get; }\n",[145,1243,1244],{"class":147,"line":173},[145,1245,271],{},[145,1247,1248],{"class":147,"line":179},[145,1249,158],{"emptyLinePlaceholder":157},[145,1251,1252],{"class":147,"line":185},[145,1253,1254],{},"public interface IInteractable\n",[145,1256,1257],{"class":147,"line":191},[145,1258,176],{},[145,1260,1261],{"class":147,"line":197},[145,1262,1263],{},"    void Interact(GameObject interactor);\n",[145,1265,1266],{"class":147,"line":203},[145,1267,1268],{},"    string InteractionPrompt { get; }\n",[145,1270,1271],{"class":147,"line":209},[145,1272,271],{},[145,1274,1275],{"class":147,"line":215},[145,1276,158],{"emptyLinePlaceholder":157},[145,1278,1279],{"class":147,"line":221},[145,1280,1281],{},"public class Enemy : MonoBehaviour, IDamageable\n",[145,1283,1284],{"class":147,"line":227},[145,1285,176],{},[145,1287,1288],{"class":147,"line":233},[145,1289,1290],{},"    [SerializeField] private int maxHealth = 50;\n",[145,1292,1293],{"class":147,"line":239},[145,1294,998],{},[145,1296,1297],{"class":147,"line":244},[145,1298,206],{},[145,1300,1301],{"class":147,"line":250},[145,1302,1303],{},"    public bool IsAlive => currentHealth > 0;\n",[145,1305,1306],{"class":147,"line":256},[145,1307,206],{},[145,1309,1310],{"class":147,"line":262},[145,1311,530],{},[145,1313,1314],{"class":147,"line":268},[145,1315,345],{},[145,1317,1318],{"class":147,"line":384},[145,1319,1151],{},[145,1321,1322],{"class":147,"line":390},[145,1323,355],{},[145,1325,1326],{"class":147,"line":395},[145,1327,206],{},[145,1329,1330],{"class":147,"line":401},[145,1331,1164],{},[145,1333,1334],{"class":147,"line":406},[145,1335,345],{},[145,1337,1338],{"class":147,"line":546},[145,1339,1173],{},[145,1341,1342],{"class":147,"line":552},[145,1343,1187],{},[145,1345,1346],{"class":147,"line":558},[145,1347,462],{},[145,1349,1350],{"class":147,"line":563},[145,1351,1352],{},"            Die();\n",[145,1354,1355],{"class":147,"line":569},[145,1356,517],{},[145,1358,1359],{"class":147,"line":575},[145,1360,355],{},[145,1362,1363],{"class":147,"line":581},[145,1364,206],{},[145,1366,1367],{"class":147,"line":586},[145,1368,1369],{},"    private void Die()\n",[145,1371,1372],{"class":147,"line":591},[145,1373,345],{},[145,1375,1376],{"class":147,"line":597},[145,1377,1378],{},"        // Death logic\n",[145,1380,1381],{"class":147,"line":603},[145,1382,1383],{},"        Destroy(gameObject);\n",[145,1385,1386],{"class":147,"line":609},[145,1387,355],{},[145,1389,1390],{"class":147,"line":614},[145,1391,271],{},[15,1393,1395],{"id":1394},"_4-نظام-service-locator","4. نظام Service Locator",[135,1397,1399],{"className":137,"code":1398,"language":139,"meta":140,"style":140},"using System;\nusing System.Collections.Generic;\nusing UnityEngine;\n\npublic class ServiceLocator : MonoBehaviour\n{\n    private static ServiceLocator instance;\n    public static ServiceLocator Instance => instance;\n    \n    private readonly Dictionary\u003CType, object> services = new Dictionary\u003CType, object>();\n    \n    private void Awake()\n    {\n        if (instance != null && instance != this)\n        {\n            Destroy(gameObject);\n            return;\n        }\n        \n        instance = this;\n        DontDestroyOnLoad(gameObject);\n    }\n    \n    public void RegisterService\u003CT>(T service)\n    {\n        services[typeof(T)] = service;\n    }\n    \n    public void UnregisterService\u003CT>()\n    {\n        services.Remove(typeof(T));\n    }\n    \n    public T GetService\u003CT>()\n    {\n        if (services.TryGetValue(typeof(T), out object service))\n        {\n            return (T)service;\n        }\n        \n        throw new Exception($\"Service {typeof(T)} not registered!\");\n    }\n    \n    public bool TryGetService\u003CT>(out T service)\n    {\n        if (services.TryGetValue(typeof(T), out object obj))\n        {\n            service = (T)obj;\n            return true;\n        }\n        \n        service = default;\n        return false;\n    }\n}\n\n// Usage\npublic class AudioManager : MonoBehaviour\n{\n    private void Awake()\n    {\n        ServiceLocator.Instance.RegisterService\u003CAudioManager>(this);\n    }\n    \n    public void PlaySound(AudioClip clip)\n    {\n        // Play sound logic\n    }\n}\n\npublic class PlayerController : MonoBehaviour\n{\n    private AudioManager audioManager;\n    \n    private void Start()\n    {\n        audioManager = ServiceLocator.Instance.GetService\u003CAudioManager>();\n    }\n    \n    private void OnJump()\n    {\n        audioManager.PlaySound(jumpSound);\n    }\n}\n",[142,1400,1401,1406,1410,1414,1418,1423,1427,1432,1437,1441,1446,1450,1454,1458,1462,1466,1470,1474,1478,1482,1486,1490,1494,1498,1503,1507,1512,1516,1520,1525,1529,1534,1538,1542,1547,1551,1556,1560,1565,1569,1573,1578,1582,1586,1591,1595,1600,1604,1609,1614,1618,1622,1627,1632,1636,1640,1644,1649,1654,1658,1662,1667,1673,1678,1683,1689,1694,1700,1705,1710,1715,1721,1726,1732,1737,1743,1748,1754,1759,1764,1770,1775,1781,1786],{"__ignoreMap":140},[145,1402,1403],{"class":147,"line":148},[145,1404,1405],{},"using System;\n",[145,1407,1408],{"class":147,"line":154},[145,1409,658],{},[145,1411,1412],{"class":147,"line":161},[145,1413,151],{},[145,1415,1416],{"class":147,"line":167},[145,1417,158],{"emptyLinePlaceholder":157},[145,1419,1420],{"class":147,"line":173},[145,1421,1422],{},"public class ServiceLocator : MonoBehaviour\n",[145,1424,1425],{"class":147,"line":179},[145,1426,176],{},[145,1428,1429],{"class":147,"line":185},[145,1430,1431],{},"    private static ServiceLocator instance;\n",[145,1433,1434],{"class":147,"line":191},[145,1435,1436],{},"    public static ServiceLocator Instance => instance;\n",[145,1438,1439],{"class":147,"line":197},[145,1440,206],{},[145,1442,1443],{"class":147,"line":203},[145,1444,1445],{},"    private readonly Dictionary\u003CType, object> services = new Dictionary\u003CType, object>();\n",[145,1447,1448],{"class":147,"line":209},[145,1449,206],{},[145,1451,1452],{"class":147,"line":215},[145,1453,530],{},[145,1455,1456],{"class":147,"line":221},[145,1457,345],{},[145,1459,1460],{"class":147,"line":227},[145,1461,539],{},[145,1463,1464],{"class":147,"line":233},[145,1465,462],{},[145,1467,1468],{"class":147,"line":239},[145,1469,549],{},[145,1471,1472],{"class":147,"line":244},[145,1473,555],{},[145,1475,1476],{"class":147,"line":250},[145,1477,517],{},[145,1479,1480],{"class":147,"line":256},[145,1481,566],{},[145,1483,1484],{"class":147,"line":262},[145,1485,572],{},[145,1487,1488],{"class":147,"line":268},[145,1489,578],{},[145,1491,1492],{"class":147,"line":384},[145,1493,355],{},[145,1495,1496],{"class":147,"line":390},[145,1497,206],{},[145,1499,1500],{"class":147,"line":395},[145,1501,1502],{},"    public void RegisterService\u003CT>(T service)\n",[145,1504,1505],{"class":147,"line":401},[145,1506,345],{},[145,1508,1509],{"class":147,"line":406},[145,1510,1511],{},"        services[typeof(T)] = service;\n",[145,1513,1514],{"class":147,"line":546},[145,1515,355],{},[145,1517,1518],{"class":147,"line":552},[145,1519,206],{},[145,1521,1522],{"class":147,"line":558},[145,1523,1524],{},"    public void UnregisterService\u003CT>()\n",[145,1526,1527],{"class":147,"line":563},[145,1528,345],{},[145,1530,1531],{"class":147,"line":569},[145,1532,1533],{},"        services.Remove(typeof(T));\n",[145,1535,1536],{"class":147,"line":575},[145,1537,355],{},[145,1539,1540],{"class":147,"line":581},[145,1541,206],{},[145,1543,1544],{"class":147,"line":586},[145,1545,1546],{},"    public T GetService\u003CT>()\n",[145,1548,1549],{"class":147,"line":591},[145,1550,345],{},[145,1552,1553],{"class":147,"line":597},[145,1554,1555],{},"        if (services.TryGetValue(typeof(T), out object service))\n",[145,1557,1558],{"class":147,"line":603},[145,1559,462],{},[145,1561,1562],{"class":147,"line":609},[145,1563,1564],{},"            return (T)service;\n",[145,1566,1567],{"class":147,"line":614},[145,1568,517],{},[145,1570,1571],{"class":147,"line":620},[145,1572,566],{},[145,1574,1575],{"class":147,"line":625},[145,1576,1577],{},"        throw new Exception($\"Service {typeof(T)} not registered!\");\n",[145,1579,1580],{"class":147,"line":631},[145,1581,355],{},[145,1583,1584],{"class":147,"line":637},[145,1585,206],{},[145,1587,1588],{"class":147,"line":642},[145,1589,1590],{},"    public bool TryGetService\u003CT>(out T service)\n",[145,1592,1593],{"class":147,"line":853},[145,1594,345],{},[145,1596,1597],{"class":147,"line":858},[145,1598,1599],{},"        if (services.TryGetValue(typeof(T), out object obj))\n",[145,1601,1602],{"class":147,"line":864},[145,1603,462],{},[145,1605,1606],{"class":147,"line":869},[145,1607,1608],{},"            service = (T)obj;\n",[145,1610,1611],{"class":147,"line":875},[145,1612,1613],{},"            return true;\n",[145,1615,1616],{"class":147,"line":881},[145,1617,517],{},[145,1619,1620],{"class":147,"line":887},[145,1621,566],{},[145,1623,1624],{"class":147,"line":892},[145,1625,1626],{},"        service = default;\n",[145,1628,1629],{"class":147,"line":897},[145,1630,1631],{},"        return false;\n",[145,1633,1634],{"class":147,"line":903},[145,1635,355],{},[145,1637,1638],{"class":147,"line":908},[145,1639,271],{},[145,1641,1642],{"class":147,"line":914},[145,1643,158],{"emptyLinePlaceholder":157},[145,1645,1646],{"class":147,"line":919},[145,1647,1648],{},"// Usage\n",[145,1650,1651],{"class":147,"line":925},[145,1652,1653],{},"public class AudioManager : MonoBehaviour\n",[145,1655,1656],{"class":147,"line":930},[145,1657,176],{},[145,1659,1660],{"class":147,"line":935},[145,1661,530],{},[145,1663,1665],{"class":147,"line":1664},61,[145,1666,345],{},[145,1668,1670],{"class":147,"line":1669},62,[145,1671,1672],{},"        ServiceLocator.Instance.RegisterService\u003CAudioManager>(this);\n",[145,1674,1676],{"class":147,"line":1675},63,[145,1677,355],{},[145,1679,1681],{"class":147,"line":1680},64,[145,1682,206],{},[145,1684,1686],{"class":147,"line":1685},65,[145,1687,1688],{},"    public void PlaySound(AudioClip clip)\n",[145,1690,1692],{"class":147,"line":1691},66,[145,1693,345],{},[145,1695,1697],{"class":147,"line":1696},67,[145,1698,1699],{},"        // Play sound logic\n",[145,1701,1703],{"class":147,"line":1702},68,[145,1704,355],{},[145,1706,1708],{"class":147,"line":1707},69,[145,1709,271],{},[145,1711,1713],{"class":147,"line":1712},70,[145,1714,158],{"emptyLinePlaceholder":157},[145,1716,1718],{"class":147,"line":1717},71,[145,1719,1720],{},"public class PlayerController : MonoBehaviour\n",[145,1722,1724],{"class":147,"line":1723},72,[145,1725,176],{},[145,1727,1729],{"class":147,"line":1728},73,[145,1730,1731],{},"    private AudioManager audioManager;\n",[145,1733,1735],{"class":147,"line":1734},74,[145,1736,206],{},[145,1738,1740],{"class":147,"line":1739},75,[145,1741,1742],{},"    private void Start()\n",[145,1744,1746],{"class":147,"line":1745},76,[145,1747,345],{},[145,1749,1751],{"class":147,"line":1750},77,[145,1752,1753],{},"        audioManager = ServiceLocator.Instance.GetService\u003CAudioManager>();\n",[145,1755,1757],{"class":147,"line":1756},78,[145,1758,355],{},[145,1760,1762],{"class":147,"line":1761},79,[145,1763,206],{},[145,1765,1767],{"class":147,"line":1766},80,[145,1768,1769],{},"    private void OnJump()\n",[145,1771,1773],{"class":147,"line":1772},81,[145,1774,345],{},[145,1776,1778],{"class":147,"line":1777},82,[145,1779,1780],{},"        audioManager.PlaySound(jumpSound);\n",[145,1782,1784],{"class":147,"line":1783},83,[145,1785,355],{},[145,1787,1789],{"class":147,"line":1788},84,[145,1790,271],{},[15,1792,1794],{"id":1793},"_5-أنماط-state-للأعداء-واللاعبين","5. أنماط State للأعداء واللاعبين",[135,1796,1798],{"className":137,"code":1797,"language":139,"meta":140,"style":140},"using UnityEngine;\n\npublic abstract class State\n{\n    protected Enemy enemy;\n    \n    public State(Enemy enemy)\n    {\n        this.enemy = enemy;\n    }\n    \n    public abstract void Enter();\n    public abstract void Update();\n    public abstract void Exit();\n}\n\npublic class Enemy : MonoBehaviour\n{\n    [SerializeField] private float patrolSpeed = 2f;\n    [SerializeField] private float chaseSpeed = 4f;\n    [SerializeField] private float detectionRange = 10f;\n    \n    private State currentState;\n    \n    public Transform Player { get; set; }\n    public float Speed { get; set; } = 2f;\n    \n    private void Start()\n    {\n        Player = GameObject.FindGameObjectWithTag(\"Player\").transform;\n        ChangeState(new PatrolState(this));\n    }\n    \n    private void Update()\n    {\n        currentState?.Update();\n    }\n    \n    public void ChangeState(State newState)\n    {\n        currentState?.Exit();\n        currentState = newState;\n        currentState.Enter();\n    }\n    \n    public bool CanSeePlayer()\n    {\n        return Vector3.Distance(transform.position, Player.position) \u003C= detectionRange;\n    }\n}\n\npublic class PatrolState : State\n{\n    private Vector3 patrolPoint;\n    private float patrolTimer;\n    \n    public PatrolState(Enemy enemy) : base(enemy) { }\n    \n    public override void Enter()\n    {\n        enemy.Speed = enemy.patrolSpeed;\n        SetNewPatrolPoint();\n    }\n    \n    public override void Update()\n    {\n        patrolTimer -= Time.deltaTime;\n        \n        if (patrolTimer \u003C= 0)\n        {\n            SetNewPatrolPoint();\n        }\n        \n        // Move towards patrol point\n        enemy.transform.position = Vector3.MoveTowards(\n            enemy.transform.position, \n            patrolPoint, \n            enemy.Speed * Time.deltaTime\n        );\n        \n        if (enemy.CanSeePlayer())\n        {\n            enemy.ChangeState(new ChaseState(enemy));\n        }\n    }\n    \n    public override void Exit() { }\n    \n    private void SetNewPatrolPoint()\n    {\n        patrolTimer = Random.Range(3f, 8f);\n        patrolPoint = enemy.transform.position + \n            new Vector3(Random.Range(-5f, 5f), 0f, Random.Range(-5f, 5f));\n    }\n}\n\npublic class ChaseState : State\n{\n    public ChaseState(Enemy enemy) : base(enemy) { }\n    \n    public override void Enter()\n    {\n        enemy.Speed = enemy.chaseSpeed;\n    }\n    \n    public override void Update()\n    {\n        // Move towards player\n        enemy.transform.position = Vector3.MoveTowards(\n            enemy.transform.position,\n            enemy.Player.position,\n            enemy.Speed * Time.deltaTime\n        );\n        \n        if (!enemy.CanSeePlayer())\n        {\n            enemy.ChangeState(new PatrolState(enemy));\n        }\n    }\n    \n    public override void Exit() { }\n}\n",[142,1799,1800,1804,1808,1813,1817,1822,1826,1831,1835,1840,1844,1848,1853,1858,1863,1867,1871,1876,1880,1885,1890,1895,1899,1904,1908,1913,1918,1922,1926,1930,1935,1940,1944,1948,1953,1957,1962,1966,1970,1975,1979,1984,1989,1994,1998,2002,2007,2011,2016,2020,2024,2028,2033,2037,2042,2047,2051,2056,2060,2065,2069,2074,2079,2083,2087,2092,2096,2101,2105,2110,2114,2119,2123,2127,2132,2137,2142,2147,2152,2157,2161,2166,2170,2175,2179,2184,2189,2195,2200,2206,2211,2217,2223,2229,2234,2239,2244,2250,2255,2261,2266,2271,2276,2282,2287,2292,2297,2302,2308,2313,2319,2325,2330,2335,2340,2346,2351,2357,2362,2367,2372,2377],{"__ignoreMap":140},[145,1801,1802],{"class":147,"line":148},[145,1803,151],{},[145,1805,1806],{"class":147,"line":154},[145,1807,158],{"emptyLinePlaceholder":157},[145,1809,1810],{"class":147,"line":161},[145,1811,1812],{},"public abstract class State\n",[145,1814,1815],{"class":147,"line":167},[145,1816,176],{},[145,1818,1819],{"class":147,"line":173},[145,1820,1821],{},"    protected Enemy enemy;\n",[145,1823,1824],{"class":147,"line":179},[145,1825,206],{},[145,1827,1828],{"class":147,"line":185},[145,1829,1830],{},"    public State(Enemy enemy)\n",[145,1832,1833],{"class":147,"line":191},[145,1834,345],{},[145,1836,1837],{"class":147,"line":197},[145,1838,1839],{},"        this.enemy = enemy;\n",[145,1841,1842],{"class":147,"line":203},[145,1843,355],{},[145,1845,1846],{"class":147,"line":209},[145,1847,206],{},[145,1849,1850],{"class":147,"line":215},[145,1851,1852],{},"    public abstract void Enter();\n",[145,1854,1855],{"class":147,"line":221},[145,1856,1857],{},"    public abstract void Update();\n",[145,1859,1860],{"class":147,"line":227},[145,1861,1862],{},"    public abstract void Exit();\n",[145,1864,1865],{"class":147,"line":233},[145,1866,271],{},[145,1868,1869],{"class":147,"line":239},[145,1870,158],{"emptyLinePlaceholder":157},[145,1872,1873],{"class":147,"line":244},[145,1874,1875],{},"public class Enemy : MonoBehaviour\n",[145,1877,1878],{"class":147,"line":250},[145,1879,176],{},[145,1881,1882],{"class":147,"line":256},[145,1883,1884],{},"    [SerializeField] private float patrolSpeed = 2f;\n",[145,1886,1887],{"class":147,"line":262},[145,1888,1889],{},"    [SerializeField] private float chaseSpeed = 4f;\n",[145,1891,1892],{"class":147,"line":268},[145,1893,1894],{},"    [SerializeField] private float detectionRange = 10f;\n",[145,1896,1897],{"class":147,"line":384},[145,1898,206],{},[145,1900,1901],{"class":147,"line":390},[145,1902,1903],{},"    private State currentState;\n",[145,1905,1906],{"class":147,"line":395},[145,1907,206],{},[145,1909,1910],{"class":147,"line":401},[145,1911,1912],{},"    public Transform Player { get; set; }\n",[145,1914,1915],{"class":147,"line":406},[145,1916,1917],{},"    public float Speed { get; set; } = 2f;\n",[145,1919,1920],{"class":147,"line":546},[145,1921,206],{},[145,1923,1924],{"class":147,"line":552},[145,1925,1742],{},[145,1927,1928],{"class":147,"line":558},[145,1929,345],{},[145,1931,1932],{"class":147,"line":563},[145,1933,1934],{},"        Player = GameObject.FindGameObjectWithTag(\"Player\").transform;\n",[145,1936,1937],{"class":147,"line":569},[145,1938,1939],{},"        ChangeState(new PatrolState(this));\n",[145,1941,1942],{"class":147,"line":575},[145,1943,355],{},[145,1945,1946],{"class":147,"line":581},[145,1947,206],{},[145,1949,1950],{"class":147,"line":586},[145,1951,1952],{},"    private void Update()\n",[145,1954,1955],{"class":147,"line":591},[145,1956,345],{},[145,1958,1959],{"class":147,"line":597},[145,1960,1961],{},"        currentState?.Update();\n",[145,1963,1964],{"class":147,"line":603},[145,1965,355],{},[145,1967,1968],{"class":147,"line":609},[145,1969,206],{},[145,1971,1972],{"class":147,"line":614},[145,1973,1974],{},"    public void ChangeState(State newState)\n",[145,1976,1977],{"class":147,"line":620},[145,1978,345],{},[145,1980,1981],{"class":147,"line":625},[145,1982,1983],{},"        currentState?.Exit();\n",[145,1985,1986],{"class":147,"line":631},[145,1987,1988],{},"        currentState = newState;\n",[145,1990,1991],{"class":147,"line":637},[145,1992,1993],{},"        currentState.Enter();\n",[145,1995,1996],{"class":147,"line":642},[145,1997,355],{},[145,1999,2000],{"class":147,"line":853},[145,2001,206],{},[145,2003,2004],{"class":147,"line":858},[145,2005,2006],{},"    public bool CanSeePlayer()\n",[145,2008,2009],{"class":147,"line":864},[145,2010,345],{},[145,2012,2013],{"class":147,"line":869},[145,2014,2015],{},"        return Vector3.Distance(transform.position, Player.position) \u003C= detectionRange;\n",[145,2017,2018],{"class":147,"line":875},[145,2019,355],{},[145,2021,2022],{"class":147,"line":881},[145,2023,271],{},[145,2025,2026],{"class":147,"line":887},[145,2027,158],{"emptyLinePlaceholder":157},[145,2029,2030],{"class":147,"line":892},[145,2031,2032],{},"public class PatrolState : State\n",[145,2034,2035],{"class":147,"line":897},[145,2036,176],{},[145,2038,2039],{"class":147,"line":903},[145,2040,2041],{},"    private Vector3 patrolPoint;\n",[145,2043,2044],{"class":147,"line":908},[145,2045,2046],{},"    private float patrolTimer;\n",[145,2048,2049],{"class":147,"line":914},[145,2050,206],{},[145,2052,2053],{"class":147,"line":919},[145,2054,2055],{},"    public PatrolState(Enemy enemy) : base(enemy) { }\n",[145,2057,2058],{"class":147,"line":925},[145,2059,206],{},[145,2061,2062],{"class":147,"line":930},[145,2063,2064],{},"    public override void Enter()\n",[145,2066,2067],{"class":147,"line":935},[145,2068,345],{},[145,2070,2071],{"class":147,"line":1664},[145,2072,2073],{},"        enemy.Speed = enemy.patrolSpeed;\n",[145,2075,2076],{"class":147,"line":1669},[145,2077,2078],{},"        SetNewPatrolPoint();\n",[145,2080,2081],{"class":147,"line":1675},[145,2082,355],{},[145,2084,2085],{"class":147,"line":1680},[145,2086,206],{},[145,2088,2089],{"class":147,"line":1685},[145,2090,2091],{},"    public override void Update()\n",[145,2093,2094],{"class":147,"line":1691},[145,2095,345],{},[145,2097,2098],{"class":147,"line":1696},[145,2099,2100],{},"        patrolTimer -= Time.deltaTime;\n",[145,2102,2103],{"class":147,"line":1702},[145,2104,566],{},[145,2106,2107],{"class":147,"line":1707},[145,2108,2109],{},"        if (patrolTimer \u003C= 0)\n",[145,2111,2112],{"class":147,"line":1712},[145,2113,462],{},[145,2115,2116],{"class":147,"line":1717},[145,2117,2118],{},"            SetNewPatrolPoint();\n",[145,2120,2121],{"class":147,"line":1723},[145,2122,517],{},[145,2124,2125],{"class":147,"line":1728},[145,2126,566],{},[145,2128,2129],{"class":147,"line":1734},[145,2130,2131],{},"        // Move towards patrol point\n",[145,2133,2134],{"class":147,"line":1739},[145,2135,2136],{},"        enemy.transform.position = Vector3.MoveTowards(\n",[145,2138,2139],{"class":147,"line":1745},[145,2140,2141],{},"            enemy.transform.position, \n",[145,2143,2144],{"class":147,"line":1750},[145,2145,2146],{},"            patrolPoint, \n",[145,2148,2149],{"class":147,"line":1756},[145,2150,2151],{},"            enemy.Speed * Time.deltaTime\n",[145,2153,2154],{"class":147,"line":1761},[145,2155,2156],{},"        );\n",[145,2158,2159],{"class":147,"line":1766},[145,2160,566],{},[145,2162,2163],{"class":147,"line":1772},[145,2164,2165],{},"        if (enemy.CanSeePlayer())\n",[145,2167,2168],{"class":147,"line":1777},[145,2169,462],{},[145,2171,2172],{"class":147,"line":1783},[145,2173,2174],{},"            enemy.ChangeState(new ChaseState(enemy));\n",[145,2176,2177],{"class":147,"line":1788},[145,2178,517],{},[145,2180,2182],{"class":147,"line":2181},85,[145,2183,355],{},[145,2185,2187],{"class":147,"line":2186},86,[145,2188,206],{},[145,2190,2192],{"class":147,"line":2191},87,[145,2193,2194],{},"    public override void Exit() { }\n",[145,2196,2198],{"class":147,"line":2197},88,[145,2199,206],{},[145,2201,2203],{"class":147,"line":2202},89,[145,2204,2205],{},"    private void SetNewPatrolPoint()\n",[145,2207,2209],{"class":147,"line":2208},90,[145,2210,345],{},[145,2212,2214],{"class":147,"line":2213},91,[145,2215,2216],{},"        patrolTimer = Random.Range(3f, 8f);\n",[145,2218,2220],{"class":147,"line":2219},92,[145,2221,2222],{},"        patrolPoint = enemy.transform.position + \n",[145,2224,2226],{"class":147,"line":2225},93,[145,2227,2228],{},"            new Vector3(Random.Range(-5f, 5f), 0f, Random.Range(-5f, 5f));\n",[145,2230,2232],{"class":147,"line":2231},94,[145,2233,355],{},[145,2235,2237],{"class":147,"line":2236},95,[145,2238,271],{},[145,2240,2242],{"class":147,"line":2241},96,[145,2243,158],{"emptyLinePlaceholder":157},[145,2245,2247],{"class":147,"line":2246},97,[145,2248,2249],{},"public class ChaseState : State\n",[145,2251,2253],{"class":147,"line":2252},98,[145,2254,176],{},[145,2256,2258],{"class":147,"line":2257},99,[145,2259,2260],{},"    public ChaseState(Enemy enemy) : base(enemy) { }\n",[145,2262,2264],{"class":147,"line":2263},100,[145,2265,206],{},[145,2267,2269],{"class":147,"line":2268},101,[145,2270,2064],{},[145,2272,2274],{"class":147,"line":2273},102,[145,2275,345],{},[145,2277,2279],{"class":147,"line":2278},103,[145,2280,2281],{},"        enemy.Speed = enemy.chaseSpeed;\n",[145,2283,2285],{"class":147,"line":2284},104,[145,2286,355],{},[145,2288,2290],{"class":147,"line":2289},105,[145,2291,206],{},[145,2293,2295],{"class":147,"line":2294},106,[145,2296,2091],{},[145,2298,2300],{"class":147,"line":2299},107,[145,2301,345],{},[145,2303,2305],{"class":147,"line":2304},108,[145,2306,2307],{},"        // Move towards player\n",[145,2309,2311],{"class":147,"line":2310},109,[145,2312,2136],{},[145,2314,2316],{"class":147,"line":2315},110,[145,2317,2318],{},"            enemy.transform.position,\n",[145,2320,2322],{"class":147,"line":2321},111,[145,2323,2324],{},"            enemy.Player.position,\n",[145,2326,2328],{"class":147,"line":2327},112,[145,2329,2151],{},[145,2331,2333],{"class":147,"line":2332},113,[145,2334,2156],{},[145,2336,2338],{"class":147,"line":2337},114,[145,2339,566],{},[145,2341,2343],{"class":147,"line":2342},115,[145,2344,2345],{},"        if (!enemy.CanSeePlayer())\n",[145,2347,2349],{"class":147,"line":2348},116,[145,2350,462],{},[145,2352,2354],{"class":147,"line":2353},117,[145,2355,2356],{},"            enemy.ChangeState(new PatrolState(enemy));\n",[145,2358,2360],{"class":147,"line":2359},118,[145,2361,517],{},[145,2363,2365],{"class":147,"line":2364},119,[145,2366,355],{},[145,2368,2370],{"class":147,"line":2369},120,[145,2371,206],{},[145,2373,2375],{"class":147,"line":2374},121,[145,2376,2194],{},[145,2378,2380],{"class":147,"line":2379},122,[145,2381,271],{},[15,2383,2385],{"id":2384},"_6-نظام-saveload-قابل-للتوسع","6. نظام Save/Load قابل للتوسع",[135,2387,2389],{"className":137,"code":2388,"language":139,"meta":140,"style":140},"using System.IO;\nusing UnityEngine;\n\n[System.Serializable]\npublic class GameSaveData\n{\n    public int level;\n    public int score;\n    public Vector3 playerPosition;\n    public string[] inventory;\n    public bool[] completedLevels;\n}\n\npublic static class SaveLoadSystem\n{\n    private static readonly string saveFileName = \"gameSave.json\";\n    \n    public static void SaveGame(GameSaveData data)\n    {\n        string json = JsonUtility.ToJson(data, true);\n        string path = Path.Combine(Application.persistentDataPath, saveFileName);\n        File.WriteAllText(path, json);\n    }\n    \n    public static GameSaveData LoadGame()\n    {\n        string path = Path.Combine(Application.persistentDataPath, saveFileName);\n        \n        if (File.Exists(path))\n        {\n            string json = File.ReadAllText(path);\n            return JsonUtility.FromJson\u003CGameSaveData>(json);\n        }\n        \n        return new GameSaveData(); // Return default save\n    }\n    \n    public static bool HasSaveFile()\n    {\n        string path = Path.Combine(Application.persistentDataPath, saveFileName);\n        return File.Exists(path);\n    }\n    \n    public static void DeleteSaveFile()\n    {\n        string path = Path.Combine(Application.persistentDataPath, saveFileName);\n        if (File.Exists(path))\n        {\n            File.Delete(path);\n        }\n    }\n}\n\n// Usage\npublic class GameManager : MonoBehaviour\n{\n    public static GameManager Instance { get; private set; }\n    \n    public int currentLevel = 1;\n    public int score = 0;\n    public Vector3 playerPosition;\n    \n    private void Awake()\n    {\n        if (Instance == null)\n        {\n            Instance = this;\n            LoadGame();\n        }\n    }\n    \n    private void OnApplicationQuit()\n    {\n        SaveGame();\n    }\n    \n    public void SaveGame()\n    {\n        GameSaveData saveData = new GameSaveData\n        {\n            level = currentLevel,\n            score = score,\n            playerPosition = playerPosition,\n            // Add other save data\n        };\n        \n        SaveLoadSystem.SaveGame(saveData);\n    }\n    \n    public void LoadGame()\n    {\n        if (SaveLoadSystem.HasSaveFile())\n        {\n            GameSaveData saveData = SaveLoadSystem.LoadGame();\n            currentLevel = saveData.level;\n            score = saveData.score;\n            playerPosition = saveData.playerPosition;\n        }\n    }\n}\n",[142,2390,2391,2396,2400,2404,2409,2414,2418,2423,2428,2433,2438,2443,2447,2451,2456,2460,2465,2469,2474,2478,2483,2488,2493,2497,2501,2506,2510,2514,2518,2523,2527,2532,2537,2541,2545,2550,2554,2558,2563,2567,2571,2576,2580,2584,2589,2593,2597,2601,2605,2610,2614,2618,2622,2626,2630,2634,2638,2643,2647,2652,2656,2660,2664,2668,2672,2677,2681,2686,2691,2695,2699,2703,2708,2712,2717,2721,2725,2730,2734,2739,2743,2748,2753,2758,2763,2768,2772,2777,2781,2785,2790,2794,2799,2803,2808,2813,2818,2823,2827,2831],{"__ignoreMap":140},[145,2392,2393],{"class":147,"line":148},[145,2394,2395],{},"using System.IO;\n",[145,2397,2398],{"class":147,"line":154},[145,2399,151],{},[145,2401,2402],{"class":147,"line":161},[145,2403,158],{"emptyLinePlaceholder":157},[145,2405,2406],{"class":147,"line":167},[145,2407,2408],{},"[System.Serializable]\n",[145,2410,2411],{"class":147,"line":173},[145,2412,2413],{},"public class GameSaveData\n",[145,2415,2416],{"class":147,"line":179},[145,2417,176],{},[145,2419,2420],{"class":147,"line":185},[145,2421,2422],{},"    public int level;\n",[145,2424,2425],{"class":147,"line":191},[145,2426,2427],{},"    public int score;\n",[145,2429,2430],{"class":147,"line":197},[145,2431,2432],{},"    public Vector3 playerPosition;\n",[145,2434,2435],{"class":147,"line":203},[145,2436,2437],{},"    public string[] inventory;\n",[145,2439,2440],{"class":147,"line":209},[145,2441,2442],{},"    public bool[] completedLevels;\n",[145,2444,2445],{"class":147,"line":215},[145,2446,271],{},[145,2448,2449],{"class":147,"line":221},[145,2450,158],{"emptyLinePlaceholder":157},[145,2452,2453],{"class":147,"line":227},[145,2454,2455],{},"public static class SaveLoadSystem\n",[145,2457,2458],{"class":147,"line":233},[145,2459,176],{},[145,2461,2462],{"class":147,"line":239},[145,2463,2464],{},"    private static readonly string saveFileName = \"gameSave.json\";\n",[145,2466,2467],{"class":147,"line":244},[145,2468,206],{},[145,2470,2471],{"class":147,"line":250},[145,2472,2473],{},"    public static void SaveGame(GameSaveData data)\n",[145,2475,2476],{"class":147,"line":256},[145,2477,345],{},[145,2479,2480],{"class":147,"line":262},[145,2481,2482],{},"        string json = JsonUtility.ToJson(data, true);\n",[145,2484,2485],{"class":147,"line":268},[145,2486,2487],{},"        string path = Path.Combine(Application.persistentDataPath, saveFileName);\n",[145,2489,2490],{"class":147,"line":384},[145,2491,2492],{},"        File.WriteAllText(path, json);\n",[145,2494,2495],{"class":147,"line":390},[145,2496,355],{},[145,2498,2499],{"class":147,"line":395},[145,2500,206],{},[145,2502,2503],{"class":147,"line":401},[145,2504,2505],{},"    public static GameSaveData LoadGame()\n",[145,2507,2508],{"class":147,"line":406},[145,2509,345],{},[145,2511,2512],{"class":147,"line":546},[145,2513,2487],{},[145,2515,2516],{"class":147,"line":552},[145,2517,566],{},[145,2519,2520],{"class":147,"line":558},[145,2521,2522],{},"        if (File.Exists(path))\n",[145,2524,2525],{"class":147,"line":563},[145,2526,462],{},[145,2528,2529],{"class":147,"line":569},[145,2530,2531],{},"            string json = File.ReadAllText(path);\n",[145,2533,2534],{"class":147,"line":575},[145,2535,2536],{},"            return JsonUtility.FromJson\u003CGameSaveData>(json);\n",[145,2538,2539],{"class":147,"line":581},[145,2540,517],{},[145,2542,2543],{"class":147,"line":586},[145,2544,566],{},[145,2546,2547],{"class":147,"line":591},[145,2548,2549],{},"        return new GameSaveData(); // Return default save\n",[145,2551,2552],{"class":147,"line":597},[145,2553,355],{},[145,2555,2556],{"class":147,"line":603},[145,2557,206],{},[145,2559,2560],{"class":147,"line":609},[145,2561,2562],{},"    public static bool HasSaveFile()\n",[145,2564,2565],{"class":147,"line":614},[145,2566,345],{},[145,2568,2569],{"class":147,"line":620},[145,2570,2487],{},[145,2572,2573],{"class":147,"line":625},[145,2574,2575],{},"        return File.Exists(path);\n",[145,2577,2578],{"class":147,"line":631},[145,2579,355],{},[145,2581,2582],{"class":147,"line":637},[145,2583,206],{},[145,2585,2586],{"class":147,"line":642},[145,2587,2588],{},"    public static void DeleteSaveFile()\n",[145,2590,2591],{"class":147,"line":853},[145,2592,345],{},[145,2594,2595],{"class":147,"line":858},[145,2596,2487],{},[145,2598,2599],{"class":147,"line":864},[145,2600,2522],{},[145,2602,2603],{"class":147,"line":869},[145,2604,462],{},[145,2606,2607],{"class":147,"line":875},[145,2608,2609],{},"            File.Delete(path);\n",[145,2611,2612],{"class":147,"line":881},[145,2613,517],{},[145,2615,2616],{"class":147,"line":887},[145,2617,355],{},[145,2619,2620],{"class":147,"line":892},[145,2621,271],{},[145,2623,2624],{"class":147,"line":897},[145,2625,158],{"emptyLinePlaceholder":157},[145,2627,2628],{"class":147,"line":903},[145,2629,1648],{},[145,2631,2632],{"class":147,"line":908},[145,2633,434],{},[145,2635,2636],{"class":147,"line":914},[145,2637,176],{},[145,2639,2640],{"class":147,"line":919},[145,2641,2642],{},"    public static GameManager Instance { get; private set; }\n",[145,2644,2645],{"class":147,"line":925},[145,2646,206],{},[145,2648,2649],{"class":147,"line":930},[145,2650,2651],{},"    public int currentLevel = 1;\n",[145,2653,2654],{"class":147,"line":935},[145,2655,600],{},[145,2657,2658],{"class":147,"line":1664},[145,2659,2432],{},[145,2661,2662],{"class":147,"line":1669},[145,2663,206],{},[145,2665,2666],{"class":147,"line":1675},[145,2667,530],{},[145,2669,2670],{"class":147,"line":1680},[145,2671,345],{},[145,2673,2674],{"class":147,"line":1685},[145,2675,2676],{},"        if (Instance == null)\n",[145,2678,2679],{"class":147,"line":1691},[145,2680,462],{},[145,2682,2683],{"class":147,"line":1696},[145,2684,2685],{},"            Instance = this;\n",[145,2687,2688],{"class":147,"line":1702},[145,2689,2690],{},"            LoadGame();\n",[145,2692,2693],{"class":147,"line":1707},[145,2694,517],{},[145,2696,2697],{"class":147,"line":1712},[145,2698,355],{},[145,2700,2701],{"class":147,"line":1717},[145,2702,206],{},[145,2704,2705],{"class":147,"line":1723},[145,2706,2707],{},"    private void OnApplicationQuit()\n",[145,2709,2710],{"class":147,"line":1728},[145,2711,345],{},[145,2713,2714],{"class":147,"line":1734},[145,2715,2716],{},"        SaveGame();\n",[145,2718,2719],{"class":147,"line":1739},[145,2720,355],{},[145,2722,2723],{"class":147,"line":1745},[145,2724,206],{},[145,2726,2727],{"class":147,"line":1750},[145,2728,2729],{},"    public void SaveGame()\n",[145,2731,2732],{"class":147,"line":1756},[145,2733,345],{},[145,2735,2736],{"class":147,"line":1761},[145,2737,2738],{},"        GameSaveData saveData = new GameSaveData\n",[145,2740,2741],{"class":147,"line":1766},[145,2742,462],{},[145,2744,2745],{"class":147,"line":1772},[145,2746,2747],{},"            level = currentLevel,\n",[145,2749,2750],{"class":147,"line":1777},[145,2751,2752],{},"            score = score,\n",[145,2754,2755],{"class":147,"line":1783},[145,2756,2757],{},"            playerPosition = playerPosition,\n",[145,2759,2760],{"class":147,"line":1788},[145,2761,2762],{},"            // Add other save data\n",[145,2764,2765],{"class":147,"line":2181},[145,2766,2767],{},"        };\n",[145,2769,2770],{"class":147,"line":2186},[145,2771,566],{},[145,2773,2774],{"class":147,"line":2191},[145,2775,2776],{},"        SaveLoadSystem.SaveGame(saveData);\n",[145,2778,2779],{"class":147,"line":2197},[145,2780,355],{},[145,2782,2783],{"class":147,"line":2202},[145,2784,206],{},[145,2786,2787],{"class":147,"line":2208},[145,2788,2789],{},"    public void LoadGame()\n",[145,2791,2792],{"class":147,"line":2213},[145,2793,345],{},[145,2795,2796],{"class":147,"line":2219},[145,2797,2798],{},"        if (SaveLoadSystem.HasSaveFile())\n",[145,2800,2801],{"class":147,"line":2225},[145,2802,462],{},[145,2804,2805],{"class":147,"line":2231},[145,2806,2807],{},"            GameSaveData saveData = SaveLoadSystem.LoadGame();\n",[145,2809,2810],{"class":147,"line":2236},[145,2811,2812],{},"            currentLevel = saveData.level;\n",[145,2814,2815],{"class":147,"line":2241},[145,2816,2817],{},"            score = saveData.score;\n",[145,2819,2820],{"class":147,"line":2246},[145,2821,2822],{},"            playerPosition = saveData.playerPosition;\n",[145,2824,2825],{"class":147,"line":2252},[145,2826,517],{},[145,2828,2829],{"class":147,"line":2257},[145,2830,355],{},[145,2832,2833],{"class":147,"line":2263},[145,2834,271],{},[15,2836,2838],{"id":2837},"_7-نظام-input-قابل-للتخصيص","7. نظام Input قابل للتخصيص",[135,2840,2842],{"className":137,"code":2841,"language":139,"meta":140,"style":140},"using System;\nusing UnityEngine;\n\n[Serializable]\npublic class InputBinding\n{\n    public string actionName;\n    public KeyCode primaryKey;\n    public KeyCode secondaryKey;\n    \n    public bool IsPressed()\n    {\n        return Input.GetKey(primaryKey) || Input.GetKey(secondaryKey);\n    }\n    \n    public bool IsDown()\n    {\n        return Input.GetKeyDown(primaryKey) || Input.GetKeyDown(secondaryKey);\n    }\n    \n    public bool IsUp()\n    {\n        return Input.GetKeyUp(primaryKey) || Input.GetKeyUp(secondaryKey);\n    }\n}\n\npublic class InputManager : MonoBehaviour\n{\n    public static InputManager Instance { get; private set; }\n    \n    [Header(\"Movement\")]\n    public InputBinding moveUp = new InputBinding { actionName = \"Move Up\", primaryKey = KeyCode.W };\n    public InputBinding moveDown = new InputBinding { actionName = \"Move Down\", primaryKey = KeyCode.S };\n    public InputBinding moveLeft = new InputBinding { actionName = \"Move Left\", primaryKey = KeyCode.A };\n    public InputBinding moveRight = new InputBinding { actionName = \"Move Right\", primaryKey = KeyCode.D };\n    \n    [Header(\"Actions\")]\n    public InputBinding jump = new InputBinding { actionName = \"Jump\", primaryKey = KeyCode.Space };\n    public InputBinding interact = new InputBinding { actionName = \"Interact\", primaryKey = KeyCode.E };\n    \n    private void Awake()\n    {\n        if (Instance == null)\n        {\n            Instance = this;\n            DontDestroyOnLoad(gameObject);\n            LoadInputBindings();\n        }\n        else\n        {\n            Destroy(gameObject);\n        }\n    }\n    \n    // Public methods for checking input\n    public bool IsMovingUp() => moveUp.IsPressed();\n    public bool IsMovingDown() => moveDown.IsPressed();\n    public bool IsMovingLeft() => moveLeft.IsPressed();\n    public bool IsMovingRight() => moveRight.IsPressed();\n    \n    public bool JumpPressed() => jump.IsDown();\n    public bool InteractPressed() => interact.IsDown();\n    \n    // Save/Load input bindings\n    private void LoadInputBindings()\n    {\n        // Load from PlayerPrefs or file\n        // Implementation depends on your save system\n    }\n    \n    public void ResetToDefaults()\n    {\n        // Reset all bindings to default values\n    }\n}\n",[142,2843,2844,2848,2852,2856,2861,2866,2870,2875,2880,2885,2889,2894,2898,2903,2907,2911,2916,2920,2925,2929,2933,2938,2942,2947,2951,2955,2959,2964,2968,2973,2977,2982,2987,2992,2997,3002,3006,3011,3016,3021,3025,3029,3033,3037,3041,3045,3050,3055,3059,3064,3068,3072,3076,3080,3084,3089,3094,3099,3104,3109,3113,3118,3123,3127,3132,3137,3141,3146,3151,3155,3159,3164,3168,3173,3177],{"__ignoreMap":140},[145,2845,2846],{"class":147,"line":148},[145,2847,1405],{},[145,2849,2850],{"class":147,"line":154},[145,2851,151],{},[145,2853,2854],{"class":147,"line":161},[145,2855,158],{"emptyLinePlaceholder":157},[145,2857,2858],{"class":147,"line":167},[145,2859,2860],{},"[Serializable]\n",[145,2862,2863],{"class":147,"line":173},[145,2864,2865],{},"public class InputBinding\n",[145,2867,2868],{"class":147,"line":179},[145,2869,176],{},[145,2871,2872],{"class":147,"line":185},[145,2873,2874],{},"    public string actionName;\n",[145,2876,2877],{"class":147,"line":191},[145,2878,2879],{},"    public KeyCode primaryKey;\n",[145,2881,2882],{"class":147,"line":197},[145,2883,2884],{},"    public KeyCode secondaryKey;\n",[145,2886,2887],{"class":147,"line":203},[145,2888,206],{},[145,2890,2891],{"class":147,"line":209},[145,2892,2893],{},"    public bool IsPressed()\n",[145,2895,2896],{"class":147,"line":215},[145,2897,345],{},[145,2899,2900],{"class":147,"line":221},[145,2901,2902],{},"        return Input.GetKey(primaryKey) || Input.GetKey(secondaryKey);\n",[145,2904,2905],{"class":147,"line":227},[145,2906,355],{},[145,2908,2909],{"class":147,"line":233},[145,2910,206],{},[145,2912,2913],{"class":147,"line":239},[145,2914,2915],{},"    public bool IsDown()\n",[145,2917,2918],{"class":147,"line":244},[145,2919,345],{},[145,2921,2922],{"class":147,"line":250},[145,2923,2924],{},"        return Input.GetKeyDown(primaryKey) || Input.GetKeyDown(secondaryKey);\n",[145,2926,2927],{"class":147,"line":256},[145,2928,355],{},[145,2930,2931],{"class":147,"line":262},[145,2932,206],{},[145,2934,2935],{"class":147,"line":268},[145,2936,2937],{},"    public bool IsUp()\n",[145,2939,2940],{"class":147,"line":384},[145,2941,345],{},[145,2943,2944],{"class":147,"line":390},[145,2945,2946],{},"        return Input.GetKeyUp(primaryKey) || Input.GetKeyUp(secondaryKey);\n",[145,2948,2949],{"class":147,"line":395},[145,2950,355],{},[145,2952,2953],{"class":147,"line":401},[145,2954,271],{},[145,2956,2957],{"class":147,"line":406},[145,2958,158],{"emptyLinePlaceholder":157},[145,2960,2961],{"class":147,"line":546},[145,2962,2963],{},"public class InputManager : MonoBehaviour\n",[145,2965,2966],{"class":147,"line":552},[145,2967,176],{},[145,2969,2970],{"class":147,"line":558},[145,2971,2972],{},"    public static InputManager Instance { get; private set; }\n",[145,2974,2975],{"class":147,"line":563},[145,2976,206],{},[145,2978,2979],{"class":147,"line":569},[145,2980,2981],{},"    [Header(\"Movement\")]\n",[145,2983,2984],{"class":147,"line":575},[145,2985,2986],{},"    public InputBinding moveUp = new InputBinding { actionName = \"Move Up\", primaryKey = KeyCode.W };\n",[145,2988,2989],{"class":147,"line":581},[145,2990,2991],{},"    public InputBinding moveDown = new InputBinding { actionName = \"Move Down\", primaryKey = KeyCode.S };\n",[145,2993,2994],{"class":147,"line":586},[145,2995,2996],{},"    public InputBinding moveLeft = new InputBinding { actionName = \"Move Left\", primaryKey = KeyCode.A };\n",[145,2998,2999],{"class":147,"line":591},[145,3000,3001],{},"    public InputBinding moveRight = new InputBinding { actionName = \"Move Right\", primaryKey = KeyCode.D };\n",[145,3003,3004],{"class":147,"line":597},[145,3005,206],{},[145,3007,3008],{"class":147,"line":603},[145,3009,3010],{},"    [Header(\"Actions\")]\n",[145,3012,3013],{"class":147,"line":609},[145,3014,3015],{},"    public InputBinding jump = new InputBinding { actionName = \"Jump\", primaryKey = KeyCode.Space };\n",[145,3017,3018],{"class":147,"line":614},[145,3019,3020],{},"    public InputBinding interact = new InputBinding { actionName = \"Interact\", primaryKey = KeyCode.E };\n",[145,3022,3023],{"class":147,"line":620},[145,3024,206],{},[145,3026,3027],{"class":147,"line":625},[145,3028,530],{},[145,3030,3031],{"class":147,"line":631},[145,3032,345],{},[145,3034,3035],{"class":147,"line":637},[145,3036,2676],{},[145,3038,3039],{"class":147,"line":642},[145,3040,462],{},[145,3042,3043],{"class":147,"line":853},[145,3044,2685],{},[145,3046,3047],{"class":147,"line":858},[145,3048,3049],{},"            DontDestroyOnLoad(gameObject);\n",[145,3051,3052],{"class":147,"line":864},[145,3053,3054],{},"            LoadInputBindings();\n",[145,3056,3057],{"class":147,"line":869},[145,3058,517],{},[145,3060,3061],{"class":147,"line":875},[145,3062,3063],{},"        else\n",[145,3065,3066],{"class":147,"line":881},[145,3067,462],{},[145,3069,3070],{"class":147,"line":887},[145,3071,549],{},[145,3073,3074],{"class":147,"line":892},[145,3075,517],{},[145,3077,3078],{"class":147,"line":897},[145,3079,355],{},[145,3081,3082],{"class":147,"line":903},[145,3083,206],{},[145,3085,3086],{"class":147,"line":908},[145,3087,3088],{},"    // Public methods for checking input\n",[145,3090,3091],{"class":147,"line":914},[145,3092,3093],{},"    public bool IsMovingUp() => moveUp.IsPressed();\n",[145,3095,3096],{"class":147,"line":919},[145,3097,3098],{},"    public bool IsMovingDown() => moveDown.IsPressed();\n",[145,3100,3101],{"class":147,"line":925},[145,3102,3103],{},"    public bool IsMovingLeft() => moveLeft.IsPressed();\n",[145,3105,3106],{"class":147,"line":930},[145,3107,3108],{},"    public bool IsMovingRight() => moveRight.IsPressed();\n",[145,3110,3111],{"class":147,"line":935},[145,3112,206],{},[145,3114,3115],{"class":147,"line":1664},[145,3116,3117],{},"    public bool JumpPressed() => jump.IsDown();\n",[145,3119,3120],{"class":147,"line":1669},[145,3121,3122],{},"    public bool InteractPressed() => interact.IsDown();\n",[145,3124,3125],{"class":147,"line":1675},[145,3126,206],{},[145,3128,3129],{"class":147,"line":1680},[145,3130,3131],{},"    // Save/Load input bindings\n",[145,3133,3134],{"class":147,"line":1685},[145,3135,3136],{},"    private void LoadInputBindings()\n",[145,3138,3139],{"class":147,"line":1691},[145,3140,345],{},[145,3142,3143],{"class":147,"line":1696},[145,3144,3145],{},"        // Load from PlayerPrefs or file\n",[145,3147,3148],{"class":147,"line":1702},[145,3149,3150],{},"        // Implementation depends on your save system\n",[145,3152,3153],{"class":147,"line":1707},[145,3154,355],{},[145,3156,3157],{"class":147,"line":1712},[145,3158,206],{},[145,3160,3161],{"class":147,"line":1717},[145,3162,3163],{},"    public void ResetToDefaults()\n",[145,3165,3166],{"class":147,"line":1723},[145,3167,345],{},[145,3169,3170],{"class":147,"line":1728},[145,3171,3172],{},"        // Reset all bindings to default values\n",[145,3174,3175],{"class":147,"line":1734},[145,3176,355],{},[145,3178,3179],{"class":147,"line":1739},[145,3180,271],{},[15,3182,3184],{"id":3183},"_8-نظام-ui-قابل-للتوسع","8. نظام UI قابل للتوسع",[135,3186,3188],{"className":137,"code":3187,"language":139,"meta":140,"style":140},"using UnityEngine;\nusing UnityEngine.UI;\nusing TMPro;\n\npublic abstract class UIManager : MonoBehaviour\n{\n    protected Canvas canvas;\n    protected GraphicRaycaster raycaster;\n    \n    protected virtual void Awake()\n    {\n        canvas = GetComponent\u003CCanvas>();\n        raycaster = GetComponent\u003CGraphicRaycaster>();\n    }\n    \n    public virtual void Show()\n    {\n        canvas.enabled = true;\n    }\n    \n    public virtual void Hide()\n    {\n        canvas.enabled = false;\n    }\n    \n    public virtual void Toggle()\n    {\n        canvas.enabled = !canvas.enabled;\n    }\n}\n\npublic class HUDManager : UIManager\n{\n    [SerializeField] private TextMeshProUGUI scoreText;\n    [SerializeField] private TextMeshProUGUI healthText;\n    [SerializeField] private Slider healthBar;\n    \n    private void Start()\n    {\n        UpdateScore(0);\n        UpdateHealth(100, 100);\n    }\n    \n    public void UpdateScore(int score)\n    {\n        scoreText.text = $\"Score: {score}\";\n    }\n    \n    public void UpdateHealth(int current, int max)\n    {\n        healthText.text = $\"{current}/{max}\";\n        healthBar.value = (float)current / max;\n    }\n}\n\npublic class PauseMenuManager : UIManager\n{\n    [SerializeField] private Button resumeButton;\n    [SerializeField] private Button settingsButton;\n    [SerializeField] private Button quitButton;\n    \n    protected override void Awake()\n    {\n        base.Awake();\n        \n        resumeButton.onClick.AddListener(ResumeGame);\n        settingsButton.onClick.AddListener(OpenSettings);\n        quitButton.onClick.AddListener(QuitGame);\n    }\n    \n    private void ResumeGame()\n    {\n        Time.timeScale = 1f;\n        Hide();\n    }\n    \n    private void OpenSettings()\n    {\n        // Open settings menu\n    }\n    \n    private void QuitGame()\n    {\n        Application.Quit();\n    }\n}\n",[142,3189,3190,3194,3199,3204,3208,3213,3217,3222,3227,3231,3236,3240,3245,3250,3254,3258,3263,3267,3272,3276,3280,3285,3289,3294,3298,3302,3307,3311,3316,3320,3324,3328,3333,3337,3342,3347,3352,3356,3360,3364,3369,3374,3378,3382,3387,3391,3396,3400,3404,3409,3413,3418,3423,3427,3431,3435,3440,3444,3449,3454,3459,3463,3468,3472,3477,3481,3486,3491,3496,3500,3504,3509,3513,3518,3523,3527,3531,3536,3540,3545,3549,3553,3558,3562,3567,3571],{"__ignoreMap":140},[145,3191,3192],{"class":147,"line":148},[145,3193,151],{},[145,3195,3196],{"class":147,"line":154},[145,3197,3198],{},"using UnityEngine.UI;\n",[145,3200,3201],{"class":147,"line":161},[145,3202,3203],{},"using TMPro;\n",[145,3205,3206],{"class":147,"line":167},[145,3207,158],{"emptyLinePlaceholder":157},[145,3209,3210],{"class":147,"line":173},[145,3211,3212],{},"public abstract class UIManager : MonoBehaviour\n",[145,3214,3215],{"class":147,"line":179},[145,3216,176],{},[145,3218,3219],{"class":147,"line":185},[145,3220,3221],{},"    protected Canvas canvas;\n",[145,3223,3224],{"class":147,"line":191},[145,3225,3226],{},"    protected GraphicRaycaster raycaster;\n",[145,3228,3229],{"class":147,"line":197},[145,3230,206],{},[145,3232,3233],{"class":147,"line":203},[145,3234,3235],{},"    protected virtual void Awake()\n",[145,3237,3238],{"class":147,"line":209},[145,3239,345],{},[145,3241,3242],{"class":147,"line":215},[145,3243,3244],{},"        canvas = GetComponent\u003CCanvas>();\n",[145,3246,3247],{"class":147,"line":221},[145,3248,3249],{},"        raycaster = GetComponent\u003CGraphicRaycaster>();\n",[145,3251,3252],{"class":147,"line":227},[145,3253,355],{},[145,3255,3256],{"class":147,"line":233},[145,3257,206],{},[145,3259,3260],{"class":147,"line":239},[145,3261,3262],{},"    public virtual void Show()\n",[145,3264,3265],{"class":147,"line":244},[145,3266,345],{},[145,3268,3269],{"class":147,"line":250},[145,3270,3271],{},"        canvas.enabled = true;\n",[145,3273,3274],{"class":147,"line":256},[145,3275,355],{},[145,3277,3278],{"class":147,"line":262},[145,3279,206],{},[145,3281,3282],{"class":147,"line":268},[145,3283,3284],{},"    public virtual void Hide()\n",[145,3286,3287],{"class":147,"line":384},[145,3288,345],{},[145,3290,3291],{"class":147,"line":390},[145,3292,3293],{},"        canvas.enabled = false;\n",[145,3295,3296],{"class":147,"line":395},[145,3297,355],{},[145,3299,3300],{"class":147,"line":401},[145,3301,206],{},[145,3303,3304],{"class":147,"line":406},[145,3305,3306],{},"    public virtual void Toggle()\n",[145,3308,3309],{"class":147,"line":546},[145,3310,345],{},[145,3312,3313],{"class":147,"line":552},[145,3314,3315],{},"        canvas.enabled = !canvas.enabled;\n",[145,3317,3318],{"class":147,"line":558},[145,3319,355],{},[145,3321,3322],{"class":147,"line":563},[145,3323,271],{},[145,3325,3326],{"class":147,"line":569},[145,3327,158],{"emptyLinePlaceholder":157},[145,3329,3330],{"class":147,"line":575},[145,3331,3332],{},"public class HUDManager : UIManager\n",[145,3334,3335],{"class":147,"line":581},[145,3336,176],{},[145,3338,3339],{"class":147,"line":586},[145,3340,3341],{},"    [SerializeField] private TextMeshProUGUI scoreText;\n",[145,3343,3344],{"class":147,"line":591},[145,3345,3346],{},"    [SerializeField] private TextMeshProUGUI healthText;\n",[145,3348,3349],{"class":147,"line":597},[145,3350,3351],{},"    [SerializeField] private Slider healthBar;\n",[145,3353,3354],{"class":147,"line":603},[145,3355,206],{},[145,3357,3358],{"class":147,"line":609},[145,3359,1742],{},[145,3361,3362],{"class":147,"line":614},[145,3363,345],{},[145,3365,3366],{"class":147,"line":620},[145,3367,3368],{},"        UpdateScore(0);\n",[145,3370,3371],{"class":147,"line":625},[145,3372,3373],{},"        UpdateHealth(100, 100);\n",[145,3375,3376],{"class":147,"line":631},[145,3377,355],{},[145,3379,3380],{"class":147,"line":637},[145,3381,206],{},[145,3383,3384],{"class":147,"line":642},[145,3385,3386],{},"    public void UpdateScore(int score)\n",[145,3388,3389],{"class":147,"line":853},[145,3390,345],{},[145,3392,3393],{"class":147,"line":858},[145,3394,3395],{},"        scoreText.text = $\"Score: {score}\";\n",[145,3397,3398],{"class":147,"line":864},[145,3399,355],{},[145,3401,3402],{"class":147,"line":869},[145,3403,206],{},[145,3405,3406],{"class":147,"line":875},[145,3407,3408],{},"    public void UpdateHealth(int current, int max)\n",[145,3410,3411],{"class":147,"line":881},[145,3412,345],{},[145,3414,3415],{"class":147,"line":887},[145,3416,3417],{},"        healthText.text = $\"{current}/{max}\";\n",[145,3419,3420],{"class":147,"line":892},[145,3421,3422],{},"        healthBar.value = (float)current / max;\n",[145,3424,3425],{"class":147,"line":897},[145,3426,355],{},[145,3428,3429],{"class":147,"line":903},[145,3430,271],{},[145,3432,3433],{"class":147,"line":908},[145,3434,158],{"emptyLinePlaceholder":157},[145,3436,3437],{"class":147,"line":914},[145,3438,3439],{},"public class PauseMenuManager : UIManager\n",[145,3441,3442],{"class":147,"line":919},[145,3443,176],{},[145,3445,3446],{"class":147,"line":925},[145,3447,3448],{},"    [SerializeField] private Button resumeButton;\n",[145,3450,3451],{"class":147,"line":930},[145,3452,3453],{},"    [SerializeField] private Button settingsButton;\n",[145,3455,3456],{"class":147,"line":935},[145,3457,3458],{},"    [SerializeField] private Button quitButton;\n",[145,3460,3461],{"class":147,"line":1664},[145,3462,206],{},[145,3464,3465],{"class":147,"line":1669},[145,3466,3467],{},"    protected override void Awake()\n",[145,3469,3470],{"class":147,"line":1675},[145,3471,345],{},[145,3473,3474],{"class":147,"line":1680},[145,3475,3476],{},"        base.Awake();\n",[145,3478,3479],{"class":147,"line":1685},[145,3480,566],{},[145,3482,3483],{"class":147,"line":1691},[145,3484,3485],{},"        resumeButton.onClick.AddListener(ResumeGame);\n",[145,3487,3488],{"class":147,"line":1696},[145,3489,3490],{},"        settingsButton.onClick.AddListener(OpenSettings);\n",[145,3492,3493],{"class":147,"line":1702},[145,3494,3495],{},"        quitButton.onClick.AddListener(QuitGame);\n",[145,3497,3498],{"class":147,"line":1707},[145,3499,355],{},[145,3501,3502],{"class":147,"line":1712},[145,3503,206],{},[145,3505,3506],{"class":147,"line":1717},[145,3507,3508],{},"    private void ResumeGame()\n",[145,3510,3511],{"class":147,"line":1723},[145,3512,345],{},[145,3514,3515],{"class":147,"line":1728},[145,3516,3517],{},"        Time.timeScale = 1f;\n",[145,3519,3520],{"class":147,"line":1734},[145,3521,3522],{},"        Hide();\n",[145,3524,3525],{"class":147,"line":1739},[145,3526,355],{},[145,3528,3529],{"class":147,"line":1745},[145,3530,206],{},[145,3532,3533],{"class":147,"line":1750},[145,3534,3535],{},"    private void OpenSettings()\n",[145,3537,3538],{"class":147,"line":1756},[145,3539,345],{},[145,3541,3542],{"class":147,"line":1761},[145,3543,3544],{},"        // Open settings menu\n",[145,3546,3547],{"class":147,"line":1766},[145,3548,355],{},[145,3550,3551],{"class":147,"line":1772},[145,3552,206],{},[145,3554,3555],{"class":147,"line":1777},[145,3556,3557],{},"    private void QuitGame()\n",[145,3559,3560],{"class":147,"line":1783},[145,3561,345],{},[145,3563,3564],{"class":147,"line":1788},[145,3565,3566],{},"        Application.Quit();\n",[145,3568,3569],{"class":147,"line":2181},[145,3570,355],{},[145,3572,3573],{"class":147,"line":2186},[145,3574,271],{},[15,3576,3578],{"id":3577},"_9-نظام-audio-قابل-للإدارة","9. نظام Audio قابل للإدارة",[135,3580,3582],{"className":137,"code":3581,"language":139,"meta":140,"style":140},"using System.Collections.Generic;\nusing UnityEngine;\n\n[System.Serializable]\npublic class Sound\n{\n    public string name;\n    public AudioClip clip;\n    \n    [Range(0f, 1f)]\n    public float volume = 1f;\n    \n    [Range(0.1f, 3f)]\n    public float pitch = 1f;\n    \n    public bool loop = false;\n    \n    [HideInInspector]\n    public AudioSource source;\n}\n\npublic class AudioManager : MonoBehaviour\n{\n    public static AudioManager Instance { get; private set; }\n    \n    [SerializeField] private Sound[] sounds;\n    [SerializeField] private AudioSource musicSource;\n    [SerializeField] private AudioSource sfxSource;\n    \n    private Dictionary\u003Cstring, Sound> soundDictionary;\n    \n    private void Awake()\n    {\n        if (Instance == null)\n        {\n            Instance = this;\n            DontDestroyOnLoad(gameObject);\n            InitializeAudio();\n        }\n        else\n        {\n            Destroy(gameObject);\n        }\n    }\n    \n    private void InitializeAudio()\n    {\n        soundDictionary = new Dictionary\u003Cstring, Sound>();\n        \n        foreach (Sound sound in sounds)\n        {\n            sound.source = gameObject.AddComponent\u003CAudioSource>();\n            sound.source.clip = sound.clip;\n            sound.source.volume = sound.volume;\n            sound.source.pitch = sound.pitch;\n            sound.source.loop = sound.loop;\n            \n            soundDictionary[sound.name] = sound;\n        }\n    }\n    \n    public void Play(string soundName)\n    {\n        if (soundDictionary.TryGetValue(soundName, out Sound sound))\n        {\n            sound.source.Play();\n        }\n        else\n        {\n            Debug.LogWarning($\"Sound {soundName} not found!\");\n        }\n    }\n    \n    public void Stop(string soundName)\n    {\n        if (soundDictionary.TryGetValue(soundName, out Sound sound))\n        {\n            sound.source.Stop();\n        }\n    }\n    \n    public void SetVolume(string soundName, float volume)\n    {\n        if (soundDictionary.TryGetValue(soundName, out Sound sound))\n        {\n            sound.source.volume = volume;\n        }\n    }\n    \n    public void PlayMusic(AudioClip musicClip)\n    {\n        musicSource.clip = musicClip;\n        musicSource.Play();\n    }\n    \n    public void StopMusic()\n    {\n        musicSource.Stop();\n    }\n    \n    public void SetMusicVolume(float volume)\n    {\n        musicSource.volume = volume;\n    }\n}\n",[142,3583,3584,3588,3592,3596,3600,3605,3609,3614,3619,3623,3628,3633,3637,3642,3647,3651,3656,3660,3665,3670,3674,3678,3682,3686,3691,3695,3700,3705,3710,3714,3719,3723,3727,3731,3735,3739,3743,3747,3752,3756,3760,3764,3768,3772,3776,3780,3785,3789,3794,3798,3803,3807,3812,3817,3822,3827,3832,3837,3842,3846,3850,3854,3859,3863,3868,3872,3877,3881,3885,3889,3894,3898,3902,3906,3911,3915,3919,3923,3928,3932,3936,3940,3945,3949,3953,3957,3962,3966,3970,3974,3979,3983,3988,3993,3997,4001,4006,4010,4015,4019,4023,4028,4032,4037,4041],{"__ignoreMap":140},[145,3585,3586],{"class":147,"line":148},[145,3587,658],{},[145,3589,3590],{"class":147,"line":154},[145,3591,151],{},[145,3593,3594],{"class":147,"line":161},[145,3595,158],{"emptyLinePlaceholder":157},[145,3597,3598],{"class":147,"line":167},[145,3599,2408],{},[145,3601,3602],{"class":147,"line":173},[145,3603,3604],{},"public class Sound\n",[145,3606,3607],{"class":147,"line":179},[145,3608,176],{},[145,3610,3611],{"class":147,"line":185},[145,3612,3613],{},"    public string name;\n",[145,3615,3616],{"class":147,"line":191},[145,3617,3618],{},"    public AudioClip clip;\n",[145,3620,3621],{"class":147,"line":197},[145,3622,206],{},[145,3624,3625],{"class":147,"line":203},[145,3626,3627],{},"    [Range(0f, 1f)]\n",[145,3629,3630],{"class":147,"line":209},[145,3631,3632],{},"    public float volume = 1f;\n",[145,3634,3635],{"class":147,"line":215},[145,3636,206],{},[145,3638,3639],{"class":147,"line":221},[145,3640,3641],{},"    [Range(0.1f, 3f)]\n",[145,3643,3644],{"class":147,"line":227},[145,3645,3646],{},"    public float pitch = 1f;\n",[145,3648,3649],{"class":147,"line":233},[145,3650,206],{},[145,3652,3653],{"class":147,"line":239},[145,3654,3655],{},"    public bool loop = false;\n",[145,3657,3658],{"class":147,"line":244},[145,3659,206],{},[145,3661,3662],{"class":147,"line":250},[145,3663,3664],{},"    [HideInInspector]\n",[145,3666,3667],{"class":147,"line":256},[145,3668,3669],{},"    public AudioSource source;\n",[145,3671,3672],{"class":147,"line":262},[145,3673,271],{},[145,3675,3676],{"class":147,"line":268},[145,3677,158],{"emptyLinePlaceholder":157},[145,3679,3680],{"class":147,"line":384},[145,3681,1653],{},[145,3683,3684],{"class":147,"line":390},[145,3685,176],{},[145,3687,3688],{"class":147,"line":395},[145,3689,3690],{},"    public static AudioManager Instance { get; private set; }\n",[145,3692,3693],{"class":147,"line":401},[145,3694,206],{},[145,3696,3697],{"class":147,"line":406},[145,3698,3699],{},"    [SerializeField] private Sound[] sounds;\n",[145,3701,3702],{"class":147,"line":546},[145,3703,3704],{},"    [SerializeField] private AudioSource musicSource;\n",[145,3706,3707],{"class":147,"line":552},[145,3708,3709],{},"    [SerializeField] private AudioSource sfxSource;\n",[145,3711,3712],{"class":147,"line":558},[145,3713,206],{},[145,3715,3716],{"class":147,"line":563},[145,3717,3718],{},"    private Dictionary\u003Cstring, Sound> soundDictionary;\n",[145,3720,3721],{"class":147,"line":569},[145,3722,206],{},[145,3724,3725],{"class":147,"line":575},[145,3726,530],{},[145,3728,3729],{"class":147,"line":581},[145,3730,345],{},[145,3732,3733],{"class":147,"line":586},[145,3734,2676],{},[145,3736,3737],{"class":147,"line":591},[145,3738,462],{},[145,3740,3741],{"class":147,"line":597},[145,3742,2685],{},[145,3744,3745],{"class":147,"line":603},[145,3746,3049],{},[145,3748,3749],{"class":147,"line":609},[145,3750,3751],{},"            InitializeAudio();\n",[145,3753,3754],{"class":147,"line":614},[145,3755,517],{},[145,3757,3758],{"class":147,"line":620},[145,3759,3063],{},[145,3761,3762],{"class":147,"line":625},[145,3763,462],{},[145,3765,3766],{"class":147,"line":631},[145,3767,549],{},[145,3769,3770],{"class":147,"line":637},[145,3771,517],{},[145,3773,3774],{"class":147,"line":642},[145,3775,355],{},[145,3777,3778],{"class":147,"line":853},[145,3779,206],{},[145,3781,3782],{"class":147,"line":858},[145,3783,3784],{},"    private void InitializeAudio()\n",[145,3786,3787],{"class":147,"line":864},[145,3788,345],{},[145,3790,3791],{"class":147,"line":869},[145,3792,3793],{},"        soundDictionary = new Dictionary\u003Cstring, Sound>();\n",[145,3795,3796],{"class":147,"line":875},[145,3797,566],{},[145,3799,3800],{"class":147,"line":881},[145,3801,3802],{},"        foreach (Sound sound in sounds)\n",[145,3804,3805],{"class":147,"line":887},[145,3806,462],{},[145,3808,3809],{"class":147,"line":892},[145,3810,3811],{},"            sound.source = gameObject.AddComponent\u003CAudioSource>();\n",[145,3813,3814],{"class":147,"line":897},[145,3815,3816],{},"            sound.source.clip = sound.clip;\n",[145,3818,3819],{"class":147,"line":903},[145,3820,3821],{},"            sound.source.volume = sound.volume;\n",[145,3823,3824],{"class":147,"line":908},[145,3825,3826],{},"            sound.source.pitch = sound.pitch;\n",[145,3828,3829],{"class":147,"line":914},[145,3830,3831],{},"            sound.source.loop = sound.loop;\n",[145,3833,3834],{"class":147,"line":919},[145,3835,3836],{},"            \n",[145,3838,3839],{"class":147,"line":925},[145,3840,3841],{},"            soundDictionary[sound.name] = sound;\n",[145,3843,3844],{"class":147,"line":930},[145,3845,517],{},[145,3847,3848],{"class":147,"line":935},[145,3849,355],{},[145,3851,3852],{"class":147,"line":1664},[145,3853,206],{},[145,3855,3856],{"class":147,"line":1669},[145,3857,3858],{},"    public void Play(string soundName)\n",[145,3860,3861],{"class":147,"line":1675},[145,3862,345],{},[145,3864,3865],{"class":147,"line":1680},[145,3866,3867],{},"        if (soundDictionary.TryGetValue(soundName, out Sound sound))\n",[145,3869,3870],{"class":147,"line":1685},[145,3871,462],{},[145,3873,3874],{"class":147,"line":1691},[145,3875,3876],{},"            sound.source.Play();\n",[145,3878,3879],{"class":147,"line":1696},[145,3880,517],{},[145,3882,3883],{"class":147,"line":1702},[145,3884,3063],{},[145,3886,3887],{"class":147,"line":1707},[145,3888,462],{},[145,3890,3891],{"class":147,"line":1712},[145,3892,3893],{},"            Debug.LogWarning($\"Sound {soundName} not found!\");\n",[145,3895,3896],{"class":147,"line":1717},[145,3897,517],{},[145,3899,3900],{"class":147,"line":1723},[145,3901,355],{},[145,3903,3904],{"class":147,"line":1728},[145,3905,206],{},[145,3907,3908],{"class":147,"line":1734},[145,3909,3910],{},"    public void Stop(string soundName)\n",[145,3912,3913],{"class":147,"line":1739},[145,3914,345],{},[145,3916,3917],{"class":147,"line":1745},[145,3918,3867],{},[145,3920,3921],{"class":147,"line":1750},[145,3922,462],{},[145,3924,3925],{"class":147,"line":1756},[145,3926,3927],{},"            sound.source.Stop();\n",[145,3929,3930],{"class":147,"line":1761},[145,3931,517],{},[145,3933,3934],{"class":147,"line":1766},[145,3935,355],{},[145,3937,3938],{"class":147,"line":1772},[145,3939,206],{},[145,3941,3942],{"class":147,"line":1777},[145,3943,3944],{},"    public void SetVolume(string soundName, float volume)\n",[145,3946,3947],{"class":147,"line":1783},[145,3948,345],{},[145,3950,3951],{"class":147,"line":1788},[145,3952,3867],{},[145,3954,3955],{"class":147,"line":2181},[145,3956,462],{},[145,3958,3959],{"class":147,"line":2186},[145,3960,3961],{},"            sound.source.volume = volume;\n",[145,3963,3964],{"class":147,"line":2191},[145,3965,517],{},[145,3967,3968],{"class":147,"line":2197},[145,3969,355],{},[145,3971,3972],{"class":147,"line":2202},[145,3973,206],{},[145,3975,3976],{"class":147,"line":2208},[145,3977,3978],{},"    public void PlayMusic(AudioClip musicClip)\n",[145,3980,3981],{"class":147,"line":2213},[145,3982,345],{},[145,3984,3985],{"class":147,"line":2219},[145,3986,3987],{},"        musicSource.clip = musicClip;\n",[145,3989,3990],{"class":147,"line":2225},[145,3991,3992],{},"        musicSource.Play();\n",[145,3994,3995],{"class":147,"line":2231},[145,3996,355],{},[145,3998,3999],{"class":147,"line":2236},[145,4000,206],{},[145,4002,4003],{"class":147,"line":2241},[145,4004,4005],{},"    public void StopMusic()\n",[145,4007,4008],{"class":147,"line":2246},[145,4009,345],{},[145,4011,4012],{"class":147,"line":2252},[145,4013,4014],{},"        musicSource.Stop();\n",[145,4016,4017],{"class":147,"line":2257},[145,4018,355],{},[145,4020,4021],{"class":147,"line":2263},[145,4022,206],{},[145,4024,4025],{"class":147,"line":2268},[145,4026,4027],{},"    public void SetMusicVolume(float volume)\n",[145,4029,4030],{"class":147,"line":2273},[145,4031,345],{},[145,4033,4034],{"class":147,"line":2278},[145,4035,4036],{},"        musicSource.volume = volume;\n",[145,4038,4039],{"class":147,"line":2284},[145,4040,355],{},[145,4042,4043],{"class":147,"line":2289},[145,4044,271],{},[15,4046,4048],{"id":4047},"_10-نظام-physics-محسن-للأداء","10. نظام Physics محسن للأداء",[135,4050,4052],{"className":137,"code":4051,"language":139,"meta":140,"style":140},"using UnityEngine;\n\npublic class OptimizedPhysics : MonoBehaviour\n{\n    [Header(\"Physics Settings\")]\n    [SerializeField] private float fixedTimeStep = 0.02f;\n    [SerializeField] private int maximumAllowedTimestep = 1;\n    [SerializeField] private int solverIterations = 6;\n    [SerializeField] private int solverVelocityIterations = 1;\n    \n    [Header(\"Layer Collision Matrix\")]\n    [SerializeField] private LayerMask playerLayer;\n    [SerializeField] private LayerMask enemyLayer;\n    [SerializeField] private LayerMask projectileLayer;\n    [SerializeField] private LayerMask environmentLayer;\n    \n    private void Awake()\n    {\n        ConfigurePhysics();\n        SetupCollisionMatrix();\n    }\n    \n    private void ConfigurePhysics()\n    {\n        Time.fixedDeltaTime = fixedTimeStep;\n        Physics.defaultMaxAngularSpeed = maximumAllowedTimestep;\n        \n        // Configure solver iterations for better performance\n        Physics.defaultSolverIterations = solverIterations;\n        Physics.defaultSolverVelocityIterations = solverVelocityIterations;\n        \n        // Enable auto-simulation if needed\n        Physics.autoSimulation = true;\n        \n        // Configure physics gravity if needed\n        Physics.gravity = new Vector3(0, -9.81f, 0);\n    }\n    \n    private void SetupCollisionMatrix()\n    {\n        // Disable unnecessary collisions for performance\n        // Players don't collide with other players\n        Physics.IgnoreLayerCollision(playerLayer, playerLayer, true);\n        \n        // Projectiles don't collide with other projectiles\n        Physics.IgnoreLayerCollision(projectileLayer, projectileLayer, true);\n        \n        // Enemies don't collide with other enemies (use custom collision detection)\n        Physics.IgnoreLayerCollision(enemyLayer, enemyLayer, true);\n    }\n    \n    // Performance monitoring\n    private void Update()\n    {\n        // Monitor physics performance\n        if (Time.frameCount % 60 == 0) // Every second at 60 FPS\n        {\n            MonitorPhysicsPerformance();\n        }\n    }\n    \n    private void MonitorPhysicsPerformance()\n    {\n        int activeBodies = Physics.Bodies.Count;\n        int activeColliders = FindObjectsOfType\u003CCollider>().Length;\n        \n        // Log or send to analytics if performance is degrading\n        if (activeBodies > 1000 || activeColliders > 5000)\n        {\n            Debug.LogWarning($\"High physics load: {activeBodies} bodies, {activeColliders} colliders\");\n        }\n    }\n    \n    // Public methods for runtime physics control\n    public void PausePhysics()\n    {\n        Physics.autoSimulation = false;\n    }\n    \n    public void ResumePhysics()\n    {\n        Physics.autoSimulation = true;\n        Physics.Simulate(Time.fixedDeltaTime);\n    }\n    \n    public void SetTimeScale(float timeScale)\n    {\n        Time.timeScale = timeScale;\n        Time.fixedDeltaTime = fixedTimeStep * timeScale;\n    }\n}\n",[142,4053,4054,4058,4062,4067,4071,4076,4081,4086,4091,4096,4100,4105,4110,4115,4120,4125,4129,4133,4137,4142,4147,4151,4155,4160,4164,4169,4174,4178,4183,4188,4193,4197,4202,4207,4211,4216,4221,4225,4229,4234,4238,4243,4248,4253,4257,4262,4267,4271,4276,4281,4285,4289,4294,4298,4302,4307,4312,4316,4321,4325,4329,4333,4338,4342,4347,4352,4356,4361,4366,4370,4375,4379,4383,4387,4392,4397,4401,4406,4410,4414,4419,4423,4427,4432,4436,4440,4445,4449,4454,4459,4463],{"__ignoreMap":140},[145,4055,4056],{"class":147,"line":148},[145,4057,151],{},[145,4059,4060],{"class":147,"line":154},[145,4061,158],{"emptyLinePlaceholder":157},[145,4063,4064],{"class":147,"line":161},[145,4065,4066],{},"public class OptimizedPhysics : MonoBehaviour\n",[145,4068,4069],{"class":147,"line":167},[145,4070,176],{},[145,4072,4073],{"class":147,"line":173},[145,4074,4075],{},"    [Header(\"Physics Settings\")]\n",[145,4077,4078],{"class":147,"line":179},[145,4079,4080],{},"    [SerializeField] private float fixedTimeStep = 0.02f;\n",[145,4082,4083],{"class":147,"line":185},[145,4084,4085],{},"    [SerializeField] private int maximumAllowedTimestep = 1;\n",[145,4087,4088],{"class":147,"line":191},[145,4089,4090],{},"    [SerializeField] private int solverIterations = 6;\n",[145,4092,4093],{"class":147,"line":197},[145,4094,4095],{},"    [SerializeField] private int solverVelocityIterations = 1;\n",[145,4097,4098],{"class":147,"line":203},[145,4099,206],{},[145,4101,4102],{"class":147,"line":209},[145,4103,4104],{},"    [Header(\"Layer Collision Matrix\")]\n",[145,4106,4107],{"class":147,"line":215},[145,4108,4109],{},"    [SerializeField] private LayerMask playerLayer;\n",[145,4111,4112],{"class":147,"line":221},[145,4113,4114],{},"    [SerializeField] private LayerMask enemyLayer;\n",[145,4116,4117],{"class":147,"line":227},[145,4118,4119],{},"    [SerializeField] private LayerMask projectileLayer;\n",[145,4121,4122],{"class":147,"line":233},[145,4123,4124],{},"    [SerializeField] private LayerMask environmentLayer;\n",[145,4126,4127],{"class":147,"line":239},[145,4128,206],{},[145,4130,4131],{"class":147,"line":244},[145,4132,530],{},[145,4134,4135],{"class":147,"line":250},[145,4136,345],{},[145,4138,4139],{"class":147,"line":256},[145,4140,4141],{},"        ConfigurePhysics();\n",[145,4143,4144],{"class":147,"line":262},[145,4145,4146],{},"        SetupCollisionMatrix();\n",[145,4148,4149],{"class":147,"line":268},[145,4150,355],{},[145,4152,4153],{"class":147,"line":384},[145,4154,206],{},[145,4156,4157],{"class":147,"line":390},[145,4158,4159],{},"    private void ConfigurePhysics()\n",[145,4161,4162],{"class":147,"line":395},[145,4163,345],{},[145,4165,4166],{"class":147,"line":401},[145,4167,4168],{},"        Time.fixedDeltaTime = fixedTimeStep;\n",[145,4170,4171],{"class":147,"line":406},[145,4172,4173],{},"        Physics.defaultMaxAngularSpeed = maximumAllowedTimestep;\n",[145,4175,4176],{"class":147,"line":546},[145,4177,566],{},[145,4179,4180],{"class":147,"line":552},[145,4181,4182],{},"        // Configure solver iterations for better performance\n",[145,4184,4185],{"class":147,"line":558},[145,4186,4187],{},"        Physics.defaultSolverIterations = solverIterations;\n",[145,4189,4190],{"class":147,"line":563},[145,4191,4192],{},"        Physics.defaultSolverVelocityIterations = solverVelocityIterations;\n",[145,4194,4195],{"class":147,"line":569},[145,4196,566],{},[145,4198,4199],{"class":147,"line":575},[145,4200,4201],{},"        // Enable auto-simulation if needed\n",[145,4203,4204],{"class":147,"line":581},[145,4205,4206],{},"        Physics.autoSimulation = true;\n",[145,4208,4209],{"class":147,"line":586},[145,4210,566],{},[145,4212,4213],{"class":147,"line":591},[145,4214,4215],{},"        // Configure physics gravity if needed\n",[145,4217,4218],{"class":147,"line":597},[145,4219,4220],{},"        Physics.gravity = new Vector3(0, -9.81f, 0);\n",[145,4222,4223],{"class":147,"line":603},[145,4224,355],{},[145,4226,4227],{"class":147,"line":609},[145,4228,206],{},[145,4230,4231],{"class":147,"line":614},[145,4232,4233],{},"    private void SetupCollisionMatrix()\n",[145,4235,4236],{"class":147,"line":620},[145,4237,345],{},[145,4239,4240],{"class":147,"line":625},[145,4241,4242],{},"        // Disable unnecessary collisions for performance\n",[145,4244,4245],{"class":147,"line":631},[145,4246,4247],{},"        // Players don't collide with other players\n",[145,4249,4250],{"class":147,"line":637},[145,4251,4252],{},"        Physics.IgnoreLayerCollision(playerLayer, playerLayer, true);\n",[145,4254,4255],{"class":147,"line":642},[145,4256,566],{},[145,4258,4259],{"class":147,"line":853},[145,4260,4261],{},"        // Projectiles don't collide with other projectiles\n",[145,4263,4264],{"class":147,"line":858},[145,4265,4266],{},"        Physics.IgnoreLayerCollision(projectileLayer, projectileLayer, true);\n",[145,4268,4269],{"class":147,"line":864},[145,4270,566],{},[145,4272,4273],{"class":147,"line":869},[145,4274,4275],{},"        // Enemies don't collide with other enemies (use custom collision detection)\n",[145,4277,4278],{"class":147,"line":875},[145,4279,4280],{},"        Physics.IgnoreLayerCollision(enemyLayer, enemyLayer, true);\n",[145,4282,4283],{"class":147,"line":881},[145,4284,355],{},[145,4286,4287],{"class":147,"line":887},[145,4288,206],{},[145,4290,4291],{"class":147,"line":892},[145,4292,4293],{},"    // Performance monitoring\n",[145,4295,4296],{"class":147,"line":897},[145,4297,1952],{},[145,4299,4300],{"class":147,"line":903},[145,4301,345],{},[145,4303,4304],{"class":147,"line":908},[145,4305,4306],{},"        // Monitor physics performance\n",[145,4308,4309],{"class":147,"line":914},[145,4310,4311],{},"        if (Time.frameCount % 60 == 0) // Every second at 60 FPS\n",[145,4313,4314],{"class":147,"line":919},[145,4315,462],{},[145,4317,4318],{"class":147,"line":925},[145,4319,4320],{},"            MonitorPhysicsPerformance();\n",[145,4322,4323],{"class":147,"line":930},[145,4324,517],{},[145,4326,4327],{"class":147,"line":935},[145,4328,355],{},[145,4330,4331],{"class":147,"line":1664},[145,4332,206],{},[145,4334,4335],{"class":147,"line":1669},[145,4336,4337],{},"    private void MonitorPhysicsPerformance()\n",[145,4339,4340],{"class":147,"line":1675},[145,4341,345],{},[145,4343,4344],{"class":147,"line":1680},[145,4345,4346],{},"        int activeBodies = Physics.Bodies.Count;\n",[145,4348,4349],{"class":147,"line":1685},[145,4350,4351],{},"        int activeColliders = FindObjectsOfType\u003CCollider>().Length;\n",[145,4353,4354],{"class":147,"line":1691},[145,4355,566],{},[145,4357,4358],{"class":147,"line":1696},[145,4359,4360],{},"        // Log or send to analytics if performance is degrading\n",[145,4362,4363],{"class":147,"line":1702},[145,4364,4365],{},"        if (activeBodies > 1000 || activeColliders > 5000)\n",[145,4367,4368],{"class":147,"line":1707},[145,4369,462],{},[145,4371,4372],{"class":147,"line":1712},[145,4373,4374],{},"            Debug.LogWarning($\"High physics load: {activeBodies} bodies, {activeColliders} colliders\");\n",[145,4376,4377],{"class":147,"line":1717},[145,4378,517],{},[145,4380,4381],{"class":147,"line":1723},[145,4382,355],{},[145,4384,4385],{"class":147,"line":1728},[145,4386,206],{},[145,4388,4389],{"class":147,"line":1734},[145,4390,4391],{},"    // Public methods for runtime physics control\n",[145,4393,4394],{"class":147,"line":1739},[145,4395,4396],{},"    public void PausePhysics()\n",[145,4398,4399],{"class":147,"line":1745},[145,4400,345],{},[145,4402,4403],{"class":147,"line":1750},[145,4404,4405],{},"        Physics.autoSimulation = false;\n",[145,4407,4408],{"class":147,"line":1756},[145,4409,355],{},[145,4411,4412],{"class":147,"line":1761},[145,4413,206],{},[145,4415,4416],{"class":147,"line":1766},[145,4417,4418],{},"    public void ResumePhysics()\n",[145,4420,4421],{"class":147,"line":1772},[145,4422,345],{},[145,4424,4425],{"class":147,"line":1777},[145,4426,4206],{},[145,4428,4429],{"class":147,"line":1783},[145,4430,4431],{},"        Physics.Simulate(Time.fixedDeltaTime);\n",[145,4433,4434],{"class":147,"line":1788},[145,4435,355],{},[145,4437,4438],{"class":147,"line":2181},[145,4439,206],{},[145,4441,4442],{"class":147,"line":2186},[145,4443,4444],{},"    public void SetTimeScale(float timeScale)\n",[145,4446,4447],{"class":147,"line":2191},[145,4448,345],{},[145,4450,4451],{"class":147,"line":2197},[145,4452,4453],{},"        Time.timeScale = timeScale;\n",[145,4455,4456],{"class":147,"line":2202},[145,4457,4458],{},"        Time.fixedDeltaTime = fixedTimeStep * timeScale;\n",[145,4460,4461],{"class":147,"line":2208},[145,4462,355],{},[145,4464,4465],{"class":147,"line":2213},[145,4466,271],{},[15,4468,4470],{"id":4469},"الخاتمة-رحلة-مستمرة-للتحسين","الخاتمة: رحلة مستمرة للتحسين",[11,4472,4473],{},"بناء كود قابل للتوسع في Unity ليس وجهة – إنه رحلة مستمرة من التعلم والتحسين. تذكر هذه النقاط الأساسية:",[11,4475,4476,4479],{},[27,4477,4478],{},"ابدأ صغيراً:"," لا تحاول بناء الهندسة المعمارية المثالية من البداية. ابدأ بأنماط بسيطة وقم بتحسينها تدريجياً.",[11,4481,4482,4485],{},[27,4483,4484],{},"اختبر دائماً:"," قم بتشغيل اختبارات الأداء بانتظام وتأكد من أن التغييرات الخاصة بك لا تكسر الأداء.",[11,4487,4488,4491],{},[27,4489,4490],{},"وثق كودك:"," اكتب تعليقات واضحة ووثائق لأنظمة معقدة.",[11,4493,4494,4497],{},[27,4495,4496],{},"تعلم من الأخطاء:"," كل مشروع يعلمك شيئاً جديداً عن كتابة كود أفضل.",[11,4499,4500,4503],{},[27,4501,4502],{},"كن مرناً:"," الهندسة المعمارية الجيدة تتكيف مع تغييرات المتطلبات.",[11,4505,4506],{},"مع هذه الأنماط والتقنيات، ستكون مجهزاً لبناء ألعاب Unity يمكن أن تنمو من أفكار بسيطة إلى تجارب AAA مذهلة. تذكر: الكود القابل للتوسع ليس مجرد ممارسة جيدة – إنه مفتاح نجاح مشاريع الألعاب الكبيرة.",[11,4508,4509,4512],{},[27,4510,4511],{},"ما هي خطوتك التالية في رحلة تطوير الألعاب؟"," 🎮",[4514,4515,4516],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":140,"searchDepth":161,"depth":161,"links":4518},[4519,4523,4527,4531,4535,4536,4537,4538,4539,4540,4541,4542],{"id":17,"depth":154,"text":18,"children":4520},[4521,4522],{"id":22,"depth":161,"text":23},{"id":89,"depth":161,"text":90},{"id":125,"depth":154,"text":126,"children":4524},[4525,4526],{"id":132,"depth":161,"text":133},{"id":274,"depth":161,"text":275},{"id":411,"depth":154,"text":412,"children":4528},[4529,4530],{"id":415,"depth":161,"text":416},{"id":647,"depth":161,"text":648},{"id":940,"depth":154,"text":941,"children":4532},[4533,4534],{"id":944,"depth":161,"text":945},{"id":1211,"depth":161,"text":1212},{"id":1394,"depth":154,"text":1395},{"id":1793,"depth":154,"text":1794},{"id":2384,"depth":154,"text":2385},{"id":2837,"depth":154,"text":2838},{"id":3183,"depth":154,"text":3184},{"id":3577,"depth":154,"text":3578},{"id":4047,"depth":154,"text":4048},{"id":4469,"depth":154,"text":4470},"development","إتقان فن كتابة كود نظيف، معياري، وقابل للتوسع في Unity. تعلم أفضل الممارسات، أنماط التصميم، والتقنيات الحديثة لبناء ألعاب قابلة للصيانة يمكن أن تنمو مع طموحاتك.","md","https://images.unsplash.com/photo-1550745165-9bc0b252726f?q=80&w=1200&auto=format&fit=crop",false,"ar",{"excerpt":4550},{"type":8,"value":4551},[4552],[11,4553,13],{},"/kwd-qabl-liaadh-alastkhdam-wqabl-lltwsa-fy-unity","2023-01-29T13:12:14.000Z",{"title":5,"description":4544},"كود-قابل-لإعادة-الاستخدام-وقابل-للتوسع-في-unity",[4559,4560,4561,4562,4563,4564],"unity","game-development","c-sharp","design-patterns","architecture","best-practices","2025-10-10","-dWrD0Vh2mjU5AAGyXjkbMg-VXAV7M94mXCvDk-PTNE",{"id":4568,"avatar":4569,"bio":4570,"extension":4545,"github":4571,"linkedin":4572,"locale":4548,"meta":4573,"name":4575,"role":4580,"slug":6,"stem":4581,"twitter":4582,"website":4583,"__hash__":4584},"authors_ar/ar/authors/رائد-البحري.md","/images/raed-bahri.avif","مدير منتجات ومطور متخصص في التطبيقات العربية أولاً","lord007tn","raed-bahri",{"path":4574,"title":4575,"description":140,"body":4576},"/ar/authors/raed-albhry","رائد البحري",{"type":8,"value":4577,"toc":4578},[],{"title":140,"searchDepth":161,"depth":161,"links":4579},[],"المؤسس و مطور منتجات","ar/authors/رائد-البحري","El_Raed_Bahri","https://raedbahri.com","pMOe7fRPZ-myQQEq3wdjao2Xvtyy74dyBfL4UTF1K2s",1761775956105]