Varlık Sürme

Entity sürüşü, diğer entity'leri kontrol etmenizi sağlar. Bu sadece arabalarla sınırlı değildir, istediğiniz herhangi bir hareket türü olabilir. Etrafta yuvarlanan basit bir top, noclip, bir helikopter, bir köpek olabilir. Hatta hareket etmek zorunda bile değil. Kontrol edebileceğiniz her şey olabilir.

Sürüş Sınıfı (The Drive Class)

Bir sürüş sınıfı, basitçe bir fonksiyonlar tablosudur. Sürüş sınıfları hem istemci hem de sunucu tarafında bulunur ve tamamen tahmin edilir (fully predicted) - bu da sürüş deneyiminin çok oyunculu modda tek oyunculu moddakiyle aynı hissettirdiği anlamına gelir. Hoş ve tepkisel.

Basit bir Sürüş Sınıfı

İşte basit bir sürüş sınıfı

-- drive_base'den türetilmiştir (bkz. lua/drive/drive_base.lua ) DEFINE_BASECLASS( "drive_base" ) drive.Register( "drive_example", { -- -- Entity'yi sürerken görünümü hesaplar -- CalcView = function( self, view ) -- -- Bize 3. şahıs bakış açısı sağlamak için drive_base.lua'daki yardımcı metodu kullanın -- self:CalcView_ThirdPerson( view, 100, 2, { self.Entity } ) view.angles.roll = 0 end, -- -- Her hareketten önce çağrılır. Entity'nizi ve cmd'yi kullanarak -- mv'yi hareketiniz için ihtiyacınız olan bilgilerle doldurmalısınız. -- StartMove = function( self, mv, cmd ) -- Gözlemci modunu takip (chase) olarak ayarlayın, böylece entity çizilecektir. self.Player:SetObserverMode( OBS_MODE_CHASE ) -- -- Hareket pozisyonunu ve hızını entity'mizden güncelleyin -- mv:SetOrigin( self.Entity:GetNetworkOrigin() ) mv:SetVelocity( self.Entity:GetAbsVelocity() ) end, -- -- Asıl hareketi çalıştırır. İstemcide tahmin hataları -- olduğunda bu birden çok kez çalıştırılabilir. -- Yalnızca mv'yi değiştirmeye çalışmalısınız. -- Move = function( self, mv ) -- -- Bir hız ayarlayın, shift basılı tutulursa daha hızlı gidin -- local speed = 0.0005 * FrameTime() if ( mv:KeyDown( IN_SPEED ) ) then speed = 0.005 * FrameTime() end -- -- movedata'dan bilgileri alın -- local ang = mv:GetMoveAngles() local pos = mv:GetOrigin() local vel = mv:GetVelocity() -- -- Hızları ekleyin. Bu karmaşık görünebilir. İlk satırda -- temel olarak ileri vektörünü al, sonra onu ileri hızımızla -- çarp diyoruz (eğer W'ye basıyorsak > 0, S'ye basıyorsak < 0 olacak -- ikisine de basmıyorsak 0 olacak) - ve bunu hıza ekle. -- Bunu sağ ve yukarı için de yaparız, bu da bize serbest hareketimizi verir. -- vel = vel + ang:Forward() * mv:GetForwardSpeed() * speed vel = vel + ang:Right() * mv:GetSideSpeed() * speed vel = vel + ang:Up() * mv:GetUpSpeed() * speed -- -- Hızımızın kontrolden çıkmasını istemiyoruz, bu yüzden -- biraz hava direnci uyguluyoruz. Eğer hiçbir tuşa basılmıyorsa -- daha fazla direnç uyguluyoruz, böylece daha çok yavaşlıyoruz. -- if ( math.abs(mv:GetForwardSpeed()) + math.abs(mv:GetSideSpeed()) + math.abs(mv:GetUpSpeed()) < 0.1 ) then vel = vel * 0.90 else vel = vel * 0.99 end -- -- Hızı pozisyona ekleyin (bu harekettir) -- pos = pos + vel -- -- Yeni hesaplanan değerleri doğrudan entity'nin üzerinde ayarlamıyoruz -- bunun yerine onları movedata'da saklıyoruz. Bunlar FinishMove'da uygulanır. -- mv:SetVelocity( vel ) mv:SetOrigin( pos ) end, -- -- Hareket tamamlandı. Yeni pozisyonları ayarlamak için mv'yi kullanın -- entity'lerinizde/oyuncularınızda. -- FinishMove = function( self, mv ) -- -- Entity'mizi güncelleyin! -- self.Entity:SetNetworkOrigin( mv:GetOrigin() ) self.Entity:SetAbsVelocity( mv:GetVelocity() ) self.Entity:SetAngles( mv:GetMoveAngles() ) -- -- Eğer bir fizik nesnemiz varsa onu da güncelleyin. Ama sadece sunucuda. -- if ( SERVER && IsValid( self.Entity:GetPhysicsObject() ) ) then self.Entity:GetPhysicsObject():EnableMotion( true ) self.Entity:GetPhysicsObject():SetPos( mv:GetOrigin() ) self.Entity:GetPhysicsObject():Wake() self.Entity:GetPhysicsObject():EnableMotion( false ) end end, }, "drive_base" )

Bu karmaşık görünebilir ama aslında oldukça basittir. Size hız tabanlı basit bir noclip modu verir.

Dikkat edilmesi gereken bazı şeyler var. Sürüş modunuzu kaydederken bunları sırayla kaydetmelisiniz. Bu, eğer modunuzu bir sınıftan türetiyorsanız, önce o sınıfı kaydetmeniz gerektiği anlamına gelir.

Oyuncuyu Sürüş Moduna Geçirme

Oyuncunun sürüşe başlamasını sağlamak için, sunucuda şunu çağırın

drive.PlayerStartDriving( player, ent, drivemode )

örneğin

drive.PlayerStartDriving( player, ent, "drive_mydriveclass" )

Sürüşü durdurmak için şunu çağırabilirsiniz

Veya eğer sürüş sınıfının içindeyseniz şunu çağırabilirsiniz

self:Stop()

Örnek

Daha ayrıntılı bir örnek için lua/drive/drive_sandbox.lua dosyasına bakabilirsiniz. Bu, Sandbox modunda entity'leri sürmek için kullanılan sürüş modudur.

lua/drive/drive_base.lua dosyasına da göz atmaya değer - çünkü bu, tüm varsayılan sürüş modları tarafından paylaşılan ortak temeldir ve tüm eklenebilir (hookable) fonksiyonları gösterir.

İç Yapı (Internals)

Sınıf bir kez oluşturulur ve önbelleğe alınır. Sunucuda, bu nesnenin sürüş süresince kalacağı neredeyse garantidir - bu yüzden üzerinde değişkenleri saklamak güvenlidir. Ancak istemcide, eğer gecikme (lag) veya tahmin hataları olursa - nesnenin yeniden oluşturulması mümkündür.

Kontrol eden oyuncu ve entity, her fonksiyona parametre olarak geçilmez çünkü nesnenin kendisinde kayıtlıdırlar. Onlara şunlar aracılığıyla erişilebilir:

self.Player self.Entity

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