Unity_U_OP1 ScriptableObject 替代单例

发布时间 2023-12-28 17:40:38作者: shenlei_blog

核心思想:解耦GameManager单例模式,不再由一个单例管理所有事件触发,拆分成无数个小单例,各自管理

优点:

  1. 更加灵活的事件管理模式
  2. 复用性高,对于相关类型的事件,只需要写一遍代码,剩下的拖拖拖就可以实现相同的功能。

缺点:

  1. 管理起来相对麻烦
  2. 不利于维护,除非对这个系统非常了解,要不然排查起来难度系数较高

下图为主要逻辑

image-20231228163319372

这里主要需要实现两个部分的内容,一个是ScriptableObject ,另一个是事件的监听部分。

Part1. ScriptableObject 部分

[CreateAssetMenu(fileName = "SceneManager", menuName = "Event/SceneManger")]
public class SceneManagerSO : ScriptableObject
{
    //事件系统,用于监听者注册
    public event UnityAction OnEventRaised;
    
    //资源,场景等等,这里可以添加组件用于处理
    [SerializeField] public AssetReference NextScene;
    
    //invoke操作
    public void RaiseEvent(bool value)
    {
        if (OnEventRaised != null)
            OnEventRaised.Invoke();
    }
}

Part2.Listener部分

public class ListenerSceneChanged : MonoBehaviour
{
    [SerializeField]
    private SceneManagerSO _sceneManager;

	//事件注册需要放在onEnable()里面,优先于Start被调用
    private void OnEnable()
    {
        _sceneManager.OnEventRaised += OnSceneChanged;
    }

    private void OnDisable()
    {
        _sceneManager.OnEventRaised -= OnSceneChanged;
    }

    //监听执行函数
    private void OnSceneChanged()
    {
        _sceneManager.NextScene.LoadSceneAsync().Completed+= ((handle) =>
        {
            Debug.Log($"{handle.Result}");
        });
    }

}

触发操作不需要单独写脚本,也可以写,本样例是点击Button切换场景,用Button自带的事件即可
image

  • 事件绑定的是ScriptableObject模块的invoke方法,这样就可以触发监听者执行对应事件