Bir çarpışma, iki 3D nesnenin 3D dünyada temas etmesiyle meydana gelir. Özelleştirilmiş çarpışma yönetimi için, BasePart bir dizi çarpışma olayı ve çarpışma filtreleme tekniği sunar, böylece hangi fiziksel bileşenlerin diğerleriyle çarpışacağını kontrol edebilirsiniz.
Çarpışma olayları
Çarpışma olayları, iki BaseParts nesnesinin 3D dünyada birbirine dokunduğunda veya dokunmayı bıraktığında meydana gelir. Bu çarpışmaları, Touched ve TouchEnded olayları aracılığıyla tespit edebilirsiniz; bu olaylar, her iki parçanın CanCollide özellik değerine bakılmaksızın meydana gelir. Parçalar üzerindeki çarpışma yönetimini düşünürken, aşağıdakileri dikkate alın:
- Bir parçanın CanTouch özelliği, çarpışma olaylarını tetikleyip tetiklemeyeceğini belirler. false olarak ayarlandığında, ne Touched ne de TouchEnded tetiklenir.
- Bir parçanın CanCollide özelliği, diğer parçalarla fiziksel olarak çarpışıp çarpışmayacağını etkiler ve onlara kuvvetlerin etki etmesine neden olur. CanCollide bir parça için devre dışı bırakılmış olsa bile, Touched ve TouchEnded olayları aracılığıyla dokunma ve dokunmama tespit edebilirsiniz.
- Touched ve TouchEnded olayları yalnızca fiziksel hareket sonucunda tetiklenir; bir parçanın başka bir parça ile kesişmesini veya kesişmeyi durdurmasını sağlayan Position veya CFrame değişikliklerinden kaynaklanmaz.
Touched
Touched olayı, bir BasePart başka bir nesneye veya bir Terrain voxel'ine temas ettiğinde tetiklenir. Bu olay yalnızca fiziksel simülasyon sonucunda tetiklenir ve parçanın Position veya CFrame değeri açıkça ayarlandığında, başka bir parça veya voxel ile kesiştiğinde tetiklenmez.
Aşağıdaki kod örneği, Touched olayının özel bir onTouched() fonksiyonuna nasıl bağlanabileceğini gösterir. Olay, çarpışmaya dahil olan diğer parçayı belirten otherPart argümanını fonksiyona gönderir.
local part = workspace.Part
local function onTouched(otherPart)
print(part.Name .. " ile çarpıştı " .. otherPart.Name)
end
part.Touched:Connect(onTouched)Touched olayının, hareket eden bir nesnenin "yerleştiği" bir pozisyona girmesi veya bir çarpışmanın çok parçalı model içermesi gibi ince fiziksel çarpışmalara bağlı olarak hızlı bir şekilde birden fazla kez tetiklenebileceğini unutmayın. Gereksiz yere daha fazla Touched olayı tetiklememek için, bir örnek özellik aracılığıyla bir "soğuma" süresi uygulayan basit bir debounce sistemi uygulayabilirsiniz.
local part = workspace.Part
local COOLDOWN_TIME = 1
local function onTouched(otherPart)
if not part:GetAttribute("Touched") then
print(part.Name .. " ile çarpıştı " .. otherPart.Name)
part:SetAttribute("Touched", true) -- Özelliği true olarak ayarla
task.wait(COOLDOWN_TIME) -- Soğuma süresi için bekle
part:SetAttribute("Touched", false) -- Özelliği sıfırla
end
end
part.Touched:Connect(onTouched)TouchEnded
TouchEnded olayı, bir BasePart'ın tüm çarpışma sınırlarının başka bir BasePart veya dolu bir Terrain voxel'inin sınırlarını terk ettiğinde tetiklenir. Bu olay yalnızca fiziksel simülasyon sonucunda tetiklenir ve parçanın Position veya CFrame değeri açıkça ayarlandığında, başka bir parça veya voxel ile kesişmeyi durdurduğunda tetiklenmez.
Aşağıdaki kod örneği, TouchEnded olayının özel bir onTouchEnded() fonksiyonuna nasıl bağlanabileceğini gösterir. Touched gibi, olay otherPart argümanını fonksiyona gönderir ve çarpışmaya dahil olan diğer parçayı belirtir.
local part = workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " artık " .. otherPart.Name ile temas etmiyor)
end
part.TouchEnded:Connect(onTouchEnded)Çarpışma özetleri
Touched, bir çarpışmanın olduğunu söyler, ancak nerede olduğunu, hangi yönden geldiğini veya ne kadar sert olduğunu belirtmez. Fizik motorundan ayrıntılı temas verileri almak için, bir parçanın üzerinde BindToCollisionSummaries() çağrısı yapın. Bu, bir geri çağırma alır ve verileri artık ihtiyaç duymadığınızda bağlantıyı kesebileceğiniz bir RBXScriptConnection döndürür. Bu, Touched'dan ayrı bir API'dir, bu nedenle onu Touched işleyicisinden çağırmayın.
Geri çağırma, fizik adımı tamamlandıktan sonra her karede bir kez çalışır. O, o çerçevede parçanın dahil olduğu her çarpışmanın bir özetini içeren bir tablo alır. Her özet, abone olunan parça ile diğer parça arasındaki bir temas alanını tanımlar. Özetler dondurulmuştur ve değiştirilemez. Her birinin şu alanları vardır:
| Alan | Tür | Açıklama |
|---|---|---|
| Time | number | Alt adımın simülasyon zamanı. |
| Part0 | BasePart | Abone olunan parça. |
| Part1 | BasePart | Çiftteki diğer parça. |
| Point | Vector3 | Temas noktası, dünya alanında ortalama. |
| Normal | Vector3 | Birim normal. Her zaman Part0'dan uzaklaşır. |
| RelativeVelocity | Vector3 | Temas noktasındaki Part1'in Part0'a göre hızı, çarpışma çözülmeden önce ölçülür. |
| Area | number | Temas alanının tahmini alanı. |
Baş başa çarpışma hızını almak için, RelativeVelocity ve Normal'ın nokta çarpımını alın. Kayma çarpmalarını veya kaymaları tespit etmek için, RelativeVelocity'nin yatay bileşenini kullanın. Bir kuvvet değerine daha yakın bir değer istiyorsanız, hızı parçaların AssemblyMass ile birleştirin.
local part = workspace.Part
local function onCollision(summaries)
for _, summary in summaries do
local impactSpeed = summary.RelativeVelocity:Dot(summary.Normal)
if impactSpeed > 10 then
print("Sert darbe", summary.Point, "hızıyla", impactSpeed)
end
end
end
local connection = part:BindToCollisionSummaries(onCollision)
-- Daha sonra, özetlere artık ihtiyaç duymadığınızda
connection:Disconnect()Çarpışma özetlerini kullanırken aşağıdakileri aklınızda bulundurun:
- Özetler, fizik simülasyonunu yürüten ağ sahibi üzerinde yalnızca üretilir; bu, bir istemci veya sunucu olabilir. Bunlar çoğaltılmaz. Diğer istemcilerin bir çarpışma hakkında bilgi alması gerekiyorsa, özeti işleyin ve yalnızca ihtiyaç duydukları verileri kendi uzaktan olay aracılığıyla gönderin.
- CanCollide özelliği false olarak ayarlanmış parçalar çarpışma özetleri üretmez.
- Karmaşık, içe doğru olmayan parçalar, aynı parça çiftleri için birden fazla özet üretebilir.
- İki uyku halindeki parça arasındaki temaslar kaydedilmez.
- İşleme maliyeti, abone olunan parçaların sayısıyla artar, yerin toplam çarpışma sayısıyla değil.
Çarpışma filtreleme
Çarpışma filtreleme, hangi fiziksel parçaların diğerleriyle çarpışacağını tanımlar. Birçok nesne için filtrelemeyi çarpışma grupları aracılığıyla yapılandırabilir veya NoCollisionConstraint örnekleri ile parça-parça bazında çarpışmaları kontrol edebilirsiniz.
Çarpışma grupları
Çarpışma grupları, BaseParts'ı özel gruplara atamanıza ve bunların diğer gruplardaki nesnelerle çarpışıp çarpışmayacağını belirtmenize olanak tanır. Çarpışma grubu olmayan gruplardaki parçalar, her iki parçanın da CanCollide özelliği true olarak ayarlanmış olsa bile birbirlerinin içinden tamamen geçer. Çarpışma grupları, Workspace veya WorldModel bazında oluşturulur ve yapılandırılır.
Çarpışma gruplarını kolayca ayarlamak için, Studio'nun Çarpışma Grupları editörünü kullanabilirsiniz; bu editöre Studio'nun Pencere ⟩ 3D menüsünden erişebilirsiniz.
Grupları kaydet
Workspace, kendi yapılandırılabilir çarpışma gruplarının durumunu saklar. Ayrıca, herhangi bir WorldModel, sorgular için kendi çarpışma gruplarını kullanmayı seçebilir.
Editör, yeniden adlandırılamayan veya silinemeyen bir Varsayılan çarpışma grubu içerir. Tüm BaseParts, başka bir gruba atanmadıkça otomatik olarak bu varsayılan gruba aittir; bu, onların Varsayılan gruptaki diğer tüm nesnelerle çarpışacağı anlamına gelir.
Yeni bir çarpışma grubu oluşturmak için:
Varsayılan olarak, gruplar Workspace üzerinde kaydedilir, ancak yerinizde en az bir WorldModel varsa, çarpışma grupları editörünün üst kısmında bir seçim açılır menüsü görünecektir. Bu açılır menüyü kullanarak farklı WorldModel örnekleri arasında çarpışma gruplarını yapılandırabilirsiniz.

