GM:ShouldCollide

  boolean GM:ShouldCollide( Entity ent1, Entity ent2 )
Bu hook tahmin edilir (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 kullanıldıysa çağrılır.

Uygulanabilir olduğu durumlarda, bunun yerine constraint.NoCollide veya bir logic_collision_pair varlığı kullanmayı düşünün - bunların kullanımı oldukça daha kolaydır ve bazı durumlarda daha uygun olabilir.

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 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.
Bu hook, belirli koşullar altında tüm fiziklerin bozulmasına neden olabilir.

Hata Takipçisi: 642

Argümanlar

1 Entity ent1
Çarpışma sorgusundaki ilk varlık.
2 Entity ent2
Çarpışma sorgusundaki ikinci varlık.

Döndürülen Değerler

1 boolean
Varlıkların çarpışıp çarpışmayacağı.

Örnek

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

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 fonksiyonunu çağırmama riskini taşır.

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 ç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.

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

-- 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.

-- 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'ı çağırmanız gerektiğini aklınızda bulundurmalısınız.

-- 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.

-- 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.

-- 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 )

Tüm sunucular · GmodTR Launcher · Rehber · GMod Wiki · GmodTR nedir? · Sunucu ekle · Discord