Перейти до основного вмісту
Жива гра

Цю сторінку ще не перекладено — показано англійську версію.

Collision

Прив’яжіть трансформ до мапи перешкод і оголосіть, що відбувається під час контакту. Модуль Collision працює всередині симуляції платформи. Ви оголошуєте тіла, шари й реакції, а на контакти підписуєтеся.

Коли це потрібно

  • Сутності (entity), що рухаються, мають обробляти контакти на сервері — ковзати, зупинятися, відскакувати, — а писати для цього власну процедуру відбиття не хочеться.
  • Геймплей реагує на дотик: предмет підбирається, щойно з ним перетнулися, а зони-тригери запускають машину станів (state machine) сутності.
  • Модулю Locomotion і снарядам потрібна неперервна (swept) перевірка зіткнень із набором перешкод мапи.
  • Для прев’ю розміщення чи прицілювання треба питати «чи поміститься це тут?» і шукати перетини об’ємів.
  • Не потрібен, якщо у грі ніщо фізично не стикається. Для геймплею за схемою «запит — відповідь» над записами вистачить звичайного модуля Data & Subscriptions.

Хто що робить

АкторЩо робить на цій сторінці
room-ownerоголошує тіла, шари й реакції; запитує перетини й контакти

Яких кімнат це стосується

Модуль працює там, де кроки симуляції обчислює платформа: у кімнатах (room), оголошених із Host = "Backend". Якщо симуляцією володіє ваш власний ігровий сервер (а PlayServ працює як метасервер), рух, зіткнення й передбачення лишаються на боці рушія. Тоді ця сторінка описує варіант із хостингом на платформі, а не обов’язкову вимогу.

Коротко

Форму, шар і реакцію на контакт оголошують просто на тілі. Окремого оголошення пар шарів десь збоку немає:

Капсула Body на танку, шар vehicles: ковзає вздовж стін, проходить крізь предмети для підбирання, а щодо ящиків вирішує під час кожного контакту
[Entity("tank")]
public class Tank
{
    [Sync] public Vector3 Position;

    [Body(Shape.Capsule, Radius = 0.6f, Layer = "vehicles")]
    [CollidesWith("walls", Response.Slide)]
    [CollidesWith("pickups", Response.Pass)]        // reported, motion passes through
    public Body Body;
}
@Entity('tank')
export class Tank {
  @Sync() position!: Vector3;

  @Body({ shape: 'capsule', radius: 0.6, layer: 'vehicles' })
  @CollidesWith('walls', Response.Slide)
  @CollidesWith('pickups', Response.Pass)        // reported, motion passes through
  body: Body;
}
@entity("tank")
class Tank:
    position: Vector3 = sync()

    body = collision.body(shape="capsule", radius=0.6, layer="vehicles",
                           collides_with=[
                               ("walls", Response.SLIDE),
                               ("pickups", Response.PASS),   # reported, motion passes through
                           ])
Незабаром — Go

Як оголошувати через атрибути в Go, поки не вирішено (O-1). Приклади з’являться, коли оберуть спосіб запису.

// the declaration rides inside the engine's own reflection macros, in the specifier position —
// UHT reads it from the header text, and the member is a reflected property at the same time
UCLASS(PSEntity = "tank")
class UTank : public UObject
{
    GENERATED_BODY()

    UPROPERTY(PSSync)
    FVector3f Position;

    // walls slide, pickups report the contact and let motion pass through —
    // multi-entry values are one quoted list (a specifier value is a single token)
    UPROPERTY(PSBody = (Shape = "Capsule", Radius = "0.6", Layer = "vehicles"),
              PSCollidesWith = "walls:Slide, pickups:Pass")
    FPSBody Body;
};
// declarations compile into the same pushed model — playserv push from the UE project or CI
Unity C# is the same C# API here — ті самі атрибути компілюються в Unity на базовій версії 2021.3 — синтаксису C# 12 тут немає
[Entity("tank")]
public class Tank
{
    [Sync] public Vector3 Position;

    [Body(Shape.Capsule, Radius = 0.6f, Layer = "vehicles")]
    [CollidesWith("walls", Response.Slide)]
    [CollidesWith("pickups", Response.Pass)]        // reported, motion passes through
    public Body Body;
}

Контакт — це подія (event), і модулі на неї підписуються. Хука на контакт немає: коли контакт з’являється, крок уже його розв’язав, і відхиляти нічого. Якщо студії потрібні інші правила, вона підміняє перевірки допустимості й шляху власною реалізацією (див. Extensibility), а реакцію й далі задає оголошення.

Модель

Що оголошує тіло.

