Laserschlag-Erkennung

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

In diesem Tutorial lernen Sie, wie Sie einen Laser vom Blaster in Creating Player Tools und entdecken, ob er einen Spieler:intrifft.

Raycasting, um Kollisionen zu finden

Raycasting erstellt einen unsichtbaren Strahl von einer Startposition in eine bestimmte Richtung mit einer bestimmten Länge. Wenn der Strahl mit Objekten oder Terrain auf seinem Weg kollidiert, gibt er Informationen über die Kollision zurück, z. B. die Position und das Objekt, mit dem der Strahl kollidiert.

Raycast von A nach B kollidiert mit einer Wand

Die Maus Position finden

Bevor ein Laser geschossen werden kann, musst du zuerst wissen, wo der Spieler zielt. Dies kann durch Raycasting von der 2D-Maus-Position des Spieler:inauf dem Bildschirm direkt vor der Kamera in die Weltkollidieren. Der Laser wird mit dem Zielen des Spielers mit der Maus kollidieren.

  1. Öffnen Sie das ToolController -Skript innerhalb des Blaster-Tools von Creating Player Tools. Wenn Sie dieses Tutorial noch nicht abgeschlossen haben, können Sie das Blaster-Modell herunterladen und es in StarterPack einfügen.

  2. In der oberen Zeile des Skript, das. PL: die Skriptsdeklarieren Sie eine Konstante namens MAX_MOUSE_DISTANCE mit einem Wert von 1000 .

  3. Erstellen Sie eine Funktion namens getWorldMousePosition.


    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
    -- Verbinde Ereignisse mit passenden Funktionen
    tool.Equipped:Connect(toolEquipped)
    tool.Activated:Connect(toolActivated)
  4. Verwenden Sie die GetMouseLocation-Funktion von UserInputService, um die 2D-Mausposition des Spieler:inauf dem Bildschirm zu erhalten. Weisen Sie dies einer Variable mit dem Namen mouseLocation zu.


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

Nun ist die 2D-Maus-Position bekannt, seine X und Y Eigenschaften können als Argumente für die Class.Camera:ViewportPointToRay() -Funktion verwendet werden, die einen 1> Datatype.Ray1> vom Bildschirm in die Welterstellt.

  1. Verwende die X und Y Eigenschaften von mouseLocation als Argumente für die 1> Class.Camera:ViewportPointToRay()|ViewportPointToRay()1> Funktion. Weise dies einer Variable namens 4> screenToWorldRay4> zu.


    local function getWorldMousePosition()
    local mouseLocation = UserInputService:GetMouseLocation()
    -- Erstellen Sie einen Strahl aus der 2D-Maus-Position
    local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
    end

Es ist Zeit, die Funktion Raycast zu verwenden, um zu überprüfen, ob der Strahl ein Objekt trifft. Dies erfordert eine Startposition und einen Vektorkraft: In diesem Beispiel verwenden Sie die Eigenschaften und Richtungsvektoren von screenToWorldRay .

Die Länge des Richtungsvektors bestimmt, wie weit der Strahl reisen wird. Der Strahl muss so lang sein wie die MAX_MOUSE_DISTANCE, also musst du den Richtungsvektor um MAX_MOUSE_DISTANCE multiplizieren.

  1. Erkläre eine Variable namens DirectionVector und weise dem Wert screenToWorldRay.Direction mit Multiplikator MAX_MOUSE_DISTANCE zu.


    local function getWorldMousePosition()
    local mouseLocation = UserInputService:GetMouseLocation()
    -- Erstellen Sie einen Strahl aus der 2D-Maus位置
    local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
    -- Die Einheitsteuerungsrichtung des Strahls, der mit einer maximalen Distanz multipliziert wird
    local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
  2. Rufen Sie die Raycast Funktion des Arbeitsbereichs auf, indem Sie die Eingabe-Eigenschaft von screenToWorldRay als ersten Argument und 1> durationVector1> als zweiten übergeben. Verweisen Sie auf diesen Variablen mit dem Namen 4> raycastResult4>.


    local function getWorldMousePosition()
    local mouseLocation = UserInputService:GetMouseLocation()
    -- Erstellen Sie einen Strahl aus der 2D-Maus位置
    local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
    -- Die Einheitsteuerungsrichtung des Strahls, der mit einer maximalen Distanz multipliziert wird
    local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
    -- Raycast von der Ray-Herkunft in Richtung seiner Richtung
    local raycastResult = workspace:Raycast(screenToWorldRay.Origin, directionVector)

Kollisionsinformationen

Wenn die Raycast-Operation ein Objekt durch den Strahl getroffen findet, wird eine RaycastResult zurückgegeben, die Informationen über die Kollision zwischen dem Strahl und dem Objekt enthält.

RaycastResult-EigenschaftBeschreibung
InstanzDie BasePart oder Terrain Zelle, in der der Strahl kreuzte.
PositionWo sich die Intersektion befindet; Normalerweise ein Punkt direkt auf der Oberfläche eines Teils oder Gelände.
MaterialDas Material an der Kollisionsstelle.
NormalDer normale Vektor des interessierten Gesichts. Dies kann verwendet werden, um zu bestimmen, in welche Richtung das Gesicht zeigt.

Die Position Eigenschaft wird die Position des Objekts sein, über das die Maus mit der Maus positioniert ist. Wenn die Maus nicht über ein Objekt innerhalb einer MAX_MOUSE_DISTANCE Range schwebt, wird raycastResult null sein.

  1. Erstellen Sie ein if- Statement, um zu überprüfen, ob raycastResult existiert.

  2. Wenn raycastResult einen Wert hat, geben Sie seine Position Eigenschaftenzurück.

  3. Wenn raycastResult null ist, finden Sie das Ende des Raycast. Berechnen Sie die 3D-Position der Maus, indem Sie screenToWorldRay.Origin und directionVector zusammen fügen.


