使用Event Trigger Unity改变bool的问题,但bool保持设置为false

好吧,我已经多次使用Unity事件触发器来检查Android游戏的屏幕button。 我做了很多次的一个例子是左右箭头button,它移动了角色。 有我正在使用(或试图至less!)的OnPointerDown()和OnPointerUp()方法。

所以我有一个叫做isLeftToggled的布尔,它的初始化为'false'。 OnPointerDown / Up链接到一个名为ToggleButtonLeft()的方法:

public void ToggleButtonLeft(){ Debug.Log ("LEFT TOGGLED" + isLeftToggled); if (isLeftToggled) { isLeftToggled = false; } else { isLeftToggled = true; } } 

上面的Debug.Log读出来确定,它切换真和假(虽然令人费解的第一个日志我得到是'真')。

然而,在我的更新方法中,我经常告诉我它是真是假,每一次调用都是错误的。

我validation了这一点,因为当我尝试使用bool来转换它时,ship(游戏角色)不会转向。 如果我把布尔初始化为“真”,并通过注释去掉切换,那么船就会变好。

我有button游戏对象的事件触发器,我不记得如果我不得不添加其他东西,使其工作。 但是我相当确定button正在工作,因为它总是打印两个button调用的方法内的Debug.Log。

任何想法为什么布尔是每个框架“假”。 上面的代码不应该在手指按在button上时将其切换为真?

