欢迎加入光光的奇妙冒险,我是你们的煎饼光子老师。
这期要介绍的是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);
}
}
相信大家一定很顺利的实现了这些效果,让我们下期再见吧