Kolizje

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

Kolizja występuje, gdy dwa obiekty 3D wchodzą w kontakt w świecie 3D.Aby dostosować obsługę kolizji, BasePart ma zestaw zdarzeń kolizyjnych i technik filtrowania kolizji, więc możesz kontrolować, które fizyczne zespoły kolizują z innymi.

Wydarzenia kolizyjne

Wydarzenia kolizyjne wystąpią, gdy dwa dotkną się lub przestaną się dotykać w świecie 3D.Możesz wykryć te kolizje za pomocą wydarzeń Touched i TouchEnded, które występują niezależnie od wartości właściwości każdej z części CanCollide.Rozważając obsługę kolizji na częściach, zauważ obserwujekwestie:

  • Własność części CanTouch określa, czy uruchamia zdarzenia kolizyjne. Jeśli jest ustawiona na false, żadne z nich nie zostanie uruchomione: ani Touched, ani TouchEnded.
  • Własność części CanCollide wpływa na to, czy będzie fizycznie kolizować z innymi częściami i powodować, że siły będą działać na nich.Nawet jeśli CanCollide jest wyłączone dla części, możesz wykrywać dotyk i nie dotyk poprzez wydarzenia Touched i TouchEnded.
  • Wydarzenia Touched i TouchEnded wystrzelają tylko w wyniku ruchu fizycznego physycznego , nie z powodu zmian Position lub CFrame, które powodują, że część styka się lub przestaje stykać z inną częścią.
  • Klasa najwyższego poziomu Terrain dziedziczy od BasePart, więc możesz przypisać grupę kolizji do Terrain, aby określić, czy inne BaseParts wokse zderzają się z terenem.

Dotknięty

Wydarzenie Touched występuje, gdy BasePart wchodzi w kontakt z innym, lub z woxelem Terenem.Wypala się tylko w wyniku symulacji fizycznej i nie będzie strzelać, gdy część Position lub CFrame jest wyraźnie ustawiona tak, że nakłada się na inną część lub woxel.

Poniższy wzór kodu pokazuje, jak wydarzenie Touched może być połączone z niestandardową funkcją onTouched().Zauważ, że wydarzenie wysyła argument otherPart do funkcji, wskazujący na pozostałą część zaangażowaną w kolizję.

Kolizja części

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. " collided with " .. otherPart.Name)
end
part.Touched:Connect(onTouched)

Zauważ, że wydarzenie Touched może wystrzelić wielokrotnie w szybkiej kolejności w oparciu o subtelne kolizje fizyczne, takie jak gdy poruszający się obiekt "uzyska" pozycję spoczną lub gdy kolizja obejmuje wielość modeli wieloczęściowych.Aby uniknąć uruchamiania więcej zdarzeń Touched niż to konieczne, możesz wdrożyć prosty system debounce, który egzekwuje okres "odpoczynku" za pośrednictwem atrybutu instancji.

Kolizja części z czasem odnowienia

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local COOLDOWN_TIME = 1
local function onTouched(otherPart)
if not part:GetAttribute("Touched") then
print(part.Name .. " collided with " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Ustaw atrybut na prawdę
task.wait(COOLDOWN_TIME) -- Poczekaj na czas odnowienia
part:SetAttribute("Touched", false) -- Zresetuj atrybut
end
end
part.Touched:Connect(onTouched)

Skończone dotknięcie

Wydarzenie TouchEnded wystrzeliwuje się, gdy całe obszary kolizji z BasePart wychodzą poza granice innego BasePart lub wypełnionego Terrain voxela.Wypala się tylko w wyniku symulacji fizycznej i nie będzie strzelać, gdy część Position lub CFrame zostanie wyraźnie ustawiona tak, że przestanie się przecinać z inną częścią lub woxelem.

Poniższy wzór kodu pokazuje, jak wydarzenie TouchEnded może być połączone z niestandardową funkcją onTouchEnded().Podobnie jak Touched , wydarzenie wysyła argument otherPart do funkcji, wskazując na pozostałą część zaangażowaną.

Niekolizyjna detekcja

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " is no longer touching " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)

Filtracja kolizji

Filtracja kolizji definiuje , które fizyczne części kolizują z innymi.Możesz skonfigurować filtrowanie dla wielu obiektów za pomocą grup kolizyjnych lub możesz kontrolować kolizje na podstawie części do części z instancjami.

Grupy kolizyjne

