如何在统一中获得对预制资产的引用
How to get a reference to a prefab asset in unity
我有以下class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PixelSystem
{
public GameObject pixelPrefab;
public Texture2D[] style;
public List<Chunk> chunks;
public GameObject mGameObject;
public PixelSystem(GameObject _mGameObject)
{
mGameObject = _mGameObject;
chunks = new List<Chunk>();
}
}
Chunk
和 Pixel
是结构,但我认为它们不相关。
我希望将 pixelPrefab
和 style
序列化,但似乎无法实现。此脚本未附加到游戏对象。
我研究过使用 Resources
或 Addressables
在运行时获取资产,但我希望能够从编辑器中设置这些字段。
我尝试让 class 继承自 MonoBehaviour
并具有 [SerializeField] public GameObject pixelPrefab;
和 [SerializeField] public Texture2D[] style;
,但结果是 pixelPrefab
是可设置的来自编辑器但不是显示 style
它显示 mGameObject
,出于某种原因...¯\_(ツ)_/¯
编辑: 结果是 [SerializeFields]
在这里什么都不做,没有它们结果是一样的。
我也试过将 [System.Serializable]
放在 class 之前,但据我所知这根本没有任何作用。
有人请帮助。
编辑:
由于一些误解,我想澄清一些事情:
- 我已经有了预制资产,它在我的资产文件夹中而不是在我的场景中,创建资产不是问题。
pixelPrefab
可以像 static
属性 一样正常工作,但是,style
不会。
- 样式只需要为默认值序列化,因此不是优先级。
- 此代码非常不完整,构造函数不完整,在我花时间编写可能无法使用的代码之前,我想得到这个问题的答案。
- 我要select编辑器中的资产
- 我不想有一个必须在使用 classes 之前调用的函数,以便加载资产
- 我不想每次引用资源的时候都加载,所以没有
get {load();}
这是我在 select 我的脚本时希望在编辑器中看到的内容:
这是目前最接近我想要的东西:
我通过将 class 设置为从 MonoBehaviour
继承得到的,我宁愿不从任何东西继承,如果你打算拥有 MonoBehaviour
classes 没有附加到游戏对象,但如果这是必要的,那就这样吧。
这里有几件事。我假设这一点是最重要的:
- I want to select the assets in the editior
因此,为了能够做到这一点,您想要看到的每个字段都必须能够被 Unity 序列化,并且 Unity 还需要能够为那个东西绘制 GUI。你说,
I would like pixelPrefab
and style
to be serialized but cannot seem to be able to make that work.
在这里,我再次使用“序列化”来表示您只希望在编辑器中公开这些字段,以便您可以将内容粘贴到其中。因此,当您给我以下代码片段时,我会立即看到几个问题:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PixelSystem
{
public GameObject pixelPrefab;
public Texture2D[] style;
public List<Chunk> chunks;
public GameObject mGameObject;
public PixelSystem(GameObject _mGameObject)
{
mGameObject = _mGameObject;
chunks = new List<Chunk>();
}
}
首先是 PixelSystem
本身没有序列化。您要么需要使用 [System.Serializable]
标记 class 以使用 Unity 的序列化程序,要么您需要继承 Unity 已经知道应该序列化的内容,例如 Component
或 MonoBehaviour
(MonoBehaviour
继承 Component
)。 Component
和 subclasses 的问题是它们需要存在于 GameObject 上,所以你不能 new
一个 Component
,你必须 .AddComponent<YourComponent>()
.
现在正如您所发现的,当您让脚本继承 MonoBehaviour
时,您会看到
that pixelPrefab
is settable from the editor but instead of showing style it shows mGameObject
, for some reason... ¯\_(ツ)_/¯
它显示 mGameObject
的原因可以在你的 class' 成员变量中看到:
public GameObject pixelPrefab;
public Texture2D[] style;
public List<Chunk> chunks;
public GameObject mGameObject;
你可以看到 pixelPrefab
是一个 public GameObject
。伟大的! (1) 你的 class 继承了 MonoBehaviour
,所以 Unity 知道要序列化它,(2) pixelPrefab
是 public
,所以编辑器知道要显示它,并且 GameObject
本身是 Unity 知道如何绘制的可序列化对象,因此最终结果是 Unity 将 pixelPrefab
添加到您的 class.
的编辑器 GUI 中
然后您到达 style
,即 public
,因此编辑器知道它应该显示它,但它是一个 数组 而 Unity 不会不知道如何为数组绘制编辑器 GUI。它是一个 Texture2D
的数组,它 确实 知道如何绘制,但它不知道如何处理数组方面,所以它没有添加 style
到您的 GUI。
然后您到达 chunks
,即 public
,因此编辑器知道它应该显示它,它是 List
,Unity 会 知道如何处理,但它是 Chunk
的列表,我打赌它不会继承 MonoBehaviour
并且也没有用 [System.Serializable]
标记,所以 Unity 不会知道它应该是序列化 Chunk
。这意味着它确实知道它应该绘制一个列表,但它认为它不应该为列表绘制任何内容,所以它完全跳过列表。
最后你到达了 public GameObject mGameObject
,它被绘制的原因与 pixelPrefab
被绘制的原因相同,最后你得到了你在最后一个屏幕截图中在编辑器中看到的内容:只有 pixelPrefab
和 mGameObject
在你的 class GUI 中绘制:
那么,如果您想在编辑器窗格中查看 class 并且还想查看 pixelPrefab
和 style
怎么办?
- 有一些可以序列化的东西,比如
MonoBehavior
,持有对 PixelSystem
的引用,或者让 PixelSystem
继承 MonoBehavior
.
- 如果
PixelSystem
不是 MonoBehavior
那么它需要在 public class PixelSystem
. 上面的行上有 [System.Serializable]
- 做你已经做过的事情并获得
public GameObject pixelPrefab
.
- 将
style
从数组转换为列表,以便 Unity 知道如何绘制它。
您应该得到以下结果:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class PixelSystem
{
public GameObject pixelPrefab;
public List<Texture2D> style = new List<Texture2D>();
public List<Chunk> chunks;
public GameObject mGameObject;
public PixelSystem(GameObject _mGameObject)
{
mGameObject = _mGameObject;
chunks = new List<Chunk>();
}
}
如果您使用 [System.Serializable]
标记 class,您还可以将 Chunk
序列化并显示在您的编辑器窗格中,并且您只需要 [SerializeField]
标记尚未 public
的字段。您仍然可以将该标签添加到 public 字段,就像您可以将 [System.Serializable]
添加到 MonoBehaviour
一样,但这是多余的。不需要。
我有以下class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PixelSystem
{
public GameObject pixelPrefab;
public Texture2D[] style;
public List<Chunk> chunks;
public GameObject mGameObject;
public PixelSystem(GameObject _mGameObject)
{
mGameObject = _mGameObject;
chunks = new List<Chunk>();
}
}
Chunk
和 Pixel
是结构,但我认为它们不相关。
我希望将 pixelPrefab
和 style
序列化,但似乎无法实现。此脚本未附加到游戏对象。
我研究过使用 Resources
或 Addressables
在运行时获取资产,但我希望能够从编辑器中设置这些字段。
我尝试让 class 继承自 MonoBehaviour
并具有 [SerializeField] public GameObject pixelPrefab;
和 [SerializeField] public Texture2D[] style;
,但结果是 pixelPrefab
是可设置的来自编辑器但不是显示 style
它显示 mGameObject
,出于某种原因...¯\_(ツ)_/¯
编辑: 结果是 [SerializeFields]
在这里什么都不做,没有它们结果是一样的。
我也试过将 [System.Serializable]
放在 class 之前,但据我所知这根本没有任何作用。
有人请帮助。
编辑:
由于一些误解,我想澄清一些事情:
- 我已经有了预制资产,它在我的资产文件夹中而不是在我的场景中,创建资产不是问题。
pixelPrefab
可以像static
属性 一样正常工作,但是,style
不会。- 样式只需要为默认值序列化,因此不是优先级。
- 此代码非常不完整,构造函数不完整,在我花时间编写可能无法使用的代码之前,我想得到这个问题的答案。
- 我要select编辑器中的资产
- 我不想有一个必须在使用 classes 之前调用的函数,以便加载资产
- 我不想每次引用资源的时候都加载,所以没有
get {load();}
这是我在 select 我的脚本时希望在编辑器中看到的内容:
这是目前最接近我想要的东西:
我通过将 class 设置为从 MonoBehaviour
继承得到的,我宁愿不从任何东西继承,如果你打算拥有 MonoBehaviour
classes 没有附加到游戏对象,但如果这是必要的,那就这样吧。
这里有几件事。我假设这一点是最重要的:
- I want to select the assets in the editior
因此,为了能够做到这一点,您想要看到的每个字段都必须能够被 Unity 序列化,并且 Unity 还需要能够为那个东西绘制 GUI。你说,
I would like
pixelPrefab
andstyle
to be serialized but cannot seem to be able to make that work.
在这里,我再次使用“序列化”来表示您只希望在编辑器中公开这些字段,以便您可以将内容粘贴到其中。因此,当您给我以下代码片段时,我会立即看到几个问题:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PixelSystem
{
public GameObject pixelPrefab;
public Texture2D[] style;
public List<Chunk> chunks;
public GameObject mGameObject;
public PixelSystem(GameObject _mGameObject)
{
mGameObject = _mGameObject;
chunks = new List<Chunk>();
}
}
首先是 PixelSystem
本身没有序列化。您要么需要使用 [System.Serializable]
标记 class 以使用 Unity 的序列化程序,要么您需要继承 Unity 已经知道应该序列化的内容,例如 Component
或 MonoBehaviour
(MonoBehaviour
继承 Component
)。 Component
和 subclasses 的问题是它们需要存在于 GameObject 上,所以你不能 new
一个 Component
,你必须 .AddComponent<YourComponent>()
.
现在正如您所发现的,当您让脚本继承 MonoBehaviour
时,您会看到
that
pixelPrefab
is settable from the editor but instead of showing style it showsmGameObject
, for some reason... ¯\_(ツ)_/¯
它显示 mGameObject
的原因可以在你的 class' 成员变量中看到:
public GameObject pixelPrefab;
public Texture2D[] style;
public List<Chunk> chunks;
public GameObject mGameObject;
你可以看到 pixelPrefab
是一个 public GameObject
。伟大的! (1) 你的 class 继承了 MonoBehaviour
,所以 Unity 知道要序列化它,(2) pixelPrefab
是 public
,所以编辑器知道要显示它,并且 GameObject
本身是 Unity 知道如何绘制的可序列化对象,因此最终结果是 Unity 将 pixelPrefab
添加到您的 class.
然后您到达 style
,即 public
,因此编辑器知道它应该显示它,但它是一个 数组 而 Unity 不会不知道如何为数组绘制编辑器 GUI。它是一个 Texture2D
的数组,它 确实 知道如何绘制,但它不知道如何处理数组方面,所以它没有添加 style
到您的 GUI。
然后您到达 chunks
,即 public
,因此编辑器知道它应该显示它,它是 List
,Unity 会 知道如何处理,但它是 Chunk
的列表,我打赌它不会继承 MonoBehaviour
并且也没有用 [System.Serializable]
标记,所以 Unity 不会知道它应该是序列化 Chunk
。这意味着它确实知道它应该绘制一个列表,但它认为它不应该为列表绘制任何内容,所以它完全跳过列表。
最后你到达了 public GameObject mGameObject
,它被绘制的原因与 pixelPrefab
被绘制的原因相同,最后你得到了你在最后一个屏幕截图中在编辑器中看到的内容:只有 pixelPrefab
和 mGameObject
在你的 class GUI 中绘制:
那么,如果您想在编辑器窗格中查看 class 并且还想查看 pixelPrefab
和 style
怎么办?
- 有一些可以序列化的东西,比如
MonoBehavior
,持有对PixelSystem
的引用,或者让PixelSystem
继承MonoBehavior
. - 如果
PixelSystem
不是MonoBehavior
那么它需要在public class PixelSystem
. 上面的行上有 - 做你已经做过的事情并获得
public GameObject pixelPrefab
. - 将
style
从数组转换为列表,以便 Unity 知道如何绘制它。
[System.Serializable]
您应该得到以下结果:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class PixelSystem
{
public GameObject pixelPrefab;
public List<Texture2D> style = new List<Texture2D>();
public List<Chunk> chunks;
public GameObject mGameObject;
public PixelSystem(GameObject _mGameObject)
{
mGameObject = _mGameObject;
chunks = new List<Chunk>();
}
}
如果您使用 [System.Serializable]
标记 class,您还可以将 Chunk
序列化并显示在您的编辑器窗格中,并且您只需要 [SerializeField]
标记尚未 public
的字段。您仍然可以将该标签添加到 public 字段,就像您可以将 [System.Serializable]
添加到 MonoBehaviour
一样,但这是多余的。不需要。