【问题标题】:Array of custom Gameobjects returns null on its indexes after objects has been instantiated?实例化对象后,自定义游戏对象数组在其索引上返回 null?
【发布时间】:2017-10-03 13:20:20
【问题描述】:

在运行时,我首先将一些项目添加到数组中,然后将它们的值写入日志(工作正常)然后我实例化它们(仍然工作正常),然后我想更改数组项目的值,但由于某种原因,现在数组索引返回 null?有谁知道出了什么问题?

public class ListEquippedItems : MonoBehaviour
 {
 private static ListEquippedItems instance = null;
 public static ListEquippedItems Instance
 {
     get
     {
         if (instance == null) instance = new ListEquippedItems();

         return instance;
     }
 }

 [SerializeField]
 private GameObject[] currentlyEquippedItems = new GameObject[8];

 void Awake()
 {
     // Putting fake items into the currently equipped to test that items can actually be transfered to it
     for (int i = 0; i < currentlyEquippedItems.Length; i++)
     {
         //////////////////// In 3 below lines the array works just fine and returns proper values.
         currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().SetItemType((EffectTypes)i);
         currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().SetItemName("I am item: " + i);
         currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().SetItemIcon(RewardAssetContainer.Instance.commonExample);

         Debug.Log(currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().GetItemIcon().ToString());
         Debug.Log(currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().GetItemType().ToString());
         Debug.Log(currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().GetItemName());
     }
 }

 public void SetEquippedItem(EffectTypes _itemType, Sprite _itemIcon, string _itemName)
 {
     for (int i = 0; i < currentlyEquippedItems.Length; i++)
     {

         Debug.Log(currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().GetItemType().ToString());
         Debug.Log(currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().GetItemName());
         Debug.Log(currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().GetItemIcon().ToString());

     //////////////////// In 3 below lines the array returns null references, but why?
         if (currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().GetItemType() == _itemType)
         {
             currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().SetItemName(_itemName);
             currentlyEquippedItems[i].GetComponent<ListEquippedEntry>().SetItemIcon(_itemIcon);
             break;
         }
     }
 }  

【问题讨论】:

  • 我不知道你的 _itemType 的类型。但是您可以尝试添加 toString() .Like .GetItemType().toString() == _itemType.toString())
  • 我已经试过了。我很确定没有其他脚本可以以任何方式访问此数组,并且游戏对象也不会被禁用或类似的东西。我不知道为什么它在我身上返回空值,但项目及其精灵在场景中仍然可见-.-
  • 我没有看到您提供的代码有任何问题,您有什么办法可以发布 SetItemNameSetItemTypeSetItemIcon 的代码,因为它们似乎是你的ListEquippedEntry 班级,我相信这可能会产生一些影响。乍一看,您的代码似乎应该可以正常工作。
  • 在导致 NPE 的部分之前添加的调试语句的结果是什么?

标签: c# arrays unity3d singleton gameobject


【解决方案1】:

我想问一个澄清问题,但我没有代表发表评论,所以我只是试一试......

您的 ListEquippedItems 编码类似于单例,但从技术上讲,它不是单例。我的猜测是调用 SetEquippedItem() 的对象与调用 Awake() 的对象不同。

这可能发生的方式:

  1. 您在层次结构中创建了一个 ListEquippedItems 游戏对象。这会创建一个实例。
  2. 您引用了 ListEquippedItems.Instance。这会创建另一个实例。
  3. 您使用构造函数创建一个 ListEquippedItems。这将创建另一个实例。
  4. 您有 2 个(或更多)线程同时引用 ListEquippedItems.Instance。只要时机合适,两个线程都可以将实例视为 null,并创建一个新实例。

如何验证这是否是正在发生的事情:

将以下代码 sn-p 添加到 Awake() 和 SetEquippedItem() 方法中:

if( this != instance )
{
    Debug.Log( "<methodName> invoked against non-singleton instance." );
}

如何解决问题:

仅以一种方式创建 ListEquippedItems。如果要将其保留在层次结构中,请将实例存储在 Awake() 方法中,而不是在引用 Instance 字段时。

如果您想要一个合适的单例,请查看 Unity wiki 中的 wiki entry。 wiki条目here上似乎有一个stackoverflow讨论。

【讨论】:

  • 谢谢你是对的,我确实创造了你解释的场景!我认为我宁愿尝试解决问题的根源,而不是使用您的建议,而是解决问题的根源,即两个“单例”,或者我很可能会在某个地方遇到其他问题:) 非常感谢您指出我正确的方向,但你太棒了!我希望我可以将 urs 标记为正确答案,但我的代表太低了抱歉:/
  • 我已经用几个可能对你有用的链接更新了我的答案。
  • 无论您有多少代表,您都应该能够接受您的问题的答案。应该有一个灰色复选标记,您可以点击答案左侧的投票向上/向下按钮下方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 2016-02-16
  • 2016-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多