Reputation: 70
I have 2 scripts (RunControl.cs and FireControl.cs) that depend on mouse click event.
RunControl.cs : Triggered by a button at the top of the screen. When clicked, the game stops.
FireControl.cs : Allows the character to fire when the mouse is clicked.
Problem: Since I have to click when I want to stop the game, first the character shoots and then the game stops. I tried the following codes for blocking but I couldn't block it.
//RunControll.cs
private void Start()
{
isRun = true;
}
public void OnButtonClick()
{
if(btn.image.sprite == runSprite)
{
btn.image.sprite = stopSprite;
FindObjectOfType<FireControl>().isRun = false;
isRun = false;
}
else
{
btn.image.sprite = runSprite;
FindObjectOfType<FireControl>().isRun = true;
isRun = true;
}
}
//FireControl.cs
private void Start()
{
isRun = true; //Controlled by RunControl.cs
}
private void Update()
{
if (isRun)
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
fire = true;
}
else
{
fire = false;
}
}
}
!!! Changing FireControl.cs to lateupdate didn't work
Upvotes: 1
Views: 97
Reputation: 418
You are creating a 'race condition' - which will happen first, disabling the game, or firing. A singleton GameManager class that keeps track of state and is updated by the OnClick and read by the FireControl would go a long way in cleaning up your code, but it would not fix the race condition.
I would take a look at this answer to the question "How to detect left mouse click but not when the click occur on a UI Button component?"
Based off that answer you could update your FireControl to not fire when clicking over the button, which would avoid the race condition all together
if (isRun)
{
if (Input.GetKeyDown(KeyCode.Mouse0) && !EventSystem.current.IsPointerOverGameObject())
{
fire = true;
}
else
{
fire = false;
}
}
Option 2 - Using RayCast
Tag your button so it is identifiable, we'll say as "button". Then do a RayCast and check if pointer is over button, and if so - do not fire
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var overButton = false;
if (Physics.Raycast(ray, out var hit)
{
overButton = hit.collider.tag == "button";
}
else
{
overButton = false;
}
// Continue with your fire logic
if (Input.GetKeyDown(KeyCode.Mouse0) && !overButton)
{
// Fire
}
The above is a little messy and could be opitmized, but should work
Upvotes: 1