这是整个class级(我想考虑修剪不相关的部分,但是不想错过重要的东西,所以决定发布整件事情):

 public class Player : MonoBehaviour { float rotationSpeed = 360f; float currentThrust = 0f; float thrustDecay = 0.02f; float accel = 0.25f; float maxThrust = 150f; float thrustAngle, prevThrustAngle; float maxTurningThrust; public GameObject laserStartPoint; float laserFireRate = 0.5f; private float laserFireTimer = 5f; // the 5 is a random amount just to make sure no delay at the beginning public GameObject laserPrefab; private List<GameObject> lasers = new List<GameObject>(); private Collider gameArea; private GameObject afterburner; public GameObject explosionPrefab; AudioSource audioSource; public AudioClip laserSound, deathSound, deathExplosionSound, thrusterSound; float deathWaitTimeBeforeDestroy = 2f; bool isDying; GameObject shipModel; private bool isLeftToggled = false, isRightToggled; void Start () { isDying = false; gameArea = GameObject.FindGameObjectWithTag("GameArea").GetComponent<Collider>(); maxTurningThrust = maxThrust * 0.012f; afterburner = GameObject.FindGameObjectWithTag("Afterburner"); afterburner.SetActive(false); audioSource = GetComponent<AudioSource>(); shipModel = GameObject.FindGameObjectWithTag("ShipModel"); } void Update () { if (isDying) { shipModel.SetActive(false); deathWaitTimeBeforeDestroy -= Time.deltaTime; if (deathWaitTimeBeforeDestroy <= 0) { Destroy(this.gameObject); GameController.instanceOf.PlayerLoseLife (); } } else { HandleInput(); CheckScreenBounds(); laserFireTimer += Time.deltaTime; } Debug.Log("is left toggled: " + isLeftToggled); } void HandleInput(){ // activate weapon if (Input.GetKey(KeyCode.Space)) { FireWeapon(); } // Rotate left if (Input.GetKey(KeyCode.A) || isLeftToggled) { transform.Rotate(0, -rotationSpeed * Time.deltaTime, 0); } // Rotate right if (Input.GetKey(KeyCode.D)) { transform.Rotate(0, rotationSpeed * Time.deltaTime, 0); } // activate thrusters if (Input.GetKey(KeyCode.W)) { //audioSource.clip = thrusterSound; audioSource.PlayOneShot(thrusterSound, 0.25f); afterburner.SetActive(true); prevThrustAngle = thrustAngle; thrustAngle = transform.eulerAngles.y; if (currentThrust < maxThrust) { if (prevThrustAngle != thrustAngle) { if (currentThrust > maxTurningThrust) { currentThrust = maxTurningThrust; } } currentThrust += accel; } } else { afterburner.SetActive(false); if (currentThrust > 0f) { currentThrust -= thrustDecay; } } // Move the ship in the direction it was facing at point when thruster button was last pressed transform.position += new Vector3(Mathf.Sin(thrustAngle * Mathf.Deg2Rad), 0, Mathf.Cos(thrustAngle * Mathf.Deg2Rad)) * currentThrust * Time.deltaTime; if (currentThrust < 0f) { currentThrust = 0f; } } void CheckScreenBounds() { if (transform.position.x - (GetComponent<Collider>().bounds.size.x / 2) > gameArea.bounds.size.x / 2) { transform.position = new Vector3(-gameArea.bounds.size.x / 2, transform.position.y, transform.position.z); } if (transform.position.x + (GetComponent<Collider>().bounds.size.x / 2) < -gameArea.bounds.size.x / 2) { transform.position = new Vector3(gameArea.bounds.size.x / 2, transform.position.y, transform.position.z); } if (transform.position.z - (GetComponent<Collider>().bounds.size.z / 2) > gameArea.bounds.size.z / 2) { transform.position = new Vector3(transform.position.x, transform.position.y, -gameArea.bounds.size.z / 2); } if (transform.position.z + (GetComponent<Collider>().bounds.size.z / 2) < -gameArea.bounds.size.z / 2) { transform.position = new Vector3(transform.position.x, transform.position.y, gameArea.bounds.size.z / 2); } } void FireWeapon() { if (laserFireTimer >= laserFireRate) { GameObject tempLaser = laserPrefab; tempLaser.transform.position = laserStartPoint.transform.position; tempLaser.transform.rotation = laserStartPoint.transform.rotation; Instantiate(tempLaser); lasers.Add(tempLaser); laserFireTimer = 0f; tempLaser = null; audioSource.PlayOneShot(laserSound); } } public void Die() { GameObject explosion = GameObject.Instantiate(explosionPrefab); explosion.transform.position = transform.position; audioSource.PlayOneShot(deathSound); audioSource.PlayOneShot(deathExplosionSound); isDying = true; } private void OnTriggerEnter(Collider other) { if (other.tag == "Asteroid" || other.tag == "Saucer" || other.tag == "LaserEnemy") { Die(); } } public void ToggleButtonLeft(){ Debug.Log ("LEFT TOGGLED" + isLeftToggled); if (isLeftToggled) { isLeftToggled = false; } else { isLeftToggled = true; } } public void ToggleButtonRight() { Debug.Log("RIGHT TOGGLED"); if (!isLeftToggled) isRightToggled = true; else isRightToggled = false; } 

}

这里是统一的截图。 我认为它总结了这个问题很好,右边的事件触发器显示它调用上面我发布的类中的方法,日志甚至显示当我按下button时切换到True,但船不旋转,并且正如你在日志中看到的那样,bool在每一帧都是“假”的:

统一屏幕

答案是,正如JoshPetrie所述,isLeftToggled是一个实例variables。 但是,我正在创造一个新的玩家的实例,每次死亡。 这个问题是我的UI上的事件触发器无法应付这个问题。 它正在调用脚本中的方法(这就是为什么我的日志告诉我,它正在切换),但它当然不能改变球员的variablesisLeftToggled布尔,因为它从来没有指向它。

我能想到的唯一解决方法是让Player在Unity层次结构中实例化,以便将其拖入事件触发器中。 而且我必须更改我的代码,以便始终使用播放器的相同实例。

除非有办法dynamic地改变事件触发器来告诉它我需要连接哪个播放器(??!?!?)

无论如何,我至less已经过去了这个问题。 所以谢谢那些帮助我的人。 干杯

编辑:感谢在Unity网站上的LegendBacon善良的帮助,他已经将我链接到此解决scheme,以更改在运行时的事件触发器: Unity Answers – 完整答案