Kolizja grup pozwala przypisać BaseParts do dedykowanych grup i określić, czy kolizują one z tymi w innych grupach, czy nie.Części w grupach niekolidujących przechodzą jedna za drugą całkowicie, nawet jeśli obie części mają ustawioną właściwość CanCollide wartość true.

W powyższym wideo obracające się obiekty znajdują się w różnych grupach kolizyjnych, tak że zderzają się z obiektami innego koloru, ale nie z obiektami własnego koloru

Możesz łatwo skonfigurować grupy kolizyjne za pomocą edytora grup kolizyjnych w Studio , dostępnego poprzez kliknięcie przycisku Grupy kolizyjne w zakładce Model w pasku narzędzi.

Collision Groups tool indicated in Model tab of Studio

Edytor funkcjonuje w trybie widoku listy , który sprzyja dokowaniu na lewo lub prawo w Studio, lub w szerszym widoku tabeli , który sprzyja dokowaniu na górze lub na dole.

List View example in Collision Groups Editor

Rejestruj grupy

Edytor zawiera jedną domyślną grupę kolizji Domyślna , której nie można zmienić ani usunąć.Wszystkie BaseParts automatycznie należą do tej domyślnej grupy, chyba że zostały przypisane do innej grupa, co oznacza, że będą się zderzać ze wszystkimi innymi obiektami w grupa Domyślna .

Aby utworzyć nową grupakolizji:

  1. Kliknij przycisk Dodaj grupę na górze panelu edytora, wprowadź nową nazwę grupy i naciśnij Enter.Nowa grupa pojawia się w obu kolumnach widoku listy lub w obu lewej kolumnie i górnej linii widoku tabeli.

    New group added to Collision Groups Editor in List View
  2. Powtórz proces, jeśli to konieczne, wybierając unikalną i opisową nazwę dla każdej grupa.Zauważ, że możesz zmienić nazwę grupapodczas rozwoju, klikając w jej pole, lub wybierając ją i klikając przycisk zmiana nazwy .

    Button and field indicated for renaming a group in the Collision Groups Editor

Konfiguruj kolizje grup

W ramach domyślnej konfiguracji obiekty we wszystkich grupach zderzają się ze sobą.Aby zapobiec kolizji obiektów w jednej grupie z obiektami w innej grupie, odznacz pudełko w odpowiedniej linii/kolumnie.

W następnym przykładzie obiekty w grupie Kostki nie będą się nie zderzać z obiektami w grupa Drzwi .

Group configured in List View of Collision Groups Editor

Nadaj obiekty do grup

Aby przypisać obiekty do grup, które zarejestrowałeś przez edytor Studio:

  1. Wybierz jedną lub więcej BaseParts, które kwalifikują się jako część grupakolizyjnej.

  2. Nadaj im grupę, klikając przycisk dla jej wiersza.Obiekty mogą należeć tylko do jednej grupy kolizyjnej na raz, więc umieszczenie ich w nowej grupie usuwa je z ich obecnej grupa.

    Plus button indicated in Collision Groups Editor for adding selected parts to a group

Po przypisaniu nowa grupa jest odzwierciedlona w właściwości CollisionGroup obiektu.

Chosen collision group indicated as the part's CollisionGroup property

grupakolizji StudioSelectable

Narzędzia w Studio wykorzystują system filtrowania kolizji, aby określić, które obiekty są kandydatami do wyboru, gdy klikniesz w widok 3D.Obiekty, których przypisana grupa kolizji nie nie zderza się z StudioSelectable , zostaną ignorowane.

Na przykład, jeśli masz punkty kontrolne w doświadczeniu wyścigowym, których skuteczne obszary są zdefiniowane przez duże przezroczyste części, możesz przypisać je do grupy kolizji Punkty kontrolne , a następnie uczynić ją niezderzalną z StudioSelectable , aby nie przeszkadzały podczas edytowania podstawowej geometrii mapy.

Checkpoints group configured to be non-collidable with StudioSelectable group

W przypadku kodu pluginów zaleca się, abyś przypisał "StudioSelectable" jako filtr grupy kolizji swoich RaycastParams części podczas wyszukiwania części za pomocą kurora.Umożliwia twoim pluginom dopasowanie mechaniki selekcji, której twórcy nauczyli się oczekiwać od wbudowanych narzędzi Studio.

Zalecany wybór wiązki pluginów Raycast

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Aby przestrzegać konwencji
raycastParams.BruteForceAllSlow = true -- Aby wybrać części z CanQuery "false",
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)

