2023-06-04 Unity ScriptableObject2——ScriptableObject 的应用

news/2024/11/25 20:35:08/

文章目录

        • 一、配置数据
        • 二、复用数据
        • 三、多态特性的利用
        • 四、单例模式获取数据

一、配置数据

​ ScriptableObject 数据文件非常适合用来做配置文件:

  1. 配置文件的数据在游戏发布之前定规则
  2. 配置文件的数据在游戏运行时只会读出来使用,不会改变内容
  3. 在 Unity 的 Inspector 窗口进行配置更加的方便

​ 对于如下角色配置信息:

image-20230604155414654

​ 可以采用如下方法进行配置:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[CreateAssetMenu(fileName = "RoleInfo", menuName = "ScriptableObject/角色信息")]
public class RoleInfo : SingleScriptableObject<RoleInfo>
{[System.Serializable]public class RoleData{public int    id;public string res;public int    atk;public string tips;public int    lockMoney;public int    type;public string hitEff;}public List<RoleData> roleList;
}

​ 创建数据文件后进行相应的编辑,使用时声明成员进行关联即可。

image-20230604155513949

​ 只用不改,并且经常会进行配置的数据,非常适合使用 ScriptableObject

​ 我们可以利用 ScriptableObject 数据文件来制作编辑器相关功能,比如:Unity内置的技能编辑器、关卡编辑器等等
​ 我们不需要把编辑器生成的数据生成别的数据文件,而是直接通过 ScriptableObject 进行存储
​ 因为内置编辑器只会在编辑模式下运行,编辑模式下 ScriptableObject 具备数据持久化的特性

二、复用数据

​ 以子弹对象为例,其数据结构如下:

public class Bullet : MonoBehaviour
{public float speed;public int   atk;// Update is called once per framevoid Update() {this.transform.Translate(Vector3.forward * speed * Time.deltaTime);}
}

​ 由于相同子弹的 speed 和 atk 一样,因此创建多个子弹时,相同数据的 speed 和 atk 占据了多余的内存。作出如下修改:

  • Bullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bullet : MonoBehaviour
{public BulletInfo info;// Update is called once per framevoid Update() {this.transform.Translate(Vector3.forward * info.speed * Time.deltaTime);}
}
  • BulletInfo.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;[CreateAssetMenu()]
public class BulletInfo : ScriptableObject
{public float speed;public int   atk;
}

​ 创建 BulletInfo 数据文件后关联到 Bullet 的成员 info。这样之后创建了多个子弹,它们的数据都是一样,更改 info 数据文件,所有子弹的数据都将被修改。

image-20230604160533122

三、多态特性的利用

​ 某些行为的变化是因为数据的不同带来的,我们可以利用面向对象的特性和原则,以及设计模式相关知识点,结合 ScriptableObject 做出更加方便的功能

​ 比如随机音效,物品拾取,AI等等等(里氏替换原则和依赖倒转原则)

  • 随机音效:播放音乐时,可能会随机播放多个音效当中的一种
  • 物品拾取:拾取一个物品,物品给玩家带来不同的效果
  • AI:不同数据带来的不同行为模式

(一)随机音效播放

​ 基类:播放音效设置

public abstract class AudioPlayBase : ScriptableObject
{public abstract void Play(AudioSource source);
}

​ 父类 1:随机播放音效

[CreateAssetMenu]
public class RandomPlayAudio : AudioPlayBase
{// 希望随机播放的音效文件(数据文件)public List<AudioClip> clips;// 重写播放函数public override void Play(AudioSource source) {if (clips.Count == 0)return;// 设置音效切片文件source.clip = clips[Random.Range(0, clips.Count)];source.Play();}
}

​ 父类 2:播放指定音效

[CreateAssetMenu()]
public class PlayerAudio : AudioPlayBase
{public AudioClip clip;public override void Play(AudioSource source) {source.clip = clip;source.Play();}
}
  • 步骤一:创建 RandomPlayAudio 数据文件

    image-20230604161418935 image-20230604161721292
  • 步骤二:通过基类调用两种父类方法

    public class Lesson7 : MonoBehaviour
    {public AudioPlayBase audioPlay;void Start() {audioPlay.Play(this.GetComponent<AudioSource>());}
    }
    

    在 Inspector 窗口中配置即可

    image-20230604161949643

(二)物品拾取

​ 通过判断物品类型来实现不同的效果

​ 基类:物品效果

public abstract class ItemEffect : ScriptableObject
{public abstract void AddEffect(GameObject obj);
}

​ 父类 1:加血效果

[CreateAssetMenu]
public class AddHealthItemEffect : ItemEffect
{public int num;public override void AddEffect(GameObject obj) {// 通过获取到的对象 让其加血 加num的值}
}

​ 父类 2:加攻击力效果

[CreateAssetMenu]
public class AddAtkItemEffect : ItemEffect
{public int atk;public override void AddEffect(GameObject obj) {// 具体加多少攻击力的逻辑}
}

​ 物品对象:

public class ItemObj : MonoBehaviour
{public ItemEffect eff;private void OnTriggerEnter(Collider other) {// 为和物品产生碰撞的对象加效果eff.AddEffect(other.gameObject);}
}
  • 步骤一:生成数据文件,配置数据

