Lazerlerle hedef tespiti

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

Bu eğitimde, bir lazerin blasterden nasıl atılacağını öğrenecek ve bir oyuncuya vurup vurmadığını tespit edeceksiniz Oyuncu araçları oluşturma ve bir oyuncuya vurup vurmadığını tespit edeceksiniz.

Çarpışma bulmak için Raycasting

Işın yayımı bir başlangıç pozisyonundan belirli bir uzunlukla verilen yöne doğru görünmez bir ışın yaratır.Işın yolundaki nesnelerle veya arazilerle çarpışırsa, konum ve çarpıştığı nesne gibi çarpışma bilgilerini geri verecektir.

B'ye doğru A'dan yayılan ışın bir duvarla çarpışıyor

Fare konumunu bul

Bir lazer vurulmadan önce, oyuncunun nereye hedeflediğini bilmeniz gerekir.Bu, doğrudan kameradan ekrana 2D fare konumundan oyun dünyasına göndererek oyuncunun ekrandaki yerinden bulunabilir.Işın, oyuncunun fareyle hedef aldığı her şeyle çarpışacaktır.

  1. Blaster aracındaki Araç Kontrolörü skriptini Oyuncu araçları oluştur aracılığıyla açın.Bu eğitimi henüz bitirmediyseniz Patlayıcı modelini indirip StarterPack'e ekleyebilirsiniz.

  2. Senaryonun üstünde, değeri 1000 olan bir sabit olan MAX_MOUSE_DISTANCE adlı sabiti ilan edin.

  3. getWorldMousePosition adlı bir işlev oluşturun.


    local tool = script.Parent
    local MAX_MOUSE_DISTANCE = 1000
    local function getWorldMousePosition()
    end
    local function toolEquipped()
    tool.Handle.Equip:Play()
    end
    local function toolActivated()
    tool.Handle.Activate:Play()
    end
    -- Etkinlikleri uygun işlevlere bağla
    tool.Equipped:Connect(toolEquipped)
    tool.Activated:Connect(toolActivated)
  4. Ekranda oyuncunun 2B fare konumunu almak için UserInputService GetMouseLocation işlevini kullanın.Bunu fareLocation adlı değişkenine atayın.


    local UserInputService = game:GetService("UserInputService")
    local tool = script.Parent
    local MAX_MOUSE_DISTANCE = 1000
    local function getWorldMousePosition()
    local mouseLocation = UserInputService:GetMouseLocation()
    end

Şimdi 2D fare konumu biliniyor, X ve Y özellikleri ekrandan 3D oyun dünyasına bir şey yaratan fonksiyonun parametreleri olarak kullanılabiliyor, ki bu ekrandan 3D oyun dünyasına bir şey yaratıyor.

  1. X ve Y özelliklerini > işlevinin argümanları olarak kullanın.Bunu ekranToWorldRay adlı değişkenine atayın.


    local function getWorldMousePosition()
    local mouseLocation = UserInputService:GetMouseLocation()
    -- 2D fare konumundan bir ışın oluştur
    local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
    end

Işın bir nesneye vurup vurmadığını kontrol etmek için Raycast işlevini kullanma zamanı geldi.Bunun bir başlangıç pozisyonu ve yön vektörü gerektirir: bu örnekte, screenToWorldRay 'in kaynağı ve yön özelliklerini kullanacaksınız.

Yön vektörünün uzunluğu, ışının ne kadar seyahat edeceğini belirler.Işın, MAX_MOUSE_DISTANCE kadar uzun olmalıdır, bu yüzden yön vektörünü MAX_MOUSE_DISTANCE ile çarpmalısınız.

  1. Bir değişken olan yönVector adlı değişkeni ilan edin ve ona çarpan değeri atayın.


    local function getWorldMousePosition()
    local mouseLocation = UserInputService:GetMouseLocation()
    -- 2D mouseLocation'dan bir ışın oluştur
    local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
    -- Işının birim yön vektörü maksimum mesafe ile çarptırıldı
    local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
  2. Çalışma alanının Raycast fonksiyonunu çağırın, ilk argüman olarak Köken özelliğini screenToWorldRay ve ikinci olarak da directionVector özelliğini geçirin.Bunu raycastResult adlı değişkenine atayın.


    local function getWorldMousePosition()
    local mouseLocation = UserInputService:GetMouseLocation()
    -- 2D mouseLocation'dan bir ışın oluştur
    local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
    -- Işının birim yön vektörü maksimum mesafe ile çarptırıldı
    local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
    -- Işının kaynağından yönüne doğru ışın yayını Raycast from the ray's origin towards its direction
    local raycastResult = workspace:Raycast(screenToWorldRay.Origin, directionVector)

Çarpışma bilgisi

Işın atma işlemi, ışın tarafından vurulan bir nesne bulursa, ışın ve nesne arasındaki çarpışma hakkında bilgiler içeren bir RaycastResult döndürecektir.

RaycastResult ÖzelliğiAçıklama
İstisnaIşının kesiştiği BasePart veya Terrain hücre.
PozisyonKesişme gerçekleştiği yer; genellikle bir parçanın veya arazinin yüzeyinde doğrudan bir nokta.
MalzemeÇarpışma noktasındaki malzeme.
NormallikKesişen yüzün normal vektörü. Bu, yüzün hangi yöne işaret ettiğini belirlemeye kullanılabilir.

Pozisyon özelliği, fare üzerinde gezinilen nesnenin pozisyonu olacaktır.Fare, MAX_MOUSE_DISTANCE mesafede herhangi bir nesneye uçmuyorsa, raycastResult olacaktır nil .

  1. raycastResult var olup olmadığını kontrol etmek için bir if ifadesi oluşturun.

  2. Eğer raycastResult bir değere sahipse, onun Konumu özelliğini geri döndürün.

  3. Eğer ise, ışın atışının sonunu bulun.Fare konumunu 3B olarak hesaplamak için screenToWorldRay.Origin ve directionVector birlikte ekleyin.


