如何在Unity中获取对预制资产的参考

发布于 2025-01-31 17:02:02 字数 2087 浏览 2 评论 0原文

我有以下类

    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>();
        }
    }

pixel是结构的,但我认为它们不相关。

我希望pixelprefab样式被序列化,但似乎无法完成该工作。此脚本未列入GameObject。

我已经考虑使用ResourcesPromeperables在运行时获得资产,但我希望能够从编辑器设置这些字段。

我曾尝试从Monobehaviour[serializeField]公共GameObject PixelPrefab; and [serializefield] public texture2d [] style;,,但是结果是,pixelprefab是可以从编辑器中设置的,但是由于某种原因,它显示style它显示mgameObject,出于某种原因... \ _(ツ)_/ 编辑:事实证明,[serializefields]在这里什么都不做,没有它们,结果是相同的。

我还尝试在班上放置[System.Serializable],但据我所知,这根本什么都不做。

有人帮助。

编辑:

由于一些误解,我想澄清一些事情:

  1. 我已经有了预制资产,而是在我的资产文件夹中不在我的场景中,创建资产不是问题。
  2. pixelprefab可以用作static属性,但是,样式不会。
  3. 样式只需要序列化默认值,因此不是优先级。
  4. 此代码非常不完整,构造函数不完整,我想在花时间编写可能无法使用的代码之前对此Qusetion进行答案。
  5. 我想在编辑中选择资产,
  6. 我不想在使用类别之前必须调用一个函数,以便加载资产时,
  7. 我不想每次引用资产,因此不想加载资产,因此否<<<代码>获取{load();}

这是我选择脚本时在编辑器中看到的: 可以看到这张图像可能无法加载,但是idk“

,这是我到目前为止最接近的东西:

我通过将类设置为从Monobehaviour来获得的IDK“> ,我宁愿不从任何东西继承,如果您是要拥有MonoBehaviour类,这些类未属于GameObjects,但是如果有必要,那就这样吧。

I have the following 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 and Pixel are structs but I don't think they are relevant.

I would like pixelPrefab and style to be serialized but cannot seem to be able to make that work. This script is not attatched to a GameObject.

I have looked into getting the assets at runtime with Resources or Addressables but I would like to be able to set these fields from the editor.

I have tried making the class inherit from MonoBehaviour and having [SerializeField] public GameObject pixelPrefab; and [SerializeField] public Texture2D[] style;, but the result of this is that pixelPrefab is settable from the editor but instead of showing style it shows mGameObject, for some reason... ¯\_(ツ)_/¯
Edit: Turns out that the [SerializeFields] do nothing here, the result is the same without them.

I've also tried puting [System.Serializable] before the class, but as far as I can tell this does nothing at all.

Someone plz help.

Edit:

Due to some misunerstandings I would like to clarify a few things:

  1. I have the prefab asset already, it is in my assets folder not in my scene, creating the assets is not the problem.
  2. pixelPrefab would work fine as a static property, however, style would not.
  3. Style only needs serializing for a default value and so is not a priority.
  4. This code is very incomplete, the constructor is incomplete, I want an answer to this qusetion before I spend time writing code that may be unusable.
  5. I want to select the assets in the editior
  6. I do not want to have a function that must be called before the classes are used, so that the assets are loaded
  7. I do not want to load the assets each time they are referenced, so no get {load();}

This is what I want to see in the editor when I select my script:
If you can see this the image probably failed to load but idk

And this is the closest thing to what I want so far:
If you can see this the image probably failed to load but idk

Which I get by setting the class to inherit from MonoBehaviour, I'd rather not inherit from anything, and idk if you are meant to have MonoBehaviour classes that aren't attatched to gameObjects, but if this is necessary then so be it.

complete .cs file here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

从来不烧饼 2025-02-07 17:02:02

这里有几件事。我要假设这一点是最重要的:

  1. 我想在Editior中选择资产

,因此,为了能够做到这一点,您想要看到的每个字段都必须能够通过Unity序列化,并且统一性需要能够为该事情绘制GUI。你说,

我想要pixelprefab样式要序列化,但似乎无法完成该工作。

再一次,我要在这里进行“序列化”,这确实是指您只希望这些领域在编辑器中展示,以便您可以将这些字段插入其中。因此,当您给我以下片段时,我立即看到几个问题:

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]使用Unity的序列化器标记课程,要么您需要从Unity已经知道应该被序列化的东西继承,例如component或<代码> MonoBehaviour (Monobehaviour继承组件)。 组件和子类的问题是它们需要在游戏对象上存在,因此您不能new a component,您必须<代码> .addcomponent&lt; yourComponent&gt;()。

现在,正如您发现的那样,当您拥有脚本继承Monobehaviour时,您会看到

pixelprefab 是可以从编辑器中设置的,但由于某些原因,它不显示mgameObject显示样式... P>

mgameObject可以在您的类的成员变量中看到:

public GameObject pixelPrefab;
public Texture2D[] style;
public List<Chunk> chunks;
public GameObject mGameObject;