Filtracja od strony do strony

Aby zapobiec kolizjom między dwoma określonymi częściami bez ustawienia grup kolizyjnych, takich jak między kołem pojazdu a jego podwoziem, rozważ ograniczenie Brak kolizji.Zalety obejmują:

  • Nie są wymagane grupy kolizji i/lub skrypty konfiguracyjne, więc łatwo możesz tworzyć i dzielić modele z niestandardowym filtrowaniem kolizji.
  • Połączone części nie będą się ze sobą kolidować, ale nadal mogą kolidować z innymi obiektami.

Wyłącz kolizje postaci

Postacie graczy Roblox kolizują ze sobą domyślnie.Może to doprowadzić do interesującej, ale niezamierzonej rozgrywka, takiej jak skakanie postaci na siebie nawzajem, aby dotrzeć do konkretnych obszarów.Jeśli to zachowanie jest niepożądane, możesz go uniknąć poprzez następujące Script w ServerScriptService.

Skrypt - Wyłącz kolizje postaci

local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
local CollisionGroupName = "Characters"
PhysicsService:RegisterCollisionGroup(CollisionGroupName)
PhysicsService:CollisionGroupSetCollidable(CollisionGroupName, CollisionGroupName, false)
local function setCollisionGroup(model)
-- Zastosuj grupę kolizji do wszystkich istniejących części w modelu
for _, descendant in model:GetDescendants() do
if descendant:IsA("BasePart") then
descendant.CollisionGroup = CollisionGroupName
end
end
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
setCollisionGroup(character)
end)
-- Jeśli gracz ma już postać, zastosuj grupę kolizji natychmiast
if player.Character then
setCollisionGroup(player.Character)
end
end)

Kolizje modeli

Model obiekty są kontenerami dla części, a nie dziedziczą od BasePart, więc nie mogą bezpośrednio połączyć się z wydarzeniami BasePart.Touched lub BasePart.TouchEnded.Aby określić, czy model uruchamia zdarzenia kolizyjne, musisz przeszukiwać jego dzieci i połączyć niestandardowe funkcje onTouched() i onTouchEnded() z każdym dzieckiem BasePart.

Poniższy przykład kodu połącza cały BaseParts model wieloczęściowy z wydarzeniami kolizyjnymi i śledzi ogólną liczbę kolizji z innymi częściami.

Kolizja modelu

local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignoruj instancje modelu, które się z sobą przecinają
if otherPart:IsDescendantOf(model) then return end
-- Zwiększ liczbę części modelu, które się dotykają
numTouchingParts += 1
print(model.Name, "intersected with", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignoruj instancje modelu, które nie przecinają się z samym sobą
if otherPart:IsDescendantOf(model) then return end
-- Zmniejsz liczbę części modelu, które się stykają
numTouchingParts -= 1
print(model.Name, "un-intersected from", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
end

Kolizje modeli siatkowych i stałych

MeshPart i PartOperation (części połączone za pomocą modelowania solidnego ) są podklasami BasePart , więc siatki i części modelowane solidem dziedziczą te same opcje kolizji i filtrowania kolizji niż zwykłe części.Jednak ponieważ siatki i części modelowane solidami zwykle mają bardziej skomplikowane geometrie, mają wyjątkową właściwość CollisionFidelity, która określa, w jaki sposób dokładnie granice fizyczne zgadzają się z wizualną reprezentacją do celów obsługi kolizji.

Właściwość CollisionFidelity ma następujące opcje, w kolejności zgodności i wpływu na wydajność od najniższej do najwyższej:

  • Pudełko — tworzy pudełko kolizyjne, idealne dla małych lub nieinteraktywnych obiektów.
  • Kadłub — Generuje konkawkowy kadłub, odpowiedni do obiektów z mniej wyraźnymi wgłębieniami lub przestrzeniami.
  • Domyślny — Wytwarza przybliżoną kształt kolizji, który wspiera wklęsłość, odpowiedni dla skomplikowanych obiektów z półszczegółowymi potrzebami interakcji.
  • Dokładna dekompozycja konweksowa — Oferuje najwyższą precyzję, ale nadal nie jest 1:1 reprezentacją wizualnąTa opcja ma najwyższy koszt wydajności i wymaga więcej czasu na obliczenie dla silnika.
Original mesh of castle tower

Aby uzyskać więcej informacji na temat wpływu na wydajność opcji wierności kolizji i sposobów ich złagodzenia, zobacz optymalizację wydajności.