Sheduler وظيفة مريحة استدعاء روتين ، نظام التكييف الخاص بي

تمت كتابة الأداة في الأصل لمساعدتك على تطوير ألعاب عرضية بسيطة في Unity ، على الأقل كانت مفيدة للغاية.



لكنني أعتقد أنني سأستخدمه في مشاريع أخرى ، وليس فقط في الوحدة.



وربما يكون مفيدًا لك أيضًا!



رابط المصدر






إذن ، ما هو الغرض منه؟



تخيل موقفًا: لقد كتبت لعبة عادية بسيطة تحتاج فيها إلى النقر على الشاشة عشر مرات لإكمال مستوى واحد ، وإرسالها إلى رئيسك (أو عميل مدلل) للمعاينة.



تليها المهام واحدة تلو الأخرى:



  1. دعنا نضيف إعلانات في النهاية كل 1.5 دقيقة؟
  2. ودعنا بعد ذلك في مكان ما في البداية ، ستكون هناك نافذة: "اشترِ علاوة حتى لا يكون هناك إعلان"؟
  3. شيء ما تضغط عليه هذه النافذة بشكل حاد ، ولكن دعه يكون بعد الإعلان ، ولكن فقط عندما يضغط اللاعب على زر البداية ويتخطى مستويين؟
  4. وتعال في المستويات 10 ، 20 ، 30 ، هل ستكون هناك نافذة "مشاركة مع الأصدقاء"؟
  5. وتعال من المستوى 10 كل 2 مستويات هل هناك نافذة "قيمنا!"؟
  6. وحفنة أكثر!


حتى بعد إجراء عملية إعدام قاسية وحظر لا نهاية له لطفلك ، بعد إجراء الفحص المائة لموقع النوافذ ، ستواجه عاجلاً أم آجلاً مثل هذه المشكلة: يمكن للنوافذ المقيدة بالمؤقت أن تتداخل مع النوافذ المرتبطة بالمستويات نفسها!



تزداد صعوبة إعادة هذا الأمر أكثر فأكثر - فبعد كل شيء ، فإن الفحوصات المشروطة تصل إلى الرقبة بالفعل ، بالإضافة إلى أن زميلك كان بإمكانه إضافة نوافذ خاصة به برمز غير قابل للقراءة تمامًا! ماذا أفعل؟






مهمة



اتصل بالنافذة في لحظة معينة (على سبيل المثال ، الضغط على زر) ، وفقط إذا تم استيفاء جميع الشروط المحددة (مر الوقت ، تم الوصول إلى النقطة المطلوبة ، وما إلى ذلك)






القرار



لهذا ، قمت بعمل فئة شرطية ، وهنا مجالاتها الرئيسية:



  1. تم ضبط المؤقت للثواني
  2. التخطي تعيين int
  3. List &ltint&gt checkPoints


, , . .



, , . , , , NextSkip(). = 0, ,

. - , START() — .

, StartTimer() ResetSkips(). , IsReady()

true , (value > 0), START() .



: — ( ) setedSeconds, , , !



IsReady() , START() , , .



    public Condition myCondition;

    void Start(){
        myCondition = new Condition("");
        myCondition.setedSeconds = 120; // 2 
        myCondition.setedSkips = 5;
        myCondition.START(); //      
    }

    //    
    public void FinishRound(){
        myCondition.NextSkip(); //  ,  

        if (myCondition.IsReady())
        {
            //    ,      ...

            myCondition.START(); //   START()    . ,     IsReady == true
        }
    }


, , — List &ltint&gt checkPoints. - , , , ., , - . , : , ( , ). , Sheduler , , — .



    public Condition myCondition;

    void Start(){
        myCondition = new Condition("",new List<int> { 1, 2, 5 }); //    ,   
        myCondition.setedSeconds = 120;
        myCondition.setedSkips = 5;
        myCondition.START();
    }

    public void FinishRound(){
        myCondition.NextSkip(); 

        if (myCondition.IsReady() || myCondition.HasCheckPoint(currentLevel)) //          
        {
            //    ,      ...

            myCondition.START();
        }
    }