Herhangi bir WorldModel için, sorguları için Workspace çarpışma gruplarını kullanmasını sağlamak üzere Workspace çarpışma gruplarını kullan seçeneğini etkinleştirebilirsiniz.

Editör panelinin üst kısmındaki Grup Ekle butonuna tıklayın, yeni bir grup adı girin ve Enter tuşuna basın. Yeni grup, hem liste görünümündeki hem de tablo görünümündeki her iki sütunda görünür.

Gerekirse, her grup için benzersiz ve açıklayıcı bir ad seçerek işlemi tekrarlayın. Geliştirme sırasında bir grubun adını değiştirebileceğinizi unutmayın; bunun için alanına tıklayabilir veya seçip yeniden adlandır butonuna tıklayabilirsiniz.

Grup çarpışmalarını yapılandır
Varsayılan yapılandırma altında, tüm gruplardaki nesneler birbirleriyle çarpışır. Bir gruptaki nesnelerin diğer bir gruptaki nesnelerle çarpışmasını önlemek için, ilgili satır/sütundaki kutuyu işaretlemeyin.
Aşağıdaki örnekte, Küpler grubundaki nesneler Kapılar grubundaki nesnelerle çarpışmayacaktır.

Nesneleri gruplara atama
Kayıtlı olduğunuz gruplara nesneleri atamak için Studio editörü aracılığıyla:
Bir çarpışma grubunun parçası olarak nitelendirilen bir veya daha fazla BaseParts seçin.
Seçilen parçaları, ilgili satır için ⊕ butonuna tıklayarak gruba atayın. Nesneler yalnızca bir çarpışma grubuna ait olabilir, bu nedenle yeni bir gruba yerleştirildiğinde mevcut gruptan çıkarılır.

