如何在需要时停止翻译?
How to stop Translate when I need?
我有一个带盒子的橱柜。当我查看框并按下鼠标按钮时,我想用 Translate open/close 它。我想移动方框,直到它的 X 坐标为 1.0(起点为 1.345)。但它移动的时间比那个点长。
我尝试使用 FixedUpdate,但没有用..
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);
}
}
在这种情况下,您应该使用动画,这样可以完全控制运动的任何方面。
如果你真的想使用代码,你可以使用 Vector3.MoveTowards 它创建一个从位置 A 到位置 B 的线性平移,每帧一定步长:
transform.position = Vector3.MoveTowards(transform.position, targetPosition, step * Time.deltaTime);
关于你的问题,你是在检查position是不是某个float。但是由于值的不准确,在计算机中比较浮点数是不准确的。
1.345 很可能是 1.345xxxxxx,它与 1.34500000 不同。所以它永远不相等。
编辑:使用相等也会导致您检查值是否大于或等于。但考虑一下:
start : 10 movement : 3
if(current >= 0){ move(movement);}
frame1 : 10
frame2 : 7
frame3 : 4
frame4 : 1
frame5 : -2 we stop here
这就是为什么在希望移动到精确点时应该使用动画或 MoveTowards 的原因。或额外添加:
if(current >= 0){ move(movement);}
else { position = 0; }
最好使用补间引擎,例如http://dotween.demigiant.com/。
如果你安装了 Dotween,你可以简单地使用
transform.DOMove(new vector3(1 ,0 , 1) , duration);
您还可以为补间设置缓动。或使用 Oncomplete 函数;
transform.DOMove(new vector3(1 ,0 , 1) , duration).SetEase(Ease.OutCubic).OnCompelete(() => { shouldClose = true; });
但是你的问题的答案是位置不是精确的数字所以你不应该使用这样的东西 != ,你必须使用 < 或 > 。
为了解决您的问题,我建议您这样做;
if(x > 1.345f)
{
x = 1.345f
}
这将解决您的问题。
我有一个带盒子的橱柜。当我查看框并按下鼠标按钮时,我想用 Translate open/close 它。我想移动方框,直到它的 X 坐标为 1.0(起点为 1.345)。但它移动的时间比那个点长。
我尝试使用 FixedUpdate,但没有用..
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);
}
}
在这种情况下,您应该使用动画,这样可以完全控制运动的任何方面。
如果你真的想使用代码,你可以使用 Vector3.MoveTowards 它创建一个从位置 A 到位置 B 的线性平移,每帧一定步长:
transform.position = Vector3.MoveTowards(transform.position, targetPosition, step * Time.deltaTime);
关于你的问题,你是在检查position是不是某个float。但是由于值的不准确,在计算机中比较浮点数是不准确的。
1.345 很可能是 1.345xxxxxx,它与 1.34500000 不同。所以它永远不相等。
编辑:使用相等也会导致您检查值是否大于或等于。但考虑一下:
start : 10 movement : 3
if(current >= 0){ move(movement);}
frame1 : 10
frame2 : 7
frame3 : 4
frame4 : 1
frame5 : -2 we stop here
这就是为什么在希望移动到精确点时应该使用动画或 MoveTowards 的原因。或额外添加:
if(current >= 0){ move(movement);}
else { position = 0; }
最好使用补间引擎,例如http://dotween.demigiant.com/。
如果你安装了 Dotween,你可以简单地使用
transform.DOMove(new vector3(1 ,0 , 1) , duration);
您还可以为补间设置缓动。或使用 Oncomplete 函数;
transform.DOMove(new vector3(1 ,0 , 1) , duration).SetEase(Ease.OutCubic).OnCompelete(() => { shouldClose = true; });
但是你的问题的答案是位置不是精确的数字所以你不应该使用这样的东西 != ,你必须使用 < 或 > 。 为了解决您的问题,我建议您这样做;
if(x > 1.345f)
{
x = 1.345f
}
这将解决您的问题。