c# - GameObject 属性值不会在游戏重新启动时重置
问题描述
概述
考虑一个简单的硬币收集游戏。有两个脚本,CollectableItem
和ItemVault
. 有CollectableItem
一个value
属性,它告诉项目的价值,它被添加到coin
预制件中。有ItemVault
一个CurrentAmount
属性来存储收集到的硬币的总价值,并将其添加到player
预制件中。
问题ItemVault对象的CurrentAmount属性的
值不会在 Unity 编辑器内重新启动游戏时重置。
代码
收藏品.cs
public class CollectableItem : MonoBehaviour
{
public float value = 1f;
public ItemVault vault;
private ItemVault m_vault;
void Start()
{
m_vault = vault.GetComponent<ItemVault>();
Debug.Log(m_vault.CurrentAmount); //Does not reset
}
//isTrigger
private void OnTriggerEnter2D(Collider2D collision)
{
if(vault != null)
{
m_vault.ChangeAmountBy(this.value);
}
Destroy(gameObject);
}
}
ItemVault.cs
public class ItemVault : MonoBehaviour
{
public float startingAmount; // 0
public float CurrentAmount { get; private set; }
void Start()
{
CurrentAmount = startingAmount;
Debug.Log(CurrentAmount); // 0
}
public void ChangeAmountBy(float amount)
{
CurrentAmount += amount;
Debug.Log(CurrentAmount); // CurrentAmount does not reset
}
}
笔记
CollectableItem
和都ItemVault
添加到prefabs
.- 的
Start
函数ItemVault
确实记录CurrentAmount
as的值,0
但记录上次运行的最后一个值的Start
函数。CollectableItem
CurrentAmount
- 重新启动编辑器本身会重置该值。
- 我之前尝试过更改to
Script Execution Order
调用ItemVault
CollectableItem
- 实例化属性
Awake()
而不是Start()
给出相同的结果
解决方案
首先:
确保_vault
您实际上是在引用场景中的现有对象引用,而不是预制资产 - 否则,是的,您将在预制上执行该方法,而不是在场景加载/退出 PlayMode 时重置。
您可以通过启动 PlayMode 来确认这一点,然后在 Hierarchy 中单击vault
Inspector 中的插槽一次。这将突出显示层次结构(预期)或资产(不应该发生!)中的引用对象。
如果这没有帮助,那么您的问题可能是时间问题。
如果您在有机会CollectableItem.Start
执行之前执行,您可能会看到不同的值。 ItemVault.Start
我通常使用拇指规则
Awake
:初始化自己,所以任何不依赖别人的东西Start
: 现在访问已经在 Awake 中初始化的其他组件的值
所以在你的情况下,我会做
public class CollectableItem : MonoBehaviour
{
public float value = 1f;
// In general rather already reference this via the Inspector
[SerializeField] private ItemVault _vault;
private void Awake()
{
// Ass fallback get it on runtime
if(!_vault) _vault = vault.GetComponent<ItemVault>();
}
private void Start()
{
Debug.Log(_vault.CurrentAmount);
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(_vault)
{
_vault.ChangeAmountBy(this.value);
}
Destroy(gameObject);
}
}
和
public class ItemVault : MonoBehaviour
{
[SerializeField] private float startingAmount; // 0
public float CurrentAmount { get; private set; }
private void Awake()
{
CurrentAmount = startingAmount;
Debug.Log(CurrentAmount);
}
public void ChangeAmountBy(float amount)
{
CurrentAmount += amount;
Debug.Log(CurrentAmount);
}
}
推荐阅读
- python - Protection against "index 0 is out of bounds for axis 0 with size 0" error in Python
- c# - CookieAuthentication cookies are invalid after application pool recycle
- c++ - 了解如何读入文件并将文件中的行分隔到不同的变量中
- android - Attempt to invoke interface method 'void org.osmdroid.api.IMapController.animateTo(org.osmdroid.api.IGeoPoint)'
- angular - 如何在角度构建时从 index.html 中删除 defer nomodule
- php - XPATH 搜索几个特定节点内的所有节点
- java - 找不到符号方法元工厂(查找、字符串、方法类型、方法类型、方法句柄、方法类型)
- flutter - Flutter Search Delegate with Firestore
- android - 使用 JsonReader.setLenient(true) 在改造 android 中接受格式错误的 JSON
- ios - Error: "Version could not be created from build. Please make sure that your .ipa file has the correct format"