Unity 中ScriptableObject 是干什么的?
一、什么是 ScriptableObject?ScriptableObject 是 Unity 提供的一个数据配置存储基类,它是一个可以用来保存大量数据的数据容器,我们可以将它保存为自定义的数据资源文件。
ScriptableObject 是一个类似 MonoBehaviour 的基类,继承自 UnityEngine.Object 。要想使用它,需要我们写个脚本去继承 ScriptableObject 。需要注意的是,继承自 SctiptableObject 的脚本无法挂载到游戏物体上,毕竟它不是继承自 MonoBehaviour。
ScriptableObject 类的实例会被保存成资源文件(.asset文件),和预制体,材质球,音频文件等类似,都是一种资源文件,存放在 Assets 文件夹下,创建出来的实例也是唯一存在的。
简单来说ScriptableObject 是一个可独立于类实例来保存大量数据的数据容器。ScriptableObject 的一个主要作用是通过避免重复值来减少项目的内存使用量。如果项目有一个预制体在附加的 MonoBehaviour 脚本中存储不变的数据,这将非常有用。
每次实例化预制体时,都会产生单独的数据副本。这种情况下可以不使用该方法并且不存储重复数据,而是使用 ScriptableObject 来存储数据,然后通过预制体的引用访问数据。这意味着内存中只有一个数据副本。
就像 MonoBehaviour 一样,ScriptableObject 派生自基本 Unity 对象,但与 MonoBehaviour 不同,不能将 ScriptableObject 附加到GameObject。正确的做法是需要将它们保存为项目中的资源。
如果使用 Editor,可以在编辑时和运行时将数据保存到 ScriptableObject,因为 ScriptableObject 使用 Editor 命名空间和 Editor 脚本。但是,在已部署的构建中,不能使用 ScriptableObject 来保存数据,但可以使用在开发期间设置的 ScriptableObject 资源中保存的数据。
从 Editor 工具作为资源保存到 ScriptableObject 的数据将写入磁盘,因此将在会话之间一直保留。
二、ScriptableObject 的使用
ScriptableObjects 的主要作用为:
1) 编辑模式下的数据持久化
2) 配置文件 (配置游戏中的数据)
3) 数据复用 (多个对象共用一套数据)
要使用 ScriptableObject,必须在应用程序的 Assets 文件夹中创建一个脚本,并使其继承自 ScriptableObject 类。您可以使用 CreateAssetMenu 属性,从而使用您的类轻松创建自定义资源。例如:
public class AnimationCurveLibrary : ScriptableObject
{
private struct AniCurve
{
public string name;
public AnimationCurve curve;
}
private AniCurve[] CurveLibrary;
public AnimationCurve GetCure(string curveName)
{
AnimationCurve curveResult = null;
for (int i = 0; i < CurveLibrary.Length; i++)
{
if (CurveLibrary.name.Equals(curveName))
{
curveResult = CurveLibrary.curve;
break;
}
}
return curveResult;
}
}使用上述在Assets文件夹中创建的脚本,您可以通过导航到Assets > Create > ScriptableObjects > Create Animation_Curve_Library来创建 ScriptableObject 的实例。为新的 ScriptableObject 实例提供有意义的名称并更改值。要使用这些值,必须创建一个引用 ScriptableObject(在本例中为AnimationCurveLibrary)的新脚本。例如:
public class DoTweenUtils
{
static AnimationCurveLibrary animationCurveLibrary = null;
public static void LoadAnimationCurveLibrary(System.Action callBack = null)
{
if (animationCurveLibrary == null)
{
ResourceManager.Instance.LoadAssetAsync<AnimationCurveLibrary>(&#34;Assets/Shelter/Scripts/ScriptableObjects/AnimationCurveLibrary.asset&#34;, &#34;AnimationCurveLibrary&#34;,
(key, asset, err) =>
{
if (string.IsNullOrEmpty(err) && asset is AnimationCurveLibrary)
{
ResourceUtils.UnloadAssetWithKey(key);
animationCurveLibrary = asset as AnimationCurveLibrary;
if (animationCurveLibrary != null && callBack != null)
{
callBack();
}
}
}
);
}
}
public static AnimationCurve GetAnimationCurveInfos(string curveName)
{
AnimationCurve curve = animationCurveLibrary.GetCure(curveName);
if (curve == null)
{
GameFramework.Log.Error(&#34;AnimationCurveLibrary Animation Curve is null ! Curve Name :{0}&#34;, curveName);
}
return curve;
}
}这样我们就可以应用DoTweenUtils类获取AnimationCurve的信息了。
这个类很简单,用下就知道了,它的作用已经很清楚了,我们可以根据项目需求来使用,它为我们提供了一种新的数据存储方式。
页:
[1]