Unity3D. Как правильно обращаться со снарядом в многопользовательском шутере?

Поэтому я попытался добавить в простой шутер от первого лица физические снаряды / пули со скоростью и гравитацией, а не просто Raycasting и использование Command, если клиент во что-то попадает. После небольшого количества проб и ошибок я понял, что использование снаряда с коллайдером - не лучший способ делать что-то, поскольку физика не рассчитывается достаточно быстро для быстро движущихся объектов. Итак, я сошел с ума по своей физике пули, как показано ниже.

 private float startingVelocity = 50f;
 private float gravity = 9.81f;

 private Vector3 forwardDirection;

 private Vector3 previousPosition;
 private Vector3 nextPosition;

 private Vector3 movementDirection;

 private Vector3 velocity;

 void Start ()
 {
   previousPosition = transform.position;
   forwardDirection = transform.forward.normalized;
   velocity = forwardDirection*startingVelocity;
 }
 void Update ()
 {
   previousPosition = transform.position;
   velocity += new Vector3(0f, -1f, 0f)*gravity*Time.deltaTime;

   nextPosition = previousPosition + velocity*Time.deltaTime;

   transform.position = nextPosition;

   Debug.DrawLine(previousPosition, nextPosition, Color.white, 10f);

   movementDirection = nextPosition - previousPosition;
   if (movementDirection!=Vector3.zero) 
   { 
     transform.rotation = Quaternion.LookRotation(movementDirection); 
   }

   CheckImpact(previousPosition, nextPosition);
 }

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

Сама пуля порождается так:

[Command]
void CmdShootProjectile(string projectilePath, Vector3 _position, Quaternion _rotation)
{
    GameObject projectile = Instantiate(Resources.Load<GameObject>(projectilePath), _position, _rotation);
    NetworkServer.Spawn(projectile);

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

Как я мог эффективно и надежно обращаться со своими снарядами? Могу ли я каким-то образом заставить клиента, который на самом деле стреляет, произвести расчет пули и проверить, попадает ли она, в то время как другие клиенты все еще могут видеть пулю?

Заранее спасибо.


person Glitshy    schedule 23.08.2018    source источник


Ответы (1)


К сожалению, сделать это на 100% безопасным и надежным способом практически невозможно. Однако существует довольно много исследований по этому поводу (такими игровыми компаниями, как Valve - для Counter Strike - и другими).

Текущий консенсус заключается в том, чтобы действительно проводить вычисления на стороне сервера, а не на стороне клиента. Есть плюсы и минусы.

Плюсы:

  • Безопаснее против мошенников: если клиент принимает решение «попала моя пуля», фальсифицированному клиенту (или подобному) легко подделать попадание.
  • Более справедливо при рассмотрении игроков с разной задержкой: если у игрока высокая задержка (50 мс +), может быть довольно легко стрелять по врагам и регистрировать попадания.

Минусы:

  • Иногда хиты не совпадают. Это было темой для дискуссий в течение многих лет в киберспорте, особенно в Counter Strike, где игроки жалуются, что их удары не «попадают». Такова жизнь.
  • В зависимости от логики это может стать довольно тяжелым для сервера, что может стать дорогим.

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

person John Ruschel    schedule 23.08.2018
comment
Есть интересный связанный с этим вопрос, на который вы, возможно, захотите взглянуть: stackoverflow.com/questions/12272855/ - person John Ruschel; 23.08.2018
comment
Я должен добавить концепцию авторитетного сервера, то есть серверную часть, о которой вам говорит Джон. На всякий случай, если вы захотите поискать дополнительную информацию ^^ - person Lotan; 23.08.2018