Dead Reckoning - клиент / серверная игра - как справляться с нажатиями клавиш
Я прочитал несколько статей о расплате, но это все еще немного смущает меня. Я почти уверен, что понимаю концепцию движения "укажи и щелкни", но как мне обновить движение клавиш между клиентом и сервером, если конечная точка перемещения неизвестна?
Как бы вы оценили, куда движется игрок (на стороне сервера), если нет конечной точки?
2 ответа
Давайте начнем с мертвой расплаты. Попробуйте думать об этом по прямой линии, где нет движения влево или вправо.
Вы находитесь в точке A и хотите попасть в точку B. Вы знаете расстояние до точки B, чтобы вы могли вычислить, сколько ускорения и скорости потребуется, чтобы добраться туда. Мертвая расплата работает по-другому. Вы находитесь в точке A и будете двигаться с заданной скоростью, чтобы приблизиться к точке B.
В мире видеоигр они используют этот метод все время. Так что не думайте об этом, когда вы двигаетесь в точку B, вы просто двигаетесь к точке B с приращениями, потому что, подобно FPS, ваша точка B будет постоянно двигаться. Когда на самом деле это действительно только движение с шагом в направлении точки B.
Как только вы продвигаетесь вперед, вы можете начать беспокоиться о левом / правом и вверх / вниз, которые будут следовать одному и тому же принципу только в разных направлениях.
Что касается реализации этого у вас есть 2 варианта.
Одним способом, вы могли бы сделать этот расчет на стороне клиента, а затем отправить новую позицию на сервер. Затем обновите то, что все остальные видят на экране.
Другой способ, который я считаю лучше, вы можете сделать все эти вычисления на стороне сервера и просто получить обновление, где вы оказались. X-Box live делает одну из консолей хостом, так что на машине запущено все программное обеспечение, а внешние пользователи просто запускают события. Вот почему вы услышите, как люди жалуются на несправедливое преимущество хозяина.
Теперь давайте посмотрим на некоторый код. Этот скрипт поставляется из стандартного установочного пакета Unity Sdk.
/// This script moves the character controller forward
/// and sideways based on the arrow keys.
/// It also jumps when pressing space.
/// Make sure to attach a character controller to the same game object.
/// It is recommended that you make only one call to Move or SimpleMove per frame.
var speed : float = 6.0;
var jumpSpeed : float = 8.0;
var gravity : float = 20.0;
private var moveDirection : Vector3 = Vector3.zero;
function Update() {
var controller : CharacterController = GetComponent(CharacterController);
if (controller.isGrounded) {
// We are grounded, so recalculate
// move direction directly from axes
moveDirection = Vector3(Input.GetAxis("Horizontal"), 0,
Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
}
}
// Apply gravity
moveDirection.y -= gravity * Time.deltaTime;
// Move the controller
controller.Move(moveDirection * Time.deltaTime);
}
Таким образом, в этом примере мы имеем скорость, которая установлена на постоянную величину. Поэтому, двигаясь в направлении, мы будем двигаться в этом векторе с постоянной скоростью, не заботясь о том, где находится точка B.
Скорость прыжка - это скорость, с которой мы будем двигаться по оси Y в положительном направлении, а сила тяжести в отрицательном направлении останавливается в точке 0.
Итак, как вы можете использовать это? Вы можете создать серверный скрипт, который выполняет действие перемещения и иметь контроллер на стороне клиента, который передает информацию о направлении на сервер.
Итак, скажем, на стороне клиента действие - это нажатие клавиши вниз, вы посылаете вызов на сервер, чтобы переместить вас в выборе направления, и сервер будет удерживать вас в этом направлении, пока клавиша действия не будет нажата вверх или изменение направления от другого вход.
Я надеюсь, что это помогло.
Посмотрим... Я понимаю, вы знаете, как кодировать, но не что, я прав?
Вы можете передать нажатия клавиш непосредственно на сервер и позволить ему делать всю работу. Серверу не нужно знать, куда вы направляетесь, у него есть ваши координаты и направление, и это все, что ему понадобится, если у вас нет ИИ с сервером. В последнем случае вы можете сделать что-то похожее на лучевое вещание в Unity, начать проверять, что находится прямо перед собой, и посмотреть, если это что-то интересное, если вы знаете потенциальный пункт назначения.
Безопасно постоянно возвращать клиенту все его данные, поэтому они всегда актуальны. Если вы считаете, что это будет напрягать ваше соединение, вы можете делать это каждые 50 мс или так часто, как вы считаете, безопасно, и для бесперебойной работы оцените все на стороне клиента. Убедитесь, что сервер выполняет все обнаружение столкновений и всю механику, не связанную с пользовательским интерфейсом, иначе игра будет подвержена сбоям на стороне клиента или злонамеренному вмешательству.
Если вам нужно посмотреть, куда может идти игрок, вы можете использовать несколько подходов, у вас может быть несколько виртуальных кубов в мире, которые отслеживают то, что находится внутри них, что упростит поиск того, что впереди в терминах ресурсов, или вы можете проверить все, что есть, что довольно тяжело на машине, но это также добавляет некоторые другие сложности. В первом случае не забудьте перестать смотреть, как только вы столкнетесь с препятствием.
Вы также можете рассчитать угол между направлением игрока и другими важными предметами, чтобы проверить, что еще может быть у него на уме.
На вопрос о UDP уже дан ответ, плюс я уверен, что в Википедии есть полезная книга по UDP и TCP, мне нечего добавить.
Объяснение мертвого расчета также было вполне удовлетворительным, я надеюсь, что я добавил другие аспекты к концепции.
Я надеюсь, что помог, если вам нужны какие-либо разъяснения или любая другая помощь, не стесняйтесь связаться со мной, если я был менее чем бесполезен, то не стесняйтесь понижать голос, я изучаю компьютерную инженерию и создаю свою вторую игру для ПК, так что, возможно, я столкнулся с некоторые проблемы уже и могут поделиться знаниями.