Awake() for Prefab without Instantiation

问题描述 投票:0回答:3

我有一个脚本,它接受一个预制件,稍后从中实例化对象。

那个预制件在它的一个组件中有一些静态数据,我希望在实例化任何东西之前读取这些数据,为此我需要获取组件,自然地使用

GetComponent()
。后来该数据被实例多次读取,所以我不想一直使用
GetComponent()
,因为我知道这是一个相当繁重的操作。所以很自然地,像往常一样,我保留了一个变量来保存这个组件,并在
Awake()
函数中初始化该变量。

问题是,

Awake()
函数不会为预制件本身调用,而只会为我稍后使用
Instantiate()
创建的实例调用。

换句话说,理想情况下我想这样做:

void Awake()
{
    imageSelector = GetComponent<ImageSelector>();
}

public int MaxValue => imageSelector.Count;

但是为了让它在实例化之前为预制件本身工作,我需要这样做:

public int MaxValue => GetComponent<ImageSelector>().Count;

当然,我可以进行类似单例的读取访问,我检查我是否已经保存了组件,如果没有保存,则获取并保存它,但这不是很好,对我来说似乎有一些初始化是合理的我可以参与其中的过程。

那么如何为未实例化的预制件初始化东西?

我还想到了一些其他的解决方法,没有一个是我特别喜欢的,但如果有必要,我会使用其中的一个——不过,我想知道是否有一种干净的方法来做到这一点。

提前致谢。

c# unity3d initialization
3个回答
2
投票

你不能

预制件没有调用 MonoBehaviour 方法,因为它们还没有——也永远不会——被初始化。

请注意,您可以自己在检查器中分配属性,而根本不用打扰

Awake
电话。


0
投票

我有一些类似的问题试图在实例化之前初始化预制设置。我很难理解,因为我希望有一种更简洁的方式来做到这一点,但似乎是 Unity 中的自然方式。 通常来自 c++、c# 或 oop,它很可能被用于像在类构造函数中那样设置组件。我得到的结论是,从programaticall的角度来看,Unity并没有完全走到那种操作方式。 您当然可以使用 c# 普通类及其构造函数等(不是从 monobehaviour 继承)但是如果您要使用 Unity 类和工具,您应该从编程的角度来看在 Unity 中设置类的笨拙方式,另一方面,它是如此有效。 所以我认为设置事物的正常方法是通过 monobehaviour 类的构造函数,这是 Awake()(或者可能是 start()),然后再进入更复杂的可以编写脚本的对象或 .json/。 xml 阅读器,除非您具有高级 c# 和 unity 知识,否则这不是一件容易的事。

希望有帮助


0
投票

ISerializationCallbackReceiver.OnAfterDeserialize() 可以用来替代预制件的 Awake()。它是这样使用的:

public class AnyCustomComponent : MonoBehaviour, ISerializationCallbackReceiver
{
    public AnySerializedData serializedData;

    private AnyInitializedData initializedData;

    public void OnBeforeSerialize() { }

    public void OnAfterDeserialize()
    {
        initializedData = serializedData.Init();
    }
}

需要注意的是,这个回调不仅会在游戏开始时发生,还会在编辑器中编辑时发生,但我想在大多数情况下这应该不是问题。

© www.soinside.com 2019 - 2024. All rights reserved.