local function getWorldMousePosition()
local mouseLocation = UserInputService:GetMouseLocation()
-- 2D mouseLocation'dan bir ışın oluştur
local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
-- Işının birim yön vektörü maksimum mesafe ile çarptırıldı
local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
-- Işının kaynağından yönüne doğru ışın yayını Raycast from the ray's origin towards its direction
local raycastResult = workspace:Raycast(screenToWorldRay.Origin, directionVector)
if raycastResult then
-- 3B kesişme noktasını geri dönün
return raycastResult.Position
else
-- Hiçbir nesne vurulmadı, bu yüzden ışının sonundaki konumu hesaplayın
return screenToWorldRay.Origin + directionVector
end
end

Hedefe ateş edin

Artık 3B fare konumu biliniyor, bir lazeri hedef almak için bir hedef konumu olarak kullanılabilir.İkinci bir ışın, oyuncunun silahı ve hedef konumu arasında Işın Fırlatma işlevi kullanarak yapılabilir.

  1. Senaryonun başında sabit bir değer olan MAX_LASER_DISTANCE ilan edin ve lazer tabancası için seçilen menzile atayın, ya da 500 .


    local UserInputService = game:GetService("UserInputService")
    local tool = script.Parent
    local MAX_MOUSE_DISTANCE = 1000
    local MAX_LASER_DISTANCE = 500
  2. fireWeapon adlı bir işlev oluşturun getWorldMousePosition işlevinin altında.

  3. getWorldMousePosition 'yi arayın ve sonucu farePosition adlı bir değişkene atayın. Bu, ışın atışı için hedef konum olacaktır.


    -- Hiçbir nesne vurulmadı, bu yüzden ışının sonundaki konumu hesaplayın
    return screenToWorldRay.Origin + directionVector
    end
    end
    local function fireWeapon()
    local mouseLocation = getWorldMousePosition()
    end
    local function toolEquipped()
    tool.Handle.Equip:Play()
    end

Bu kez, ışın atma işlevinin yön vektörü, oyuncunun alet pozisyonundan hedef konumuna yönü temsil edecektir.

  1. Hedef yönü adında bir değişken ilan edin ve hedef yönü aracı konumundan çıkararak yön vektörünü hesaplayın mouseLocation .

  2. Vektörün Birimi özelliğini kullanarak normalleştirin. Bu, daha sonra bir uzunluk ile çarpmayı kolaylaştıran bir büyüklük verir.


    local function fireWeapon()
    local mouseLocation = getWorldMousePosition()
    -- Normalize edilmiş bir yön vektörü hesaplayın ve lazer mesafesi ile çarptırın
    local targetDirection = (mouseLocation - tool.Handle.Position).Unit
    end
  3. Bir değişken olan yönVector adlı değişkeni ilan edin ve ona targetDirection çarpan ile atayın MAX_LASER_DISTANCE.


    local targetDirection = (mouseLocation - tool.Handle.Position).Unit
    -- Silahı ateş etmek için yön, maksimum mesafe ile çarptırılır
    local directionVector = targetDirection * MAX_LASER_DISTANCE
    end

Bir RaycastParams nesnesi, ışın atma işlevi için ek parametler depolamak için kullanılabilir.Lazer bombardmanınızda, silahı ateş eden oyuncuyla kazara çarpışmayacağından emin olmak için kullanılacaktır.Bir RaycastParams nesnesinin FilterDescendantsInstances dahil edilen herhangi bir parça, raycastta göz ardı edilecektir.

  1. fireWeapon fonksiyonunu devam ettirin ve silahRaycastParams adlı bir değişken ilan edin. Ona yeni bir RaycastParams nesnesi atayın.

  2. oyuncuyerel karakterini içeren bir tablo oluştur ve onu weaponRaycastParams.FilterDescendantsInstances özelliğine atayın.

  3. Oyuncunun alet kolu konumundan directionVector yönünde bir yayın yap, oyuncunun alet kolu konumundan yayın yap, oyuncunun alet kolu konumundan yayın yapBu sefer bir argüman olarak weaponRaycastParams eklemek unutmayın.Bunu silahRaycastResult adlı değişkenine atayın.


local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local tool = script.Parent
local MAX_MOUSE_DISTANCE = 1000
local MAX_LASER_DISTANCE = 500
local function getWorldMousePosition()

local function fireWeapon()
local mouseLocation = getWorldMousePosition()
-- Normalize edilmiş bir yön vektörü hesaplayın ve lazer mesafesi ile çarptırın
local targetDirection = (mouseLocation - tool.Handle.Position).Unit
-- Silahı ateşleme yönü maksimum mesafe ile çarptırılmış
local directionVector = targetDirection * MAX_LASER_DISTANCE
-- oyuncukarakterini görmezden gelerek kendilerine zarar vermelerini engelle
local weaponRaycastParams = RaycastParams.new()
weaponRaycastParams.FilterDescendantsInstances = {Players.LocalPlayer.Character}
local weaponRaycastResult = workspace:Raycast(tool.Handle.Position, directionVector, weaponRaycastParams)
end

Son olarak, ışın atma işleminin bir değer döndürdüğünü kontrol etmeniz gerekecek.Bir değer döndürülürse, bir nesne silah ve vuruş konumu arasında bir lazer oluşturulabilir ve bir değer döndürülürse, bir nesne silah ve vuruş konumu arasında bir lazer oluşturulabilir.Hiçbir şey dönmediyse, lazer oluşturmak için son konum hesaplanmalıdır.

  1. Boş bir değişken olan hitPosition adlı değişkeni ilan edin.

  2. Bir değere sahip olup olmadığını kontrol etmek için bir if ifadesi kullanın. Eğer bir nesneye vurulduysa, weaponRaycastResult 'e weaponRaycastResult.Position atayın hitPosition .


    local weaponRaycastResult = workspace:Raycast(tool.Handle.Position, directionVector, weaponRaycastParams)
    -- Başlangıç ve bitiş konumları arasında herhangi bir nesneye vuruldu mu kontrol edin
    local hitPosition
    if weaponRaycastResult then
    hitPosition = weaponRaycastResult.Position
    end
  3. Eğer weaponRaycastResult değeri yoksa, ışın atışının son konumunu hesaplamak için alet tutucunun pozisyonunu ile directionVector 'i birleştirerek ekleyin.Bunu vuruş konumuna atayın.


    local weaponRaycastResult = workspace:Raycast(tool.Handle.Position, directionVector, weaponRaycastParams)
    -- Başlangıç ve bitiş konumları arasında herhangi bir nesneye vuruldu mu kontrol edin
    local hitPosition
    if weaponRaycastResult then
    hitPosition = weaponRaycastResult.Position
    else
    -- Maksimum lazer mesafesi üzerine dayanarak son konumu hesapla
    hitPosition = tool.Handle.Position + directionVector
    end
    end
  4. Navigate to the toolActivated function and call the fireWeapon function so that the lazer her defasında alet etkinleştirildiğinde ateş eder.


    local function toolActivated()
    tool.Handle.Activate:Play()
    fireWeapon()
    end

Nesneye vuruş kontrol et

Lazer tarafından vurulan nesnenin bir oyuncunun karakterinin bir parçası olup olmadığını bulmak veya sadece bir manzara parçası olup olmadığını bulmak için, her karakterin bir tane olduğundan bir Humanoid aramalısınız.

Öncelikle, karakter modelini bulmanız gerekecek.Karakterin bir kısmı vurulduysa, vurulan nesnenin ebeveyninin karakter olacağını varsayamazsınız.Lazer bir vücut parçasına, bir aksesuara veya bir aleta vurabilir, hepsi de karakterin hiyerarşisinin farklı kısımlarında bulunur.

Lazer tarafından vurulan nesneye ait bir karakter modeli atası bulmak için FindFirstAncestorOfClass kullanabilirsiniz, eğer bir tane varsa.Bir model bulursanız ve bir insansız içeriyorsa, çoğu durumda bunun bir karakter olduğunu varsayabilirsiniz.

  1. Bir karaktere vurulduğunu kontrol etmek için weaponRaycastResult if ifadesine vurgulanan kodu ekleyin.


    -- Başlangıç ve bitiş konumları arasında herhangi bir nesneye vuruldu mu kontrol edin
    local hitPosition
    if weaponRaycastResult then
    hitPosition = weaponRaycastResult.Position
    -- Vuruş örneği bir karakter modelinin yavrusu olacak
    -- Bir insansız modelde bulunursa, muhtemelen oyuncunun karakteridir
    local characterModel = weaponRaycastResult.Instance:FindFirstAncestorOfClass("Model")
    if characterModel then
    local humanoid = characterModel:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    print("Player hit")
    end
    end
    else
    -- Maksimum lazer mesafesi üzerine dayanarak son konumu hesapla
    hitPosition = tool.Handle.Position + directionVector
    end

Şimdi lazer patlayıcısı, ışın atma işlemi başka bir oyuncuya vurduğunda her seferinde çıktı penceresine Player hit basmalıdır.

Çok oyuncu ile test et

Silah ışınlarının diğer oyuncuları bulduğunu test etmek için iki oyuncu gereklidir, bu yüzden yerel bir sunucu başlatmanız gerekir.

  1. Studio'da Test sekmesini seçin.

  2. Oyuncuların bırakılması '2 Oyuncu' olarak ayarlanmış olduğundan emin olun ve başlat düğmesine tıklayarak yerel bir sunucuyu 2 istemci ile başlatın .Üç pencere görünecek.İlk pencere yerel sunucu olacak, diğer pencereler Player1 ve Player2 için müşteriler olacak.

  3. Bir kliende, diğer oyuncuyu silahla vurarak testere ateş etmeyi test edin.Oyuncu vuruşu her oyuncuya vurulduğunda çıktıda görüntülenmelidir. "Player hit" should be displayed in the output each time a player is shot.

Test sekmesi hakkında daha fazla bilgi edinebilirsiniz burada.

Lazer konumunu bul

Lazer, hedefine kırmızı bir ışın atmalıdır.Bunun için işlevi bir ModuleScript içinde olacak, böylece daha sonra diğer kodlarda tekrar kullanılabilecek.Öncelikle, senaryonun lazer ışınının görüntülenmesi gereken konumu bulması gerekecek.

  1. Create a ModülScript named LaserRenderer , StarterPlayerScripts altında StarterPlayer'a bağlı olarak

  2. Senaryoyu aç ve modül tablosunu senaryonun adına yeniden adlandır LazerRenderörü .

  3. Bir değere sahip SHOT_DURATION adlı bir değişkeni ilan edin, değeri 0.15 .Bu, lazerin görülebildiği süre (saniyeler) olacaktır.

  4. LazerRenderör'ün adı createLaser olan bir işlev oluşturun ve iki parametre ile çağrılan toolHandle ve endPosition .


    local LaserRenderer = {}
    local SHOT_DURATION = 0.15 -- Lazerin görülebildiği süre
    -- Bir başlangıç ​​pozisyonundan son bir pozisyona doğru bir lazer ışını oluştur
    function LaserRenderer.createLaser(toolHandle, endPosition)
    end
    return LaserRenderer
  5. Bir değişken olan başlangıçPozisyonu adlı değişkeni ilan edin ve Pozisyon özelliğini toolHandle değer olarak ayarlayın.Bu, oyuncunun lazer bombardmanının konumu olacaktır.

  6. Bir değişken olan lazer mesafe adlı değişkeni ilan edin ve iki vektör arasındaki farkı bulmak için endPosition 'den çıkarın startPosition çıkarın.Lazer ışınının uzunluğunu almak için bu Büyüklük özelliğini kullanın.


    function LaserRenderer.createLaser(toolHandle, endPosition)
    local startPosition = toolHandle.Position
    local laserDistance = (startPosition - endPosition).Magnitude
    end
  7. Lazer ışınının konumunu ve yönünü depolamak için bir laserCFrame değişken ilan edinPozisyon, ışının başlangıcından ve bitiminden orta nokta olmalıdır.Yeni bir CFrame.lookAt oluşturmak için 'a yerleştirilen ve 'e doğru yönelen yeni bir oluşturmak için kullanın ].Bunu negatif laserDistance yarısı bir Z eksen değeri ile yeni bir CFrame ile çarparak orta noktayı alın


    function LaserRenderer.createLaser(toolHandle, endPosition)
    local startPosition = toolHandle.Position
    local laserDistance = (startPosition - endPosition).Magnitude
    local laserCFrame = CFrame.lookAt(startPosition, endPosition) * CFrame.new(0, 0, -laserDistance / 2)
    end

Lazer parçasını oluştur

Artık bir lazer ışını nerede oluşturacağınızı bildiğinize göre, ışının kendisini eklemelisiniz. Bu, Neon parçası ile kolayca yapılabilir.

  1. Bir değişkeni lazerPart ilan edin ve ona yeni bir Part durum.

  2. Aşağıdaki özellikleri laserPart ayarlayın:

    1. Boyut : Vector3.new(0.2, 0.2, lazer mesafesi)
    2. CFrame : lazerCFrame
    3. Sabitlenmiş : true
    4. CanCollide : false: Yapışabilir
    5. Renk : Color3.fromRGB(225, 0, 0) (güçlü kırmızı renk)
    6. Malzeme : Enum.Material.Neon
  3. Ebeveyn laserPart Çalışma Alanına .

  4. Parçayı Debris servisine ekleyin, böylece SHOT_DURATION değişkenin saniye sayısından sonra kaldırılır.


    function LaserRenderer.createLaser(toolHandle, endPosition)
    local startPosition = toolHandle.Position
    local laserDistance = (startPosition - endPosition).Magnitude
    local laserCFrame = CFrame.lookAt(startPosition, endPosition) * CFrame.new(0, 0, -laserDistance / 2)
    local laserPart = Instance.new("Part")
    laserPart.Size = Vector3.new(0.2, 0.2, laserDistance)
    laserPart.CFrame = laserCFrame
    laserPart.Anchored = true
    laserPart.CanCollide = false
    laserPart.Color = Color3.fromRGB(225, 0, 0)
    laserPart.Material = Enum.Material.Neon
    laserPart.Parent = workspace
    -- Kaldırılması ve temizlenmesi gereken Debris hizmetine lazer işını ekleyin
    Debris:AddItem(laserPart, SHOT_DURATION)
    end

Şimdi lazer ışınını görüntüleme işlevi tamamlandı, Araç Denetleyicisi tarafından çağrılabilir.

  1. Araç Denetleyicisi skriptinin üstünde, LaserRenderer adlı bir değişken ilan edin ve OyuncuScriptlerde bulunan LaserRenderer ModülScript'ini gerektirin.


    local UserInputService = game:GetService("UserInputService")
    local Players = game:GetService("Players")
    local LaserRenderer = require(Players.LocalPlayer.PlayerScripts.LaserRenderer)
    local tool = script.Parent
  2. fireWeapon işlevinin dibinde, araç kolu ve createLaser ve hitPosition argümanları kullanarak LaserRenderer işlevini çağırın.


    -- Maksimum lazer mesafesi üzerine dayanarak son konumu hesapla
    hitPosition = tool.Handle.Position + directionVector
    end
    LaserRenderer.createLaser(tool.Handle, hitPosition)
    end
  3. Oyun düğmesine tıklayarak silahı test edin. Araç etkinleştirildiğinde silah ve fare arasında bir lazer ışını görünmelidir.

Silah ateş değerlendirkontrol et

Silahların her atış arasında bir gecikmeye ihtiyacı vardır, böylece oyuncular kısa bir sürede çok fazla hasar veremez.Bir oyuncunun son kez ateş edildiğinden beri yeterli süre geçip geçmediğini kontrol ederek bunun kontrol edilebilir.

  1. Bir değişkeni Araç Denetleyicisi üstünde ATEŞ_HIZI olarak ilan edin.Bu, her atış arasındaki minimum süre olacaktır.Seçtiğiniz bir değere verin; bu örnek 0.3 saniye kullanır.

  2. Altında başka bir değişken ilan edin timeOfPreviousShot ile bir değeri 0 .Bu, oyuncunun son kez ateş ettiğini ve her atışla güncelleneceğini saklar.


    local MAX_MOUSE_DISTANCE = 1000
    local MAX_LASER_DISTANCE = 300
    local FIRE_RATE = 0.3
    local timeOfPreviousShot = 0
  3. Hiçbir parametre ile canShootWeapon adlı bir işlev oluşturun.Bu işlev, önceki atıştan beri ne kadar süre geçtiğine bakacak ve gerçek veya yanlış döndürecek.


    local FIRE_RATE = 0.3
    local timeOfPreviousShot = 0
    -- Önceki atışın ateş edildiğinden beri yeterli süre geçtiğini kontrol et
    local function canShootWeapon()
    end
    local function getWorldMousePosition()
  4. İşlevin içinde, currentTime adlı bir değişken ilan edin; tick() işlevini çağırmak sonucunu ona atayın.Bu, 1 Ocak 1970'ten (zamanı hesaplamak için yaygın olarak kullanılan rastgele bir tarihten) beri kaç saniye geçtiğini döndürür (zaman hesaplamak için geniş çapta kullanılan rastgele bir tarih).

  5. Sonucun daha küçük olduğu durumda 'den çıkar ve yanlış geri döner eğer sonuç daha küçükse; aksi takdirde doğru geri döner.


    -- Önceki atışın ateş edildiğinden beri yeterli süre geçtiğini kontrol et
    local function canShootWeapon()
    local currentTime = tick()
    if currentTime - timeOfPreviousShot < FIRE_RATE then
    return false
    end
    return true
    end
  6. fireWeapon işlevinin sonunda, silah timeOfPreviousShot kullanılarak her seferinde güncellenir tick.


    hitPosition = tool.Handle.Position + directionVector
    end
    timeOfPreviousShot = tick()
    LaserRenderer.createLaser(tool.Handle, hitPosition)
    end
  7. toolActivated işlevinin içinde, bir if ifadesi oluşturun ve silahın ateş edilebilir olup olmadığını kontrol etmek için canShootWeapon çağırın.


    local function toolActivated()
    if canShootWeapon() then
    tool.Handle.Activate:Play()
    fireWeapon()
    end
    end

Patlamayı test ettiğinizde, ne kadar hızlı tıklarsanız tıklayın, her atış arasında daima kısa bir 0.3 saniye gecikme olacağını bulmalısınız.

oyuncuzarar ver

Müşteriler doğrudan diğer müşterilere hasar veremez; bir oyuncuya hasar verildiğinde sunucunun hasar verme sorumluluğu üstlenmesi gerekir.

