【问题标题】:ScriptableObject build error with Inheritance but runs fine in Unity Editor带有继承的 ScriptableObject 构建错误,但在 Unity 编辑器中运行良好
【发布时间】:2021-02-23 02:09:37
【问题描述】:

这是我收到的错误:

错误在这一行。:

 if (pItem.isStackable)
 {
 }

我应该注意,该错误仅在我构建游戏时发生。在编辑器中运行游戏时不会出现这种情况。

我认为错误来自试图在玩家的物品栏中为玩家提供武器。

因为它运行良好:

 Player.playerInv.AddItem(apple);

这不是:

  Player.playerInv.AddItem(sword2);

唯一的区别是苹果是一件物品,而 Sword2 是一件武器……我有理由相信构建期望加载的是物品而不是武器。 (Weapon 是 item 的子项。item 继承 ScriptableObject)。

这是武器和物品的代码(抱歉,文件太大):

 using System;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 
 [CreateAssetMenu(fileName = "Item", menuName = "StrangeEngine/Item", order = 2)]
 public class Item : ScriptableObject
 {
     public enum ItemType
     {
         Item = 1,
         Skill = 2,
         Equipment = 3
     }
     public ItemType type;
     public int ID;
     public string itemName;
     public string info;
     public int worth;
     public bool isStackable = false;
     //public Sprite icon;
     public Dictionary<string, int> itemStats = new Dictionary<string, int>(); // "stats" that come in pairs, a name (string) and a number. for example ("weight", 22)
 
     public Item(ItemType pType, int pID, string pName, string pInfo, int pWorth, Dictionary<string,int> pStats)
     {
         type = pType;
         ID = pID;
         itemName = pName;
         info = pInfo;
         worth = pWorth;
         itemStats = pStats;
     }
     public Item(ItemType pType, int pID, string pName, string pInfo, int pWorth, Dictionary<string, int> pStats, bool pIsStackable)
     {
         type = pType;
         ID = pID;
         itemName = pName;
         info = pInfo;
         worth = pWorth;
         itemStats = pStats;
         isStackable = pIsStackable;
     }
 }
 
 [CreateAssetMenu(fileName = "Item", menuName = "StrangeEngine/Weapon", order = 3)]
 public class Weapon : Item
 {
     public int Damage;
     public GameObject WeaponModelPrefab;
 
 
     public Weapon(int pID, string pName, string pInfo, int pWorth, Dictionary<string, int> pStatsfloat, int pDamage, GameObject pWeaponPrefab) : base(ItemType.Equipment,pID, pName, pInfo,pWorth,pStatsfloat)
     {
         Damage = pDamage;
         WeaponModelPrefab = pWeaponPrefab;
     }
 }
 

【问题讨论】:

    标签: unity3d serialization build-error scriptable-object


    【解决方案1】:

    我可以在这里看到几个警告标志。但是,特别是,该错误可能与您使用了构造函数这一事实有关。对于 ScriptableObject 类型,您应该让 Unity 处理构建项目。

    ScriptableObject 通常用于序列化数据以供运行时使用。之后,可以在整个游戏中使用 SO。但是创建新的应该使用 CreateInstance 方法,如 Unity 文档中的 here 所述。

    无论如何,您的构造函数都只是设置私有字段。您可以从调用代码中分配它们,而不是将其作为构造函数参数传递。

    另外一点,您应该知道 Unity 不会序列化字典。您可以序列化 List&lt;T&gt; 并使用 ISerializationCallbackReceiverinterface 将列表反序列化为 Dictionary,但这取决于您是否需要序列化该数据,或者您只是在运行时使用它。您可以找到有关 ISerializationCallbackReceiverhere 的更多信息。

    SO 也会听取一些 Unity 消息。因此,例如,您可以使用 Awake 消息进行任何 SO 初始化。可以在this 页面上找到 SO 消息的简要说明。

    总而言之,我认为您的问题是您从继承的 SO 中绕过构造函数设置,这通常会导致序列化问题。

    【讨论】:

    • 非常感谢。构造函数仍然存在于旧的库存管理系统中,我将其重新设计为我现在拥有的可编写脚本的对象系统。该代码应该在不久前被删除,但我没有注意到它是多么不合时宜......在删除所有构造函数之后。代码运行良好。
    猜你喜欢
    • 2018-04-04
    • 2017-11-22
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    相关资源
    最近更新 更多