Wprowadzanie zachowań Blastera

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

implementowanie zachowań blastera jest procesem programowania eksplozji mechanika w doświadczeniach strzelcy pierwszej osoby. Chociaż gracze mogą eksplodować jednym kliknięciem lub naciśnięciem przycisku, tworzenie satysfakcjonującego i dokładnego zachowania eksplozji jest ważne, ponieważ poprawia to zabawę graczy.

Używając do referencji 示例 laser tag experience, ta sekcja tutorialu uczy cię o skryptach za implementacją zachowania laserowego dla dwóch różnych typów laserów, w tym kierunkach:

  • Wykrywanie, gdy gracze naciskają przycisk wybuchu.
  • Sprawdzenie, czy gracz może użyć swojego blastera, jeśli niedawno naciągnął przycisk „Explosja”.
  • Generowanie danych eksplozji, które mówią serwerowi, kto inicjował eksplozję, skąd pochodzi i jakie było ostateczne miejsce docelowe każdego lasera.
  • Powiadomienie serwera o danym eksplozji, aby mógł wykonać odpowiednie działania, jeśli eksplozja uderzyła inną gracz.
  • Zresetowanie blastera między każdym atakiem, aby dać blasterowi wystarczająco dużo czasu na schnięcie, zanim może eksplodować ponownie.

Po zakończeniu tej sekcji dowiesz się o skryptach, które umożliwiają blasterowi wykrycie, gdy jego pociski kolidują z innymi graczami, a potem odejmij odpowiednią ilość zdrowia zgodnie z każdym wpisywaćblastera.

Wykryj wejście gracza

Pierwszym krokiem do wdrożenia zachowania blastera jest słuchanie, gdy gracz nacisnął przycisk wybuchowy. Typ wejścia, który używają gracze do naciskania przycisku wybuchowego, zależy od urządzenia, z którego korzystają do uzyskania dostępu do doświadczenia. Na przykład, wtyczka laserowa do przycisku wybuchowego wspiera sterowanie myszką

Ten kod klienta używa ContextActionService, aby związać MouseButton1 i ButtonR2 z akcjiwybuchową. Oznacza to, że za każdym razem, gdy gracz naciśnie lewy przycisk myszy lub przycisk R2 na urządzeniu mobilnym, wt

Przetwarzacz danych użytkownika

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