Müşteriler, bir karakterin vurulduğunu sunucuya söylemek için bir RemoteEvent kullanabilir.Bunların her ikisine de açık olduğu Yeniden Yazılabilir Depolama 'da saklanması gerekir.

  1. ReplicatedStorage'a adı Etkinlikler olan bir Klasör oluştur .

  2. Uzaktan Etkinliği Etkinlikler klasörüne ekleyin ve adlandırın HasarKarakteri .

  3. In Araç Denetleyicisi , ReplicatedStorage ve Etkinlikler klasörünün başında değişkenler oluşturun.


    local UserInputService = game:GetService("UserInputService")
    local Players = game:GetService("Players")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local LaserRenderer = require(Players.LocalPlayer.PlayerScripts.LaserRenderer)
    local tool = script.Parent
    local eventsFolder = ReplicatedStorage.Events
    local MAX_MOUSE_DISTANCE = 1000
    local MAX_LASER_DISTANCE = 500
  4. "Player hit" baskı ifadesini fireWeapon Luau ile bir satırla değiştirin, böylece HasarKarakteri uzaktaki olayı ile characterModel değişken bir argman olarak ateşleyin.


    local characterModel = weaponRaycastResult.Instance:FindFirstAncestorOfClass("Model")
    if characterModel then
    local humanoid = characterModel:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    eventsFolder.DamageCharacter:FireServer(characterModel)
    end
    end
    else
    -- Maksimum lazer mesafesi üzerine dayanarak son konumu hesapla
    hitPosition = tool.Handle.Position + directionVector
    end

Sunucu, olay ateşlendiğinde vurulan oyuncuya hasar vermelidir.

  1. ServerScriptService'e bir Kript Yazma ekleyin ve adlandırın Sunucu Lazer Yöneticisi .

  2. LASER_DAMAGE adlı bir değişken ilan edin ve onu 10 veya seçtiğiniz bir değere ayarlayın.

  3. Oluştur damageCharacter iki parametre ile adlandırılan bir işlev playerFired ve characterToDamage ile isimlendirin.

  4. İşlevin içinde, karakterin Humanoid'ini bul ve sağlığından LASER_DAMAGE çıkar.

  5. damageCharacter fonksiyonunu HasarKarakteri uzaktan etkinliğine Etkinlik klasöründe bağlayın.


    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local eventsFolder = ReplicatedStorage.Events
    local LASER_DAMAGE = 10
    function damageCharacter(playerFired, characterToDamage)
    local humanoid = characterToDamage:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    -- Karakterden sağlığı kaldır
    humanoid.Health -= LASER_DAMAGE
    end
    end
    -- Etkinlikleri uygun işlevlere bağla
    eventsFolder.DamageCharacter.OnServerEvent:Connect(damageCharacter)
  6. Yerel bir sunucu başlatarak patlayıcıyı 2 oyuncu ile test edin.Diğer oyuncuyu vurduğunuzda, sağlıkları LASER_DAMAGE 'a atanan sayı ile azalacaktır.

Diğer oyuncunun lazer ışınlarını görüntüle

Şu anda, lazer ışını silahı ateşleyen müşteri tarafından oluşturulduğundan, sadece onlar lazer ışını görebileceklerdir.

Lazer ışını sunucuda oluşturulduysa, herkes onu görebilirdi.Bununla birlikte, müşterinin silahı ateşlemesi ve sunucunun atışla ilgili bilgileri alması arasında küçük bir gecikme olurdu.Bu, müşterinin silahı ateş etmesinin, silahı aktifleştirdikleri ve lazer ışını gördükleri arasında bir gecikme görmesi demektir; sonuç olarak silah gecikmeli hissedecektir.

Bu sorunu çözmek için, her bir müşteri kendi lazer ışınlarını oluşturacaktır.Bu, müşterinin silahı ateşlemesiyle lazer ışını anında göreceği anlamına gelir.Diğer kullanıcılar, başka bir oyuncu ateş ettiğinde ve bir ışın göründüğünde küçük bir gecikme yaşayacaktır.En iyi durum senaryosu budur: başka müşterilerin lazerini bir müşteriden daha hızlı iletmenin bir yolu yoktur.

Ateş edenin müşterisi

Öncelikle, müşterinin, bir lazer ateşlediğini ve son konumu sağladığını sunucuya söylemesi gerekir.

  1. ReplicatedStorage'daki Etkinlikler klasörüne bir Uzaktan Etkinlik ekleyin ve adlandırın LazerAteşli .

  2. fireWeapon fonksiyonunu Araç Denetleyicisi skriptinde bulun.İşlevin sonunda, LaserFired uzaktan etkinliğini bir argüman olarak hitPosition ateşleyin.


    hitPosition = tool.Handle.Position + directionVector
    end
    timeOfPreviousShot = tick()
    eventsFolder.LaserFired:FireServer(hitPosition)
    LaserRenderer.createLaser(tool.Handle, hitPosition)
    end

Sunucu

Artık sunucu, müşterinin ateşlediği olayı almalı ve tüm müşterilere lazer ışınının başlangıç ve bitiş konumunu söylemelidir, böylece onu da gösterebilirler.

  1. Sunucu Lazer Yöneticisi skriptinde, oyuncuAteşlenenLazer adlı bir işlev oluşturun ve damageCharacter ve playerFired olarak adlandırılan iki parametre ile endPosition .

  2. İşlevi LaserFired uzaktan etkinliğine bağlayın.


    -- Tüm müşterilere bir lazerın ateş edildiğini bildirin, böylece lazeri görebilirler
    local function playerFiredLaser(playerFired, endPosition)
    end

    -- Etkinlikleri uygun işlevlere bağla
    eventsFolder.DamageCharacter.OnServerEvent:Connect(damageCharacter)
    eventsFolder.LaserFired.OnServerEvent:Connect(playerFiredLaser)

Sunucu lazerin başlangıç konumuna ihtiyaç duyar.Bunlar istemci tarafından gönderilebilir, ancak mümkün olduğunda istemciye güvenmekten kaçınılmalıdır.Karakterin silah tutma konumu başlangıç pozisyonu olacak, böylece sunucu oradan bulabilir.

  1. Bir işlev oluştur getPlayerToolHandle playerFiredLaser işlevinin üzerinde bir parametre ile çalıştırın player .

  2. Silah için oyuncunun karakterini aramak için aşağıdaki kodu kullanın ve kullanıcı arayüzü nesnesini geri gönderin.


    local LASER_DAMAGE = 10
    -- Oyuncunun tuttuğu aletin kolu bulun
    local function getPlayerToolHandle(player)
    local weapon = player.Character:FindFirstChildOfClass("Tool")
    if weapon then
    return weapon:FindFirstChild("Handle")
    end
    end
    -- Tüm müşterilere bir lazerın ateş edildiğini bildirin, böylece lazeri görebilirler
    local function playerFiredLaser(playerFired, endPosition)

