我希望y轴上的对象沿Z轴移动吗? [英] I want an Object lerping in the y-axis to move along the Z-Axis?

查看:143
本文介绍了我希望y轴上的对象沿Z轴移动吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在制作一款不是在Unity中随机生成的亚军类型的游戏.播放器,相机和背景留在同一位置(夹紧了播放器的移动),并且危险通过以下简单的代码行沿负Z轴传向播放器:

I'm currently making a runner type game that is not randomly generated in Unity. The player, camera and background stay in the same place (the player movement is clamped) and the hazards come towards the player along the negative Z-Axis with this simple lines of code:

public float speed;

private Rigidbody rb;

void Start () {
    rb = GetComponent<Rigidbody> ();
    rb.velocity = transform.forward * -speed;
}

它工作正常.现在,我想添加不仅会朝向玩家的小行星,而且还会使它们上下移动(并重复)的小行星,我尝试使用Lerp()进行操作.我不是Lerp的专业人士,因此我使用了在网上找到的有效的代码:

And it works fine. Now I want to add asteroids that not only come towards the player, but they move up and down (and repeat) and I tried doing this with Lerp(). I'm not a pro about Lerp so I used a code that I found online that works:

public Transform startPos, endPos;
public bool repeatable = true;
public float speed = 1.0f;
public float duration = 3.0f;

float startTime, totalDistance;

IEnumerator Start () {
    startTime = Time.time;

    while(repeatable) {
        yield return RepeatLerp(startPos.position, endPos.position, duration);
        yield return RepeatLerp(endPos.position, startPos.position, duration);
    }
}

void Update () {
    totalDistance = Vector3.Distance(startPos.position, endPos.position);
    if(!repeatable) {
        float currentDuration = (Time.time - startTime) * speed;
        float journeyFraction = currentDuration / totalDistance;
        this.transform.position = Vector3.Lerp(startPos.position, endPos.position, journeyFraction);
    }
}

public IEnumerator RepeatLerp(Vector3 a, Vector3 b, float time) {
    float i = 0.0f;
    float rate = (1.0f / time) * speed;
    while (i < 1.0f) {
        i += Time.deltaTime * rate;
        this.transform.position = Vector3.Lerp(a, b, i);
        yield return null;
    }
}

我所做的是为起点和终点位置创建2个空对象,然后将危险和两个危险点放在另一个空对象下,我们将其称为父对象"(因此,父对象">-危害-开始-结束").然后,我将沿Z轴移动的脚本添加到了父级空白中,这有点奏效,但就像跳跃一样.因此,拉幅有效,但直到完成拉幅功能,对象才沿Z轴移动,对象跳到Z轴上的新位置.因此,它看起来非常跳跃和小故障.

What I did is create 2 Empty Objects for the start and end positions and then I put the hazard and two lerping points under another Empty Object, let's call it Parent (So Parent > -Hazard -Start - End). Then I added the moving script along the Z-Axis to the parent empty and it kinda works but is like jumping. So the lerping works but it does not move along the Z-Axis until the lerping function is done, the the object jumps to the new Position in the Z-Axis. So it looks very jumpy and glitchy.

我该怎么做,这样才能使沿Z轴的运动平稳,而束带仍沿Y轴工作?

How can I do this so is a smooth movement along the Z-Axis and the lerp still works along the Y?

谢谢!

PS:我知道我可以移动角色和照相机等,但是现在我想保持这种方式.

PS: I know I could just move the character and camera etc, but for now I would like to keep it this way.

推荐答案

协程RepeatLerp在多个帧中起作用,但是接收到类型为Vector3的输入.参考点的实际位置会随着时间而改变,但是参数值ab直到协程终止之前都不会改变.

The coroutine RepeatLerp acts across several frames, but receives input of type Vector3. The actual position of a reference point will change over time, but the argument values a and b do not change until the coroutine terminates.

因此,立即解决方案很简单:与其传递Vector3而不是传递Vector3,而是将引用传递给Transform,然后在每帧获取其新位置.将您的功能更改为此:

So the immediate solution is simple: instead of passing Vector3, pass reference to Transform, and grab its new position each frame. Change your function to this:

public IEnumerator RepeatLerp(Transform a, Transform b, float time)
{
    float i = 0.0f;
    float rate = (1.0f / time) * speed;
    while (i < 1.0f)
    {
        i += Time.deltaTime * rate;
        this.transform.position = Vector3.Lerp(a.position, b.position, i);
        yield return null;
    }
}

Start功能中,调用现在为:

And in Start funtion the invocation will now be:

yield return RepeatLerp(startPos, endPos, duration);
yield return RepeatLerp(endPos, startPos, duration);

这将解决您的问题,但是,我强烈建议您重新考虑移动对象的方式.您将Rigidbody语义与使用transform的移动对象混合使用,这是一种非常糟糕的做法.该引擎并非旨在做到这一点,将来可能会导致性能问题.

This will solve your problem, however, having said that, I strongly suggest you reconsider the way you move your object. You have a mix of Rigidbody semantics with moving objects using transform, which is a really bad practice. The engine is not designed to do that and it may cause great performance issues in the future.

通常,如果物体上有碰撞器(看起来像是有碰撞器),则应仅使用Rigidbody并对其施加速度/力来移动物体.如果您想使用Lerp,也许可以看看 Rigidbody.MovePosition . ,但最好使用Rigidbody.velocity,例如(以下代码仅是示意图):

In general, if you have colliders on your objects (and it looks like you have) you should move your objects around using only Rigidbody and applying velocity / forces to it. Maybe have a look at Rigidbody.MovePosition if you want to use Lerp, but even better use Rigidbody.velocity, like for example (the code below is just schematic):

if (transform.position.x > highLimit) rigidbody.velocity -= 2*pulsingSpeed;
if (transform.position.x < lowLimit) rigidbody.velocity += 2*pulsingSpeed;

这篇关于我希望y轴上的对象沿Z轴移动吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