Si verifica una collisione quando due oggetti 3D entrano in contatto nel Mondo3D. Per la gestione delle collisioni personalizzata, BasePart ha un set di eventi di collisione e filtri di collisione tecniche, in modo che tu possa controllare quali assemblaggi fisici si scontrano con gli altri.
Eventi di collisione
I 事件 di collisione avvengono quando due BaseParts toccano o smettono di toccare nel Mondo3D. Puoi rilevare queste collisioni attraverso i Touched e
- La proprietà CanTouch di una parte determina se attiva gli eventi di collisione. Se impostato su false , né Class.BasePart.Touched|Touched né 1> Class.BasePart.TouchEnded|TouchEnded1> Lanciaregli eventi di collisione.
- La proprietà CanCollide di una parte influenza se si scontrerà fisicamente con altre parti e causerà forze ad agire su di loro. Anche se CanCollide è disabilitato
- Gli eventi Touched e TouchEnded solo vengono attivati come risultato di un movimento fisico, non da un Class.BasePart.Position|Position o 1>Class.BasePart.CFrame|CFrame1> cambiamenti che causano l'
- La classe di livello superiore Terrain eredita da BasePart , quindi puoi assegnare un gruppo di collisione a 1> Class.Terrain per determinare se altri 4> Class.BasePart|BaseParts4> collidono con 7> Terrain7> voxels.
Toccato
L'evento Touched attiva quando un BasePart viene in contatto con un altro, o con un voxel terreno. Si attiva solo come risultato di 2>simulazione fisica
Il seguente modello di codice mostra come l'evento Touched può essere connesso a una funzione personalizzata onTouched() . Nota che l'evento invia l'argomento otherPart alla funzione, indicando la parte coinvolta nella collisione.
Collisioni parti
local part = workspace.Part
local function onTouched(otherPart)
print(part.Name .. " collided with " .. otherPart.Name)
end
part.Touched:Connect(onTouched)
Nota che l'evento Touched può attivarsi più volte in rapida successione in base a collisioni fisiche sottili, come quando un oggetto in movimento "setta" in una posizione di riposo o quando una collisione coinvolge un modello di multi-part . Per
Collisioni delle parti con il cooldown
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) -- Imposta l'attributo a vero
task.wait(COOLDOWN_TIME) -- Attendere la durata del cooldown
part:SetAttribute("Touched", false) -- Ripristina l'attributo
end
end
part.Touched:Connect(onTouched)
TouchEnded
L'evento TouchEnded attiva quando l'intera collisioni di un BasePart esce dalle limitazioni di un altro Class
Il seguente modello di codice mostra come l'evento TouchEnded può essere connesso a una funzione personalizzata onTouchEnded() . Come Class.BasePart.Touched|Touched , l'evento invia l'argomento 1> otherPart 1> alla funzione, indicando l'altra parte coinvolta.
Rilevamento della non collisione
local part = workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " is no longer touching " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)
Filtro di collisione
Il filtro di collisione include filtri che parti fisiche si scontrano con gli altri. Puoi configurare il filtro per numerosi oggetti attraverso gruppi di collisione o puoi controllare le collisioni su una base parte-per-parte con Class.NoCollisionConstraint istanze.
Gruppi di collisione
I gruppi di collisione ti consentono di assegnare Class.BasePart|BaseParts a gruppi dedicati e specificare se o no collidono con quelli in altri gruppi. Le parti all'interno dei gruppi non collidono completamente, anche se entrambe le parti hanno la loro proprietà BaseParts impostata su CanCollide .
Puoi facilmente impostare i gruppi di collisione attraverso il Editor dei gruppi di collisione di Studio, accessibile facendo clic sul pulsante Collisioni gruppi nella scheda Modello.
Le funzioni dell'editor in either Lista Visualizza which favors docking to the left or right side of Studio, or in a wider Visualizza Tavola which favors docking to the top or bottom.
Registrazione dei gruppi
L'editor include un gruppo di collisione Predefinito che non può essere rinominato o cancellato. Tutti BaseParts appartengono automaticamente a questo gruppo predefinito a meno che non siano assegnati a un altro Gruppo, il che significa che si scontreranno con tutti gli altri oggetti nel Gruppo Predefinito .
Per creare un nuovo Gruppodi collisioni:
Fai clic sul pulsante Aggiungi gruppo nella parte superiore del pannello dell'editor, inserisci un nuovo nome del gruppo e premi Inserisci . Il nuovo gruppo appare in entrambe le colonne della vista di lista, o nella colonna di sinistra e di nuovo nella riga superiore della vista di tabella.
Ripeti il processo se necessario, scegliendo un nome unico e descrittivo per ciascun Gruppo. Nota che puoi cambiare il nome di un Gruppodurante lo sviluppo facendo clic nel suo campo, o selezionandolo e facendo clic sul pulsante ripristina .
Configurazione delle collisioni di gruppo
Per impostazione predefinita, gli oggetti in tutti i gruppi collidono tra loro. Per prevenire che gli oggetti in un gruppo possano collidere con gli oggetti in un altro Gruppo, non selezionare la casella nella riga / colonna rispettiva.
Nell'esempio seguente, gli oggetti nel gruppo Cubi non si scontreranno con gli oggetti nel GruppoPorte.
Assegnare oggetti ai gruppi
Per assegnare oggetti ai gruppi che hai registrato attraverso il editor Studio:
Seleziona uno o più BaseParts che qualificano come parte di un gruppo di collisioni.
Assegnati al gruppo facendo clic sul pulsante ⊕ per la sua riga. Gli oggetti possono appartenere a un solo gruppo di collisione alla volta, quindi posizionarli in un nuovo gruppo li rimuove dal loro Gruppoattuale.
Una volta assegnato, il nuovo gruppo viene riflesso sotto la proprietà CollisionGroup Proprietà'oggetto.
Gruppo di collisione selezionabile
Gli strumenti in Studio utilizzano il sistema di filtro di collisione per determinare quali oggetti sono candidati per la selezione quando si fa clic nella finestra3D. Gli oggetti per cui il gruppo di collisione assegnato non si scontreranno con StudioSelectable saranno ignorati.
Ad esempio, se hai checkpoint in un'esperienza di corsa il cui area effettiva è definita da grandi parti trasparenti, puoi assegnarli a un gruppo di collisioni Checkpoint e quindi rendere quel gruppo non collidibile con StudioSelectable in modo che non si interrompa quando stai modificando la geometria di base.
Per il codice del plugin, si consiglia di assegnare "StudioSelectable" come filtro di gruppo di collisione della tua RaycastParams quando trovi parti sotto il cursore. Ciò consente ai tuoi plugin di corrispondere alle meccaniche di selezione che i creatori hanno imparato a aspettarsi dalle strumentazioni di Studio incorporate.
Reccomended Plugin Selection Raycast
local UserInputService = game:GetService("UserInputService")local raycastParams = RaycastParams.new()raycastParams.CollisionGroup = "StudioSelectable" -- Per seguire la convenzioneraycastParams.BruteForceAllSlow = true -- In modo che le parti con CanQuery di "false" possano essere selezionatelocal mouseLocation = UserInputService:GetMouseLocation()local mouseRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)local filteredSelectionHit = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)
Filtro parte-per-parte
Per prevenire le collisioni tra due parti specifiche senza impostare gruppi di collisione, come tra la ruota di un veicolo e il suo telaio, considera la VincoloNessuna collisione. Vantaggi include:
- I gruppi di collisione e/o gli script di configurazione non sono richiesti, so you can easily create and share models with customized collision filtering.
- Le parti connesse non si scontreranno tra loro, ma possono comunque scontrarsi con altri oggetti.
Disattivare le collisioni dei personaggi
I personaggi dei giocatori Roblox si scontrano tra loro per impostazione predefinita. Ciò può comportare un Partitainteressante ma non intenzionale, come i personaggi che saltano sopra l'un l'altro per raggiungere aree specifiche. Se questo comportamento non è desiderato, puoi prevenirlo attraverso il seguente Script in ServerScriptService.
Script - Disabilita collisioni personaggio
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)
local function onDescendantAdded(descendant)
-- Imposta il gruppo di collisione per qualsiasi parte DIscendente
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Characters"
end
end
local function onCharacterAdded(character)
-- Elabora i discendenti esistenti e nuovi per la fisica
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Rileva quando il personaggio del Giocatoreviene aggiunto
player.CharacterAdded:Connect(onCharacterAdded)
end)
Collisioni di modelli
Model oggetti sono container per parti piuttosto che ereditare da BasePart , quindi non possono connettersi direttamente a BasePart.Touched o
Il seguente codice di esempio connette tutti BaseParts di un modello multi-parte ai eventi di collisione e traccia il numero totale di collisioni con altre parti.
Collisioni di modelli
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Ignora le istanze del modello che intersecano con se stesso
if otherPart:IsDescendantOf(model) then return end
-- Aumenta il numero di parti del modello che toccano
numTouchingParts += 1
print(model.Name, "intersected with", otherPart.Name, "| Model parts touching:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Ignora le istanze del modello che non interseccionano con se stessi
if otherPart:IsDescendantOf(model) then return end
-- Riduci il numero di parti del modello che toccano
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
Collisioni mesh e solido
MeshPart e PartOperation (parti unite da modellazione solida ) sono sottoclassi di 0> Class.Base
La proprietà CollisionFidelity ha le seguenti opzioni, in ordine di fedeltà e impatto di prestazioni dal minimo all'altro:
- Box — Crea una Quadro di selezionedi collisione di contorno, ideale per oggetti piccoli o non interattivi.
- Hull — Genera una hull convenzionale, adatta per gli oggetti con meno marcature o cavità pronunciate.
- Predefinito — Produce una forma di collisione approssimativa che supporta la concavità, adatta per oggetti complessi con esigenze di interazione semi-dettagliate.
- PreciseConvexDecomposition — Offre la più elevata fedeltà ma non è ancora una rappresentazione 1:1 del visivo. Questa opzione ha il costo di performance più elevato e richiede più tempo per il motore per calcolare.
Per ulteriori informazioni sull'impatto sulle prestazioni delle opzioni di fedeltà di collisione e su come mitigarle, vedi ottimizzazione delle prestazioni . Per un'esperienza in dettaglio su come scegliere un'opzione di fedeltà di collisione che bilancia le tue esigenze di precisione e le richieste di prestazioni, vedi qui .