ScriptableObject其实出了好多年了,一直以来网上的教程都是把ScriptableObject当作一个数据保存的方式来使用,都没想过这玩意里还能写逻辑。
然后前两天官方出了一期视频:https://www.bilibili.com/video/BV1eA411p7Ra
这期视频中讲Unity论坛开放一个线上的开源游戏项目,全球开发者包括策划、美术等等可以一起参加开发这个项目,然后到2021年3月份截止。具体的可以参考咖喱老师的视频解说https://space.bilibili.com/434224775?spm_id_from=333.788.b_765f7570696e666f.1
有兴趣的小伙伴可以一起参与进去看看,写不了代码帮忙测试一些报个bug也能留名不是~
不想参与的也可以学习一下,这个项目的程序部分目前是以ScriptableObject为中心,数据都在ScriptableObject上填,然后事件的收发则是走ScriptableObject的类。
这里我们简化一下,看看官方的设计:
代码如下,注释很详细,结构如图所示,也是很基础的委托用法,不熟悉委托的可以看一下再读本篇,我的其他文章里也有讲:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//创建一个数据类,可以填写这个类要使用的相关数据
//使用CreateAssetMenu在右键菜单栏可以创建这个ScriptableObject
[CreateAssetMenu(fileName = "New Duck", menuName = "创建Duck", order = 1)]
public class Duck : ScriptableObject
{
//把数据序列化出来让别人可填
[SerializeField]
private string m_DuckName;
//属性暴露出去让外部类访问
public string DuckName { get => m_DuckName; set => m_DuckName = value; }
//一个委托,在输入时调用此委托,在需要监听的地方监听此委托即可
public Action QuackAction;
//输入是通过UGUI直接调用此函数,或者其他的输入方式
//比较适合官方的这个项目,但其他项目还要考虑一下输入方式
//这里我们参考官方使用UGUI接入一下,源代码还有键盘输入的一些获取可以自行参考
public void Quack(string content)
{
Debug.Log(m_DuckName + ":" + content);
if (QuackAction != null)
{
//委托触发
QuackAction.Invoke();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Reader : MonoBehaviour
{
[SerializeField]
private Duck m_Duck = default;//监听的鸭子对象,需要在面板上绑定
void Start()
{
//添加委托需要实现的函数
m_Duck.QuackAction += OnActionInvoke;
}
void OnActionInvoke()
{
Debug.Log("OnActionInvoke");
}
}
需要在Unity中创建:
创建完成后可以填写数据:
而输入来自UGUI,同样可以填写一些参数:
最后Reader监听者上还需要挂上这个消息发送者:
说实话,个人感觉解耦是解耦了,但是只是代码意义上的解耦,应付小项目也还行,对一个项目而言其他的耦合都暴露在Unity中挂关联关系,我还需要深入理解一下这样做的好处