首页 > 数据库 >如何使用 Unity 的 ScriptableObjects 和 Resources 系统来创建一个简易的数据库系统,用于存储和管理游戏数据。

如何使用 Unity 的 ScriptableObjects 和 Resources 系统来创建一个简易的数据库系统,用于存储和管理游戏数据。

时间:2024-07-12 13:31:38浏览次数:20  
标签:return id Unity ScriptableObjects DataManager cs dataDictionary public Resources

1. 引言

  • 问题: 如何在 Unity 中存储数据?
  • 解决方案: 使用 ScriptableObjects 和 Resources 系统创建一个易于使用和管理的数据库。
  • 优势:
    • 自动读写数据
    • 自动处理资源实例化和更改
    • 无需额外插件
    • 使用用户定义键进行访问
    • 可扩展性强

2. 实现

2.1 项目结构

四个主要的脚本:

  • ItemData.cs: 定义了一个 ScriptableObject 类,用于存储物品数据,例如 ID、名称、等级和图标。
  • DataManager.cs: 定义了一个抽象类,用于管理数据,包括读取、添加和删除数据项。
  • ItemDataManager.cs: 继承自 DataManager 类,并实现了具体的数据管理逻辑,例如从 Resources 文件夹加载物品数据。
  • InventoryTestContext.cs: 用于测试数据库功能,打印所有物品信息。

2.2 ScriptableObjects

  • ScriptableObjects 用于在 Unity 中存储数据到资源文件夹中,可以通过代码进行读写和修改。
  • 使用 [CreateAssetMenu] 属性可以创建自定义菜单项,用于在编辑器中创建 ScriptableObject 对象。
  • 警告:不建议在游戏运行时通过代码修改 ScriptableObject 中的字段,可能会导致编辑器中出现奇怪的行为。

2.3 创建对象数据:Scriptable Object Item.cs 脚本

  • ItemData 类继承自 ScriptableObject,并定义了四个属性:id、displayName、levelRequired 和 icon。
  • 使用 [SerializeField] 属性使属性在编辑器中可见并可编辑。
  • 提供了相应的 getter 和 setter 方法。

ItemData.cs:

using System.Globalization;
using UnityEngine;

namespace DatabaseSystem.ScriptableObjects 
{
    [CreateAssetMenu(menuName = "Demo/Items/Item Data")]
    public class ItemData : ScriptableObject
    {
        #region 变量
        [SerializeField] private int id = default;
        [SerializeField] private string displayName = default;
        [SerializeField] private int levelRequired = default;
        [SerializeField] private Sprite icon = default;

        public int Id 
        {
            get { return id; }
            set { id = value; }
        }

        public string DisplayName 
        {
            set { displayName = value; }
            get { return displayName; }
        }

        public int LevelRequired
        { 
            get { return levelRequired; } 
            set {  levelRequired = value; } 
        }
        public Sprite Icon 
        {
            get { return icon; }
            set { icon = value; } 
        }
        #endregion
    }
}

2.4 编写 ItemDataManager 代码

  • DataManager 类是一个抽象类,定义了数据管理的基本方法,例如 GetAllDataObjects、GetDataObject、TryPutDataItem 和 TryRemoveItem。
  • ItemDataManager 类继承自 DataManager 类,并实现了具体的数据管理逻辑。
  • LoadFromResources 方法从 Resources 文件夹加载所有物品数据,并将其存储在字典中。
  • Initialize 方法用于初始化数据管理器。

DataManager.cs:

using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace DatabaseSystem.Managers
{
    // T 表示key类型,D 表示ItemDat的类型
    public abstract class DataManager<T, D> : MonoBehaviour
    {
        #region Variables
        protected Dictionary<T, D> dataDictionary = default;
        #endregion

        #region Public Methods
        public Dictionary<T, D> GetAllDataObjects()
        {
            return dataDictionary.ToDictionary(k => k.Key, v => v.Value);
        }
        public D GetDataObject(T id)
        {
            if(dataDictionary.ContainsKey(id))
            {
                return dataDictionary[id];
            }

            return default;
        }
        #endregion

        #region Protected Methods
        protected virtual bool TryPutDataItem(T id, D data)
        {
            if (dataDictionary.ContainsKey(id))
            {
                return false;
            }

            dataDictionary.Add(id, data);
            return true;
        }
        protected virtual bool TryRemoveItem(T id, D data)
        {
            if (!dataDictionary.ContainsKey(id))
            {
                return false;
            }

            dataDictionary.Remove(id);
            return true;
        }
        #endregion
    }
}

ItemDataManager:

using DatabaseSystem.ScriptableObjects;
using System.Collections.Generic;
using UnityEngine;

namespace DatabaseSystem.Managers
{
    public class ItemsDataManager : DataManager<int, ItemData>
    {
        #region Variables
        [SerializeField] private string resourcesItemsFolder = default;
        #endregion

        #region Private Methods
        private void LoadFromResources()
        {
            dataDictionary = new Dictionary<int, ItemData>();
            ItemData[] itemsFromResources = Resources.LoadAll<ItemData>(resourcesItemsFolder);
            foreach (var itemData in itemsFromResources)
            {
                TryPutDataItem(itemData.Id, itemData);
            }
        }
        #endregion