local function getWorldMousePosition()
local mouseLocation = UserInputService:GetMouseLocation()
-- Erstellen Sie einen Strahl aus der 2D-Maus位置
local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
-- Die Einheitsteuerungsrichtung des Strahls, der mit einer maximalen Distanz multipliziert wird
local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
-- Raycast von der Ray-Herkunft in Richtung seiner Richtung
local raycastResult = workspace:Raycast(screenToWorldRay.Origin, directionVector)
if raycastResult then
-- Kehre den 3D-Punkt der Intersektion zurück
return raycastResult.Position
else
-- Kein Objekt wurde getroffen, so dass die Position am Ende des Strahls berechnet wird
return screenToWorldRay.Origin + directionVector
end
end

Feuern Sie auf das Ziel

Da die 3D-Mausposition bekannt ist, kann sie als Zielposition verwendet werden, um einen Laser auf das Ziel zu feuern. Ein zweiter Strahl kann zwischen der Waffe des Spieler:inund der Zielposition mit der Strahlenwurf-Funktion kastiert werden.

  1. Erkläre eine Konstante namens MAX_LASER_DISTANCE an der Spitze des Skripts und weise sie auf 500 oder deine gewählte Reichweite für den Laserblaster zu.


    local UserInputService = game:GetService("UserInputService")
    local tool = script.Parent
    local MAX_MOUSE_DISTANCE = 1000
    local MAX_LASER_DISTANCE = 500
  2. Erstellen Sie eine Funktion namens fireWeapon unter der getWorldMousePosition Funktion.

  3. Rufen Sie getWorldMousePosition auf und weisen Sie das Ergebnis an eine Variable namens mousePosition zu. Dies wird die Zielposition für Raycast sein.


    -- Kein Objekt wurde getroffen, so dass die Position am Ende des Strahls berechnet wird
    return screenToWorldRay.Origin + directionVector
    end
    end
    local function fireWeapon()
    local mouseLocation = getWorldMousePosition()
    end
    local function toolEquipped()
    tool.Handle.Equip:Play()
    end

Diesmal wird der Richtungsvektor für die Raycast-Funktion die Richtung vom Werkzeug des Spieler:inzur Zielposition repräsentieren.

  1. Erkläre eine Variable namens targetDirection und berechne den Richtungsvektor, indem du die Toolposition von mouseLocation abziehst.

  2. Normalisieren Sie den Vector, indem Sie seine Eigenschaftenverwenden. Dies gibt ihm eine Größe von 1, was es einfach macht, später um eine Länge zu multiplizieren.


    local function fireWeapon()
    local mouseLocation = getWorldMousePosition()
    -- Berechnen Sie einen normalisierten Richtungsvektor und multiplizieren Sie ihn durch Laser-Entfernung
    local targetDirection = (mouseLocation - tool.Handle.Position).Unit
    end
  3. Erkläre eine Variable namens DirectionVector und weise ihr den targetDirection Multiplikator mit der MAX_LASER_DISTANCE zu.


    local targetDirection = (mouseLocation - tool.Handle.Position).Unit
    -- Die Richtung, in die die Waffe abgefeuert werden soll, multipliziert durch eine maximale Entfernung
    local directionVector = targetDirection * MAX_LASER_DISTANCE
    end

Ein RaycastParams-Objekt kann verwendet werden, um zusätzliche Parameter für die Funktion raycast zu speichern. Es wird in deinem Laserblaster verwendet, um sicherzustellen, dass der Raycast nicht mit dem Spieler, der die Waffe feuert, versehentlich kollidiert. Alle Teile, die in der Eigenschaft Datatype.RaycastParams.Filter

  1. Fortsetzen Sie die Funktion fireWeapon und erklären Sie eine Variable namens weaponRaycastParams . Weisen Sie einem neuen RaycastParams-Objekt zu.

  2. Erstellen Sie eine Tabelle, die den lokalen Charakter des Spieler:inenthält, und weisen Sie ihn an die weaponRaycastParams.FilterDescendantsInstancesEigenschaftenzu.

  3. Raycast von der Spieler:in, in eine Richtung in Richtung des directionVector. Denken Sie daran, dieses Mal weaponRaycastParams als Argument hinzuzufügen. Zuordnen Sie dies an eine Variable namens weaponRaycastResult.


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()
-- Berechnen Sie einen normalisierten Richtungsvektor und multiplizieren Sie ihn durch Laser-Entfernung
local targetDirection = (mouseLocation - tool.Handle.Position).Unit
-- Die Richtung, mit der die Waffe abgefeuert wird, multipliziert durch eine maximale Entfernung
local directionVector = targetDirection * MAX_LASER_DISTANCE
-- Ignoriere den Charakter des Spieler:in, um ihn daran zu hindern, sich selbst zu schaden
local weaponRaycastParams = RaycastParams.new()
weaponRaycastParams.FilterDescendantsInstances = {Players.LocalPlayer.Character}
local weaponRaycastResult = workspace:Raycast(tool.Handle.Position, directionVector, weaponRaycastParams)
end