    image-20230604162549993
  • 步骤二:创建物品预制体,关联数据文件

    image-20230604162735193
  • 步骤三:物品实现完成

四、单例模式获取数据

​ 对于只用不变并且要复用的数据,比如配置文件中的数据,往往需要在很多地方获取它们
​ 将此类数据通过单例模式化的去获取,可以提升效率,减少代码量

​ 单例模式基类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SingleScriptableObject<T> : ScriptableObject where T : ScriptableObject
{// 所有的数据文件都放在 Resources文件夹下的 ScriptableObject 中private static string LOAD_PATH = "ScriptableObject/";private static T instance;public static T Instance {get {// 如果为空 首先应该去资源路劲下加载 对应的 数据资源文件if (instance == null) {// 定两个规则// 1.所有的 数据资源文件都放在 Resources文件夹下的 ScriptableObject 中// 2.需要复用的 唯一的数据资源文件名 我们定一个规则:和类名是一样的instance = Resources.Load<T>(LOAD_PATH + typeof(T).Name);}// 如果没有这个文件 为了安全起见 我们可以在这直接创建一个数据if (instance == null) {instance = CreateInstance<T>();}// 甚至可以在这里 从json当中读取数据,但是不建议用ScriptableObject来做数据持久化return instance;}}// 对于相同类型不同名称的数据资源,通过该方法指定名称加载public static T Load(string name) {return Resources.Load<T>(LOAD_PATH + name);}
}

使用:

[CreateAssetMenu]
public class TestData : SingleScriptableObject<TestData>
{public int i;public bool b;
}
public class Lesson8 : MonoBehaviour
{// Start is called before the first frame updatevoid Start() {print(TestData.Instance.i);print(TestData.Load("TestData").b);}
}

http://www.ppmy.cn/news/208904.html

相关文章

通用程序设计——如果需要精确,避免使用float和double

float和double主要为了科学计算和工程计算而设计&#xff0c;执行二进制浮点运算&#xff0c;这是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的。然而&#xff0c;它们没有提供完全精确的结果&#xff0c;所以不适合用于需要精确结果的场合&#xff0c;尤其是…

Object.is() 同值相等

Object.is() 同值相等 同值相等的底层实现 Object.is() Object.is() 是 ES6抛出来的方法 ES5并没有暴露js引擎的同值相等的方法 不进行隐式类型转换 1’与 1 var a 1 var b 1 var res Object.is(a, b) console.log(res); // false0 与 0 与 -0 Object.is(0, 0) // true O…

Lync方案建议书

Lync方案建议书 微软&#xff08;中国&#xff09;有限公司 2011年2月 修改记录 日期版本/修改者备注2011/2/20 目 录 第1章 系统建设目标 2 第2章 系统建设原则 2 2.1 协议开放性 2 2.2 安全性 3 2.3 易用性 3 2.4 可用性 3 2.5 易管理 3 …

iOS

iOS 分类&#xff1a; 操作系统 2011-10-18 22:53 80人阅读 评论(0) 收藏 举报 ios 求助编辑百科名片 ios系统界面 iOS是由苹果公司为iPhone开发的操作系统。它主要是给iPhone、iPod touch以及iPad使用。就像其基于的Mac OS X操作系统一样&#xff0c;它也是以Darwin为基础的…

iPhone史上最全的使用教程

为什么80%的码农都做不了架构师?>>> iPhone史上最全的使用教程 iPhone的解锁、越狱、激活、固件等等是什么意思,有什么分别 这几天看见好多新人问这几个词的含义及区别。我在这儿说说我的看法,不是官方解释,不懂的学习一下,懂的绕道,如有错误,敬请指正! …

江苏省×××局数据复制软件招标

(1) 需为平台提供商品化数据同步 / 复制软件 &#xff0c; 其中 省局和 12 个地市局&#xff08;不包括南京局&#xff09;各提供一套数据 同步 / 复制软件&#xff0c; 具体配置和功能要求如下&#xff1a; 配置 13 套数据同步 / 复制软件 的 license &#xff08;许可&a…

dropbox介绍

百科名片 Dropbox Dropbox是一个提供同步本地文件的网络存储在线应用。支持在多台电脑多种操作中自动同步。并可当作大容量的 网络硬盘使用。Dropbox采用免费试用高级服务收费的Freemium模式&#xff0c;最初2GB空间免费&#xff0c;此后则需要按月支付存储费用。对于已经从Dro…

dropbox

dropbox 百科名片 Dropbox Dropbox&#xff08;中文名&#xff1a;碉堡箱&#xff09;是一个提供同步本地文件的网络存储在线应用。支持在多台 电脑多种操作中自动 同步。并可当作大容量的网络硬盘使用。Dropbox采用免费试用高级服务 收费的Freemium模式&#xff0c;最初2GB空间…