【问题标题】:Unity2D changing sprite image from array c#Unity2D从数组c#中改变精灵图像
【发布时间】:2018-12-01 18:23:02
【问题描述】:

我正在研究一种玩家可以自定义他们的精灵的方法。我在我的管理器脚本中创建了一个数组,如下所示:

public Sprite[] spriteImages = new Sprite[5];

在这个数组中,我打算添加 5 个 png 文件,用于更新 spriteRenderer 精灵。我有两个问题,我正在努力访问精灵脚本中的数组(我认为这是更改图像的最佳方法)。我也在努力实际解决如何更改精灵图像。目前我正在使用此代码:

this.gameObject.GetComponent<SpriteRenderer> ().sprite = GameObject.Find ("UIManager").GetComponent<UIManager> ().spriteImages [0];

在我的精灵列表中,我放置了 5 个 png 文件(2D 精灵纹理),但是当我运行程序时,它显示“对象引用未设置为对象的实例”。不知道为什么当数组中有精灵时它会给出这个错误?

我指的是“UIManager”的游戏对象与我使用查找对象的场景不同。这是无效的吗?

【问题讨论】:

  • 静态的“编辑器”为什么不能添加图片?您能否显示更多代码或解释更多问题所在。您看到的错误向您展示了如何解决问题 - 您需要一个类的实例而不是静态引用,因为数组不是静态的。
  • 对不起,对这一切都很陌生,类的实例是什么意思?
  • 你需要有一个UIManager 对象。在您的代码中类似于var uiMgr = new UIManager(...);。这将创建一个类的实例。如果您不熟悉这些类型的术语,我强烈建议您阅读有关 object oriented programming 的书籍或一些教程

标签: c# unity3d


【解决方案1】:

我有几种方法可以解决您的问题。

1)Singleton classes。声明你的类的一个静态实例,其中保存了精灵数组,即 uIManager 类。您可以使用链接中显示的方法使您的类单例,或者您可以简单地声明如下:

public class UIManager : MonoBehaviour {
    UIManager static instance;

    void Start() {
        instance = this;
    }
}

好的部分是您可以像 UIManager.instance 一样直接引用您的类并获取类中的所有公共变量。缺点是如果您在同一个场景中有多个脚本,它只会引用其中一个实例,您将无法访问场景中存在的脚本的其他实例。所以这个方法只能用于每个场景的一个实例。

2) 在 Unity 编辑器中保存所需脚本的引用并将其分配给脚本中的公共变量。假设您有 A 类进行一些计算,并且您有 B 类存储一些数据;让我们假设它的 Sprite 数组类似于您的脚本。现在在 A 类中,您需要该精灵数组进行分配。所以你可以做的是声明一个B类的公共变量,即public ClassB classBInstance;。您将能够在统一编辑器中看到 ClassB 字段的实例为空。您可以直接分配所需的引用,瞧,您将能够访问 B 类的变量。

3) 使用统一 API 查找您的类所附加的游戏对象。 除了以上两种方法之外,这些是我经常使用的一些 API:

4) 将您的数组设置为静态,但如果这样做,您将无法在统一编辑器中访问它,因此无法在编辑器中分配 Sprite。

对于您的问题,我认为第一种方法应该不仅仅是诀窍。

【讨论】:

  • 我尝试了第二种方法,因为它似乎最有效,但现在出现了一个新错误。我已经更新了我原来的问题来解决这个问题。谢谢。
  • 所以您的意思是说 UIManager 不存在于您更改精灵的场景中?
  • 正确。是这个问题吗?
【解决方案2】:

spriteImages 变量未声明为static,这意味着您需要一个 UIManager 实例来访问其中的spriteImages 变量。您可以将其标记为静态,并且无需提供它的实例即可访问它。

public static Sprite[] spriteImages = new Sprite[5];

这是解决该错误的一种方法,但我认为您不应该为此使用staticUIManager 可能是附加到游戏对象的脚本,因此您所要做的就是找到 UIManager 附加到的游戏对象,然后从中获取 UIManager 组件。该组件是访问spriteImages 变量而不使其成为static 所需的脚本实例。

private UIManager uIManager;

void Start()
{
    //Find the GameObject then the script instance
    GameObject uManagerObj = GameObject.Find("UIManager GameObject");
    uIManager = uManagerObj.GetComponent<UIManager>();

    //Now you can do this with the script instance
    this.gameObject.GetComponent<SpriteRenderer>().sprite = uIManager.spriteImages[0];
}

确保将 GameObject.Find 函数中的 "UIManager GameObject" 替换为 UIManager 脚本附加到的游戏对象的名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    相关资源
    最近更新 更多