Schließlich musst du überprüfen, dass die Raycast-Operation einen Wert zurückgegeben hat. Wenn ein Wert zurückgegeben wird, wurde ein Objekt von dem Laser getroffen und ein Laser zwischen der Waffe und dem Treffort erstellt. Wenn nichts zurückgegeben wurde, muss die endgültige Position berechnet werden, um den Laser zu erstellen.

  1. Erklären Sie eine leere Variable namens hitPosition .

  2. Verwenden Sie eine if-Anweisung, um zu überprüfen, ob weaponRaycastResult einen Wert hat. Wenn ein Objekt getroffen wurde, weisen Sie weaponRaycastResult.Position an 2> hitPosition2> .


    local weaponRaycastResult = workspace:Raycast(tool.Handle.Position, directionVector, weaponRaycastParams)
    -- Überprüfen Sie, ob irgendwelche Objekte zwischen der Start- und Endposition getroffen wurden
    local hitPosition
    if weaponRaycastResult then
    hitPosition = weaponRaycastResult.Position
    end
  3. Wenn weaponRaycastResult keinen Wert hat, berechnen Sie die Endposition des Raycast, indem Sie die Position des Werkzeuggriffs mit dem numberDirectionVector zusammenfügen. Weisen Sie dies an directionVector zu.


    local weaponRaycastResult = workspace:Raycast(tool.Handle.Position, directionVector, weaponRaycastParams)
    -- Überprüfen Sie, ob irgendwelche Objekte zwischen der Start- und Endposition getroffen wurden
    local hitPosition
    if weaponRaycastResult then
    hitPosition = weaponRaycastResult.Position
    else
    -- Berechnen Sie die Endposition basierend auf der maximalen Laser-Entfernung
    hitPosition = tool.Handle.Position + directionVector
    end
    end
  4. Navigate to the toolActivated function and call the fireWeapon function, so that the laser fires each time the tool is activated.


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

Objekt-Treffer überprüfen

Um zu finden, ob das von dem Laser getroffene Objekt Teil eines Charakters des Spieler:inist oder nur ein Teil der Szenerie, musst du nach einem Humanoid suchen, da jeder Charakter eines hat.

Zuerst musst du das Charaktermodell finden. Wenn ein Teil des Charakters getroffen wurde, kannst du nicht davon ausgehen, dass der Elternteil des Objekts getroffen wurde. Der Laser könnte einen Körperteil, ein Zubehör oder ein Tooltreffen, alle von denen sich in verschiedenen Teilen der Charakterniere befinden.

Sie können FindFirstAncestorOfClass verwenden, um ein Charaktermodell-Vorläufer des Objekts zu finden, das vom Laser getroffen wurde, wenn es vorhanden ist. Wenn Sie ein Modell finden und es ein Humanoid enthält, können Sie es in der Regel als Charakter annehmen.

  1. Fügen Sie den markierten Code unten zu der weaponRaycastResult if Anweisung hinzu, um zu überprüfen, ob ein Charakter getroffen wurde.


    -- Überprüfen Sie, ob irgendwelche Objekte zwischen der Start- und Endposition getroffen wurden
    local hitPosition
    if weaponRaycastResult then
    hitPosition = weaponRaycastResult.Position
    -- Die zu treffende Instanz wird ein Kind eines Modellsein
    -- Wenn ein Humanoid im Modell gefunden wird, ist es wahrscheinlich der Charakter eines Spieler:in
    local characterModel = weaponRaycastResult.Instance:FindFirstAncestorOfClass("Model")
    if characterModel then
    local humanoid = characterModel:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    print("Player hit")
    end
    end
    else
    -- Berechnen Sie die Endposition basierend auf der maximalen Laser-Entfernung
    hitPosition = tool.Handle.Position + directionVector
    end

Jetzt sollte der Laserblaster jedes Mal, wenn die Raycast-Operation einen anderen Spieler:intrifft, Player hit zur Ausgabe-Fenster drucken.

Testen mit mehreren Spielern

Zwei Spieler sind erforderlich, um zu testen, ob die Waffenraycast andere Spieler findet, sodass Sie einen lokalen Server starten müssen.

  1. Wählen Sie die Test -Registerkarte in Studio.

  2. Stellen Sie sicher, dass die Dropdown-Liste auf "2 Spieler" eingestellt ist und klicken Sie auf die Schaltfläche "Starten", um einen lokalen Server mit 2 Clients zu starten mit 3 Fenstern. Das erste Fenster wird sein. Das andere Fenster wird die Clients für Player1 und Player2 sein.

  3. Auf einem Client testen Sie das andere Spieler mit der Waffe, indem Sie auf sie klicken. "Player hat" sollte jedes Mal angezeigt werden, wenn ein Spieler erschossen wird.

Weitere Informationen finden Sie unter der Registerkarte Test hier.

Die Laserposition finden

Der Blaster sollte einen roten Lichtstrahl auf sein Ziel abfeuern. Die Funktion für dieses wird in einem ModuleScript sein, sodass sie später in anderen Skripts wiederverwendet werden kann. Zuerst muss das Skript den Ort finden, an dem der Laserstrahl gerendert werden soll.

  1. Erstellen Sie ein ModuleScript mit dem Namen LaserRenderer , der unter StarterPlayer.Scripts unter StarterPlayer übergeordnet ist.

  2. Öffnen Sie das Skript und benennen Sie die Modul-Tabelle in den Namen des Skripts LaserRender .

  3. Erkläre eine Variable namens SHOT_DURATION mit einem Wert von 0.15 . Dies wird die Zeit sein, die der Laser für sichtbar ist (in Sekunden).

  4. Erstellen Sie eine Funktion von LaserRender namens createLaser mit zwei Parametern wie toolHandle und endPosition .


    local LaserRenderer = {}
    local SHOT_DURATION = 0.15 -- Zeit, für die der Laser sichtbar ist
    -- Erstellen Sie einen Laserstrahl von einer Startposition in Richtung einer Endposition
    function LaserRenderer.createLaser(toolHandle, endPosition)
    end
    return LaserRenderer
  5. Erkläre eine Variable namens startPosition und setze die Eigenschaft Position von toolHandle als ihren Wert. Dies wird die Position des Lasers des Spieler:insein.

  6. Erkläre eine Variable namens laserDistance und subtrahiere endPosition von startPosition, um den Unterschied zwischen den beiden Vektoren zu finden. Verwende die Eigenschaft 1> Magnitude1> von dieser, um die Länge des Laserstrahls zu erhalten.


    function LaserRenderer.createLaser(toolHandle, endPosition)
    local startPosition = toolHandle.Position
    local laserDistance = (startPosition - endPosition).Magnitude
    end
  7. Erkläre eine laserCFrame Variable, um die Position und Ausrichtung des Laserstrahls zu speichern. Die Position muss der Mitte des Starts und Ends des Laserstrahls sein. Verwende CFrame.lookAt , um einen neuen CFrame


    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

