[英]How can you check if object is moving/not moving?
我想制作一个简单的脚本,当您单击屏幕时,游戏中的球将向右移动(20000 * Time.deltaTime),然后如果我再次单击,它将向左移动,然后向右移动等等。
我设法使球向右移动,但是动画结束后我需要等待球,因为我需要检查玩家是否再次单击(如果他单击了,我需要检查向哪个方向移动球)。 我尝试了许多在线发现的方法,例如检查Rigidbody.velocity.magnitude == 0.0f,这意味着球没有移动。
public Rigidbody rb;
public Transform PlayerPosition;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
rb.AddForce(20000 * Time.deltaTime, 0, 0); // moving ball to the right
while (rb.velocity.magnitude != 0.0f) // I tried to check until the ball is not moving
{
}
Debug.Log(PlayerPosition.position.x);
}
}
这是我最近的尝试:
void Update()
{
if (Input.GetMouseButtonDown(0))
{
rb.AddForce(20000 * Time.deltaTime, 0, 0); // moving ball to the right
if(rb.velocity.magnitude < 0.05f) // if i click the ball it just prints it and not wating for the ball to not move
{
Debug.Log(PlayerPosition.position.x);
}
}
}
我希望输出能等到动画结束后才显示,但是当我单击鼠标时,它会输出vaule(x)。
您需要检查动画是否仍在播放。 您仅在检查速度是否大于0.05f时才检查,这正确地打印了该语句。
使用Animation.IsPlaying(string name)
。 需要注意的是,此方法将在调用它的Update
的同一帧中返回false
,因为从技术上讲直到动画之后才开始。
void Update()
{
if (!rb.velocity.magnitude <= 0.01f && !Animation.IsPlaying(nameOfAnimation))
{
Debug.Log("We're not moving and the animation is not playing");
}
}
你不应该需要使用while
在你的Update
方法。
在Update
使用if
语句
void Update()
{
if (rb.velocity.magnitude > 0.01f) Debug.Log("We're moving!");
}
第一
rb.velocity.magnitude != 0.0f
由于单精度浮点,几乎总是 true
:即使两个浮点值看起来逻辑相等,也很可能不是。
因此,您可以使用阈值来尝试
if(rb.velocity.magnitude <= 0.5f)
或使用Mathf.roximated ,它使用非常小的Epsilon或阈值进行比较
if(Mathf.Approximately(rb.velocity.magintude, 0))
听起来比您想等到球停止移动并输出位置之前要多得多,例如进行台球游戏。 因此,实际上似乎没有涉及动画 。
在大多数情况下,当您想到“动画”时,您实际上的意思是“随时间做某事”,不要与在Unity中将Animator
或Animation
组件与AnimationClip
一起使用混淆。
您可以/应该使用协程 :
public Rigidbody rb;
public Transform PlayerPosition;
// a flag to make sure there is only one animation at a time
private bool isMoving;
// a flag for altering between left and right movement
private bool isMovingRight;
// Update is called once per frame
void Update()
{
// only allow clicks while not moving already
if (!isMoving && Input.GetMouseButtonDown(0))
{
// stop further input until not moving anymore
isMoving = true;
// add the force
// (you might btw want to skip that Time.deltaTime here it makes no sense)
rb.AddForce(isMovingRight ? 20000 : -20000 * Time.deltaTime, 0, 0);
// alter the direction for the next call
isMovingRight = !isMovingRight;
// if you rather want to be able to interrupt the current animation by clicking again
// remove the isMoving flag and instead use this
//StopCoroutine(WaitForMoveStops());
// Start the routine
StartCoroutine(WaitForMoveStops());
}
}
private IEnumerator WaitForMoveStops()
{
// Inside a Coroutine while is okey now
// as long as you yield somwhere
// check if velocity is below threshold
while (!Mathf.Approximately(rb.velocity.magnitude, 0)
{
// yield in simple words means "leave" this method here, render the frame
// and than continue from here in the next frame
yield return null;
}
// I would now hard reset the velocity just to be sure
rb.velocity = Vector3.zero;
Debug.Log(PlayerPosition.position.x);
// whatever you want to do now
// reset the flag to allow input again
isMoving = false;
}
我认为如果要停止它,则要移动它,然后仅在其空闲时才调用AddForce:
var wasMovingLastTime = false;
void Update()
{
var isMoving = rb.velocity.magnitude > 0f;
if (wasMovingLastTime && !isMoving)
{
/// Has just finished moving
Debug.Log(PlayerPosition.position.x);
}
if (Input.GetMouseButtonDown(0))
{
if (!isMoving)
{
rb.AddForce(20000 * Time.deltaTime, 0, 0);
}
}
wasMovingLastTime = isMoving;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.