Я хочу, чтобы объект, движущийся по оси Y, двигался вдоль оси Z? - PullRequest
0 голосов
/ 16 октября 2018

В настоящее время я делаю игру типа раннер, которая не генерируется случайным образом в Unity.Игрок, камера и фон остаются на одном месте (движение игрока ограничено), и опасности попадают к игроку вдоль отрицательной оси Z с помощью следующих простых строк кода:

public float speed;

private Rigidbody rb;

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

И это работаетхорошо.Теперь я хочу добавить астероиды, которые не только приходят к игроку, но и двигаются вверх и вниз (и повторяются), и я попытался сделать это с помощью Lerp ().Я не профессионал в Lerp, поэтому я использовал код, который я нашел в Интернете, который работает:

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 пустых объекта для начальной и конечной позиций, а затем я добавил опасность идве точки перехода под другим пустым объектом, назовем его Parent (So Parent> -Hazard -Start - End).Затем я добавил сценарий перемещения вдоль оси Z к родительскому пустому объекту, и это вроде как работает, но похоже на прыжок.Таким образом, прокачка работает, но она не перемещается вдоль оси Z, пока не будет выполнена функция раскрепощения, и объект переместится на новую позицию в оси Z.Так что выглядит очень нервно и глючно.

Как я могу это сделать, так что плавное движение вдоль оси Z и lerp все еще работает вдоль Y?

Спасибо !!

PS: Я знаю, что яЯ мог бы просто переместить персонажа, камеру и т. д., но сейчас я бы хотел оставить это так.

1 Ответ

0 голосов
/ 16 октября 2018

Сопрограмма RepeatLerp действует в нескольких кадрах, но получает ввод типа Vector3.Фактическая позиция контрольной точки будет меняться со временем, но значения аргументов a и b не изменятся, пока сопрограмма не завершится.

Таким образом, решение немедленное простое:вместо передачи Vector3 передайте ссылку на Transform и захватите ее новую позицию в каждом кадре.Измените свою функцию следующим образом:

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 вызов теперь будет:

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

Однако это решит вашу проблему, сказав, что Я настоятельно рекомендую вам пересмотреть способ перемещения вашего объекта .У вас есть смесь семантики Rigidbody с движущимися объектами с использованием transform, что является очень плохой практикой.Движок не предназначен для этого, и он может вызвать большие проблемы с производительностью в будущем.

В общем, если у вас есть коллайдеры на ваших объектах (и, похоже, у вас есть), вы должны перемещать свои объекты, используятолько Rigidbody и применение к нему скорости / силы.Возможно, посмотрите на Rigidbody.MovePosition , если вы хотите использовать Lerp, но еще лучше использовать Rigidbody.velocity, как, например, (код ниже только схематический):

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