将 ScriptableObjects 加载到单个预制件/多个预制件的最佳实践是什么?

2024-03-12

(脚本化对象 = SO)

我最近一直在尝试了解 ScriptableObjects,并在 Unity 中建立了一个项目,我只想射击生成的传入敌人。我已经设置了它,这样我就可以通过 SO:s 创建不同的敌人,但注意到我仍然需要为每个敌人创建一个预制件。因此,在谷歌搜索不太顺利之后,我想问是否有一种方法可以为每个产生的敌人加载特定的SO:s?

假设我有一个生成管理器,它根据生成的百分比生成不同的敌人。是否可以在运行时通过脚本检查生成哪个敌人的概率,然后加载/查找通过 SO:s 创建的特定数据?


TLDR:使用 Monobehvaiour 来实现敌人。使用 SO 只是为了设置其数据或实现其部分逻辑。所以最好不要为每个敌人生成一个 SO。您将敌人生成为预制件,并在其预制件中添加一个或多个 SO 来实现合成。

为了理解这一点,我可以解释 SO 的历史,这样您就可以找到所有常用的实现。

第 1 阶段 - 数据容器

最初 SO 是为了存储(非可变)数据。它们可以用作模板。

即,您有一个武器,并且您为每种武器实例化一个武器。 通过这种方式,您可以将武器附加到一个单元上。

    public class Attacker : MonoBehaviour
    {
        public Weapon weapon;

        public void Attack(IDamageGetter target) => target.GetDamage(weapon.damage);
    }

    public interface IDamageGetter
    {
       void GetDamage(int Damage);
    }

    [CreateAssetMenu(menuName = "Base Weapon")]
    public class Weapon : ScriptableObject
    {
        public int damage = 5;
    }

关于用于数据的 SO 的一些不错的教程如下:使用可编写脚本的对象自定义 UI https://www.youtube.com/watch?v=HkUSmI7F304

第 2 阶段 - SO 组合逻辑

第一阶段之后,有人注意到 https://www.youtube.com/watch?v=6vmRwLYWNRoSO 可以用于许多不同的事情。 许多开发人员开始在 SO 中添加逻辑。

    public class AttackerWithLogic : MonoBehaviour
    {
        public WeaponWithLogic weapon;

        public void Attack(IDamageGetter target) => weapon.Attack(target);
    }

    public abstract class WeaponWithLogic : ScriptableObject
    {
        public int damage = 5;

        public abstract void Attack(IDamageGetter target);
    }

这样做可以将大量逻辑与单一行为分离,并将任何逻辑附加到 SO 本身上。 你不会有一个具有 2 个派生类敌人WithAxe 和敌人WithSword 的单一行为敌人。 你将有一个单一行为敌人,并且你可以附加武器斧或武器剑。

本系列教程是理解此逻辑并将事件应用于人工智能的重要来源。带有可编写脚本的对象的可插入人工智能 https://www.youtube.com/watch?v=cHUXh5biQMg

第 3 阶段 - 反应式脚本对象

最后,我们有了使用 Scriptable 对象的新方法,描述如下:团结奥斯汀 2017 https://www.youtube.com/watch?v=raQ3iHhE_Kk.

这比其他想法更先进,并且需要了解观察者模式和 C# 事件系统,但它是使用可编写脚本的对象的好方法。

这可以用作生成器。

    [CreateAssetMenu(menuName = "EnemySpawner")]
    public class EnemySpawner : ScriptableObject
    {
        public event Action<Enemy> OnSpawn;

        public Enemy enemyPrefab;

        public void SpawnEnemyWithSword()
        {
            var enemy = Instantiate(enemyPrefab);
            //..
            //code to setup sword 
            //..
            OnSpawn?.Invoke(enemy);
        }

        public void SpawnEnemyWithAxe()
        {
            //any other logic with the same event
        }
    }

SO 非常适合实现 OOP 模式,我仍然不确定新 ECS 的未来会怎样,但我希望他们也能有一席之地。

综上所述

我是 SO 的忠实粉丝,但在某些情况下你想为敌人生成一个 SO。无论如何,SO 不应该在任何地方取代 MonoBehaviours。我会使用 MonoBehaviour 来代表敌人。

如果您仍然需要为每个单一行为拥有一个 SO,您可以在唤醒时使用 ScriptableObject.CreateInstance 创建它们,但在这种情况下,它们与基本可序列化类没有太大区别。

