我只想用lerp来实现x轴上的移动对象,以使其平滑移动。
这是我需要的图片
我不知道如何对这些代码实施lerp以获得这些值之间的平滑移动,它现在可以工作,但是它可以传送玩家,而这并不是我想要实现的平滑移动
这是我传送玩家的工作代码:
void Start()
{
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 desiredPos = new Vector3(transform.position.x + 1.5f, transform.position.y, transform.position.z);
transform.position = desiredPos;
}
if (Input.GetMouseButtonDown(1))
{
Vector3 desiredPos = new Vector3(transform.position.x -1.5f, transform.position.y, transform.position.z);
transform.position = desiredPos;
}
}
我想实现此功能,但我不知道该怎么做..当我将所有代码都更新时,播放器甚至都不会动..仅当我复制并粘贴文档中的所有代码时,它才对我有用,但是我如何才能将时间从开始方法更新到更新,并且始终做到这一点,以便在左右移动时为玩家提供平稳的移动,我不知道真的可以帮助我。.
这是有效的代码,但我不知道如何更改示例。
答案 0 :(得分:2)
有多种方法。我会不使用Translate
,因为这在这里几乎无法控制您,但例如MoveTowards
可以确保最后没有过度射击。将此运动用于具有给定 moveSpeed 的线性运动:
// set move speed in Units/seconds in the Inspector
public float moveSpeed = 1f;
private Vector3 desiredPos;
private bool isMoving;
private void Update()
{
if (!isMoving && Input.GetMouseButtonDown(0))
{
desiredPos = transform.position + Vector3.right * 1.5f;
isMoving = true;
}
if (!isMoving && Input.GetMouseButtonDown(1))
{
desiredPos = transform.position - Vector3.right * 1.5f;
isMoving = true;
}
if(isMoving)
{
transform.position = Vector3.MoveTowards(transform.position, desiredPos, moveSpeed * Time.deltaTime);
// this == is true if the difference between both
// vectors is smaller than 0.00001
if(transform.position == desiredPos)
{
isMoving = false;
// So in order to eliminate any remaining difference
// make sure to set it to the correct target position
transform.position = desiredPos;
}
}
}
或者您要求使用Vector3.Lerp
,例如
// a factor between 0 and 1
[Range(0, 1)] public float lerpFactor;
...
transform.position = Vector3.Lerp(transform.position, desiredPos, lerpFactor);
lerpFactor
的值必须介于0
和1
之间,在这种情况下,0
表示该对象永远不会移动,而1
则直接跳转到目标位置。换句话说,将其设置为0
越接近目标,就越慢,将其设置到1
越接近目标。
很多人这样做是为了使动作“平稳”,但实际上发生的是例如如果将0.5
设置为lerpFactor
,则对象的每一帧都将放置在当前位置和目标位置之间的中间。
看起来很平滑,在开始时移动非常快,而在结束时非常慢...但是:实际上,它从未真正到达目标位置,而是变得非常慢。
对于您来说情况还不错,因为无论如何我们都会使用==
with a precision of 0.00001
比较当前位置和目标位置。只需记住Lerp
的工作方式。
但是与此同时,您将无法控制移动速度和持续时间。
如果您想要总体上更好地控制(我这样做),我建议您使用Coroutine(这不是绝对必要的,您也可以在Update
中进行同样的操作,但在我看来,协程更好地维护和跟踪)。
比起您还可以始终保持固定持续时间的情况下,进行平稳的缓入缓出运动
// set desired move duration in seconds
public float moveDuration = 1;
private bool isMoving;
privtae void Update()
{
if (!isMoving && Input.GetMouseButtonDown(0))
{
StartCoroutine(transform.position + Vector3.right * 1.5f, moveDuration);
}
if (!isMoving && Input.GetMouseButtonDown(1))
{
StartCoroutine(transform.position - Vector3.right * 1.5f, moveDuration);
}
}
private IEnumerator Move(Vector3 targetPosition, float duration)
{
if(isMoving) yield break;
isMoving = true;
var startPosition = transform.position;
var passedTime = 0f;
do
{
// This would move the object with a linear speed
var lerpfactor = passedTime / duration;
// This is a cool trick to simply ease-in and ease-out
// the move speed
var smoothLerpfactor = Mathf.SmoothStep(0, 1, lerpfactor);
transform.position = Vector3.Lerp(startPosition, targetPosition, smoothLerpfactor);
// increase the passedTime by the time
// that passed since the last frame
passedTime += Time.deltaTime;
// Return to the main thread, render this frame and go on
// from here in the next frame
yield return null;
} while (passedTime < duration);
// just like before set the target position just to avoid any
// under shooting
transform.position = targetPosition;
isMoving = false;
}
,您仍然可以扩展该示例,以便也将dtsnace纳入考虑范围,例如
var actualDuration = duration * Vector3.Distance(startPosition, targetPosition);
,然后到处使用actualDuration
。
答案 1 :(得分:1)
使用transform.Translate代替:
public float moveSpeed = 3f;
void Update ()
{
//Moves Left and right along x Axis
transform.Translate(Vector3.right * Time.deltaTime * Input.GetAxis("Horizontal")* moveSpeed);
}