, , =) AutoInvoke(Action CallBack, int checkPoint = 0) , NextSkip() START() , START() .



    public Condition myCondition;

    void Start(){
        myCondition = new Condition("",new List<int> { 1, 2, 5 });
        myCondition.setedSeconds = 120;
        myCondition.setedSkips = 5;
        myCondition.START(); 
    }

    public void FinishRound(){

        myCondition.AutoInvoke(() => Debug.Log("hello World"), currentLevel); 
        //   currentLevel,                                                                                
    }




سيساعدك كائن الشرط الواحد على توفير مجموعة من الشروط الضرورية بسرعة لتشغيل أي وظيفة واحدة !!!



إذا كانت مهمتك في المهمة الفنية أصعب قليلاً من مكالمة بسيطة ، على سبيل المثال ، مكالمة كل مرة أخرى أو بعد فترة من الوقت ، فسيكون من المفيد بالفعل اللجوء إلى الشرط ، لأن هذا تجريد وإمكانية القراءة - عليك فقط أن تبدأها وتتحقق من جاهزيتها.




لقد أضفت سمات وحدة مفيدة إلى حقول الشرط لتسهيل التهيئة من خلال المفتش!





الشيء الرئيسي هو المرونة ، وإذا جاء شخص ما فجأة بوظائفه الخاصة التي لا ينبغي أن تتعارض مع حالتك ، فأنت تحتاج فقط إلى إنشاء مخطط عام ...






المهمة التالية



أضف نوافذ مختلفة (استدعاء الوظيفة) بمرونة من أماكن مختلفة في البرنامج ، حافظ على المزامنة وتجنب تعارضات التراكب!






الحل:



والآن وصلنا إلى فئة Sheduler الرئيسية ، مخطط الحالة لدينا!

من الأفضل تهيئة كائن من هذه الفئة في أقرب وقت ممكن. على وجه التحديد في الوحدة ، من الأفضل أن يكون الكائن هو DontDestroyOnLoad .



إذا نظرت داخل Sheduler ، يمكنك رؤية الحقول التالية:



  1. نقطة التفتيش الحالية في نقطة الفحص الحالية
  2. مجموعة من جميع الشروط المضافة وسلوكها القاموس ومعاملو الحالة والإجراء والظروف - بحيث

    يعرف المخطط الدور الذي يجب أن يلعبه الشرط النهائي
  3. Dictionary &ltint,Condition&gt CheckPoints — Sheduler, Dictionary, , . .
  4. Queue &ltCondition&gt WaitingConditions ,



يخزن Sheduler سلوك كل شرط ويتم تشغيله وفقًا لهذه الفئة ، ويتم تعيينه في وقت إضافة الشرط إضافة الفراغ العام (Condition newCondition ، Action CallBack) ، حيث يوجد مفوض مطلوب في الوسيطات. تقرأ الطريقة نفسها اسم الشرط وتلقي استثناءً إذا كان فارغًا أو تمت إضافته بالفعل - وهذا ضروري في حالة احتياجك لسبب ما إلى أخذ شرط من الجدول المسمى List & ltCondition & gt GetConditions (params string [] conditionName) . أيضًا ، تعمل طريقة الإضافة Add () فورًا على تشغيل Start () للشرط المُضاف. هذا مفيد إذا قمت بتشغيل Start ()سيتم نسيان الشرط الإضافي من خلال أي من المطورين ، وأيضًا لتجنب التخلص المستمر من هذه الوظيفة من Sheduler. إذا كنت بحاجة إلى مكان مختلف لبدء الشرط ، فأنت تعمل فقط مع الشرط كما كان من قبل ، ويمكنك دائمًا تغيير عداداته. هذا هو جمال Sheduler - فهو يتعامل مع المكان الذي يكون فيه الشرط جاهزًا ، وحيث يتم تغيير جاهزيته ، ويقوم بإجراء هذا الحساب في وقت استدعاء طريقته الرئيسية Condition Invoke (params Condition [] شارات) . في الحجج ، يمكنك تحديد بعض الشارات ، أي تلك الشروط التي يجب أن تعمل حصريًا ، وتلك التي جاء دورها ، ومع ذلك ، لم تظهر في قائمة الشارات ، فلن تعمل. ولكن ، إذا لم تحدد أي شيء ، فعندئذٍ ، كما ينبغي ، يحق لكل شخص الاتصال في ذروة قائمة الانتظار!



