@marsep

Как заставить объект динамически двигаться за другим в 2D (Unity)?

Всем привет. Уже много времени потратил на то, чтобы решить следующую проблему: есть два объекта, А и Б, объект А находит в позиции по Y = 0, а объект Б в позиции Y = -100. Объект А является лидером и находится в постоянном движении, например:

transform.position += transform.up * speed;

Объект Б должен двигаться за ним так, чтобы если дистанция между ними, например, выше 300, то объект Б добавляет скорость к базовой и постепенно догоняет объект А, а если дистанция ниже, то объект Б наоборот отстает от объекта А, убавляя базовую скорость. На старте базовая скорость объекта Б такая же, как и у объекта А. Дистанцию вычислять можно так:

var distance = (a.transform.position - b.transform.position).magnitude;


Дистанцию вычисляется, как задумано, но проблема такая - не могу я сделать, чтобы объект Б догонял и отставал от объекта А. Перепробовал уже много способов. Пробовал с помощью простых условий, где в какие-то моменты скорость убавлялась или прибавлялась к объекту Б, но проблема у меня была в том, что объект Б постоянно дергается, т.е. по условиям это плохо получается. Выполняю соответственно в методе Update. Подскажите, как можно решить такое, чтобы объект Б мог отставать или догонять объект А при этом делая это корректно и когда это действительно нужно в плане дистанции, ну и чтобы не было никаких таких проблем, вроде подергиваний и т.п. Заранее огромная благодарность!
  • Вопрос задан
  • 9857 просмотров
Решения вопроса 1
@marsep Автор вопроса
Из-за небольшого опыта я не знал про интересный метод Lerp в Vector3:

Vector3.Lerp(Vector3 a, Vector3 b, float t)

Vector3.Lerp
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@vovo801
Freelance Unity3d/C# Developer
Можно для начала попробовать пару готовых скриптов типа Smooth Camera Follow.
Например:
answers.unity3d.com/questions/29183/2d-camera-smoo...

Пользоваться просто. Скрипт вешается на то, что должно следовать за другой штукой, а ссылка на то, за чем надо следовать помещается в поле target в Инспекторе.

Лучше не двигать таким образом объект, на котором уже есть Rigidbody. Тогда будет вибрация.

Чтобы сохранить дистанцию, можно в код из примера вставить простой if оператор
Vector3 delta = target.position - camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, point.z));
if (delta. magnitude > someValue)
{
        Vector3 destination = transform.position + delta;
        transform.position = Vector3.SmoothDamp(transform.position, destination, ref velocity, dampTime);
}


UPDATE: Прочитал еще раз - на счет отставания хотел написать. Можно поиграться с dampTime -
в зависимости от этого значения, объект будет двигаться за целью плавно или быстро. Можно установить так, чтобы было плавное движение, то есть догонит если долго подождать, но включить код -
Vector3 delta = target.position - camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, point.z));
if (delta. magnitude < someValue)
{
        Vector3 destination = transform.position + delta;
        transform.position = Vector3.SmoothDamp(transform.position, destination, ref velocity, dampTime);
}

Разница с тем, что я раньше писал - только в знаке, не > somevalue, a < somevalue, то есть следовать только если объект находится близко. Тогда можно будет от него убежать и он следить перестанет.
Первый вариант когда > someValue подходит для спутников, которые будут следовать, но не надо чтобы они "залезли" на персонажа. А второй - для врагов - будут преследовать, пока мы от них не убежим на безопасное расстояние. Надо только в начале класса будет объявить:
public float someValue; // дистанция слежения.
Вообще лучше диапазон сделать - между двух значений.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы