Blaster davranışını uygulama

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Blaster davranışını uygulama, birinci şahıs nişancı oyunlarında bir patlama mekanizmasını programlama sürecidir. Oyuncular bir tıklama veya bir düğmeye basarak patlayabilirken, tatmin edici ve doğru bir patlama davranışı oluşturmak önemlidir çünkü bu, oyuncuların genel oyun deneyimlerini artırır.

örnek lazer tag oyunu referans alarak, bu öğretici bölümünde iki farklı blaster türü için blaster davranışını uygulamanın arkasındaki scriptler hakkında bilgi edineceksiniz. Bu bölümde aşağıdaki konulara rehberlik edilecektir:

  • Oyuncuların patlama düğmesine bastıklarında bunu tespit etme.
  • Oyuncunun patlama düğmesine yakın zamanda basıp basmadığını kontrol etme.
  • Sunucuya patlamayı başlatan kişinin kim olduğunu, nereden geldiğini ve her lazer ışınının son varış noktasını bildiren patlama verilerini oluşturma.
  • Patlama verilerini sunucuya bildirerek, patlamanın başka bir oyuncuyla çarpışması durumunda uygun eylemleri gerçekleştirmesini sağlama.
  • Her patlama arasında blaster'ı sıfırlayarak, blaster'ın tekrar patlayabilmesi için yeterli soğuma süresi tanıma.

Bu bölümü tamamladıktan sonra, blaster'ın patlamalarının diğer oyuncularla çarpıştığını tespit etmesini sağlayan scriptler hakkında bilgi edinecek ve ardından her blaster türüne göre ilgili sağlık miktarını düşüreceksiniz.

Oyuncu girişini kontrol etme

Blaster davranışını uygulamanın ilk adımı, bir oyuncunun patlama düğmesine bastığında dinlemektir. Oyuncuların patlama düğmesine basmak için kullandıkları giriş türü, oyuna erişmek için kullandıkları cihaza bağlıdır. Örneğin, örnek lazer tag oyunu fare ve klavye kontrollerini, oyun kumandalarını ve dokunmatik kontrolleri destekler. Bu giriş türlerinin her birini ReplicatedStorageUserInputHandler içinde görebilirsiniz.

Bu istemci scripti, ContextActionService kullanarak MouseButton1 ve ButtonR2'yi patlama eylemine bağlar. Bu, bir oyuncu sol fare düğmesine veya bir oyun kumandasının R2 düğmesine her bastığında, blaster'dan bir lazer ışınının patlamasını tetikler. HUDGui'nin mobil cihazlarda patlama için bir düğme içerdiğini ve scriptin ilerleyen kısımlarında buna bağlandığını unutmayın.

UserInputHandler
ContextActionService:BindAction("_", onBlasterActivated, false,
Enum.UserInputType.MouseButton1,
Enum.KeyCode.ButtonR2
)

onBlasterActivated() tanımında Enum.UserInputState.Begin kullanımına dikkat etmek önemlidir. Bir blaster seçmek gibi birçok kullanıcı arayüzü etkileşimi, fare düğmesi yukarı kalktıktan sonra (Enum.UserInputState.End) gerçekleşmez, bu da kullanıcılara etkileşimden kaçınmak için son bir şans tanır. Ancak, bir patlama mekanizması, düğmeye basıldığı anda gerçekleşmediği sürece duyarlı hissettirmiyor.

Bunu göstermek için, Enum.UserInputState.Begin'i Enum.UserInputState.End olarak değiştirebilir ve ardından oyun testini yaparak patlamanın duyarlılığının oyunun oynanışını nasıl etkilediğini görebilirsiniz. Örneğin, oyuncular düğmeyi basılı tutabiliyorsa ve patlama tetiklenmiyorsa, bu diğer oyuncuları etiketlerken deneyimlerini nasıl değiştirebilir?

UserInputHandler
local function onBlasterActivated(_actionName: string,
inputState: Enum.UserInputState, _inputObject: InputObject)
if inputState == Enum.UserInputState.End then -- güncellenmiş satır, lütfen geri değiştirin
attemptBlastClient()
end
end

Oyuncunun patlayıp patlayamayacağını kontrol etme

UserInputHandler bir düğme basışını veya ekran dokunuşunu tespit ettikten sonra, ReplicatedStorageBlasterattemptBlastClient'i çağırarak oyuncunun patlayıp patlayamayacağını kontrol eder. Örnek lazer tag oyunundaki çoğu kontrol gibi, bu işlem iki kez gerçekleşir: önce istemcide, sonra sunucuda. attemptBlastClient, ardından ReplicatedStorageBlastercanLocalPlayerBlast'i çağırarak blasterStateClient oyuncu niteliğinin basit bir kontrolünü gerçekleştirir:

canLocalPlayerBlast
local function canLocalPlayerBlast(): boolean
return localPlayer:GetAttribute(PlayerAttribute.blasterStateClient) == BlasterState.Ready
end

ReplicatedStorageBlasterBlasterState'i incelediğinizde, oyunun üç blaster durumu olduğunu görebilirsiniz: Ready, Blasting ve Disabled. Bu durumların her birinin etkisini görmek için oyunu test edebilir, Players hizmeti altında oyuncunuzu seçebilir ve ardından Properties penceresinde blasterStateClient niteliğini gözlemleyebilirsiniz. Blaster'ınızı seçerken Disabled, çoğu zaman Ready ve düğmeye bastıktan sonra bir saniyeden daha kısa bir süre için Blasting olarak görüntülendiğini fark edin.

Bu küçük gecikme, tıkladığınız kadar hızlı patlayamamanızı sağlar. Örneğin, fonksiyonu her zaman true dönecek şekilde değiştirirseniz, herhangi bir gecikme olmadan blaster'ınızı hızlı bir şekilde patlatabilirsiniz ki bu lazer tag oyun deneyimi için gerçekçi değildir.

canLocalPlayerBlast
local function canLocalPlayerBlast(): boolean
return true -- güncellenmiş satır, lütfen geri değiştirin
end

Patlama verilerini oluşturma

Oyuncunun blaster'ının Ready durumunda olduğunu doğruladıktan sonra, attemptBlastClient ReplicatedStorageattemptBlastClientblastClient'i çağırır. blastClient'in attığı ilk adım, blasterStateClient oyuncu niteliğini Blasting olarak ayarlamaktır; bu, daha önceki hızlı ateş durumunu önler.

Sonraki adım, patlama verilerini oluşturmaktır. ReplicatedStorageBlasterBlastData'yı gözden geçirirseniz, her patlamanın üç bilgi parçasından oluştuğunu görebilirsiniz:

  • Patlamayı başlatan oyuncu.
  • Patlamanın başlangıç noktasını temsil eden bir DataType.CFrame.
  • Eğer başka bir oyuncuya çarparsa, her lazer ışınının son varış noktasını ve çarpılan oyuncuyu içeren bir RayResult tablosu.

Bu verileri oluşturmak için, blastClient ReplicatedStorageattemptBlastClientblastClientgenerateBlastData'yi çağırır; aşağıda gözden geçirebilirsiniz.

generateBlastData
local function generateBlastData(): BlastData.Type
local blasterConfig = getBlasterConfig()
local rayDirections = getDirectionsForBlast(
currentCamera.CFrame, blasterConfig)
local rayResults = castLaserRay(
localPlayer, currentCamera.CFrame.Position, rayDirections)
local blastData: BlastData.Type = {
player = localPlayer,
originCFrame = currentCamera.CFrame,
rayResults = rayResults,
}
return blastData
end

Bu fonksiyon, oyuncunun blaster türünü almak için getBlasterConfig kullanarak başlar. Örnek, geniş, yatay bir yayılma ile birkaç ışın üreten bir blaster ve tek bir ışın üreten başka bir blaster türü sağlar. Bu yapılandırmaları ReplicatedStorageInstancesLaserBlastersFolder içinde bulabilirsiniz.

Fonksiyon, patlama için başlangıç noktası olarak currentCamera.CFrame'i kullanır ve bunu getDirectionsForBlast'a geçirir. Bu noktada, kod artık blaster ile ilgili değil, lazer ışını ile ilgilidir; lazer ışını hakkında daha fazla bilgi edineceğiniz çarpışmaları tespit etme bölümüne geçeceksiniz. Son olarak, rayResults tablosunu oluşturduktan sonra, generateBlastData patlama verilerini blastClient'e döndürmek için ihtiyaç duyduğu tüm bilgilere sahiptir.

Sunucuya bildirme

blastClient patlama için tam verilere sahip olduğunda, iki olayı tetikler:

blastClient
local laserBlastedBindableEvent = ReplicatedStorage.Instances.LaserBlastedBindableEvent
local laserBlastedEvent = ReplicatedStorage.Instances.LaserBlastedEvent
laserBlastedBindableEvent:Fire(blastData)
laserBlastedEvent:FireServer(blastData)

BindableEvent, patlamayı diğer istemci scriptlerine bildirir. Örneğin, ReplicatedStorageFirstPersonBlasterVisuals bu olayı, patlama animasyonu ve soğuma çubuğu gibi görsel efektleri ne zaman göstereceğini bilmek için kullanır. Benzer şekilde, RemoteEvent, sunucu scriptlerine patlamayı bildirir ve bu, ServerScriptServiceLaserBlastHandler içinde patlamayı işlemeye başlar.

