# GM:ShouldCollide

- **Ortam:** İstemci, Sunucu
- **İngilizce aslı:** https://wiki.facepunch.com/gmod/GM:ShouldCollide
- **Çeviri tarihi:** 2025-09-08

```lua
boolean GM:ShouldCollide( Entity ent1, Entity ent2 )
```

> **NOT:** Bu hook [tahmin edilir](https://gmod.tr/wiki/Prediction) (predicted). Bu, tek oyunculu modda, İstemci (Client) alanında **çağrılmayacağı** anlamına gelir.

## Açıklama

Bir çift varlığın (entity) birbiriyle çarpışıp çarpışmayacağına karar vermek için çağrılır. Bu, yalnızca bir veya her iki varlıkta [Entity:SetCustomCollisionCheck](https://gmod.tr/wiki/Entity:SetCustomCollisionCheck) kullanıldıysa çağrılır.

Uygulanabilir olduğu durumlarda, bunun yerine [constraint.NoCollide](https://gmod.tr/wiki/constraint.NoCollide) veya bir [logic_collision_pair](https://developer.valvesoftware.com/wiki/Logic_collision_pair) varlığı kullanmayı düşünün - bunların kullanımı oldukça daha kolaydır ve bazı durumlarda daha uygun olabilir.

> **UYARI:** Bu hook, aynı varlık çifti için **mutlaka** tutarlı bir şekilde aynı değeri döndürmelidir.
> Bir varlığın çarpışma kurallarını değiştirecek şekilde değişmesi durumunda, o varlık üzerinde derhal [Entity:CollisionRulesChanged](https://gmod.tr/wiki/Entity:CollisionRulesChanged) fonksiyonunu çağırmalısınız - **bu hook içinde ve fizik geri çağrımlarında (physics callbacks) değil.**
> Örneklerle belirlenen kurallara harfiyen uyduğunuz sürece bu hook, bozulmadan güvenilir bir şekilde çalışacaktır, küçük bir hata bile fiziği bozabilir.

> **HATA:** Bu hook, belirli koşullar altında tüm fiziklerin bozulmasına neden olabilir.
> Hata Takipçisi: [642](https://github.com/Facepunch/garrysmod-issues/issues/642)

## Argümanlar

1. [Entity](https://gmod.tr/wiki/Entity) **ent1**: Çarpışma sorgusundaki ilk varlık.
2. [Entity](https://gmod.tr/wiki/Entity) **ent2**: Çarpışma sorgusundaki ikinci varlık.

## Döndürülen Değerler

1. [boolean](https://gmod.tr/wiki/boolean): Varlıkların çarpışıp çarpışmayacağı.

### Örnek

Oyuncuların birbiriyle çarpışmadığı basit bir örnek.

```lua
hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
	-- Eğer her iki varlık da oyuncu ise çarpışmaları devre dışı bırak!
	if ( ent1:IsPlayer() and ent2:IsPlayer() ) then return false end
end )
```

### Örnek

En iyi uygulama olarak, bu hook için mümkün olduğunca önbelleğe alınmış değerlerin kullanılması önerilir. Bu hook'un içinde herhangi bir hesaplama yapmak hem son derece maliyetlidir hem de aynı varlık çifti için dönüş değerindeki bir değişiklik için [Entity:CollisionRulesChanged](https://gmod.tr/wiki/Entity:CollisionRulesChanged) fonksiyonunu çağırmama riskini taşır.

```lua
hook.Add( "PlayerInitialSpawn", "SetCustomCollisions", function( ply )
	ply:SetCustomCollisionCheck( true )
end )

-- Çok kötü!!!!!
-- Bir oyuncunun canının azalacağını önceden bilmenin garantili bir yolu yoktur,
-- Source Engine'deki bir değişiklik Lua API'sine ulaştığında, ShouldCollide'ı geçmek için muhtemelen çok geçtir.
hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
	-- Eğer varlıklar oyuncuysa ve her ikisinin de canı 50'nin altındaysa çarpışmaları devre dışı bırak!
	if ( ent1:IsPlayer() and ent2:IsPlayer() ) and ( ent1:Health() < 50 and ent2:Health() < 50 ) then return false end
end )

-- İyi!!!!
-- Çarpışma olmaması için yeterince düşük cana sahip olduklarında oyuncular üzerinde ayarladığımız özel bir değişkeni kontrol ediyoruz,
-- bunun üzerinde tam kontrole sahibiz ve doğru anda CollisionRulesChanged'ı çağırabiliriz.

-- Bunun paylaşılan (shared) kodda olduğundan emin olun, aksi takdirde süngerimsi (spongy) fiziklerle karşılaşırsınız!
hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
	-- Eğer varlıklar düşük can modundaysa çarpışmaları devre dışı bırak!
	if ( ent1:IsPlayer() and ent2:IsPlayer() ) and ( ent1:GetLowHealthMode() and ent2:GetLowHealthMode() ) then return false end
end )

-- Yine de, hook'u eklemeden önce aşağıdaki kodun çalıştığından emin olun, hata oluşturmak istemeyiz!

-- DT değişkenimiz için bir isim oluşturun, oyuncular SetupDataTables'ı desteklemediği için bunu manuel olarak yapmalıyız.
DT_PLAYER_BOOL_LOWHEALTHMODE = 0

local meta = FindMetaTable( "Player" )
function meta:GetLowHealthMode()
	return self:GetDTBool( DT_PLAYER_BOOL_LOWHEALTHMODE )
end

function meta:SetLowHealthMode( enabled )
	self:SetDTBool( DT_PLAYER_BOOL_LOWHEALTHMODE, enabled )

	-- Çarpışmalarla ilgili bir şeyi değiştirdik, şimdi CollisionRulesChanged'ı çağırmalıyız!
	self:CollisionRulesChanged()
end

-- Artık oyuncularımızda fiziği bozmadan SetLowHealthMode'u çağırabiliriz!
```

### Örnek

[Entity:SetCustomCollisionCheck](https://gmod.tr/wiki/Entity:SetCustomCollisionCheck) çağrılmadan önce, bir ShouldCollide dönüşünü kontrol eden koşullar her zaman ayarlanmalıdır. Bunun yapılmaması, başlangıç değeri atanmamış değerlerin birkaç kare boyunca farklı olması ve dönüş değerini etkilemesi nedeniyle fiziğin bozulmasına neden olacaktır.

```lua
hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
	-- Eğer varlık talep ederse hiçbir şeyle çarpışma
	if ( ent1.DontCollideWithAnything or ent2.DontCollideWithAnything ) then return false end
end )

-- Aşağıda, bu hatayı çoğu zaman yaptığınız yer olan bir varlığın Initialize fonksiyonu bulunmaktadır.

-- Kötü! SetCustomCollisionCheck'i çağırdığımız anda çalışacak, bunu birkaç kare boyunca nil olarak alacak ve bu da ShouldCollide'ımızda false olarak yorumlanacaktır
-- Bu nedenle tutarsız olacak ve fiziği bozacaktır.
function ENT:Initialize()
	self:SetCustomCollisionCheck( true )
	self.DontCollideWithAnything = true
end

-- İyi! önce değişkenlerimizi ayarlıyoruz ve sonra SetCustomCollisionCheck'i etkinleştiriyoruz
function ENT:Initialize()
	self.DontCollideWithAnything = true
	self:SetCustomCollisionCheck( true )
end
```

### Örnek

Bir çift varlık için her zaman aynı değeri döndürmelisiniz, bu yüzden argümanların sırasına bakılmaksızın onları aynı şekilde kontrol etmelisiniz

```lua
-- Kötü! değişkeni sadece ent1 üzerinde kontrol ediyoruz, eğer ent2 olarak görünürse fiziğimiz bozulur çünkü tutarlı değiliz!
hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
    -- Eğer varlık talep ederse hiçbir şeyle çarpışma
    if ( ent1.DontCollideWithAnything ) then return false end
end )

-- İyi! şeyleri hangi sırada göründüklerine bakılmaksızın kontrol ediyoruz!
hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
    -- Eğer varlık talep ederse hiçbir şeyle çarpışma
    if ( ent1.DontCollideWithAnything or ent2.DontCollideWithAnything ) then return false end
end )
```

### Örnek

Bu hook'u birden fazla kez eklemekten kaçının, çalıştırılması son derece maliyetlidir. Bunun yerine, gerektiğinde çarpışmaları devre dışı bırakmak için varlıklara bir fonksiyon verdiğiniz ters bir desen kullanabilirsiniz, bu da çok sayıda hook eklemekten kaçınmanızı sağlar.

```lua
-- Sunucunuzu durma noktasına getirecek bir sürü hook eklemekten kaçınmak için Entity:ShouldNotCollide kontrolleri yapın.
-- Bunun tek doğruluk kaynağınız olmasını sağlamak için bu, GM varyantı olarak atanır.
function GM:ShouldCollide( enta, entb )

    local snca = enta.ShouldNotCollide
    if snca and snca( enta, entb ) then return ( false ) end

    local sncb = entb.ShouldNotCollide
    if sncb and sncb( entb, enta ) then return ( false ) end

    return ( true )
end

-- Bu artık varlık dosyalarında, oyuncu metatable'ında veya varlık metatable'ında çarpışmaların ne zaman devre dışı bırakılacağını tanımlamak için kullanılabilir.
-- Burada kullanılan koşullar, dışındaki koddan değiştirilmelidir, yani ShouldCollide'ın aynı kısıtlamaları burada da geçerlidir,
-- dönüş değerini etkileyen bir şeyi değiştirdiğinizde, hemen ardından CollisionRulesChanged'ı çağırın, bu fonksiyonun içinde değil.

function ENT:Initialize()
	self:SetCustomCollisionCheck( true )
end

function ENT:ShouldNotCollide( ent )
    -- func_breakable ile çarpışma
    return ent:GetClass() == "func_breakable"
end
```

### Örnek

Eğer bu hook içinde bir oyuncunun Takımını (Team) bir değişken olarak kullanmak isterseniz, takım değişikliklerinden hemen sonra [Entity:CollisionRulesChanged](https://gmod.tr/wiki/Entity:CollisionRulesChanged)'ı çağırmanız gerektiğini aklınızda bulundurmalısınız.

```lua
-- Artık Player:SetTeam/GM:PlayerJoinTeam yerine ChangeTeam kullanıyoruz, böylece takım değiştirme üzerinde kontrolümüz oluyor çünkü anında CollisionRulesChanged'ı çağırmamız gerekiyor,
-- ve bu, bir hook'un sonucu olarak değil, çünkü bu muhtemelen ShouldCollide'ı geçmek için çok geç olacaktır.
local meta = FindMetaTable( "Player" )
function meta:ChangeTeam( teamid )
	local oldteam = self:Team()
	self:SetTeam( teamid )
	self:CollisionRulesChanged()
	if oldteam ~= teamid then
		gamemode.Call( "OnPlayerChangedTeam", self, oldteam, teamid )
	end
end

hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
    -- Eğer oyuncuların takımı aynıysa çarpışma
    if ( ent1:IsPlayer() and ent2:IsPlayer() ) and ( ent1:Team() == ent2:Team() ) then return false end
end )

hook.Add( "PlayerInitialSpawn", "SetCustomCollisions", function( ply )
	ply:SetCustomCollisionCheck( true )
end )
```

### Örnek

Bu hook, özel Çarpışma Grupları (Collision Groups) oluşturmak için de kullanılabilir, koşullarının değişmesi beklenmediği sürece bu, hook'u kullanmanın oldukça güvenli bir yoludur. Bu, özellikle özel bir varlık tabanında kullanıldığında güçlüdür.

```lua
-- Bu örnek için tekrar ShouldNotCollide kullanın, bu, belirli bir varlıkla ilgili olmayan paylaşılan (shared) bir dosyada olmalıdır.
hook.Add( "PlayerInitialSpawn", "SetCustomCollisions", function( ply )
	ply:SetCustomCollisionCheck( true )
end )

function GM:ShouldCollide( enta, entb )
    local snca = enta.ShouldNotCollide
    if snca and snca( enta, entb ) then return ( false ) end

    local sncb = entb.ShouldNotCollide
    if sncb and sncb( entb, enta ) then return ( false ) end

    return ( true )
end

-- Özel çarpışma türlerimizin bazı yeni ENUM'larını oluşturun, bunlar paylaşılan (shared) bir dosyada global olmalıdır.
MY_CUSTOM_COLLISIONS_PROJECTILES = 0
MY_CUSTOM_COLLISIONS_PLAYERS = 1

-- Özel çarpışma fonksiyonları, burası asıl Varlık dosyasının başladığı yerdir, bunlar da hepsi paylaşılan (shared) dosyalardır.
local M_Player = FindMetaTable( "Player" )
local function ShouldNotCollide_NoCollidesWithProjectiles( thisent, ent )
	return getmetatable( ent ) == M_Player and ent:IsMyCustomProjectile()
end

local function ShouldNotCollide_NoCollidesWithPlayers( thisent, ent )
	return getmetatable( ent ) == M_Player
end

local collisionFunctionByType = {
	[ MY_CUSTOM_COLLISIONS_PROJECTILES ] = ShouldNotCollide_NoCollidesWithProjectiles,
	[ MY_CUSTOM_COLLISIONS_PLAYERS ] = ShouldNotCollide_NoCollidesWithPlayers
}

-- Örnek olarak bir tanesini ayarlıyoruz
ENT.CustomCollisionGroup = MY_CUSTOM_COLLISIONS_PLAYERS

-- Fonksiyonun gerçek uygulaması, bu, Initialize'da yapmanız gereken ilk şey olmalıdır.
function ENT:Initialize()
	self.ShouldNotCollide = collisionFunctionByType[ self.CustomCollisionGroup ]
	self:SetCustomCollisionCheck( true )
end
```

### Örnek

Bu hook, yalnızca ondan etkilenen herhangi bir varlık var olmadan ÖNCE eklenmelidir, bu genellikle onu bir sunucunun yükleme aşamasında oluşturmanız gerektiği anlamına gelir. Dinamik olarak eklemek ve kaldırmak belaya davetiye çıkarmaktır.

```lua
-- Kötü! bu hook'ları rastgele eklemek ve kaldırmak büyük olasılıkla bir fizik çökmesine yol açacaktır, varlıklar tüm ömürleri boyunca bu hook'a sadık kalmalıdır!
-- ShouldCollide kuralını 10 dakika sonra ekle
timer.Simple( 10 * 60, function()
    hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
        if ( ent1:IsPlayer() and ent2:IsPlayer() ) then return false end
    end )
end )

-- 20 dakika sonra kaldır
timer.Simple( 20 * 60, function()
    hook.Remove( "ShouldCollide", "CustomCollisions" )
end )

-- İyi! Hook sonsuza kadar var olur, beklenmedik değişiklikler olmaz.
hook.Add( "ShouldCollide", "CustomCollisions", function( ent1, ent2 )
    if ( ent1:IsPlayer() and ent2:IsPlayer() ) then return false end
end )
```

- [GMod Wiki ana sayfası](https://gmod.tr/wiki)

---

[Tüm sunucular](https://gmod.tr/) · [GmodTR Launcher](https://gmod.tr/launcher) · [Rehber](https://gmod.tr/rehber) · [GMod Wiki](https://gmod.tr/wiki) · [GmodTR nedir?](https://gmod.tr/hakkinda) · [Sunucu ekle](https://gmod.tr/sunucu-ekle) · [Discord](https://discord.gg/gmodtr)

Kaynak: https://gmod.tr/wiki/GM:ShouldCollide