Atandıktan sonra, yeni grup nesnenin CollisionGroup özelliği altında yansıtılır.

StudioSelectable grubu
Studio'daki araçlar, 3D görünümde tıklanırken hangi nesnelerin seçim için aday olduğunu belirlemek için çarpışma filtreleme sistemini kullanır. Atanan çarpışma grubu StudioSelectable ile çarpışmayan nesneler göz ardı edilir.
Örneğin, bir yarış oyununda etkili alanları büyük şeffaf parçalarla tanımlanan kontrol noktalarınız varsa, bunları Kontrol Noktaları çarpışma grubuna atayabilir ve ardından bu grubu StudioSelectable ile çarpışmaz hale getirerek, altındaki harita geometrisini düzenlerken engel olmalarını önleyebilirsiniz.

Eklenti kodu için, parçaları imlecin altında bulmak için RaycastParams'ınızın çarpışma grubu filtresi olarak "StudioSelectable" atamanız önerilir. Bu, eklentilerinizin, yaratıcıların yerleşik Studio araçlarından beklediği seçim mekaniklerini eşleştirmesine olanak tanır.
local UserInputService = game:GetService("UserInputService")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- Konvansiyonu takip etmek için
raycastParams.BruteForceAllSlow = true -- "false" olan CanQuery'ye sahip parçaların seçilebilmesi için
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)Parça-parça filtreleme
İki belirli parça arasında çarpışmaları önlemek için, çarpışma grupları kurmadan, örneğin bir aracın tekerleği ile şasisinin çarpışmasını önlemek için No Collision kısıtlamasını düşünebilirsiniz. Avantajları şunlardır:
- Çarpışma grupları ve/veya yapılandırma scriptleri gerektirmediğinden, özelleştirilmiş çarpışma filtrelemesi ile kolayca model oluşturabilir ve paylaşabilirsiniz.
- Bağlı parçalar birbirleriyle çarpışmaz, ancak diğer nesnelerle çarpışabilirler.
Karakter çarpışmalarını devre dışı bırakma
Roblox oyuncu karakterleri varsayılan olarak birbirleriyle çarpışır. Bu, karakterlerin belirli alanlara ulaşmak için birbirlerinin üstüne zıplaması gibi ilginç ama istenmeyen bir oyun deneyimi yaratabilir. Bu davranış istenmiyorsa, aşağıdaki Script aracılığıyla bunu önleyebilirsiniz.
local Players = game:GetService("Players")
workspace:RegisterCollisionGroup("Karakterler")
workspace:CollisionGroupSetCollidable("Karakterler", "Karakterler", false)
local function onDescendantAdded(descendant)
-- Herhangi bir parça alt nesnesi için çarpışma grubunu ayarla
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Karakterler"
end
end
local function onCharacterAdded(character)
-- Fizik ayarları için mevcut ve yeni alt nesneleri işleyin
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- Oyuncunun karakterinin eklendiğini tespit et
player.CharacterAdded:Connect(onCharacterAdded)
end)Model çarpışmaları
Model nesneleri parçaların konteynerleridir ve BasePart'tan türetilmezler, bu nedenle doğrudan BasePart.Touched veya BasePart.TouchEnded olaylarına bağlanamazlar. Bir modelin çarpışma olaylarını tetkip etmesini belirlemek için, çocuklarını döngüye almanız ve her bir çocuk BasePart için özel onTouched() ve onTouchEnded() fonksiyonlarını bağlamanız gerekir.
Aşağıdaki kod örneği, çok parçalı bir modelin tüm BaseParts'ını çarpışma olaylarına bağlar ve diğer parçalarla toplam çarpışma sayısını takip eder.
local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- Modelin kendisiyle kesişen örnekleri göz ardı et
if otherPart:IsDescendantOf(model) then return end
-- Model parçalarının dokunma sayısını artır
numTouchingParts += 1
print(model.Name, "ile kesişti", otherPart.Name, "| Model parçaları dokunuyor:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- Modelin kendisiyle kesişmeyen örnekleri göz ardı et
if otherPart:IsDescendantOf(model) then return end
-- Model parçalarının dokunma sayısını azalt
numTouchingParts -= 1
print(model.Name, "ile kesişmeyi bıraktı", otherPart.Name, "| Model parçaları dokunuyor:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
endMesh ve katı model çarpışmaları
MeshPart ve PartOperation (katı modelleme ile birleştirilmiş parçalar) BasePart'ın alt sınıflarıdır, bu nedenle mesh ve katı model parçaları, normal parçalarla aynı çarpışma olayları ve çarpışma filtreleme seçeneklerini miras alır. Ancak, mesh ve katı model parçaları genellikle daha karmaşık geometrilere sahip olduğundan, çarpışma yönetimi için fiziksel sınırların görsel temsille ne kadar hassas bir şekilde hizalandığını belirleyen belirgin bir CollisionFidelity özelliğine sahiptir.
CollisionFidelity özelliği, en düşükten en yükseğe doğru performans etkisi ve hassasiyet sırasına göre aşağıdaki seçeneklere sahiptir:
- Kutu — Küçük veya etkileşimli olmayan nesneler için ideal olan bir sınırlayıcı çarpışma kutusu oluşturur.
- Kapsül — Daha az belirgin girintilere veya boşluklara sahip nesneler için uygun olan bir konveks kapsül oluşturur.
- Varsayılan — karmaşık nesneler için yarı detaylı etkileşim ihtiyaçlarını destekleyen yaklaşık bir çarpışma şekli üretir.
- Hassas Konveks Ayrıştırma — En hassas fideliteyi sunar, ancak yine de görselin 1:1 temsili değildir. Bu seçenek, en pahalı performans maliyetine sahiptir ve motorun hesaplaması daha uzun sürer.

Çarpışma fidelitesi seçeneklerinin performans etkisi ve bunları nasıl azaltacağınız hakkında daha fazla bilgi için, performans optimizasyonu bölümüne bakın.