我想使Rigidbody对象向右或向左滑动。
例如,如果他的位置为0 X,则他将向一个方向滑动1,然后沿该方向停止并停止。
通过施加力,对象将继续沿该方向移动,我希望对象移动,然后停止。
修改 这就是我尝试过的
void Update() {
if (Input.GetKeyDown("d") && !isMoving) {
StartCoroutine(MoveToPos(Vector3.right));
}
if (Input.GetKeyDown("a") && !isMoving) {
StartCoroutine(MoveToPos(Vector3.left));
}
}
public IEnumerator MoveToPos(Vector3 direction) {
isMoving = true;
var t = 0f;
var startPosition = transform.position;
var value = direction == Vector3.right? 1 : -1;
while (t < 1f) {
t += 0.05f;
var endPosition = transform.position;
endPosition.x = startPosition.x + value * t;
transform.position = Vector3.Lerp(transform.position, endPosition, t);
Debug.Log(player.position);
yield return null;
}
isMoving = false;
}
但是可悲的是,它的动画非常丑陋,对象在一段时间后会捕捉到最终位置,看起来不像对象滑动然后停在那里。就像没有加减速一样。
编辑2
我尝试调整值并进行减速运动。 Kinda工作正常,但我认为它仍需要改进。
public IEnumerator MoveToPos(Vector3 direction) {
isMoving = true;
var t = 0.0;
var startPosition = transform.position;
var value = direction == Vector3.right ? 1 : -1;
while (t < 1) {
if (t < 0.5) t += 0.1;
else t += 0.03125;
Debug.Log(t);
var endPosition = transform.position;
endPosition.x = startPosition.x + value * (float)t;
transform.position = Vector3.Lerp(transform.position, endPosition, (float)t);
yield return null;
}
isMoving = false;
}
我猜想调整加速度和减速度的值会使动画更平滑。
答案 0 :(得分:0)
简单的方法是这样的:
void Update()
{
if(Input.GetKeyDown(KeyCode.A))
transform.Translate(Vector3.right * 1);
}
成为“键”的条件是移动对象,并更改Vector3.right
的对应方向(左,上,下...)
但是我建议使用Lerp函数使它更加逼真: https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html
答案 1 :(得分:-1)
您的代码中几乎没有错误:
1 。不要用固定的数字增加时间(t
变量)。为此使用Time.deltaTime
。
2 。请勿使用带有transform
的Rigidbody来移动GameObject。因此,请勿执行transform.position = xxx
或transform.Translate(xxx)
。移动刚体对象时,请使用Rigidbody.MovePosition
函数。
3 。 使用isKinematic
函数移动刚体时,应在刚体上启用Rigidbody.MovePosition
,因为它非常平滑。
最后,要使其在运动完成后立即停止,请将velocity
和angularVelocity
设置为零。
您已修复的新功能:
bool isMoving = false;
IEnumerator MoveToPos(Rigidbody targetObject, Vector3 direction, float duration, float units = 1f)
{
isMoving = true;
targetObject.isKinematic = true;
float counter = 0;
//Get the current position of the object to be moved
Vector3 startPos = targetObject.position;
//Get destination position
Vector3 toPosition = startPos + direction * units;
while (counter < duration)
{
counter += Time.deltaTime;
//targetObject.position = Vector3.Lerp(startPos, toPosition, counter / duration);
Vector3 newPos = Vector3.Lerp(startPos, toPosition, counter / duration); ;
targetObject.MovePosition(newPos);
yield return null;
}
targetObject.isKinematic = false;
//Stop right away
targetObject.velocity = Vector3.zero;
targetObject.angularVelocity = Vector3.zero;
isMoving = false;
}
用法:
Rigidbody rb = GetComponent<Rigidbody>();
StartCoroutine(MoveToPos(rb, Vector3.right, 3f, 1f));