Erstellen der Laser-Teil

Jetzt, da Sie wissen, wo Sie einen Laserstrahl erstellen müssen, müssen Sie den Strahl selbst hinzufügen. Dies kann mit einem Neon-Teil leicht getan werden.

  1. Erkläre eine Variable laserPart und weise ihr eine neue Part Instanz zu.

  2. Setzen Sie die folgenden Eigenschaften von laserPart :

    1. Größe : Vector3.new(0.2, 0.2, laserDistance)
    2. CFrame : laserCFrame
    3. Verankert : true
    4. Kann kollidieren : fals
    5. Farbe : Color3.fromRGB(225, 0, 0) (eine starke rote Farbe)
    6. Material : Enum.Material.Neon
  3. Elternteil laserPart zu Workspace .

  4. Fügen Sie das Teil dem Debris -Dienst hinzu, damit es nach der Anzahl der Sekunden in der SHOT_DURATION Variable entfernt wird.


    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
    -- Fügen Sie Laserstrahl dem Debris-Dienst hinzu, um entfernt und sauber zu werden
    Debris:AddItem(laserPart, SHOT_DURATION)
    end

Jetzt ist die Funktion, den Laserstrahl zu rendern, fertig, sie kann von dem ToolController aufgerufen werden.

  1. In der obersten Zeile des Skript, das. PL: die Skripts, declare eine Variable namens LaserRenderer und erfordere das LaserRenderer-ModulScript, das in PlayerScripts befindet sich.


    local UserInputService = game:GetService("UserInputService")
    local Players = game:GetService("Players")
    local LaserRenderer = require(Players.LocalPlayer.PlayerScripts.LaserRenderer)
    local tool = script.Parent
  2. At the bottom of the fireWeapon function, call the LaserRender createLaser function using the tool handle and hitPosition as arguments.


    -- Berechnen Sie die Endposition basierend auf der maximalen Laser-Entfernung
    hitPosition = tool.Handle.Position + directionVector
    end
    LaserRenderer.createLaser(tool.Handle, hitPosition)
    end
  3. Testen Sie die Waffe, indem Sie auf die Schaltfläche Spielen klicken. Ein Laserstrahl sollte zwischen der Waffe und der Maus sichtbar sein, wenn das Werkzeug aktiviert ist.

Waffenfeuerrate steuern

Waffen benötigen eine Verzögerung zwischen jedem Schuss, um die Spieler daran zu hindern, zu viel Schaden in einer kurzen Zeit zu verursachen. Dies kann durch den Check kontrolliert werden, ob genug Zeit seit dem letzten Feuer eines Spielers vergangen ist.

  1. Erklären Sie eine Variable oben in der ToolController mit dem Namen FIRE_RATE . Dies wird die minimale Zeit zwischen jedem Schuss sein. Gib ihm einen Wert deiner Wahl; dieses Beispiel verwendet 0.3 Sekunden.

  2. Erkläre eine weitere Variable unterhalb mit dem Namen timeOfPreviousShot mit einem Wert von 0 . Dies speichert das letzte Mal, dass der Spieler feuert, und wird mit jedem Schuss aktualisiert.


    local MAX_MOUSE_DISTANCE = 1000
    local MAX_LASER_DISTANCE = 300
    local FIRE_RATE = 0.3
    local timeOfPreviousShot = 0
  3. Erstellen Sie eine Funktion namens kannShootWeapon mit keine Parametern. Diese Funktion wird betrachten, wie viel Zeit seit dem letzten Schuss vergangen ist und die Rückgabe wahr oder falsch ist.


    local FIRE_RATE = 0.3
    local timeOfPreviousShot = 0
    -- Überprüfen, ob genug Zeit vergangen ist, seitdem der vorherige Schuss abgefeuert wurde
    local function canShootWeapon()
    end
    local function getWorldMousePosition()
  4. In der Funktion declare a variable namens currentTime ; weise dem Ergebnis der Aufrufe der Funktion tick() zu. Dies gibt an, wie viel Zeit seit dem 1. Januar 1970 (ein beliebiges Datum, das weit verbreitet verwendet wird, um die Zeit zu berechnen) verstrichen ist.

  5. Subtrahiere den timeOfPreviousShot von currentTime und gib false zurück, wenn das Ergebnis kleiner als 1> FIRE_RATE1> ist; ansonsten gib 4> true4> zurück.


    -- Überprüfen, ob genug Zeit vergangen ist, seitdem der vorherige Schuss abgefeuert wurde
    local function canShootWeapon()
    local currentTime = tick()
    if currentTime - timeOfPreviousShot < FIRE_RATE then
    return false
    end
    return true
    end
  6. Am Ende der Funktion fireWeapon aktualisieren Sie timeOfPreviousShot jedes Mal, wenn die Waffe mit tick abgefeuert wird.


    hitPosition = tool.Handle.Position + directionVector
    end
    timeOfPreviousShot = tick()
    LaserRenderer.createLaser(tool.Handle, hitPosition)
    end
  7. In der toolActivated Funktion erstellen Sie ein if Statistik und rufen Sie canShootWeapon auf, um zu überprüfen, ob die Waffe abgefeuert werden kann.


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

