help with the code

hello, maybe the question is stupid or funny, but I don’t know how to solve it.
There is a code, there is a condition in the code, if the character position is equal to the position of some object, then the menu is activated through SetActive, in the same code there is a method that closes the menu through SetActive through a button. But here such a thing turned out, it is impossible to close the menu because of the condition that is indicated.

    private void OpenMenu()
    {
       
        if (transform.position.x == GameManager.Personage.transform.position.x)
            Menu.SetActive(true);
    }

    public void Exit()
    {
        Menu.SetActive(false);
    }

Called in Update.
Please tell me how to solve this problem?

Make something like:

private bool _isMenuOpen;

and then statement like:

if (!_isMenuOpen && transform.position.x ==  GameManager.Personage.transform.position.x)
{
    _isMenuOpen = true;
    Menu.SetActive(true);
}

and don’t forget to mark it false later:

public void Exit()
{
    Menu.SetActive(false);
    _isMenuOpen = false;
}

Though, this will not help you much if your object stays in the same position, because the condition will be true again. Maybe try to move it manually?

2 Likes

Thanks for the answer, but unfortunately it doesn’t work. Because the object does not move anywhere from the point at which it changes true to false and the menu cannot be closed either, it just returns false immediately.

Yes I thought so. Then store the position of your object in the outer variable at the time the menu opens and then compare if object moved and if not - don’t allow the menu to open.

Something like this:

private float _previousXPos = float.MaxValue;

private void Update ()
{
    float currentXPos = transform.position.x;

    if (currentXPos != _previousXPos && currentXPos == GameManager.Personage.transform.position.x)
    {
        _previousXPos = currentXPos;
        OpenMenu();
    }
}

and leave everything else like it was in your original message. Also, not sure which object moves here for you - transform.position.x or GameManager.Personage.transform.position.x? If it’s the later then use that instead in line 5.

Though, have in mind that comparing float values like this doesn’t always work as expected. You should always add some margin to comparison like using the Mathf.Epsilon value

1 Like

You are always going to have issues with this. Do not compare floating point values for equality, ESPECIALLY floating point values coming back from an internal game engine property like this.

Here’s why:

https://starmanta.gitbooks.io/unitytipsredux/content/floating-point.html

Also, while you’re at it, if you have more than one or two dots (.) in a single statement, you’re just being mean to yourself.

How to break down hairy lines of code:

http://plbm.com/?p=248

Break it up, practice social distancing in your code, one thing per line please.

“Programming is hard enough without making it harder for ourselves.” - angrypenguin on Unity3D forums

1 Like

A typical solution that would solve the initial problem and also any potential issues with floating point equality is having some hysteresis.

if (distance < r1 && canOpen) {
   open();
   canOpen = false;
}
// require moving further away  than opening distance
// before allowing to open again
if (distance > r1 + k) {
   canOpen = true;
}
1 Like