Unity框架之公共Mono模块

欢迎加入光光的奇妙冒险,我是你们的煎饼光子老师。

这期要介绍的是Unity框架之公共Mono模块

首先这里的Mono指的就是Unity中的MonoBehaviour类(偷懒简写。。。)

为什么要介绍这个框架呢?

相信大家在游戏开发一定会碰到这个问题,想让不继承Mono的类也能够使用Mono的API,类似生命周期函数和协程这些,但是该怎么实现呢

其实非常简单,只需要两个脚本就可以搞定

(如果想要直接获取代码的话,可以直接免费下载在文章上方的相关资源)

以实现Update和协程为例,我们开始讲解代码


第一个脚本是MonoController

在里面创建一个委托,并给外部提供两个方法用于往委托中添加和移除函数

之后就是在Update中判断委托是否为空,如果不为空就调用委托

扫描二维码关注公众号,回复: 17429479 查看本文章
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// Mono的管理者
/// 1.生命周期函数
/// 2.事件 
/// 3.协程
/// </summary>
public class MonoController : MonoBehaviour {

    //事件
    private event UnityAction updateEvent;
	
	void Start () 
    {
        //在场景上生成对象,并且过场景不移除
        DontDestroyOnLoad(gameObject);
	}
		
	void Update () 
    {
        //如果事件不为空就调用
        if (updateEvent != null)
            updateEvent();
    }

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

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

第二个脚本是MonoMgr,我们会通过它来使用MonoController

首先它是一个单例模式

(如果大家不了解单例模式的话,可以在我的空间搜索单例去免费看我之前写过的相关文章)

其次它需要关联MonoController以使用

并给外部提供两个方法用于往MonoController的委托中添加和移除函数,相当于是又进行了一次封装

至此实现使用Update就已经结束了

然后协程的使用

这一步其实也非常简单,就是F12去查看Mono的协程代码,然后将需要的API复制到MonoMgr中,

在其中的方法实现中,去调用MonoController来开启协程

这里大家可以结合下面的代码理解

using System.Collections;
using System.ComponentModel;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 通过MonoMgr来使用MonoController
/// 1.可以提供给外部添加帧更新事件的方法
/// 2.可以提供给外部添加协程的方法
/// </summary>
public class MonoMgr : BaseMgr<MonoMgr>
{
    private MonoController controller;

    private MonoMgr()
    {
        //保证了MonoController对象的唯一性
        GameObject obj = new GameObject("MonoController");
        controller = obj.AddComponent<MonoController>();
    }

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

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

    //其余的方法可以F12查看 然后复制过来,
    //其实就是对现有的API再加一次封装
    public Coroutine StartCoroutine(IEnumerator routine)
    {
        return controller.StartCoroutine(routine);
    }

    public Coroutine StartCoroutine(string methodName, [DefaultValue("null")] object value)
    {
        return controller.StartCoroutine(methodName, value);
    }

    public Coroutine StartCoroutine(string methodName)
    {
        return controller.StartCoroutine(methodName);
    }
}

最后,我们简单写个测试脚本,来测试一下 

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Test2
{    
    public Test2()
    {
        MonoMgr.Instance.StartCoroutine(Print123());
    }

    IEnumerator Print123()
    {
        yield return new WaitForSeconds(1);
        Debug.Log("123");
    }
    public void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha0))
            SceneManager.LoadScene(0);
        if (Input.GetKeyDown(KeyCode.Alpha1))
            SceneManager.LoadScene(1);

        if (Input.GetMouseButtonDown(0))
        {
            PoolMgr.Instance.PoolGet("Test/Cube");
        }

        if (Input.GetMouseButtonDown(1))
        {
            PoolMgr.Instance.PoolGet("Test/Sphere");
        }
    }
}
public class Test:MonoBehaviour
{
    private void Start()
    {
        Test2 t2=new Test2();
        MonoMgr.Instance.AddUpdateListener(t2.Update);
    }
}

 相信大家一定很顺利的实现了这些效果,让我们下期再见吧

猜你喜欢

转载自blog.csdn.net/Blueberry124/article/details/142361271