试图让两个variables在两个脚本之间保持同步。 任何人都知道问题是什么?

基本上我正在制定一个库存系统,玩家拥有一定数量的物品,如果他们去一个皮卡,那么它会给他们更多的特定types的物品。 我目前有两个问题。 首先,皮卡脚本确实find了值,并且正确地更新它。 但是,当我去更新库存脚本中的值时,它会一直将其更改回最后一个已知值,并将其保留为静态variables。

另一个较小的问题是我的拾取系统的OnTriggerEnter部分只添加一次,然后停止,尽管日志告诉我它仍在检测对象。

第一个脚本是库存系统…

using UnityEngine; using System.Collections; public class InventoryManager : MonoBehaviour { public Rigidbody Shape1; public Rigidbody Shape2; public Rigidbody Shape3; public Rigidbody Shape4; public Rigidbody Shape5; public float Shape1Amount; public float Shape2Amount; public float Shape3Amount; public float Shape4Amount; public float Shape5Amount; public float Shape1AmountUpdated; public Transform SpawnLoc; public Transform SpawnLoc2; //I had to make this due tot he fact because it doesn't like to spawn centered properly :(. public float coolDown; public float coolDownTimer; // Use this for initialization void Start () { } // Update is called once per frame void Update () { Shape1AmountUpdated = GameObject.Find("PickUp").GetComponent<PickUpSystem>().ShapeValue1; //This was my attempt at trying to *tell* the pick up system the new amount, but it didn't quite work. Shape1Amount = Shape1AmountUpdated; if (coolDownTimer > 0) // If it's above it will subtract from timer. { coolDownTimer -= Time.deltaTime; } if (coolDownTimer < 0) // Checks that cd timer isn't below zero. { coolDownTimer = 0; } if (Input.GetKeyDown("1") && coolDownTimer == 0 && Shape1Amount > 0) { Rigidbody ShapeToSpawn1; ShapeToSpawn1 = Instantiate(Shape1, SpawnLoc.position, SpawnLoc.rotation) as Rigidbody; coolDownTimer = coolDown; Shape1Amount = Shape1Amount - 1; } if (Input.GetKeyDown("2") && coolDownTimer == 0 && Shape2Amount > 0) { Rigidbody ShapeToSpawn2; ShapeToSpawn2 = Instantiate(Shape2, SpawnLoc2.position, SpawnLoc.rotation) as Rigidbody; coolDownTimer = coolDown; Shape2Amount = Shape2Amount - 1; } if (Input.GetKeyDown("3") && coolDownTimer == 0 && Shape3Amount > 0) { Rigidbody ShapeToSpawn3; ShapeToSpawn3 = Instantiate(Shape3, SpawnLoc2.position, SpawnLoc.rotation) as Rigidbody; coolDownTimer = coolDown; Shape3Amount = Shape3Amount - 1; } if (Input.GetKeyDown("4") && coolDownTimer == 0 && Shape4Amount > 0) { Rigidbody ShapeToSpawn4; ShapeToSpawn4 = Instantiate(Shape4, SpawnLoc2.position, SpawnLoc.rotation) as Rigidbody; coolDownTimer = coolDown; Shape4Amount = Shape4Amount - 1; } if (Input.GetKeyDown("5") && coolDownTimer == 0 && Shape5Amount > 0) { Rigidbody ShapeToSpawn5; ShapeToSpawn5 = Instantiate(Shape5, SpawnLoc.position, SpawnLoc.rotation) as Rigidbody; coolDownTimer = coolDown; Shape5Amount = Shape5Amount - 1; } } } 

这里是皮卡系统本身…

 using UnityEngine; using System.Collections; public class PickUpSystem : MonoBehaviour { public float ShapeValue1; public float ShapeValue2; public float ShapeValue3; public float ShapeValue4; public float ShapeValue5; private float oldShapeValue1; private float oldShapeValue2; private float oldShapeValue3; private float oldShapeValue4; private float oldShapeValue5; private float ShapeValue1Updated; // Use this for initialization void Update () { oldShapeValue1 = GameObject.Find("Main Camera").GetComponent<InventoryManager>().Shape1Amount; oldShapeValue2 = GameObject.Find("Main Camera").GetComponent<InventoryManager>().Shape2Amount; oldShapeValue3 = GameObject.Find("Main Camera").GetComponent<InventoryManager>().Shape3Amount; oldShapeValue4 = GameObject.Find("Main Camera").GetComponent<InventoryManager>().Shape4Amount; oldShapeValue5 = GameObject.Find("Main Camera").GetComponent<InventoryManager>().Shape5Amount; } // Update is called once per frame //void Update () //{ //} void OnTriggerEnter (Collider other) { if (ShapeValue1 > 0) { Debug.Log("Object detected!"); ShapeValue1 = oldShapeValue1 + 1; //Fix me. I only add 1 on the first collision afterwards I won't add anymore. } } } 

任何人都知道我应该如何“同步”这两个variables? 基本上,ShapeAmount1值应该总是等于另一个脚本中的ShapeValue1。

当试图在同步的2个不同脚本中保持2个variables时,应该只从一个脚本更新它们。 脚本不能同时运行,要记住脚本运行的顺序,即使不是不可能,也很难。还要记住,更新函数不会与触发器/碰撞器函数同时运行。 物理引擎有自己的Updatefunction,称为FixedUpdate Update

请查看此页面( http://docs.unity3d.com/Manual/ExecutionOrder.html )了解更多信息。

为了解决您的问题,您应该清除InventoryManager Update中的variables更新代码,并从variables实际更新的拾取系统中的Trigger函数(请参阅下面的代码)更新那里的variables。 或者使用volvis的答案。

有一点注意:“查找”function是非常沉重的,并不是一个好主意,使用更新function。

至于你的触发器只更新一次的问题,这是因为OnTriggerEnter只有在触发器input时才触发一次。 要在触发器中保持更新,您需要使用OnTriggerStay

  // Use OnTriggerStay instead of OnTriggerEnter void OnTriggerStay (Collider other) { if (ShapeValue1 > 0) { Debug.Log("Object detected!"); ShapeValue1 = oldShapeValue1 + 1; // After Updating send the updated variable back to the InventoryManager // Or just update the variable in the InventoryManger directly GameObject.Find("Main Camera").GetComponent<InventoryManager>().Shape1Amount = ShapeValue1; } } 

在您的皮卡系统脚本中使用此function并删除库存管理器中的variables更新应该可以解决您的问题。

其中一种方法是将共享variables移动到ScriptableObject实例中,并将其传递给需要访问它们的组件。 就像是 –

 using UnityEngine; [CreateAssetMenu()] public class MySharedStuff : ScriptableObject { public float SharedFloat {get; set;} } public class ObjectUsingSharedStuff : MonoBehaviour { [SerializeField] MySharedStuff mySharedStuff; } 

ScriptableObject作为参考被传递,所以它们总是“同步”。

通常,您可以通过创建脚本实例来在两个脚本之间同步variables。 使InventoryManager实例如下所示:

 public static InventoryManager instance //public variables void Awake() { MakeInstance (); } void MakeInstance() { if (instance == null) { instance = this; } } 

并在下面的另一个脚本中使用公共variables,

 ScriptName.instance.variableName