Wenn Sie den Blaster testen, sollten Sie finden, dass, egal wie schnell Sie klicken, immer eine kurze 0,3 Sekunden Verzögerung zwischen jedem Schuss.

Schaden am Spieler

Clients können anderen Clients nicht direkt Schaden zufügen; Der Server muss für die Ausgabe von Schaden verantwortlich sein, wenn ein Spieler getroffen wird.

Clients können ein RemoteEvent verwenden, um dem Server zu sagen, dass ein Charakter getroffen wurde. Diese sollten in ReplicatedStorage gespeichert werden, wo sie sowohl für den Client als auch für den Server sichtbar sind.

  1. Erstellen Sie einen Ordner in ReplicatedStorage namens Events.

  2. Fügen Sie ein RemoteEvent in den Events-Ordner ein und benennen Sie es SchadensCharakter .

  3. In ToolController , erstellen Sie Variablen am Beginn des Skripts für ReplicatedStorage und die Events-Ordner.


    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. Ersetzen Sie die "Player hit" druck statement in fireWeapon mit einer Reihe von Lua, um das SchadensCharacter Remote-Ereignis mit der 1> characterModel -Variable als Argument zu feuern.


    local characterModel = weaponRaycastResult.Instance:FindFirstAncestorOfClass("Model")
    if characterModel then
    local humanoid = characterModel:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    eventsFolder.DamageCharacter:FireServer(characterModel)
    end
    end
    else
    -- Berechnen Sie die Endposition basierend auf der maximalen Laser-Entfernung
    hitPosition = tool.Handle.Position + directionVector
    end

Der Server muss Schaden am Spieler verursachen, der getroffen wurde, wenn das Ereignis ausgelöst wird.

  1. Fügen Sie ein Skript in ServerScriptService ein und nennen Sie es ServerLaserManager.

  2. Erkläre eine Variable namens LASER_DAMAGE und setze sie auf 10 oder einen Wert deiner Wahl.

  3. Erstellen Sie eine Funktion namens damageCharacter mit zwei Parametern wie playerFired und characterToDamage .

  4. In der Funktion finden Sie den Charakter's Humanoid und subtrahieren Sie LASER_DAMAGE von seiner Gesundheit.

  5. Verbinden Sie die Funktion damageCharacter mit dem damageCharacter Remote-Ereignis im Ordner Ereignisse.


    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
    -- Leben vom Charakter entfernen
    humanoid.Health -= LASER_DAMAGE
    end
    end
    -- Verbinde Ereignisse mit passenden Funktionen
    eventsFolder.DamageCharacter.OnServerEvent:Connect(damageCharacter)
  6. Testen Sie den Blaster mit 2 Spielern, indem Sie einen lokalen Server starten. Wenn Sie den anderen Spieler:inschießen, wird seine Gesundheit um die zugewiesene Zahl LASER_DAMAGE verringert.

Other Player's Laserstrahlen rendern

Derzeit wird der Laserstrahl vom Client erstellt, der die Waffe feuert, so dass nur sie den Laserstrahl sehen können.

Wenn der Laserstrahl auf dem Server erstellt wurde, dann würde jeder ihn sehen können. jedoch, es würde eine kleine Verzögerung zwischen dem Client, der die Waffe schießt, und dem Server geben, der die Information über den Schuss erhält. Dies würde bedeuten, dass der Client, der die Waffe schießt, eine Verzögerung sehen würde, zwischen dem Zeitpunkt, an dem sie die Waffe aktivieren und sehen, und dem Zeitpunkt, an dem sie den Laserstrahl erhalten.

Um dieses Problem zu lösen, wird jedes Client seine eigenen Laserstrahlen erstellen. Dies bedeutet, dass der Client, der die Waffe schießt, sofort den Laserstrahl sieht. Andere Clients erleben eine kleine Verzögerung zwischen der Zeit, in der ein anderer Spieler schießt und ein Laser erscheint. Dies ist das beste Fall-Szenario: Es gibt keine Möglichkeit, einen Client's Laser an andere Clients zu übermitteln.

Client des Schießers

Zuerst muss der Client dem Server sagen, dass er einen Laser abgefeuert hat und die Endposition bereitgestellt.

  1. Fügen Sie einen RemoteEvent in den Events-Ordner in ReplicatedStorage ein und benennen Sie ihn LaserFired .

  2. Suchen Sie die Funktion fireWeapon im Skript, das. PL: die Skripts. Am Ende der Funktion feuern Sie das LaserFired-Remote-Ereignis mit 1> hitPosition1> als Argumentan.


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

Der Server

Der Server muss jetzt das Ereignis erhalten, das der Client abgefeuert hat, und allen Clients die Start- und Endposition des Laserstrahls mitteilen, damit sie ihn auch rendern können.

  1. Im ServerLaserManager Skript, das. PL: die Skripts, erstellen Sie eine Funktion namens playerFiredLaser über damageCharacter mit zwei Parametern wie 1> playerFired1> und 4> endPosition4>.

  2. Verbinden Sie die Funktion mit dem LaserFired Remote-Ereignis.


    -- Benachrichtigen Sie alle Clients, dass ein Laser abgefeuert wurde, damit sie den Laser anzeigen können
    local function playerFiredLaser(playerFired, endPosition)
    end

    -- Verbinde Ereignisse mit passenden Funktionen
    eventsFolder.DamageCharacter.OnServerEvent:Connect(damageCharacter)
    eventsFolder.LaserFired.OnServerEvent:Connect(playerFiredLaser)