Sunucu artık FireAllClients ı LaserFired uzaktaki olaya çağırarak lazerin müşterilere gönderilmesi gereken bilgileri gönderebilir.Buna, lazeri ateşleyen oyuncu dahil edilir (yani bu oyuncu için müşteri, lazer için başlangıç pozisyonu olarak hareket eden blaster ve lazerin son pozisyonu), lazerin son pozisyonu ve lazerin son pozisyonu.

  1. işlevinde, işlevini bir argman olarak çağırın ve değeri toolHandle adlı değişkene atayın.

  2. Eğer toolHandle varsa, playerFired , toolHandle ve endPosition gibi tüm kullanıcılar için LaserFired etkinliğini ateşleyin, argüman olarak.


    -- Tüm müşterilere bir lazerın ateş edildiğini bildirin, böylece lazeri görebilirler
    local function playerFiredLaser(playerFired, endPosition)
    local toolHandle = getPlayerToolHandle(playerFired)
    if toolHandle then
    eventsFolder.LaserFired:FireAllClients(playerFired, toolHandle, endPosition)
    end
    end

Müşterilerde görüntüleme

Şimdi FireAllClients çağrıldı ve her bir kullanıcı, lazer ışını görüntülemek için sunucudan bir olay alacak.Her bir müşteri, lazer ışınını sunucunun tarafından gönderilen aletin tutma konumu ve son konum değeri kullanarak renderlemek için daha önce LazerRenderörü modülünü yeniden kullanabilir.Lazer ışını ilk sırada ateşleyen oyuncu bu olayı görmezse, 2 lazer görecekler.

  1. BaşlatıcıOyunScriptleri adlı YerelScript oluşturun, ClientLaserManager adında.

  2. Senaryo içinde, LazerRenderleyici modülünü gerektirin.

  3. CreatePlayerLaser adlı işlevi createPlayerLaser ile parametreler playerWhoShot , toolHandle ve endPosition ile oluşturun.

  4. İşlevi LaserFired uzaktan etkinliğine Etkinlikler klasöründe bağlayın.

  5. Fonksiyonda, if ifadesini kullanarak, ifadesinin Yerel Oynatıcı ile eşit olmadığını kontrol edin.

  6. if ifadesinin içinde, createLaser fonksiyonunu toolHandle ve endPosition argümanları kullanarak LaserRenderer modülünden çağırın.


    local Players = game:GetService("Players")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local LaserRenderer = require(script.Parent:WaitForChild("LaserRenderer"))
    local eventsFolder = ReplicatedStorage.Events
    -- Diğer bir oyuncunun lazerini göster
    local function createPlayerLaser(playerWhoShot, toolHandle, endPosition)
    if playerWhoShot ~= Players.LocalPlayer then
    LaserRenderer.createLaser(toolHandle, endPosition)
    end
    end
    eventsFolder.LaserFired.OnClientEvent:Connect(createPlayerLaser)
  7. Yerel bir sunucu başlatarak patlayıcıyı 2 oyuncu ile test edin.Her bir müşteriyi monitörün farklı taraflarına yerleştirin, böylece her iki pencereyi aynı anda görebilirsiniz.Bir müşteride vurduğunuzda, diğer müşteride lazeri görmelisiniz.

Ses etkileri

Ateş eden ses efekti şu anda sadece mermiyi ateş eden istemci üzerinde çalıyor.Kodu oynatmak için ses çıkarmak için diğer oyuncuların da duyacağı şekilde taşımanız gerekecek.

  1. Araç Denetleyicisi skriptinde, araç aktifleştirildi işlevine geç ve aktifleştirme sesini çalan satırı kaldır.


    local function toolActivated()
    if canShootWeapon() then
    fireWeapon()
    end
    end
  2. LazerRenderör içindeki fonksiyonun dibinde, atış sesi adlı bir değişken ilan edin ve aktifleştirme sesi kontrol etmek için yöntemini kullanın.

  3. if ifadesini kullanarak var olup olmadığını kontrol edin shootingSound ; eğer varsa, onun Oynatma işlevini çağırın.


    laserPart.Parent = workspace
    -- Kaldırılması ve temizlenmesi gereken Debris hizmetine lazer işını ekleyin
    Debris:AddItem(laserPart, SHOT_DURATION)
    -- Silahın atış sesini çal
    local shootingSound = toolHandle:FindFirstChild("Activate")
    if shootingSound then
    shootingSound:Play()
    end
    end

Doğrulama kullanarak uzaktan güvenli hale getirme

Sunucu gelen isteklerden veri kontrol etmiyorsa, bir bilgisayar korsanı uzaktaki işlevleri ve olayları kötüye kullanabilir ve sunucuya sahte değerler göndermek için kullanabilir.Bunu önlemek için sunucu tarafı doğrulama kullanmak önemlidir.

Mevcut formunda, HasarKarakteri uzaktan olayı saldırıya çok açıktır.Hackerlar bu olayı kullanarak oyunda istedikleri herhangi bir oyuncuya ateş etmeden hasar verebilirler.

Doğrulama, sunucuya gönderilen değerlerin gerçekçi olup olmadığını kontrol etme sürecidir. Bu durumda, sunucunun şunlara ihtiyacı olacaktır:

  • Oyuncu ve lazer tarafından vurulan konum arasındaki mesafenin belirli bir sınır içinde olup olmadığını kontrol edin.
  • Lazer ateşleyen silah ve vuruş pozisyonu arasında ışın atışının mümkün olduğundan ve herhangi bir duvardan geçmediğinden emin olmak için Raycast.

Müşteri

Client, ışınlama tarafından vurulan konumu sunucuya göndermelidir, böylece mesafenin gerçekçi olup olmadığını kontrol edebilir.

  1. In Araç Denetleyicisi , DamageCharacter uzaktan etkinliğinin fireWeapon fonksiyonunda ateşlendiği satıra yönlendirin.

  2. Bir argüman olarak hitPosition ekleyin.


    if characterModel then
    local humanoid = characterModel:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    eventsFolder.DamageCharacter:FireServer(characterModel, hitPosition)
    end
    end