LaserBlastHandler
local function onLaserBlastedEvent(playerBlasted: Player, blastData: BlastData.Type)
local validatedBlastData = getValidatedBlastData(playerBlasted, blastData)
if not validatedBlastData then
return
end
if not canPlayerBlast(playerBlasted) then
return
end
blastServer(playerBlasted)
processTaggedPlayers(playerBlasted, blastData)
for _, replicateToPlayer in Players:GetPlayers() do
if playerBlasted == replicateToPlayer then
continue
end
replicateBlastEvent:FireClient(replicateToPlayer, playerBlasted, blastData)
end
end

Hile yapmayı önlemek için, sunucu her istemcinin gönderdiği verileri doğrulamak zorundadır. Bu kontroller şunları içerir:

  1. BlastData bir tablo mu? Bir Class.CFrame ve başka bir rayResults tablosu içeriyor mu?
  2. Oyuncunun bir blaster'ı var mı?
  3. Oyuncunun bir karakteri ve dünyada bir konumu var mı?
  4. Patlama verilerini gönderdikten sonra, oyuncu lazer ışınını patlattığı yerden aşırı bir mesafeye mi hareket etti?

Bu son kontrol bir yargı çağrısı içerir ve sunucu gecikmesi ile oyuncu hareket hızı göz önüne alındığında, kendi oyununuz için aşırı değerlerin ne olacağına karar verebilirsiniz. Bu yargı çağrısını nasıl yapacağınızı göstermek için, getValidatedBlastData içinde bir print ifadesi ekleyebilir ve oyunu test edebilirsiniz.

getValidatedBlastData
local distanceFromCharacterToOrigin = blastData.originCFrame.Position - rootPartCFrame.Position
print(distanceFromCharacterToOrigin.Magnitude) -- güncellenmiş satır, lütfen kaldırın
if distanceFromCharacterToOrigin.Magnitude > ToleranceValues.DISTANCE_SANITY_CHECK_TOLERANCE_STUDS then
warn(`Player {player.Name} failed an origin sanity check while blasting`)
return
end

Hareket ederken ve patlarken, çıktıyı not edin. Şöyle bir şey görünebilir:

1.9019629955291748
3.1549558639526367
2.5742883682250977
4.8044586181640625
2.6434271335601807

ReplicatedStoragePlayerStateHandlertogglePlayerMovement içinde oyuncuların hareket hızını artırırsanız, tekrar test ettiğinizde, patlamalar arasında aşırı hareket nedeniyle birçok başarısız kontrol ile karşılaşabilirsiniz.

togglePlayerMovement
local ENABLED_WALK_SPEED = 60 -- güncellenmiş satır, lütfen geri değiştirin

Sunucu daha sonra şunları yapar:

  • rayResults'ı doğrular.
  • Oyuncunun patlayıp patlayamayacağını kontrol eder.
  • Blaster durumunu sıfırlar.
  • Etiketlenmiş oyuncuların sağlıklarını azaltır.
  • Diğer tüm oyunculara patlamayı çoğaltarak, üçüncü şahıs görsellerini görmelerini sağlar.

Bu sunucu işlemleri hakkında daha fazla bilgi için, öğreticinin çarpışmaları tespit etme bölümüne bakın.

Blaster'ı sıfırlama

Örnek lazer tag oyununda, blaster'lar bir ısı mekanizması kullanır. Belirli bir patlama sayısından sonra yeniden yüklemek yerine, her patlama arasında "soğuma" süresine ihtiyaç duyarlar. Bu aynı soğuma gecikmesi, istemci (blastClient) ve sunucu (blastServer) üzerinde gerçekleşir; sunucu gerçek bilgi kaynağı olarak hareket eder.

blastServer
local blasterConfig = getBlasterConfig(player)
local secondsBetweenBlasts = blasterConfig:GetAttribute("secondsBetweenBlasts")
task.delay(secondsBetweenBlasts, function()
local currentState = player:GetAttribute(PlayerAttribute.blasterStateServer)
if currentState == BlasterState.Blasting then
player:SetAttribute(PlayerAttribute.blasterStateServer, BlasterState.Ready)
end
end)

secondsBetweenBlasts niteliği, ReplicatedStorageInstancesLaserBlastersFolder içindeki blaster yapılandırmasının bir parçasıdır. secondsBetweenBlasts gecikmesi geçtikten sonra, oyuncu tekrar patlayabilir ve tüm süreç tekrar başlar. Oyuncunun tekrar ne zaman patlayabileceğini anlamasına yardımcı olmak için, oyun bir soğuma çubuğu içerir.

Bu noktada, oyuncular doğabilir ve yeniden doğabilir, nişan alabilir ve patlayabilir, ancak oyun hala her patlamanın sonuçlarını belirlemelidir. Öğreticinin bir sonraki bölümünde, blaster'ın patlamanın başka bir oyuncuya çarptığını tespit etme yeteneğini programlamayı ve ardından blaster ayarlarına göre uygun miktarda oyuncu sağlığını azaltmayı öğreneceksiniz.

©2026 Roblox Corporation. Roblox, the Roblox logo and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.