Как определить направление вращения башни, если угол поворота должен быть ограничен, а цель "пропущена"? - PullRequest
0 голосов
/ 02 февраля 2020

Я начал программировать в Unity просто для развлечения пару дней go. Пока что моя игра (в значительной степени нисходящий шутер) состоит из игрока, летящего на астероидном поле, в котором скрываются вражеские корабли. Игрок может сбивать астероиды и врагов, а вражеские корабли имеют ракетные башни, которые «отслеживают» игрока.

Все отлично работало, пока я не решил, что вражеские корабли не должны поворачивать свои башни на 360 градусов. Думайте об этом как о реальном линкоре, неспособном повернуть его переднюю башню (№ 1) на 180 градусов позади, потому что турель № 2 находится в пути.

В настоящее время код для вращения башни является следующим (это не о «постепенном вращении», настройке «скорости вращения» или о чем-то другом, поэтому, пожалуйста, не смотрите на это!):

playerTarget = GameObject.FindGameObjectWithTag("Player");
chaseDirection = Quaternion.LookRotation(playerTarget.transform.position - transform.position);
newYaw = Mathf.Clamp(chaseDirection.eulerAngles.y, minYaw, maxYaw);
transform.rotation = Quaternion.Euler(0, newYaw, 0);

Это работает нормально, пока игрок не улетит позади вражеский корабль. Как только игрок попадает в «возможный угол поворота» башни, он просто переходит за «мертвую зону» в новое направление, если я не поворачиваю его постепенно с фиксированным углом, или все еще застрял, пытаясь повернуть «мимо предела» до цели ( игрок) летает вокруг вражеского корабля, поэтому угол к цели достаточно мал, чтобы направление вращения можно было вычислить через «активированную» зону вращения, а не через «мертвую зону».

Важно то, что я не ищу ответ "как сделать постепенное вращение". Я рассчитываю на направление вращения!

Turret points at player. Player moves counter-clockwize

Turret tries to target player. Player is in

Now the player has left

Я думал о кодировании противника, чтобы он начал вращать турель в противоположном направлении, как только игрок пройдет «прямо за» башней «вперед». Но концепция того, как это сделать, ускользает от меня.

Потому что, как только турель немного поворачивается от предела, она может снова повернуться к игроку и снова застрянет на пределе.

1 Ответ

0 голосов
/ 02 февраля 2020

Отредактировано с учетом уточнения.

Вам нужна функция, которая сообщит вам, следует ли вам вращаться по часовой стрелке или против часовой стрелки, в зависимости от местоположения противника.

Сначала найдите середину точка, это будет:

var mid = (minYaw + maxYaw) / 2

В вашем примере это будет 3 часа, прямо направо. Теперь, если ваше текущее вращение ниже среднего, а цель выше среднего, вы должны повернуть по часовой стрелке , даже если это не самое короткое вращение, чтобы попасть туда.

Если цель вращение выше среднего, а цель ниже среднего, по той же причине вы должны повернуть против часовой стрелки . Возможно, вам придется скорректировать отрицательные градусы.

Обратите внимание, что это создаст вторичный эффект, когда корабль пересекает половину мертвой зоны (скажем, с 10 до 8 часов). в вашем примере), турель начнет двигаться, как будто ожидая фланга. Вы можете отключить это движение в особом случае.

Я оставлю вторую часть своего ответа как есть для будущих ссылок.

Если вы хотите, чтобы он двигался постепенно, вам нужно использовать deltaTime или fixedDeltaTime в случае фиксированного Обновить. Вы можете определить, насколько быстро он будет двигаться, добавив свойство скорости. Попробуйте что-то вроде этого:

void update () {
  var playerTarget = GameObject.FindGameObjectWithTag("Player");
  var chaseDirection = Quaternion.LookRotation(playerTarget.transform.position - transform.position);
  var newYaw = Mathf.Clamp(chaseDirection.eulerAngles.y, minYaw, maxYaw);

  var currentRotation = transform.eulerAngles;
  var desiredRotation= currentRotation;
  var desiredRotation.y = newYaw;
  transform.eulerAngles = Vector3.RotateTowards(currentRotation, desiredRotation, Time.deltaTime * RotationSpeed, 0.0f);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...