Sunucu

Müşteri şimdi HasarKarakter uzaktan etkinliği aracılığıyla ek bir parametre gönderiyor, bu yüzden kabul etmek için SunucuLazerYöneticisi ayarlandı gerekiyor.

  1. Sunucu Lazer Yöneticisi skriptinde, hitPosition fonksiyonuna bir damageCharacter değeri ekleyin.


    function damageCharacter(playerFired, characterToDamage, hitPosition)
    local humanoid = characterToDamage:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    -- Karakterden sağlığı kaldır
    humanoid.Health -= LASER_DAMAGE
    end
    end
  2. ] işlevinin altında, üç parametre ile adlandırılan bir işlev oluşturun: isHitValid , ve .


    end
    local function isHitValid(playerFired, characterToDamage, hitPosition)
    end

İlk kontrol, vuruş pozisyonu ve karakter vuruşu arasındaki mesafe olacaktır.

  1. Senaryonun başında bir değişken olan MAX_HIT_PROXIMITY adlı değişkeni ilan edin ve ona bir değer atayın 10 .Bu, isabet ve karakter arasında izin verilen maksimum mesafe olacaktır.Karakter, müşteri etkinliği ateşlediğinden beri hafifçe hareket etmiş olabilir, bu yüzden bir tolerans gereklidir.


    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local eventsFolder = ReplicatedStorage.Events
    local LASER_DAMAGE = 10
    local MAX_HIT_PROXIMITY = 10
  2. isHitValid fonksiyonunda, karakter ve vuruş pozisyonu arasındaki mesafeyi hesaplayın.Mesafe MAX_HIT_PROXIMITY daha büyükse, geri dön yalan .


    local function isHitValid(playerFired, characterToDamage, hitPosition)
    -- Karakter vuruşu ve vuruş pozisyonu arasındaki mesafeyi doğrula
    local characterHitProximity = (characterToDamage.HumanoidRootPart.Position - hitPosition).Magnitude
    if characterHitProximity > MAX_HIT_PROXIMITY then
    return false
    end
    end

İkinci kontrol, ateş edilen silah ve vuruş pozisyonu arasında bir ışın atışı içerecektir.Işın atışı karakter olmayan bir nesneyi döndürürse, atışın geçersiz olduğunu varsayabilirsiniz, çünkü bir şey atışı engelliyordu.

  1. Bu kontrol etyürütmek için aşağıdaki kodu kopyalayın. İşlevin sonunda doğru döndürün: eğer bitirulaşırsa, tüm kontroller geçmiştir.


    local function isHitValid(playerFired, characterToDamage, hitPosition)
    -- Karakter vuruşu ve vuruş pozisyonu arasındaki mesafeyi doğrula
    local characterHitProximity = (characterToDamage.HumanoidRootPart.Position - hitPosition).Magnitude
    if characterHitProximity > 10 then
    return false
    end
    -- Duvarlardan atış yapıp yapmadığınızı kontrol edin
    local toolHandle = getPlayerToolHandle(playerFired)
    if toolHandle then
    local rayLength = (hitPosition - toolHandle.Position).Magnitude
    local rayDirection = (hitPosition - toolHandle.Position).Unit
    local raycastParams = RaycastParams.new()
    raycastParams.FilterDescendantsInstances = {playerFired.Character}
    local rayResult = workspace:Raycast(toolHandle.Position, rayDirection * rayLength, raycastParams)
    -- Karakter olmayan bir örnek vurulduysa, atışı görmezden gelin
    if rayResult and not rayResult.Instance:IsDescendantOf(characterToDamage) then
    return false
    end
    end
    return true
    end
  2. Geçerli atış olarak adlandırılan damageCharacter işlevinde bir değişken ilan edin validShot .Üç argümanla bir isHitValid fonksiyonuna yapılan çağrının sonucunu atayın: playerFired , characterToDamage ve hitPosition.

  3. Aşağıdaki if ifadesinde, 'in doğru olup olmadığını kontrol etmek için bir ve operatörü ekleyin.


    function damageCharacter(playerFired, characterToDamage, hitPosition)
    local humanoid = characterToDamage:FindFirstChildWhichIsA("Humanoid")
    local validShot = isHitValid(playerFired, characterToDamage, hitPosition)
    if humanoid and validShot then
    -- Karakterden sağlığı kaldır
    humanoid.Health -= LASER_DAMAGE
    end
    end

Artık hasarKarakter uzaktan etkinliği daha güvenli ve çoğu oyuncunun bunu kötüye kullanmasını engelleyecek.Bazı kötü niyetli oyuncuların sıklıkla doğrulama etrafında yollar bulacağını unutmayın; uzaktaki olayları güvende tutmak sürekli bir çaba.

Lazer bombardman silahınız artık temel bir vuruş algılama sistemi kullanarak raycasting ile tamamlandı.Lazer silahınıza yeniden yükleme eylemi ekleyebilmenizi veya eğlenceli bir oyun haritası oluşturabilmenizi ve diğer oyuncularla lazer silahınızı deneyebilmenizi bulmak için Kullanıcı Girişi Tespiti eğitimini deneyin!

Final kodu

Araç Kontrolörü