        #region Public Methods
        public void Initialize()
        {
            LoadFromResources();
        }
        #endregion
    }
}

2.5 在数据清单中使用数据库

  • 创建两个空物体,分别为其添加 ItemDataManager.cs 和 InventoryTestContext.cs 组件。
  • InventoryTestContext 组件负责初始化 ItemDataManager,并打印所有物品信息。

3. 总结

InventoryTestContext.cs:

  • 使用 ScriptableObjects 和 Resources 系统可以轻松创建一个可扩展的数据库系统。
  • 这种方法可以用于存储各种类型的数据,简化游戏开发流程。

其他要点

  • 警告:序列化成 json 格式时,需要注意字段是否可序列化。
  • DataManager 类可以进行扩展,以支持更多类型的数据。

标签:return,id,Unity,ScriptableObjects,DataManager,cs,dataDictionary,public,Resources
From: https://www.cnblogs.com/guangzhiruijie/p/18298194

相关文章

  • unity 用gps获取经纬度,然后将经纬度通过逆地理编码转换成中文地址(百度API)
    1.通过GPS获取经纬度直接上代码了usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;usingUnityEngine.UI;publicclassGetGPS:MonoBehaviour{stringGetGps="";//publicButtonupdateBtn;Vector2jingWei=newVe......
  • Unity中用于处理 UI 的射线检测和事件处理的两种脚本
    GraphicRaycaster组件GraphicRaycaster是Unity中用于UI系统的射线检测组件。它主要用于检测屏幕上的图形界面元素(如按钮、图片、文本等)的点击事件,并将这些事件传递给相应的UI元素。主要功能射线检测:用于检测屏幕空间中的射线,确定用户点击了哪个UI元素。UI交互:处理......
  • 在unity中被攻击时无敌的设置
    publicclassInvincible:MonoBehaviour {publicSpriteRendererrender; publicColornormalColor; publicColorflashColor; publicintduration; publicboolisInvincible;publicIEnumeratorSetInvincibility(){  isInvincible=true;  for......
  • Unity入门之重要组件和API(4) : Input
    前言Input类主要处理用户输入设备相关操作;输入设备包括鼠标、键盘、触屏、手柄、陀螺仪(重力感应)。1.鼠标1.1鼠标在屏幕的位置print(Input.mousePosition);1.2检测鼠标输入0-左键1-右键2-中键if(Input.GetMouseButtonDown(0)){ print("鼠标按下");}if(Input......
  • Unity实现安卓App预览图片、Pdf文件和视频的一种解决方案
    一、问题背景最近在开发app项目,其中有个需求就是需要在app软件内显示图片、pdf和视频,一开始想的解决方案是分开实现,也就是用Image组件显示图片,找一个加载pdf的插件和播放视频的插件,转念一想觉得太麻烦了,于是就想着看能不能想电脑浏览器打开图片、pdf和视频一样直接加载显示......
  • 【漏洞复现】泛微e-cology——resourceservlet——任意文件读取
    声明:本文档或演示材料仅供教育和教学目的使用,任何个人或组织使用本文档中的信息进行非法活动,均与本文档的作者或发布者无关。文章目录漏洞描述漏洞复现测试工具漏洞描述泛微e-cology是一款由泛微网络科技开发的协同管理平台,支持人力资源、财务、行政等多功能管理......
  • 【Unity】关于IDisposable / 托管资源和非托管资源
    背景最近在做后台快捷键的功能,当应用不被聚焦时,也需要响应快捷键的输入。于是就用到了Win32API里的系统钩子,系统钩子会用到IntPtr去记录hookID,这些资源都是非托管资源,绕过了C#的内存管理系统。在网上搜索了腾讯云社区里关于GlobalKeyBoardHook的文章[1]后作用IDisposable是一......
  • 零基础 用unity做一款FPS射击游戏-制作游戏场景(3)
    制作游戏场景需要各种的资源例如颜色图片模型动画所以我们首先要了解如何去找到资源下载到本地Unity资源商店-优质3D2D游戏制作资源平台 进入这个网站选择3D你就可以找到你所需要的各种资源了随便点击一个免费的模型  添加到我的资源然后回到我们的项目中......
  • Java工程中读取resources目录下properties文件的方式,从上图可知,当工程部署在服务器下
    Java工程中读取resources目录下properties文件的方式,从上图可知,当工程部署在服务器下时,配置文件以及代码都是在对应的classes文件夹下二、具体读取方法1、当需要读取当前路径下的properties文件时,即在本地没有部署到具体服务器上的情况:Filefile=newFile(“src/main/re......
  • Unity读取xml文件
    在XML中配置字典名称,字典的key和value,目前key和value都是用的string类型,通过ParseXml类的ParseData函数,传递字典名称和key来获取valuexml文件内容解析数据类usingUnityEngine;usingSystem.Xml;usingSystem;///<summary>///读取xml信息类///</summary>publicclas......