تأكد من التفكير في المكان الذي سيتم فيه حساب نقاط التفتيش لـ Sheduler NextCheckPoint () ، على سبيل المثال ، في الطريقة ، في النهاية أو في بداية الجولة ،

مثال كامل لما هو مطلوب للعمل مع Sheduler:



    public Condition OfferBuyVip;
    public Condition OfferToShareWithFriends;
    public Condition OfferToVisitSite;

    public Sheduler OfferSheduler;

    public void Start(){
        OfferSheduler = new Sheduler(currentLevel); //      

        /*
         *         
         */

        OfferSheduler.Add(OfferBuyVip, () => Debug.Log("     VIP"));
        OfferSheduler.Add(OfferToShareWithFriends, () => Debug.Log("    "));
        OfferSheduler.Add(OfferToVisitSite, () => Debug.Log("     ,   "));
    }

    public void FinishRound(){
        OfferSheduler.NextCheckPoint(currentLevel); //  ,      
        OfferSheduler.Invoke(OfferBuyVip, OfferToShareWithFriends) //      ,    
    }

    public void StartRound(){
        OfferSheduler.Invoke(OfferToVisitSite); //     
        //   ,   ,           Sheduler
    }





هذه هي الطريقة التي حققنا بها أن الوظائف الثلاث لشروطنا يتم استدعاؤها في أماكن مختلفة ، بينما يحترمون بعضهم البعض ولا يزحفون إلى كل شيء ، لكن يلاحظون قائمة الانتظار (مثل قائمة انتظار رقمية حديثة للقسائم) ، ويقفز المستخدم بسرعة من خط النهاية إلى بداية اللعبة ، لن ترهق من عدد من المقترحات. مع Sheduler ، يحافظ على انسجام واضح من البساطة والمرونة ، لأنه مع Sheduler والمفوض الذي تم تمريره إليه عبر طريقة Add (Condition newCondition ، Action CallBack) ، من الممكن تنفيذ أي اتصال بين النوافذ.



على سبيل المثال ، عند استدعاء لافتة إعلانية ، يظهر عرض شراء Premium بدون إعلان بعد مستويين:



    void Start(){
        OfferSheduler = new Sheduler(currentLevel);

        callAddBanner = new Condition(" ");
        callAddBanner.setedSeconds = 80; //    80 
        OfferBuyVip = new Condition("  VIP  ");

        OfferSheduler.Add(callAddBanner, 
            delegate()
            {
                Debug.Log(" ");
                OfferBuyVip.setedSkips = 2; //   
                OfferBuyVip.START();  // 
            }
           );
        OfferSheduler.Add(OfferBuyVip,
            delegate ()
            {
                Debug.Log("     VIP");
                OfferBuyVip.setedSkips = 0; //  !  
 //,  
            }
           );
        }
        
        void Finish(){
            OfferSheduler.NextCheckPoint(currentLevel); //    
// 
            OfferSheduler.Invoke(); //     
//    
        }


تمامًا مثل هذا ، سيتم الآن إطلاق إعلان غير مشتت للانتباه كل 80 ثانية (بعد كل شيء ، لا يتم استدعاؤه خلال جولة مهمة ، ولكن عند خط النهاية) وأيضًا يطلق عرضًا لشراء إعلان عندما يكون ذلك مناسبًا لك! وأفضل شيء هو أن أي مطور في الفريق يمكنه الآن إضافة مقترحاته إلى Sheduler ، وسيقوم Sheduler بتوزيع كل شيء.



All Articles