Amazing User
Amazing User

Reputation: 3563

How to stop Translate when I need?

I have a cupboard with boxes. When I look on the box and press mouse button, I want to open/close it with Translate. I want to move box, till it's X coordinate will be 1.0 (and start point is 1.345). But it moves longer than that point.

enter image description here

I tried to use FixedUpdate, but it doesn't helped..

public LayerMask mask;

private bool shouldClose;
private bool changeXCoordinate;
private Transform objectToMove;

void Update ()
{
    if (changeXCoordinate)
        OpenCloseBox();
    else if(DoPlayerLookAtCupboardBox() && Input.GetMouseButtonDown(0))
        changeXCoordinate = true;
}

bool DoPlayerLookAtCupboardBox()
{
    RaycastHit _hit;
    Ray _ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
    bool isHit = Physics.Raycast(_ray, out _hit, 1.5f, mask.value);

    if (isHit && !changeXCoordinate)
    {
        objectToMove = _hit.transform;
        return true;
    }
    else
        return false;
}

void OpenCloseBox()
{
    if (shouldClose)
    {         
        if(objectToMove.position.x != 1.345f) // It must stop at this point, but it don't
        {
            changeXCoordinate = false;
            shouldClose = !shouldClose;
        }
        else
            objectToMove.Translate(Vector3.right * Time.deltaTime);
    }
    else
    {
        if (objectToMove.position.x >= 0.1f) // The same problem here..
        {
            changeXCoordinate = false;
            shouldClose = !shouldClose;
        }
        else
            objectToMove.Translate(Vector3.left * Time.deltaTime);            
    }
}

Upvotes: 0

Views: 243

Answers (2)

AminSojoudi
AminSojoudi

Reputation: 2016

Its better to use a tween engine , like http://dotween.demigiant.com/.

If you install Dotween the you can simply use

transform.DOMove(new vector3(1 ,0 , 1) , duration);

You can also set Ease for tweens. or use Oncomplete fucntions;

transform.DOMove(new vector3(1 ,0 , 1) , duration).SetEase(Ease.OutCubic).OnCompelete(() => { shouldClose = true; });  

But the answer for your question is that positions are not exact numbers so you shouldn't use something like this != , you must use < or > . to fix you problem i would recommend you to do something like this ;

if(x > 1.345f)
{
    x = 1.345f
}

This will fix your problem.

Upvotes: 2

Everts
Everts

Reputation: 10721

In this kind of situation, you should use an animation, this allows full control on any aspect of the movement.

If you really want to use code, you could use Vector3.MoveTowards which creates a linear translation from position A to position B by a certain step amount per frame:

transform.position = Vector3.MoveTowards(transform.position, targetPosition, step * Time.deltaTime);

As for your issue, you are checking if the position is a certain float. But comparing float is not accurate in computer due to inaccuracy of value.

1.345 is most likely 1.345xxxxxx and that is not the same as 1.34500000. So it never equal.

EDIT: Using equality also results in the fact that you are checking if the value is greater or equal. But consider this:

start : 10 movement : 3

if(current >= 0){ move(movement);}

frame1 : 10
frame2 : 7
frame3 : 4
frame4 : 1
frame5 : -2 we stop here

This is why you should use animation or MoveTowards when wishing to move to exact point. Or add extra:

if(current >= 0){ move(movement);}
else { position = 0; }

Upvotes: 1

Related Questions