public Mono class

        In daily development, we sometimes encounter classes that do not want to inherit MonoBehaviour, but we need to call the life cycle function in MonoBehaviour or open and close coroutines. At this time, we only need to use a management class to encapsulate MonoBehaviour, and only call this management class inside the class that needs to use the above functions to solve the problem. Below is the implementation for the public Mono class.

First declare a MonoController class for the first layer of encapsulation of MonoBehaviour.

    public class MonoController : MonoBehaviour
    {
        public event UnityAction updataEvent;
        private void Start()
        {
            DontDestroyOnLoad(this);
        }

        private void Update()
        {
            if (updataEvent != null)
                updataEvent();
        }

        /// <summary>
        /// 给外部提供的添加帧更新事件的函数
        /// </summary>
        public void AddUpdateListener(UnityAction action)
        {
            updataEvent += action;
        }

        /// <summary>
        /// 给外部提供的移除帧更新事件的函数
        /// </summary>
        /// <param name="action"></param>
        public void RemoveUpdateListener(UnityAction action)
        {
            updataEvent -= action;
        }
    }

 Although this class inherits from MonoController, it encapsulates functions through delegated events, and then calls these functions in its Update. In essence, it provides an interface for the outside to execute functions every frame in Update.

Then declare a singleton MonoManager for the second layer of encapsulation.

public class MonoManager : ISingleton
    {
        public static MonoManager Instance => Singleton<MonoManager>.Instace;
        public MonoController controller;
        public MonoManager() {
            GameObject obj = new GameObject("MonoContorller");
            controller = obj.AddComponent<MonoController>();
        }
        public void Init() { }

        /// <summary>
        /// 给外部提供的添加帧更新事件的函数
        /// </summary>
        public void AddUpdateListener(UnityAction action)
        {
            controller.AddUpdateListener(action);
        }

        /// <summary>
        /// 给外部提供的移除帧更新事件的函数
        /// </summary>
        /// <param name="action"></param>
        public void RemoveUpdateListener(UnityAction action)
        {
            controller.RemoveUpdateListener(action);
        }

        /// <summary>
        /// 开启协程
        /// </summary>
        /// <returns></returns>
        public Coroutine StartCoroutine(IEnumerator routine) {
            return controller.StartCoroutine(routine);
        }

        /// <summary>
        /// 开启协程
        /// </summary>
        /// <param name="methodName">函数名</param>
        /// <param name="value">想要传递的参数</param>
        /// <returns></returns>
        public Coroutine StartCoroutine(string methodName, [DefaultValue("null")] object value) {
            return controller.StartCoroutine(methodName, value);
        }

        /// <summary>
        /// 开启协程
        /// </summary>
        /// <param name="methodName">函数名</param>
        /// <returns></returns>
        public Coroutine StartCoroutine(string methodName) {
            return controller.StartCoroutine(methodName);
        }
        //通过string函数名 只能开启controller中的函数
        //如果想要通过协程去开启别的脚本中的函数
        //则不能使用该方法
    }

 Generate the MonoController game object in the scene and add the MonoController to it, and then let the MonoManager control whether to add a delegate. And directly declared inside the Manager that the return value is Coroutine to start the coroutine function, its essence is also the encapsulation of Mono.

 The method of use is as follows:

    public class Test
{
    public  void TestFunc()
    {
        Debug.Log(111);
    }
}

public class TestTest:MonoBehaviour {
    Test test =new Test ();
    private void Start()
    {
        MonoManager.Instance.AddUpdateListener(test.TestFunc);
    }
}

Declare a Test class, which has a method TestFunc to print 111, then declare a TestTest class inheriting the word MonoBehaviour, and then add TestFunc in its Start function. Mount TestTest to GameObjet, and finally implement the function in the class Test that is not inherited from MonoBehaviour to execute every frame.

Guess you like

Origin blog.csdn.net/qq_52690206/article/details/128858283
Recommended