vector3 lerp на основе 2 разных поплавков/осей?

Я пытаюсь перемещать объект вокруг моего игрока в игре с боковой прокруткой 2.5d, основанной на аналоговом вводе стика. Дело в том, что мой игрок вращается в мире (с камерой, закрепленной сбоку), поэтому его локальное горизонтальное направление (transform.right) не всегда совпадает с глобальным направлением x для его локального направления вверх (transform.up). У меня это отлично работало, когда направление движения игрока было зафиксировано по оси X, установив смещение положения игроков и добавив аналог по той же оси, например:

 Vector3 endPoint = new Vector3(transform.position.x + inputs.x * floraDistanceMultiplier, transform.position.y + inputs.y * floraDistanceMultiplier, transform.position.z);

но теперь, когда игрок, так сказать, находится вне оси, это, конечно, не работает.

Я могу заставить его работать по одной оси за раз:

 Vector3 h = player.transform.position + player.transform.right * floraDistanceMultiplier * inputs.x;
 Vector3 v = player.transform.position + player.transform.up * floraDistanceMultiplier * inputs.y;

Но не мог понять, как заставить оба вектора влиять на конечную позицию. Я предполагаю, что использование localPosition или применение x и y конечного вектора вручную не сработало, потому что x и y всегда являются глобальными, а не определяют transform.right как длинную локальную ось X.

У меня была мысль сделать лерп двумя - что почти дало успешные результаты, в том, что конечная точка правильно перемещается вокруг игрока только слева вверх, хотя и не по полному кругу вокруг игрока, а диагональ сильно ближе, чем полный степени вверх и влево.

 Vector3 endPoint = Vector3.Lerp(h, v, inputs.x + inputs.y);

есть ли лучший способ сделать это в целом? Или есть какой-то способ lerp между двумя векторами, используя 2 поплавка? (аналоговый джойстик x и y) или с помощью вектора? Спасибо!


person smackledorf    schedule 11.03.2021    source источник


Ответы (1)


Что вы делаете изначально

var endPoint = new Vector3(transform.position.x + inputs.x * floraDistanceMultiplier, transform.position.y + inputs.y * floraDistanceMultiplier, transform.position.z);

в основном равно использованию

var endPoint = transform.position + Vector3.right * input.x * floraDistanceMultiplier + Vector3.up * input.y * floraDistanceMultiplier;

Итак, чтобы преобразовать это в локальное пространство, просто замените глобальные векторы Vector3.right и Vector3.up местным transform.right и transform.up уже должен это сделать

var endPoint = transform.position + transform.right * input.x * floraDistanceMultiplier + transform.up * input.y * floraDistanceMultiplier; 

Другой способ написать это немного короче:

var endPoint = transform.position + (Vector3)input * floraDistanceMultiplier;

а чтобы преобразовать это в локальное пространство, просто умножьте (Quaternion * Vector3 оператор ) вектор движения с поворотом игрока

var endPoint = transform.position + transform.rotation * input * floraDistanceMultiplier;

В качестве альтернативы, если вам не обязательно нужен endPoint в качестве вектора, вы можете напрямую использовать transform.Translate где вы можете просто решить с помощью второго параметра, хотите ли вы применить движение в мировом или локальном пространстве

transform.Translate(input * floraDistanceMultiplier);

По умолчанию это уже перемещает объект в локальном пространстве. Однако обратите внимание, что здесь также учитывается масштабирование ваших объектов. Так что это может вести себя не так, как ожидалось.

person derHugo    schedule 11.03.2021
comment
сработало отлично спасибо! - person smackledorf; 11.03.2021