您可以看到pixelprefabpublic> public gameObject。伟大的! (1)您的类正在继承MonoBehaviour,因此Unity知道要序列化,(2)pixelPrefab is public,因此编辑者知道要显示它,gameObject本身是Unity知道如何绘制的序列化对象,因此最终结果是Unity unity添加了pixelprefab for类的编辑器GUI。

然后,您可以进入样式public,因此编辑知道它应该显示它,但是它是 array and unity andity不知道如何绘制编辑GUI的数组。它是texture2d的数组,它 do 知道如何绘制,但它不知道如何处理数组方面,因此它不会添加>样式到您的GUI。

然后,您进入, public ,因此编辑者知道它应该显示它,并且是list,哪个Unity 知道如何处理,但它是的列表,我押注的不是继承monobehaviour,也没有用[ System.Serializable],因此Unity不知道它应该序列化。这意味着它确实知道它应该在绘制列表,但是它认为它不应该为列表绘制任何内容,因此它完全跳过了列表。

最后,您可以到达public gameObject mgameObject,它的绘制是出于pixelprefab的所有相同原因而被绘制的,最后,您在上一个ScreenShot中获得了您在编辑器中看到的内容:只有pixelprefabmgameObject在您的类GUI中绘制:

“编辑器中的OP类”

那么,如果您想在Editor Pane中查看类,该怎么办您还想查看pixelprefab样式

  1. 具有可以序列化的东西,例如Monobehavior,请参考Pixelsystem或具有pixelsystem sasenit monobehavior
  2. 如果PixelSystem不是Monobehavior,则需要在上面的行上的System.Serializable] 公共类Pixelsystem >。
  3. 做您已经完成的事情,并拥有public gameObject PixelPrefab
  4. 样式从数组转换为列表,因此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]标记该类,则可以将序列化并显示在编辑窗格中,而您仅您只使用需要[serializefield]标签尚未public的字段。您仍然可以将该标签添加到公共字段中,就像您可以将[System.Serializable]添加到Monobehaviour,但它是多余的。不需要。

A few things here. I'm going to assume this point is the most important:

  1. I want to select the assets in the editior

So, in order to be able to do this, every field you want to see has to be able to be serialized by Unity and also Unity needs to be able to draw the GUI for that thing. You said,

I would like pixelPrefab and style to be serialized but cannot seem to be able to make that work.

and again here I'm taking "serialized" to really mean that you just want those fields exposed in the Editor so you can stick things into them. So when you give me the following snippet I immediately see several issues:

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>();
    }
}

The first is that PixelSystem itself isn't serialized. You either need to tag the class with [System.Serializable] to use Unity's serializer or you need to inherit from something that Unity already knows should be serialized, like Component or MonoBehaviour (MonoBehaviour inherits Component). The issue with Component and subclasses is that they need to exist on a GameObject, so you can't new a Component, you have to .AddComponent<YourComponent>().

Now as you've discovered, when you have your script inherit MonoBehaviour, you see

that pixelPrefab is settable from the editor but instead of showing style it shows mGameObject, for some reason... ¯\_(ツ)_/¯

And the reason it's showing mGameObject can be seen in your class' member variables:

public GameObject pixelPrefab;
public Texture2D[] style;
public List<Chunk> chunks;
public GameObject mGameObject;

You can see that pixelPrefab is a public GameObject. Great! (1) your class is inheriting MonoBehaviour, so Unity knows to serialize it, (2) pixelPrefab is public, so the Editor knows to show it, and GameObject is itself a serializable object that Unity knows how to draw, so the end result is that Unity adds pixelPrefab to the Editor GUI for your class.

Then you get to style, which is public, so the Editor knows it should show it, but it's an array and Unity doesn't know how to draw the Editor GUI for an array. It's an array of Texture2D, which it does know how to draw, but it doesn't know how to handle the array aspect, so it doesn't add style to your GUI.

Then you get to chunks, which is public, so the Editor knows it should show it, and it's a List, which Unity does know how to handle, but it's a List of Chunk, which I'm betting is not inheriting MonoBehaviour and is also not tagged with [System.Serializable], so Unity doesn't know that it's supposed to be serializing Chunk. This means that it does know it's supposed to be drawing a list, but it think it's not supposed to be drawing any contents for the list, so it skips the list completely.

Finally you get to public GameObject mGameObject, which gets drawn for all the same reasons that pixelPrefab gets drawn, and finally you get what you see in the Editor in your last screenshot: Only pixelPrefab and mGameObject are drawn in your class GUI:

OP's class in Editor

So, what to do if you want to view your class in an Editor pane and you also want to see pixelPrefab and style?

  1. Have something that can be serialized, like a MonoBehavior, hold a reference to PixelSystem OR have PixelSystem inherit MonoBehavior.
  2. If PixelSystem is not a MonoBehavior then it needs to have [System.Serializable] on the line above public class PixelSystem.
  3. Do what you've already done and have public GameObject pixelPrefab.
  4. Convert style from an array to a list so Unity knows how to draw it.

You should wind up with the following:

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>();
    }
}

You can also have Chunk be serialized and shown in your Editor pane if you tag that class with [System.Serializable], and you only need the [SerializeField] tag for fields that aren't already public. You can still add that tag to public fields just like you can add [System.Serializable] to a MonoBehaviour but it's redundant. Not required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文