मेरे पास कक्षा "ए" है, जो ईवेंट "ए" भेज देगा। ईवेंट "ए" की सदस्यता लेने वाले वर्ग इस घटना पर प्रतिक्रिया देंगे। अन्य वर्ग "ए" वर्ग में कुछ भी बदले बिना घटना "ए" की सदस्यता ले सकते हैं;

अब, एकता में ऐसा करने का सबसे उचित तरीका क्या है? क्या कोई मैसेजिंग सिस्टम है जो पहले से ही ऐसा कर सकता है?

यदि नहीं, तो क्या मुझे EventManager वर्ग की तरह कुछ बनाना चाहिए जो ग्राहक वर्गों को सरणी में संग्रहीत करेगा और उनकी विधियों को कॉल करेगा?

0
Etwus 27 मई 2019, 13:25

1 उत्तर

सबसे बढ़िया उत्तर

ऐसा करने के शायद कई तरीके हैं।

सार्वजनिक स्थैतिक सूची

public class A : MonoBehaviour
{
    public static List<A> AvailableAs = new List<A>();

    private void Awake()
    {
        if(!AvailableAs.Contains(this)) AvailableAs.Add(this);
    }

    private void OnDestroy()
    {
        if(AvailableAs.Contains(this)) AvailableAs.Remove(this);
    }

    public void SomePublicMethod()
    {
        // magic
    }
}

और इसका उपयोग करें उदा। पसंद

public class B : MonoBehaviour
{
    // run the method on all currently registered A instances
    public void DoIt()
    {
        foreach(var a in A.AvailableAs)
        {
            a.SomePublicMethod();
        }
    }
}

ग्लोबल इवेंट हैंडलर

या यदि आप एनकैप्सुलेशन के लिए जाना चाहते हैं, जैसा कि आपने सभी ए के लिए एक वैश्विक ईवेंट हैंडलर का उल्लेख किया है

namespace ANamespace
{
    public static class AEventHandler
    {
        internal static event Action OnInvokeA;

        public static void InvokeAEvent()
        {
            if(OnInvokeA != null) OnInvokeA.Invoke();
        }
    }
}

और ए में

namespace ANamespace
{
    public class A : MonoBehaviour { 

        private void Awake()
        {
            // it is save to remove a callback first even 
            // if it was not added yet. This makes sure it is
            // added only once always
            AEventHandler.OnIvokeA -= SomePrivateMethod;
            AEventHandler.OnIvokeA += SomePrivateMethod;
        }

        private void OnDestroy()
        {
            AEventHandler.OnIvokeA -= SomePrivateMethod;
        }

        private void SomePrivateMethod()
        {
            // magic
        }

    }  
}

अब B में आप बस करना पसंद करेंगे

// invoke the event and whoever is added as listener will do 
// whatever he registered
// in this case all A instances execute their method
AEventHandler.InvokeAEvent();

एकता घटना

यदि आपके पास केवल एक वर्ग A है जो किसी घटना को अंजाम देता है और आप चाहते हैं कि अन्य लोग उस पर प्रतिक्रिया दें तो बस UnityEvent लाइक करें

public class A : MonoBehaviour
{
    public UnityEvent OnSomethingHappened = new UnityEvent();

    private void SomeMethodIWillRun()
    {
        //...
        OnSomethingHappened.Invoke();
    }
}

अब आप GameObjects/Components में खींचकर उस ईवेंट में आसानी से कॉलबैक जोड़ सकते हैं और कॉल करने के लिए विधि का चयन कर सकते हैं। (बिल्कुल वही चीज़ onClick के लिए प्रयोग की जाती है घटना Button घटक btw। ;))

और आप अभी भी रनटाइम पर स्क्रिप्ट के माध्यम से कॉलबैक जोड़ सकते हैं जैसे

public class B : MonoBehaviour
{
    public A referenceToA;

    private void Start()
    {
        referenceToA.OnSomethingHappened.AddCallback(OnASomethingHappened);
    }

    private void OnDestroy()
    {
        referenceToA.OnSomethingHappened.RemoveCallback(OnASomethingHappened)
    }

    private void OnASomethingHappened()
    {
        //
    }
}

नोट: स्मार्टफोन पर टाइप किया गया है इसलिए कोई वारंटी नहीं है लेकिन मुझे आशा है कि विचार स्पष्ट हो जाएगा।

4
Immorality 27 मई 2019, 11:49