Der Server benötigt die Startposition des Lasers. Dies könnte vom Client gesendet werden, aber es ist am besten, dem Client zu vertrauen, wo möglich. Die Waffengriffposition des Charakters wird die Startposition sein, so dass der Server sie von dort aus finden kann.

  1. Erstellen Sie eine Funktion getPlayerToolHandle über der Funktion playerFiredLaser mit einem Parameter namens player.

  2. Verwenden Sie den folgenden Code, um den Charakter des Spieler:innach der Waffe zu suchen und das Handling-Objekt zurückzugeben.


    local LASER_DAMAGE = 10
    -- Finden Sie die Griff des Werkzeugs, das der Spieler hält
    local function getPlayerToolHandle(player)
    local weapon = player.Character:FindFirstChildOfClass("Tool")
    if weapon then
    return weapon:FindFirstChild("Handle")
    end
    end
    -- Benachrichtigen Sie alle Clients, dass ein Laser abgefeuert wurde, damit sie den Laser anzeigen können
    local function playerFiredLaser(playerFired, endPosition)

Der Server kann jetzt auf dem LaserFired Remote-Ereignis FireAllClients aufrufen, um die Informationen zu senden, die erforderlich sind, um den Laser an die Clients zu rendern. Dies beinhaltet den 1> Spieler1>, der den Laser abgefeuert hat (so dass der Client für diesen Spieler nicht den Laser zweimal rendern muss), den 4> Griff des Blasters

  1. In der playerFiredLaser-Funktion rufen Sie die getPlayerToolHandle-Funktion mit playerFired als Argument auf und weisen den Wert an eine Variable namens 1> toolHandle1> zu.

  2. Wenn toolHandle existiert, fire das LaserFired-Ereignis für alle Clients mit playerFired , toolHandle und 1> endPosition1> als Argumente.


    -- Benachrichtigen Sie alle Clients, dass ein Laser abgefeuert wurde, damit sie den Laser anzeigen können
    local function playerFiredLaser(playerFired, endPosition)
    local toolHandle = getPlayerToolHandle(playerFired)
    if toolHandle then
    eventsFolder.LaserFired:FireAllClients(playerFired, toolHandle, endPosition)
    end
    end

Rendern auf den Clients

Jetzt FireAllClients wurde aufgerufen, jedes Client wird ein Ereignis vom Server erhalten, um einen Laserstrahl zu rendern. Jeder Client kann das Laserformer-Modul von früher wiederverwenden, um den Laserstrahl mit dem Schalter position und Endposition des Tool, die vom Server gesendet wird, zu rendern. Der Spieler, der den Laserstrahl zuerst gesendet hat, sollte dieses Ereignis ignorieren, sonst sehen Sie 2 Las

  1. Erstellen Sie ein lokales Skript in StarterPlayerScripts, die ClientLaserManager heißen.

  2. Im Skript, das. PL: die Skriptsbenötigen Sie das Laserrency-Render-Modul .

  3. Erstellen Sie eine Funktion namens createPlayerLaser mit den Parametern playerWhoShot , toolHandle und 1> endPosition1>.

  4. Verbinden Sie die Funktion mit dem LaserFired Remote-Ereignis in der Registerkarte Events.

  5. In der Funktion verwenden Sie eine if Anweisung, um zu überprüfen, ob playerWhoShot nicht gleich ist 1> des lokalen Spielers.

  6. In der if-Anweisung, rufen Sie die Funktion createLaser aus dem LaserRender-Modul mit toolHandle und endPosition als Argumente auf.


    local Players = game:GetService("Players")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local LaserRenderer = require(script.Parent:WaitForChild("LaserRenderer"))
    local eventsFolder = ReplicatedStorage.Events
    -- Zeigen Sie den Laser eines anderen Spieler:inan
    local function createPlayerLaser(playerWhoShot, toolHandle, endPosition)
    if playerWhoShot ~= Players.LocalPlayer then
    LaserRenderer.createLaser(toolHandle, endPosition)
    end
    end
    eventsFolder.LaserFired.OnClientEvent:Connect(createPlayerLaser)
  7. Testen Sie den Blaster mit 2 Spielern, indem Sie einen lokalen Server starten. Positionieren Sie jeden Client auf verschiedenen Seiten Ihres Monitors, damit Sie beide Fenster gleichzeitig sehen können. Wenn Sie auf einen Client schießen, sollten Sie den Laser auf der anderen Seite des Monitors sehen.

Soundeffekte

Der Schießeffekt spielt derzeit nur auf dem Client, der das Projektil schießt. Du musst den Code bewegen, um den Sound zu spielen, damit andere Spieler ihn auch hören können.

  1. Im ToolController -Skript navigiere zur toolActivated -Funktion und entferne die Zeile, die den Aktivieren-Sound wiedergibt.


    local function toolActivated()
    if canShootWeapon() then
    fireWeapon()
    end
    end
  2. In der unteren Hälfte der createLaser -Funktion in LaserRender , declare eine Variable namens schießensound und verwende die Methode 2>Class.Instance:FindFirstChild()|FindFirstChild()2> , um nach dem 5> Aktivieren5>-Sound zu suchen.

  3. Verwenden Sie eine if Anweisung, um zu überprüfen, ob shootingSound existiert; wenn es so ist, rufen Sie seine Play-Funktion auf.


    laserPart.Parent = workspace
    -- Fügen Sie Laserstrahl dem Debris-Dienst hinzu, um entfernt und sauber zu werden
    Debris:AddItem(laserPart, SHOT_DURATION)
    -- Spielen Sie den Schuss des Waffenklangs
    local shootingSound = toolHandle:FindFirstChild("Activate")
    if shootingSound then
    shootingSound:Play()
    end
    end