Kolejnym ważnym uzupełnieniem jest użycie Enum.UserInputState.Begin w definicji onBlasterActivated(). Wiele interakcji interfejsu użytkownika, takich jak wybór blastera w tym przykładzie, nie następuje, dopóki przycisk nie pojawi się ( Enum.UserInput

Aby pokazać, możesz zmienić Enum.UserInputState.Begin na Enum.UserInputState.End, a następnie przetestować, jak reakcja na eksplozję wpływa na grę w doświadczeniu. Na przykład, jeśli gracze mogą przytrzymać przycisk bez uruchomienia eksplozji, jak to może zmienić ich doświadczenie, gdy tagują innych graczy?

Przetwarzacz danych użytkownika

local function onBlasterActivated(_actionName: string,
inputState: Enum.UserInputState, _inputObject: InputObject)
if inputState == Enum.UserInputState.End then -- aktualizowana linia, upewnij się, że zmieniłeś wstecz
attemptBlastClient()
end
end

Sprawdź, czy gracz może eksplodować

Po wykryciu przez UserInputHandler przycisku lub uderzenia ekranu, wzywa ReplicatedStorage > Blaster

możliwość wykonania

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

Jeśli

Ta lekka przerwa zapobiega, że możesz eksplodować tak szybko, jak możesz klikać. Na przykład, jeśli zmienisz funkcję zawsze return true, możesz szybko eksplodować swojego blastera bez żadnego opóźnienia, co jest nieprawdopodobne dla rozgrywkaw laser tagi.

możliwość wykonania

local function canLocalPlayerBlast(): boolean
return true -- aktualizowana linia, upewnij się, że zmieniłeś wstecz
end

Generuj dane eksplozji

Po weryfikacji, że blaster gracza jest w stanie Ready, attemptBlastClient wzywa ReplicatedStorage > 2> attemptBlastClient2> > 5> blastClient5>. Pierwszym krokiem

Następnym krokiem jest generacja danych eksplozji. Jeśli przeglądasz ReplicatedStorage > Blaster > BlastData , możesz zobaczyć, że każda eksplozja składa się z trzech części informacji:

  • Gracz, który inicjuje eksplozję.
  • A DataType.CFrame , które reprezentuje punkt pochodzenia eksplozji.
  • Tabela RayResult, która zawiera ostateczne miejsce docelowe każdego lasera i gracza, jeśli dotknie inny gracz.

Aby generować te dane, blastClient wzywa ReplicatedStorage > attemptBlastClient > 2>błąd prób2> > 5>błąd prób5> > 8>生成BlastData8>, który można przeglądać poniżej.

GenerujBlastData

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

Funkcja ta zaczyna się używając getBlasterConfig , aby odzyskać wpisywaćblastera gracza. Przykład dostarcza dwa rodzaje blasterów: jeden, który produkuje kilka promieni z szerokim rozprzestrzenianiem poziomym, i inny, który produkuje pojedynczy promień. Można znaleźć ich konfiguracje w ReplicatedStorage > Inst

Funkcja wtedy używa currentCamera.CFrame jako punkt wyjścia dla eksplozji, przesyłając ją do getDirectionsForBlast. W tym momencie kod nie jest już o blaster

Powiadom Serwer

Gdy blastClient ma ukończone dane dla eksplozji, wtedy uruchamia dwa wydarzenia:

eksplozjaClient

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

Class.BindableEvent poinformuje inne skrypty klientów o eksplozji. Na przykład, ReplicatedStorage > FirstPersonBlasterVisuals używa tego wydarzenia, aby wiedzieć, kiedy wyświetlić efekty wizualne, takie

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

Aby pomóc zapobiec oszustwom, serwer musi weryfikować wszystkie dane, które każdy klient wysyła. Te czynności obejmują:

  1. Czy BlastData jest tabelą? Czy zawiera Class.CFrame i inną tabelę nazyającą się rayResults?
  2. Czy gracz ma założony blaster?
  3. Czy gracz ma postać i lokalizację w świecie?
  4. Po wysłaniu danych eksplozji, czy gracz przeszedł zbyt dużą odległość od miejsca, w którym eksplodował promień laserowy?

Ten ostatni test wiąże się z wezwanie do sądu, a zgodnie z czasami serwera i szybkością ruchu gracza, możesz zdecydować, że różne wartości są nadmierne dla własnego doświadczenia. Aby pokazać, jak wykonać ten wniosek sądowy, możesz uzyskać poczucie typowej wielkości zmiany pozycji, dodając oświadczenie drukowania w getValidatedBlastData i testując

dostać potwierdzone dane eksplozji

local distanceFromCharacterToOrigin = blastData.originCFrame.Position - rootPartCFrame.Position
print(distanceFromCharacterToOrigin.Magnitude) -- aktualna linia, upewnij się, że usuwać, wyjmować
if distanceFromCharacterToOrigin.Magnitude > ToleranceValues.DISTANCE_SANITY_CHECK_TOLERANCE_STUDS then
warn(`Player {player.Name} failed an origin sanity check while blasting`)
return
end

Podczas swojego ruchu i eksplozji, zauważaj wynik. Może to wyglądać coś takiego:


1.9019629955291748
3.1549558639526367
2.5742883682250977
4.8044586181640625
2.6434271335601807

Jeśli zwiększysz szybkość przesuwania dla graczy w ReplicatedStorage > PlayerStateHandler > togglePlayerMovement , to prawdopodobnie znajdziesz wiele niepowodzenia ze względu na nadmierne przesuwanie między wstrzymań.

Przenieśnik gracza

local ENABLED_WALK_SPEED = 60 -- updated line, be sure to change back

Następnie serwer robi co obserwuje:

  • Zweryfikowuje rayResults .
  • Sprawdza, czy gracz może eksplodować.
  • Zresetuje stan błastra.
  • Redukuje zdrowie dla każdego oznaczonego gracza.
  • Replikuje eksplozję do wszystkich innych graczy, aby mogli zobaczyć wizualizacje trzecioludzkie.

Dla więcej informacji na temat tych operacji serwera, zobacz sekcję Wykrywanie trafień w samouczku.

Zresetuj Blaster

W doświadczeniu laserowego tagu próbkowego laser używa mechanizmu termicznego. Zamiast ponownego ładowania po serii rzucania, potrzebuje czasu na "wylanie" między każdym rzucaniem. Ten sam opóźniony czas odnowienia następuje zarówno na klienta ( blastClient ) i serwera ( blastServer ) z serwera działającym jako źródło prawdy.

eksplozjaSerwer

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)

Attribut secondsBetweenBlasts jest częścią konfiguracji blastera w ReplicatedStorage > Instances > 1>LaserBlastersFolder1>. Po przekroczeniu opóźnienia 4>secondsBetweenBlasts4>, gracz może znowu eksplodować, a cały proces powtarza się. Aby pomó

W tym momencie gracze mogą wywołać i odrodzić, celować i wystrzelić, ale doświadczenie nadal musi określić wyniki każdej eksplozji. W następnej sekcji tutorialu nauczysz się programować umiejętność dla blastera, aby wykryć, gdy eksplozja trafi innego gracza, a następnie zmniejsz odpowiednią ilość zdrowia gracza zgodnie z ustawieniami blastera.