local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LaserRenderer = require(Players.LocalPlayer.PlayerScripts.LaserRenderer)
local tool = script.Parent
local eventsFolder = ReplicatedStorage.Events
local MAX_MOUSE_DISTANCE = 1000
local MAX_LASER_DISTANCE = 500
local FIRE_RATE = 0.3
local timeOfPreviousShot = 0
-- Önceki atışın ateş edildiğinden beri yeterli süre geçtiğini kontrol et
local function canShootWeapon()
local currentTime = tick()
if currentTime - timeOfPreviousShot < FIRE_RATE then
return false
end
return true
end
local function getWorldMousePosition()
local mouseLocation = UserInputService:GetMouseLocation()
-- 2D fare konumundan bir ışın oluştur
local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
-- Işının birim yön vektörü maksimum mesafe ile çarptırıldı
local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
-- Kraliyetin kaynağından kendi yönüne doğru ışınlanma
local raycastResult = workspace:Raycast(screenToWorldRay.Origin, directionVector)
if raycastResult then
-- 3B kesişme noktasını geri dönün
return raycastResult.Position
else
-- Hiçbir nesne vurulmadı, bu yüzden ışının sonundaki konumu hesaplayın
return screenToWorldRay.Origin + directionVector
end
end
local function fireWeapon()
local mouseLocation = getWorldMousePosition()
-- Normalize edilmiş bir yön vektörü hesaplayın ve lazer mesafesi ile çarptırın
local targetDirection = (mouseLocation - tool.Handle.Position).Unit
-- Silahı ateş etmek için yön, maksimum mesafe ile çarptırılır
local directionVector = targetDirection * MAX_LASER_DISTANCE
-- oyuncukarakterini görmezden gelerek kendilerine zarar vermelerini engelle
local weaponRaycastParams = RaycastParams.new()
weaponRaycastParams.FilterDescendantsInstances = {Players.LocalPlayer.Character}
local weaponRaycastResult = workspace:Raycast(tool.Handle.Position, directionVector, weaponRaycastParams)
-- Başlangıç ve bitiş konumları arasında herhangi bir nesneye vuruldu mu kontrol edin
local hitPosition
if weaponRaycastResult then
hitPosition = weaponRaycastResult.Position
-- Vuruş örneği bir karakter modelinin yavrusu olacak
-- Bir insansız modelde bulunursa, muhtemelen oyuncunun karakteridir
local characterModel = weaponRaycastResult.Instance:FindFirstAncestorOfClass("Model")
if characterModel then
local humanoid = characterModel:FindFirstChildWhichIsA("Humanoid")
if humanoid then
eventsFolder.DamageCharacter:FireServer(characterModel, hitPosition)
end
end
else
-- Maksimum lazer mesafesi üzerine dayanarak son konumu hesapla
hitPosition = tool.Handle.Position + directionVector
end
timeOfPreviousShot = tick()
eventsFolder.LaserFired:FireServer(hitPosition)
LaserRenderer.createLaser(tool.Handle, hitPosition)
end
local function toolEquipped()
tool.Handle.Equip:Play()
end
local function toolActivated()
if canShootWeapon() then
fireWeapon()
end
end
tool.Equipped:Connect(toolEquipped)
tool.Activated:Connect(toolActivated)

Lazer Renderlayıcı


local LaserRenderer = {}
local Debris = game:GetService("Debris")
local SHOT_DURATION = 0.15 -- Lazerin görülebildiği süre
-- Bir başlangıç ​​pozisyonundan son bir pozisyona doğru bir lazer ışını oluştur
function LaserRenderer.createLaser(toolHandle, endPosition)
local startPosition = toolHandle.Position
local laserDistance = (startPosition - endPosition).Magnitude
local laserCFrame = CFrame.lookAt(startPosition, endPosition) * CFrame.new(0, 0, -laserDistance / 2)
local laserPart = Instance.new("Part")
laserPart.Size = Vector3.new(0.2, 0.2, laserDistance)
laserPart.CFrame = laserCFrame
laserPart.Anchored = true
laserPart.CanCollide = false
laserPart.Color = Color3.fromRGB(255, 0, 0)
laserPart.Material = Enum.Material.Neon
laserPart.Parent = workspace
-- Kaldırılması ve temizlenmesi gereken Debris hizmetine lazer işını ekleyin
Debris:AddItem(laserPart, SHOT_DURATION)
-- Silahın atış sesini çal
local shootingSound = toolHandle:FindFirstChild("Activate")
if shootingSound then
shootingSound:Play()
end
end
return LaserRenderer

SunucuLazerYöneticisi


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local eventsFolder = ReplicatedStorage.Events
local LASER_DAMAGE = 10
local MAX_HIT_PROXIMITY = 10
-- Oyuncunun tuttuğu aletin kolu bulun
local function getPlayerToolHandle(player)
local weapon = player.Character:FindFirstChildOfClass("Tool")
if weapon then
return weapon:FindFirstChild("Handle")
end
end
local function isHitValid(playerFired, characterToDamage, hitPosition)
-- Karakter vuruşu ve vuruş pozisyonu arasındaki mesafeyi doğrula
local characterHitProximity = (characterToDamage.HumanoidRootPart.Position - hitPosition).Magnitude
if characterHitProximity > MAX_HIT_PROXIMITY then
return false
end
-- Duvarlardan atış yapıp yapmadığınızı kontrol edin
local toolHandle = getPlayerToolHandle(playerFired)
if toolHandle then
local rayLength = (hitPosition - toolHandle.Position).Magnitude
local rayDirection = (hitPosition - toolHandle.Position).Unit
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {playerFired.Character}
local rayResult = workspace:Raycast(toolHandle.Position, rayDirection * rayLength, raycastParams)
-- Karakter olmayan bir örnek vurulduysa, atışı görmezden gelin
if rayResult and not rayResult.Instance:IsDescendantOf(characterToDamage) then
return false
end
end
return true
end
-- Tüm müşterilere bir lazerın ateş edildiğini bildirin, böylece lazeri görebilirler
local function playerFiredLaser(playerFired, endPosition)
local toolHandle = getPlayerToolHandle(playerFired)
if toolHandle then
eventsFolder.LaserFired:FireAllClients(playerFired, toolHandle, endPosition)
end
end
function damageCharacter(playerFired, characterToDamage, hitPosition)
local humanoid = characterToDamage:FindFirstChildWhichIsA("Humanoid")
local validShot = isHitValid(playerFired, characterToDamage, hitPosition)
if humanoid and validShot then
-- Karakterden sağlığı kaldır
humanoid.Health -= LASER_DAMAGE
end
end
-- Etkinlikleri uygun işlevlere bağla
eventsFolder.DamageCharacter.OnServerEvent:Connect(damageCharacter)
eventsFolder.LaserFired.OnServerEvent:Connect(playerFiredLaser)

MüşteriLazerYöneticisi


local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LaserRenderer = require(Players.LocalPlayer.PlayerScripts:WaitForChild("LaserRenderer"))
local eventsFolder = ReplicatedStorage.Events
-- Diğer bir oyuncunun lazerini göster
local function createPlayerLaser(playerWhoShot, toolHandle, endPosition)
if playerWhoShot ~= Players.LocalPlayer then
LaserRenderer.createLaser(toolHandle, endPosition)
end
end
eventsFolder.LaserFired.OnClientEvent:Connect(createPlayerLaser)