我有一个物理划船设备,它不断地将划船比赛的剩余距离发送给 Unity(即完成比赛还剩 350m)。当我尝试相应地更新玩家的位置(仅限 Z 轴)时,运动不稳定。 我怎样才能插入这种运动以使其更平滑?
我的第一次尝试是这样的:
void Update()
{
player.position = new Vector3(player.position.x, player.position.y,
pm5.Pm5_distance);
}
这导致了运动的不稳定,可能是因为玩家只是被传送到下一个位置。
接下来我尝试移动到下一个位置,但我不确定我是否正确执行了操作,或者这是否有效,因为我的播放器每帧都会收到一个新位置:
private float startTime;
private float journeyLength;
public float speed = 5.0F;
void Start()
{
startTime = Time.time;
}
void Update()
{
if (player.position != new Vector3(player.position.x,
player.position.y, pm5.Pm5_distance))
{
journeyLength = Vector3.Distance(player.position, new
Vector3(player.position.x, player.position.y, pm5.Pm5_distance));
float distCovered = (Time.time - startTime) * speed;
float fracJourney = distCovered / journeyLength;
transform.position = Vector3.Lerp(player.position, new
Vector3(player.position.x, player.position.y, pm5.Pm5_distance),
fracJourney);
}
}
尽管这不会引发错误,但它似乎也无法解决我的问题。也许整个概念都是错误的?如果有人能在这里帮助我,我会很高兴。
编辑 2019 年 4 月 25 日: 通过尝试使用我的大卫代码,我到达这里:
void Update()
{
if (useLerpMovementModel)
{
float newDistance = pm5.Pm5_distance;
if (player.position.z != newDistance)
{
// Distance moved
float distCovered = journeyLength - pm5.Pm5_distance;
// Fraction of journey completed = current distance divided by total distance.
float fracJourney = distCovered / journeyLength;
// Set our position as a fraction of the distance between the markers.
transform.position = Vector3.Lerp(player.position, new Vector3(player.position.x, player.position.y, newDistance), fracJourney);
}
}
else
{
player.position = new Vector3(player.position.x, player.position.y, journeyLength - pm5.Pm5_distance);
}
}
我不确定这是否会起到任何作用,但与player.position = new Vector3(player.position.x,player.position.y,journeyLength - pm5.Pm5_distance)相比,这在平滑运动方面是否有任何作用);
最佳答案
下面这行实际上是一个不正确的计算:
journeyLength = Vector3.Distance(player.position, new
Vector3(player.position.x, player.position.y, pm5.Pm5_distance));
您需要存储旅程开始和结束时的位置,以便可以在它们之间插入玩家的位置。
我将尝试通过获取您的代码并添加注释来解释必要的内容。我还包括了我建议的更改以及其他更改:
private float journeyLength;
private Vector3 startPosition;
private Vector3 endPosition;
void Start()
{
// The total length of the journey, let's imagine it's 100
// This assumes that when this Start() method is called that
// pm5.Pm5_distance is equal to the journey length
journeyLength = pm5.Pm5_distance;
// Store the player's starting position
// This will be used to interpolate between start/end
startPosition = player.position;
// Store the position that the player will be at when the journey is complete
// This will be used to interpolate between start/end
endPosition = startPosition + Vector3.forward * journeyLength;
}
void Update()
{
// I am assuming that 'pm5.Pm5_distance' is the remaining distance
if (pm5.Pm5_distance > 0f)
{
// Take the remaining distance from the total journey length to get
// the current distance travelled. Let's imagine the remaining distance is 50:
// This will end up being 100 - 50 = 50 units travelled into the journey
float distCovered = journeyLength - pm5.Pm5_distance;
// We now get the fraction of the journey that that distance equates to,
// which in this case will be 0.5
float fracJourney = distCovered / journeyLength;
// Interpolate the players position from where it originally started
// to the position at the end of the journey (the one we calculated in Start())
transform.position = Vector3.Lerp(startPosition, endPosition, fracJourney);
}
}
最后一点,了解 Vector3.Lerp()
函数的工作原理非常重要:
它采用两个向量并在它们之间插值 0 到 1 之间的值。
如果值为 0,则返回第一个向量。
如果值为 1,则返回第二个向量。
如果值为 0.5,则返回位于两者之间的向量。
因此您可以看到,在上面的示例中,fracJourney
为 0.5,这意味着对于此帧,玩家的位置将恰好位于比赛的一半位置。
但在下一帧中,fracJourney
将被重新计算,比如 0.55。
在该帧中,新位置将比前一帧中的位置稍微向前计算。
这样一直持续下去,直到最终距离比赛终点为 0。
关于c# - 如何在 Unity 中每次更新时插入一个获得新位置的相机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55834367/