Verriegelung von Fernzündungen mit der Überprüfung

Wenn der Server keine Daten von eingehenden Anfragen überprüft, kann ein Hacker entfernte Funktionen und Ereignisse missbrauchen und sie verwenden, um gefälschte Werte auf den Server zu senden. Es ist wichtig, Server-seitige Überprüfung zu verwenden, um dies zu verhindern.

In seiner aktuellen Form ist das SchadensCharacter- Remote-Ereignis sehr verwundbar gegen Angriffe. Hacker könnten dieses Ereignis verwenden, um jeden Spieler im Spiel zu schaden, ohne sie zu schießen.

Die Überprüfung ist der Prozess, bei dem überprüft wird, ob die Werte, die an den Server gesendet werden, realistisch sind. In diesem Fall muss der Server:

  • Überprüfen Sie, ob die Entfernung zwischen dem Spieler und der Position, die vom Laser getroffen wird, innerhalb eines bestimmten Grenzbereichs liegt.
  • Raycast zwischen der Waffe, die den Laser abgefeuert hat, und der Schussposition, um sicherzustellen, dass der Schuss möglich ist und nicht durch irgendwelche Wände geht.

Client

Der Client muss den Server die Position senden, die vom Raycast getroffen wird, damit er die Reichweite realistisch überprüfen kann.

  1. In ToolController navigieren Sie zur Zeile, in der das Remote-Ereignis für Schaden im fireWeapon-Funktionsbereich ausgeführt wird.

  2. Füge hitPosition als Argument hinzu.


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

Server

Der Client sendet jetzt einen zusätzlichen Parallel über das Schaden-Charakter-Remote-Ereignis, sodass der ServerLaserManager angepasst werden muss, um ihn anzunehmen.

  1. Im ServerLaserManagerSkript, das. PL: die Skriptsfügen Sie einen hitPosition-Parameter an die damageCharacter-Funktion hinzu.


    function damageCharacter(playerFired, characterToDamage, hitPosition)
    local humanoid = characterToDamage:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    -- Leben vom Charakter entfernen
    humanoid.Health -= LASER_DAMAGE
    end
    end
  2. Unter der getPlayerToolHandle-Funktion erstellen Sie eine Funktion namens isHitValid mit drei Parametern: playerFired, 2> characterToDamage2> und 5> hitPosition5>.


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

Der erste Check wird die Distance zwischen der Position des Treffers und dem Charakter Treffer sein.

  1. Erkläre eine Variable namens MAX_HIT_PROXIMITY an der Spitze des Skripts und weise ihr einen Wert von 10 zu. Dies wird die maximale Distanz zwischen dem Treffer und dem Charakter sein. Ein Toleranz ist erforderlich, da der Charakter seit der Client-Feuerung des Ereignisses etwas versetzt sein kann.


    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local eventsFolder = ReplicatedStorage.Events
    local LASER_DAMAGE = 10
    local MAX_HIT_PROXIMITY = 10
  2. In der isHitValid Funktion berechnen Sie die Entfernung zwischen dem Charakter und der Treffposition. Wenn die Entfernung größer als MAX_HIT_PROXIMITY ist, dann geben Sie false zurück.


    local function isHitValid(playerFired, characterToDamage, hitPosition)
    -- Überprüfen Sie die Entfernung zwischen dem Charakter Treffer und der Trefferposition
    local characterHitProximity = (characterToDamage.HumanoidRootPart.Position - hitPosition).Magnitude
    if characterHitProximity > MAX_HIT_PROXIMITY then
    return false
    end
    end

Die zweite Prüfung beinhaltet eine Raycast zwischen der Waffe, die abgefeuert wurde, und der Treffposition. Wenn die Raycast ein Objekt zurückgibt, das nicht der Charakter ist, können Sie davon ausgehen, dass der Schuss ungültig ist, da etwas den Schuss blockiert.

  1. Kopiere den Code unten, um diesen überprüfenauszuführen. Return true am Ende der Funktion: Wenn es das beendenerreicht, haben alle Checks bestanden.


    local function isHitValid(playerFired, characterToDamage, hitPosition)
    -- Überprüfen Sie die Entfernung zwischen dem Charakter Treffer und der Trefferposition
    local characterHitProximity = (characterToDamage.HumanoidRootPart.Position - hitPosition).Magnitude
    if characterHitProximity > 10 then
    return false
    end
    -- Überprüfen Sie, ob Sie durch Wände schießen
    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)
    -- Wenn eine Instanz getroffen wurde, die nicht der Charakter war, dann ignoriere den Schuss
    if rayResult and not rayResult.Instance:IsDescendantOf(characterToDamage) then
    return false
    end
    end
    return true
    end
  2. Erkläre eine Variable in der damageCharacter Funktion namens validShot , die das Ergebnis eines Anrufs zur isHitValid Funktion mit drei Argumenten zuweist: 1> playerFired1>, 4> characterToDamage4> und 7> hitPosition7>.

  3. In der folgenden if-Anweisung fügen Sie einen und Operator hinzu, um zu überprüfen, ob validShot. wahr ist.


    function damageCharacter(playerFired, characterToDamage, hitPosition)
    local humanoid = characterToDamage:FindFirstChildWhichIsA("Humanoid")
    local validShot = isHitValid(playerFired, characterToDamage, hitPosition)
    if humanoid and validShot then
    -- Leben vom Charakter entfernen
    humanoid.Health -= LASER_DAMAGE
    end
    end

