gpt4 book ai didi

c# - 如何确保 MonoBehaviour 对象在另一个 Actor 想要访问它之前加载了它的数据?

转载 作者:行者123 更新时间:2023-11-30 15:13:56 25 4
gpt4 key购买 nike

我有一个 Inventory:MonoBehaviour,它在 Start() 中加载一些模拟数据,包括一个已设置且可以读取的“selectedWeapon”变量。

假设我想在同一场景中设置另一个 MonoBehaviour 时访问此变量。

有没有什么好的方法可以确保在尝试访问变量时已设置该变量?我的目标是在 Start() 或某些初始函数中最好只执行一次。

我的临时解决方案是在想要从 Inventory 访问“selectedWeapon”的实例上使用 Update() 函数,并反复尝试设置它自己的变量(只要它未设置)。

/// This is only an example, illustrating my problem.

public class Inventory : MonoBehaviour
{
[SerializeField]
private WeaponItem m_SelectedWeapon = null;
.
.
.
void Start()
{
m_SelectedWeapon = MockDatabase.GetSelectedWeapon();
}
.
.
.
public WeaponItem GetSelectedWeapon()
{
return m_SelectedWeapon;
}
}

//--------------------------------------------------------------------

public class Actor : MonoBehaviour
{
private WeaponItem m_SelectedWeapon = null;

public Inventory inventory;
.
.
.
void Start()
{
// Would like to set up things here
// but this can let m_SelectedWeapon be null
// since it may be null in Inventory
m_SelectedWeapon = inventory.GetSelectedWeapon();
}

void Update()
{
// If not yet set, load from inventory
if(m_SelectedWeapon == null)
m_SelectedWeapon = inventory.GetSelectedWeapon();
}
.
.
.
}

临时解决方案感觉不可持续,因为 Update 中的检查肯定会在我的项目中增加。

最佳答案

我的一般捷径总是

  • 使用 Awake对于您不依赖他人的所有内容,因此设置您自己的值,设置组件之间的所有引用(但尚未使用它们的值),您可以使用 static 类的东西。

    对于长时间加载/IO 如果可能的话也使用它,这样它就在应用程序加载期间完成并且不会对用户显示为延迟。

  • 使用 Start对于您需要其他组件的所有内容,例如已经设置好使用在 Awake 中设置的引用值。

另见 Awake and Start Tutorial


这当然有其局限性,因此在需要时您可以开始操纵 Script Execution Order但我尽可能避免这种情况。


如果它变得非常复杂,有时就没有办法使用事件系统,例如

public class A : MonoBehaviour
{
public event Action OnReady;
public bool isReady;

private void Awake()
{
// do your stuff

isReady = true;

// execute whatever was added as callback
OnReady?.Invoke();
}
}

然后在需要的地方添加回调,例如

public class B : MonoBehaviour
{
// either reference it in the Inspector
public A a;

private void Awake()
{
// or get it somehow on runtime
a = FindObjectOfType<A>();

// if ready directly move on otherwise add callbacks
if(a.isReady)
{
OnAReady();
}
else
{
// it is always good to remove the callback even though
// it wasn't added yet. Makes sure it is always only added once
a.OnReady -= OnAReady;
a.OnReady += OnAReady;
}
}

private void OnDestroy()
{
// always remove callbacks when no longer needed
a.OnReady -= OnAReady;
}

private void OnAReady()
{
// always remove callbacks when no longer needed
a.OnReady -= OnAReady;

// use stuff from A
}
}

这看起来更烦人也更复杂,但比在 Update 方法中等待一些只做一次事件要高效得多。

关于c# - 如何确保 MonoBehaviour 对象在另一个 Actor 想要访问它之前加载了它的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56832509/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com