您仍然可以实现 SO 来设置其数据(例如生命值或武器伤害),处理其部分逻辑(例如为每个武器添加效果),或处理生成机制的事件。 我强烈建议您查看我在这里分享的链接。根据您的经验选择从哪里开始,第一阶段的视频更容易,而第三阶段的视频最高级。 (不管怎样,都很简单,只有最后一个需要理解event of c#)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 ScriptableObjects 加载到单个预制件/多个预制件的最佳实践是什么? 的相关文章

  • Nullable 是不可能的,为什么不呢? [复制]

    这个问题在这里已经有答案了 如果这是一个愚蠢的问题 请原谅 我正在尝试更好地理解 Net 中的 Nullable 类型 从我从 Microsoft 源代码 使用 ReSharper 中注意到的内容 我了解到 Nullable 是一个结构 而
  • 通过 SOAP 的 Gmt php 或 UTC C# 等效项

    is C DateTime UtcNow和 PHPdate c 是等价的 我怀疑 因为当我肥皂时 我得到了 C
  • 使用 Xamarin.Forms 和 Zxing 生成 QR 码

    我在网上看到了很多关于这个的内容 旧帖子 但似乎没有什么对我有用 我正在尝试从字符串中生成二维码并将其显示在应用程序中 这就是我一开始的情况 qrCode new ZXingBarcodeImageView BarcodeFormat Ba
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 如何查明 .exe 是否正在 C++ 中运行?

    给定进程名称 例如 程序 exe C 标准库没有这样的支持 您需要一个操作系统 API 来执行此操作 如果这是 Windows 那么您将使用 CreateToolhelp32Snapshot 然后使用 Process32First 和 Pr
  • DataGridView 列中的数字文本框

    我有一个DataGridView 我想要它的第一列或任何所需的列 其中有textboxes在其中 成为NUMERIC ONLY 我目前正在使用这段代码 private void dataGridViewItems EditingContro
  • 以下 PLINQ 代码没有改进

    我没有看到使用以下代码的处理速度有任何改进 IEnumerable
  • make_shared<>() 中的 WKWYL 优化是否会给某些多线程应用程序带来惩罚?

    前几天我偶然看到这个非常有趣的演示 http channel9 msdn com Events GoingNative GoingNative 2012 STL11 Magic Secrets作者 Stephan T Lavavej 其中提
  • 虚拟并行端口模拟器

    在我的计算机网络课程中 我们应该通过使用本机寄存器 例如使用 outportb 等命令 来学习并行端口编程 我没有并行端口 因为我住在 2011 年 但想练习这些程序 我使用 dosbox 安装了旧的 Turboc 3 IDE 有没有一个程
  • PrivateObject 找不到属性

    我的结构基本上如下所示 abstract class A protected string Identificator get set private void DoSomething DoSomethingSpecific protect
  • 提升mapped_file_source、对齐方式和页面大小

    我正在尝试在性能很重要的上下文中解析一些大小高达几百兆字节的文本文件 因此我使用 boostmapped file source 解析器期望源以空字节终止 因此我想检查文件大小是否是页面大小的精确倍数 如果是 则使用较慢的非内存映射方法 我
  • “没有合适的默认构造函数可用”——为什么会调用默认构造函数?

    我已经查看了与此相关的其他一些问题 但我不明白为什么在我的情况下甚至应该调用默认构造函数 我可以只提供一个默认构造函数 但我想了解它为什么这样做以及它会产生什么影响 error C2512 CubeGeometry no appropria
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 将 2 个字节转换为整数

    我收到一个 2 个字节的端口号 最低有效字节在前 我想将其转换为整数 以便我可以使用它 我做了这个 char buf 2 Where the received bytes are char port 2 port 0 buf 1 port
  • 如何在 EF Core 2.1 中定义外键关系

    我的 DAL 使用 EF Core 2 1 这就是我的模型的样子 一名用户只能拥有一种角色 Role entity kind of master public class Role public int RoleId get set pub
  • 如何对STL向量进行排序?

    我想排序一个vector vector
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 当 Verb="runas" 时设置 ProcessStartInfo.EnvironmentVariables

    我正在开发一个 C 应用程序 我需要创建变量并将其传递给新进程 我正在使用ProcessStartInfo EnvironmentVariables 新进程必须提升运行 因此我使用 Verb runas var startInfo new
  • 初始化列表在 VC10 中不起作用

    我在 VC 2010 中编写了这个程序 class class1 public class1 initializer list

随机推荐

  • 如何通过相应文档的数组获取每个组的字段最大值?

    我有一个像这样的集合 id ObjectId 5738cb363bb56eb8f76c2ba8 records Name Joe Salary 70000 Department IT id ObjectId 5738cb363bb56eb8
  • Firefox 扩展如何以编程方式获取自己的版本号?

    如何使用 Javascript 以编程方式获取我自己的 Firefox 扩展版本号 我的扩展有一个 install rdf 文件 其中包含类似于下面的版本号 我想提取其中的内容
  • CMYK颜色直接转HSV颜色

    如何将HSV颜色直接转换为CMYK颜色 提及做到这一点的 JavaScript 库会加分 我只见过将 HSV 转换为 RGB 然后将 RGB 转换为 CMYK 的解决方案 我知道的唯一解决方案是转换为 RGB 作为中间层 然后将其转换为您想
  • 配置 WCF 服务以接受不合格参数

    我的 WCF 服务无法识别以不合格形式发送的请求参数值 而是替换为默认值 例如 此请求将产生 您输入 21 的结果
  • 如何重新配置​​ Meteor 的 Facebook 账户,或者 Meteor 的 Facebook 配置在哪里?

    流星的accounts facebook包的设置非常容易 为了输入 Facebook 应用程序 ID 和秘密令牌 我在浏览器中加载了 Meteor Web 应用程序 单击登录按钮 然后单击 配置 Facebook 它要求我提供应用程序 ID
  • C# ASP.NET 列表视图

    我正在尝试创建一个包含多个产品列表的视图 下面的示例展示了产品列表的外观 我不确定是否应该使用表格并为每个新产品或其他内容创建一个新表格 我不是一个很好的 ASP NET 开发人员 我不知道如何解决这个问题 基本上 如果我有 10 个结果
  • JS中的罗马到整数为什么只转换第一个字符

    我尝试解决Leedcode问题13 问题是给定一个罗马数字 将其转换为整数 输入保证在1到3999的范围内 这是我的代码 我想知道为什么它只将罗马数字中的第一个字符转换为整数 var romanToInt function s var re
  • 使用 mod_rewrite 将所有流量重定向到 index.php

    我正在尝试构建一个 url 缩短器 并且我希望能够在域之后立即获取任何字符并将它们作为变量 url 传递 例如 http google com asdf http google com asdf 会成为 http www google co
  • 从数据库中选择最受欢迎的地点的算法

    我们有一个包含地点数据库的网站 对于每个地方 我们的用户都可以执行我们记录的以下操作之一 查看 查看其个人资料 评级 按 1 5 星的等级对其进行评级 审查 审查它 已完成 标记他们已经去过那里 愿望清单 标记他们想去那里 最喜欢的 标记这
  • 实体框架,更新前值的触发机制

    EF 中是否有在更新对象值之前具有的内容 例如当实体对象 假设用户 被保存时 我想在更新用户对象值之前了解日志记录的目的 Thanks 如果您与ObjectContext edmx 您可以订阅SavingChanges http msdn
  • 为什么我无法实例化 switch-case 块内的对象

    我的代码有 3 个类 n hexa n octa n bin 代码在这里 switch choice case 1 cin gt gt n n hexa nx n break case 2 cin gt gt n n octa no n b
  • 如何使用 gulp 在浏览器中进行刷新

    我有一个应用程序在 iis 中 它是一个用 angularjs 和 webapi C 2 0 制作的应用程序 我想创建一个任务 在保存任何 js 文件后立即更新浏览器 吞咽版本 3 9 1 gulp task livereload func
  • 尝试在本地环境中调试 LeetCode 答案时出错

    我正在研究 LeetCode 问题199 二叉树右侧视图 https leetcode com problems binary tree right side view 给定二叉树的根 想象自己站在它的右侧 返回您可以看到从上到下排序的节点
  • 无法使用通过 VS2010 发布在 Windows Azure 上发布网站

    当我尝试通过 Visual Studio 2010 在 Windows Azure 上发布我的 Web 应用程序时 我遇到了这个问题 我尝试右键单击项目并选择发布并导入从 Windows Azure 平台下载的发布配置文件 我收到此错误 错
  • 加入多个文件

    我正在使用标准连接命令来连接两个基于column1 的排序文件 命令很简单 join file1 file2 gt output file 但是如何使用相同的技术连接 3 个或更多文件呢 连接 file1 file2 file3 gt 输出
  • 在运行时根据输入从属性文件中获取值 - java Spring

    我的 color properties 文件为 rose red lily white jasmine pink 我需要获取颜色值 String flower runTimeFlower Value flower String colour
  • Playframework 2.0.x 是否支持模板中的

    不知道play 2 0 3及更高版本是否支持else if在视图中 我只读到必须这样编码 if else if else 不敢相信 我在第二个 if 之前使用了 if true else if true else
  • 使用 nltk 没有上下文的词性标记

    有没有一种简单的方法来确定给定单词最可能的词性标签没有上下文使用nltk 或者如果不使用任何其他工具 数据集 我尝试使用 wordnet 但似乎 sysnet 不是按可能性排序的 gt gt gt wn synsets says Synse
  • Android计算器-Editview无法输入小数位

    我是Android代码开发新手 我正在开发一个Android计算器应用程序 不明白为什么两个EditText 第一个输入和第二个输入 不能接受小数位而只能输入整数 附如下是代码 Thanks 主要活动 package com trial j
  • 将 ScriptableObjects 加载到单个预制件/多个预制件的最佳实践是什么?

    脚本化对象 SO 我最近一直在尝试了解 ScriptableObjects 并在 Unity 中建立了一个项目 我只想射击生成的传入敌人 我已经设置了它 这样我就可以通过 SO s 创建不同的敌人 但注意到我仍然需要为每个敌人创建一个预制件