Що оголошуєЩо це
shapeпримітив із закритого набору — сфера, капсула, бокс — з оголошеними розмірами. Довільного меша немає: обмеження те саме й з тієї самої причини, що й у серверної моделі світу в модулі Map
де живе тілона аспекті, разом із трансформом. Аспект — одиниця політики, і доля в тіла та його трансформа спільна
як перевіряють шляхstepwise — перевіряє кінцеву позицію кроку, це швидко. swept — перевіряє відрізок між позиціями: дорожче, зате в межах кроку тіло не проскочить крізь перешкоду. Спосіб оголошують, реалізація ніколи не обирає його сама за швидкістю
у яких областях бере участьусередині яких об’ємів тіло враховують
зв’язок із візуальною моделлюне обов’язковий: тіло — це спрощення, і розбіжність із візуальною моделлю допустима в оголошених межах

Швидке тіло зі stepwise пролітає крізь тонкі перешкоди

stepwise перевіряє лише точку, де закінчується крок, тож швидке тіло може проскочити тонку перешкоду наскрізь. swept перевіряє відрізок між позиціями й не дає тілу проскочити в межах кроку. Чи може снаряд (projectile) пролетіти крізь стіну — властивість вашої гри, і оголошуєте її ви.

Реакцію оголошують для пари «тип прохідності перешкоди × тип тіла» й обирають її із закритого набору:

РеакціяЩо означає
stopрух припиняється в останній допустимій позиції
slideрух триває вздовж перешкоди — на ту складову, яка допустима
bounceнапрямок відбивається, а швидкість множиться на оголошений коефіцієнт
dampрух триває, а швидкість множиться на оголошену частку
passперешкода не впливає на рух, але контакт однаково можна спостерігати
cease to existсутність припиняє існування — як снаряд, що влучив у стіну

Коефіцієнти — це оголошені значення, а не результат розрахунку за масами й матеріалами: ні мас, ні матеріалів у цьому контракті немає.

Що справджується для кожної перевірки.

ЗавждиЩо це
кожна парамає реакцію. Пропущена пара — це дефект оголошення (declaration): його відхилить деплой, а не виявить бій
таблиця реакційдоступна клієнтові для читання. Це та сама таблиця, за якою обчислює авторитетна сторона (authority), тож клієнт і сервер з одним оголошенням однаково відповідають на той самий контакт
відтворюваність у межах однієї авторитетної сторони, а не між платформамиті самі вхідні дані в тому самому порядку дають той самий результат у межах одного процесу й однієї збірки. Побітово однакових результатів на різних платформах і збірках не обіцяють
одночасністьоголошують: якщо два рухомі тіла стикаються всередині одного кроку, порядок їх розв’язання оголошений і детермінований. Підставою для нього не можуть бути порядок обходу сховища, порядок надходження введення чи випадковість
один контакт — один фактконтакт двох тіл обидві сторони бачать як один факт з одним ідентифікатором, а не як дві незалежні події
точки розширення — на кроці, а не на контактідо кроку трансформ можна змінити, після нього — лише спостерігати. Перевизначені перевірки допустимості й шляху мають бути доступні й клієнтові
модульсам нічого не рухає. Він відповідає, чи допустима позиція і якою буде реакція, а застосовує це модуль Locomotion
контакт — це подіятому модулі підписуються на нього, а не зв’язуються напряму. Машина станів пастки прив’язує перехід до входу в зону-тригер, дроп підбирається при перетині, а снаряди знаходять влучання через swept-перевірку цього модуля

Помилки

  • «Недопустимо» — це відповідь, а не помилка, і вона називає, яка з трьох причин спрацювала: позиція поза межами, її займає статична перешкода або тіло іншої сутності. Клієнт реагує на них по-різному: розвернутися, об’їхати або зачекати.
  • Помилки оголошення спливають під час деплою, а не на першому контакті. Тіло з формою поза закритим набором, тіло на аспекті без трансформа й пару без оголошеної реакції відхиляє деплой.
  • Якщо сутність або місце не знайдено, відповідь — not found, і повторювати запит марно.
  • Якщо перевищено частоту перевірок, відповідь приходить у категорії обмеження частоти разом із терміном, до якого повторювати марно.

Обмеження

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

  • Тіла в кімнаті: оголошення ще одного тіла відхиляють як конфлікт. Наявні тіла ніколи не видаляють, щоб звільнити місце.
  • Контакти за крок: зайві ніколи не відкидають мовчки. Або крок відхиляють, або порядок відсікання оголошено.
  • Розмір тіла відносно кроку сітки мапи: невідповідність відхиляють під час деплою, бо тіло, менше за крок поля висот, провалюється крізь рельєф.
  • Області, у яких тіло може перебувати одночасно: надлишок відхиляють під час деплою.
  • Частота перевірок на актора: обмеження частоти з терміном.
  • Тіла у відповіді на запит «хто в цій області»: список обрізають в оголошеному порядку, і прапорець обрізання обов’язковий.