Nun ist das SchadensCharacter-Remote-Ereignis sicherer und wird die meisten Spieler davon abhalten, es zu missbrauchen. Beachten Sie, dass einige böswillige Spieler oft Möglichkeiten finden, um die Überprüfung zu umgehen; das Gewährleisten von Remote-Ereignissen ist ein kontinuierlicher Prozess.

Ihr Laserblaster ist jetzt fertig, mit einem grundlegenden Treffer-Erkennungssystem, das Raycasting verwendet. Versuchen Sie das Detecting User-Input Tutorial, um herauszufinden, wie Sie einen Neuladen-Aktion zu Ihrem Laserblaster hinzufügen können, oder erstellen Sie eine lustige Spielkarte und versuchen Sie Ihren Laserblaster mit anderen Spielern!

End-Code

ToolController


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
-- Überprüfen, ob genug Zeit vergangen ist, seitdem der vorherige Schuss abgefeuert wurde
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()
-- Erstellen Sie einen Strahl aus der 2D-Maus-Position
local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
-- Die Einheitsteuerungsrichtung des Strahls, der mit einer maximalen Distanz multipliziert wird
local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
-- Raycast von der roy's Ursprung in Richtung seiner Richtung
local raycastResult = workspace:Raycast(screenToWorldRay.Origin, directionVector)
if raycastResult then
-- Kehre den 3D-Punkt der Intersektion zurück
return raycastResult.Position
else
-- Kein Objekt wurde getroffen, so dass die Position am Ende des Strahls berechnet wird
return screenToWorldRay.Origin + directionVector
end
end
local function fireWeapon()
local mouseLocation = getWorldMousePosition()
-- Berechnen Sie einen normalisierten Richtungsvektor und multiplizieren Sie ihn durch Laser-Entfernung
local targetDirection = (mouseLocation - tool.Handle.Position).Unit
-- Die Richtung, in die die Waffe abgefeuert werden soll, multipliziert durch eine maximale Entfernung
local directionVector = targetDirection * MAX_LASER_DISTANCE
-- Ignoriere den Charakter des Spieler:in, um ihn daran zu hindern, sich selbst zu schaden
local weaponRaycastParams = RaycastParams.new()
weaponRaycastParams.FilterDescendantsInstances = {Players.LocalPlayer.Character}
local weaponRaycastResult = workspace:Raycast(tool.Handle.Position, directionVector, weaponRaycastParams)
-- Überprüfen Sie, ob irgendwelche Objekte zwischen der Start- und Endposition getroffen wurden
local hitPosition
if weaponRaycastResult then
hitPosition = weaponRaycastResult.Position
-- Die zu treffende Instanz wird ein Kind eines Modellsein
-- Wenn ein Humanoid im Modell gefunden wird, ist es wahrscheinlich der Charakter eines Spieler:in
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
-- Berechnen Sie die Endposition basierend auf der maximalen Laser-Entfernung
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)

LaserRenderer


local LaserRenderer = {}
local Debris = game:GetService("Debris")
local SHOT_DURATION = 0.15 -- Zeit, für die der Laser sichtbar ist
-- Erstellen Sie einen Laserstrahl von einer Startposition in Richtung einer Endposition
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
-- Fügen Sie Laserstrahl dem Debris-Dienst hinzu, um entfernt und sauber zu werden
Debris:AddItem(laserPart, SHOT_DURATION)
-- Spielen Sie den Schuss des Waffenklangs
local shootingSound = toolHandle:FindFirstChild("Activate")
if shootingSound then
shootingSound:Play()
end
end
return LaserRenderer

ServerLaserManager


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local eventsFolder = ReplicatedStorage.Events
local LASER_DAMAGE = 10
local MAX_HIT_PROXIMITY = 10
-- Finden Sie die Griff des Werkzeugs, das der Spieler hält
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)
-- Überprüfen Sie die Entfernung zwischen dem Charakter Treffer und der Trefferposition
local characterHitProximity = (characterToDamage.HumanoidRootPart.Position - hitPosition).Magnitude
if characterHitProximity > MAX_HIT_PROXIMITY then
return false
end
-- Überprüfen Sie, ob Sie durch Wände schießen
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)
-- Wenn eine Instanz getroffen wurde, die nicht der Charakter war, dann ignoriere den Schuss
if rayResult and not rayResult.Instance:IsDescendantOf(characterToDamage) then
return false
end
end
return true
end
-- Benachrichtigen Sie alle Clients, dass ein Laser abgefeuert wurde, damit sie den Laser anzeigen können
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
-- Leben vom Charakter entfernen
humanoid.Health -= LASER_DAMAGE
end
end
-- Verbinde Ereignisse mit passenden Funktionen
eventsFolder.DamageCharacter.OnServerEvent:Connect(damageCharacter)
eventsFolder.LaserFired.OnServerEvent:Connect(playerFiredLaser)

ClientLaserManager


local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LaserRenderer = require(Players.LocalPlayer.PlayerScripts:WaitForChild("LaserRenderer"))
local eventsFolder = ReplicatedStorage.Events
-- Zeigen Sie den Laser eines anderen Spieler:inan
local function createPlayerLaser(playerWhoShot, toolHandle, endPosition)
if playerWhoShot ~= Players.LocalPlayer then
LaserRenderer.createLaser(toolHandle, endPosition)
end
end
eventsFolder.LaserFired.OnClientEvent:Connect(createPlayerLaser)