【问题标题】:Unity 2D: Destroy + Instantiate new GameObject vs Changing state and spriteUnity 2D:销毁+实例化新游戏对象与更改状态和精灵
【发布时间】:2017-11-13 00:54:36
【问题描述】:

我正在我的 2D 游戏中为农田创建预制件。由于我希望所有地砖在被锄头击中时都变成可耕地,因此我担心性能(因为一个场景中会有数百个这样的游戏对象)。

最好的办法是销毁地面瓷砖并在其位置实例化一个农场瓷砖,还是创建一个附加到每个地面瓷砖(?)的更通用的脚本会更好,其状态如下:

GROUND, FARMABLE, PLANTED

,然后根据状态我改变行为并设置一个精灵,如:tile.GetComponent<Image>().sprite = Resources.Load<Sprite>(pathToSprite);

也许我错过了更好的选择,但这些是我能想到的。

【问题讨论】:

  • 请告诉我你为什么投反对票?我是新来的,不知道这个问题有什么问题

标签: c# performance unity3d unity5


【解决方案1】:

在运行时销毁和实例化数百个游戏对象会导致灾难、内存碎片和疯狂的 GC,从而降低性能。

第二种解决方案要好得多。为游戏逻辑中所有可能的图块状态使用enum,然后相应地更改Sprite Renderer 组件的Sprite 字段。

PSA:不要在每次需要更改精灵时都使用GetComponentResources.Load,获取对Sprite Renderer 组件和Sprite[] 数组的引用,该数组包含所有可能的状态图像以用于Awake,然后在需要时使用这些引用来更改精灵图像。

编辑:在评论中回答您的问题。

  • 确保Sprites 都在您的Resources 文件夹中 项目,它们可以在子文件夹中,即:Resources/Sprites
  • 检查path字符串是否正确,即如果精灵资源被称为Circle,并且它在Resources/Sprites文件夹中, path 必须是 "Sprites/Circle"

代码示例:

public class MyClass : MonoBehaviour {

    Sprite[] spritesArray = new Sprite[10];

    void Awake() {
        spritesArray[0] = Resources.Load<Sprite>("Sprites/Circle");
    }
}

【讨论】:

  • 如果我尝试在 Start() 中调用 cachedSprites[0] = Resources.Load&lt;Sprite&gt;("path");,我会得到一个 NullReferenceException: Object reference not set to an instance of an object
  • 我像这样启动数组:private Sprite[] cachedSprites,我错过了什么吗?
  • 谢谢。它还可以将其公开并从编辑器中的资源拖放精灵。
  • 是的,显然您可以通过 public[SerializeField] private 公开数组并通过 Inspector 分配引用。
【解决方案2】:

试试这个:{ tile.GetComponent(/).sprite = Resources.Load(pathtosprite); }

【讨论】:

  • 好的,请清楚地解释这个问题,因为像我这样的人甚至不明白这意味着什么......
  • 这个问题已经很清楚了。你的回答质量很差,建议你删掉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-17
相关资源
最近更新 更多